build-system: Merge of changes for 0.07.01rc1

	Based-on: 2d28043ac9a19d7d93fa91841f99e3234ac9f9d5
diff --git a/.default-version b/.default-version
new file mode 100644
index 0000000..db5f78c
--- /dev/null
+++ b/.default-version
@@ -0,0 +1 @@
+0.07.01rc1
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..11b2946
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,58 @@
+.git
+.DS_Store
+*.swp
+*.o
+*.lo
+.deps
+Makefile.in
+/Makefile
+/doc/Makefile
+/src/Makefile
+/src/connman-plugin/Makefile
+/src/ipc-dbus/Makefile
+/src/ncp-spinel/Makefile
+/src/ncp-dummy/Makefile
+/src/util/Makefile
+/src/wpanctl/Makefile
+/src/wpantund/Makefile
+/third_party/Makefile
+*.gcda
+*.gcno
+*~
+*~.c
+*.xcuserdatad
+*.orig
+xcuserdata
+.gdb_history
+*.a
+*.la
+.gdbinit
+/build
+/build-*
+/DerivedData
+/autom4te.cache
+/aclocal.m4
+/config.h.in
+/config.log
+/config.status
+/configure
+/libtool
+/src/config.h
+/m4
+/wpantund-*/
+/wpantund-*.tar.*
+src/stamp-h1
+src/config.h.in
+doxygen.cfg
+*.gz
+src/wpantund/wpantund
+src/wpanctl/wpanctl
+.dirstamp
+src/wpanctl/version.c
+wpantund.xcodeproj/project.xcworkspace/xcshareddata/wpan-tunnel-driver.xccheckout
+wpantund.xcodeproj/project.xcworkspace/xcshareddata/wpantund.xccheckout
+.cproject
+.project
+src/wpantund/.libs/wpantund
+Android.mk
+/etc/android
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..59d1081
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,45 @@
+language: cpp
+
+addons:
+    apt:
+        packages:
+            - bsdtar
+            - libdbus-1-dev
+            - autoconf-archive
+            - libglib2.0-dev
+            - libboost-dev
+            - libboost-signals-dev
+            - libreadline-dev
+            - libtool
+            - autoconf-archive
+
+sudo: required
+
+os:
+    - linux
+    - osx
+
+compiler:
+    - gcc
+    - clang
+
+before_install:
+    - .travis/before_install.sh
+
+script:
+    - .travis/script.sh
+
+after_success:
+    - ssh-agent .travis/after_success.sh
+
+env:
+    - BUILD_MAKEPATH=build BUILD_MAKEARGS="distcheck" TAR=bsdtar
+    - BUILD_MAKEPATH=build BUILD_MAKEARGS="distcheck" TAR=bsdtar BUILD_CONFIGFLAGS=--with-boost=internal
+
+matrix:
+    allow_failures:
+        - os: linux        # This seems to be some sort of weird failure to
+          compiler: clang  # find boost-signals. Needs further investigation.
+    exclude:
+        - os: osx
+          compiler: gcc
diff --git a/.travis/after_success.sh b/.travis/after_success.sh
new file mode 100755
index 0000000..8283316
--- /dev/null
+++ b/.travis/after_success.sh
@@ -0,0 +1,75 @@
+#!/bin/sh
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+PREV_PATH="`pwd`"
+
+die() {
+	echo " *** ERROR: " $*
+	exit 1
+}
+
+set -x
+
+prep_ssh_key() {
+	openssl aes-256-cbc -K "${encrypted_8f78c13496e8_key}" -iv "${encrypted_8f78c13496e8_iv}" -in .travis/deploy.prv.enc -out .travis/deploy.prv -d &&
+	chmod 600 .travis/deploy.prv &&
+	ssh-add .travis/deploy.prv &&
+	git config --global user.name "Travis CI" &&
+	git config --global user.email "noreply@travis-ci.com"
+}
+
+AUTOCONF_BRANCH="autoconf/$TRAVIS_BRANCH"
+
+
+if [ $TRAVIS_REPO_SLUG = "openthread/wpantund" ] \
+&& [ $TRAVIS_BRANCH = "master" ]                 \
+&& [ $TRAVIS_OS_NAME = "linux" ]                 \
+&& [ $TRAVIS_PULL_REQUEST = "false" ]            \
+&& [ $BUILD_MAKEPATH = "build" ]                 \
+&& [ $BUILD_MAKEARGS = "distcheck" ]             \
+&& prep_ssh_key                                  #
+then
+	git fetch --unshallow origin || git fetch origin || die
+
+	git fetch origin scripts:scripts ${AUTOCONF_BRANCH}:${AUTOCONF_BRANCH} ${TRAVIS_BRANCH}:${TRAVIS_BRANCH} || die
+
+	PREVREV="`git rev-parse ${AUTOCONF_BRANCH}`"
+
+	echo "Checking for update to '${AUTOCONF_BRANCH}'..."
+
+	git checkout scripts || die
+
+	NO_PUSH=1 ./update-autoconf-master ${TRAVIS_BRANCH} || die
+
+	CHANGED_LINES=`git diff "${PREVREV}".."${AUTOCONF_BRANCH}" | grep '^[-+]' | grep -v '^[-+]SOURCE_VERSION=' | wc -l`
+
+	if [ "$CHANGED_LINES" -gt "2" ]
+	then
+		echo "Branch '${AUTOCONF_BRANCH}' is OUT OF DATE."
+
+		git checkout "${TRAVIS_BRANCH}" || die
+
+		git push git@github.com:${TRAVIS_REPO_SLUG}.git ${AUTOCONF_BRANCH}:${AUTOCONF_BRANCH} || die
+	else
+		echo "Branch '${AUTOCONF_BRANCH}' is still up-to-date."
+	fi
+else
+	echo "Skipping update of '${AUTOCONF_BRANCH}'."
+fi
+
+exit 0
diff --git a/.travis/before_install.sh b/.travis/before_install.sh
new file mode 100755
index 0000000..0905be5
--- /dev/null
+++ b/.travis/before_install.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+die() {
+	echo " *** ERROR: " $*
+	exit 1
+}
+
+set -x
+
+[ $TRAVIS_OS_NAME != linux ] || {
+	wget https://gist.github.com/darconeous/d1d9bc39e0758e45a1d7/raw/ef9b01ac378a9b2e92031c846c4f6b5f94abab53/connman-include.tar.bz2 || die
+	sudo tar xvjf connman-include.tar.bz2 -C / || die
+}
+
+[ $TRAVIS_OS_NAME != osx ] || {
+	brew install d-bus
+	brew install autoconf-archive
+	brew install libtool
+	brew install gnu-sed
+}
diff --git a/.travis/deploy.prv.enc b/.travis/deploy.prv.enc
new file mode 100644
index 0000000..9c8bb57
--- /dev/null
+++ b/.travis/deploy.prv.enc
Binary files differ
diff --git a/.travis/deploy.pub b/.travis/deploy.pub
new file mode 100644
index 0000000..7c514a0
--- /dev/null
+++ b/.travis/deploy.pub
@@ -0,0 +1 @@
+ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEz2HAMQ1MWCP3ukYnuqbyunjIegE5dgN+5bW/YjrOsnO0iuYvh3ZsKf0gBMYdDsGXYE+nRzn9tm4tKVNwjl67w= noreply@travis-ci.org
diff --git a/.travis/script.sh b/.travis/script.sh
new file mode 100755
index 0000000..cf03a26
--- /dev/null
+++ b/.travis/script.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+PREV_PATH="`pwd`"
+
+die() {
+	echo " *** ERROR: " $*
+	exit 1
+}
+
+set -x
+
+[ $TRAVIS_OS_NAME != linux ] || BUILD_CONFIGFLAGS="${BUILD_CONFIGFLAGS} --with-connman"
+
+[ -e configure ] || ./bootstrap.sh || die
+
+mkdir -p "${BUILD_MAKEPATH}" || die
+
+cd "${BUILD_MAKEPATH}" || die
+
+../configure ${BUILD_CONFIGFLAGS} || die
+
+make ${BUILD_MAKEARGS} || die
+
+cd ..
diff --git a/.uncrustify.cfg b/.uncrustify.cfg
new file mode 100644
index 0000000..e5f1502
--- /dev/null
+++ b/.uncrustify.cfg
@@ -0,0 +1,1578 @@
+# Uncrustify 0.60
+
+#
+# General options
+#
+
+# The type of line endings
+newlines                                 = auto     # auto/lf/crlf/cr
+
+# The original size of tabs in the input
+input_tab_size                           = 4        # number
+
+# The size of tabs in the output (only used if align_with_tabs=true)
+output_tab_size                          = 4        # number
+
+# The ASCII value of the string escape char, usually 92 (\) or 94 (^). (Pawn)
+string_escape_char                       = 92       # number
+
+# Alternate string escape char for Pawn. Only works right before the quote char.
+string_escape_char2                      = 0        # number
+
+# Allow interpreting '>=' and '>>=' as part of a template in 'void f(list<list<B>>=val);'.
+# If true (default), 'assert(x<0 && y>=3)' will be broken.
+# Improvements to template detection may make this option obsolete.
+tok_split_gte                            = false    # false/true
+
+# Control what to do with the UTF-8 BOM (recommend 'remove')
+utf8_bom                                 = ignore   # ignore/add/remove/force
+
+# If the file contains bytes with values between 128 and 255, but is not UTF-8, then output as UTF-8
+utf8_byte                                = false    # false/true
+
+# Force the output encoding to UTF-8
+utf8_force                               = false    # false/true
+
+#
+# Indenting
+#
+
+# The number of columns to indent per level.
+# Usually 2, 3, 4, or 8.
+indent_columns                           = 4        # number
+
+# The continuation indent. If non-zero, this overrides the indent of '(' and '=' continuation indents.
+# For FreeBSD, this is set to 4. Negative value is absolute and not increased for each ( level
+indent_continue                          = 0        # number
+
+# How to use tabs when indenting code
+# 0=spaces only
+# 1=indent with tabs to brace level, align with spaces
+# 2=indent and align with tabs, using spaces when not on a tabstop
+indent_with_tabs                         = 1        # number
+
+# Comments that are not a brace level are indented with tabs on a tabstop.
+# Requires indent_with_tabs=2. If false, will use spaces.
+indent_cmt_with_tabs                     = false    # false/true
+
+# Whether to indent strings broken by '\' so that they line up
+indent_align_string                      = false    # false/true
+
+# The number of spaces to indent multi-line XML strings.
+# Requires indent_align_string=True
+indent_xml_string                        = 0        # number
+
+# Spaces to indent '{' from level
+indent_brace                             = 0        # number
+
+# Whether braces are indented to the body level
+indent_braces                            = false    # false/true
+
+# Disabled indenting function braces if indent_braces is true
+indent_braces_no_func                    = false    # false/true
+
+# Disabled indenting class braces if indent_braces is true
+indent_braces_no_class                   = false    # false/true
+
+# Disabled indenting struct braces if indent_braces is true
+indent_braces_no_struct                  = false    # false/true
+
+# Indent based on the size of the brace parent, i.e. 'if' => 3 spaces, 'for' => 4 spaces, etc.
+indent_brace_parent                      = false    # false/true
+
+# Whether the 'namespace' body is indented
+indent_namespace                         = false    # false/true
+
+# The number of spaces to indent a namespace block
+indent_namespace_level                   = 0        # number
+
+# If the body of the namespace is longer than this number, it won't be indented.
+# Requires indent_namespace=true. Default=0 (no limit)
+indent_namespace_limit                   = 0        # number
+
+# Whether the 'extern "C"' body is indented
+indent_extern                            = false    # false/true
+
+# Whether the 'class' body is indented
+indent_class                             = true    # false/true
+
+# Whether to indent the stuff after a leading class colon
+indent_class_colon                       = false    # false/true
+
+# Virtual indent from the ':' for member initializers. Default is 2
+indent_ctor_init_leading                 = 2        # number
+
+# Additional indenting for constructor initializer list
+indent_ctor_init                         = 0        # number
+
+# False=treat 'else\nif' as 'else if' for indenting purposes
+# True=indent the 'if' one level
+indent_else_if                           = false    # false/true
+
+# Amount to indent variable declarations after a open brace. neg=relative, pos=absolute
+indent_var_def_blk                       = 0        # number
+
+# Indent continued variable declarations instead of aligning.
+indent_var_def_cont                      = false    # false/true
+
+# True:  force indentation of function definition to start in column 1
+# False: use the default behavior
+indent_func_def_force_col1               = false    # false/true
+
+# True:  indent continued function call parameters one indent level
+# False: align parameters under the open paren
+indent_func_call_param                   = false    # false/true
+
+# Same as indent_func_call_param, but for function defs
+indent_func_def_param                    = false    # false/true
+
+# Same as indent_func_call_param, but for function protos
+indent_func_proto_param                  = false    # false/true
+
+# Same as indent_func_call_param, but for class declarations
+indent_func_class_param                  = false    # false/true
+
+# Same as indent_func_call_param, but for class variable constructors
+indent_func_ctor_var_param               = false    # false/true
+
+# Same as indent_func_call_param, but for templates
+indent_template_param                    = false    # false/true
+
+# Double the indent for indent_func_xxx_param options
+indent_func_param_double                 = false    # false/true
+
+# Indentation column for standalone 'const' function decl/proto qualifier
+indent_func_const                        = 0        # number
+
+# Indentation column for standalone 'throw' function decl/proto qualifier
+indent_func_throw                        = 0        # number
+
+# The number of spaces to indent a continued '->' or '.'
+# Usually set to 0, 1, or indent_columns.
+indent_member                            = 0        # number
+
+# Spaces to indent single line ('//') comments on lines before code
+indent_sing_line_comments                = 0        # number
+
+# If set, will indent trailing single line ('//') comments relative
+# to the code instead of trying to keep the same absolute column
+indent_relative_single_line_comments     = false    # false/true
+
+# Spaces to indent 'case' from 'switch'
+# Usually 0 or indent_columns.
+indent_switch_case                       = 0        # number
+
+# Spaces to shift the 'case' line, without affecting any other lines
+# Usually 0.
+indent_case_shift                        = 0        # number
+
+# Spaces to indent '{' from 'case'.
+# By default, the brace will appear under the 'c' in case.
+# Usually set to 0 or indent_columns.
+indent_case_brace                        = 0        # number
+
+# Whether to indent comments found in first column
+indent_col1_comment                      = false    # false/true
+
+# How to indent goto labels
+#  >0 : absolute column where 1 is the leftmost column
+#  <=0 : subtract from brace indent
+indent_label                             = 1        # number
+
+# Same as indent_label, but for access specifiers that are followed by a colon
+indent_access_spec                       = 1        # number
+
+# Indent the code after an access specifier by one level.
+# If set, this option forces 'indent_access_spec=0'
+indent_access_spec_body                  = false    # false/true
+
+# If an open paren is followed by a newline, indent the next line so that it lines up after the open paren (not recommended)
+indent_paren_nl                          = false    # false/true
+
+# Controls the indent of a close paren after a newline.
+# 0: Indent to body level
+# 1: Align under the open paren
+# 2: Indent to the brace level
+indent_paren_close                       = 0        # number
+
+# Controls the indent of a comma when inside a paren.If TRUE, aligns under the open paren
+indent_comma_paren                       = false    # false/true
+
+# Controls the indent of a BOOL operator when inside a paren.If TRUE, aligns under the open paren
+indent_bool_paren                        = false    # false/true
+
+# If 'indent_bool_paren' is true, controls the indent of the first expression. If TRUE, aligns the first expression to the following ones
+indent_first_bool_expr                   = false    # false/true
+
+# If an open square is followed by a newline, indent the next line so that it lines up after the open square (not recommended)
+indent_square_nl                         = false    # false/true
+
+# Don't change the relative indent of ESQL/C 'EXEC SQL' bodies
+indent_preserve_sql                      = false    # false/true
+
+# Align continued statements at the '='. Default=True
+# If FALSE or the '=' is followed by a newline, the next line is indent one tab.
+indent_align_assign                      = true     # false/true
+
+# Indent OC blocks at brace level instead of usual rules.
+indent_oc_block                          = false    # false/true
+
+# Indent OC blocks in a message relative to the parameter name.
+# 0=use indent_oc_block rules, 1+=spaces to indent
+indent_oc_block_msg                      = 0        # number
+
+# Minimum indent for subsequent parameters
+indent_oc_msg_colon                      = 0        # number
+
+#
+# Spacing options
+#
+
+# Add or remove space around arithmetic operator '+', '-', '/', '*', etc
+sp_arith                                 = ignore   # ignore/add/remove/force
+
+# Add or remove space around assignment operator '=', '+=', etc
+sp_assign                                = ignore   # ignore/add/remove/force
+
+# Add or remove space around '=' in C++11 lambda capture specifications. Overrides sp_assign
+sp_cpp_lambda_assign                     = ignore   # ignore/add/remove/force
+
+# Add or remove space after the capture specification in C++11 lambda.
+sp_cpp_lambda_paren                      = ignore   # ignore/add/remove/force
+
+# Add or remove space around assignment operator '=' in a prototype
+sp_assign_default                        = ignore   # ignore/add/remove/force
+
+# Add or remove space before assignment operator '=', '+=', etc. Overrides sp_assign.
+sp_before_assign                         = ignore   # ignore/add/remove/force
+
+# Add or remove space after assignment operator '=', '+=', etc. Overrides sp_assign.
+sp_after_assign                          = ignore   # ignore/add/remove/force
+
+# Add or remove space around assignment '=' in enum
+sp_enum_assign                           = ignore   # ignore/add/remove/force
+
+# Add or remove space before assignment '=' in enum. Overrides sp_enum_assign.
+sp_enum_before_assign                    = ignore   # ignore/add/remove/force
+
+# Add or remove space after assignment '=' in enum. Overrides sp_enum_assign.
+sp_enum_after_assign                     = ignore   # ignore/add/remove/force
+
+# Add or remove space around preprocessor '##' concatenation operator. Default=Add
+sp_pp_concat                             = add      # ignore/add/remove/force
+
+# Add or remove space after preprocessor '#' stringify operator. Also affects the '#@' charizing operator.
+sp_pp_stringify                          = ignore   # ignore/add/remove/force
+
+# Add or remove space before preprocessor '#' stringify operator as in '#define x(y) L#y'.
+sp_before_pp_stringify                   = ignore   # ignore/add/remove/force
+
+# Add or remove space around boolean operators '&&' and '||'
+sp_bool                                  = ignore   # ignore/add/remove/force
+
+# Add or remove space around compare operator '<', '>', '==', etc
+sp_compare                               = ignore   # ignore/add/remove/force
+
+# Add or remove space inside '(' and ')'
+sp_inside_paren                          = ignore   # ignore/add/remove/force
+
+# Add or remove space between nested parens
+sp_paren_paren                           = ignore   # ignore/add/remove/force
+
+# Whether to balance spaces inside nested parens
+sp_balance_nested_parens                 = false    # false/true
+
+# Add or remove space between ')' and '{'
+sp_paren_brace                           = ignore   # ignore/add/remove/force
+
+# Add or remove space before pointer star '*'
+sp_before_ptr_star                       = ignore   # ignore/add/remove/force
+
+# Add or remove space before pointer star '*' that isn't followed by a variable name
+# If set to 'ignore', sp_before_ptr_star is used instead.
+sp_before_unnamed_ptr_star               = ignore   # ignore/add/remove/force
+
+# Add or remove space between pointer stars '*'
+sp_between_ptr_star                      = ignore   # ignore/add/remove/force
+
+# Add or remove space after pointer star '*', if followed by a word.
+sp_after_ptr_star                        = ignore   # ignore/add/remove/force
+
+# Add or remove space after a pointer star '*', if followed by a func proto/def.
+sp_after_ptr_star_func                   = ignore   # ignore/add/remove/force
+
+# Add or remove space after a pointer star '*', if followed by an open paren (function types).
+sp_ptr_star_paren                        = ignore   # ignore/add/remove/force
+
+# Add or remove space before a pointer star '*', if followed by a func proto/def.
+sp_before_ptr_star_func                  = ignore   # ignore/add/remove/force
+
+# Add or remove space before a reference sign '&'
+sp_before_byref                          = ignore   # ignore/add/remove/force
+
+# Add or remove space before a reference sign '&' that isn't followed by a variable name
+# If set to 'ignore', sp_before_byref is used instead.
+sp_before_unnamed_byref                  = ignore   # ignore/add/remove/force
+
+# Add or remove space after reference sign '&', if followed by a word.
+sp_after_byref                           = ignore   # ignore/add/remove/force
+
+# Add or remove space after a reference sign '&', if followed by a func proto/def.
+sp_after_byref_func                      = ignore   # ignore/add/remove/force
+
+# Add or remove space before a reference sign '&', if followed by a func proto/def.
+sp_before_byref_func                     = ignore   # ignore/add/remove/force
+
+# Add or remove space between type and word. Default=Force
+sp_after_type                            = force    # ignore/add/remove/force
+
+# Add or remove space before the paren in the D constructs 'template Foo(' and 'class Foo('.
+sp_before_template_paren                 = ignore   # ignore/add/remove/force
+
+# Add or remove space in 'template <' vs 'template<'.
+# If set to ignore, sp_before_angle is used.
+sp_template_angle                        = ignore   # ignore/add/remove/force
+
+# Add or remove space before '<>'
+sp_before_angle                          = ignore   # ignore/add/remove/force
+
+# Add or remove space inside '<' and '>'
+sp_inside_angle                          = ignore   # ignore/add/remove/force
+
+# Add or remove space after '<>'
+sp_after_angle                           = ignore   # ignore/add/remove/force
+
+# Add or remove space between '<>' and '(' as found in 'new List<byte>();'
+sp_angle_paren                           = ignore   # ignore/add/remove/force
+
+# Add or remove space between '<>' and a word as in 'List<byte> m;'
+sp_angle_word                            = ignore   # ignore/add/remove/force
+
+# Add or remove space between '>' and '>' in '>>' (template stuff C++/C# only). Default=Add
+sp_angle_shift                           = add      # ignore/add/remove/force
+
+# Permit removal of the space between '>>' in 'foo<bar<int> >' (C++11 only). Default=False
+# sp_angle_shift cannot remove the space without this option.
+sp_permit_cpp11_shift                    = false    # false/true
+
+# Add or remove space before '(' of 'if', 'for', 'switch', and 'while'
+sp_before_sparen                         = ignore   # ignore/add/remove/force
+
+# Add or remove space inside if-condition '(' and ')'
+sp_inside_sparen                         = ignore   # ignore/add/remove/force
+
+# Add or remove space before if-condition ')'. Overrides sp_inside_sparen.
+sp_inside_sparen_close                   = ignore   # ignore/add/remove/force
+
+# Add or remove space before if-condition '('. Overrides sp_inside_sparen.
+sp_inside_sparen_open                    = ignore   # ignore/add/remove/force
+
+# Add or remove space after ')' of 'if', 'for', 'switch', and 'while'
+sp_after_sparen                          = ignore   # ignore/add/remove/force
+
+# Add or remove space between ')' and '{' of 'if', 'for', 'switch', and 'while'
+sp_sparen_brace                          = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'invariant' and '(' in the D language.
+sp_invariant_paren                       = ignore   # ignore/add/remove/force
+
+# Add or remove space after the ')' in 'invariant (C) c' in the D language.
+sp_after_invariant_paren                 = ignore   # ignore/add/remove/force
+
+# Add or remove space before empty statement ';' on 'if', 'for' and 'while'
+sp_special_semi                          = ignore   # ignore/add/remove/force
+
+# Add or remove space before ';'. Default=Remove
+sp_before_semi                           = remove   # ignore/add/remove/force
+
+# Add or remove space before ';' in non-empty 'for' statements
+sp_before_semi_for                       = ignore   # ignore/add/remove/force
+
+# Add or remove space before a semicolon of an empty part of a for statement.
+sp_before_semi_for_empty                 = ignore   # ignore/add/remove/force
+
+# Add or remove space after ';', except when followed by a comment. Default=Add
+sp_after_semi                            = add      # ignore/add/remove/force
+
+# Add or remove space after ';' in non-empty 'for' statements. Default=Force
+sp_after_semi_for                        = force    # ignore/add/remove/force
+
+# Add or remove space after the final semicolon of an empty part of a for statement: for ( ; ; <here> ).
+sp_after_semi_for_empty                  = ignore   # ignore/add/remove/force
+
+# Add or remove space before '[' (except '[]')
+sp_before_square                         = ignore   # ignore/add/remove/force
+
+# Add or remove space before '[]'
+sp_before_squares                        = ignore   # ignore/add/remove/force
+
+# Add or remove space inside a non-empty '[' and ']'
+sp_inside_square                         = ignore   # ignore/add/remove/force
+
+# Add or remove space after ','
+sp_after_comma                           = ignore   # ignore/add/remove/force
+
+# Add or remove space before ','
+sp_before_comma                          = remove   # ignore/add/remove/force
+
+# Add or remove space between an open paren and comma: '(,' vs '( ,'
+sp_paren_comma                           = force    # ignore/add/remove/force
+
+# Add or remove space before the variadic '...' when preceded by a non-punctuator
+sp_before_ellipsis                       = ignore   # ignore/add/remove/force
+
+# Add or remove space after class ':'
+sp_after_class_colon                     = ignore   # ignore/add/remove/force
+
+# Add or remove space before class ':'
+sp_before_class_colon                    = ignore   # ignore/add/remove/force
+
+# Add or remove space before case ':'. Default=Remove
+sp_before_case_colon                     = remove   # ignore/add/remove/force
+
+# Add or remove space between 'operator' and operator sign
+sp_after_operator                        = ignore   # ignore/add/remove/force
+
+# Add or remove space between the operator symbol and the open paren, as in 'operator ++('
+sp_after_operator_sym                    = ignore   # ignore/add/remove/force
+
+# Add or remove space after C/D cast, i.e. 'cast(int)a' vs 'cast(int) a' or '(int)a' vs '(int) a'
+sp_after_cast                            = ignore   # ignore/add/remove/force
+
+# Add or remove spaces inside cast parens
+sp_inside_paren_cast                     = ignore   # ignore/add/remove/force
+
+# Add or remove space between the type and open paren in a C++ cast, i.e. 'int(exp)' vs 'int (exp)'
+sp_cpp_cast_paren                        = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'sizeof' and '('
+sp_sizeof_paren                          = ignore   # ignore/add/remove/force
+
+# Add or remove space after the tag keyword (Pawn)
+sp_after_tag                             = ignore   # ignore/add/remove/force
+
+# Add or remove space inside enum '{' and '}'
+sp_inside_braces_enum                    = ignore   # ignore/add/remove/force
+
+# Add or remove space inside struct/union '{' and '}'
+sp_inside_braces_struct                  = ignore   # ignore/add/remove/force
+
+# Add or remove space inside '{' and '}'
+sp_inside_braces                         = ignore   # ignore/add/remove/force
+
+# Add or remove space inside '{}'
+sp_inside_braces_empty                   = ignore   # ignore/add/remove/force
+
+# Add or remove space between return type and function name
+# A minimum of 1 is forced except for pointer return types.
+sp_type_func                             = ignore   # ignore/add/remove/force
+
+# Add or remove space between function name and '(' on function declaration
+sp_func_proto_paren                      = ignore   # ignore/add/remove/force
+
+# Add or remove space between function name and '(' on function definition
+sp_func_def_paren                        = ignore   # ignore/add/remove/force
+
+# Add or remove space inside empty function '()'
+sp_inside_fparens                        = ignore   # ignore/add/remove/force
+
+# Add or remove space inside function '(' and ')'
+sp_inside_fparen                         = ignore   # ignore/add/remove/force
+
+# Add or remove space inside the first parens in the function type: 'void (*x)(...)'
+sp_inside_tparen                         = ignore   # ignore/add/remove/force
+
+# Add or remove between the parens in the function type: 'void (*x)(...)'
+sp_after_tparen_close                    = ignore   # ignore/add/remove/force
+
+# Add or remove space between ']' and '(' when part of a function call.
+sp_square_fparen                         = ignore   # ignore/add/remove/force
+
+# Add or remove space between ')' and '{' of function
+sp_fparen_brace                          = ignore   # ignore/add/remove/force
+
+# Add or remove space between function name and '(' on function calls
+sp_func_call_paren                       = ignore   # ignore/add/remove/force
+
+# Add or remove space between function name and '()' on function calls without parameters.
+# If set to 'ignore' (the default), sp_func_call_paren is used.
+sp_func_call_paren_empty                 = ignore   # ignore/add/remove/force
+
+# Add or remove space between the user function name and '(' on function calls
+# You need to set a keyword to be a user function, like this: 'set func_call_user _' in the config file.
+sp_func_call_user_paren                  = ignore   # ignore/add/remove/force
+
+# Add or remove space between a constructor/destructor and the open paren
+sp_func_class_paren                      = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'return' and '('
+sp_return_paren                          = ignore   # ignore/add/remove/force
+
+# Add or remove space between '__attribute__' and '('
+sp_attribute_paren                       = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'defined' and '(' in '#if defined (FOO)'
+sp_defined_paren                         = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'throw' and '(' in 'throw (something)'
+sp_throw_paren                           = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'throw' and anything other than '(' as in '@throw [...];'
+sp_after_throw                           = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'catch' and '(' in 'catch (something) { }'
+# If set to ignore, sp_before_sparen is used.
+sp_catch_paren                           = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'version' and '(' in 'version (something) { }' (D language)
+# If set to ignore, sp_before_sparen is used.
+sp_version_paren                         = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'scope' and '(' in 'scope (something) { }' (D language)
+# If set to ignore, sp_before_sparen is used.
+sp_scope_paren                           = ignore   # ignore/add/remove/force
+
+# Add or remove space between macro and value
+sp_macro                                 = ignore   # ignore/add/remove/force
+
+# Add or remove space between macro function ')' and value
+sp_macro_func                            = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'else' and '{' if on the same line
+sp_else_brace                            = ignore   # ignore/add/remove/force
+
+# Add or remove space between '}' and 'else' if on the same line
+sp_brace_else                            = ignore   # ignore/add/remove/force
+
+# Add or remove space between '}' and the name of a typedef on the same line
+sp_brace_typedef                         = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'catch' and '{' if on the same line
+sp_catch_brace                           = ignore   # ignore/add/remove/force
+
+# Add or remove space between '}' and 'catch' if on the same line
+sp_brace_catch                           = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'finally' and '{' if on the same line
+sp_finally_brace                         = ignore   # ignore/add/remove/force
+
+# Add or remove space between '}' and 'finally' if on the same line
+sp_brace_finally                         = ignore   # ignore/add/remove/force
+
+# Add or remove space between 'try' and '{' if on the same line
+sp_try_brace                             = ignore   # ignore/add/remove/force
+
+# Add or remove space between get/set and '{' if on the same line
+sp_getset_brace                          = ignore   # ignore/add/remove/force
+
+# Add or remove space before the '::' operator
+sp_before_dc                             = ignore   # ignore/add/remove/force
+
+# Add or remove space after the '::' operator
+sp_after_dc                              = ignore   # ignore/add/remove/force
+
+# Add or remove around the D named array initializer ':' operator
+sp_d_array_colon                         = ignore   # ignore/add/remove/force
+
+# Add or remove space after the '!' (not) operator. Default=Remove
+sp_not                                   = remove   # ignore/add/remove/force
+
+# Add or remove space after the '~' (invert) operator. Default=Remove
+sp_inv                                   = remove   # ignore/add/remove/force
+
+# Add or remove space after the '&' (address-of) operator. Default=Remove
+# This does not affect the spacing after a '&' that is part of a type.
+sp_addr                                  = remove   # ignore/add/remove/force
+
+# Add or remove space around the '.' or '->' operators. Default=Remove
+sp_member                                = remove   # ignore/add/remove/force
+
+# Add or remove space after the '*' (dereference) operator. Default=Remove
+# This does not affect the spacing after a '*' that is part of a type.
+sp_deref                                 = remove   # ignore/add/remove/force
+
+# Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. Default=Remove
+sp_sign                                  = remove   # ignore/add/remove/force
+
+# Add or remove space before or after '++' and '--', as in '(--x)' or 'y++;'. Default=Remove
+sp_incdec                                = remove   # ignore/add/remove/force
+
+# Add or remove space before a backslash-newline at the end of a line. Default=Add
+sp_before_nl_cont                        = add      # ignore/add/remove/force
+
+# Add or remove space after the scope '+' or '-', as in '-(void) foo;' or '+(int) bar;'
+sp_after_oc_scope                        = ignore   # ignore/add/remove/force
+
+# Add or remove space after the colon in message specs
+# '-(int) f:(int) x;' vs '-(int) f: (int) x;'
+sp_after_oc_colon                        = ignore   # ignore/add/remove/force
+
+# Add or remove space before the colon in message specs
+# '-(int) f: (int) x;' vs '-(int) f : (int) x;'
+sp_before_oc_colon                       = ignore   # ignore/add/remove/force
+
+# Add or remove space after the colon in immutable dictionary expression
+# 'NSDictionary *test = @{@"foo" :@"bar"};'
+sp_after_oc_dict_colon                   = ignore   # ignore/add/remove/force
+
+# Add or remove space before the colon in immutable dictionary expression
+# 'NSDictionary *test = @{@"foo" :@"bar"};'
+sp_before_oc_dict_colon                  = ignore   # ignore/add/remove/force
+
+# Add or remove space after the colon in message specs
+# '[object setValue:1];' vs '[object setValue: 1];'
+sp_after_send_oc_colon                   = ignore   # ignore/add/remove/force
+
+# Add or remove space before the colon in message specs
+# '[object setValue:1];' vs '[object setValue :1];'
+sp_before_send_oc_colon                  = ignore   # ignore/add/remove/force
+
+# Add or remove space after the (type) in message specs
+# '-(int)f: (int) x;' vs '-(int)f: (int)x;'
+sp_after_oc_type                         = ignore   # ignore/add/remove/force
+
+# Add or remove space after the first (type) in message specs
+# '-(int) f:(int)x;' vs '-(int)f:(int)x;'
+sp_after_oc_return_type                  = ignore   # ignore/add/remove/force
+
+# Add or remove space between '@selector' and '('
+# '@selector(msgName)' vs '@selector (msgName)'
+# Also applies to @protocol() constructs
+sp_after_oc_at_sel                       = ignore   # ignore/add/remove/force
+
+# Add or remove space between '@selector(x)' and the following word
+# '@selector(foo) a:' vs '@selector(foo)a:'
+sp_after_oc_at_sel_parens                = ignore   # ignore/add/remove/force
+
+# Add or remove space inside '@selector' parens
+# '@selector(foo)' vs '@selector( foo )'
+# Also applies to @protocol() constructs
+sp_inside_oc_at_sel_parens               = ignore   # ignore/add/remove/force
+
+# Add or remove space before a block pointer caret
+# '^int (int arg){...}' vs. ' ^int (int arg){...}'
+sp_before_oc_block_caret                 = ignore   # ignore/add/remove/force
+
+# Add or remove space after a block pointer caret
+# '^int (int arg){...}' vs. '^ int (int arg){...}'
+sp_after_oc_block_caret                  = ignore   # ignore/add/remove/force
+
+# Add or remove space between the receiver and selector in a message.
+# '[receiver selector ...]'
+sp_after_oc_msg_receiver                 = ignore   # ignore/add/remove/force
+
+# Add or remove space after @property.
+sp_after_oc_property                     = ignore   # ignore/add/remove/force
+
+# Add or remove space around the ':' in 'b ? t : f'
+sp_cond_colon                            = ignore   # ignore/add/remove/force
+
+# Add or remove space around the '?' in 'b ? t : f'
+sp_cond_question                         = ignore   # ignore/add/remove/force
+
+# Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make sense here.
+sp_case_label                            = ignore   # ignore/add/remove/force
+
+# Control the space around the D '..' operator.
+sp_range                                 = ignore   # ignore/add/remove/force
+
+# Control the spacing after ':' in 'for (TYPE VAR : EXPR)' (Java)
+sp_after_for_colon                       = ignore   # ignore/add/remove/force
+
+# Control the spacing before ':' in 'for (TYPE VAR : EXPR)' (Java)
+sp_before_for_colon                      = ignore   # ignore/add/remove/force
+
+# Control the spacing in 'extern (C)' (D)
+sp_extern_paren                          = ignore   # ignore/add/remove/force
+
+# Control the space after the opening of a C++ comment '// A' vs '//A'
+sp_cmt_cpp_start                         = ignore   # ignore/add/remove/force
+
+# Controls the spaces between #else or #endif and a trailing comment
+sp_endif_cmt                             = ignore   # ignore/add/remove/force
+
+# Controls the spaces after 'new', 'delete', and 'delete[]'
+sp_after_new                             = ignore   # ignore/add/remove/force
+
+# Controls the spaces before a trailing or embedded comment
+sp_before_tr_emb_cmt                     = ignore   # ignore/add/remove/force
+
+# Number of spaces before a trailing or embedded comment
+sp_num_before_tr_emb_cmt                 = 0        # number
+
+# Control space between a Java annotation and the open paren.
+sp_annotation_paren                      = ignore   # ignore/add/remove/force
+
+#
+# Code alignment (not left column spaces/tabs)
+#
+
+# Whether to keep non-indenting tabs
+align_keep_tabs                          = false    # false/true
+
+# Whether to use tabs for aligning
+align_with_tabs                          = false    # false/true
+
+# Whether to bump out to the next tab when aligning
+align_on_tabstop                         = false    # false/true
+
+# Whether to left-align numbers
+align_number_left                        = false    # false/true
+
+# Align variable definitions in prototypes and functions
+align_func_params                        = false    # false/true
+
+# Align parameters in single-line functions that have the same name.
+# The function names must already be aligned with each other.
+align_same_func_call_params              = false    # false/true
+
+# The span for aligning variable definitions (0=don't align)
+align_var_def_span                       = 0        # number
+
+# How to align the star in variable definitions.
+#  0=Part of the type     'void *   foo;'
+#  1=Part of the variable 'void     *foo;'
+#  2=Dangling             'void    *foo;'
+align_var_def_star_style                 = 0        # number
+
+# How to align the '&' in variable definitions.
+#  0=Part of the type
+#  1=Part of the variable
+#  2=Dangling
+align_var_def_amp_style                  = 0        # number
+
+# The threshold for aligning variable definitions (0=no limit)
+align_var_def_thresh                     = 0        # number
+
+# The gap for aligning variable definitions
+align_var_def_gap                        = 0        # number
+
+# Whether to align the colon in struct bit fields
+align_var_def_colon                      = false    # false/true
+
+# Whether to align any attribute after the variable name
+align_var_def_attribute                  = false    # false/true
+
+# Whether to align inline struct/enum/union variable definitions
+align_var_def_inline                     = false    # false/true
+
+# The span for aligning on '=' in assignments (0=don't align)
+align_assign_span                        = 0        # number
+
+# The threshold for aligning on '=' in assignments (0=no limit)
+align_assign_thresh                      = 0        # number
+
+# The span for aligning on '=' in enums (0=don't align)
+align_enum_equ_span                      = 0        # number
+
+# The threshold for aligning on '=' in enums (0=no limit)
+align_enum_equ_thresh                    = 0        # number
+
+# The span for aligning struct/union (0=don't align)
+align_var_struct_span                    = 0        # number
+
+# The threshold for aligning struct/union member definitions (0=no limit)
+align_var_struct_thresh                  = 0        # number
+
+# The gap for aligning struct/union member definitions
+align_var_struct_gap                     = 0        # number
+
+# The span for aligning struct initializer values (0=don't align)
+align_struct_init_span                   = 0        # number
+
+# The minimum space between the type and the synonym of a typedef
+align_typedef_gap                        = 0        # number
+
+# The span for aligning single-line typedefs (0=don't align)
+align_typedef_span                       = 0        # number
+
+# How to align typedef'd functions with other typedefs
+# 0: Don't mix them at all
+# 1: align the open paren with the types
+# 2: align the function type name with the other type names
+align_typedef_func                       = 0        # number
+
+# Controls the positioning of the '*' in typedefs. Just try it.
+# 0: Align on typedef type, ignore '*'
+# 1: The '*' is part of type name: typedef int  *pint;
+# 2: The '*' is part of the type, but dangling: typedef int *pint;
+align_typedef_star_style                 = 0        # number
+
+# Controls the positioning of the '&' in typedefs. Just try it.
+# 0: Align on typedef type, ignore '&'
+# 1: The '&' is part of type name: typedef int  &pint;
+# 2: The '&' is part of the type, but dangling: typedef int &pint;
+align_typedef_amp_style                  = 0        # number
+
+# The span for aligning comments that end lines (0=don't align)
+align_right_cmt_span                     = 0        # number
+
+# If aligning comments, mix with comments after '}' and #endif with less than 3 spaces before the comment
+align_right_cmt_mix                      = false    # false/true
+
+# If a trailing comment is more than this number of columns away from the text it follows,
+# it will qualify for being aligned. This has to be > 0 to do anything.
+align_right_cmt_gap                      = 0        # number
+
+# Align trailing comment at or beyond column N; 'pulls in' comments as a bonus side effect (0=ignore)
+align_right_cmt_at_col                   = 0        # number
+
+# The span for aligning function prototypes (0=don't align)
+align_func_proto_span                    = 0        # number
+
+# Minimum gap between the return type and the function name.
+align_func_proto_gap                     = 0        # number
+
+# Align function protos on the 'operator' keyword instead of what follows
+align_on_operator                        = false    # false/true
+
+# Whether to mix aligning prototype and variable declarations.
+# If true, align_var_def_XXX options are used instead of align_func_proto_XXX options.
+align_mix_var_proto                      = false    # false/true
+
+# Align single-line functions with function prototypes, uses align_func_proto_span
+align_single_line_func                   = false    # false/true
+
+# Aligning the open brace of single-line functions.
+# Requires align_single_line_func=true, uses align_func_proto_span
+align_single_line_brace                  = false    # false/true
+
+# Gap for align_single_line_brace.
+align_single_line_brace_gap              = 0        # number
+
+# The span for aligning ObjC msg spec (0=don't align)
+align_oc_msg_spec_span                   = 0        # number
+
+# Whether to align macros wrapped with a backslash and a newline.
+# This will not work right if the macro contains a multi-line comment.
+align_nl_cont                            = false    # false/true
+
+# # Align macro functions and variables together
+align_pp_define_together                 = false    # false/true
+
+# The minimum space between label and value of a preprocessor define
+align_pp_define_gap                      = 0        # number
+
+# The span for aligning on '#define' bodies (0=don't align)
+align_pp_define_span                     = 0        # number
+
+# Align lines that start with '<<' with previous '<<'. Default=true
+align_left_shift                         = true     # false/true
+
+# Span for aligning parameters in an Obj-C message call on the ':' (0=don't align)
+align_oc_msg_colon_span                  = 0        # number
+
+# If true, always align with the first parameter, even if it is too short.
+align_oc_msg_colon_first                 = false    # false/true
+
+# Aligning parameters in an Obj-C '+' or '-' declaration on the ':'
+align_oc_decl_colon                      = false    # false/true
+
+#
+# Newline adding and removing options
+#
+
+# Whether to collapse empty blocks between '{' and '}'
+nl_collapse_empty_body                   = false    # false/true
+
+# Don't split one-line braced assignments - 'foo_t f = { 1, 2 };'
+nl_assign_leave_one_liners               = false    # false/true
+
+# Don't split one-line braced statements inside a class xx { } body
+nl_class_leave_one_liners                = false    # false/true
+
+# Don't split one-line enums: 'enum foo { BAR = 15 };'
+nl_enum_leave_one_liners                 = false    # false/true
+
+# Don't split one-line get or set functions
+nl_getset_leave_one_liners               = false    # false/true
+
+# Don't split one-line function definitions - 'int foo() { return 0; }'
+nl_func_leave_one_liners                 = false    # false/true
+
+# Don't split one-line if/else statements - 'if(a) b++;'
+nl_if_leave_one_liners                   = false    # false/true
+
+# Don't split one-line OC messages
+nl_oc_msg_leave_one_liner                = false    # false/true
+
+# Add or remove newlines at the start of the file
+nl_start_of_file                         = ignore   # ignore/add/remove/force
+
+# The number of newlines at the start of the file (only used if nl_start_of_file is 'add' or 'force'
+nl_start_of_file_min                     = 0        # number
+
+# Add or remove newline at the end of the file
+nl_end_of_file                           = ignore   # ignore/add/remove/force
+
+# The number of newlines at the end of the file (only used if nl_end_of_file is 'add' or 'force')
+nl_end_of_file_min                       = 0        # number
+
+# Add or remove newline between '=' and '{'
+nl_assign_brace                          = ignore   # ignore/add/remove/force
+
+# Add or remove newline between '=' and '[' (D only)
+nl_assign_square                         = ignore   # ignore/add/remove/force
+
+# Add or remove newline after '= [' (D only). Will also affect the newline before the ']'
+nl_after_square_assign                   = ignore   # ignore/add/remove/force
+
+# The number of blank lines after a block of variable definitions at the top of a function body
+# 0 = No change (default)
+nl_func_var_def_blk                      = 0        # number
+
+# The number of newlines before a block of typedefs
+# 0 = No change (default)
+nl_typedef_blk_start                     = 0        # number
+
+# The number of newlines after a block of typedefs
+# 0 = No change (default)
+nl_typedef_blk_end                       = 0        # number
+
+# The maximum consecutive newlines within a block of typedefs
+# 0 = No change (default)
+nl_typedef_blk_in                        = 0        # number
+
+# The number of newlines before a block of variable definitions not at the top of a function body
+# 0 = No change (default)
+nl_var_def_blk_start                     = 0        # number
+
+# The number of newlines after a block of variable definitions not at the top of a function body
+# 0 = No change (default)
+nl_var_def_blk_end                       = 0        # number
+
+# The maximum consecutive newlines within a block of variable definitions
+# 0 = No change (default)
+nl_var_def_blk_in                        = 0        # number
+
+# Add or remove newline between a function call's ')' and '{', as in:
+# list_for_each(item, &list) { }
+nl_fcall_brace                           = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'enum' and '{'
+nl_enum_brace                            = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'struct and '{'
+nl_struct_brace                          = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'union' and '{'
+nl_union_brace                           = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'if' and '{'
+nl_if_brace                              = ignore   # ignore/add/remove/force
+
+# Add or remove newline between '}' and 'else'
+nl_brace_else                            = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'else if' and '{'
+# If set to ignore, nl_if_brace is used instead
+nl_elseif_brace                          = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'else' and '{'
+nl_else_brace                            = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'else' and 'if'
+nl_else_if                               = ignore   # ignore/add/remove/force
+
+# Add or remove newline between '}' and 'finally'
+nl_brace_finally                         = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'finally' and '{'
+nl_finally_brace                         = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'try' and '{'
+nl_try_brace                             = ignore   # ignore/add/remove/force
+
+# Add or remove newline between get/set and '{'
+nl_getset_brace                          = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'for' and '{'
+nl_for_brace                             = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'catch' and '{'
+nl_catch_brace                           = ignore   # ignore/add/remove/force
+
+# Add or remove newline between '}' and 'catch'
+nl_brace_catch                           = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'while' and '{'
+nl_while_brace                           = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'scope (x)' and '{' (D)
+nl_scope_brace                           = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'unittest' and '{' (D)
+nl_unittest_brace                        = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'version (x)' and '{' (D)
+nl_version_brace                         = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'using' and '{'
+nl_using_brace                           = ignore   # ignore/add/remove/force
+
+# Add or remove newline between two open or close braces.
+# Due to general newline/brace handling, REMOVE may not work.
+nl_brace_brace                           = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'do' and '{'
+nl_do_brace                              = ignore   # ignore/add/remove/force
+
+# Add or remove newline between '}' and 'while' of 'do' statement
+nl_brace_while                           = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'switch' and '{'
+nl_switch_brace                          = ignore   # ignore/add/remove/force
+
+# Add a newline between ')' and '{' if the ')' is on a different line than the if/for/etc.
+# Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch, and nl_catch_brace.
+nl_multi_line_cond                       = false    # false/true
+
+# Force a newline in a define after the macro name for multi-line defines.
+nl_multi_line_define                     = false    # false/true
+
+# Whether to put a newline before 'case' statement
+nl_before_case                           = false    # false/true
+
+# Add or remove newline between ')' and 'throw'
+nl_before_throw                          = ignore   # ignore/add/remove/force
+
+# Whether to put a newline after 'case' statement
+nl_after_case                            = false    # false/true
+
+# Add or remove a newline between a case ':' and '{'. Overrides nl_after_case.
+nl_case_colon_brace                      = ignore   # ignore/add/remove/force
+
+# Newline between namespace and {
+nl_namespace_brace                       = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'template<>' and whatever follows.
+nl_template_class                        = ignore   # ignore/add/remove/force
+
+# Add or remove newline between 'class' and '{'
+nl_class_brace                           = ignore   # ignore/add/remove/force
+
+# Add or remove newline after each ',' in the constructor member initialization
+nl_class_init_args                       = ignore   # ignore/add/remove/force
+
+# Add or remove newline between return type and function name in a function definition
+nl_func_type_name                        = ignore   # ignore/add/remove/force
+
+# Add or remove newline between return type and function name inside a class {}
+# Uses nl_func_type_name or nl_func_proto_type_name if set to ignore.
+nl_func_type_name_class                  = ignore   # ignore/add/remove/force
+
+# Add or remove newline between function scope and name in a definition
+# Controls the newline after '::' in 'void A::f() { }'
+nl_func_scope_name                       = ignore   # ignore/add/remove/force
+
+# Add or remove newline between return type and function name in a prototype
+nl_func_proto_type_name                  = ignore   # ignore/add/remove/force
+
+# Add or remove newline between a function name and the opening '('
+nl_func_paren                            = ignore   # ignore/add/remove/force
+
+# Add or remove newline between a function name and the opening '(' in the definition
+nl_func_def_paren                        = ignore   # ignore/add/remove/force
+
+# Add or remove newline after '(' in a function declaration
+nl_func_decl_start                       = ignore   # ignore/add/remove/force
+
+# Add or remove newline after '(' in a function definition
+nl_func_def_start                        = ignore   # ignore/add/remove/force
+
+# Overrides nl_func_decl_start when there is only one parameter.
+nl_func_decl_start_single                = ignore   # ignore/add/remove/force
+
+# Overrides nl_func_def_start when there is only one parameter.
+nl_func_def_start_single                 = ignore   # ignore/add/remove/force
+
+# Add or remove newline after each ',' in a function declaration
+nl_func_decl_args                        = ignore   # ignore/add/remove/force
+
+# Add or remove newline after each ',' in a function definition
+nl_func_def_args                         = ignore   # ignore/add/remove/force
+
+# Add or remove newline before the ')' in a function declaration
+nl_func_decl_end                         = ignore   # ignore/add/remove/force
+
+# Add or remove newline before the ')' in a function definition
+nl_func_def_end                          = ignore   # ignore/add/remove/force
+
+# Overrides nl_func_decl_end when there is only one parameter.
+nl_func_decl_end_single                  = ignore   # ignore/add/remove/force
+
+# Overrides nl_func_def_end when there is only one parameter.
+nl_func_def_end_single                   = ignore   # ignore/add/remove/force
+
+# Add or remove newline between '()' in a function declaration.
+nl_func_decl_empty                       = ignore   # ignore/add/remove/force
+
+# Add or remove newline between '()' in a function definition.
+nl_func_def_empty                        = ignore   # ignore/add/remove/force
+
+# Whether to put each OC message parameter on a separate line
+# See nl_oc_msg_leave_one_liner
+nl_oc_msg_args                           = false    # false/true
+
+# Add or remove newline between function signature and '{'
+nl_fdef_brace                            = ignore   # ignore/add/remove/force
+
+# Add or remove a newline between the return keyword and return expression.
+nl_return_expr                           = ignore   # ignore/add/remove/force
+
+# Whether to put a newline after semicolons, except in 'for' statements
+nl_after_semicolon                       = false    # false/true
+
+# Whether to put a newline after brace open.
+# This also adds a newline before the matching brace close.
+nl_after_brace_open                      = false    # false/true
+
+# If nl_after_brace_open and nl_after_brace_open_cmt are true, a newline is
+# placed between the open brace and a trailing single-line comment.
+nl_after_brace_open_cmt                  = false    # false/true
+
+# Whether to put a newline after a virtual brace open with a non-empty body.
+# These occur in un-braced if/while/do/for statement bodies.
+nl_after_vbrace_open                     = false    # false/true
+
+# Whether to put a newline after a virtual brace open with an empty body.
+# These occur in un-braced if/while/do/for statement bodies.
+nl_after_vbrace_open_empty               = false    # false/true
+
+# Whether to put a newline after a brace close.
+# Does not apply if followed by a necessary ';'.
+nl_after_brace_close                     = false    # false/true
+
+# Whether to put a newline after a virtual brace close.
+# Would add a newline before return in: 'if (foo) a++; return;'
+nl_after_vbrace_close                    = false    # false/true
+
+# Control the newline between the close brace and 'b' in: 'struct { int a; } b;'
+# Affects enums, unions, and structures. If set to ignore, uses nl_after_brace_close
+nl_brace_struct_var                      = ignore   # ignore/add/remove/force
+
+# Whether to alter newlines in '#define' macros
+nl_define_macro                          = false    # false/true
+
+# Whether to not put blanks after '#ifxx', '#elxx', or before '#endif'
+nl_squeeze_ifdef                         = false    # false/true
+
+# Add or remove blank line before 'if'
+nl_before_if                             = ignore   # ignore/add/remove/force
+
+# Add or remove blank line after 'if' statement
+nl_after_if                              = ignore   # ignore/add/remove/force
+
+# Add or remove blank line before 'for'
+nl_before_for                            = ignore   # ignore/add/remove/force
+
+# Add or remove blank line after 'for' statement
+nl_after_for                             = ignore   # ignore/add/remove/force
+
+# Add or remove blank line before 'while'
+nl_before_while                          = ignore   # ignore/add/remove/force
+
+# Add or remove blank line after 'while' statement
+nl_after_while                           = ignore   # ignore/add/remove/force
+
+# Add or remove blank line before 'switch'
+nl_before_switch                         = ignore   # ignore/add/remove/force
+
+# Add or remove blank line after 'switch' statement
+nl_after_switch                          = ignore   # ignore/add/remove/force
+
+# Add or remove blank line before 'do'
+nl_before_do                             = ignore   # ignore/add/remove/force
+
+# Add or remove blank line after 'do/while' statement
+nl_after_do                              = ignore   # ignore/add/remove/force
+
+# Whether to double-space commented-entries in struct/enum
+nl_ds_struct_enum_cmt                    = false    # false/true
+
+# Whether to double-space before the close brace of a struct/union/enum
+# (lower priority than 'eat_blanks_before_close_brace')
+nl_ds_struct_enum_close_brace            = false    # false/true
+
+# Add or remove a newline around a class colon.
+# Related to pos_class_colon, nl_class_init_args, and pos_comma.
+nl_class_colon                           = ignore   # ignore/add/remove/force
+
+# Change simple unbraced if statements into a one-liner
+# 'if(b)\n i++;' => 'if(b) i++;'
+nl_create_if_one_liner                   = false    # false/true
+
+# Change simple unbraced for statements into a one-liner
+# 'for (i=0;i<5;i++)\n foo(i);' => 'for (i=0;i<5;i++) foo(i);'
+nl_create_for_one_liner                  = false    # false/true
+
+# Change simple unbraced while statements into a one-liner
+# 'while (i<5)\n foo(i++);' => 'while (i<5) foo(i++);'
+nl_create_while_one_liner                = false    # false/true
+
+#
+# Positioning options
+#
+
+# The position of arithmetic operators in wrapped expressions
+pos_arith                                = ignore   # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+
+# The position of assignment in wrapped expressions.
+# Do not affect '=' followed by '{'
+pos_assign                               = ignore   # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+
+# The position of boolean operators in wrapped expressions
+pos_bool                                 = ignore   # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+
+# The position of comparison operators in wrapped expressions
+pos_compare                              = ignore   # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+
+# The position of conditional (b ? t : f) operators in wrapped expressions
+pos_conditional                          = ignore   # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+
+# The position of the comma in wrapped expressions
+pos_comma                                = ignore   # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+
+# The position of the comma in the constructor initialization list
+pos_class_comma                          = ignore   # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+
+# The position of colons between constructor and member initialization
+pos_class_colon                          = ignore   # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+
+#
+# Line Splitting options
+#
+
+# Try to limit code width to N number of columns
+code_width                               = 0        # number
+
+# Whether to fully split long 'for' statements at semi-colons
+ls_for_split_full                        = false    # false/true
+
+# Whether to fully split long function protos/calls at commas
+ls_func_split_full                       = false    # false/true
+
+# Whether to split lines as close to code_width as possible and ignore some groupings
+ls_code_width                            = false    # false/true
+
+#
+# Blank line options
+#
+
+# The maximum consecutive newlines
+nl_max                                   = 0        # number
+
+# The number of newlines after a function prototype, if followed by another function prototype
+nl_after_func_proto                      = 0        # number
+
+# The number of newlines after a function prototype, if not followed by another function prototype
+nl_after_func_proto_group                = 0        # number
+
+# The number of newlines after '}' of a multi-line function body
+nl_after_func_body                       = 0        # number
+
+# The number of newlines after '}' of a multi-line function body in a class declaration
+nl_after_func_body_class                 = 0        # number
+
+# The number of newlines after '}' of a single line function body
+nl_after_func_body_one_liner             = 0        # number
+
+# The minimum number of newlines before a multi-line comment.
+# Doesn't apply if after a brace open or another multi-line comment.
+nl_before_block_comment                  = 0        # number
+
+# The minimum number of newlines before a single-line C comment.
+# Doesn't apply if after a brace open or other single-line C comments.
+nl_before_c_comment                      = 0        # number
+
+# The minimum number of newlines before a CPP comment.
+# Doesn't apply if after a brace open or other CPP comments.
+nl_before_cpp_comment                    = 0        # number
+
+# Whether to force a newline after a multi-line comment.
+nl_after_multiline_comment               = false    # false/true
+
+# The number of newlines after '}' or ';' of a struct/enum/union definition
+nl_after_struct                          = 0        # number
+
+# The number of newlines after '}' or ';' of a class definition
+nl_after_class                           = 0        # number
+
+# The number of newlines before a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label.
+# Will not change the newline count if after a brace open.
+# 0 = No change.
+nl_before_access_spec                    = 0        # number
+
+# The number of newlines after a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label.
+# 0 = No change.
+nl_after_access_spec                     = 0        # number
+
+# The number of newlines between a function def and the function comment.
+# 0 = No change.
+nl_comment_func_def                      = 0        # number
+
+# The number of newlines after a try-catch-finally block that isn't followed by a brace close.
+# 0 = No change.
+nl_after_try_catch_finally               = 0        # number
+
+# The number of newlines before and after a property, indexer or event decl.
+# 0 = No change.
+nl_around_cs_property                    = 0        # number
+
+# The number of newlines between the get/set/add/remove handlers in C#.
+# 0 = No change.
+nl_between_get_set                       = 0        # number
+
+# Add or remove newline between C# property and the '{'
+nl_property_brace                        = ignore   # ignore/add/remove/force
+
+# Whether to remove blank lines after '{'
+eat_blanks_after_open_brace              = false    # false/true
+
+# Whether to remove blank lines before '}'
+eat_blanks_before_close_brace            = false    # false/true
+
+# How aggressively to remove extra newlines not in preproc.
+# 0: No change
+# 1: Remove most newlines not handled by other config
+# 2: Remove all newlines and reformat completely by config
+nl_remove_extra_newlines                 = 0        # number
+
+# Whether to put a blank line before 'return' statements, unless after an open brace.
+nl_before_return                         = false    # false/true
+
+# Whether to put a blank line after 'return' statements, unless followed by a close brace.
+nl_after_return                          = false    # false/true
+
+# Whether to put a newline after a Java annotation statement.
+# Only affects annotations that are after a newline.
+nl_after_annotation                      = ignore   # ignore/add/remove/force
+
+# Controls the newline between two annotations.
+nl_between_annotation                    = ignore   # ignore/add/remove/force
+
+#
+# Code modifying options (non-whitespace)
+#
+
+# Add or remove braces on single-line 'do' statement
+mod_full_brace_do                        = ignore   # ignore/add/remove/force
+
+# Add or remove braces on single-line 'for' statement
+mod_full_brace_for                       = ignore   # ignore/add/remove/force
+
+# Add or remove braces on single-line function definitions. (Pawn)
+mod_full_brace_function                  = ignore   # ignore/add/remove/force
+
+# Add or remove braces on single-line 'if' statement. Will not remove the braces if they contain an 'else'.
+mod_full_brace_if                        = ignore   # ignore/add/remove/force
+
+# Make all if/elseif/else statements in a chain be braced or not. Overrides mod_full_brace_if.
+# If any must be braced, they are all braced.  If all can be unbraced, then the braces are removed.
+mod_full_brace_if_chain                  = false    # false/true
+
+# Don't remove braces around statements that span N newlines
+mod_full_brace_nl                        = 0        # number
+
+# Add or remove braces on single-line 'while' statement
+mod_full_brace_while                     = ignore   # ignore/add/remove/force
+
+# Add or remove braces on single-line 'using ()' statement
+mod_full_brace_using                     = ignore   # ignore/add/remove/force
+
+# Add or remove unnecessary paren on 'return' statement
+mod_paren_on_return                      = ignore   # ignore/add/remove/force
+
+# Whether to change optional semicolons to real semicolons
+mod_pawn_semicolon                       = false    # false/true
+
+# Add parens on 'while' and 'if' statement around bools
+mod_full_paren_if_bool                   = false    # false/true
+
+# Whether to remove superfluous semicolons
+mod_remove_extra_semicolon               = false    # false/true
+
+# If a function body exceeds the specified number of newlines and doesn't have a comment after
+# the close brace, a comment will be added.
+mod_add_long_function_closebrace_comment = 0        # number
+
+# If a switch body exceeds the specified number of newlines and doesn't have a comment after
+# the close brace, a comment will be added.
+mod_add_long_switch_closebrace_comment   = 0        # number
+
+# If an #ifdef body exceeds the specified number of newlines and doesn't have a comment after
+# the #endif, a comment will be added.
+mod_add_long_ifdef_endif_comment         = 0        # number
+
+# If an #ifdef or #else body exceeds the specified number of newlines and doesn't have a comment after
+# the #else, a comment will be added.
+mod_add_long_ifdef_else_comment          = 0        # number
+
+# If TRUE, will sort consecutive single-line 'import' statements [Java, D]
+mod_sort_import                          = false    # false/true
+
+# If TRUE, will sort consecutive single-line 'using' statements [C#]
+mod_sort_using                           = false    # false/true
+
+# If TRUE, will sort consecutive single-line '#include' statements [C/C++] and '#import' statements [Obj-C]
+# This is generally a bad idea, as it may break your code.
+mod_sort_include                         = false    # false/true
+
+# If TRUE, it will move a 'break' that appears after a fully braced 'case' before the close brace.
+mod_move_case_break                      = false    # false/true
+
+# Will add or remove the braces around a fully braced case statement.
+# Will only remove the braces if there are no variable declarations in the block.
+mod_case_brace                           = ignore   # ignore/add/remove/force
+
+# If TRUE, it will remove a void 'return;' that appears as the last statement in a function.
+mod_remove_empty_return                  = false    # false/true
+
+#
+# Comment modifications
+#
+
+# Try to wrap comments at cmt_width columns
+cmt_width                                = 0        # number
+
+# Set the comment reflow mode (default: 0)
+# 0: no reflowing (apart from the line wrapping due to cmt_width)
+# 1: no touching at all
+# 2: full reflow
+cmt_reflow_mode                          = 0        # number
+
+# If false, disable all multi-line comment changes, including cmt_width. keyword substitution, and leading chars.
+# Default is true.
+cmt_indent_multi                         = true     # false/true
+
+# Whether to group c-comments that look like they are in a block
+cmt_c_group                              = false    # false/true
+
+# Whether to put an empty '/*' on the first line of the combined c-comment
+cmt_c_nl_start                           = false    # false/true
+
+# Whether to put a newline before the closing '*/' of the combined c-comment
+cmt_c_nl_end                             = false    # false/true
+
+# Whether to group cpp-comments that look like they are in a block
+cmt_cpp_group                            = false    # false/true
+
+# Whether to put an empty '/*' on the first line of the combined cpp-comment
+cmt_cpp_nl_start                         = false    # false/true
+
+# Whether to put a newline before the closing '*/' of the combined cpp-comment
+cmt_cpp_nl_end                           = false    # false/true
+
+# Whether to change cpp-comments into c-comments
+cmt_cpp_to_c                             = false    # false/true
+
+# Whether to put a star on subsequent comment lines
+cmt_star_cont                            = false    # false/true
+
+# The number of spaces to insert at the start of subsequent comment lines
+cmt_sp_before_star_cont                  = 0        # number
+
+# The number of spaces to insert after the star on subsequent comment lines
+cmt_sp_after_star_cont                   = 0        # number
+
+# For multi-line comments with a '*' lead, remove leading spaces if the first and last lines of
+# the comment are the same length. Default=True
+cmt_multi_check_last                     = true     # false/true
+
+# The filename that contains text to insert at the head of a file if the file doesn't start with a C/C++ comment.
+# Will substitute $(filename) with the current file's name.
+cmt_insert_file_header                   = ""         # string
+
+# The filename that contains text to insert at the end of a file if the file doesn't end with a C/C++ comment.
+# Will substitute $(filename) with the current file's name.
+cmt_insert_file_footer                   = ""         # string
+
+# The filename that contains text to insert before a function implementation if the function isn't preceded with a C/C++ comment.
+# Will substitute $(function) with the function name and $(javaparam) with the javadoc @param and @return stuff.
+# Will also substitute $(fclass) with the class name: void CFoo::Bar() { ... }
+cmt_insert_func_header                   = ""         # string
+
+# The filename that contains text to insert before a class if the class isn't preceded with a C/C++ comment.
+# Will substitute $(class) with the class name.
+cmt_insert_class_header                  = ""         # string
+
+# The filename that contains text to insert before a Obj-C message specification if the method isn't preceeded with a C/C++ comment.
+# Will substitute $(message) with the function name and $(javaparam) with the javadoc @param and @return stuff.
+cmt_insert_oc_msg_header                 = ""         # string
+
+# If a preprocessor is encountered when stepping backwards from a function name, then
+# this option decides whether the comment should be inserted.
+# Affects cmt_insert_oc_msg_header, cmt_insert_func_header and cmt_insert_class_header.
+cmt_insert_before_preproc                = false    # false/true
+
+#
+# Preprocessor options
+#
+
+# Control indent of preprocessors inside #if blocks at brace level 0
+pp_indent                                = ignore   # ignore/add/remove/force
+
+# Whether to indent #if/#else/#endif at the brace level (true) or from column 1 (false)
+pp_indent_at_level                       = false    # false/true
+
+# If pp_indent_at_level=false, specifies the number of columns to indent per level. Default=1.
+pp_indent_count                          = 1        # number
+
+# Add or remove space after # based on pp_level of #if blocks
+pp_space                                 = ignore   # ignore/add/remove/force
+
+# Sets the number of spaces added with pp_space
+pp_space_count                           = 0        # number
+
+# The indent for #region and #endregion in C# and '#pragma region' in C/C++
+pp_indent_region                         = 0        # number
+
+# Whether to indent the code between #region and #endregion
+pp_region_indent_code                    = false    # false/true
+
+# If pp_indent_at_level=true, sets the indent for #if, #else, and #endif when not at file-level
+pp_indent_if                             = 0        # number
+
+# Control whether to indent the code between #if, #else and #endif when not at file-level
+pp_if_indent_code                        = false    # false/true
+
+# Whether to indent '#define' at the brace level (true) or from column 1 (false)
+pp_define_at_level                       = false    # false/true
+
+# You can force a token to be a type with the 'type' option.
+# Example:
+# type myfoo1 myfoo2
+#
+# You can create custom macro-based indentation using macro-open,
+# macro-else and macro-close.
+# Example:
+# macro-open  BEGIN_TEMPLATE_MESSAGE_MAP
+# macro-open  BEGIN_MESSAGE_MAP
+# macro-close END_MESSAGE_MAP
+#
+# You can assign any keyword to any type with the set option.
+# set func_call_user _ N_
+#
+# The full syntax description of all custom definition config entries
+# is shown below:
+#
+# define custom tokens as:
+# - embed whitespace in token using '' escape character, or
+#   put token in quotes
+# - these: ' " and ` are recognized as quote delimiters
+#
+# type token1 token2 token3 ...
+#             ^ optionally specify multiple tokens on a single line
+# define def_token output_token
+#                  ^ output_token is optional, then NULL is assumed
+# macro-open token
+# macro-close token
+# macro-else token
+# set id token1 token2 ...
+#               ^ optionally specify multiple tokens on a single line
+#     ^ id is one of the names in token_enum.h sans the CT_ prefix,
+#       e.g. PP_PRAGMA
+#
+# all tokens are separated by any mix of ',' commas, '=' equal signs
+# and whitespace (space, tab)
+#
diff --git a/CHANGELOG b/CHANGELOG
new file mode 100644
index 0000000..b24cf43
--- /dev/null
+++ b/CHANGELOG
@@ -0,0 +1,3 @@
+## New in 0.07.00
+
+* Initial Open-Source Release.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..f50e5f2
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,37 @@
+Contributing to wpantund
+========================
+
+Want to contribute? Great! First, read this page (including the small
+print at the end).
+
+### Before you contribute ###
+
+Before we can use your code, you must sign the [Google Individual
+Contributor License Agreement][CLA-INDI] (CLA), which you can do
+online. The CLA is necessary mainly because you own the copyright to
+your changes, even after your contribution becomes part of our
+codebase, so we need your permission to use and distribute your code.
+We also need to be sure of various other things—for instance that
+you'll tell us if you know that your code infringes on other people's
+patents. You don't have to sign the CLA until after you've submitted
+your code for review and a member has approved it, but you must do it
+before we can put your code into our codebase. Before you start
+working on a larger contribution, you should get in touch with us
+first through the issue tracker with your idea so that we can help out
+and possibly guide you. Coordinating up front makes it much easier to
+avoid frustration later on.
+
+[CLA-INDI]: https://cla.developers.google.com/about/google-individual
+
+### Code reviews ###
+
+All submissions, including submissions by project members, require
+review. We use Github pull requests for this purpose.
+
+### The small print ###
+
+Contributions made by corporations are covered by a different
+agreement than the one above, the [Software Grant and Corporate
+Contributor License Agreement][CLA-CORP].
+
+[CLA-CORP]: https://cla.developers.google.com/about/google-corporate
diff --git a/HACKING.md b/HACKING.md
new file mode 100644
index 0000000..520977a
--- /dev/null
+++ b/HACKING.md
@@ -0,0 +1,56 @@
+Hacking wpantund
+================
+
+## Prerequisite Knowledge ##
+
+The wpantund project makes heavy use of the following:
+
+* [Protothreads](http://dunkels.com/adam/pt/)
+* [`boost::any`](http://www.boost.org/doc/libs/1_57_0/doc/html/any.html)
+* [`boost::signals2`](http://www.boost.org/doc/libs/1_51_0/doc/html/signals2.html)
+
+Understanding what these are and how they work are critical to being able to
+successfully work on WPAN Tunnel Driver.
+
+
+## General Project Structure ##
+
+There are give types of code in this project:
+
+1.  Third-party code - Always contained in the `third_party`
+    directory.
+2.  Separable Utilities - There are stand-alone utilities that are
+    generally useful and may be easily used by other projects. These
+    are in the `src/utils` directory.
+3.  Fundamental Utilities - These are utilitity classes and functions
+    which are specific to WPAN Tunnel Driver, but used by both
+    application-specific and modem-specific classes. These can be
+    found in `src/utils` and `src/wpantund`.
+4.  Application Specific - There are classes which define the basic
+    structure of the application. These are found in `src/wpantund`.
+5.  Modem Specific - These are classes that are specific to individual
+    NCP implementations. These are found in specific subdirectories.
+    For example, `src/ncp-spinel`.
+
+There are three primary application-level virtual base classes in
+wpantund:
+
+ *  `NCPControlInterface`
+ *  `NCPInstance`
+ *  `IPCServer`
+
+The `NCPControlInterface` is the interface through which all
+operations on an NCP are preformed, with the exception of sending and
+receiving packets on the network. For example, if you want to form or
+join a network, you do so via the virtual methods of this class.
+
+The `NCPInstance` class represents a NCP. The methods of this class
+are use by WPAN Tunnel Driver for low-level configuration and setup of
+the NCP. The `NCPInstance` class offers the `NCPControlInterface`
+object which is used to interact with this specific NCP. Generally,
+NCP implementations use this class for setting up the `TUN` interface,
+framing/unframing data and management packets, etc.
+
+The `IPCServer` class exposes the methods from the
+`NCPControlInterface` class via an unspecified IPC mechanism (DBus is
+currently the only sublass implemented).
diff --git a/INSTALL.md b/INSTALL.md
new file mode 100644
index 0000000..8fbe97e
--- /dev/null
+++ b/INSTALL.md
@@ -0,0 +1,247 @@
+`wpantund` Installation Guide
+=============================
+
+This document describes the process of building and installing
+`wpantund` on both Ubuntu and OS X. Installation on other platforms
+may be possible, but are left as an excercise for the reader. This
+document assumes that you are at least casually familiar with
+[Autoconf][1]. It also assumes that you have already gotten a copy of
+the wpantund sources, extracted them, and are wondering what to do
+next.
+
+[1]: http://www.gnu.org/software/autoconf/autoconf.html
+
+
+
+Installing `wpantund` on Ubuntu
+-------------------------------
+
+### 1. Install Dependencies ###
+
+Open up a terminal and perform the following commands:
+
+	sudo apt-get update
+
+	# Install runtine-dependent packages (libreadline is optional)
+	sudo apt-get install dbus libreadline
+
+	# Install build-dependent packages (libreadline-dev is optional)
+	sudo apt-get install gcc g++ libdbus-1-dev libboost-dev libreadline-dev
+
+### 2. Configure and build the project ###
+
+If the `configure` script is not already present in the root directory
+of your `wpantund` sources (which it should be if you got these
+sources from a tarball), you will need to either grab one of the `full/*`
+tags from the official git repository or run the bootstrap script.
+
+#### 2.1. Grabbing a full tag from Git ####
+
+The most likely thing you want to build is the latest stable release.
+In that case, all you need to do is checkout the tag `full/latest-release`:
+
+    git checkout full/latest-release
+
+And you should then be ready to build configure. Jump to section 2.3.
+
+#### 2.2. Running the bootstrap script  ####
+
+Alternatively, you can *bootstrap* the project directly by doing the
+following:
+
+    sudo apt-get install libtool autoconf autoconf-archive
+    ./bootstrap.sh
+
+#### 2.3. Running the configure script  ####
+
+If the `configure` script is present, run it and them start the make
+process:
+
+    ./configure --sysconfdir=/etc
+    make
+
+This may take a while. You can speed up the process by adding the
+argument `-j4` to the call to `make`, substituting the number `4` with
+the number of processor cores you have on your machine. This greatly
+improves the speed of builds.
+
+Also, if additional debugging information is required or helpful from
+`wpantund`, add the argument `--enable-debug` to the `./configure`
+line above.
+
+### 3. Install `wpantund` ###
+
+Once the build above is complete, execute the following command:
+
+    sudo make install
+
+This will install `wpantund` onto your computer.
+
+Installing `wpantund` on OS X
+-----------------------------
+
+Installing `wpantund` on OS X is largely similar to the process above,
+except things are complicated by the fact that we depend on D-Bus—and
+there is no native package manager for OS X. These instructions assume
+that you are using [Homebrew][2] as your package manager.
+
+[2]: http://brew.sh/
+
+What is nice about homebrew is that we have a recipe to build
+`wpantund` for you. This makes installing `wpantund` on OS X as easy
+as:
+
+    brew update
+    brew install ./etc/wpantund.rb
+
+    # Start the D-Bus daemon
+    sudo cp "$(brew --repository)"/Cellar/d-bus/*/org.freedesktop.dbus-session.plist /Library/LaunchDaemons/
+    sudo launchctl load -w /Library/LaunchDaemons/org.freedesktop.dbus-session.plist
+
+(the last two commands are for setting D-Bus up to launch properly at
+startup)
+
+PRO-TIP: Use `brew install wpantund --HEAD` if you want the latest
+bleeding-edge version of wpantund!
+
+However, **if you want to build `wpantund` manually**, the procedure
+described below allows you to manually set up the `wpantund` dependencies
+so that the build can run without a hitch.
+
+### 1. Install Xcode ###
+
+Go [here](http://itunes.apple.com/us/app/xcode/id497799835?ls=1&mt=12)
+and install [Xcode](https://developer.apple.com/xcode/) if you haven't
+already.
+
+After you have installed Xcode, you will need to install the Xcode
+command-line tools. You can do this easily from the command line with
+the following command:
+
+    xcode-select --install
+
+### 2. Install Homebrew ###
+
+[Homebrew](http://brew.sh/) is a package management system for OS X. While
+it is possible to install wpantund's dependencies manually, using
+homebrew makes this process much easier. If you don't already have it
+installed on your Mac, you can install it to your home directory using
+the following instructions:
+
+    cd ~
+    mkdir homebrew && curl -L https://github.com/mxcl/homebrew/tarball/master | tar xz --strip 1 -C homebrew
+    mkdir ~/bin
+
+Create the file `~/.bash_profile` with the following contents (tweak to
+your preference if you know what you're doing):
+
+    # Global stuff
+    export PATH=$HOME/bin:$PATH
+    export EDITOR=vi
+
+    # Homebrew stuff
+    export PATH=$HOME/homebrew/bin:$PATH
+
+Then close and reopen your terminal window.
+
+Alternatively, you can follow the instructions at <http://brew.sh/>, which
+installs to the prefix `/usr/local` instead of `~/homebrew`.
+
+### 2. Install and Setup `wpantund` dependencies ###
+
+We need a few dependencies in order to be able to build and use
+wpantund. The following commands will get us up and running:
+
+	brew install pkg-config
+	brew install autoconf-archive
+	brew install libtool
+	brew install boost
+	brew install d-bus
+
+	# Start the D-Bus daemon
+	sudo cp "$(brew --repository)"/Cellar/d-bus/*/org.freedesktop.dbus-session.plist /Library/LaunchDaemons/
+	sudo launchctl load -w /Library/LaunchDaemons/org.freedesktop.dbus-session.plist
+
+### 3. Configure and build ###
+
+At this point, you can jump over to step 2 from the section
+*Installing `wpantund` on Ubuntu*, above.
+
+
+
+
+Configuring and Using `wpantund`
+-------------------------------
+
+### 1. Configuring `wpantund` ###
+
+Now that you have `wpantund` installed, you will need to edit the
+configuration file to tell the daemon how to communicate with the NCP.
+You do this by editing the `wpantund.conf` file, which (if you
+followed the directions above) should now be at `/etc/wpantund.conf`.
+
+This file is, by default, filled only with comments—which describe
+all of the important configuration options that you might need to set
+in order to make wpantund usable. Read them over and then uncomment
+and update the appropriate configuration properties.
+
+Alternatively, you can specify any needed properties on the command
+line when invoking `wpantund`. At a minimum, at least `NCPSocketName`
+needs to be specified, which describes how `wpantund` is supposed to
+talk to the NCP.
+
+Refer to the authorative documentation in `/etc/wpantund.conf` or
+`./src/wpantund/wpantund.conf` for more information.
+
+### 2. Start wpantund ###
+
+To connect to an NCP on the serial port `/dev/ttyUSB0`, type the
+following into terminal:
+
+    sudo /usr/local/sbin/wpantund -o NCPSocketName /dev/ttyUSB0
+
+To start wpan on more than one interface, you can specify the WPAN
+interface name. For example, to set `wpan0` network interface on
+`/dev/ttyUSB0` USB interface, and `wpan1` on `/dev/ttyUSB1`, run:
+
+    sudo /usr/local/sbin/wpantund -o NCPSocketName /dev/ttyUSB0 -o WPANInterfaceName wpan0
+
+and
+
+    sudo /usr/local/sbin/wpantund -o NCPSocketName /dev/ttyUSB1 -o WPANInterfaceName wpan1
+
+Note that, unless you are running as root, you *must* use `sudo` when
+invoking `wpantund` directly.
+
+On an embedded device, you would add the appropriate scripts or
+configuration files that would cause `wpantund` to be started at boot.
+Doing so should be pretty straightforward.
+
+### 3. Using `wpanctl` ###
+
+Now that you have `wpantund` running, you can now issue commands to
+the daemon using `wpanctl` from another window: (Again, unless you are
+running as root, you *must* use `sudo`)
+
+    $ sudo /usr/local/bin/wpanctl
+    wpanctl:wpan0> leave
+    Leaving current WPAN. . .
+    wpanctl:wpan0> setprop NetworkKey --data 000102030405060708090a0b0c0d0e0f
+    wpanctl:wpan0> form "MyCoolNetwork" -c 26
+    Forming WPAN "MyCoolNetwork" as node type 2
+    Successfully formed!
+    wpanctl:wpan0> permit-join 3600 22
+    Permitting Joining on the current WPAN for 3600 seconds, commissioning traffic on TCP/UDP port 22. . .
+    wpanctl:wpan0> status
+    wpan0 => [
+        "AssociationState" => "joined"
+        "NetworkName" => "MyCoolNetwork"
+        "XPanId" => 0xD6D8A04025AB3B0C
+        "PanId" => 0xE3C3
+        "Channel" => 26
+        "AllowingJoin" => true
+        "Prefix" => [FDD6D8A040250000]
+        "NCPVersion" => "OpenThread/1.0d26-25-gb684c7f; DEBUG; May 9 2016 18:22:04"
+        "HWAddr" => [18B430000003F202]
+    ]
+    wpanctl:wpan0>
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..4b872bb
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,71 @@
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+AUTOMAKE_OPTIONS = foreign
+ACLOCAL_AMFLAGS = -I m4
+DIST_TARGETS = dist-gzip dist-bzip2
+DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2
+AM_DISTCHECK_CONFIGURE_FLAGS = --enable-all-restricted-plugins
+
+SUBDIRS =                              \
+	src                                \
+	doc                                \
+	third_party                        \
+	$(NULL)
+
+DISTCLEANFILES =                       \
+	config.log                         \
+	config.status                      \
+	Makefile                           \
+	libtool                            \
+	make.out                           \
+	$(distdir).tar.*                   \
+	$(NULL)
+
+EXTRA_DIST =                           \
+	.default-version                   \
+	.gitignore                         \
+	.uncrustify.cfg                    \
+	bootstrap.sh                       \
+	README.md                          \
+	TODO.md                            \
+	HACKING.md                         \
+	LICENSE                            \
+	CHANGELOG                          \
+	CONTRIBUTING.md                    \
+	INSTALL.md                         \
+	doxygen.cfg.in                     \
+	etc/Dockerfile                     \
+	etc/build-in-docker.sh             \
+	etc/run-in-docker.sh               \
+	etc/wpantund.rb                    \
+	etc/autoandr/autoandr              \
+	m4/nl.m4                           \
+	$(NULL)
+
+
+
+HASH_VERSION = $(shell                                                   \
+	git describe --dirty --match __poison__ --always 2> /dev/null        \
+)
+
+EXTRA_VERSION = $(shell                                                  \
+	git describe --all --contains 54e116add1f093663e047f88dac18b4851589483 1> /dev/null 2> /dev/null \
+		&& (test "`git describe 2> /dev/null | sed 's:^full/::'`" = $(VERSION) || echo -g$(HASH_VERSION))  \
+)
+
+distdir = $(PACKAGE)-$(VERSION)$(EXTRA_VERSION)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..84ad629
--- /dev/null
+++ b/README.md
@@ -0,0 +1,205 @@
+wpantund, Userspace WPAN Network Daemon
+=======================================
+
+`wpantund` is a user-space network interface driver/daemon that
+provides a native IPv6 network interface to a low-power wireless
+**Network Co-Processor** (or *NCP*). It was written and developed by
+Nest Labs to make supporting [Thread](http://threadgroup.org)
+connectivity on Unix-like operating systems more straightforward.
+
+`wpantund` is designed to marshall all access to the NCP, ensuring
+that it always remains in a consistent and well-defined state.
+
+This is not an official Google product.
+
+## Feature and Architecture Summary ##
+
+`wpantund` provides:
+
+ *  ... a native IPv6 interface to an NCP.
+ *  ... a command line interface (`wpanctl`) for managing and
+    configuring the NCP.
+ *  ... a DBus API for managing and configuring the NCP.
+ *  ... a way to reliably manage the power state of the NCP.
+ *  ... a uniform mechanism for handling NCP firmware updates.
+
+The architecture and design of `wpantund` has been motivated by the
+following design goals (in no specific order):
+
+ *  Portability across Unix-like operating systems (currently supports
+    Linux and OS X. BSD support should be fairly trivial to add)
+ *  Require few runtime dependencies (DBus, with boost needed when
+    building)
+ *  Single-threaded architecture, with heavy use of asynchronous I/O
+ *  Power efficiency (0% CPU usage when idle)
+ *  Allow management interface to be used by multiple independent
+    applications simultaneously
+ *  Allow multiple instances of `wpantund` to gracefully co-exist on a
+    single machine
+ *  Modular, plugin-based architecture (all details for communicating
+    with a specific NCP stack are implemented as plugins)
+
+Note that Windows is not currently supported, but patches are welcome.
+
+The following NCP plugins are provided:
+
+*   `src/ncp-spinel`: Supports NCPs that communicate using the [Spinel NCP
+    Protocol][1], used by NCPs running [OpenThread][2]
+*   `src/ncp-dummy`: A dummy NCP plug-in implementation meant to be the
+    starting point for implementing new NCP plug-ins
+
+[1]: ./third_party/openthread/src/ncp/PROTOCOL.md
+[2]: https://github.com/openthread/openthread/
+
+## License ##
+
+`wpantund` is open-source software released under the [Apache License,
+Version 2.0][3]. See the file [`LICENSE`][4] for more information.
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the [License][4] for the specific language governing permissions and
+limitations under the License.
+
+[3]: http://www.apache.org/licenses/LICENSE-2.0
+[4]: ./LICENSE
+
+## Conceptual Overview ##
+
+`wpantund` is conceptually similar in purpose to the point-to-point
+daemon (`pppd`, commonly used on Unix platforms to provide network
+connectivity via a dial-up modems) except that instead of communicating
+with a dial-up modem, `wpantund` is communicating with an NCP.
+
+`wpantund` communicates with the NCP via an abstraction of a
+asynchronous stream socket, which could be any of the following:
+
+ *  A real serial port (UART) connected to the NCP (preferably with
+    hardware flow control)
+ *  The stdin and stdout from a subprocess (for supporting SPI
+    interfaces using a translator program or debugging virtual
+    stacks)
+ *  A TCP socket (for debugging, not recommended for production)
+
+Unlike a dial-up modem, NCPs often have a rich management interface
+for performing operations, such as forming a network, joining a
+network, scanning for nearby networks, etc. To perform these operations,
+`wpantund` includes a command line utility called `wpanctl`.
+Applications that need to directly configure the network interface can
+also communicate directly with `wpantund` using its DBus API.
+
+To expose a native IPv6 network interface to the host operating
+system, `wpantund` uses the `tun` driver on Linux and the `utun`
+driver on OS X. On Linux, the default name for the interface is
+`wpan0`. On OS X, the default name is `utun0`.
+
+## Usage Overview ##
+
+The behavior of `wpantund` is determined by its configuration
+parameters, which may be specified in a configuration file (typically
+`/etc/wpantund.conf`) or at the command line. A typical configuration
+file might look like that shown below. For a more thorough explanation
+of available configuration parameters, see the [included example][5].
+
+    # Try to name the network interface `wpan0`.
+    # If not possible, a different name will be used.
+    Config:TUN:InterfaceName      "wpan0"
+
+    # The pathname of the socket used to communicate
+    # with the NCP.
+    Config:NCP:SocketPath         "/dev/ttyUSB0"
+
+    # The name of the driver plugin to use. The chosen
+    # plugin must support the NCP you are trying to use.
+    Config:NCP:DriverName         "spinel"
+
+    # Drop root privileges after opening all sockets
+    Config:Daemon:PrivDropToUser  "nobody"
+
+    # Use a CCA Threshold of -70db
+    NCP:CCAThreshold              "-70"
+
+When up and running, you can use `wpanctl` to check the status of the
+interface and perform various management operations. For example, to
+check the general status of an interface:
+
+    $ sudo wpanctl status
+    wpan0 => [
+        "NCP:State" => "offline"
+        "Daemon:Enabled" => true
+        "NCP:Version" => "OPENTHREAD/g1651a47; May 23 2016 17:23:24"
+        "Daemon:Version" => "0.07.00 (May 23 2016 12:58:54)"
+        "Config:NCP:DriverName" => "spinel"
+        "NCP:HardwareAddress" => [F1D92A82C8D8FE43]
+    ]
+
+Here we see that the NCP is in the `offline` state along with a few
+additional bits of information such as the version of the NCP and its
+hardware address. From here we can easily form a new network:
+
+    $ sudo wpanctl form "wpantund-testnet"
+    Forming WPAN "wpantund-testnet" as node type router
+    Successfully formed!
+    $
+
+Now if we check the status, we will see more information:
+
+    $ sudo wpanctl status
+    wpan0 => [
+        "NCP:State" => "associated"
+        "Daemon:Enabled" => true
+        "NCP:Version" => "OPENTHREAD/g1651a47; May 23 2016 17:23:24"
+        "Daemon:Version" => "0.07.00 (May 23 2016 12:58:54)"
+        "Config:NCP:DriverName" => "spinel"
+        "NCP:HardwareAddress" => [F1D92A82C8D8FE43]
+        "NCP:Channel" => 23
+        "Network:NodeType" => "leader"
+        "Network:Name" => "wpantund-testnet"
+        "Network:XPANID" => 0x09717AEF221F66FB
+        "Network:PANID" => 0xBFCD
+        "IPv6:LinkLocalAddress" => "fe80::f3d9:2a82:c8d8:fe43"
+        "IPv6:MeshLocalAddress" => "fd09:717a:ef22::9a5d:5d1e:5527:5fc8"
+        "IPv6:MeshLocalPrefix" => "fd09:717a:ef22::/64"
+    ]
+    $ ifconfig wpan0
+    wpan0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1280
+        inet6 fe80::f3d9:2a82:c8d8:fe43%wpan0 prefixlen 10 scopeid 0x15
+        inet6 fd09:717a:ef22::9a5d:5d1e:5527:5fc8 prefixlen 64
+
+If compiled with `libreadline` or `libedit`, `wpanctl` supports an
+convenient interactive console. All commands support online help: type
+`help` to get a list of supported commands, or add `-h` to a command to get
+help with that specific command.
+
+For more information, see the wiki: <https://github.com/openthread/wpantund/wiki>
+
+[5]: ./src/wpantund/wpantund.conf
+
+## Support ##
+
+Submit bugs and feature requests to [issue tracker][6]. We use the
+following mailing lists for discussion and announcements:
+
+ *  [wpantund-announce](https://groups.google.com/forum/#!forum/wpantund-announce)
+    \- Official Anouncements About `wpantund`
+ *  [wpantund-users](https://groups.google.com/forum/#!forum/wpantund-users)
+    \- `wpantund` User Discussion Group
+ *  [wpantund-devel](https://groups.google.com/forum/#!forum/wpantund-devel)
+    \- `wpantund` Developer Discussion Group
+
+[6]: https://github.com/openthread/wpantund/issues
+
+## Authors and Contributors ##
+
+The following people have significantly contributed to the design
+and development of `wpantund`:
+
+ *  Robert Quattlebaum
+ *  Marcin Szczodrak
+ *  Vaas Krishnamurthy
+ *  Arjuna Siva
+ *  Abtin Keshavarzian
+
+If you would like to contribute to this project, please read
+[CONTRIBUTING.md](CONTRIBUTING.md) first.
diff --git a/TODO.md b/TODO.md
new file mode 100644
index 0000000..8ce3b26
--- /dev/null
+++ b/TODO.md
@@ -0,0 +1,35 @@
+TODO LIST
+=========
+
+This document describes various tasks and features that are wanted or
+in-progress.
+
+General Cleanup/Refactoring Tasks
+---------------------------------
+
+### Finish DBusv1 API and move `wpanctl` to use it ###
+
+The new DBusv1 API is all but complete, but we still need to move a
+few methods in `wpanctl` over to use the new API. We also need to add
+the DBusv1 API equivalent for the `GetInterfaces` method, which is
+currently only in the V0 API.
+
+
+
+Security Tasks
+--------------
+
+Since WPAN Tunnel Driver communicates directly with the dangerous
+uncontrolled real-world, additional hardening is warranted. The
+following tasks are important for hardening `wpantund` from malicious foes:
+
+ *  Investigate ways to harden the process by Limiting kernel attackable
+    surface-area by using a syscall filter like [`libseccomp`](https://github.com/seccomp/libseccomp).
+ *  Full security audit of code paths which directly interpret data
+    from the NCP. Should be performed after the refactoring described
+    above.
+
+Wanted Features/Tasks
+---------------------
+
+ *  Provide more behavioral logic in the `NCPInstanceBase` class.
diff --git a/bootstrap.sh b/bootstrap.sh
new file mode 100755
index 0000000..5074de6
--- /dev/null
+++ b/bootstrap.sh
@@ -0,0 +1,128 @@
+#!/bin/sh
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOGFILE=`mktemp -q /tmp/bootstrap.log.XXXXXX`
+BOOTSTRAP_ANDROID=0
+BOOTSTRAP_AUTOTOOLS=1
+SOURCE_DIR=$(cd `dirname $0` && pwd)
+AUTOANDR=${AUTOANDR-${SOURCE_DIR}/etc/autoandr/autoandr}
+AUTOMAKE="automake --foreign"
+
+die() {
+	local errcode=$?
+	local prog=$1
+	shift
+
+	echo " ***************************** "
+
+	[[ $prog == "autoreconf" ]] && cat "$LOGFILE"
+
+	echo ""
+	if [[ $# -ge 1 ]]
+	then echo " *** $prog failed: \"$*\""
+	else echo " *** $prog failed with error code $errcode"
+	fi
+
+	exit 1
+}
+
+while [ "$#" -ge 1 ]
+do
+	case $1 in
+		--all)
+			BOOTSTRAP_ANDROID=1
+			BOOTSTRAP_AUTOTOOLS=1
+			;;
+
+		--android)
+			BOOTSTRAP_ANDROID=1
+			BOOTSTRAP_AUTOTOOLS=0
+			;;
+
+		--verbose)
+			LOGFILE=/dev/stderr
+			export V=1
+			;;
+
+		*)
+			die bootstrap "Unknown argument: $1"
+			;;
+	esac
+	shift
+done
+
+
+if [ "$BOOTSTRAP_AUTOTOOLS" = 1 ]
+then
+	cd "${SOURCE_DIR}"
+
+	which autoreconf 1>/dev/null 2>&1 || {
+		echo " *** error: The 'autoreconf' command was not found."
+		echo "Use the appropriate command for your platform to install the package:"
+		echo ""
+		echo "Homebrew(OS X) ....... brew install libtool autoconf autoconf-archive"
+		echo "Debian/Ubuntu ........ apt-get install libtool autoconf autoconf-archive"
+		exit 1
+	}
+
+	autoreconf --verbose --force --install 2>"$LOGFILE" || die autoreconf
+
+	grep -q AX_CHECK_ configure && {
+		echo " *** error: The 'autoconf-archive' package is not installed."
+		echo "Use the appropriate command for your platform to install the package:"
+		echo ""
+		echo "Homebrew(OS X) ....... brew install autoconf-archive"
+		echo "Debian/Ubuntu ........ apt-get install autoconf-archive"
+		exit 1
+	}
+fi
+
+if [ "$BOOTSTRAP_ANDROID" = 1 ]
+then
+	cd "${SOURCE_DIR}"
+
+	AUTOANDR_STDOUT="$LOGFILE" \
+	AUTOANDR_MODULE_TAGS=optional \
+	$AUTOANDR start \
+		--disable-option-checking \
+		--enable-static-link-ncp-plugin \
+		--disable-shared \
+		--prefix=/system \
+		--localstatedir=/data/misc \
+		--bindir=/system/bin \
+		--sbindir=/system/bin \
+		--libexecdir=/system/bin \
+		--libdir=/system/lib \
+		--includedir=/system/include \
+		--oldincludedir=/system/include \
+		--enable-debug=verbose \
+		CXXFLAGS="-fexceptions -Wno-non-virtual-dtor -frtti -Wno-c++11-narrowing" \
+		CPPFLAGS="-Wno-date-time -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare" \
+		DBUS_CFLAGS="-Iexternal/dbus" \
+		DBUS_LIBS="-ldbus" \
+		TUNNEL_TUNTAP_DEVICE="/dev/tun" \
+		SOCKET_UTILS_DEFAULT_SHELL="/system/bin/sh" \
+		ac_cv_func_getdtablesize=no \
+		ac_cv_func_fgetln=no \
+		ac_cv_header_util_h=no \
+		--with-boost=internal \
+	|| die autoandr
+fi
+
+echo
+echo Success. Logs in '"'$LOGFILE'"'
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..3f1f033
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,336 @@
+dnl #
+dnl # Copyright (c) 2016 Nest Labs, Inc.
+dnl # All rights reserved.
+dnl #
+dnl # Licensed under the Apache License, Version 2.0 (the "License");
+dnl # you may not use this file except in compliance with the License.
+dnl # You may obtain a copy of the License at
+dnl #
+dnl #    http://www.apache.org/licenses/LICENSE-2.0
+dnl #
+dnl # Unless required by applicable law or agreed to in writing, software
+dnl # distributed under the License is distributed on an "AS IS" BASIS,
+dnl # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl # See the License for the specific language governing permissions and
+dnl # limitations under the License.
+dnl #
+
+AC_PREREQ(2.59)
+
+dnl This is the project name and release verison number.
+dnl The release version is stored in the file `.default-version`.
+dnl Update that file *after* every release to indicate the version
+dnl of the *next* anticipated release.
+AC_INIT(
+	[wpantund],
+	m4_esyscmd([printf "%s" `cat .default-version`]),
+	[wpantund-devel@googlegroups.com],
+	[wpantund],
+	[https://github.com/openthread/wpantund/]dnl
+)
+
+dnl These are the list of plugins that have usage restrictions
+dnl associated with their license. These will be automatically
+dnl disabled by default and print out a warning when enabled.
+m4_define(RESTRICTED_USE_NCP_PLUGINS, [  dnl
+])
+
+dnl This is the list of plugins which are included with wpantund.
+dnl As plugins are added, they should be appended to this list.
+m4_define(AVAILABLE_NCP_PLUGINS, [       dnl
+	RESTRICTED_USE_NCP_PLUGINS           dnl
+	spinel                               dnl
+	dummy                                dnl
+])
+
+dnl These are the list of plugins are disabled by default.
+dnl This list automatically includes the plugins from
+dnl RESTRICTED_USE_NCP_PLUGINS.
+m4_define(DISABLED_NCP_PLUGINS, [RESTRICTED_USE_NCP_PLUGINS])
+
+dnl Attempt to include a reasonable git tag description.
+SOURCE_VERSION=m4_esyscmd([
+	configver="$PACKAGE_VERSION"
+	(test -d .git && gitver=`git describe --dirty --match "[0-9].*"` && printf "$gitver") ||
+	(test -d .git && gitver=`git describe --always` && printf "$configver-g$gitver") ||
+	printf "$configver"
+])
+
+AC_CONFIG_AUX_DIR([m4])
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_FILES(Makefile doxygen.cfg src/Makefile doc/Makefile src/connman-plugin/Makefile src/ipc-dbus/Makefile src/wpanctl/Makefile src/wpantund/Makefile src/util/Makefile src/scripts/Makefile third_party/Makefile)
+
+# Set up AC_CONFIG_FILES for all of the available plugins.
+AC_CONFIG_FILES(m4_normalize(m4_foreach_w(THIS_PLUGIN,AVAILABLE_NCP_PLUGINS,[src/ncp-[]THIS_PLUGIN/Makefile ])))
+
+
+PLUGIN_SUBDIRS="[]m4_foreach_w(THIS_PLUGIN,AVAILABLE_NCP_PLUGINS,ncp-[]THIS_PLUGIN )"
+AC_SUBST(PLUGIN_SUBDIRS)
+
+AM_INIT_AUTOMAKE()
+
+AM_MAINTAINER_MODE
+
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+m4_ifdef([AX_CODE_COVERAGE], [AX_CODE_COVERAGE], [AC_SUBST([CODE_COVERAGE_RULES])])
+
+LT_INIT
+
+AC_LIBTOOL_DLOPEN_SELF
+
+AC_PROG_LIBTOOL
+
+AC_CONFIG_SRCDIR([src/version.h])
+AC_CONFIG_HEADERS([src/config.h])
+
+# This varable is for defining the default NCP plugin.
+# This is the default value, which can be overridden below.
+default_ncp_plugin=none
+
+dnl Add --enable/--disable configure arguments for all the available plugins.
+m4_foreach_w(THIS_PLUGIN,AVAILABLE_NCP_PLUGINS,[
+	m4_define([THIS_PLUGIN_DISABLED],m4_foreach_w(THAT_PLUGIN,DISABLED_NCP_PLUGINS,[m4_if(THIS_PLUGIN,THAT_PLUGIN,[disabled])]))
+
+	AC_ARG_ENABLE(
+		ncp-[]m4_translit(THIS_PLUGIN,[_],[-]),
+		AC_HELP_STRING(
+			[--[]m4_if(THIS_PLUGIN_DISABLED,[disabled],[enable],[disable])-ncp-[]m4_translit(THIS_PLUGIN,[_],[-])],
+			m4_do([[]m4_if(THIS_PLUGIN_DISABLED,[disabled],[enable],[disable]) the NCP plugin "],[THIS_PLUGIN],["])
+		),
+		[
+			if test "x$enableval" = "xdefault"
+			then
+				default_ncp_plugin=[]THIS_PLUGIN
+				enable_ncp_[]THIS_PLUGIN=yes
+			fi
+		],
+		[m4_if(THIS_PLUGIN_DISABLED,[disabled],[true],[enable_ncp_[]THIS_PLUGIN=yes])],
+	)
+])
+
+AC_ARG_ENABLE(
+	all-restricted-plugins,
+	AC_HELP_STRING(
+		[--enable-all-restricted-plugins],
+		[Enable all plugins with restrictive licenses]
+	)
+)
+
+AC_ARG_ENABLE(
+	static-link-ncp-plugin,
+	AC_HELP_STRING(
+		[--enable-static-link-ncp-plugin=[plugin]],
+		[Statically link against a single NCP plugin]
+	),
+	[],
+	[
+		if test "x$enable_shared" == "xno"
+		then enable_static_link_ncp_plugin=yes
+		fi
+	]
+)
+
+if test "x$enable_all_restricted_plugins" = "xyes"
+then {
+true
+m4_foreach_w(THIS_PLUGIN,RESTRICTED_USE_NCP_PLUGINS,
+[	if test "x$enable_ncp_[]m4_translit(THIS_PLUGIN,[-],[_])" = "x"
+	then enable_ncp_[]m4_translit(THIS_PLUGIN,[-],[_])="yes"
+	fi
+])}
+fi
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+test "x$pkglibexecdir" = x && pkglibexecdir='${libexecdir}/${PACKAGE_TARNAME}'
+
+AC_DEFINE_UNQUOTED([PREFIX], ["`eval echo "$prefix"`"], [Define to the install prefix])
+AC_DEFINE_UNQUOTED([SYSCONFDIR], ["`eval echo "$sysconfdir"`"], [Define to the sub-directory for system settings.])
+AC_DEFINE_UNQUOTED([PKGLIBEXECDIR], ["`eval eval eval echo "$pkglibexecdir"`"], [Define to the sub-directory for plugins.])
+
+AC_DEFINE_UNQUOTED([SOURCE_VERSION], ["`eval echo "$SOURCE_VERSION"`"], [Source version])
+
+if test "${TUNNEL_TUNTAP_DEVICE+set}" = "set"
+then AC_DEFINE_UNQUOTED([TUNNEL_TUNTAP_DEVICE], ["$TUNNEL_TUNTAP_DEVICE"], [Path to tuntap device])
+fi
+if test "${SOCKET_UTILS_DEFAULT_SHELL+set}" = "set"
+then AC_DEFINE_UNQUOTED([SOCKET_UTILS_DEFAULT_SHELL], ["$SOCKET_UTILS_DEFAULT_SHELL"], [Default path to a shell])
+fi
+
+AC_PROG_CC([],AC_MSG_ERROR(["A working C compiler is required"]))
+AC_PROG_CXX([],AC_MSG_ERROR(["A working C++ compiler is required"]))
+
+AC_HEADER_STDC
+AC_HEADER_TIME
+
+AC_CHECK_HEADERS([unistd.h errno.h stdbool.h], [], AC_MSG_ERROR(["Missing a required header."]))
+
+AC_CHECK_HEADERS([sys/un.h sys/wait.h pty.h pwd.h execinfo.h asm/sigcontext.h sys/prctl.h])
+
+AC_C_CONST
+AC_TYPE_SIZE_T
+AC_TYPE_SSIZE_T
+
+AC_C_INLINE
+AC_C_VOLATILE
+
+dnl Raspberry Pi's clock_gettime() function is in librt.
+dnl This should only pick it up if necessary.
+AC_SEARCH_LIBS([clock_gettime], [rt])
+AC_CHECK_FUNCS([clock_gettime])
+
+AC_CHECK_FUNCS([alloca fgetln memcmp memset strtol strdup strndup strlcpy strlcat stpncpy vsnprintf vsprintf snprintf getdtablesize getloadavg])
+
+NL_DEBUG
+NL_CHECK_DBUS
+NL_CHECK_BOOST_SIGNALS2([],AC_MSG_ERROR([Unable to find a usable implementation of boost::signals2 (not even our internal copy)]))
+NL_CHECK_READLINE
+NL_CHECK_PTS
+
+AC_DEFINE_UNQUOTED([__STDC_LIMIT_MACROS], [1], [Needed by C++])
+AC_DEFINE_UNQUOTED([__STDC_CONSTANT_MACROS], [1], [Needed by C++])
+
+AC_DEFINE_UNQUOTED([ASSERT_MACROS_USE_SYSLOG], 1, [Define to 1 to have assertmacros.h use syslog])
+AC_DEFINE_UNQUOTED([ASSERT_MACROS_SQUELCH], 0, [Define to 0 to explicitly prevent squelching assert printouts])
+
+NL_CHECK_CONNMAN([
+	NL_CHECK_GLIB(
+		[],
+		AC_MSG_ERROR(["Found ConnMan headers, but couldn't find GLIB"])
+	)
+])
+AM_CONDITIONAL([BUILD_CONNMAN_PLUGIN],[test "x${with_connman}" = "xyes"])
+
+
+AM_CONDITIONAL([HOST_IS_LINUX],[(case "${host_os}" in *linux*) true ;; *) false ;; esac)])
+
+building_ncp_plugins=""
+
+m4_foreach_w(THIS_PLUGIN,AVAILABLE_NCP_PLUGINS,[
+	if test "x${enable_ncp_[]m4_translit(THIS_PLUGIN,[-],[_])}" = "xyes"
+	then building_ncp_plugins=`echo ${building_ncp_plugins} []THIS_PLUGIN`
+	fi
+])
+
+if test "x$building_ncp_plugins" != "x"
+then
+	if test "x$default_ncp_plugin" = "xnone"
+	then default_ncp_plugin=$(IFS=" " ; set -- $building_ncp_plugins ; echo $1)
+	fi
+fi
+
+if test "x${enable_static_link_ncp_plugin-no}" != "xno"
+then {
+	if test "x${enable_static_link_ncp_plugin-no}" != "xyes"
+	then {
+		# TODO: Extract statically linked plugin here, make sure it is enabled.
+		default_ncp_plugin=${enable_static_link_ncp_plugin}
+		enable_static_link_ncp_plugin=yes
+	} fi
+
+	if test "x${default_ncp_plugin-none}" = "xnone"
+	then AC_MSG_ERROR(["You must enable one NCP plugin when statically linking"])
+	fi
+
+	building_ncp_plugins=${default_ncp_plugin}
+
+	m4_foreach_w(THIS_PLUGIN,AVAILABLE_NCP_PLUGINS,[
+		if test "[]THIS_PLUGIN" != "${default_ncp_plugin}"
+		then enable_ncp_[]m4_translit(THIS_PLUGIN,[-],[_])=no
+		fi
+	])
+
+	AC_DEFINE_UNQUOTED([WPANTUND_PLUGIN_STATICLY_LINKED], [1], [Set to 1 if we are statically linking the plugin/])
+}
+else {
+	NL_CHECK_LIBDL
+	NL_EXPORT_DYNAMIC
+}
+fi
+
+AC_DEFINE_UNQUOTED([WPANTUND_DEFAULT_NCP_PLUGIN], ["${default_ncp_plugin}"], [Set to the name of the default NCP plugin])
+
+AM_CONDITIONAL(STATIC_LINK_NCP_PLUGIN,[test "x${enable_static_link_ncp_plugin}" = "xyes"])
+
+building_ncp_plugins=""
+
+
+m4_foreach_w(THIS_PLUGIN,AVAILABLE_NCP_PLUGINS,[
+	if test "x${enable_ncp_[]m4_translit(THIS_PLUGIN,[-],[_])}" = "xyes"
+	then building_ncp_plugins=`echo ${building_ncp_plugins} []THIS_PLUGIN`
+	fi
+
+	m4_ifdef([m4_do(WPANTUND_PLUGIN_NCP_[]m4_toupper(m4_translit(THIS_PLUGIN,[-],[_]))],
+		[WPANTUND_PLUGIN_NCP_[]m4_toupper(m4_translit(THIS_PLUGIN,[-],[_])]
+	)
+
+	AM_CONDITIONAL(BUILD_PLUGIN_NCP_[]m4_toupper(m4_translit(THIS_PLUGIN,[-],[_])),[test "x${enable_ncp_[]m4_translit(THIS_PLUGIN,[-],[_])}" = "xyes"])
+])
+
+m4_foreach_w(THIS_PLUGIN,RESTRICTED_USE_NCP_PLUGINS,[
+	if test "x${enable_ncp_[]m4_translit(THIS_PLUGIN,[-],[_])}" = "xyes"
+	then restricted_use_ncp_plugins=`echo ${restricted_use_ncp_plugins} []THIS_PLUGIN`
+	fi
+])
+
+AC_SUBST(default_ncp_plugin)
+
+AC_OUTPUT
+
+echo ""
+echo "= Summary ====================================================================="
+echo ""
+echo "ConnMan Plugin ................. ${with_connman-no}"
+echo "Using libreadline .............. ${with_readline-???}"
+echo "Boost .......................... ${with_boost-???}"
+echo "NCP plugins to build ........... ${building_ncp_plugins-none}"
+echo "Default NCP Plugin ............. ${default_ncp_plugin}"
+echo "Static link NCP plugin ......... ${enable_static_link_ncp_plugin-no}"
+echo ""
+
+if test "x${with_readline}" != "xyes"
+then {
+	echo "warning: libreadline was disabled or not found, interactive"
+	echo "         wpanctl command line interface will not be enabled!"
+	echo ""
+}
+fi
+
+if test "x$restricted_use_ncp_plugins" != "x"
+then {
+	echo "ATTENTION: Some of the plugins you are building have proprietary licenses which"
+	echo "           are more restrictive than the Apache 2.0 license that covers wpantund"
+	echo "           in general. If you are reading this message, it means you have manually"
+	echo "           enabled at least one plug-in that has a proprietary license. Please"
+	echo "           make sure that you understand the usage restrictions before using"
+	echo "           wpantund with these plugins: "
+	echo ""
+	echo "           $restricted_use_ncp_plugins"
+	echo ""
+}
+fi
+
+if test "x$building_ncp_plugins" = "x"
+then {
+	echo " *** WARNING: The current configuration is NOT BUILDING ANY PLUGINS! wpantund won't"
+	echo "              be very useful in this state. Note that plugins with proprietary"
+	echo "              licenses are no longer built by default: you must either enable them"
+	echo '              individually (using `--enable-ncp-*` configuration options) or by using'
+	echo '              the `--enable-all-restricted-plugins` configuration option.'
+	echo "              In any case, you can still make and install wpantund without plugins"
+	echo "              if you really know what you are doing."
+	echo ""
+}
+fi
+
+if test "x$building_ncp_plugins" = "xdummy"
+then {
+	echo " *** WARNING: The current configuration is only building the dummy plugin! wpantund"
+	echo "              won't be very useful in this state. Note that plugins with proprietary"
+	echo "              licenses are no longer built by default: you must either enable them"
+	echo '              individually (using `--enable-ncp-*` configuration options) or by using'
+	echo '              the `--enable-all-restricted-plugins` configuration option.'
+	echo ""
+}
+fi
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 0000000..d8d8258
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+man_MANS =                   \
+	wpantund.1               \
+	wpanctl.1                \
+	$(NULL)
+
+EXTRA_DIST =                 \
+	wpantund-oss-plan.md     \
+	wpan-dbus-protocol.md    \
+	wpantund.1               \
+	wpanctl.1                \
+	$(NULL)
diff --git a/doc/wpan-dbus-protocol.md b/doc/wpan-dbus-protocol.md
new file mode 100644
index 0000000..13bf867
--- /dev/null
+++ b/doc/wpan-dbus-protocol.md
@@ -0,0 +1,136 @@
+wpantund DBus Protocol v1
+=========================
+
+This document outlines the DBus protocol used to communicate
+with `wpantund` to manage a low-power wireless network interface.
+
+It is a work in progress.
+
+daemon id: `org.wpantund`
+
+# Interface: `org.wpantund`
+
+## Path `/org/wpantund/`
+
+### Command: `GetInterfaces`
+### Command: `GetVersion`
+### Signal: `InterfaceAdded`
+### Signal: `InterfaceRemoved`
+
+## Path `/org/wpantund/<iface-name>`
+
+### Signal: `NetScanBeacon`
+### Signal: `NetScanComplete`
+
+### Command: `NetScanStart`
+### Command: `NetScanStop`
+
+### Command: `Status`
+### Command: `Reset`
+
+### Command: `BeginLowPower`
+### Command: `HostDidWake`
+
+### Command: `Attach`
+### Command: `Join`
+### Command: `Form`
+### Command: `Leave`
+
+### Command: `ConfigGateway`
+### Command: `DataPoll`
+
+## Path `/org/wpantund/<iface-name>/Properties/<property-name>`
+
+### Signal: "Changed"
+### Command: "Set"
+### Command: "Get"
+
+# Interface: `com.nestlabs.wpantund.internal`
+
+## Path `/org/wpantund/<iface-name>`
+
+### Command: `PermitJoin`
+### Command: `BeginNetWake`
+
+
+
+-------------------------------------------------------------------------------
+
+# Configuration Properties
+
+## `Config:NCP:SocketPath`
+## `Config:NCP:SocketBaud`
+## `Config:NCP:DriverName`
+## `Config:NCP:HardResetPath`
+## `Config:NCP:PowerPath`
+## `Config:NCP:ReliabilityLayer`
+## `Config:NCP:FirmwareCheckCommand`
+## `Config:NCP:FirmwareUpgradeCommand`
+## `Config:TUN:InterfaceName`
+## `Config:Daemon:PIDFile`
+## `Config:Daemon:PrivDropToUser`
+## `Config:Daemon:Chroot`
+
+## `Daemon:Version`
+## `Daemon:Enabled`
+## `Daemon:SyslogMask`
+## `Daemon:TerminateOnFault`
+
+
+## `Daemon:ReadyForHostSleep`
+Read only. Set to `true` if `wpantund` is busy. Set to `false` if it is idle.
+Primarily used for determining if it is a good opportunity to attempt to
+put the host into a low-power state.
+
+## `Daemon:AutoAssociateAfterReset` (Was AutoResume)
+If the NCP persistently stores network association and the NCP
+comes up in the `offline:commissioned` state, this option being set
+will cause `wpantund` to automatiaclly attempt to associate.
+
+## `Daemon:AutoFirmwareUpdate`
+## `Daemon:AutoDeepSleep`
+
+## `NCP:Version`
+## `NCP:State`
+## `NCP:HardwareAddress`
+## `NCP:Channel`
+## `NCP:TXPower`
+## `NCP:TXPowerLimit`
+## `NCP:CCAThreshold`
+## `NCP:DefaultChannelMask`
+## `NCP:SleepyPollInterval`
+
+## `Network:Name`
+## `Network:XPANID`
+## `Network:PANID`
+## `Network:NodeType`
+## `Network:Key`
+## `Network:KeyIndex`
+## `Network:IsAssociated`
+
+## `IPv6:LinkLocalAddress`
+## `IPv6:MeshLocalAddress`
+## `IPv6:AllAddresses`
+
+
+
+
+
+
+
+
+
+# NCP States
+
+## "uninitialized"                  (same)
+## "uninitialized:fault"            (same)
+## "uninitialized:upgrading"        (same)
+## "offline:deep-sleep"             (was "deep-sleep")
+## "offline"                        (was "disconnected")
+## "offline:commissioned"           (was "saved")
+## "associating"                    (was "joining")
+## "associating:credentials-needed" (was "credentials-needed")
+## "associated"                     (was "joined")
+## "associated:no-parent"           (was "joined-no-parent")
+## "associated:netwake-sleeping"    (was "joined-lurking")
+## "associated:netwake-waking"      (was "net-wake")
diff --git a/doc/wpanctl.1 b/doc/wpanctl.1
new file mode 100644
index 0000000..ac4cea2
--- /dev/null
+++ b/doc/wpanctl.1
@@ -0,0 +1,377 @@
+.TH wpanctl 1 "" "" "USER COMMANDS"
+
+.SH NAME
+wpanctl \- command line interfase for wpantund
+
+.SH SYNOPSIS
+.B wpanctl
+[\fIOPTIONS\fR] <\fICOMMANDS\fR> [args]
+
+.SH DESCRIPTION
+.B wpanctl
+is itself a command-line interface. You can specify an individual single command
+directly on the \fBwpanctl\fR command line, or run \fBwpanctl\fR without any arguments
+to enter the command-line interface shell.
+
+.SH OPTIONS
+
+.TP
+\fB\-h\fP, \fB\-\-help\fp
+Print help.
+
+.TP
+\fB\-v\fP, \fB\-\-version\fp
+Print version.
+
+.TP
+\fB\-f\fP \fIFILE
+Read commands from a file.
+
+.TP
+\fB\-I\fP, \fB\-\-interface\fp \fIINTERFACE\fR
+Set interface to use (e.g. wpan0).
+
+.TP
+\fB\-i\fP, \fB\-\-ignore-mismatch\fP
+Ignore driver version mismatch.
+
+.SH COMMANDS
+
+.TP
+\fBbegin-low-power\fR [\fBargs\fR]
+Enter low-power mode.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+.TP
+\fBbegin-net-wake\fR [\fBargs\fR]
+Initiate a network wakeup.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+.TP
+\fBcd\fR
+Change current interface (command mode).
+
+.TP
+\fBconfig-gateway\fR [\fBargs\fR] <\fBPREFIX\fR>
+Configure gateway.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+  \fB\-p\fP, \fB\-\-preferred-lifetime\fR
+  Set the \fBPREFERRED_LIFETIME\fR.
+
+  \fB\-v\fP, \fB\-\-valid-lifetime\fR
+  Set the \fBVALID_LIFETIME\fR.
+
+  \fB\-d\fP, \fB\-\-default\fR
+  Indicates that we can be a default route.
+
+.TP
+\fBform\fR [\fBargs\fR] [\fBNETWORK_NAME\fR]
+Form a new WPAN.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+  \fB\-u\fP, \fB\-\-ula-prefix\fR [\fBULA_PREFIX\fR]
+  Specify a specific ULA prefix.
+
+  \fB\-c\fP, \fB\-\-channel\fR [\fBCHANNEL\fR]
+  Specify a specific radio channel.
+
+.TP
+\fBgetprop\fR, \fBget\fR [\fBargs\fR] <\fBproperty-name\fR>
+Get a property.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+  \fB\-a\fP, \fB\-\-all\fR
+  Print all supported properties.
+
+  \fB\-v\fP, \fB\-\-value-only\fR
+  Print only the value of the property.
+
+.TP
+\fBhelp\fR
+Display help.
+
+.TP
+\fBhost-did-wake\fR [\fBargs\fR]
+Perform any host-wakeup related tasks.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+.TP
+\fBjoin\fR [\fBargs\fR] [\fBNETWORK_NAME\fR]
+Join a WPAN.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+  \fB\-T\fP, \fB\-\-type\fR [\fBNODE_TYPE\fR]
+  Join as a specific node type.
+
+  \fB\-p\fP, \fB\-\-panid\fR [\fBPAN_ID\fR]
+  Specify a specific PAN ID.
+
+  \fB\-x\fP, \fB\-\-xpanid\fR [\fBExtended_PAN_ID\fR]
+  Specify a specific extended PAN ID.
+
+  \fB\-c\fP, \fB\-\-channel\fR [\fBCHANNEL\fR]
+  Specify a specific radio channel.
+
+.TP
+\fBleave\fR [\fBargs\fR]
+Abandon the currently connected WPAN.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+.TP
+\fBlist\fR [\fBargs\fR]
+List available interfaces.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+.TP
+\fBpermit-join\fR [\fBargs\fR] <\fBPERMIT_JOIN_DURATION\fR> [\fBCOMMISSIONING_PORT\fR]
+Permit other devices to join the current network.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+  \fB\-n\fP, \fB\-\-network-wide\fR
+  Permit joining network-wide.
+
+  \fB\-c\fP, \fB\-\-tcp\fR
+  Permit only TCP for commissioning traffic.
+
+  \fB\-d\fP, \fB\-\-udp\fR
+  Permit only UDP for commissioning traffic.
+
+.TP
+\fBping\fR [\fBargs\fR]
+Ping the NCP.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+.TP
+\fBpoll\fR [\fBargs\fR]
+Poll the parent immediately to see if there is IP traffic.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+.TP
+\fBquit\fR
+Terminate command line mode.
+
+.TP
+\fBreset\fR [\fBargs\fR]
+Reset the NCP.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+.TP
+\fBresume\fR [\fBargs\fR]
+Resume a previously connected network.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+.TP
+\fBscan\fR [\fBargs\fR]
+Scan for nearby networks.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+  \fB\-c\fP, \fB\-\-channel\fR [\fBCHANNEL\fR]
+  Specify a specific radio channel.
+
+.TP
+\fBsetprop\fR, \fBset\fR \fBget\fR [\fBargs\fR] <\fBproperty-name\fR> <\fBproperty-value\fR>
+Set a property.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+  \fB\-d\fP, \fB\-\-data\fR
+  Value is binary data (in hex).
+
+  \fB\-s\fP, \fB\-\-string\fR
+  Value is a string.
+
+  \fB\-i\fP, \fB\-\-integer\fR
+  Value is an integer.
+
+  \fB\-v\fP, \fB\-\-value\fR
+  Useful when the value starts with a '-'.
+
+.TP
+\fBstatus\fR [\fBargs\fR]
+Retrieve the status of the interface.
+
+  \fB\-h\fP, \fB\-\-help\fR
+  Print join help.
+
+  \fB\-t\fP, \fB\-\-timeout\fR [\fBTIMEOUT\fR]
+  Set timeout period.
+
+
+.SH EXAMPLES
+
+.TP
+$ sudo wpanctl
+Enter wpanctl command line interface that starts with prompt \fBwpanctl:[Iinterface_name]>\fR
+
+.TP
+$ sudo wpanctl -I <interface-name>
+Enter wpanctl command line and connect to specified interface, e.g.
+\fI$ sudo wpanctl -I wpan0\fR
+results with the following wpanctl shell prompt:
+\fBwpanctl:wpan0>\fR
+
+.TP
+$ sudo wpanctl scan
+Sends \fIscan\fR command to wpantund.
+The wpantund output is printed in the shell.
+
+.TP
+$ sudo wpanctl scan -c25-26,14,18-16
+Requests wpantund to scan for networks on channels 14,16,17,18,25,26.
+
+.SH DEFINITIONS
+
+.TP
+\fBCHANNEL\fR
+Integer in range [11-26] indicating one of the IEEE 802.15.4 channels.
+
+.TP
+\fBCOMMISSIONING_PORT\fR
+???
+
+.TP
+\fBEXTENDED_PAN_ID\fR
+???
+
+.TP
+\fBNCP\fR
+Network Control Processor.
+
+.TP
+\fBNETWORK_NAME\fR
+A string identifier of a network, e.g. "HomeNetwork".
+
+.TP
+\fBNODE_TYPE\fR
+WPAN type as one of the following:
+  - 0 (unknown): will starts as 2
+  - 1 (coordinator)
+  - 2 (router)
+  - 3 (end | end-device)
+  - 4 (sleepy | sleepy-end-device)
+  - 5 (mobile | mobile-end-device)
+  - 6 (lurker)
+
+.TP
+\fBPAN_ID\fR
+???
+
+.TP
+\fBPERMIT_JOIN_DURATION\fR
+???unit??
+unit: seconds (sec)
+
+.TP
+\fBPREFERRED_LIFETIME\fR
+???
+unit: seconds (sec)
+(Default: infinite)
+
+.TP
+\fBTIMEOUT\fR
+???
+unit: milliseconds (msec)
+
+.TP
+\fBULA_PREFIX\fR
+A unique local address (ULA) in the block fc00::/7.
+
+.TP
+\fBVALID_LIFETIME\fR
+???
+(Default: infinite)
+
+\" .SH FILES
+\" .TP
+\" .I /etc/wpantund.conf
+\" The default wpantund configuration file.
+
+.SH SEE ALSO
+wpantund(1)
+.SH BUGS
+Bug tracker:
+.IP
+http://...
+.PP
+
+.\" .SH HISTORY
diff --git a/doc/wpantund-oss-plan.md b/doc/wpantund-oss-plan.md
new file mode 100644
index 0000000..e2d7003
--- /dev/null
+++ b/doc/wpantund-oss-plan.md
@@ -0,0 +1,235 @@
+# "wpantund" Open-Source Plan #
+
+This document outlines the resources, processes, and procedures for
+the launch and ongoing operation of the "wpantund" open-source
+project.
+
+## Online Resources ##
+
+ *  Github: <https://github.com/openthread/wpantund/>
+     *  Public Wiki: <https://github.com/openthread/wpantund/wiki>
+ *  Front-end URL: <http://wpantund.org>
+     *  Will initially redirect to
+        <https://github.com/openthread/wpantund/#readme>
+     *  Content eventually maintained in gh-pages branch.
+ *  Mailing Lists
+     *  <wpantund-announce@googlegroups.com>
+         *  Read-only. Announces releases, security issues, etc.
+     *  <wpantund-user@googlegroups.com>
+         *  Read-write. For people who are using wpantund.
+     *  <wpantund-devel@googlegroups.com>
+         *  Read-write. For people who are contributing to wpantund.
+
+## Continuous Integration ##
+
+"wpantund" will use [Travis](https://travis-ci.org/) for continuous
+integration testing. All pull requests MUST pass the travis build test
+before being considered for merging into the master branch.
+
+## Versoning ##
+
+"wpantund" follows the Semantic Versioning guidelines, with one
+exception: the minor and patch versions use a minimum of two digits to
+facilitate better sorting.
+
+In short, the version format is of the form `M.mm.pp`, where `M` is
+the major version, `mm` is the minor version, and `pp` is the patch
+level. Additional suffixes can be appended according to the release
+type, as described in the following section.
+
+## Releases ##
+
+A "release" denotes a specific state of the code base that has been
+officially designated a unique identifier called the version
+(Depending on context, it is sometimes called the release tag). Note
+that this section refers to a several git branches which are defined
+in later sections.
+
+Broadly, there are three types of releases:
+
+**Primary Releases** — Any release in which the release tag takes the
+form of `M.mm.pp`, without any additional annotations. These are the
+canonical releases. There are generally two categories of primary
+releases:
+
+ *  **Patch Releases** — Increment only the patch version. Made
+    periodically as needed.
+ *  **Major and Minor Releases** — Patch version is always `00`. Used
+    as feature milestones and are planned well in advance.
+
+**Pre-Releases** — Any release leading up to a primary release. There
+are three different types of pre-releases:
+
+ *  **Alpha Releases** — which have the suffix `a#`, e.g.: `1.02.03a4`
+ *  **Beta Releases** — which have the suffix `b#`, e.g.: `1.02.03b4`
+ *  **Release Candidates** — which have the suffix `rc#`, e.g.:
+    `1.02.03rc4`
+
+**Special Releases** — Any release that is intended for a special
+purpose or task. Denoted by the suffix `-*`, e.g. `1.02.03-special`
+or `4.56.78a9-foobar`.
+
+### Release Process Output ###
+
+"Cutting a release" involves the creation and updating of tarballs,
+branches, and tags. The following git tags are created or updated:
+
+ *  `<VERSION>` — The identifying tag of the release, pointing to
+    the commit that is being released. The contents of this tag
+    contain the information contained in the CHANGELOG which has been
+    added since the previous release this release was based on. This
+    tag is cryptographically signed with the OpenPGP signature of a
+    project maintainer.  Ex: `1.02.03a4`
+ *  `full/<VERSION>` - A merge commit between the release tag and the
+    corresponding commit from `autoconf/master` (See the git
+    repository plan later in this document). In other words, this tag
+    points to the actual files that are released in the official
+    tarballs. Created for each of the two above tags (contains
+    autoconf files). This tag is cryptographically signed with the
+    OpenPGP signature of a project maintainer.  Ex: `full/1.02.03a4`
+ *  `latest-unstable` — Updated to point to the release tag ONLY if
+    the version of this release is larger than the previous version
+    this tag points to. This is a pointer-only tag.
+ *  `latest-release` — Updated to point to the release tag ONLY if
+    this release is a primary release and ONLY if version of this
+    release is larger than the previous version this tag points to.
+    This is a pointer-only tag, and MUST NOT contain a message.
+ *  `full/latest-unstable` / `full/latest-release` — Created for
+    each of the two above tags (contains autoconf files).
+
+Tarballs are created by checking out the `full/<VERSION>` tag (created
+above) and performing a `./configure && make distcheck`. The resulting
+files are the official tarballs. All released tarballs are
+cryptographically signed with the OpenPGP signature of a maintainer.
+
+### Release Checklist ###
+
+The following is the checklist followed by a project maintainer to cut
+an official release from the top of the master branch:
+
+1.  Clone a clean copy of the repository from the official repository
+    on GitHub. If this fails, STOP.
+2.  Do a `git checkout master`. If this fails, STOP.
+3.  Do a `git show`. Verify that Travis has passed the given commit.
+    If this commit has not passed, STOP.
+4.  Collect the changes that have been included since the last release
+    and update the contents of the CHANGELOG accordingly.
+5.  Verify that the project version in `.default-version` is set to
+    the version that is about to be released. This should already be
+    the case, but if it isn’t go ahead and update `.default-version`
+     to the version of the release.
+6.  Commit the changes made to the working directory from steps 2 and
+    3\. Use a commit message like `Updated CHANGELOG for release
+    <VERSION>` or `Updated CHANGELOG and configure.ac for release
+    <VERSION>`.
+7.  If this is a prerelease, copy the section that you just added to
+    the CHANGELOG to the clipboard. If this is a primary release,
+    copy the contents of the CHANGELOG added after the last primary
+    release to the clipboard.
+8.  Create a signed tag for the release named `<VERSION>`, making sure
+    pasting in the contents we copied to the clipboard as the tag
+    message. This is performed with the command `git tag -s
+    <VERSION>`. If this command fails, STOP.
+9.  Check out the `origin/scripts` branch: `git checkout
+    origin/scripts`. If this command fails, STOP.
+10. If this is a primary release execute the command
+    `./primary-release-from-master-helper`; or if this is a
+    prerelease execute the command
+    `./pre-release-from-master-helper`. These commands update
+    `autoconf/master`, `full/<VERSION>`, `latest-unstable`,
+    `full/latest-unstable` and (if this is a primary release)
+    `latest-release`, `full/latest-release`. If the command fails,
+    STOP. Note that the tag `full/<VERSION>` will be signed by this
+    process, so you may be asked for your GPG keychain credentials or
+    your token PIN.
+11. Check out the `full/<VERSION>` branch: `git checkout
+    full/<VERSION>`. If this command fails, STOP.
+12. Execute the command `./configure && make distcheck`. If this
+    command fails, STOP.
+13. There should now be at least one tarball (maybe more) in the
+    current directory. If this is not the case, STOP.
+14. Use GPG to sign the tarballs. If this process fails, STOP.
+15. Type `git show master`. Review the commit to make sure it looks
+    sane. If you notice anything wrong, STOP.
+16. Type `git show <VERSION>`. Review the tag notes make they look
+    properly formatted. If you notice anything wrong, STOP.
+17. Push the branches and tags to the origin server: `git push origin
+    master autoconf/master <VERSION> full/<VERSION>`. If this command
+    fails, STOP.
+18. Update the `latest-*` tags on the origin server: `git push origin
+    latest-release latest-unstable full/latest-release
+    full/latest-unstable`
+19. Upload the tarballs and their signatures to the designated
+    location. (Currently TBD)
+20. ???
+21. Pr0fit!!1
+
+Note that the above checklist is only appropriate for cutting releases
+from the master branch! Cutting releases from non-master branches
+would follow a similar (but different) process that is not yet
+defined.
+
+## Public Git Repository Branch and Tag Plan ##
+
+### Branches ###
+
+ *  `master` — Main development branch. Acceptable commits are
+    generally limited to those intended for the next major/minor
+    release. Does not contain any autoconf-generated files!
+ *  `autoconf/master` — All of (and only!) the autoconf-generated
+    files associated with master. Automatically maintained by a script
+    that checks if a commit to master has invalidated any of these
+    files and commits updates.
+ *  `scripts` — A collection of repository maintenance scripts.
+ *  `gh-pages` — Will eventually contain the content of
+    <http://wpantund.org/>.
+ *  `feature/*` — Feature-specific branches that are currently
+    under development but not yet appropriate for inclusion in master.
+ *  `release/M.mm/master` — A separate branch maintained for each
+    minor version release, for tracking things like security updates
+    and back-ported changes. These branches are created when
+    master is opened to taking commits for the next major/minor
+    release.
+
+### Tags ###
+
+ *  `M.mm.pp` — Each primary release is tagged with the bare
+    version number of the release.
+ *  `M.mm.ppx#` — Each pre-release is tagged with the version of
+    the upcoming release with a suffix `x` denoting the type of
+    pre-release and `#` denoting the count.
+ *  `M.mm.pp-x` — Each special-purpose release is tagged with the
+    version of the most recent official release (for any other type),
+    suffixed with a dash and a short descriptor of the release.
+ *  `full/*` — For each release (primary, pre, or
+    special-purpose), the tag that is the name of the release prefixed
+    with `full/` points to a merge commit between the release tag and
+    the corresponding commit from `autoconf/master`. In other words,
+    this tag points to the actual files that are released in the
+    official tarballs.
+ *  `latest-release` — A tag with no message that points to the tag
+    of the most recent primary release.
+ *  `full/latest-release` — A tag with no message that points to
+    the tag of the most recent primary release in `full/*`.
+ *  `latest-unstable` — A tag with no message that points to the
+    tag of the most recent primary release or pre-release.
+ *  `full/latest-unstable` — A tag with no message that points to
+    the tag of the most recent primary release or pre-release in
+    `full/*`.
+
+### Regarding Autotools ###
+
+No generated autotools files are allowed in master, or in any branch
+that doesn’t begin with `autoconf/` or `full/`.
+
+If you are working from the top of master and don’t have a working
+copy of autotools, the following command will populate your working
+tree with all of the appropriate files and is the functional
+equivalent of typing `./bootstrap.sh` on a machine with autotools
+installed:
+
+	git archive origin/autoconf/master | tar xv
+
+Note that the `full/*` branches contain the full set of files,
+including the sources and autotools files. The `autoconf/*` branches
+contain ONLY the autoconf files.
diff --git a/doc/wpantund.1 b/doc/wpantund.1
new file mode 100644
index 0000000..28b56ea
--- /dev/null
+++ b/doc/wpantund.1
@@ -0,0 +1,97 @@
+.TH wpantund 1 "" "" "USER COMMANDS"
+
+.SH NAME
+wpantund \- interface to 6LoWPAN communication
+
+.SH SYNOPSIS
+.B wpantund
+[\fIOPTIONS\fR]
+
+.SH DESCRIPTION
+.B wpantund
+is a userspace driver which uses the Linux TUN driver (or the UTUN driver on OS X)
+to present a network interface for 6LoWPAN communication. It communicates with the
+NCP via a socket, which can be any of the following:
+.TP
+\- a TCP socket
+
+.TP
+\- a serial port
+
+.TP
+\- stdin and stdout from a subprocess
+
+.SH OPTIONS
+
+.TP
+\fB\-h\fP, \fB\-\-help\fp
+Print help.
+
+.TP
+\fB\-v\fP, \fB\-\-version\fp
+Print version.
+
+.TP
+\fB\-d\fP, \fB\-\-debug\fp \fILEVEL
+Enable debugging mode (see \fBDEBUGGING\fP below).
+
+.TP
+\fB\-c\fP, \fB\-\-config\fp \fIFILE
+Specify config file (default /etc/wpantund.conf).
+
+.TP
+\fB\-s\fP, \fB\-\-socket\fp \fIFILE
+Specify socket file; same as \fI-o NCPSocketName\fR.
+
+.TP
+\fB\-b\fP, \fB\-\-baudrate\fp \fIFILE
+Specify baudrate; same as \fI-o NCPSocketBaud\fR.
+
+.TP
+\fB\-I\fP, \fB\-\-interface\fp \fIFILE
+Specify network interface; same as \fI-o WPANInterfaceName\fR.
+
+.TP
+\fB\-o\fP, \fB\-\-option\fp \fIWPAN_OPTIONS
+Overwrites config file options.
+
+  -- NCPSocketName \fIFILE\fR
+     Specify socket location (e.g. /dev/ttyUSB0).
+
+  -- WPANInterfaceName \fIINTERFACE\fR
+     Specify the name of the created network interface (e.g. wpan0).
+
+  -- SyslogMask \fIMASK\fR
+     To add more logs, start \fBwpantund\fP with SyslogMask all.
+
+  -- PIDFile \fIFILE\fR
+     Specify location of the file with the wpan-tunnel-daemon PID.
+
+  -- NCPReliabilityLayer
+     Specify a serial reliability layer, \fBlibsoot\fP or \fBnone\fP.
+
+  -- NCPSocketBaud
+
+.SH DEBUGGING
+
+
+.SH EXAMPLES
+
+.TP
+$ sudo wpantund -o NCPSocketName /dev/ttyUSB0 -o WPANInterfaceName wpan0
+Starts wpantund on /dev/ttyUSB0 and create network intarfeca called wpan0.
+
+.SH FILES
+.TP
+.I /etc/wpantund.conf
+The default wpantund configuration file.
+
+.SH SEE ALSO
+wpanctl(1)
+.SH BUGS
+Bug tracker:
+.IP
+http://...
+.PP
+
+.\" .SH HISTORY           \" Document history if command behaves in a unique manner
diff --git a/doxygen.cfg.in b/doxygen.cfg.in
new file mode 100644
index 0000000..a301174
--- /dev/null
+++ b/doxygen.cfg.in
@@ -0,0 +1,1808 @@
+# Doxyfile 1.8.2
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a hash (#) is considered a comment and will be ignored.
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME           = "@PACKAGE@"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER         =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = "Wireless Network Interface Daemon for Low-Power Wireless SoCs"
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO           =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = doc
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip. Note that you specify absolute paths here, but also
+# relative paths, which will be relative from the directory where doxygen is
+# started.
+
+STRIP_FROM_PATH        = @top_srcdir@
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
+# itcl::class meaning.
+
+TCL_SUBST              =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension,
+# and language is one of the parsers supported by doxygen: IDL, Java,
+# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C,
+# C++. For instance to make doxygen treat .inc files as Fortran files (default
+# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note
+# that for custom extensions you also need to set FILE_PATTERNS otherwise the
+# files are not read by doxygen.
+
+EXTENSION_MAPPING      =
+
+# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all
+# comments according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you
+# can mix doxygen, HTML, and XML commands with Markdown formatting.
+# Disable only in case of backward compatibilities issues.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented classes,
+# or namespaces to their corresponding documentation. Such a link can be
+# prevented in individual cases by by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter and setter methods for a property. Setting this option to YES (the default) will make doxygen replace the get and set methods by a property in the documentation. This will only work if the methods are indeed getting or setting a simple type. If this is not the case, or you want to show the methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields will be shown inline in the documentation
+# of the scope in which they are defined (i.e. file, namespace, or group
+# documentation), provided this scope is documented. If set to NO (the default),
+# structs, classes, and unions are shown on a separate page (for HTML and Man
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penalty.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will roughly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+SYMBOL_CACHE_SIZE      = 0
+
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
+# their name and scope. Since this can be an expensive process and often the
+# same symbol appear multiple times in the code, doxygen keeps a cache of
+# pre-resolved symbols. If the cache is too small doxygen will become slower.
+# If the cache is too large, memory is wasted. The cache size is given by this
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE            =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
+# feature you need bibtex and perl available in the search path.
+
+CITE_BIB_FILES         =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE           =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT                  = @top_srcdir@ @top_srcdir@/src/wpantund @top_srcdir@/src/wpanctl @top_srcdir@/src/ncp-spinel @top_srcdir@/src/ncp-dummy @top_srcdir@/src/ipc-dbus @top_srcdir@/src/utils
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS          =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH           =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS       =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH             =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS =
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C, C++ and Fortran comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header. Note that when using a custom header you are responsible
+#  for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER            =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If left blank doxygen will
+# generate a default style sheet. Note that it is recommended to use
+# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
+# tag will in the future become obsolete.
+
+HTML_STYLESHEET        =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
+# user-defined cascading style sheet that is included after the standard
+# style sheets created by doxygen. Using this option one can overrule
+# certain style aspects. This is preferred over using HTML_STYLESHEET
+# since it does not replace the standard style sheet and is therefor more
+# robust against future updates. Doxygen will copy the style sheet file to
+# the output directory.
+
+HTML_EXTRA_STYLESHEET  =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES       =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the style sheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
+# entries shown in the various tree structured indices initially; the user
+# can expand and collapse entries dynamically later on. Doxygen will expand
+# the tree to such a level that at most the specified number of entries are
+# visible (unless a fully collapsed tree already exceeds this amount).
+# So setting the number of entries 1 will produce a full collapsed tree by
+# default. 0 is a special value representing an infinite number of entries
+# and will result in a full expanded tree by default.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
+# identify the documentation publisher. This should be a reverse domain-name
+# style string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE               =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING     =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION           =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+#  will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you may also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to
+# the MathJax Content Delivery Network so you can quickly see the result without
+# installing MathJax.
+# However, it is strongly recommended to install a local
+# copy of MathJax from http://www.mathjax.org before deployment.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS     =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvantages are that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER           =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA             =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD                =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS  =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED             =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED      =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. For each
+# tag file the location of the external documentation should be added. The
+# format of a tag file without this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths
+# or URLs. Note that each tag file must have a unique name (where the name does
+# NOT include the path). If a tag file is not located in the directory in which
+# doxygen is run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS        = 0
+
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
+# directory containing the font.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
+# set the path where dot can find it.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside
+# the class node. If there are many fields or methods and many nodes the
+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
+# threshold limits the number of items for each type to make the size more
+# managable. Set this to 0 for no limit. Note that the threshold may be
+# exceeded by 50% before the limit is enforced.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG        = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS           =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+MSCFILE_DIRS           =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP            = YES
diff --git a/etc/Dockerfile b/etc/Dockerfile
new file mode 100644
index 0000000..f2baee1
--- /dev/null
+++ b/etc/Dockerfile
@@ -0,0 +1,52 @@
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+FROM ubuntu:trusty
+
+ENV CONNMAN_INCLUDE_ARCHIVE=https://gist.github.com/darconeous/d1d9bc39e0758e45a1d7/raw/ef9b01ac378a9b2e92031c846c4f6b5f94abab53/connman-include.tar.bz2
+
+RUN apt-get -y update \
+	&& DEBIAN_FRONTEND=noninteractive \
+			apt-get install -y -q --no-install-recommends \
+				libglib2.0-dev \
+				libdbus-1-dev \
+				libdbus-1-dev \
+				libreadline-dev \
+				libtool \
+				autoconf-archive \
+				dbus \
+				xtables-addons-source \
+				net-tools \
+				usbutils \
+				vim \
+				man \
+				bsdtar \
+				gcc g++ \
+				pkg-config \
+				autoconf \
+				autoconf-archive \
+				automake
+
+ADD $CONNMAN_INCLUDE_ARCHIVE /
+
+RUN apt-get -y update \
+	&& DEBIAN_FRONTEND=noninteractive \
+			apt-get install -y -q --no-install-recommends \
+				libboost-dev \
+				libboost-signals-dev
+
+RUN tar xvjf /connman-include.tar.bz2 -C / && rm /connman-include.tar.bz2
diff --git a/etc/autoandr/autoandr b/etc/autoandr/autoandr
new file mode 100755
index 0000000..c86705f
--- /dev/null
+++ b/etc/autoandr/autoandr
@@ -0,0 +1,1165 @@
+#!/bin/bash
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ---------------------------------------------------------------------------
+#
+# AUTOANDR v0.1
+# =============
+#
+# Autoandr is a tool for easily generating `Android.mk` files for
+# autotools-based projects.
+#
+
+
+# todo: add support for  LOCAL_COPY_HEADERS_TO and LOCAL_COPY_HEADERS
+
+# -- CONSTANTS --------------------------------------------------------------
+
+AUTOANDR_VERSION=0.00.01
+
+AUTOANDR_CFLAGS_SUFFIX=.andr_cflags
+AUTOANDR_CXX_FEATURES_SUFFIX=.andr_cxxfeatures
+AUTOANDR_INCLUDEPATH_SUFFIX=.andr_includes
+AUTOANDR_SOURCE_SUFFIX=.andr_source
+AUTOANDR_AIDL_SUFFIX=.andr_aidl
+
+AUTOANDR_MAKE_FLAGS=
+
+if [ -t 1 ]
+then
+	export ESC_BOLD=${ESC_BOLD-`printf '\033[0;1m'`} # '
+	export ESC_NORMAL=${ESC_NORMAL-`printf '\033[0m'`} # '
+fi
+
+export AUTOANDR_DIR=${AUTOANDR_DIR-`cd "$(dirname $0)" && pwd`}
+export SOURCE_DIR=${SOURCE_DIR-`pwd`}
+export BUILD_DIR=${BUILD_DIR-${SOURCE_DIR}/etc/android}
+export DESTDIR=${DESTDIR-${BUILD_DIR}/root}
+
+export V=${V-0}
+
+# -- FUNCS AND UTILS --------------------------------------------------------
+
+die() {
+	echo " *** ${ESC_BOLD}Fatal Error${ESC_NORMAL} $*" > /dev/stderr
+	exit 1
+}
+
+show_version() {
+	echo "autoandr ${AUTOANDR_VERSION}"
+}
+
+announce_pass() {
+	echo " *** ${ESC_BOLD}${*}${ESC_NORMAL}"
+}
+
+announce_tool() {
+	local tool=$1
+	shift
+	echo " * ${ESC_BOLD}${tool}${ESC_NORMAL} $*"
+}
+
+announce_path() {
+	echo " ** ${ESC_BOLD}path${ESC_NORMAL} $*"
+}
+
+
+source_pwd() {
+	echo "${SOURCE_DIR}/$(proj_pwd)"
+}
+
+library_converter() {
+	while [[ $# -ge 1 ]]
+	do
+		case $1 in
+			dbus-1) echo dbus ;;
+			util) ;;
+			*) echo $1 ;;
+		esac
+		shift
+	done
+}
+
+proj_path() {
+	local tmp="$*"
+	tmp="${tmp#$BUILD_DIR}"
+	tmp="${tmp#$SOURCE_DIR}"
+	echo "${tmp#/}"
+}
+
+proj_pwd() {
+	proj_path `pwd`
+}
+
+full_real_path() {
+	local dir_name=`dirname $1`
+	local base_name=`basename $1`
+	if test -d $dir_name
+	then printf "%s/%s\n" "$(cd $dir_name && pwd)" "$base_name"
+	else echo $1
+	fi
+}
+
+adjust_include_path() {
+	includedir=$(full_real_path "${1}")
+	rel_includedir="$(rel_path ${includedir})"
+
+	[ -z "${rel_includedir}" ] && continue
+	if [ "${rel_includedir::1}" = "." ]
+	then rel_includedir='$(LOCAL_PATH)/'"${rel_includedir}"
+	fi
+
+	if test "${includedir#$SOURCE_DIR}" == "${includedir}"
+	then rel_includedir="${includedir#$ANDROID_BUILD_TOP/}"
+	fi
+	echo "${rel_includedir}"
+}
+
+rel_path() {
+	local target=$(cd `dirname "${1}"` 2>/dev/null && pwd || dirname "${1}" )/`basename "${1}"`
+	local common_part=`pwd`
+	local result=""
+
+	if [[ "${target:0:1}" == "/" ]]
+	then
+		while [[ "${target#$common_part}" == "${target}" ]]; do
+			# no match, means that candidate common part is not correct
+			# go up one level (reduce common part)
+			common_part="$(dirname $common_part)"
+			# and record that we went back, with correct / handling
+			if [[ -z $result ]]; then
+				result=".."
+			else
+				result="../$result"
+			fi
+		done
+
+		if [[ $common_part == "/" ]]; then
+			# special case for root (no common path)
+			result="$result/"
+		fi
+
+		# since we now have identified the common part,
+		# compute the non-common part
+		forward_part="${target#$common_part}"
+
+		# and now stick all parts together
+		if [[ -n $result ]] && [[ -n $forward_part ]]; then
+			result="$result$forward_part"
+		elif [[ -n $forward_part ]]; then
+			# extra slash removal
+			result="${forward_part:1}"
+		fi
+	else
+		result="${target}"
+	fi
+
+	echo $result
+}
+
+# This function checks the arguments that would be passed to a `cc`-like
+# program to see if the output is going to be an executable or an object
+# file. This is needed because autotools uses `cc` as a linker when making
+# executables. This function allows us to quickly determine the intent.
+is_ccld() {
+	while [[ $# -ge 1 ]]
+	do
+		case $1 in
+			-c)
+				return 1 # false
+				;;
+		esac
+		shift
+	done
+
+	return 0 # true
+}
+
+# ---------------------------------------------------------------------------
+
+androidmake_prep() {
+	local parentdir
+
+	if ! [ -f Android.mk ]
+	then
+		(
+			echo "# File automatically generated by $(show_version)"
+			echo "# \"`proj_pwd`\""
+			echo "#"
+			echo
+			echo 'LOCAL_PATH := $(call my-dir)'
+		) > Android.mk
+
+		localpath="$(pwd)"
+		parentdir="$(cd .. && pwd)"
+
+		if [[ "$(cd $BUILD_DIR/.. && pwd)" != "${parentdir}" ]] && [[ "${SOURCE_DIR}" != "${parentdir}" ]] && [[ "${SOURCE_DIR}" != "${localpath}" ]]
+		then
+			(cd .. && androidmake_prep)
+			grep -q all-subdir-makefiles ../Android.mk || echo 'include $(call all-subdir-makefiles)' >> ../Android.mk
+		fi
+	fi
+}
+
+# Arguments: <object-name> <source-file>
+androidmake_object_begin() {
+	ANDROIDMAKE_OBJECT_NAME=$1
+	ANDROIDMAKE_SOURCE_FILE=$2
+
+	if [ -f "${ANDROIDMAKE_SOURCE_FILE}${AUTOANDR_AIDL_SUFFIX}" ]
+	then
+		announce_tool aidl-object `basename ${ANDROIDMAKE_OBJECT_NAME}`: $(basename $2)
+		cp "${ANDROIDMAKE_SOURCE_FILE}${AUTOANDR_AIDL_SUFFIX}" "${ANDROIDMAKE_OBJECT_NAME}"${AUTOANDR_AIDL_SUFFIX}
+		cp "${ANDROIDMAKE_SOURCE_FILE}${AUTOANDR_INCLUDEPATH_SUFFIX}" "${ANDROIDMAKE_OBJECT_NAME}"${AUTOANDR_INCLUDEPATH_SUFFIX}
+	else
+		announce_tool object `basename ${ANDROIDMAKE_OBJECT_NAME}`: $(basename $2)
+		echo "$2" > "${ANDROIDMAKE_OBJECT_NAME}"${AUTOANDR_SOURCE_SUFFIX}
+	fi
+}
+
+# Arguments: <c-flags>
+androidmake_object_cflags() {
+	[ "${ANDROIDMAKE_OBJECT_NAME}" != "" ] || die "Internal error"
+	echo "$@" >> "${ANDROIDMAKE_OBJECT_NAME}"${AUTOANDR_CFLAGS_SUFFIX}
+}
+
+# Arguments: <c++-features>
+androidmake_object_cxx_features() {
+	[ "${ANDROIDMAKE_OBJECT_NAME}" != "" ] || die "Internal error"
+	echo "$@" >> "${ANDROIDMAKE_OBJECT_NAME}"${AUTOANDR_CXX_FEATURES_SUFFIX}
+}
+
+# Arguments: <header-include-paths>
+androidmake_object_include_paths() {
+	[ "${ANDROIDMAKE_OBJECT_NAME}" != "" ] || die "Internal error"
+	if ! [ -f "${ANDROIDMAKE_SOURCE_FILE}${AUTOANDR_AIDL_SUFFIX}" ]
+	then echo "$@" >> "${ANDROIDMAKE_OBJECT_NAME}"${AUTOANDR_INCLUDEPATH_SUFFIX}
+	fi
+}
+
+androidmake_object_end() {
+	[ "${ANDROIDMAKE_OBJECT_NAME}" != "" ] || die "Internal error"
+	unset ANDROIDMAKE_OBJECT_NAME
+	unset ANDROIDMAKE_SOURCE_FILE
+}
+
+
+
+# Arguments: <source-name> <aidl-file>
+androidmake_aidl_begin() {
+	ANDROIDMAKE_AIDL_OUTPUT=$1
+	ANDROIDMAKE_AIDL_INPUT=$2
+	announce_tool aidl `basename ${ANDROIDMAKE_AIDL_INPUT}`
+
+	mkdir -p `dirname ${ANDROIDMAKE_AIDL_OUTPUT}` || die "Unable to mkdir `dirname ${ANDROIDMAKE_AIDL_OUTPUT}`"
+	echo "${ANDROIDMAKE_AIDL_INPUT}" > "${ANDROIDMAKE_AIDL_OUTPUT}"${AUTOANDR_AIDL_SUFFIX}
+}
+
+# Arguments: <header-dir>
+androidmake_aidl_header_dir() {
+	[ "${ANDROIDMAKE_AIDL_OUTPUT}" != "" ] || die "Internal error"
+	[ "${ANDROIDMAKE_AIDL_INPUT}" != "" ] || die "Internal error"
+	# Nothing to do here?
+}
+
+# Arguments: <aidl-include-paths>*
+androidmake_aidl_include_paths() {
+	[ "${ANDROIDMAKE_AIDL_INPUT}" != "" ] || die "Internal error"
+	[ "${ANDROIDMAKE_AIDL_OUTPUT}" != "" ] || die "Internal error"
+	echo $* >> "${ANDROIDMAKE_AIDL_OUTPUT}"${AUTOANDR_INCLUDEPATH_SUFFIX}
+}
+
+androidmake_aidl_end() {
+	[ "${ANDROIDMAKE_AIDL_INPUT}" != "" ] || die "Internal error"
+	[ "${ANDROIDMAKE_AIDL_OUTPUT}" != "" ] || die "Internal error"
+	unset ANDROIDMAKE_AIDL_OUTPUT
+	unset ANDROIDMAKE_AIDL_INPUT
+}
+
+
+
+# Arguments: <module-name>
+androidmake_module_begin() {
+	ANDROIDMAKE_MODULE_NAME=$1
+	androidmake_prep
+	(
+		echo ''
+		echo "#### BEGIN ${ANDROIDMAKE_MODULE_NAME} ####"
+		echo 'include $(CLEAR_VARS)'
+		echo "LOCAL_MODULE := ${ANDROIDMAKE_MODULE_NAME}"
+	) >> $ANDROIDMAKE_MODULE_NAME.Android.mk
+	rm -f $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp || die
+}
+
+androidmake_module_tags() {
+	[ "${ANDROIDMAKE_MODULE_NAME}" != "" ] || die "Internal error"
+	(
+		echo 'LOCAL_MODULE_TAGS +=' "$@"
+	) >> $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp
+}
+
+androidmake_module_dependency() {
+	[ "${ANDROIDMAKE_MODULE_NAME}" != "" ] || die "Internal error"
+	(
+		echo "LOCAL_ADDITIONAL_DEPENDENCIES +=" $1
+	) >> $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp
+}
+
+androidmake_module_path_64() {
+	[ "${ANDROIDMAKE_MODULE_NAME}" != "" ] || die "Internal error"
+	(
+		echo "LOCAL_MODULE_PATH_64 := \$(PRODUCT_OUT)$1"
+	) >> $ANDROIDMAKE_MODULE_NAME.Android.mk
+}
+
+androidmake_module_link_shared_library() {
+	[ "${ANDROIDMAKE_MODULE_NAME}" != "" ] || die "Internal error"
+	(
+		echo "LOCAL_SHARED_LIBRARIES +=" $1
+	) >> $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp
+}
+
+androidmake_module_link_static_library() {
+	[ "${ANDROIDMAKE_MODULE_NAME}" != "" ] || die "Internal error"
+	(
+		echo "LOCAL_STATIC_LIBRARIES +=" $1
+	) >> $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp
+}
+
+# Arguments: <object-name>
+androidmake_module_add_object() {
+	[ "${ANDROIDMAKE_MODULE_NAME}" != "" ] || die "Internal error"
+	object=$1
+	if [ -f ${object}${AUTOANDR_AIDL_SUFFIX} ]
+	then
+		source_file=`rel_path $(cat ${object}${AUTOANDR_AIDL_SUFFIX})`
+		(
+			echo "LOCAL_SRC_FILES +=" ${source_file}
+			for includedir in $(cat ${object}${AUTOANDR_INCLUDEPATH_SUFFIX})
+			do
+				echo "LOCAL_AIDL_INCLUDES += $(adjust_include_path "$includedir")"
+			done
+		) >> $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp
+	else
+		source_file=`rel_path $(cat ${object}${AUTOANDR_SOURCE_SUFFIX})`
+		(
+			echo "LOCAL_SRC_FILES +=" ${source_file}
+			if [ "${source_file%.cpp}" != "${source_file}" ]
+			then # C++ File
+				cat ${object}${AUTOANDR_CFLAGS_SUFFIX} | sed "s/\\\\\"/'\\\\\"'/g;" | xargs -n 1 echo "LOCAL_CPPFLAGS +="
+			else # C file
+				cat ${object}${AUTOANDR_CFLAGS_SUFFIX} | sed "s/\\\\\"/'\\\\\"'/g;" | xargs -n 1 echo "LOCAL_CFLAGS +="
+			fi
+			for includedir in $(cat ${object}${AUTOANDR_INCLUDEPATH_SUFFIX})
+			do
+				echo "LOCAL_C_INCLUDES += $(adjust_include_path "$includedir")"
+			done
+			cat ${object}${AUTOANDR_CXX_FEATURES_SUFFIX} | xargs -n 1 echo "LOCAL_CPP_FEATURES +="
+		) >> $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp
+	fi
+}
+
+androidmake_module_allow_shlib_undefined() {
+	[ "${ANDROIDMAKE_MODULE_NAME}" != "" ] || die "Internal error"
+	(
+		echo "LOCAL_ALLOW_UNDEFINED_SYMBOLS := true"
+	) >> $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp
+}
+
+androidmake_module_end_exec() {
+	[ "${ANDROIDMAKE_MODULE_NAME}" != "" ] || die "Internal error"
+	(
+		grep LOCAL_STATIC_LIBRARIES $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp
+		sort -u $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp | grep -v LOCAL_STATIC_LIBRARIES
+		echo 'include $(BUILD_EXECUTABLE)'
+		echo "#### END ${ANDROIDMAKE_MODULE_NAME} ####"
+	) >> $ANDROIDMAKE_MODULE_NAME.Android.mk
+	rm -f $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp
+	#lockfile -1 -r 3 Android.mk.lock || die Lock failure
+	cat $ANDROIDMAKE_MODULE_NAME.Android.mk >> Android.mk
+	#rm -fr Android.mk.lock
+	rm -f $ANDROIDMAKE_MODULE_NAME.Android.mk
+	unset ANDROIDMAKE_MODULE_NAME
+}
+
+androidmake_module_end_shared_lib() {
+	[ "${ANDROIDMAKE_MODULE_NAME}" != "" ] || die "Internal error"
+	(
+		grep LOCAL_STATIC_LIBRARIES $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp
+		sort -u $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp | grep -v LOCAL_STATIC_LIBRARIES
+		echo 'include $(BUILD_SHARED_LIBRARY)'
+		echo "#### END ${ANDROIDMAKE_MODULE_NAME} ####"
+	) >> $ANDROIDMAKE_MODULE_NAME.Android.mk
+	rm -f $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp
+	#lockfile -1 -r 3 Android.mk.lock || die Lock failure
+	cat $ANDROIDMAKE_MODULE_NAME.Android.mk >> Android.mk
+	#rm -fr Android.mk.lock
+	rm -f $ANDROIDMAKE_MODULE_NAME.Android.mk
+	unset ANDROIDMAKE_MODULE_NAME
+}
+
+androidmake_module_end_static_lib() {
+	[ "${ANDROIDMAKE_MODULE_NAME}" != "" ] || die "Internal error"
+	(
+		grep LOCAL_STATIC_LIBRARIES $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp
+		sort -u $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp | grep -v LOCAL_STATIC_LIBRARIES
+		echo 'include $(BUILD_STATIC_LIBRARY)'
+		echo "#### END ${ANDROIDMAKE_MODULE_NAME} ####"
+	) >> $ANDROIDMAKE_MODULE_NAME.Android.mk
+	rm -f $ANDROIDMAKE_MODULE_NAME.Android.mk.tmp
+	#lockfile -1 -r 3 Android.mk.lock || die Lock failure
+	cat $ANDROIDMAKE_MODULE_NAME.Android.mk >> Android.mk
+	#rm -fr Android.mk.lock
+	rm -f $ANDROIDMAKE_MODULE_NAME.Android.mk
+	unset ANDROIDMAKE_MODULE_NAME
+}
+
+# -- ARGUMENT PARSERS  ------------------------------------------------------
+
+handle_cc() {
+	if [[ ${AUTOANDR_MODE} == "make" ]]
+	then (
+
+		INCLUDE_PATHS=
+		SOURCES=
+		CFLAGS=
+		OUTPUT=
+		CXX_FEATURES=
+		DEPENDS="${AUTOANDR_DEPENDS}"
+
+		while [[ $# -ge 1 ]]
+		do
+			case $1 in
+				-include)
+					CFLAGS="${CFLAGS} $1 $2"
+					shift
+					;;
+
+				-I*|-i*)
+					INCLUDE_PATHS="${INCLUDE_PATHS} ${1:2}"
+					;;
+
+				--AUTOANDR-DEPENDS,*|--AUTOANDR-DEPENDS=*)
+					DEPENDS="${DEPENDS} ${1:19}"
+					;;
+
+				-frtti|-fexceptions)
+					# For some reason, the LOCAL_CPP_FEATURES
+					# variable doesn't seem to be working, so
+					# we just pass these as normal CFLAGS.
+					#CXX_FEATURES="${CXX_FEATURES} ${1:2}"
+					CFLAGS="${CFLAGS} $(printf "%q" "$1")"
+					;;
+
+				-Werror)
+					# Ignore -Werror, if present.
+					;;
+
+				-f*|-W*|-D*|-U*|-pthread|-std=*|-O[0-9]|-pedantic-*)
+					CFLAGS="${CFLAGS} $(printf "%q" "$1")"
+					;;
+
+				-o)
+					shift
+					OUTPUT="$1"
+					;;
+
+				*.c|*.cpp)
+					SOURCES="${SOURCES} $1"
+					;;
+
+				-g|-O[0-9]|-c)
+					# Ignore these
+					;;
+
+				*)
+					echo "    $# UNKNOWN \"$1\""
+					;;
+			esac
+			shift
+		done
+		if [ -z "${OUTPUT}" ]
+		then return 0
+		fi
+
+		touch "${OUTPUT}"
+
+		androidmake_object_begin ${OUTPUT} ${SOURCES}
+		androidmake_object_cflags "${CFLAGS}"
+		androidmake_object_cxx_features "${CXX_FEATURES}"
+		androidmake_object_include_paths "${INCLUDE_PATHS}"
+		androidmake_object_end
+
+	) >&3
+	elif [[ ${AUTOANDR_MODE} == "install" ]]
+	then true
+	else false
+	fi
+}
+
+handle_ccld() {
+	if [[ ${AUTOANDR_MODE} == "make" ]]
+	then (
+		OBJECTS=
+		OUTPUT=
+		LIBRARIES=
+		STATIC_LIBRARIES=
+		CFLAGS=
+		OUTPUT_SHARED_LIBRARY=0
+		ALLOW_SHLIB_UNDEFINED=1
+		DEPENDS="${AUTOANDR_DEPENDS}"
+		TAGS=${AUTOANDR_MODULE_TAGS}
+		while [[ $# -ge 1 ]]
+		do
+			case $1 in
+				-o)
+					shift
+					OUTPUT="$1"
+					;;
+				-shared)
+					OUTPUT_SHARED_LIBRARY=1
+					;;
+				-Wl,--allow-shlib-undefined)
+					ALLOW_SHLIB_UNDEFINED=1
+					;;
+				-Wl*)
+					# Linker stuff. Ignore for now.
+					;;
+				--AUTOANDR-MODULE-TAG=*)
+					TAGS="${TAGS} ${1:25}"
+					;;
+				--AUTOANDR-DEPENDS,*|--AUTOANDR-DEPENDS=*)
+					DEPENDS="${DEPENDS} ${1:19}"
+					;;
+				--AUTOANDR-MODULE-PATH-64=*)
+					AUTOANDR_MODULE_PATH_64="${1:26}"
+					;;
+				--AUTOANDR,-l*)
+					LIBRARIES="${LIBRARIES} ${1:13}"
+					;;
+				-l*)
+					LIBRARIES="${LIBRARIES} ${1:2}"
+					;;
+				*.so|*.la)
+					lib=${1:2}
+					lib=$(basename ${lib%.so})
+					lib=$(basename ${lib%.la})
+					LIBRARIES="${LIBRARIES} $lib"
+					;;
+				-f*|-W*|-U*|-D*|-pthread|-pedantic-*)
+					CFLAGS="${CFLAGS} ${1}"
+					;;
+				-L*|-I*)
+					# Ignore library and header search paths
+					;;
+				*.a)
+					STATIC_LIBRARIES="${STATIC_LIBRARIES} $1"
+					;;
+				*.o|*.lo)
+					OBJECTS="${OBJECTS} $1"
+					;;
+				-g|-O[0-9]|-c|-std=*)
+					# Ignore these
+					;;
+				-V)
+					# Version query.
+					return 0
+					;;
+				--AUTOANDR*)
+					echo " >>> Unknown autoandr argument $1"
+					;;
+				*)
+					echo "    $# UNKNOWN \"$1\""
+					;;
+			esac
+			shift
+		done
+
+		if [ "${OUTPUT}" != "${OUTPUT%.so}" ] || [ "${OUTPUT}" != "${OUTPUT%.so.0.0.0}" ]
+		then OUTPUT_SHARED_LIBRARY=1
+		fi
+
+		OUTPUT=${OUTPUT%.so.0.0.0}
+		OUTPUT=${OUTPUT%.so}
+		OUTPUT=$(basename $OUTPUT)
+
+		announce_tool link "${OUTPUT}"
+
+		androidmake_module_begin ${OUTPUT}
+		if test "${AUTOANDR_MODULE_PATH_64}" != ""
+		then androidmake_module_path_64 "${AUTOANDR_MODULE_PATH_64}"
+		fi
+		for tag in ${TAGS}
+		do androidmake_module_tags ${tag}
+		done
+		for object in ${OBJECTS}
+		do androidmake_module_add_object ${object}
+		done
+		for depend in $(library_converter ${DEPENDS})
+		do androidmake_module_dependency ${depend}
+		done
+		for lib in $(library_converter ${LIBRARIES})
+		do androidmake_module_link_shared_library lib${lib#lib}
+		done
+		for lib in ${STATIC_LIBRARIES}
+		do androidmake_module_link_static_library $(basename ${lib%.a})
+		done
+		if [ "${OUTPUT_SHARED_LIBRARY}" = "1" ]
+		then
+			[ "${ALLOW_SHLIB_UNDEFINED}" = "1" ] && androidmake_module_allow_shlib_undefined
+			androidmake_module_end_shared_lib
+		else androidmake_module_end_exec
+		fi
+
+	) >&3
+	elif [[ ${AUTOANDR_MODE} == "install" ]]
+	then true
+	else false
+	fi
+}
+
+handle_libtool() {
+	# We use this to extract library arguments when building static libraries.
+
+	if [[ ${AUTOANDR_MODE} == "make" ]]
+	then (
+		COMMAND="${AUTOANDR_LIBTOOL} $@"
+		export AUTOANDR_LIBTOOL_LIBS=
+		export AUTOANDR_DEPENDS=
+		export AUTOANDR_MODULE_PATH_64=
+		while [[ $# -ge 1 ]]
+		do
+			case $1 in
+				-l*)
+					AUTOANDR_LIBTOOL_LIBS="${AUTOANDR_LIBTOOL_LDFLAGS} ${1:2}"
+					COMMAND="${COMMAND} --AUTOANDR,$1"
+					;;
+				--AUTOANDR-DEPENDS,*|--AUTOANDR-DEPENDS=*)
+					AUTOANDR_DEPENDS="${AUTOANDR_DEPENDS} ${1:19}"
+					;;
+				--AUTOANDR-MODULE-PATH-64=*)
+					AUTOANDR_MODULE_PATH_64="${1:26}"
+					;;
+				--AUTOANDR*)
+					echo " >>> Unknown autoandr argument $1"
+					;;
+				*)
+					;;
+			esac
+			shift
+		done
+
+		${COMMAND} "$@" >&4
+
+		true
+	) 4>&1 >&3
+	elif [[ ${AUTOANDR_MODE} == "install" ]]
+	then true
+	else false
+	fi
+}
+
+
+handle_aidl_cpp() {
+	if [[ ${AUTOANDR_MODE} == "make" ]]
+	then (
+		INPUT_FILE=
+		HEADER_DIR=
+		OUTPUT_FILE=
+		INCLUDE_PATHS=
+
+		while [[ $# -ge 1 ]]
+		do
+			case $1 in
+				-I*|-i*)
+					INCLUDE_PATHS="${INCLUDE_PATHS} ${1:2}"
+					;;
+
+				*.cxx|*.cpp)
+					OUTPUT_FILE="$1"
+					;;
+
+				*.aidl)
+					INPUT_FILE="$1"
+					;;
+
+				-g|-O[0-9]|-c)
+					# Ignore these
+					;;
+
+				*)
+					HEADER_DIR="$1"
+					;;
+			esac
+			shift
+		done
+
+		[ -n "${OUTPUT_FILE}" ] || return 0
+		[ -n "${INPUT_FILE}" ] || return 0
+		[ -n "${HEADER_DIR}" ] || return 0
+
+		mkdir -p `dirname ${OUTPUT_FILE}` || die "Unable to mkdir `dirname ${OUTPUT_FILE}`"
+		touch "${OUTPUT_FILE}"
+
+		androidmake_aidl_begin ${OUTPUT_FILE} ${INPUT_FILE}
+		androidmake_aidl_header_dir ${HEADER_DIR}
+		androidmake_aidl_include_paths ${INCLUDE_PATHS}
+		androidmake_aidl_end
+
+	) >&3
+	elif [[ ${AUTOANDR_MODE} == "install" ]]
+	then true
+	else false
+	fi
+}
+
+handle_ar() {
+	if [[ ${AUTOANDR_MODE} == "make" ]]
+	then (
+		OUTPUT=
+		LIBRARIES=${AUTOANDR_LIBTOOL_LIBS}
+		STATIC_LIBRARIES=
+		OBJECTS=
+
+		shift
+		OUTPUT=`basename $1`
+		shift
+		while [[ $# -ge 1 ]]
+		do
+			case $1 in
+				*.a)
+					STATIC_LIBRARIES="${STATIC_LIBRARIES} $1"
+					;;
+				*.o|*.lo)
+					OBJECTS="${OBJECTS} $(rel_path $1)"
+					;;
+				*)
+					echo "    $# UNKNOWN \"$1\""
+					;;
+			esac
+			shift
+		done
+		if [ -z "${OUTPUT}" ]
+		then return 0
+		fi
+
+		touch "${OUTPUT}"
+
+		OUTPUT=${OUTPUT%.a}
+		OUTPUT=$(basename $OUTPUT)
+
+		announce_tool link-lib "${OUTPUT}"
+
+		androidmake_module_begin ${OUTPUT}
+		if test "${AUTOANDR_MODULE_PATH_64}" != ""
+		then androidmake_module_path_64 "${AUTOANDR_MODULE_PATH_64}"
+		fi
+		for tag in ${AUTOANDR_MODULE_TAGS}
+		do androidmake_module_tags ${tag}
+		done
+		for object in ${OBJECTS}
+		do androidmake_module_add_object ${object}
+		done
+		for depend in $(library_converter ${AUTOANDR_DEPENDS})
+		do androidmake_module_dependency ${depend}
+		done
+		for lib in $(library_converter ${LIBRARIES})
+		do androidmake_module_link_shared_library lib${lib#lib}
+		done
+		for lib in ${STATIC_LIBRARIES}
+		do androidmake_module_link_static_library $(basename ${lib%.a})
+		done
+		androidmake_module_end_static_lib
+
+	) >&3
+	elif [[ ${AUTOANDR_MODE} == "install" ]]
+	then true
+	else false
+	fi
+}
+
+handle_make() {
+	if [[ ${AUTOANDR_MODE} == "make" ]]
+	then
+		[[ $1 == "all" ]] && (
+		announce_path "$(proj_pwd)"
+
+	) >&3
+	fi
+}
+
+
+# -- COMMANDS ---------------------------------------------------------
+
+autoandr_cc() {
+	[ -z ${AUTOANDR_MODE} ] && die "missing mode"
+
+	if is_ccld "$@"
+	then handle_ccld "$@" || ${AUTOANDR_CC} "$@"
+	else handle_cc "$@" || ${AUTOANDR_CC} "$@"
+	fi
+}
+
+autoandr_cxx() {
+	[ -z ${AUTOANDR_MODE} ] && die "missing mode"
+
+	if is_ccld "$@"
+	then handle_ccld "$@" || ${AUTOANDR_CXX} "$@"
+	else handle_cc "$@" || ${AUTOANDR_CXX} "$@"
+	fi
+}
+
+autoandr_libtool() {
+	[ -z ${AUTOANDR_MODE} ] && die "missing mode"
+
+	handle_libtool "$@" || ${AUTOANDR_LIBTOOL} "$@"
+}
+
+autoandr_ccld() {
+
+	[ -z ${AUTOANDR_MODE} ] && die "missing mode"
+
+	handle_ccld "$@" ||
+
+	${AUTOANDR_CCLD} "$@"
+}
+
+autoandr_aidl_cpp() {
+
+	[ -z ${AUTOANDR_MODE} ] && die "missing mode"
+
+	handle_aidl_cpp "$@" ||
+
+	${AUTOANDR_AIDL_CPP} "$@"
+}
+
+
+autoandr_cxxld() {
+	[ -z ${AUTOANDR_MODE} ] && die "missing mode"
+
+	handle_ccld "$@" ||
+
+	${AUTOANDR_CXXLD} "$@"
+}
+
+autoandr_ld() {
+	[ -z ${AUTOANDR_MODE} ] && die "missing mode"
+
+	if [[ ${AUTOANDR_MODE} == "make" ]]
+	then
+		echo " **" ld "$@" >&3
+	fi
+
+	${AUTOANDR_LD} "$@"
+}
+
+autoandr_cpp() {
+	[ -z ${AUTOANDR_MODE} ] && die "missing mode"
+
+	${AUTOANDR_CPP} "$@"
+}
+
+autoandr_ar() {
+	[ -z ${AUTOANDR_MODE} ] && die "missing mode"
+
+	handle_ar "$@" ||
+
+	${AUTOANDR_AR} "$@"
+}
+
+autoandr_ranlib() {
+	[ -z ${AUTOANDR_MODE} ] && die "missing mode"
+
+	if [[ ${AUTOANDR_MODE} != "make" ]]
+	then ${AUTOANDR_RANLIB} "$@"
+	fi
+
+	true
+}
+
+autoandr_make() {
+	[ -z ${AUTOANDR_MODE} ] && die "missing mode"
+
+	handle_make "$@"
+
+	${AUTOANDR_MAKE} "$@"
+}
+
+autoandr_install() {
+	[ -z ${AUTOANDR_MODE} ] && die "missing mode"
+
+	if [[ ${AUTOANDR_MODE} == "install" ]]
+	then
+		announce_tool install "$*" >&3
+	else
+		${AUTOANDR_INSTALL} "$@"
+	fi
+}
+
+# ---------------------------------------------------------------------------
+
+autoandr_cleanup() {
+	if [ "${AUTOANDR_SKIP_CLEANUP}" == 1 ]
+	then
+		announce_pass "SKIPPING CLEANING UP"
+		return
+	fi
+
+	announce_pass "CLEANING UP"
+
+	[ "${BUILD_DIR}" != "/" ] || die "Build directory is root"
+	[ "${DESTDIR}" != "/" ] || die "DESTDIR is root"
+
+	cd ${BUILD_DIR}
+
+	find . "(" \
+		-name Makefile \
+		-o -name Makefile.in \
+		-o -name config.status \
+		-o -name .libs \
+		-o -name '*.[oa]' \
+		-o -name '*.[sl]o' \
+		-o -name '*.la' \
+		-o -name '*.dylib' \
+		-o -name '.deps' \
+		-o -name '.dirstamp' \
+		-o -name 'stamp-h[0-9]' \
+		-o -name 'config.log' \
+		-o -name 'libtool' \
+		-o -name 'I*.cpp' \
+		-o -name '*'${AUTOANDR_CFLAGS_SUFFIX} \
+		-o -name '*'${AUTOANDR_CXX_FEATURES_SUFFIX} \
+		-o -name '*'${AUTOANDR_INCLUDEPATH_SUFFIX} \
+		-o -name '*'${AUTOANDR_SOURCE_SUFFIX} \
+		-o -name '*'${AUTOANDR_AIDL_SUFFIX} \
+		")" -print0 \
+	| xargs -0 rm -rf || die
+
+	rm -fr ${DESTDIR}
+}
+
+first() {
+	echo $1
+}
+
+autoandr_start() {
+	# Set up our environment
+
+	# Maybe the root was specified with the NDK environment variable.
+	[ -z "${NDK_ROOT}" ] && NDK_ROOT="${NDK}"
+
+	# Maybe the NDK is in the path. If so, grab it via `which`.
+	[ -z "${NDK_ROOT}" ] && NDK_ROOT=$(dirname `which ndk-build 2>/dev/null`)
+
+	[ -z "${NDK_ROOT}" ] && die "\$NDK_ROOT environment variable not set!"
+	[ -d "${NDK_ROOT}" ] || die "NDK root doesn't seem to exist (\"$NDK_ROOT\")"
+
+	export NDK_ROOT
+	export NDK=${NDK-$NDK_ROOT}
+
+	export SYSROOT=${SYSROOT-$NDK/platforms/android-21/arch-arm}
+
+	export PKG_CONFIG_PATH=/dev/null
+	export PKG_CONFIG_LIBDIR=/dev/null
+	export PKG_CONFIG_DATADIR=/dev/null
+
+	export PATH="${NDK_ROOT}:${PATH}"
+
+	HOST=$(basename `ndk-which gcc`)
+	HOST=${HOST%-gcc}
+
+	echo NDK_ROOT=${NDK_ROOT}
+	echo HOST=${HOST}
+
+	export AUTOANDR_CC=${CC-$(ndk-which gcc) --sysroot=$SYSROOT}
+	export AUTOANDR_CCLD=${CCLD-$AUTOANDR_CC}
+	export AUTOANDR_AR=${AR-$(ndk-which ar)}
+	export AUTOANDR_LD=${LD-$(ndk-which ld)}
+	export AUTOANDR_CPP=${CPP-$(ndk-which cpp) --sysroot=$SYSROOT}
+	export AUTOANDR_CXX=${CXX-$(ndk-which c++) --sysroot=$SYSROOT}
+	export AUTOANDR_CXXLD=${CXXLD-$AUTOANDR_CXX}
+	export AUTOANDR_MAKE=${MAKE-make}
+	export AUTOANDR_INSTALL=${INSTALL-install}
+	export AUTOANDR_RANLIB=${RANLIB-$(ndk-which ranlib)}
+	export AUTOANDR_AIDL_CPP=${AIDL_CPP-$(ndk-which aidl-cpp)}
+	export AUTOANDR_LIBTOOL=${LIBTOOL-${BUILD_DIR}/libtool}
+
+	# Make sure the build directory exists
+	mkdir -p "${BUILD_DIR}" || die "Unable to create \"${BUILD_DIR}\""
+
+	# Make sure DESTDIR exists
+	mkdir -p "${DESTDIR}" || die "Unable to create \"${DESTDIR}\""
+
+	# Make sure BUILD_DIR is absolute.
+	BUILD_DIR=$(cd "${BUILD_DIR}" && pwd) || die "Unable to normalize build directory path"
+
+	# Make sure SOURCE_DIR is absolute.
+	SOURCE_DIR=$(cd "${SOURCE_DIR}" && pwd) || die "Unable to normalize source directory path"
+
+	# Make sure DESTDIR is absolute.
+	DESTDIR=$(cd "${DESTDIR}" && pwd) || die "Unable to normalize DESTDIR"
+
+	# Sanity checks
+	[ "${SOURCE_DIR::1}" == "/" ] || die "SOURCE_DIR is not an absolute path"
+	[ "${BUILD_DIR::1}" == "/" ] || die "BUILD_DIR is not an absolute path"
+	[ "${DESTDIR::1}" == "/" ] || die "DESTDIR is not an absolute path"
+	[ "${BUILD_DIR}" != "${SOURCE_DIR}" ] || die "Build directory same as source directory"
+	[ "${BUILD_DIR}" != "/" ] || die "Build directory is root"
+	[ "${DESTDIR}" != "/" ] || die "DESTDIR is root"
+
+	# Clean up our build directory
+	rm -fr "${BUILD_DIR}"
+	mkdir -p "${BUILD_DIR}"
+
+	# Make a root Android.mk file
+	cd "${SOURCE_DIR}" || die
+	rm -f Android.mk
+	androidmake_prep
+	echo 'include $(LOCAL_PATH)/'$(rel_path "${BUILD_DIR}")'/Android.mk' >> ${SOURCE_DIR}/Android.mk
+
+	cd "${BUILD_DIR}" || die
+
+	announce_pass "CONFIGURE PASS"
+	export AUTOANDR_MODE=configure
+	( "${SOURCE_DIR}/configure"                    \
+		CC="${AUTOANDR_DIR}/autoandr cc"         \
+		CCLD="${AUTOANDR_DIR}/autoandr ccld"         \
+		LD="${AUTOANDR_DIR}/autoandr ld"         \
+		CPP="${AUTOANDR_DIR}/autoandr cpp"       \
+		AR="${AUTOANDR_DIR}/autoandr ar"      \
+		CXX="${AUTOANDR_DIR}/autoandr cxx"    \
+		CXXLD="${AUTOANDR_DIR}/autoandr cxxld"    \
+		MAKE="${AUTOANDR_DIR}/autoandr make"    \
+		INSTALL="${AUTOANDR_DIR}/autoandr install"    \
+		RANLIB="${AUTOANDR_DIR}/autoandr ranlib"    \
+		AIDL_CPP="${AUTOANDR_DIR}/autoandr aidl-cpp"    \
+		--disable-dependency-tracking             \
+		--with-gnu-ld \
+		--host=${HOST} \
+		ac_cv_func_getdtablesize=no \
+		ac_cv_func_fgetln=no \
+		ac_cv_header_util_h=no \
+		${OTHER_CONFIGURE_FLAGS}                  \
+		"$@"                                       \
+	) 3>&1 1> "${AUTOANDR_STDOUT}" || die "Configure script failed"
+
+	announce_pass "MAKE PASS"
+	export AUTOANDR_MODE=make
+	( autoandr_make all V=1 \
+		${AUTOANDR_MAKE_FLAGS} \
+		MAKE="${AUTOANDR_DIR}/autoandr make" \
+		CCLD="${AUTOANDR_DIR}/autoandr ccld"         \
+		CXXLD="${AUTOANDR_DIR}/autoandr cxxld"   \
+		CXXLINK="${AUTOANDR_DIR}/autoandr cxxld"   \
+		LIBTOOL="\$(SHELL) ${AUTOANDR_DIR}/autoandr libtool"   \
+		AIDL_CPP="${AUTOANDR_DIR}/autoandr aidl-cpp"    \
+	) 3>&1 1> "${AUTOANDR_STDOUT}" || die
+
+	# Skipping install pass for now
+	#
+	#announce_pass "INSTALL PASS"
+	#export AUTOANDR_MODE=install
+	#( autoandr_make install V=1 \
+	#	${AUTOANDR_MAKE_FLAGS} \
+	#	DESTDIR=${DESTDIR} \
+	#	MAKE="${AUTOANDR_DIR}/autoandr make" \
+	#	CCLD="${AUTOANDR_DIR}/autoandr ccld"         \
+	#	CXXLD="${AUTOANDR_DIR}/autoandr cxxld"    \
+	#) 3>&1 1> "${AUTOANDR_STDOUT}" || die
+
+	autoandr_cleanup
+
+	cd ${SOURCE_DIR} || die
+
+	marker="Added by autoandr"
+	if sed -i.bak "/# $marker\$/d" Makefile.in
+	then
+		rm Makefile.in.bak
+	else
+		die "Call to 'sed' failed"
+	fi
+	echo "EXTRA_DIST += Android.mk" $(find `rel_path "${BUILD_DIR}"` -type f) "# $marker" >> Makefile.in
+}
+
+
+show_help() {
+	show_version
+	echo ""
+	echo "syntax: autoandr [general-args] <command> [command-args]"
+	echo ""
+	echo "General Arguments:"
+	echo "    -v,--verbose .................... Verbose output"
+	echo "    -V,--version .................... Print version"
+	echo "    -?,-h,--help .................... Show help"
+	echo ""
+	echo "Commands:"
+	echo ""
+	echo "    start <configure-args>"
+	echo "        Starts the process of building the Android.mk files."
+	echo "        Must be executed from the root of the project. Any"
+	echo "        arguments that you want passed to the configure script"
+	echo "        should be specified after the command."
+	echo ""
+}
+
+# ---------------------------------------------------------------------------
+
+# Parse the arguments present before the command
+while [[ $# -ge 1 ]]
+do
+	case $1 in
+		-v|--verbose)
+			AUTOANDR_STDOUT=/dev/stdout
+			;;
+		-V|--version)
+			show_version
+			exit 0
+			;;
+		-j*)
+			AUTOANDR_MAKE_FLAGS="${AUTOANDR_MAKE_FLAGS} $1"
+			;;
+		-*)
+			die "Unknown argument \"$1\""
+			;;
+		*)
+			break
+			;;
+	esac
+	shift
+done
+
+AUTOANDR_STDOUT=${AUTOANDR_STDOUT-/dev/null}
+
+case $1 in
+	cc)       shift ; autoandr_cc "$@" ;;
+	ccld)     shift ; autoandr_ccld "$@" ;;
+	ar)       shift ; autoandr_ar "$@" ;;
+	ld)       shift ; autoandr_ld "$@" ;;
+	cxx)      shift ; autoandr_cxx "$@" ;;
+	cxxld)    shift ; autoandr_cxxld "$@" ;;
+	libtool)  shift ; autoandr_libtool "$@" ;;
+	cpp)      shift ; autoandr_cpp "$@" ;;
+	make)     shift ; autoandr_make "$@" ;;
+	install)  shift ; autoandr_install "$@" ;;
+	ranlib)   shift ; autoandr_ranlib "$@" ;;
+	aidl-cpp) shift ; autoandr_aidl_cpp "$@" ;;
+
+	start)    shift ; autoandr_start "$@" ;;
+	cleanup)  shift ; autoandr_cleanup "$@" ;;
+
+	*)        die "Unknown command \"$1\"" ;;
+esac
diff --git a/etc/build-in-docker.sh b/etc/build-in-docker.sh
new file mode 100755
index 0000000..c6d3083
--- /dev/null
+++ b/etc/build-in-docker.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+DIR="`dirname $0`"
+
+"${DIR}"/run-in-docker.sh -i 'DIR="`pwd`" &&
+mkdir -p /build &&
+cd /build && "${DIR}"/configure --enable-all-restricted-plugins --with-connman --with-readline &&
+make -j `nproc` distcheck AM_DEFAULT_VERBOSITY=1
+' || exit 1
+
+"${DIR}"/run-in-docker.sh -i 'DIR="`pwd`" &&
+mkdir -p /build &&
+cd /build && "${DIR}"/configure --enable-ncp-spinel --enable-static-link-ncp-plugin=spinel &&
+make -j `nproc` check AM_DEFAULT_VERBOSITY=1 &&
+make -j `nproc` install DESTDIR=/destdir AM_DEFAULT_VERBOSITY=1 &&
+cd /destdir &&
+find .
+' || exit 1
diff --git a/etc/run-in-docker.sh b/etc/run-in-docker.sh
new file mode 100755
index 0000000..e644754
--- /dev/null
+++ b/etc/run-in-docker.sh
@@ -0,0 +1,161 @@
+#!/bin/bash
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+set -e
+
+path_to_dir ()
+{
+    f=$@;
+    if [ -d "$f" ]; then
+        base="";
+        dir="$f";
+    else
+        base="/$(basename "$f")";
+        dir=$(dirname "$f");
+    fi;
+    dir=$(cd "$dir" && /bin/pwd);
+    echo "$dir$base"
+}
+
+usage ()
+{
+  echo "usage: "
+  echo "$0 [-i] <command to exec inside docker>"
+  echo "$0 -c|--clear"
+  echo "$0 -a|--clear-all"
+  echo -n
+  echo "-c, --clear              delete all docker images including the current one"
+  echo "--priv                   run container with privileges"
+  echo "-p, --prune              delete all docker images except the current one"
+  echo "-i, --interactive        run docker with -it"
+}
+
+calc_sha1 ()
+{
+	# Figure out which program to use to calculate
+	# the SHA1 hash and execute it.
+	if ( which shasum > /dev/null 2>&1 )
+	then shasum "$1"
+	elif ( which sha1sum > /dev/null 2>&1 )
+	then sha1sum "$1"
+	elif ( which openssl > /dev/null 2>&1 )
+	then openssl dgst -sha1 < "$1"
+	fi
+}
+
+SCRIPT_DIR="$(path_to_dir "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )")"
+PROJECT_DIR="$(pwd)"
+SRC_DIR="/src"
+
+# 1. Calculate the SHA1 hash of the Dockerfile
+DOCKER_SHA=$(calc_sha1 $SCRIPT_DIR/Dockerfile)
+DOCKER_SHORT_SHA=${DOCKER_SHA:0:8}
+DOCKER_IMAGE_NAME_BASE="nestlabs/wpantund-build"
+DOCKER_IMAGE_NAME="$DOCKER_IMAGE_NAME_BASE:$DOCKER_SHORT_SHA"
+
+prune_unused_dockers ()
+{
+  docker images | grep $DOCKER_IMAGE_NAME_BASE | awk 'BEGIN{OFS = ":"}{print $1,$2}' | grep -v $DOCKER_IMAGE_NAME | xargs -I {} docker rmi {}
+  return 0
+}
+
+delete_current_docker ()
+{
+  docker rmi $DOCKER_IMAGE_NAME
+}
+
+delete_all_dockers ()
+{
+  prune_unused_dockers
+  delete_current_docker
+  rm -rf "$SCRIPT_DIR/hostinfo"
+}
+
+if [[ $# -eq 0 ]]
+then
+  echo "Give me something to do."
+  usage
+  exit 0
+fi
+
+OTHER_OPTS=""
+
+# Check to see if we have any arguments to work on.
+while [[ $# > 0 ]]
+do
+  key="$1"
+
+  case $key in
+    -h|--help)
+      usage
+     exit 0;
+      ;;
+    -c|--clear)
+      delete_all_dockers
+      exit $?
+      ;;
+    -p|--prune)
+      prune_unused_dockers
+      exit $?
+      ;;
+    --priv)
+      OTHER_OPTS="${OTHER_OPTS} --privileged"
+      ;;
+    -i|--it)
+      OTHER_OPTS="${OTHER_OPTS} -it"
+      ;;
+    *)
+      if [ ${key:0:1} ==  '-' ]
+      then
+        echo "Unknown option $key"
+        usage
+        exit 1
+      fi
+      break
+      ;;
+  esac
+  shift
+done
+
+# 2. Check to see if that docker image exists.
+RESULT=$(docker images | awk 'BEGIN{OFS = ":"}{print $1,$2}' |grep -c $DOCKER_IMAGE_NAME) || true
+
+if [ $RESULT -eq 1 ]; then
+  echo "Docker image $DOCKER_IMAGE_NAME already exists"
+else
+  echo "Creating new docker image: $DOCKER_IMAGE_NAME"
+  docker build -t $DOCKER_IMAGE_NAME $SCRIPT_DIR
+fi
+
+COMMAND="$@"
+TMPFILE="$(mktemp ./tmp.XXXXXXXXXX)"
+echo "$COMMAND" > "$TMPFILE"
+chmod 0755 "$TMPFILE"
+trap "rm -f '$TMPFILE'" EXIT
+echo "Executing '$COMMAND' as $USERNAME"
+
+CMD="docker run \
+  -v=$PROJECT_DIR:$SRC_DIR \
+  -w=$SRC_DIR \
+  --hostname=`hostname`\
+  --rm \
+  $OTHER_OPTS \
+  $DOCKER_IMAGE_NAME \
+  bash --login -ci '$TMPFILE'"
+
+$CMD
diff --git a/etc/wpantund.rb b/etc/wpantund.rb
new file mode 100644
index 0000000..36ff72b
--- /dev/null
+++ b/etc/wpantund.rb
@@ -0,0 +1,58 @@
+# Homebrew recipe for wpantund.
+
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'formula'
+
+class Wpantund < Formula
+  homepage 'https://github.com/openthread/wpantund'
+  head 'https://github.com/openthread/wpantund.git', :using => :git, :branch => 'master'
+  url 'https://github.com/openthread/wpantund.git', :using => :git, :tag => 'full/0.07.00'
+  version '0.07.00'
+
+  devel do
+    url 'https://github.com/openthread/wpantund.git', :using => :git, :tag => 'full/latest-unstable'
+    version 'latest-unstable'
+  end
+
+  depends_on 'pkg-config' => :build
+  depends_on 'd-bus'
+  depends_on 'boost'
+
+  depends_on 'autoconf' => :build
+  depends_on 'automake' => :build
+  depends_on 'libtool' => :build
+  depends_on 'autoconf-archive' => :build
+
+  def install
+    system "[ -x configure ] || PATH=\"#{HOMEBREW_PREFIX}/bin:$PATH\" ./bootstrap.sh"
+
+    system "./configure",
+      "--disable-dependency-tracking",
+      "--without-connman",
+      "--enable-all-restricted-plugins",
+      "--prefix=#{prefix}"
+
+    system "make check"
+    system "make install"
+  end
+
+  def test
+    system "wpanctl"
+  end
+end
diff --git a/m4/nl.m4 b/m4/nl.m4
new file mode 100644
index 0000000..4de5476
--- /dev/null
+++ b/m4/nl.m4
@@ -0,0 +1,345 @@
+dnl #
+dnl # Copyright (c) 2016 Nest Labs, Inc.
+dnl # All rights reserved.
+dnl #
+dnl # Licensed under the Apache License, Version 2.0 (the "License");
+dnl # you may not use this file except in compliance with the License.
+dnl # You may obtain a copy of the License at
+dnl #
+dnl #    http://www.apache.org/licenses/LICENSE-2.0
+dnl #
+dnl # Unless required by applicable law or agreed to in writing, software
+dnl # distributed under the License is distributed on an "AS IS" BASIS,
+dnl # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl # See the License for the specific language governing permissions and
+dnl # limitations under the License.
+dnl #
+
+AC_DEFUN([NL_DEBUG], [
+	AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug[=verbose|symbols]],
+				[enable compiling with debugging information and symbols]),
+				[],
+				[enable_debug=no])
+
+	if test "x$enable_debug" '!=' "xno"
+	then
+		CXXFLAGS="$CXXFLAGS -g"
+		CFLAGS="$CFLAGS -g"
+
+		if test "x$enable_debug" '!=' "xsymbols"
+		then CPPFLAGS="$CPPFLAGS -DDEBUG=1 -DDEBUG_LEVEL=2"
+		fi
+
+		if test "x$enable_debug" = "xverbose"
+		then CPPFLAGS="$CPPFLAGS -DVERBOSE_DEBUG=1"
+		fi
+	fi
+
+
+	AM_CONDITIONAL([DEBUG],[test "x$enable_debug" '!=' "xno" && test "x$enable_debug" '!=' "xsymbols"])
+	AM_CONDITIONAL([VERBOSE_DEBUG],[test "x$enable_debug" = "xverbose"])
+])
+
+AC_DEFUN([NL_EXPORT_DYNAMIC], [
+	prev_LDFLAGS="${LDFLAGS}"
+	LDFLAGS="-Wl,--export-dynamic"
+	AC_LANG_PUSH(C)
+	AC_MSG_CHECKING([linker flags needed for programs to export symbols])
+	AC_LINK_IFELSE(
+		AC_LANG_PROGRAM,
+		[EXPORT_DYNAMIC_LDFLAGS="$LDFLAGS"],
+		[EXPORT_DYNAMIC_LDFLAGS=""]
+	)
+	LDFLAGS="${prev_LDFLAGS}"
+	unset prev_LDFLAGS
+	AC_MSG_RESULT([\"$EXPORT_DYNAMIC_LDFLAGS\"])
+	AC_SUBST(EXPORT_DYNAMIC_LDFLAGS)
+	AC_LANG_POP(C)
+])
+
+AC_DEFUN([NL_CHECK_BOOST_SIGNALS2], [
+	AC_LANG_PUSH([C++])
+
+	AC_ARG_VAR([BOOST_CXXFLAGS], [C compiler flags for boost])
+	AC_ARG_VAR([BOOST_LIBS], [linker flags for boost])
+
+	boost_internal_cxxflags="-I$(cd $srcdir && pwd)/third_party/boost -DBOOST_NO_CXX11_VARIADIC_TEMPLATES -DBOOST_NO_CXX11_HDR_ARRAY -DBOOST_NO_CXX11_HDR_CODECVT -DBOOST_NO_CXX11_HDR_CONDITION_VARIABLE -DBOOST_NO_CXX11_HDR_FORWARD_LIST -DBOOST_NO_CXX11_HDR_INITIALIZER_LIST -DBOOST_NO_CXX11_HDR_MUTEX -DBOOST_NO_CXX11_HDR_RANDOM -DBOOST_NO_CXX11_HDR_RATIO -DBOOST_NO_CXX11_HDR_REGEX -DBOOST_NO_CXX11_HDR_SYSTEM_ERROR -DBOOST_NO_CXX11_HDR_THREAD -DBOOST_NO_CXX11_HDR_TUPLE -DBOOST_NO_CXX11_HDR_TYPEINDEX -DBOOST_NO_CXX11_HDR_UNORDERED_MAP -DBOOST_NO_CXX11_HDR_UNORDERED_SET -DBOOST_NO_CXX11_NUMERIC_LIMITS -DBOOST_NO_CXX11_ALLOCATOR -DBOOST_NO_CXX11_SMART_PTR -DBOOST_NO_CXX11_HDR_FUNCTIONAL -DBOOST_NO_CXX11_STD_ALIGN -DBOOST_NO_CXX11_ADDRESSOF -DBOOST_NO_CXX11_DECLTYPE_N3276 -Wp,-w"
+
+	AC_ARG_WITH(
+		[boost],
+		AC_HELP_STRING([--with-boost=internal], [Use internal copy of boost])
+	)
+
+	with_boost=${with_boost-yes}
+
+	case ${with_boost} in
+		no)
+			$2
+			;;
+		internal)
+			BOOST_CXXFLAGS="${boost_internal_cxxflags}"
+			$1
+			;;
+		yes)
+			if test -z "${BOOST_CXXFLAGS}"
+			then
+				# If BOOST_CFLAGS was set for some reason, merge them into BOOST_CXXFLAGS.
+				test -n "${BOOST_CFLAGS}" && BOOST_CXXFLAGS="${BOOST_CXXFLAGS} ${BOOST_CFLAGS}"
+
+				# Go ahead and add the BOOST_CPPFLAGS into CFLAGS for now.
+				nl_check_boost_signals2_CXXFLAGS="${CXXFLAGS}"
+				nl_check_boost_signals2_CPPFLAGS="${CPPFLAGS}"
+				CXXFLAGS+=" ${BOOST_CXXFLAGS}"
+				CPPFLAGS+=" ${BOOST_CXXFLAGS}"
+
+				AC_CHECK_HEADERS([boost/signals2/signal.hpp], [$1],[
+
+					# Sometimes boost explicitly needs this flag to work.
+					AX_CHECK_COMPILE_FLAG([-std=c++11], [
+						CXXFLAGS="$CXXFLAGS -std=c++11"
+						CPPFLAGS="$CPPFLAGS -std=c++11"
+						BOOST_CXXFLAGS="$BOOST_CXXFLAGS -std=c++11"
+					], [$2])
+
+					## Clear the cache entry we that we try again
+					unset ac_cv_header_boost_signals2_signal_hpp
+
+					AC_CHECK_HEADERS([boost/signals2/signal.hpp], [$1], [
+						with_boost=internal
+						BOOST_CXXFLAGS="${boost_internal_cxxflags}"
+						CXXFLAGS="${nl_check_boost_signals2_CXXFLAGS} ${BOOST_CXXFLAGS}"
+						CPPFLAGS="${nl_check_boost_signals2_CPPFLAGS} ${BOOST_CXXFLAGS}"
+						unset ac_cv_header_boost_signals2_signal_hpp
+						AC_CHECK_HEADERS([boost/signals2/signal.hpp], [
+							$1
+							with_boost=internal
+						], [
+							$2
+						])
+					])
+				])
+
+				CXXFLAGS="${nl_check_boost_signals2_CXXFLAGS}"
+				unset nl_check_boost_signals2_CXXFLAGS
+
+				CPPFLAGS="${nl_check_boost_signals2_CPPFLAGS}"
+				unset nl_check_boost_signals2_CPPFLAGS
+			fi
+
+			;;
+		*)
+			BOOST_CXXFLAGS="-I${with_boost}"
+			;;
+	esac
+
+	AC_SUBST(BOOST_CXXFLAGS)
+	AC_SUBST(BOOST_LIBS)
+
+	AC_LANG_POP([C++])
+])
+
+AC_DEFUN([NL_CHECK_READLINE], [
+	AC_LANG_PUSH([C])
+
+	readline_required=no
+
+	AC_ARG_WITH(
+		[readline],
+		AC_HELP_STRING([--without-readline], [Don't use libreadline or libedit])
+	)
+
+	if test "${with_readline}" '!=' "no"
+	then
+		if test "${with_readline}" '=' "yes"
+		then unset with_readline;
+			readline_required=yes
+		fi
+
+		temp_LIBS="${LIBS}"
+		temp_CPPFLAGS="${CPPFLAGS}"
+		LIBS="${LIBREADLINE_LIBS}"
+		CPPFLAGS="${LIBREADLINE_CPPFLAGS} ${LIBREADLINE_CFLAGS}"
+
+		AC_CHECK_HEADER(
+			[readline/readline.h],
+			[
+				AC_SEARCH_LIBS(waddstr, [ncurses cursesX curses])
+				AC_SEARCH_LIBS(tgetstr, [tinfo])
+				AC_SEARCH_LIBS(
+					[readline],
+					[${with_readline-readline edit}],
+					[with_readline=yes]
+				)
+			]
+		)
+
+		if test "x$with_readline" = "xyes"
+		then
+			LIBREADLINE_LIBS="${LIBS}"
+			LIBREADLINE_CPPFLAGS="${CPPFLAGS}"
+			AC_DEFINE([HAVE_LIBREADLINE], [1], [Define to 1 if we have libreadline or libedit])
+		fi
+
+		CPPFLAGS="${temp_CPPFLAGS}"
+		LIBS="${temp_LIBS}"
+	else
+		LIBREADLINE_LIBS=""
+		LIBREADLINE_CPPFLAGS=""
+	fi
+
+	AC_SUBST(LIBREADLINE_LIBS)
+	AC_SUBST(LIBREADLINE_CPPFLAGS)
+	AM_CONDITIONAL([HAVE_LIBREADLINE],[test "x$with_readline" = "xyes"])
+
+	if test "x$with_readline" = "xyes"
+	then true; $1
+	elif test "x$readline_required" = "xyes"
+	then false; AC_MSG_ERROR(["libreadline or libedit was explicitly requested but was unable to figure out how to use either"])
+	else false; $2
+	fi
+
+	AC_LANG_POP([C])
+])
+
+AC_DEFUN([NL_CHECK_DBUS], [
+	PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.4, [$1], [$2])
+	AC_SUBST(DBUS_CFLAGS)
+	AC_SUBST(DBUS_LIBS)
+
+	AC_ARG_WITH(dbusconfdir,
+		AC_HELP_STRING([--with-dbusconfdir=PATH], [path to D-Bus config directory]),
+		[path_dbusconf=${withval}],
+		[
+			if test "$prefix" = "`$PKG_CONFIG --variable=prefix dbus-1`"
+			then path_dbusconf="`$PKG_CONFIG --variable=sysconfdir dbus-1`"
+			fi
+		]
+	)
+	if (test -z "${path_dbusconf}"); then
+		if test "${prefix}" = "/usr/local" && test "${sysconfdir}" = '${prefix}/etc' && test -d /etc/dbus-1/system.d
+		then DBUS_CONFDIR='/etc/dbus-1/system.d'
+		else DBUS_CONFDIR='${sysconfdir}/dbus-1/system.d'
+		fi
+	else
+		[path_dbusconf="$(echo ${path_dbusconf} | sed 's:^'"${prefix}"':${prefix}:')" ; ]
+		[path_dbusconf="$(echo ${path_dbusconf} | sed 's:^'"${sysconfdir}"':${sysconfdir}:')" ; ]
+		DBUS_CONFDIR="${path_dbusconf}/dbus-1/system.d"
+	fi
+	AC_SUBST(DBUS_CONFDIR)
+
+	AC_ARG_WITH(dbusdatadir, AC_HELP_STRING([--with-dbusdatadir=PATH],
+		[path to D-Bus data directory]), [path_dbusdata=${withval}],
+		[
+			if test "$prefix" = "`$PKG_CONFIG --variable=prefix dbus-1`"
+			then path_dbusdata="`$PKG_CONFIG --variable=datadir dbus-1`"
+			fi
+		]
+	)
+	if (test -z "${path_dbusdata}"); then
+		DBUS_DATADIR='${datadir}/dbus-1/system-services'
+	else
+		[path_dbusconf="$(echo ${path_dbusdata} | sed 's:^'"${prefix}"':${prefix}:')" ; ]
+		[path_dbusconf="$(echo ${path_dbusdata} | sed 's:^'"${datadir}"':${datadir}:')" ; ]
+		DBUS_DATADIR="${path_dbusdata}/dbus-1/system-services"
+	fi
+	AC_SUBST(DBUS_DATADIR)
+])
+
+AC_DEFUN([NL_CHECK_LIBDL], [
+	HAVE_LIBDL=false
+	AC_ARG_WITH(libdl,AC_HELP_STRING([--without-libdl], [Do not use libdl]))
+	if test "${with_libdl-yes}" '!=' 'no'; then :
+		AC_CHECK_HEADER(
+			[dlfcn.h],
+			AC_CHECK_LIB([dl], [dlsym], [
+				HAVE_LIBDL=true
+				LIBDL_LIBS="-ldl"
+			],
+				AC_CHECK_LIB([ltdl], [dlsym], [
+					HAVE_LIBDL=true
+					LIBDL_LIBS="-lltdl"
+				])
+			)
+		)
+	fi
+	AC_SUBST(LIBDL_LIBS)
+])
+
+
+AC_DEFUN([NL_CHECK_CONNMAN], [
+	AC_ARG_WITH(
+		[connman],
+		[AC_HELP_STRING([--without-connman], [Don't build connman plugin])],
+		[
+			if test "x${with_connman}" '=' "xyes"
+			then require_connman=yes
+			fi
+		]
+	)
+
+	if test "x${with_connman}" '==' "xforce"
+	then
+		with_connman=yes
+		if test "x${CONNMAN_LIBS}" == "x"
+		then CONNMAN_LIBS="-module -avoid-version -export-symbols-regex connman_plugin_desc"
+		fi
+	elif test "x${with_connman}" '!=' "xno"
+	then
+		if test "x${CONNMAN_CFLAGS}" '==' "x"
+		then
+			PKG_CHECK_MODULES(
+				[CONNMAN],
+				[connman >= 1.0],
+				[with_connman=yes],
+				[with_connman=no]
+			)
+		else
+			# CONNMAN_CFLAGS was given manually.
+			prev_CPPFLAGS="${CPPFLAGS}"
+			CPPFLAGS="${CPPFLAGS} ${CONNMAN_CFLAGS}"
+			AC_CHECK_HEADERS([connman/plugin.h],[with_connman=yes],[with_connman=no])
+			CPPFLAGS="${prev_CPPFLAGS}"
+			unset prev_CPPFLAGS
+
+			if test "x${CONNMAN_LIBS}" == "x"
+			then CONNMAN_LIBS="-module -avoid-version -export-symbols-regex connman_plugin_desc"
+			fi
+		fi
+	fi
+
+	AC_SUBST(CONNMAN_CFLAGS)
+	AC_SUBST(CONNMAN_LIBS)
+
+	if test "x${with_connman}" = "xyes"
+	then {
+		$1
+	}
+	elif test "x$require_connman" = "xyes"
+	then false; AC_MSG_ERROR(["ConnMan plugin was explicitly requested, but can't find ConnMan headers"])
+	else false; $2
+	fi
+])
+
+AC_DEFUN([NL_CHECK_GLIB], [
+	if test "x${GLIB_CFLAGS}" '==' "x"
+	then
+		PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.28, [$1], [$2])
+	else {
+		true
+		$1
+	}
+	fi
+
+	GLIB_CFLAGS="${GLIB_CFLAGS} -DGLIB_VERSION_MAX_ALLOWED=138240 -DGLIB_VERSION_MIN_REQUIRED=138240"
+
+	AC_SUBST(GLIB_CFLAGS)
+	AC_SUBST(GLIB_LIBS)
+])
+
+dnl Unix Pseudoterminal Support
+AC_DEFUN([NL_CHECK_PTS], [
+	AC_CHECK_LIB([util], [forkpty])
+	AC_CHECK_HEADERS([pty.h util.h phy.h])
+	AM_CONDITIONAL([_XOPEN_SOURCE],[true])
+	AC_CHECK_FUNCS([forkpty ptsname], [$1], [$2])
+])
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..102f22a
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,47 @@
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+SUBDIRS =                \
+	util                 \
+	wpanctl              \
+	ipc-dbus             \
+	connman-plugin       \
+	@PLUGIN_SUBDIRS@     \
+	wpantund             \
+	scripts              \
+	$(NULL)
+
+DISTCLEANFILES =         \
+	.deps                \
+	Makefile             \
+	$(NULL)
+
+EXTRA_DIST =             \
+	version.c.in         \
+	version.h            \
+	$(NULL)
+
+SOURCE_VERSION=$(shell                                            \
+	git describe --dirty --always --match "[0-9].*" 2> /dev/null  \
+)
+
+CLEANFILES    = $(top_builddir)/$(subdir)/version.c
+BUILT_SOURCES = $(top_builddir)/$(subdir)/version.c
+.INTERMEDIATE:  $(top_builddir)/$(subdir)/version.c
+
+$(top_builddir)/$(subdir)/version.c: version.c.in Makefile
+	sed 's/SOURCE_VERSION/"$(SOURCE_VERSION)"/' < $< > $@
diff --git a/src/connman-plugin/Makefile.am b/src/connman-plugin/Makefile.am
new file mode 100644
index 0000000..349bf98
--- /dev/null
+++ b/src/connman-plugin/Makefile.am
@@ -0,0 +1,53 @@
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src \
+	-I$(top_srcdir)/src/ipc-dbus \
+	-I$(top_srcdir)/src/wpantund \
+	-I$(top_srcdir)/src/util \
+	-I$(top_srcdir)/third_party/assert-macros \
+	$(NULL)
+
+DISTCLEANFILES = .deps Makefile
+
+if BUILD_CONNMAN_PLUGIN
+
+connman_plugindir = ${libdir}/connman/plugins
+
+connman_plugin_LTLIBRARIES = wpan-tunnel-plugin.la
+
+wpan_tunnel_plugin_la_SOURCES = \
+	wpan-connman-plugin.c \
+	../util/string-utils.c \
+	$(NULL)
+
+wpan_tunnel_plugin_la_CFLAGS = \
+	$(CONNMAN_CFLAGS) \
+	$(GLIB_CFLAGS) \
+	$(DBUS_CFLAGS) \
+	$(NULL)
+
+wpan_tunnel_plugin_la_LDFLAGS = \
+	$(CONNMAN_LIBS) \
+	-shared \
+	-module \
+	-avoid-version \
+	-Wl,--allow-shlib-undefined \
+	$(NULL)
+
+endif
diff --git a/src/connman-plugin/wpan-connman-plugin.c b/src/connman-plugin/wpan-connman-plugin.c
new file mode 100644
index 0000000..9387597
--- /dev/null
+++ b/src/connman-plugin/wpan-connman-plugin.c
@@ -0,0 +1,2701 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define ASSERT_MACROS_USE_SYSLOG 1
+#include "assert-macros.h"
+#include <errno.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+
+#define _GNU_SOURCE 1
+#include <stdio.h>
+
+#ifndef IFF_LOWER_UP
+#define IFF_LOWER_UP    0x10000
+#endif
+
+#define CONNMAN_API_SUBJECT_TO_CHANGE
+#include <connman/technology.h>
+#include <connman/plugin.h>
+#include <connman/device.h>
+#include <connman/inet.h>
+#include <connman/ipaddress.h>
+#include <connman/log.h>
+#include <connman/dbus.h>
+#include <syslog.h>
+#include <dbus/dbus.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <string.h>
+#include <stdio.h>
+#include <syslog.h>
+#include "wpan-dbus-v0.h"
+#include "wpan-properties.h"
+#include "wpan-error.h"
+#include <stdbool.h>
+#include "string-utils.h"
+
+static struct connman_technology *lowpan_tech;
+static DBusConnection *connection;
+
+//#define DEBUG 1
+
+#define LOWPAN_AUTH_KEY     "WiFi.Passphrase"
+#define LOWPAN_SECURITY_KEY     "WiFi.Security"
+#define LOWPAN_PERMIT_JOINING_KEY   "LoWPAN.PermitJoining"
+#define LOWPAN_PARENT_ADDRESS_KEY   "LoWPAN.ParentAddress"
+
+#if DEBUG
+#undef DBG
+#define DBG(fmt, arg ...) \
+	connman_debug("%s:%d:%s() " fmt, \
+	              "wpan-connman-plugin.c", __LINE__, __FUNCTION__, ## arg);
+#endif
+
+static GHashTable* devices;
+static GHashTable* networks;
+
+// Simplified state representation
+typedef enum {
+	NCP_STATE_UNINITIALIZED,
+	NCP_STATE_UPGRADING,
+	NCP_STATE_OFFLINE,
+	NCP_STATE_COMMISSIONED,
+	NCP_STATE_ASSOCIATING,
+	NCP_STATE_CREDENTIALS_NEEDED,
+	NCP_STATE_ASSOCIATED,
+	NCP_STATE_NET_WAKE_ASLEEP,
+} ncp_state_t;
+
+struct wpan_network_info_s {
+	char network_name[17];
+	dbus_bool_t allowing_join;
+	uint16_t pan_id;
+	int16_t channel;
+	uint64_t xpanid;
+	int8_t rssi;
+	uint8_t hwaddr[8];
+	uint8_t prefix[8];
+};
+
+struct lowpan_device_s {
+	struct wpan_network_info_s current_network_info;
+	struct connman_network*         current_network;
+	uint8_t hwaddr[8];
+	ncp_state_t ncp_state;
+};
+
+struct lowpan_network_s {
+	struct wpan_network_info_s network_info;
+	int16_t node_type;
+};
+
+/* -------------------------------------------------------------------------- */
+// MARK: - Other Helpers
+
+
+static bool
+ncp_state_is_initializing(ncp_state_t ncp_state)
+{
+	switch (ncp_state) {
+	case NCP_STATE_UNINITIALIZED:
+	case NCP_STATE_UPGRADING:
+		return true;
+		break;
+
+	default:
+		break;
+	}
+	return false;
+}
+
+static bool
+ncp_state_is_not_associated(ncp_state_t ncp_state)
+{
+	switch(ncp_state) {
+	case NCP_STATE_OFFLINE:
+	case NCP_STATE_UPGRADING:
+	case NCP_STATE_UNINITIALIZED:
+		return true;
+
+	default:
+		break;
+	}
+	return false;
+}
+
+
+static bool
+ncp_state_is_has_joined(ncp_state_t ncp_state)
+{
+	switch(ncp_state) {
+	case NCP_STATE_ASSOCIATED:
+	case NCP_STATE_NET_WAKE_ASLEEP:
+		return true;
+
+	default:
+		break;
+	}
+	return false;
+}
+
+
+static ncp_state_t
+string_to_ncp_state(const char* new_state, ncp_state_t ncp_state) {
+	DBG("string_to_ncp_state: %s",new_state);
+
+	if(new_state == NULL) {
+		DBG("Bad association state");
+	} else if (0 == strcmp(new_state, kWPANTUNDStateFault)) {
+		ncp_state = NCP_STATE_UNINITIALIZED;
+
+	} else if (0 == strcmp(new_state, kWPANTUNDStateUpgrading)) {
+		ncp_state = NCP_STATE_UPGRADING;
+
+	} else if (0 == strcmp(new_state, kWPANTUNDStateCommissioned)) {
+		ncp_state = NCP_STATE_COMMISSIONED;
+
+	} else if (0 == strcmp(new_state, kWPANTUNDStateCredentialsNeeded)) {
+		ncp_state = NCP_STATE_CREDENTIALS_NEEDED;
+
+	} else if (0 == strcmp(new_state, kWPANTUNDStateNetWake_Asleep)) {
+		ncp_state = NCP_STATE_NET_WAKE_ASLEEP;
+
+	} else if (0 == strcmp(new_state, kWPANTUNDStateIsolated)) {
+		ncp_state = NCP_STATE_ASSOCIATING;
+
+	} else if (0 == strncmp(new_state, kWPANTUNDStateOffline, sizeof(kWPANTUNDStateOffline)-1)) {
+		ncp_state = NCP_STATE_OFFLINE;
+
+	} else if (0 == strncmp(new_state, kWPANTUNDStateAssociating, sizeof(kWPANTUNDStateAssociating)-1)) {
+		ncp_state = NCP_STATE_ASSOCIATING;
+
+	} else if (0 == strncmp(new_state, kWPANTUNDStateAssociated, sizeof(kWPANTUNDStateAssociated)-1)) {
+		ncp_state = NCP_STATE_ASSOCIATED;
+
+	} else if (0 == strncmp(new_state, kWPANTUNDStateUninitialized, sizeof(kWPANTUNDStateUninitialized)-1)) {
+		ncp_state = NCP_STATE_UNINITIALIZED;
+	}
+	return ncp_state;
+}
+
+static void
+parse_prefix_string(const char *prefix_cstr, uint8_t *prefix)
+{
+	uint8_t bytes[16];
+	char str[INET6_ADDRSTRLEN + 10];
+	char *p;
+
+	memset(prefix, 0, 8);
+	memset(bytes, 0, sizeof(bytes));
+
+	// Create a copy of the prefix string so we can modify it.
+	strcpy(str, prefix_cstr);
+
+	// Search for "/64" and remove it from the str.
+	p = strchr(str, '/');
+	if (p != NULL) {
+		*p = 0;
+	}
+
+	// Parse the str as an ipv6 address.
+	if (inet_pton(AF_INET6, str, bytes) > 0)
+	{
+		// If successful, copy the first 8 bytes.
+		memcpy(prefix, bytes, 8);
+	}
+}
+
+static int
+encode_data_into_b16_string(
+    const uint8_t*  buffer,
+    size_t len,
+    char*                   c_str,
+    size_t c_str_max_len,
+    int pad_to
+    )
+{
+	int ret = 0;
+
+	while (len && (c_str_max_len > 2)) {
+		uint8_t byte = *buffer++;
+		len--;
+		pad_to--;
+		*c_str++ = int_to_hex_digit(byte >> 4);
+		*c_str++ = int_to_hex_digit(byte & 0xF);
+		c_str_max_len -= 2;
+		ret += 2;
+	}
+
+	while (pad_to > 0 && (c_str_max_len > 2)) {
+		pad_to--;
+		*c_str++ = '0';
+		*c_str++ = '0';
+		c_str_max_len -= 2;
+		ret += 2;
+	}
+
+	*c_str++ = 0;
+	return ret;
+}
+
+static int
+encode_ipv6_address_from_prefx_and_hwaddr(
+    char*                   c_str,
+    size_t c_str_max_len,
+    const uint8_t prefix[8],
+    const uint8_t hwaddr[8]
+    )
+{
+	return snprintf(c_str, c_str_max_len,
+	                "%02X%02X:%02X%02X:%02X%02X:%02X%02X:"
+	                "%02X%02X:%02X%02X:%02X%02X:%02X%02X",
+	                prefix[0], prefix[1], prefix[2], prefix[3],
+	                prefix[4], prefix[5], prefix[6], prefix[7],
+	                hwaddr[0] ^ 0x02, hwaddr[1], hwaddr[2], hwaddr[3],
+	                hwaddr[4], hwaddr[5], hwaddr[6], hwaddr[7]
+	                );
+}
+
+/* -------------------------------------------------------------------------- */
+// MARK: - Static Declarations
+
+static void lowpan_device_leave(struct connman_device *device);
+static int lowpan_driver_setprop_data(struct connman_device *device, const char* key, const uint8_t* data, size_t size);
+static int lowpan_driver_getprop_data(struct connman_device *device, const char* key, void(*callback)(void* context, int error, const uint8_t* data, size_t len), void* context);
+
+static void lowpan_device_set_network(struct connman_device *device, struct connman_network *network);
+
+static int lowpan_device_update_status(struct connman_device *device);
+
+
+/* -------------------------------------------------------------------------- */
+// MARK: - DBus Helpers
+
+uint8_t
+CalculateStrengthFromRSSI(int8_t rssi)
+{
+	uint8_t ret = 0;
+
+	if (rssi > -120) {
+		ret = 120 + rssi;
+	}
+
+	if (ret > 100) {
+		ret = 100;
+	}
+	return ret;
+}
+
+static void
+dump_info_from_iter(
+    FILE* file, DBusMessageIter *iter, int indent, bool bare
+    )
+{
+	DBusMessageIter sub_iter;
+	int i;
+
+	if (!bare) for (i = 0; i < indent; i++) fprintf(file, "\t");
+
+	switch (dbus_message_iter_get_arg_type(iter)) {
+	case DBUS_TYPE_DICT_ENTRY:
+		dbus_message_iter_recurse(iter, &sub_iter);
+		dump_info_from_iter(file, &sub_iter, indent + 1, true);
+		fprintf(file, " => ");
+		dbus_message_iter_next(&sub_iter);
+		dump_info_from_iter(file, &sub_iter, indent + 1, true);
+		break;
+	case DBUS_TYPE_ARRAY:
+		dbus_message_iter_recurse(iter, &sub_iter);
+		if (dbus_message_iter_get_arg_type(&sub_iter) == DBUS_TYPE_BYTE ||
+		    dbus_message_iter_get_arg_type(&sub_iter) == DBUS_TYPE_INVALID) {
+			fprintf(file, "[");
+			indent = 0;
+		} else {
+			fprintf(file, "[\n");
+		}
+
+		for (;
+		     dbus_message_iter_get_arg_type(&sub_iter) != DBUS_TYPE_INVALID;
+		     dbus_message_iter_next(&sub_iter)) {
+			dump_info_from_iter(file,
+			                    &sub_iter,
+			                    indent + 1,
+			                    dbus_message_iter_get_arg_type(&sub_iter) == DBUS_TYPE_BYTE);
+		}
+		for (i = 0; i < indent; i++) fprintf(file, "\t");
+		fprintf(file, "]");
+
+		break;
+	case DBUS_TYPE_VARIANT:
+		dbus_message_iter_recurse(iter, &sub_iter);
+		dump_info_from_iter(file, &sub_iter, indent, true);
+		break;
+	case DBUS_TYPE_STRING:
+	{
+		const char* string;
+		dbus_message_iter_get_basic(iter, &string);
+		fprintf(file, "\"%s\"", string);
+	}
+	break;
+
+	case DBUS_TYPE_BYTE:
+	{
+		uint8_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		fprintf(file, "%02X", v);
+	}
+	break;
+	case DBUS_TYPE_UINT16:
+	{
+		uint16_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		fprintf(file, "0x%04X", v);
+	}
+	break;
+	case DBUS_TYPE_INT16:
+	{
+		int16_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		fprintf(file, "%d", v);
+	}
+	break;
+	case DBUS_TYPE_UINT32:
+	{
+		uint32_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		fprintf(file, "%d", v);
+	}
+	break;
+	case DBUS_TYPE_BOOLEAN:
+	{
+		dbus_bool_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		fprintf(file, "%s", v ? "true" : "false");
+	}
+	break;
+	case DBUS_TYPE_INT32:
+	{
+		int32_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		fprintf(file, "%d", v);
+	}
+	break;
+	case DBUS_TYPE_UINT64:
+	{
+		uint64_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		fprintf(file, "0x%016llX", (unsigned long long)v);
+	}
+	break;
+	default:
+		fprintf(file, "<%s>",
+		        dbus_message_type_to_string(dbus_message_iter_get_arg_type(iter)));
+		break;
+	}
+	if (!bare)
+		fprintf(file, "\n");
+}
+
+static int
+parse_network_info_from_iter(
+    struct wpan_network_info_s *network_info, DBusMessageIter *iter
+    )
+{
+	int ret = 0;
+	DBusMessageIter outer_iter;
+	DBusMessageIter dict_iter;
+
+	if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_ARRAY) {
+		dbus_message_iter_recurse(iter, &outer_iter);
+		iter = &outer_iter;
+	}
+
+	memset(network_info, 0, sizeof(*network_info));
+
+	for (;
+	     dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID;
+	     dbus_message_iter_next(iter)) {
+		DBusMessageIter value_iter;
+		char* key;
+
+		if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY) {
+			DBG(
+			    "error: Bad type for network (%c)\n",
+			    dbus_message_iter_get_arg_type(iter));
+			ret = -1;
+			goto bail;
+		}
+
+		dbus_message_iter_recurse(iter, &dict_iter);
+
+		if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_STRING) {
+			DBG(
+			    "error: Bad type for network list (%c)\n",
+			    dbus_message_iter_get_arg_type(&dict_iter));
+			ret = -1;
+			goto bail;
+		}
+
+		// Get the key
+		dbus_message_iter_get_basic(&dict_iter, &key);
+		dbus_message_iter_next(&dict_iter);
+
+		if (key == NULL) {
+			ret = -EINVAL;
+			goto bail;
+
+		}
+
+		if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_VARIANT) {
+			DBG(
+			    "error: Bad type for network list (%c)\n",
+			    dbus_message_iter_get_arg_type(&dict_iter));
+			ret = -1;
+			goto bail;
+		}
+
+		dbus_message_iter_recurse(&dict_iter, &value_iter);
+
+		if (strcmp(key, kWPANTUNDProperty_NetworkName) == 0 || strcmp(key, "NetworkName") == 0) {
+			char* network_name = NULL;
+			dbus_message_iter_get_basic(&value_iter, &network_name);
+			snprintf(network_info->network_name,
+			         sizeof(network_info->network_name), "%s", network_name);
+		} else if ((strcmp(key, kWPANTUNDProperty_NCPChannel) == 0) || strcmp(key, "Channel") == 0) {
+			dbus_message_iter_get_basic(&value_iter, &network_info->channel);
+		} else if ((strcmp(key, kWPANTUNDProperty_NetworkPANID) == 0) || strcmp(key, "PanId") == 0) {
+			dbus_message_iter_get_basic(&value_iter, &network_info->pan_id);
+		} else if ((strcmp(key, kWPANTUNDProperty_NetworkXPANID) == 0) || strcmp(key, "XPanId") == 0) {
+			dbus_message_iter_get_basic(&value_iter, &network_info->xpanid);
+		} else if ((strcmp(key, kWPANTUNDProperty_NestLabs_NetworkAllowingJoin) == 0) || strcmp(key, "AllowingJoin") == 0) {
+			dbus_message_iter_get_basic(&value_iter,
+			                            &network_info->allowing_join);
+		} else if ((strcmp(key, kWPANTUNDProperty_NCPHardwareAddress) == 0) || strcmp(key, "BeaconHWAddr") == 0) {
+			DBusMessageIter array_iter;
+			dbus_message_iter_recurse(&value_iter, &array_iter);
+			const uint8_t* value = NULL;
+			int nelements = 0;
+			dbus_message_iter_get_fixed_array(&array_iter, &value, &nelements);
+			if (value != NULL && nelements == 8)
+				memcpy(network_info->hwaddr, value, 8);
+		} else if (strcmp(key, kWPANTUNDProperty_IPv6MeshLocalPrefix) == 0) {
+			int value_dbus_type = dbus_message_iter_get_arg_type(&value_iter);
+			if (value_dbus_type == DBUS_TYPE_STRING) {
+				const char *prefix_cstr = NULL;
+				dbus_message_iter_get_basic(&value_iter, &prefix_cstr);
+				parse_prefix_string(prefix_cstr, network_info->prefix);
+			} else if (value_dbus_type == DBUS_TYPE_ARRAY) {
+				DBusMessageIter array_iter;
+				dbus_message_iter_recurse(&value_iter, &array_iter);
+				const uint8_t *value = NULL;
+				int nelements = 0;
+				dbus_message_iter_get_fixed_array(&array_iter, &value, &nelements);
+				if (value != NULL && nelements == 8) {
+					memcpy(network_info->prefix, value, 8);
+				}
+			} else {
+				DBG("Unexpected dbus type %c for %s", value_dbus_type, kWPANTUNDProperty_IPv6MeshLocalPrefix);
+				memset(network_info->prefix, 0 , sizeof(network_info->prefix));
+			}
+		} else if (strcmp(key, "RSSI") == 0) {
+			int8_t rssi;
+			dbus_message_iter_get_basic(&value_iter, &rssi);
+			network_info->rssi = rssi;
+		} else {
+#if DEBUG
+			DBG(
+			    "info: %s -> (%c)\n",
+			    key,
+			    dbus_message_iter_get_arg_type(&value_iter));
+#endif
+		}
+	}
+
+bail:
+	if (ret) DBG("Network parse failed.\n");
+	return ret;
+}
+
+/* -------------------------------------------------------------------------- */
+// MARK: - LoWPAN Network
+
+static struct connman_network*
+get_network_from_iter(
+    struct connman_device* device, DBusMessageIter *iter
+    )
+{
+	const char* new_state = NULL;
+	struct connman_network *network = NULL;
+	struct wpan_network_info_s network_info = {};
+	char network_identifier[256];
+	const char * group_identifier = network_identifier;
+	char hwaddr_str[256];
+	struct lowpan_network_s *network_data = NULL;
+
+	if (parse_network_info_from_iter(&network_info, iter) != 0) {
+		goto bail;
+	}
+
+	if (!network_info.network_name[0]) {
+		goto bail;
+	}
+
+	if (network_info.xpanid == 0) {
+		goto bail;
+	}
+
+	encode_data_into_b16_string(
+	    (const uint8_t*)network_info.network_name,
+	    strlen(network_info.network_name),
+	    network_identifier,
+	    sizeof(network_identifier),
+	    0
+    );
+
+	encode_data_into_b16_string(
+	    (const uint8_t*)network_info.hwaddr,
+	    8,
+	    hwaddr_str,
+	    sizeof(hwaddr_str),
+	    0
+    );
+
+	snprintf(network_identifier + strlen(network_identifier),
+	         sizeof(network_identifier) - strlen(
+	             network_identifier), "_x%016llX", (unsigned long long)network_info.xpanid);
+
+	network = connman_device_get_network(device, network_identifier);
+
+	if (!network) {
+		network = connman_network_create(
+		    network_identifier,
+		    CONNMAN_NETWORK_TYPE_LOWPAN
+	    );
+		network_data = (struct lowpan_network_s *)calloc(1,sizeof(struct lowpan_network_s));
+		network_data->network_info = network_info;
+		network_data->node_type = WPAN_IFACE_ROLE_ROUTER;
+		connman_network_set_data(network, network_data);
+		connman_network_set_string(network, LOWPAN_SECURITY_KEY, "psk");
+
+		connman_device_add_network(device, network);
+
+		connman_network_unref(network);
+
+		connman_network_set_strength(network,
+		                             CalculateStrengthFromRSSI(network_info.rssi));
+		connman_network_set_name(network, network_info.network_name);
+
+		// Set network extended ID before a service is created from network
+		// since this information is needed when service loads provision.
+		connman_network_set_lowpan_xpan_id(network, network_data->network_info.xpanid);
+
+		connman_network_set_group(network, group_identifier);
+		connman_network_set_index(network, -1);
+
+		DBG("New Network: %p ident:%s group:%s", network, network_identifier, group_identifier);
+	} else {
+		network_data = connman_network_get_data(network);
+		network_data->network_info = network_info;
+	}
+
+	connman_network_set_bool(network, LOWPAN_PERMIT_JOINING_KEY, network_data->network_info.allowing_join);
+	connman_network_set_string(network, LOWPAN_PARENT_ADDRESS_KEY, hwaddr_str);
+
+bail:
+
+	DBG("%p NetworkFromIter: %p", device, network);
+	return network;
+}
+
+
+static void
+network_unref_callback(void* user_data)
+{
+	struct connman_network *network = (struct connman_network *)user_data;
+
+	connman_network_unref(network);
+}
+
+static int
+lowpan_network_probe(struct connman_network *network)
+{
+	DBG("%p %s", network, connman_network_get_identifier(network));
+
+	return 0;
+}
+
+static void
+lowpan_network_remove(struct connman_network *network)
+{
+	DBG("%p %s", network, connman_network_get_identifier(network));
+
+	struct lowpan_network_s *network_data =
+	    (struct lowpan_network_s *)connman_network_get_data(network);
+
+	if(network_data) {
+		connman_network_set_name(network, "X");
+		connman_network_set_group(network, "X");
+
+		free(network_data);
+		connman_network_set_data(network, NULL);
+	}
+
+}
+
+static void
+join_finished_callback(
+    DBusPendingCall *pending, void* user_data
+    )
+{
+	int32_t ret = 0;
+	struct connman_network *network = (struct connman_network *)user_data;
+	struct connman_device* device = NULL;
+	struct lowpan_device_s *device_info = NULL;
+	DBusMessage* reply = dbus_pending_call_steal_reply(pending);
+	DBusMessageIter iter;
+	DBusMessageIter list_iter;
+
+	// network will never be NULL in this callback.
+
+	DBG("%p %s", network, connman_network_get_identifier(network));
+
+	device = connman_network_get_device(network);
+
+	require_action(device != NULL, bail, ret = -ENODEV);
+
+	device_info = (struct lowpan_device_s *)connman_device_get_data(device);
+
+	require_action(device_info != NULL, bail, ret = -ENODEV);
+	require_action(reply != NULL, bail, ret = -EINVAL);
+
+	dbus_message_iter_init(reply, &iter);
+
+	// Get return code
+	dbus_message_iter_get_basic(&iter, &ret);
+
+bail:
+	if (reply) {
+		dbus_message_unref(reply);
+	}
+	if (pending) {
+		dbus_pending_call_unref(pending);
+	}
+
+	if ((ret != 0) && (ret != -EINPROGRESS) && (ret != kWPANTUNDStatus_InProgress)) {
+		DBG("%p Join/Resume returned failure: %d", network, ret);
+
+		if((device_info != NULL) && ncp_state_is_has_joined(device_info->ncp_state)) {
+			DBG("%p ... But we seem to have connected anyway. Ignoring the error.", network);
+			ret = 0;
+		} else {
+			connman_network_set_error(network, CONNMAN_NETWORK_ERROR_INVALID_KEY);
+		}
+	}
+
+	if (ret == 0) {
+		connman_network_set_connected(network, TRUE);
+	}
+
+	return;
+}
+
+static int
+lowpan_network_connect_using_join(struct connman_network *network)
+{
+	int ret = -EINVAL;
+	DBG("%p %s", network, connman_network_get_identifier(network));
+	struct connman_device* device = connman_network_get_device(network);
+	DBusPendingCall *pending_call = NULL;
+	DBusMessage *message = NULL;
+	char dbus_path[DBUS_MAXIMUM_NAME_LENGTH];
+	struct lowpan_network_s *network_data =
+	    (struct lowpan_network_s *)connman_network_get_data(network);
+
+	require_action(device != NULL, bail, ret = -ENODEV);
+
+	require_action(network_data != NULL, bail, ret = -ENODEV);
+
+	struct lowpan_device_s *device_info =
+	    (struct lowpan_device_s *)connman_device_get_data(device);
+
+	require_action(device_info != NULL, bail, ret = -ENODEV);
+
+	snprintf(dbus_path,
+	         sizeof(dbus_path),
+	         "%s/%s",
+	         WPAN_TUNNEL_DBUS_PATH,
+	         connman_device_get_ident(device));
+
+	message = dbus_message_new_method_call(
+	    WPAN_TUNNEL_DBUS_NAME,
+	    dbus_path,
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_IFACE_CMD_JOIN
+	    );
+	const char* network_name = network_data->network_info.network_name;
+	dbus_message_append_args(
+	    message,
+	    DBUS_TYPE_STRING, &network_name,
+	    DBUS_TYPE_INVALID
+	    );
+
+	dbus_message_append_args(
+	    message,
+	    DBUS_TYPE_INT16, &network_data->node_type,
+	    DBUS_TYPE_INVALID
+	    );
+
+	dbus_message_append_args(
+	    message,
+	    DBUS_TYPE_UINT64, &network_data->network_info.xpanid,
+	    DBUS_TYPE_INVALID
+	    );
+
+	dbus_message_append_args(
+	    message,
+	    DBUS_TYPE_UINT16, &network_data->network_info.pan_id,
+	    DBUS_TYPE_INVALID
+	    );
+
+	dbus_message_append_args(
+	    message,
+	    DBUS_TYPE_BYTE, &network_data->network_info.channel,
+	    DBUS_TYPE_INVALID
+	    );
+
+
+	if (!dbus_connection_send_with_reply(
+	        connection,
+	        message,
+	        &pending_call,
+	        45000
+	        )
+	    ) {
+		ret = -EINVAL;
+		goto bail;
+	}
+
+	connman_network_ref(network);
+
+	if (!dbus_pending_call_set_notify(
+	        pending_call,
+	        &join_finished_callback,
+	        (void*)network,
+	        (DBusFreeFunction) & network_unref_callback
+	        )
+	    ) {
+		dbus_pending_call_cancel(pending_call);
+		connman_network_unref(network);
+		ret = -EINVAL;
+		goto bail;
+	}
+
+	ret = -EINPROGRESS;
+
+
+bail:
+	if(message)
+		dbus_message_unref(message);
+	return ret;
+}
+
+static int
+lowpan_network_connect_using_resume(struct connman_network *network)
+{
+	int ret = -EINVAL;
+
+	DBG("%p %s", network, connman_network_get_identifier(network));
+	struct connman_device* device = connman_network_get_device(network);
+	DBusPendingCall *pending_call = NULL;
+	DBusMessage *message = NULL;
+	char dbus_path[DBUS_MAXIMUM_NAME_LENGTH];
+
+	require_action(device != NULL, bail, ret = -ENODEV);
+
+	struct lowpan_device_s *device_info =
+	    (struct lowpan_device_s *)connman_device_get_data(device);
+
+	require_action(device_info != NULL, bail, ret = -ENODEV);
+
+	snprintf(dbus_path,
+	         sizeof(dbus_path),
+	         "%s/%s",
+	         WPAN_TUNNEL_DBUS_PATH,
+	         connman_device_get_ident(device));
+
+	message = dbus_message_new_method_call(
+	    WPAN_TUNNEL_DBUS_NAME,
+	    dbus_path,
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_IFACE_CMD_RESUME
+	    );
+
+	if (!dbus_connection_send_with_reply(
+	        connection,
+	        message,
+	        &pending_call,
+	        30000 // Thirty seconds
+	        )) {
+		ret = -1;
+		goto bail;
+	}
+
+	connman_network_ref(network);
+
+	if (!dbus_pending_call_set_notify(
+	        pending_call,
+	        &join_finished_callback,
+	        (void*)network,
+	        (DBusFreeFunction) & network_unref_callback
+	        )
+	    ) {
+		dbus_pending_call_cancel(pending_call);
+		connman_network_unref(network);
+		ret = -EINVAL;
+		return -1;
+	}
+
+	DBG("Now waiting for resume to complete...");
+
+	ret = -EINPROGRESS;
+
+bail:
+	if(message)
+		dbus_message_unref(message);
+	return ret;
+}
+
+static void
+lowpan_network_update_key(struct connman_network *network, const uint8_t* data, size_t len)
+{
+	char key_cstr[16*2+1];
+
+	DBG("%p %s", network, connman_network_get_identifier(network));
+
+	if (len != 0) {
+		encode_data_into_b16_string(data, len, key_cstr, sizeof(key_cstr), 0);
+		connman_network_set_string(network, LOWPAN_AUTH_KEY, key_cstr);
+		connman_network_update(network);
+	}
+}
+
+static void
+_lowpan_network_update_key_from_ncp_callback(void* context, int error, const uint8_t* data, size_t len)
+{
+	struct connman_network *network = context;
+	DBG("%p %s", network, connman_network_get_identifier(network));
+	if (error == 0) {
+		lowpan_network_update_key(network, data, len);
+	}
+
+	struct connman_device* device = connman_network_get_device(network);
+
+	if (!device) {
+		DBG("NO DEVICE!");
+		return;
+	}
+
+	struct lowpan_device_s *device_info =
+	    (struct lowpan_device_s *)connman_device_get_data(device);
+
+	if (!device_info) {
+		DBG("NO DEVICE INFO!");
+		return;
+	}
+
+	if (ncp_state_is_has_joined(device_info->ncp_state)
+		&& !connman_network_get_connected(network)
+		&& !connman_network_get_connecting(network)
+		&& !connman_network_get_associating(network)
+	) {
+		DBG("We got the network key, asking connman to connect...");
+		connman_service_connect(connman_service_lookup_from_network(network),
+                CONNMAN_SERVICE_CONNECT_REASON_USER);
+	}
+
+	connman_network_unref(network);
+}
+
+static int
+lowpan_network_update_key_from_ncp(struct connman_network *network)
+{
+	int ret = 0;
+	struct connman_device* device = connman_network_get_device(network);
+	if (!device) {
+		ret = -ENODEV;
+		goto bail;
+	}
+
+	DBG("%p %s", network, connman_network_get_identifier(network));
+
+	connman_network_ref(network);
+
+	ret = lowpan_driver_getprop_data(
+		device,
+		kWPANTUNDProperty_NetworkKey,
+		&_lowpan_network_update_key_from_ncp_callback,
+		network
+	);
+
+	if(ret != 0)
+		goto bail;
+
+bail:
+	return ret;
+}
+
+static int
+lowpan_network_set_key_on_ncp(struct connman_network *network)
+{
+	int ret = 0;
+	struct connman_device* device = connman_network_get_device(network);
+	DBG("%p %s", network, connman_network_get_identifier(network));
+	if (!device) {
+		ret = -ENODEV;
+		goto bail;
+	}
+	uint8_t key[16];
+	unsigned int size = sizeof(key);
+	const char* key_cstr = connman_network_get_string(network, LOWPAN_AUTH_KEY);
+
+	if (key_cstr) {
+		size = parse_string_into_data(key, size, key_cstr);
+
+		if (size > sizeof(key)) {
+			connman_warn("Key is too large: %d (max %d)", size, (int)sizeof(key));
+			ret = -EINVAL;
+		} else if (sizeof(key) != size) {
+			connman_warn("Key-size mismatch (Expecting %d, but key was %d bytes long)", (int)sizeof(key), size);
+		}
+	} else {
+#if 0
+		size = 16;
+		memset(key,0,sizeof(key));
+		size = sizeof(key);
+		connman_warn("No valid key specified for %s, using all-zeros...", connman_network_get_identifier(network));
+#else
+		ret = -ENOKEY;
+		DBG("No key to set!");
+#endif
+	}
+
+	if (ret == 0) {
+		DBG("Setting the key at %p for the service...", key);
+		ret = lowpan_driver_setprop_data(device, kWPANTUNDProperty_NetworkKey, key, size);
+	}
+
+bail:
+	return ret;
+}
+
+static int
+lowpan_network_connect(struct connman_network *network)
+{
+	int ret = -EINVAL;
+	struct connman_device* device = connman_network_get_device(network);
+
+	DBG("%p %s", network, connman_network_get_identifier(network));
+
+	if (!device) {
+		ret = -ENODEV;
+		goto bail;
+	}
+
+	struct lowpan_device_s *device_info =
+	    (struct lowpan_device_s *)connman_device_get_data(device);
+
+	if (!device_info) {
+		ret = -ENODEV;
+		goto bail;
+	}
+
+	if (device_info->ncp_state == NCP_STATE_UPGRADING) {
+		// We can't connect while upgrading.
+		ret = -EBUSY;
+		goto bail;
+	} else if (ncp_state_is_not_associated(device_info->ncp_state)) {
+		lowpan_device_set_network(device, network);
+		ret = lowpan_network_connect_using_join(network);
+	} else if (device_info->ncp_state == NCP_STATE_COMMISSIONED) {
+		if (device_info->current_network == network) {
+			// Do not auto-resume, this is performed automatically by wpantund.
+			// TODO: Check if Autoresume is enabled and allow this if not.
+			// ret = lowpan_network_connect_using_resume(network);
+
+			// Since we know Autoresume is on, we return -EINPROGRESS.
+			ret = -EINPROGRESS;
+		} else {
+			ret = -EBUSY;
+		}
+	} else if (device_info->ncp_state == NCP_STATE_CREDENTIALS_NEEDED) {
+		if (device_info->current_network == network) {
+			ret = lowpan_network_set_key_on_ncp(network);
+
+			if (-ENOKEY == ret) {
+				ret = connman_network_needs_input(network);
+				if (0 != ret) {
+					DBG("connman_network_needs_input(network) failed with %d", ret);
+				}
+			}
+
+			if ((0 != ret) && (-EINPROGRESS != ret)) {
+				connman_network_set_associating(network, false);
+				lowpan_device_leave(device);
+			}
+
+			if (0 == ret) {
+				ret = -EINPROGRESS;
+			}
+		} else {
+			DBG("%p Aborting connection in progress", network);
+			lowpan_device_leave(device);
+			ret = -EAGAIN;
+		}
+	} else if (device_info->ncp_state == NCP_STATE_ASSOCIATING) {
+		if (device_info->current_network == network) {
+			DBG("%p Already connecting to THIS network!", network);
+			ret = -EINPROGRESS;
+		} else {
+			DBG("%p Already connecting to a different network!", network);
+			ret = -EINVAL;
+		}
+	} else if (ncp_state_is_has_joined(device_info->ncp_state)) {
+		if (device_info->current_network == network) {
+			DBG("%p Already connected to THIS network!", network);
+			ret = 0;
+			connman_network_set_connected(network, TRUE);
+		} else if(device_info->current_network && 0 == strcmp(connman_network_get_group(device_info->current_network),connman_network_get_group(network))) {
+			DBG("%p Already connected to THIS service!", network);
+			ret = 0;
+			connman_network_unref(device_info->current_network);
+			device_info->current_network = network;
+			connman_network_ref(device_info->current_network);
+			connman_network_set_connected(network, TRUE);
+		} else {
+			DBG("%p Already connected to an entirely different network, %s!", network, connman_network_get_identifier(device_info->current_network));
+			ret = -EINVAL;
+		}
+	}
+
+bail:
+	DBG("%p ret=%d", network, ret);
+	return ret;
+}
+
+static void
+disconnect_finished_callback(
+    DBusPendingCall *pending, void* user_data
+    )
+{
+}
+
+
+void
+lowpan_device_leave(struct connman_device *device)
+{
+	DBusMessage *message = NULL;
+	char dbus_path[DBUS_MAXIMUM_NAME_LENGTH];
+
+	snprintf(dbus_path,
+	         sizeof(dbus_path),
+	         "%s/%s",
+	         WPAN_TUNNEL_DBUS_PATH,
+	         connman_device_get_ident(device));
+
+	message = dbus_message_new_method_call(
+	    WPAN_TUNNEL_DBUS_NAME,
+	    dbus_path,
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_IFACE_CMD_LEAVE
+	    );
+
+	dbus_connection_send(connection, message, NULL);
+
+	if(message)
+		dbus_message_unref(message);
+}
+
+static void
+lowpan_device_reset(struct connman_device *device)
+{
+	DBusMessage *message = NULL;
+	char dbus_path[DBUS_MAXIMUM_NAME_LENGTH];
+
+	snprintf(dbus_path,
+	         sizeof(dbus_path),
+	         "%s/%s",
+	         WPAN_TUNNEL_DBUS_PATH,
+	         connman_device_get_ident(device));
+
+	message = dbus_message_new_method_call(
+	    WPAN_TUNNEL_DBUS_NAME,
+	    dbus_path,
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_IFACE_CMD_RESET
+	    );
+
+	dbus_connection_send(connection, message, NULL);
+
+	if(message)
+		dbus_message_unref(message);
+}
+
+
+static int
+lowpan_network_disconnect(struct connman_network *network, bool user_initiated)
+{
+	int ret = -EINVAL;
+	bool should_reset = false;
+	struct connman_device* device = connman_network_get_device(network);
+	struct lowpan_device_s *device_info =
+	    (struct lowpan_device_s *)connman_device_get_data(device);
+
+	DBG("%p %s", network, connman_network_get_identifier(network));
+
+	if (!device) {
+		ret = -ENODEV;
+		goto bail;
+	}
+
+	if (!device_info) {
+		ret = -ENODEV;
+		goto bail;
+	}
+
+	if (device_info->current_network != network) {
+		ret = -EINVAL;
+		goto bail;
+	}
+
+	connman_network_set_connected(network, FALSE);
+
+	switch(device_info->ncp_state) {
+	case NCP_STATE_ASSOCIATING:
+	case NCP_STATE_CREDENTIALS_NEEDED:
+		should_reset = true;
+		break;
+
+	case NCP_STATE_OFFLINE:
+		user_initiated = TRUE;
+		break;
+	default:
+		break;
+	}
+
+	if (user_initiated) {
+		lowpan_device_leave(device);
+	} else if (should_reset) {
+		lowpan_device_reset(device);
+	}
+
+	ret = 0;
+
+bail:
+	DBG("%p ret=%d", network, ret);
+	return ret;
+}
+
+int
+lowpan_driver_setprop_int32(struct connman_device *device, const char* key, int32_t value)
+{
+	int ret = 0;
+	DBusMessage *message = NULL;
+	char dbus_path[128];
+
+	snprintf(dbus_path,
+	         sizeof(dbus_path),
+	         "%s/%s",
+	         WPAN_TUNNEL_DBUS_PATH,
+	         connman_device_get_ident(device));
+
+	message = dbus_message_new_method_call(
+	    WPAN_TUNNEL_DBUS_NAME,
+	    dbus_path,
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_IFACE_CMD_SET_PROP
+	    );
+
+	dbus_message_append_args(
+	    message,
+	    DBUS_TYPE_STRING, &key,
+	    DBUS_TYPE_INT32, &value,
+	    DBUS_TYPE_INVALID
+	    );
+
+	if (!dbus_connection_send(
+	        connection,
+	        message,
+	        NULL)) {
+		dbus_message_unref(message);
+		ret = -ENOMEM;
+		goto bail;
+	}
+
+bail:
+	if(message)
+		dbus_message_unref(message);
+	return ret;
+}
+
+int
+lowpan_driver_setprop_data(struct connman_device *device, const char* key, const uint8_t* data, size_t size)
+{
+	int ret = 0;
+	DBusMessage *message = NULL;
+	char dbus_path[128];
+
+	snprintf(dbus_path,
+	         sizeof(dbus_path),
+	         "%s/%s",
+	         WPAN_TUNNEL_DBUS_PATH,
+	         connman_device_get_ident(device));
+
+	message = dbus_message_new_method_call(
+	    WPAN_TUNNEL_DBUS_NAME,
+	    dbus_path,
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_IFACE_CMD_SET_PROP
+	    );
+
+	dbus_message_append_args(
+	    message,
+	    DBUS_TYPE_STRING, &key,
+	    DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, size,
+	    DBUS_TYPE_INVALID
+	    );
+
+	if (!dbus_connection_send(
+	        connection,
+	        message,
+	        NULL)) {
+		dbus_message_unref(message);
+		ret = -ENOMEM;
+		goto bail;
+	}
+
+bail:
+	if(message)
+		dbus_message_unref(message);
+	return ret;
+}
+
+struct lowpan_driver_getprop_state_s {
+	void(*callback)(void* context, int err, const uint8_t* data, size_t len);
+	void* context;
+	struct connman_device* device;
+};
+
+static void
+_lowpan_driver_getprop_data_free(void* user_data)
+{
+	struct lowpan_driver_getprop_state_s* state = user_data;
+	DBG("%p device:%p", state, state->device);
+//	DBG("%p %s", state->device, connman_device_get_ident(state->device));
+
+	if (NULL != state->callback) {
+		(*state->callback)(state->context, -1, NULL, 0);
+		state->callback = NULL;
+	}
+	if(state->device)
+		connman_device_unref(state->device);
+	free(state);
+}
+
+static void
+_lowpan_driver_getprop_data_callback(
+    DBusPendingCall *pending, void* user_data
+    )
+{
+	int32_t ret = 0;
+	struct lowpan_driver_getprop_state_s* state = user_data;
+	DBusMessage* reply = dbus_pending_call_steal_reply(pending);
+	DBusMessageIter iter;
+	const uint8_t* value = NULL;
+	int nelements = 0;
+
+	if (!state) {
+		goto bail;
+	}
+
+	DBG("%p device:%p", state, state->device);
+//	DBG("%p %s", state->device, connman_device_get_ident(state->device));
+
+	if (!reply) {
+		DBG("No reply...?");
+		goto bail;
+	}
+
+	dbus_message_iter_init(reply, &iter);
+
+	// Get return code
+	dbus_message_iter_get_basic(&iter, &ret);
+	dbus_message_iter_next(&iter);
+
+	if (ret == 0) {
+		DBusMessageIter array_iter;
+		dbus_message_iter_recurse(&iter, &array_iter);
+		dbus_message_iter_get_fixed_array(&array_iter, &value, &nelements);
+	}
+
+	if (NULL != state->callback) {
+		(*state->callback)(state->context, ret, value, nelements);
+		state->callback = NULL;
+	}
+
+bail:
+	if (reply) {
+		dbus_message_unref(reply);
+	}
+	if (pending) {
+		dbus_pending_call_unref(pending);
+	}
+
+	DBG("%p ret = %d", state->device, ret);
+	return;
+}
+
+int
+lowpan_driver_getprop_data(struct connman_device *device, const char* key, void(*callback)(void* context, int err, const uint8_t* data, size_t len), void* context)
+{
+	int ret = 0;
+	DBusMessage *message = NULL;
+	DBusPendingCall *pending_call = NULL;
+	struct lowpan_driver_getprop_state_s* state = NULL;
+	char dbus_path[128];
+
+	DBG("%p %s key:%s", device, connman_device_get_ident(device),key);
+
+	snprintf(dbus_path,
+	         sizeof(dbus_path),
+	         "%s/%s",
+	         WPAN_TUNNEL_DBUS_PATH,
+	         connman_device_get_ident(device));
+
+	message = dbus_message_new_method_call(
+	    WPAN_TUNNEL_DBUS_NAME,
+	    dbus_path,
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_IFACE_CMD_GET_PROP
+	    );
+
+	state = calloc(sizeof(*state),1);
+	if(!state) {
+		ret = -ENOMEM;
+		goto bail;
+	}
+	state->context = context;
+	state->callback = callback;
+	state->device = device;
+	connman_device_ref(device);
+
+	dbus_message_append_args(
+	    message,
+	    DBUS_TYPE_STRING, &key,
+	    DBUS_TYPE_INVALID
+	    );
+
+	if (!dbus_connection_send_with_reply(
+	        connection,
+	        message,
+	        &pending_call,
+	        10000 // Ten seconds
+	        )
+	) {
+		ret = -ENOMEM;
+		goto bail;
+	}
+
+	if (!dbus_pending_call_set_notify(
+	        pending_call,
+	        &_lowpan_driver_getprop_data_callback,
+	        (void*)state,
+	        &_lowpan_driver_getprop_data_free
+		)
+	) {
+		ret = -EINVAL;
+		goto bail;
+	}
+
+	DBG("state:%p device:%p ret = %d",state, state->device, ret);
+
+	pending_call = NULL;
+	state = NULL;
+
+bail:
+	DBG("device:%p ret = %d",device, ret);
+
+	if(state)
+		_lowpan_driver_getprop_data_free((void*)state);
+	if(message)
+		dbus_message_unref(message);
+	if(pending_call)
+		dbus_pending_call_cancel(pending_call);
+
+	return ret;
+}
+
+
+static struct connman_network_driver lowpan_network_driver = {
+	.name           = "lowpan",
+	.type           = CONNMAN_NETWORK_TYPE_LOWPAN,
+	.priority       = CONNMAN_NETWORK_PRIORITY_LOW,
+	.probe          = lowpan_network_probe,
+	.remove         = lowpan_network_remove,
+	.connect        = lowpan_network_connect,
+	.disconnect = lowpan_network_disconnect,
+};
+
+/* -------------------------------------------------------------------------- */
+// MARK: - LoWPAN Device
+
+void
+lowpan_device_set_network(struct connman_device *device, struct connman_network *network)
+{
+	struct lowpan_device_s *device_info =
+	    (struct lowpan_device_s *)connman_device_get_data(device);
+
+	if (network != device_info->current_network) {
+		DBG("%p Request to change current network from %p (\"%s\") to %p (\"%s\").", device, device_info->current_network,device_info->current_network?connman_network_get_identifier(device_info->current_network):NULL,network,network?connman_network_get_identifier(network):NULL);
+		if(device_info->current_network
+		   && network
+		   && 0 == strcmp(connman_network_get_group(device_info->current_network),connman_network_get_group(network)))
+		{
+			if(connman_network_get_connected(device_info->current_network)
+			   || connman_network_get_connecting(device_info->current_network)
+			   || connman_network_get_associating(device_info->current_network)
+			   ) {
+				DBG("%p Networks are a part of the same group and a connection is in progress. Network change aborted.", device);
+
+				return;
+			}
+		}
+
+		if (device_info->current_network != NULL) {
+			connman_network_set_index(device_info->current_network, -1);
+			connman_network_unref(device_info->current_network);
+		}
+		device_info->current_network = network;
+		if (device_info->current_network != NULL)
+			connman_network_ref(device_info->current_network);
+		DBG("%p Network change complete.", device);
+	}
+}
+
+int
+lowpan_device_handle_state_change(
+    struct connman_device*  device,
+    ncp_state_t new_state,
+    struct connman_network* network
+    )
+{
+	int ret;
+	struct lowpan_device_s *device_info =
+	    (struct lowpan_device_s *)connman_device_get_data(device);
+
+	if (!ncp_state_is_not_associated(new_state) && !network) {
+		network = device_info->current_network;
+	}
+
+	DBG("%s %d network %p", connman_device_get_ident(device), new_state, network);
+
+	if (network == device_info->current_network
+		&& (new_state == device_info->ncp_state)
+		&& (new_state != NCP_STATE_ASSOCIATED)
+	) {
+		DBG("%s State was already %d", connman_device_get_ident(device), new_state);
+
+		// Skip when nothing has really changed.
+		return 0;
+	}
+
+	if (ncp_state_is_not_associated(new_state)) {
+		// If the previous NCP state is also 'disconnected' or 'uninitialized' ignore the new state change
+		if (ncp_state_is_not_associated(device_info->ncp_state)) {
+			// In case of connecting to a network from 'deep-sleep' we get a 'disconnected' state before change
+			// to 'joining'. In this case, we should ignore the 'disconnected' state change as to not remove the
+			// current_network we are attempting to connect to and fail to connect/join.
+			device_info->ncp_state = new_state;
+			DBG("%s State was already effectively %d", connman_device_get_ident(device), new_state);
+			return 0;
+		}
+
+		connman_device_set_disconnected(device, TRUE);
+
+		if (device_info->current_network != NULL) {
+			memset(&device_info->current_network_info,0,sizeof(device_info->current_network_info));
+			if (connman_network_get_connecting(device_info->current_network))
+				connman_network_set_error(device_info->current_network, CONNMAN_NETWORK_ERROR_CONNECT_FAIL);
+			else if (connman_network_get_associating(device_info->current_network))
+				connman_network_set_error(device_info->current_network, CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
+			else
+				connman_network_set_connected(device_info->current_network, FALSE);
+		}
+		network = NULL;
+	}
+
+	lowpan_device_set_network(device, network);
+	network = device_info->current_network;
+
+	if (ncp_state_is_initializing(new_state)) {
+		return 0;
+	}
+
+	device_info->ncp_state = new_state;
+
+	if (network) {
+		if (new_state == NCP_STATE_COMMISSIONED) {
+			if (connman_network_get_connected(network)) {
+				// Do not auto-resume, this is performed automatically by wpantund.
+				// TODO: Check if Autoresume is enabled and allow this if not.
+				// lowpan_network_connect_using_resume(network);
+			} else if (connman_network_get_connecting(network)
+			           || connman_network_get_associating(network)
+			           ) {
+				connman_network_set_error(network, CONNMAN_NETWORK_ERROR_CONNECT_FAIL);
+			} else {
+				connman_service_connect(connman_service_lookup_from_network(network),
+                        CONNMAN_SERVICE_CONNECT_REASON_USER);
+			}
+		} else if (new_state == NCP_STATE_ASSOCIATING) {
+
+		} else if (new_state == NCP_STATE_CREDENTIALS_NEEDED) {
+			if (connman_network_get_associating(network)) {
+				int err;
+
+				connman_service_create_ip6config(connman_service_lookup_from_network(network), connman_device_get_index(device));
+				connman_network_set_index(network, connman_device_get_index(device));
+				connman_network_set_ipv4_method(network, CONNMAN_IPCONFIG_METHOD_OFF);
+				connman_network_set_ipv6_method(network, CONNMAN_IPCONFIG_METHOD_FIXED);
+
+				err = lowpan_network_set_key_on_ncp(network);
+				if (-ENOKEY == err) {
+					err = connman_network_needs_input(network);
+					if (0 != err) {
+						DBG("connman_network_needs_input(network) failed with %d", err);
+					}
+				}
+
+				if ((0 != err) && (-EINPROGRESS != err)) {
+					connman_network_set_associating(network, false);
+					lowpan_device_leave(device);
+				}
+			}
+
+
+		} else if (new_state == NCP_STATE_NET_WAKE_ASLEEP) {
+			// Don't do anything special when we are in the lurking state.
+
+		} else if (new_state == NCP_STATE_ASSOCIATED) {
+
+			connman_service_create_ip6config(connman_service_lookup_from_network(network), connman_device_get_index(device));
+			connman_network_set_index(network, connman_device_get_index(device));
+			connman_network_set_ipv4_method(network, CONNMAN_IPCONFIG_METHOD_OFF);
+			connman_network_set_ipv6_method(network, CONNMAN_IPCONFIG_METHOD_FIXED);
+
+#if 0
+			/* This part is removed as a solution for COM-1070 (Need temporary workaround for ConnMan supporting only one IPv6 address)
+			 * We'd like the connman to store just the Thread ULA address (which is set by client through network manager)
+			 */
+
+			if (buffer_is_nonzero(device_info->current_network_info.prefix, sizeof(device_info->current_network_info.prefix))) {
+				struct connman_ipaddress *ip_address;
+				char v6_addr_str[56];
+
+				ip_address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV6);
+				encode_ipv6_address_from_prefx_and_hwaddr(v6_addr_str,
+														  sizeof(v6_addr_str),
+														  device_info->current_network_info.prefix,
+														  device_info->hwaddr);
+
+				connman_ipaddress_set_ipv6(ip_address, v6_addr_str, 64, "::");
+
+				connman_network_set_ipaddress(network, ip_address);
+
+				connman_ipaddress_free(ip_address);
+			} else {
+				struct connman_ipaddress *ip_address;
+
+				// If there is no prefix, set an empty address.
+				ip_address = connman_ipaddress_alloc(CONNMAN_IPCONFIG_TYPE_IPV6);
+				connman_ipaddress_set_ipv6(ip_address, "::", 128, "::");
+				connman_network_set_ipaddress(network, ip_address);
+				connman_ipaddress_free(ip_address);
+			}
+
+#endif       /*  End of change for COM-1070 */
+
+			lowpan_network_update_key_from_ncp(network);
+
+			if (!connman_network_get_connected(network)) {
+				if (!connman_network_get_connecting(network)
+				    && !connman_network_get_associating(network)
+				    ) {
+					if(connman_network_get_string(network, LOWPAN_AUTH_KEY)) {
+						DBG("We need to get connman to connect...");
+						connman_service_connect(connman_service_lookup_from_network(network),
+                                CONNMAN_SERVICE_CONNECT_REASON_USER);
+					} else {
+						DBG("Waiting to get network key before asking connman to connect...");
+						// This should happen in a few moments, initiated
+						// by the call to lowpan_network_update_key_from_ncp, above.
+					}
+					return 0;
+				} else {
+					DBG("Marking Network as connected.");
+					connman_network_set_connected(network, TRUE);
+				}
+			} else {
+				DBG("Service/Network already connected.");
+			}
+		}
+	}
+
+	return 0;
+}
+
+
+DBusHandlerResult
+lowpan_device_signal_handler(
+    DBusConnection *connection,
+    DBusMessage *   message,
+    void *                  user_data
+    )
+{
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	struct connman_device* device = user_data;
+	struct lowpan_device_s *device_info =
+	    (struct lowpan_device_s *)connman_device_get_data(device);
+	const char* msg_path = dbus_message_get_path(message);
+	const char* interface_name = connman_device_get_ident(device);
+	char* path = NULL;
+
+	asprintf(&path, "%s/%s", WPAN_TUNNEL_DBUS_PATH, interface_name);
+
+
+	if (!msg_path || (0 != strcmp(path, msg_path)))
+		goto bail;
+
+	if (dbus_message_is_signal(message, WPAN_TUNNEL_DBUS_INTERFACE,
+	                           WPAN_IFACE_SIGNAL_STATE_CHANGED)) {
+		DBusMessageIter iter;
+		const char* new_state = NULL;
+		struct connman_network *network = NULL;
+		struct wpan_network_info_s network_info;
+		bool should_change_device_power_state = false;
+		bool new_device_power_state = false;
+		char network_identifier[256];
+
+		ret = DBUS_HANDLER_RESULT_HANDLED;
+
+		dbus_message_iter_init(message, &iter);
+
+		dbus_message_iter_get_basic(&iter, &new_state);
+
+		if (new_state == NULL) {
+			ret = -EINVAL;
+			goto bail;
+		}
+
+		if (ncp_state_is_initializing(device_info->ncp_state)) {
+			// Make sure that we start up in a powered state.
+			should_change_device_power_state = true;
+			new_device_power_state = true;
+		}
+
+		DBG("AssociationStateChanged: %s", new_state);
+
+		dbus_message_iter_next(&iter);
+
+		network = get_network_from_iter(device, &iter);
+		parse_network_info_from_iter(&device_info->current_network_info, &iter);
+		ncp_state_t ncp_state;
+
+		ncp_state = string_to_ncp_state(new_state, device_info->ncp_state);
+
+
+		DBusMessageIter outer_iter;
+		DBusMessageIter dict_iter;
+		if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_ARRAY) {
+			dbus_message_iter_recurse(&iter, &outer_iter);
+			iter = outer_iter;
+		}
+
+		for (;
+			 dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID;
+			 dbus_message_iter_next(&iter)) {
+			DBusMessageIter value_iter;
+			char* key = NULL;
+
+			if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_DICT_ENTRY) {
+				ret = -1;
+				goto bail;
+			}
+
+			dbus_message_iter_recurse(&iter, &dict_iter);
+
+			if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_STRING) {
+				ret = -1;
+				goto bail;
+			}
+
+			// Get the key
+			dbus_message_iter_get_basic(&dict_iter, &key);
+			dbus_message_iter_next(&dict_iter);
+
+			if(key == NULL) {
+				ret = -EINVAL;
+				goto bail;
+			}
+
+			if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_VARIANT) {
+				ret = -1;
+				goto bail;
+			}
+
+			dbus_message_iter_recurse(&dict_iter, &value_iter);
+
+			if (strcmp(key, "Enabled") == 0) {
+				dbus_bool_t enabled = 0;
+				bool device_power_state = (should_change_device_power_state?
+						new_device_power_state : connman_device_get_powered(device) );
+
+				dbus_message_iter_get_basic(&value_iter, &enabled);
+
+				DBG("NCP IS %s",enabled?"ENABLED":"DISABLED");
+				if (enabled != device_power_state) {
+					if (ncp_state_is_initializing(device_info->ncp_state)) {
+						// If this connman_device is uninitialized/initializing, then we need to make
+						// sure that the NCP is in our current power state.
+						enabled = !enabled;
+						DBG("%sABLING NCP",enabled?"EN":"DIS");
+						lowpan_driver_setprop_int32(device, kWPANTUNDProperty_DaemonEnabled, enabled);
+					} else {
+						// If this connman_device is initialized, then we need to make
+						// sure that our power state matches the power state of the NCP.
+						should_change_device_power_state = true;
+						new_device_power_state = enabled;
+					}
+				}
+			}
+		}
+
+
+		lowpan_device_handle_state_change(device, ncp_state, network);
+
+		if (should_change_device_power_state) {
+			DBG("%sABLING CONNMAN DEVICE",new_device_power_state?"EN":"DIS");
+			connman_device_set_powered(device, new_device_power_state);
+		}
+	}
+
+bail:
+	free(path);
+	return ret;
+}
+
+
+static int
+lowpan_device_probe(struct connman_device *device)
+{
+	DBG("%p %s", device, connman_device_get_ident(device));
+
+	if (dbus_connection_add_filter(connection,
+	                           lowpan_device_signal_handler,
+	                           (void*)device,
+	                           NULL) == FALSE) {
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void
+lowpan_device_remove(struct connman_device *device)
+{
+	DBG("%p %s", device, connman_device_get_ident(device));
+
+	(void)dbus_connection_remove_filter(connection, lowpan_device_signal_handler,
+	                              (void*)device);
+}
+
+
+static int
+lowpan_device_enable(struct connman_device *device)
+{
+	DBG("%p %s", device, connman_device_get_ident(device));
+	lowpan_driver_setprop_int32(device, kWPANTUNDProperty_DaemonEnabled, 1);
+	return 0;
+}
+
+static int
+lowpan_device_disable(struct connman_device *device)
+{
+	DBG("%p %s", device, connman_device_get_ident(device));
+
+	struct lowpan_device_s *device_info = (struct lowpan_device_s *)connman_device_get_data(device);
+	if (device_info) {
+		lowpan_device_set_network(device, NULL);
+		connman_device_set_disconnected(device, TRUE);
+	}
+
+	lowpan_driver_setprop_int32(device, kWPANTUNDProperty_DaemonEnabled, 0);
+	return 0;
+}
+
+static void
+status_finished_callback(
+    DBusPendingCall *pending, void* user_data
+    )
+{
+	int32_t ret = 0;
+	struct connman_device *device = (struct connman_device *)user_data;
+	struct lowpan_device_s *device_info =
+	    (struct lowpan_device_s *)connman_device_get_data(device);
+	struct connman_network *network = NULL;
+	DBusMessage* reply = dbus_pending_call_steal_reply(pending);
+	DBusMessageIter iter;
+	ncp_state_t ncp_state;
+	bool should_change_device_power_state = false;
+	bool new_device_power_state = false;
+
+	DBG("%p %s", device, connman_device_get_ident(device));
+
+	if (!reply) {
+		DBG("%p Status callback failed", device);
+		ret = -1;
+		goto bail;
+	}
+
+	dbus_message_iter_init(reply, &iter);
+	dump_info_from_iter(stderr, &iter, 1, false);
+
+	if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) {
+		char* cstr = NULL;
+		dbus_message_iter_get_basic(&iter,&cstr);
+		DBG("%p Status callback failed: %s", device, cstr);
+		ret = -1;
+		goto bail;
+	}
+
+	parse_network_info_from_iter(&device_info->current_network_info, &iter);
+	network = get_network_from_iter(device, &iter);
+
+	DBusMessageIter outer_iter;
+	DBusMessageIter dict_iter;
+	if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_ARRAY) {
+		dbus_message_iter_recurse(&iter, &outer_iter);
+		iter = outer_iter;
+	}
+
+	if (ncp_state_is_initializing(device_info->ncp_state)) {
+		// Make sure that we start up in a powered state.
+		should_change_device_power_state = true;
+		new_device_power_state = true;
+	}
+
+	ncp_state = device_info->ncp_state;
+
+	for (;
+	     dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID;
+	     dbus_message_iter_next(&iter)) {
+		DBusMessageIter value_iter;
+		char* key = NULL;
+
+		if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_DICT_ENTRY) {
+			ret = -1;
+			goto bail;
+		}
+
+		dbus_message_iter_recurse(&iter, &dict_iter);
+
+		if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_STRING) {
+			ret = -1;
+			goto bail;
+		}
+
+		// Get the key
+		dbus_message_iter_get_basic(&dict_iter, &key);
+		dbus_message_iter_next(&dict_iter);
+
+		if(key == NULL) {
+			ret = -EINVAL;
+			goto bail;
+		}
+
+		if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_VARIANT) {
+			ret = -1;
+			goto bail;
+		}
+
+		dbus_message_iter_recurse(&dict_iter, &value_iter);
+
+		if (strcmp(key, kWPANTUNDProperty_NCPHardwareAddress) == 0) {
+			DBusMessageIter array_iter;
+			dbus_message_iter_recurse(&value_iter, &array_iter);
+			const uint8_t* value = NULL;
+			int nelements = 0;
+			dbus_message_iter_get_fixed_array(&array_iter, &value, &nelements);
+			if (nelements == 8)
+				memcpy(device_info->hwaddr, value, 8);
+			else
+				DBG("%p Bad HWAddr length: %d", device, nelements);
+
+			char hwaddr_str[64];
+			snprintf(hwaddr_str,
+			         sizeof(hwaddr_str),
+			         "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
+			         device_info->hwaddr[0],
+			         device_info->hwaddr[1],
+			         device_info->hwaddr[2],
+			         device_info->hwaddr[3],
+			         device_info->hwaddr[4],
+			         device_info->hwaddr[5],
+			         device_info->hwaddr[6],
+			         device_info->hwaddr[7]);
+			DBG("%p HWAddr set to %s", device, hwaddr_str);
+			connman_device_set_string(device, "Address", hwaddr_str);
+
+			struct connman_ipdevice *ipdevice = NULL;
+			ipdevice = connman_ipdevice_lookup_from_index(connman_device_get_index(device));
+
+			if (ipdevice) {
+				connman_ipdevice_set_address(ipdevice, hwaddr_str);
+				DBG("Set HWAddr on ipdevice! GOOD");
+			} else {
+				DBG("Can't set HWAddr on ipdevice because we can't find the ipdevice!");
+			}
+
+		} else if (strcmp(key, kWPANTUNDProperty_DaemonEnabled) == 0) {
+			dbus_bool_t enabled = FALSE;
+			bool device_power_state = (should_change_device_power_state?
+					new_device_power_state : connman_device_get_powered(device) );
+
+			dbus_message_iter_get_basic(&value_iter, &enabled);
+
+			DBG("NCP IS %s",enabled?"ENABLED":"DISABLED");
+			if (enabled != device_power_state) {
+				if (ncp_state_is_initializing(device_info->ncp_state)) {
+					// If this connman_device is UNinitialized, then we need to make
+					// sure that the NCP is in our current power state.
+					enabled = !enabled;
+					DBG("%sABLING NCP",enabled?"EN":"DIS");
+					lowpan_driver_setprop_int32(device, kWPANTUNDProperty_DaemonEnabled, enabled);
+				} else {
+					// If this connman_device is initialized, then we need to make
+					// sure that our power state matches the power state of the NCP.
+					should_change_device_power_state = true;
+					new_device_power_state = enabled;
+				}
+			}
+
+		} else if (strcmp(key, kWPANTUNDProperty_NetworkKey) == 0) {
+			DBusMessageIter array_iter;
+			dbus_message_iter_recurse(&value_iter, &array_iter);
+			const uint8_t* value = NULL;
+			int nelements = 0;
+			dbus_message_iter_get_fixed_array(&array_iter, &value, &nelements);
+
+			lowpan_network_update_key(network, value, nelements);
+		} else if (strcmp(key, kWPANTUNDProperty_NCPState) == 0) {
+			const char* new_state = NULL;
+			dbus_message_iter_get_basic(&value_iter, &new_state);
+
+			ncp_state = string_to_ncp_state(new_state, ncp_state);
+		} else {
+#if DEBUG
+			DBG(
+			    "info: %s -> (%c)\n",
+			    key,
+			    dbus_message_iter_get_arg_type(&value_iter));
+#endif
+		}
+	}
+
+	lowpan_device_handle_state_change(device, ncp_state, network);
+
+	if (should_change_device_power_state) {
+		DBG("%sABLING CONNMAN DEVICE",new_device_power_state?"EN":"DIS");
+		connman_device_set_powered(device, new_device_power_state);
+	}
+
+bail:
+	if (reply) {
+		dbus_message_unref(reply);
+	}
+	if (pending) {
+		dbus_pending_call_unref(pending);
+	}
+
+	return;
+}
+
+static void
+scan_free_callback(void* user_data)
+{
+	struct connman_device *device = (struct connman_device *)user_data;
+
+	connman_device_unref(device);
+}
+
+
+static int
+lowpan_device_update_status(struct connman_device *device)
+{
+	DBusPendingCall *pending_status = NULL;
+	DBusMessage *message = NULL;
+	char dbus_path[128];
+
+	snprintf(dbus_path,
+	         sizeof(dbus_path),
+	         "%s/%s",
+	         WPAN_TUNNEL_DBUS_PATH,
+	         connman_device_get_ident(device));
+
+	message = dbus_message_new_method_call(
+	    WPAN_TUNNEL_DBUS_NAME,
+	    dbus_path,
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_IFACE_CMD_STATUS
+	);
+
+	if (!dbus_connection_send_with_reply(
+	        connection,
+	        message,
+	        &pending_status,
+	        3000
+		)
+	) {
+		dbus_message_unref(message);
+		return -1;
+	}
+
+	dbus_message_unref(message);
+
+	if (!dbus_pending_call_set_notify(
+	        pending_status,
+	        &status_finished_callback,
+	        (void*)device,
+	        (DBusFreeFunction) & scan_free_callback
+		)
+	) {
+		dbus_pending_call_cancel(pending_status);
+		return -1;
+	}
+
+	connman_device_ref(device);
+
+	return 0;
+}
+
+static void
+scan_finished_callback(
+    DBusPendingCall *pending, void* user_data
+    )
+{
+	int32_t ret = 0;
+	struct connman_device *device = (struct connman_device *)user_data;
+	struct lowpan_device_s *device_info = (struct lowpan_device_s *)connman_device_get_data(device);
+	DBusMessage* reply = dbus_pending_call_steal_reply(pending);
+	DBusMessageIter iter;
+	DBusMessageIter list_iter;
+
+	DBG("%p SCAN CALLBACK", device);
+
+	if (!reply) {
+		DBG("%p Scan reply was empty?", device);
+		ret = -1;
+		goto bail;
+	}
+
+	dbus_message_iter_init(reply, &iter);
+	dump_info_from_iter(stderr, &iter, 1, false);
+
+	if(dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) {
+		char* cstr = NULL;
+		dbus_message_iter_get_basic(&iter,&cstr);
+		DBG("%p Scan failed: %s", device, cstr);
+		ret = -1;
+		connman_device_reset_scanning(device);
+		goto bail;
+	}
+
+
+	// Get return code
+	dbus_message_iter_get_basic(&iter, &ret);
+
+	if (ret) {
+		DBG("%p Scan failed: %d", device, ret);
+		connman_device_reset_scanning(device);
+		goto bail;
+	}
+
+	// Move to the list of networks.
+	dbus_message_iter_next(&iter);
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
+		ret = -1;
+		goto bail;
+	}
+
+	dbus_message_iter_recurse(&iter, &list_iter);
+
+	for (;
+	     dbus_message_iter_get_arg_type(&list_iter) == DBUS_TYPE_ARRAY;
+	     dbus_message_iter_next(&list_iter)) {
+		struct connman_network *network = NULL;
+		char network_name[128];
+
+		network = get_network_from_iter(device, &list_iter);
+
+		if(network == NULL)
+			continue;
+
+		connman_network_set_available(network, TRUE);
+		connman_network_update(network);
+	}
+
+
+bail:
+	if (reply) {
+		dbus_message_unref(reply);
+	}
+	if (pending) {
+		dbus_pending_call_unref(pending);
+	}
+
+	if ((device_info != NULL) && (device_info->current_network != NULL)) {
+		// Always make sure that the current network is marked as
+		// available, so that we don't end up accidentally
+		// disconnecting from it.
+		connman_network_set_available(device_info->current_network, TRUE);
+	}
+
+	connman_device_set_scanning(device, CONNMAN_SERVICE_TYPE_LOWPAN, FALSE);
+	return;
+}
+
+static int
+lowpan_device_scan(enum connman_service_type type,
+    struct connman_device *device,
+    const char *ssid, unsigned int ssid_len,
+    const char *identity, const char* passphrase,
+    const char *security, void* user_data
+    )
+{
+	int status = 0;
+	DBusPendingCall *pending_scan = NULL;
+	DBusMessage *message = NULL;
+	char *dbus_path = NULL;
+	struct lowpan_device_s *device_info =
+	    (struct lowpan_device_s *)connman_device_get_data(device);
+
+	DBG("%p ssid=%s, id=%s, passphrate=%s", device, ssid, identity, passphrase);
+
+	require_action(
+		connman_device_get_scanning(device) == FALSE,
+		bail,
+		status = -EALREADY
+	);
+
+	if (device_info->current_network != NULL) {
+		require_action(
+			connman_network_get_associating(device_info->current_network) == FALSE,
+			bail,
+			status = -EBUSY
+		);
+	}
+
+	require_action(device_info->ncp_state != NCP_STATE_ASSOCIATING, bail, status = -EBUSY);
+	require_action(device_info->ncp_state != NCP_STATE_COMMISSIONED, bail, status = -EBUSY);
+	require_action(!ncp_state_is_initializing(device_info->ncp_state), bail, status = -EBUSY);
+
+	asprintf(&dbus_path,
+	         "%s/%s",
+	         WPAN_TUNNEL_DBUS_PATH,
+	         connman_device_get_ident(device));
+
+	message = dbus_message_new_method_call(
+	    WPAN_TUNNEL_DBUS_NAME,
+	    dbus_path,
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_IFACE_CMD_SCAN
+	);
+
+	require_action(message != NULL, bail, status = -ENOMEM);
+
+	require_action(message != NULL, bail, status = -ENOMEM);
+
+	require_action(
+		dbus_connection_send_with_reply(
+	        connection,
+	        message,
+	        &pending_scan,
+	        45000 // Timeout, in ms
+		) == TRUE,
+		bail,
+		status = -EIO
+	);
+
+	require_action(
+		dbus_pending_call_set_notify(
+	        pending_scan,
+	        &scan_finished_callback,
+	        (void*)device,
+	        (DBusFreeFunction) & scan_free_callback
+		) == TRUE,
+		bail,
+		status = -EIO
+	);
+
+	pending_scan = NULL;
+	connman_device_ref(device);
+	connman_device_set_scanning(device, CONNMAN_SERVICE_TYPE_LOWPAN, TRUE);
+
+bail:
+	free(dbus_path);
+
+	if (pending_scan != NULL) {
+		dbus_pending_call_cancel(pending_scan);
+	}
+
+	if (message != NULL) {
+		dbus_message_unref(message);
+	}
+	return status;
+}
+
+
+static int lowpan_device_set_regdom(
+    struct connman_device *device, const char *alpha2
+    )
+{
+	DBG("%p", device);
+	connman_device_regdom_notify(device, 0, alpha2);
+	return 0;
+}
+
+static struct connman_device_driver lowpan_device_driver = {
+	.name           = "lowpan",
+	.type           = CONNMAN_DEVICE_TYPE_LOWPAN,
+	.priority       = CONNMAN_DEVICE_PRIORITY_LOW,
+	.probe          = lowpan_device_probe,
+	.remove         = lowpan_device_remove,
+	.enable         = lowpan_device_enable,
+	.disable        = lowpan_device_disable,
+	.scan           = lowpan_device_scan,
+	.set_regdom = lowpan_device_set_regdom,
+};
+
+static struct connman_device*
+lowpan_device_create(const char* interface_name)
+{
+	struct connman_device *device = NULL;
+
+	device = g_hash_table_lookup(devices, interface_name);
+	if (!device) {
+		struct lowpan_device_s *device_info =
+		    calloc(1, sizeof(struct lowpan_device_s));
+
+		device = connman_device_create(
+		    "lowpan",
+		    lowpan_device_driver.type
+		    );
+
+		connman_device_set_data(device, device_info);
+
+		g_hash_table_replace(devices, g_strdup(interface_name), device);
+
+		connman_device_set_index(device, connman_inet_ifindex(interface_name));
+		connman_device_set_ident(device, interface_name);
+		connman_device_set_interface(device, interface_name);
+
+		if(connman_device_register(device)<0) {
+			g_hash_table_remove(devices, device);
+			device = NULL;
+		}
+		DBG("device created: %p", device);
+	}
+
+	if(device)
+		lowpan_device_update_status(device);
+
+	return device;
+}
+
+static void
+lowpan_device_finalize(gpointer data)
+{
+	struct connman_device *device = data;
+	struct lowpan_device_s *device_info =
+	    (struct lowpan_device_s *)connman_device_get_data(device);
+
+	DBG("%p %s", device, connman_device_get_ident(device));
+	if (device_info) {
+		if (device_info->current_network) {
+			connman_network_set_connected(device_info->current_network, FALSE);
+		}
+
+		connman_device_remove_network(device, device_info->current_network);
+
+		lowpan_device_set_network(device, NULL);
+
+		free(device_info);
+		connman_device_set_data(device, NULL);
+
+		connman_device_unregister(device);
+
+		connman_device_set_ident(device, "X");
+		connman_device_set_interface(device, "X");
+
+		connman_device_unref(device);
+	}
+}
+
+/* -------------------------------------------------------------------------- */
+// MARK: - LoWPAN Technology
+
+static int
+lowpan_tech_probe(struct connman_technology *technology)
+{
+	DBG("%s: %p", __FUNCTION__, technology);
+	lowpan_tech = technology;
+
+	return 0;
+}
+
+static void
+lowpan_tech_remove(struct connman_technology *technology)
+{
+	DBG("");
+	lowpan_tech = NULL;
+}
+
+static int
+lowpan_tech_set_regdom(
+    struct connman_technology *technology, const char *alpha2
+    )
+{
+	return 0;
+}
+
+static int
+lowpan_tech_set_tethering(
+    struct connman_technology *technology,
+    const char *identifier, const char *passphrase,
+    const char *bridge, bool enabled
+    )
+{
+	return 0;
+}
+
+static struct connman_technology_driver lowpan_tech_driver = {
+	.name           = "lowpan",
+	.type           = CONNMAN_SERVICE_TYPE_LOWPAN,
+	.probe          = lowpan_tech_probe,
+	.remove         = lowpan_tech_remove,
+	.set_regdom = lowpan_tech_set_regdom,
+};
+
+/* -------------------------------------------------------------------------- */
+// MARK: - LoWPAN DBus
+
+static void
+lowpan_dbus_init_interfaces(void)
+{
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error = DBUS_ERROR_INIT;
+	DBusMessageIter iter;
+	DBusMessageIter list_iter;
+
+	DBG("%s", __FUNCTION__);
+
+	message = dbus_message_new_method_call(
+	    WPAN_TUNNEL_DBUS_NAME,
+	    WPAN_TUNNEL_DBUS_PATH,
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_TUNNEL_CMD_GET_INTERFACES
+	    );
+
+	if (!message) {
+		DBG("%s: Unable to create dbus message.", __FUNCTION__);
+		goto bail;
+	}
+
+	reply = dbus_connection_send_with_reply_and_block(
+	    connection,
+	    message,
+	    5000,
+	    &error
+	    );
+
+	if (!reply) {
+		DBG("%s: DBus call to GetInterfaces failed: %s", __FUNCTION__, error.message);
+		goto bail;
+	}
+
+	dbus_message_iter_init(reply, &iter);
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
+		DBG("%s: Bad return type for GetInterfaces", __FUNCTION__);
+		goto bail;
+	}
+
+	dbus_message_iter_recurse(&iter, &list_iter);
+
+	for (;
+	     dbus_message_iter_get_arg_type(&list_iter) != DBUS_TYPE_INVALID;
+	     dbus_message_iter_next(&list_iter)) {
+		DBusMessageIter tmp_iter;
+		DBusMessageIter *this_iter = &list_iter;
+		char *interface_name = NULL;
+
+		if (dbus_message_iter_get_arg_type(this_iter) == DBUS_TYPE_ARRAY) {
+			dbus_message_iter_recurse(this_iter, &tmp_iter);
+			this_iter = &tmp_iter;
+		}
+
+		if (dbus_message_iter_get_arg_type(this_iter) == DBUS_TYPE_STRING) {
+			dbus_message_iter_get_basic(this_iter, &interface_name);
+		}
+
+		if (interface_name != NULL) {
+			DBG("%s: Interface: \"%s\"", __FUNCTION__, interface_name);
+			lowpan_device_create(interface_name);
+		} else {
+			DBG("%s: Unable to extract interface name", __FUNCTION__);
+		}
+	}
+
+bail:
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+}
+
+DBusHandlerResult
+lowpan_signal_handler(
+    DBusConnection *connection,
+    DBusMessage *   message,
+    void *                  user_data
+    )
+{
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	if (dbus_message_is_signal(message, WPAN_TUNNEL_DBUS_INTERFACE,
+	                           WPAN_TUNNEL_SIGNAL_INTERFACE_ADDED)) {
+		const char* interface_name = NULL;
+		DBG("%s", dbus_message_get_path(message));
+
+		dbus_message_get_args(
+		    message, NULL,
+		    DBUS_TYPE_STRING, &interface_name,
+		    DBUS_TYPE_INVALID
+		    );
+
+		DBG("%s: InterfaceAdded: %s", __FUNCTION__, interface_name);
+		lowpan_device_create(interface_name);
+
+		ret = DBUS_HANDLER_RESULT_HANDLED;
+	} else if (dbus_message_is_signal(message, WPAN_TUNNEL_DBUS_INTERFACE,
+	                                  WPAN_TUNNEL_SIGNAL_INTERFACE_REMOVED)) {
+		const char* interface_name = NULL;
+		DBG("%s", dbus_message_get_path(message));
+		dbus_message_get_args(
+		    message, NULL,
+		    DBUS_TYPE_STRING, &interface_name,
+		    DBUS_TYPE_INVALID
+		    );
+
+		DBG("%s: InterfaceRemoved: %s", __FUNCTION__, interface_name);
+
+		struct connman_device *device = g_hash_table_lookup(devices, interface_name);
+
+		g_hash_table_remove(devices, device);
+
+		ret = DBUS_HANDLER_RESULT_HANDLED;
+	} else if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS,
+	                                  "NameOwnerChanged")) {
+		const char* name = NULL;
+		const char* oldOwner = NULL;
+		const char* newOwner = NULL;
+
+		dbus_message_get_args(
+		    message, NULL,
+		    DBUS_TYPE_STRING, &name,
+		    DBUS_TYPE_STRING, &oldOwner,
+		    DBUS_TYPE_STRING, &newOwner,
+		    DBUS_TYPE_INVALID
+		    );
+		if (name && (0 == strcmp(name, WPAN_TUNNEL_DBUS_INTERFACE))) {
+			if(newOwner[0]!=0 && oldOwner[0]==0) {
+				DBG("%s is now ONLINE: \"%s\" (was \"%s\")",name, newOwner, oldOwner);
+			}
+			if(newOwner[0]!=0) {
+				lowpan_dbus_init_interfaces();
+			}
+			if(oldOwner[0]!=0 && newOwner[0]==0) {
+				DBG("%s is now OFFLINE: \"%s\" (was \"%s\")",name, newOwner, oldOwner);
+				g_hash_table_remove_all(devices);
+			}
+		}
+	}
+
+	return ret;
+}
+
+
+static int
+lowpan_dbus_init(void)
+{
+	int ret = 0;
+	DBG("%s", __FUNCTION__);
+
+	// TODO: Add free function!
+	if (dbus_connection_add_filter(connection, lowpan_signal_handler, NULL, NULL) == FALSE) {
+		ret = -EIO;
+		goto bail;
+	}
+
+	static const char *lowpan_dbus_rule0 = "type=signal,"
+	                                       "path=" DBUS_PATH_DBUS ","
+	                                       "sender=" DBUS_SERVICE_DBUS ","
+	                                       "interface=" DBUS_INTERFACE_DBUS ","
+	                                       "member=NameOwnerChanged,"
+	                                       "arg0=" WPAN_TUNNEL_DBUS_NAME;
+	static const char *lowpan_dbus_rule1 = "type=signal,"
+	                                       "interface=" WPAN_TUNNEL_DBUS_INTERFACE;
+
+	dbus_bus_add_match(connection, lowpan_dbus_rule0, NULL);
+	dbus_bus_add_match(connection, lowpan_dbus_rule1, NULL);
+
+	lowpan_dbus_init_interfaces();
+
+bail:
+	return ret;
+}
+
+/* -------------------------------------------------------------------------- */
+// MARK: - LoWPAN Plugin
+
+static int
+lowpan_tunnel_init(void)
+{
+	DBG("%s", __FUNCTION__);
+
+	int err = -1;
+
+	connection = connman_dbus_get_connection();
+	if (connection == NULL) {
+		DBG("%s: No DBUS connection...?", __FUNCTION__);
+		err = -EIO;
+
+		goto out;
+	}
+
+	devices = g_hash_table_new_full(g_str_hash,
+	                                g_str_equal,
+	                                g_free,
+	                                lowpan_device_finalize);
+
+	err = connman_technology_driver_register(&lowpan_tech_driver);
+	if (err < 0)
+		goto out;
+
+	err = connman_network_driver_register(&lowpan_network_driver);
+	if (err < 0) {
+		connman_technology_driver_unregister(&lowpan_tech_driver);
+		goto out;
+	}
+
+	err = connman_device_driver_register(&lowpan_device_driver);
+	if (err < 0) {
+		connman_network_driver_unregister(&lowpan_network_driver);
+		connman_technology_driver_unregister(&lowpan_tech_driver);
+		goto out;
+	}
+
+	err = lowpan_dbus_init();
+	if (err < 0) {
+		connman_device_driver_unregister(&lowpan_device_driver);
+		connman_network_driver_unregister(&lowpan_network_driver);
+		connman_technology_driver_unregister(&lowpan_tech_driver);
+		goto out;
+	}
+
+#if 0
+
+
+	err = connman_device_driver_register(&ethernet_driver);
+	if (err < 0) {
+		connman_network_driver_unregister(&cable_driver);
+		goto out;
+	}
+
+	err = connman_technology_driver_register(&tech_driver);
+	if (err < 0) {
+		connman_device_driver_unregister(&ethernet_driver);
+		connman_network_driver_unregister(&cable_driver);
+		goto out;
+	}
+#endif
+
+	return 0;
+out:
+
+	return err;
+}
+
+static void
+lowpan_tunnel_exit(void)
+{
+	DBG("%s", __FUNCTION__);
+
+	connman_network_driver_unregister(&lowpan_network_driver);
+
+	connman_technology_driver_unregister(&lowpan_tech_driver);
+
+	connman_device_driver_unregister(&lowpan_device_driver);
+
+#if 0
+	connman_technology_driver_unregister(&tech_driver);
+
+	connman_network_driver_unregister(&cable_driver);
+
+	connman_device_driver_unregister(&ethernet_driver);
+#endif
+}
+
+CONNMAN_PLUGIN_DEFINE(
+    lowpan_tunnel,
+    "LoWPAN tunnel plugin",
+    CONNMAN_VERSION,
+    CONNMAN_PLUGIN_PRIORITY_DEFAULT,
+    lowpan_tunnel_init,
+    lowpan_tunnel_exit
+    )
diff --git a/src/ipc-dbus/DBUSIPCServer.cpp b/src/ipc-dbus/DBUSIPCServer.cpp
new file mode 100644
index 0000000..7ee595f
--- /dev/null
+++ b/src/ipc-dbus/DBUSIPCServer.cpp
@@ -0,0 +1,413 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Implementation of the DBus IPCServer subclass.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef ASSERT_MACROS_USE_SYSLOG
+#define ASSERT_MACROS_USE_SYSLOG 1
+#endif
+
+#include <stdio.h>
+#include "DBUSIPCServer.h"
+#include <dbus/dbus.h>
+#if USING_GLIB
+#include <glib.h>
+#include <glib-object.h>
+#endif
+#include <string.h>
+#include "NCPControlInterface.h"
+#include "assert-macros.h"
+
+#include <boost/bind.hpp>
+#include "DBUSHelpers.h"
+#include <errno.h>
+#include <algorithm>
+#include "any-to.h"
+#include "wpan-dbus-v0.h"
+
+using namespace DBUSHelpers;
+using namespace nl;
+using namespace nl::wpantund;
+
+static const char gDBusObjectManagerMatchString[] =
+	"type='signal'"
+	",interface='" WPAN_TUNNEL_DBUS_INTERFACE "'"
+	;
+
+static DBusConnection *
+get_dbus_connection()
+{
+	static DBusConnection* connection = NULL;
+	DBusError error;
+	dbus_error_init(&error);
+
+	if (connection == NULL) {
+		syslog(LOG_DEBUG, "Getting DBus connection");
+
+		connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+		if (!connection) {
+			dbus_error_free(&error);
+			dbus_error_init(&error);
+			connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+		}
+
+		require_string(connection != NULL, bail, error.message);
+
+		syslog(LOG_DEBUG, "Registering DBus connection");
+
+		dbus_bus_register(connection, &error);
+
+		require_string(error.name == NULL, bail, error.message);
+
+		syslog(LOG_DEBUG, "Requesting DBus connection name %s", WPAN_TUNNEL_DBUS_NAME);
+
+		dbus_bus_request_name(
+			connection,
+			WPAN_TUNNEL_DBUS_NAME,
+			0,
+			&error
+		);
+
+		require_string(error.name == NULL, bail, error.message);
+	}
+
+bail:
+	if (error.message) {
+		throw std::runtime_error(error.message);
+	}
+	dbus_error_free(&error);
+
+	return connection;
+}
+
+DBUSIPCServer::DBUSIPCServer():
+	mConnection(get_dbus_connection()),
+	mAPI_v0(mConnection),
+	mAPI_v1(mConnection)
+{
+	DBusError error;
+
+	dbus_error_init(&error);
+
+	static const DBusObjectPathVTable ipc_interface_vtable = {
+		NULL,
+		&DBUSIPCServer::dbus_message_handler,
+	};
+
+	require(
+		dbus_connection_register_object_path(
+			mConnection,
+			WPAN_TUNNEL_DBUS_PATH,
+			&ipc_interface_vtable,
+			(void*)this
+		),
+		bail
+	);
+
+	dbus_bus_add_match(
+		mConnection,
+		gDBusObjectManagerMatchString,
+		&error
+	);
+	require_string(error.name == NULL, bail, error.message);
+
+	dbus_connection_add_filter(mConnection, &DBUSIPCServer::dbus_message_handler, (void*)this, NULL);
+
+	syslog(LOG_NOTICE, "Ready. Using DBUS bus \"%s\"", dbus_bus_get_unique_name(mConnection));
+
+bail:
+	if (error.message) {
+		throw std::runtime_error(error.message);
+	}
+	dbus_error_free(&error);
+}
+
+DBUSIPCServer::~DBUSIPCServer()
+{
+	dbus_bus_remove_match(
+		mConnection,
+		gDBusObjectManagerMatchString,
+		NULL
+	);
+	dbus_connection_unref(mConnection);
+}
+
+cms_t
+DBUSIPCServer::get_ms_to_next_event()
+{
+	cms_t ret = CMS_DISTANT_FUTURE;
+
+	/* We could set up some sort of complicated mechanism
+	 * using the dbus_timer objects to actually calculate this
+	 * correctly, however we aren't really using any of the
+	 * timer-dependent stuff in DBus. As such, the following
+	 * seems to suffice. If we want wpantund to do things
+	 * like handle response timeouts in a timely manner then
+	 * we will need to go ahead and fully implement such a
+	 * mechanism. */
+
+	if (dbus_connection_get_dispatch_status(mConnection) == DBUS_DISPATCH_DATA_REMAINS) {
+		ret = 0;
+	}
+
+	if (dbus_connection_has_messages_to_send(mConnection)) {
+		ret = 0;
+	}
+
+	return ret;
+}
+
+void
+DBUSIPCServer::process(void)
+{
+	dbus_connection_read_write_dispatch(mConnection, 0);
+}
+
+int
+DBUSIPCServer::update_fd_set(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *error_fd_set, int *max_fd, cms_t *timeout)
+{
+	int ret = -1;
+	int unix_fd = -1;
+
+	require(dbus_connection_get_unix_fd(mConnection, &unix_fd), bail);
+
+	if (read_fd_set != NULL) {
+		FD_SET(unix_fd, read_fd_set);
+	}
+
+	if (error_fd_set != NULL) {
+		FD_SET(unix_fd, error_fd_set);
+	}
+
+	if ((write_fd_set != NULL) && dbus_connection_has_messages_to_send(mConnection)) {
+		FD_SET(unix_fd, write_fd_set);
+	}
+
+	if ((max_fd != NULL)) {
+		*max_fd = std::max(*max_fd, unix_fd);
+	}
+
+	if (timeout != NULL) {
+		*timeout = std::min(*timeout, get_ms_to_next_event());
+	}
+
+	ret = 0;
+bail:
+	return ret;
+}
+
+
+
+void
+DBUSIPCServer::interface_added(const std::string& interface_name)
+{
+	DBusMessage* signal;
+	const char *interface_name_cstr = interface_name.c_str();
+
+	syslog(LOG_DEBUG,
+	       "DBus Sending Interface Added Signal for %s",
+	       interface_name_cstr);
+	signal = dbus_message_new_signal(
+	    WPAN_TUNNEL_DBUS_PATH,
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_TUNNEL_SIGNAL_INTERFACE_ADDED
+	    );
+	dbus_message_append_args(
+	    signal,
+	    DBUS_TYPE_STRING, &interface_name_cstr,
+	    DBUS_TYPE_INVALID
+	    );
+
+	dbus_connection_send(mConnection, signal, NULL);
+	dbus_message_unref(signal);
+}
+
+void
+DBUSIPCServer::interface_removed(const std::string& interface_name)
+{
+	DBusMessage* signal;
+	const char *interface_name_cstr = interface_name.c_str();
+
+	syslog(LOG_DEBUG,
+	       "DBus Sending Interface Added Signal for %s",
+	       interface_name_cstr);
+	signal = dbus_message_new_signal(
+	    WPAN_TUNNEL_DBUS_PATH,
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    "InterfaceRemoved"
+	    );
+	dbus_message_append_args(
+	    signal,
+	    DBUS_TYPE_STRING, &interface_name_cstr,
+	    DBUS_TYPE_INVALID
+	    );
+	dbus_connection_send(mConnection, signal, NULL);
+	dbus_message_unref(signal);
+}
+
+int
+DBUSIPCServer::add_interface(NCPControlInterface* instance)
+{
+	std::string name = instance->get_name();
+
+	mInterfaceMap[name] = instance;
+
+	mAPI_v0.add_interface(instance);
+	mAPI_v1.add_interface(instance);
+
+	interface_added(name);
+
+	return 0;
+}
+
+DBusHandlerResult
+DBUSIPCServer::message_handler(
+    DBusConnection *connection,
+    DBusMessage *message
+    )
+{
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	if (dbus_message_is_method_call(message, WPAN_TUNNEL_DBUS_INTERFACE,
+	                                WPAN_TUNNEL_CMD_GET_INTERFACES)) {
+		DBusMessage *reply = dbus_message_new_method_return(message);
+		DBusMessageIter iter, array_iter;
+		dbus_message_iter_init_append(reply, &iter);
+
+		dbus_message_iter_open_container(
+		    &iter,
+		    DBUS_TYPE_ARRAY,
+			DBUS_TYPE_ARRAY_AS_STRING
+		    DBUS_TYPE_STRING_AS_STRING,
+		    &array_iter
+		    );
+		{
+			std::map<std::string, NCPControlInterface*>::const_iterator i;
+			std::map<std::string,
+					 NCPControlInterface*>::const_iterator end =
+				mInterfaceMap.end();
+			for (i = mInterfaceMap.begin(); i != end; ++i) {
+				DBusMessageIter item_iter;
+				const char* name = i->first.c_str();
+				const char* bus_name = dbus_bus_get_unique_name(connection);
+				dbus_message_iter_open_container(
+					&array_iter,
+					DBUS_TYPE_ARRAY,
+					DBUS_TYPE_STRING_AS_STRING,
+					&item_iter
+					);
+				dbus_message_iter_append_basic(&item_iter, DBUS_TYPE_STRING,
+											   &name);
+				dbus_message_iter_append_basic(&item_iter, DBUS_TYPE_STRING,
+											   &bus_name);
+				dbus_message_iter_close_container(&array_iter, &item_iter);
+			}
+		}
+		{
+			std::map<std::string, std::string>::const_iterator i;
+			std::map<std::string, std::string>::const_iterator end =
+				mExternalInterfaceMap.end();
+			for (i = mExternalInterfaceMap.begin(); i != end; ++i) {
+				DBusMessageIter item_iter;
+				const char* name = i->first.c_str();
+				const char* bus_name = i->second.c_str();
+				dbus_message_iter_open_container(
+					&array_iter,
+					DBUS_TYPE_ARRAY,
+					DBUS_TYPE_STRING_AS_STRING,
+					&item_iter
+					);
+				dbus_message_iter_append_basic(&item_iter, DBUS_TYPE_STRING,
+											   &name);
+				dbus_message_iter_append_basic(&item_iter, DBUS_TYPE_STRING,
+											   &bus_name);
+				dbus_message_iter_close_container(&array_iter, &item_iter);
+			}
+		}
+
+		dbus_message_iter_close_container(&iter, &array_iter);
+
+		dbus_connection_send(connection, reply, NULL);
+		dbus_message_unref(reply);
+
+		ret = DBUS_HANDLER_RESULT_HANDLED;
+	} else if (dbus_message_is_signal(message, WPAN_TUNNEL_DBUS_INTERFACE, WPAN_TUNNEL_SIGNAL_INTERFACE_ADDED)) {
+		ret = DBUS_HANDLER_RESULT_HANDLED;
+		if (!strequal(dbus_message_get_sender(message), dbus_bus_get_unique_name(connection))) {
+			const char* interface_name = NULL;
+			dbus_message_get_args(
+				message, NULL,
+				DBUS_TYPE_STRING, &interface_name,
+				DBUS_TYPE_INVALID
+			);
+			if (NULL != interface_name && (mInterfaceMap.count(interface_name) == 0)) {
+				mExternalInterfaceMap[interface_name] = dbus_message_get_sender(message);
+			}
+		}
+	} else if (dbus_message_is_signal(message, WPAN_TUNNEL_DBUS_INTERFACE, WPAN_TUNNEL_SIGNAL_INTERFACE_REMOVED)) {
+		ret = DBUS_HANDLER_RESULT_HANDLED;
+		if (!strequal(dbus_message_get_sender(message), dbus_bus_get_unique_name(connection))) {
+			const char* interface_name = NULL;
+			dbus_message_get_args(
+				message, NULL,
+				DBUS_TYPE_STRING, &interface_name,
+				DBUS_TYPE_INVALID
+			);
+			if ((NULL != interface_name)
+				&& (mInterfaceMap.count(interface_name) == 0)
+				&& (mExternalInterfaceMap.count(interface_name) == 1)
+				&& (mExternalInterfaceMap[interface_name] == dbus_message_get_sender(message))
+			) {
+				mExternalInterfaceMap.erase(interface_name);
+			}
+		}
+	} else if (dbus_message_is_method_call(message, WPAN_TUNNEL_DBUS_INTERFACE,
+	                                WPAN_TUNNEL_CMD_GET_VERSION)) {
+		DBusMessage *reply = dbus_message_new_method_return(message);
+		uint32_t version = WPAN_TUNNEL_DBUS_VERSION;
+		dbus_message_append_args(
+			reply,
+			DBUS_TYPE_UINT32, &version,
+			DBUS_TYPE_INVALID
+			);
+
+		dbus_connection_send(connection, reply, NULL);
+		dbus_message_unref(reply);
+
+		ret = DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	return ret;
+}
+
+DBusHandlerResult
+DBUSIPCServer::dbus_message_handler(
+    DBusConnection *connection,
+    DBusMessage *   message,
+    void *                  user_data
+    )
+{
+	return ((DBUSIPCServer*)user_data)->message_handler(connection, message);
+}
diff --git a/src/ipc-dbus/DBUSIPCServer.h b/src/ipc-dbus/DBUSIPCServer.h
new file mode 100644
index 0000000..0a4ade4
--- /dev/null
+++ b/src/ipc-dbus/DBUSIPCServer.h
@@ -0,0 +1,76 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Declaration of the DBus IPCServer subclass.
+ *
+ */
+
+#ifndef wpantund_DBUSIPCServer_h
+#define wpantund_DBUSIPCServer_h
+
+#include "IPCServer.h"
+#include <map>
+#include <dbus/dbus.h>
+#include <boost/signals2/signal.hpp>
+#include <boost/bind.hpp>
+
+#include "DBusIPCAPI_v0.h"
+#include "DBusIPCAPI_v1.h"
+
+namespace nl {
+namespace wpantund {
+
+class DBUSIPCServer : public IPCServer {
+public:
+
+	DBUSIPCServer();
+	virtual ~DBUSIPCServer();
+
+	virtual int add_interface(NCPControlInterface* instance);
+	virtual cms_t get_ms_to_next_event(void );
+	virtual void process(void);
+	virtual int update_fd_set(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *error_fd_set, int *max_fd, cms_t *timeout);
+
+private:
+	DBusHandlerResult message_handler(
+	    DBusConnection *connection,
+	    DBusMessage *   message
+	    );
+
+	static DBusHandlerResult dbus_message_handler(
+	    DBusConnection *connection,
+	    DBusMessage *   message,
+	    void *                  user_data
+	    );
+
+	void interface_added(const std::string& interface_name);
+	void interface_removed(const std::string& interface_name);
+
+private:
+	DBusConnection *mConnection;
+	std::map<std::string, NCPControlInterface*> mInterfaceMap;
+	std::map<std::string, std::string> mExternalInterfaceMap;
+	DBusIPCAPI_v0 mAPI_v0;
+	DBusIPCAPI_v1 mAPI_v1;
+};
+
+};
+};
+
+
+#endif
diff --git a/src/ipc-dbus/DBusIPCAPI_v0.cpp b/src/ipc-dbus/DBusIPCAPI_v0.cpp
new file mode 100644
index 0000000..8874712
--- /dev/null
+++ b/src/ipc-dbus/DBusIPCAPI_v0.cpp
@@ -0,0 +1,1626 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include <string.h>
+#include <errno.h>
+#include <algorithm>
+
+#include <boost/bind.hpp>
+
+#include <dbus/dbus.h>
+
+#include "DBusIPCAPI_v0.h"
+#include "wpan-dbus-v0.h"
+
+#include "NCPControlInterface.h"
+#include "NCPTypes.h"
+#include "NCPMfgInterface_v0.h"
+#include "assert-macros.h"
+
+#include "DBUSHelpers.h"
+#include "any-to.h"
+#include "wpan-error.h"
+
+using namespace DBUSHelpers;
+using namespace nl;
+using namespace nl::wpantund;
+
+DBusIPCAPI_v0::DBusIPCAPI_v0(DBusConnection *connection)
+	:mConnection(connection)
+{
+	dbus_connection_ref(mConnection);
+	init_callback_tables();
+}
+
+DBusIPCAPI_v0::~DBusIPCAPI_v0()
+{
+	dbus_connection_unref(mConnection);
+}
+
+void
+DBusIPCAPI_v0::init_callback_tables()
+{
+#define INTERFACE_CALLBACK_CONNECT(cmd_name, member_func) \
+	mInterfaceCallbackTable[(cmd_name)] = boost::bind( \
+		&DBusIPCAPI_v0::member_func, this, _1, _2)
+
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_JOIN, interface_join_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_FORM, interface_form_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_BEGIN_NET_WAKE, interface_begin_net_wake_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_PERMIT_JOIN, interface_permit_join_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_LEAVE, interface_leave_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_DATA_POLL, interface_data_poll_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_CONFIG_GATEWAY, interface_config_gateway_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_ADD_ROUTE, interface_add_route_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_REMOVE_ROUTE, interface_remove_route_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_BEGIN_LOW_POWER, interface_begin_low_power_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_PING, interface_ping_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_HOST_DID_WAKE, interface_host_did_wake_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_STOP_SCAN, interface_stop_scan_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_GET_PROP, interface_get_prop_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_SET_PROP, interface_set_prop_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_RESET, interface_reset_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_STATUS, interface_status_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_ACTIVE_SCAN, interface_active_scan_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_RESUME, interface_resume_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_MFG_BEGIN_TEST, interface_mfg_begin_test_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_MFG_END_TEST, interface_mfg_end_test_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_MFG_TX_PACKET, interface_mfg_tx_packet_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_MFG_FINISH, interface_mfg_finish_handler);
+
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_MFG_CLOCKMON, interface_mfg_clockmon_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_MFG_GPIO_SET, interface_mfg_gpio_set_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_MFG_GPIO_GET, interface_mfg_gpio_get_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_MFG_CHANNELCAL, interface_mfg_channelcal_handler);
+	INTERFACE_CALLBACK_CONNECT(WPAN_IFACE_CMD_MFG_CHANNELCAL_GET, interface_mfg_channelcal_get_handler);
+}
+
+void
+DBusIPCAPI_v0::CallbackWithStatus_Helper(
+    int ret, DBusMessage *original_message
+    )
+{
+	DBusMessage *reply = dbus_message_new_method_return(original_message);
+
+	syslog(LOG_DEBUG, "Sending DBus response for \"%s\" to \"%s\"", dbus_message_get_member(original_message), dbus_message_get_sender(original_message));
+
+	if(reply) {
+		dbus_message_append_args(
+			reply,
+			DBUS_TYPE_INT32, &ret,
+			DBUS_TYPE_INVALID
+			);
+
+		dbus_connection_send(mConnection, reply, NULL);
+		dbus_message_unref(reply);
+	}
+	dbus_message_unref(original_message);
+}
+
+static void
+ipc_append_network_properties(
+    DBusMessageIter *iter, const WPAN::NetworkInstance& network
+    )
+{
+	const char* network_name = network.name.c_str();
+
+	if (network_name[0])
+		append_dict_entry(iter,
+		                  "NetworkName",
+		                  DBUS_TYPE_STRING,
+		                  &network_name);
+
+	if (network.get_xpanid_as_uint64() != 0) {
+		uint64_t xpan_id = network.get_xpanid_as_uint64();
+		append_dict_entry(iter, "XPanId", DBUS_TYPE_UINT64, &xpan_id);
+	}
+
+	if (network.panid && network.panid != 0xFFFF) {
+		uint16_t pan_id = network.panid;
+		append_dict_entry(iter, "PanId", DBUS_TYPE_UINT16, &pan_id);
+	}
+
+	if (network.channel) {
+		uint16_t channel = network.channel;
+		append_dict_entry(iter, "Channel", DBUS_TYPE_INT16, &channel);
+
+		if (network.rssi != -128) {
+			int8_t rssi = network.rssi;
+			append_dict_entry(iter, "RSSI", DBUS_TYPE_BYTE, &rssi);
+		}
+
+		dbus_bool_t allowing_join = network.joinable;
+		append_dict_entry(iter,
+		                  "AllowingJoin",
+		                  DBUS_TYPE_BOOLEAN,
+		                  &allowing_join);
+	}
+
+	if (network.type != 0) {
+		int32_t type = network.type;
+		append_dict_entry(iter, "Type", DBUS_TYPE_INT32, &type);
+	}
+
+	if (network.get_hwaddr_as_uint64() != 0)
+		append_dict_entry(iter, "BeaconHWAddr",
+		                  nl::Data(network.hwaddr, 8));
+
+}
+
+static void
+ipc_append_network_dict(
+    DBusMessageIter *iter, const WPAN::NetworkInstance& network
+    )
+{
+	DBusMessageIter dict;
+
+	dbus_message_iter_open_container(
+	    iter,
+	    DBUS_TYPE_ARRAY,
+	    DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+	    DBUS_TYPE_STRING_AS_STRING
+	    DBUS_TYPE_VARIANT_AS_STRING
+	    DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+	    &dict
+	    );
+	ipc_append_network_properties(&dict, network);
+
+
+	dbus_message_iter_close_container(iter, &dict);
+}
+
+static void
+ipc_append_networks(
+    DBusMessageIter *iter, const std::list<WPAN::NetworkInstance>& networks
+    )
+{
+	DBusMessageIter array;
+
+	dbus_message_iter_open_container(
+	    iter,
+	    DBUS_TYPE_ARRAY,
+	    DBUS_TYPE_ARRAY_AS_STRING
+	    DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+	    DBUS_TYPE_STRING_AS_STRING
+	    DBUS_TYPE_VARIANT_AS_STRING
+	    DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+	    &array
+	    );
+
+	std::list<WPAN::NetworkInstance>::const_iterator i;
+	std::list<WPAN::NetworkInstance>::const_iterator end = networks.end();
+	for (i = networks.begin(); i != end; ++i) {
+		ipc_append_network_dict(&array, *i);
+	}
+
+	dbus_message_iter_close_container(iter, &array);
+}
+
+void
+DBusIPCAPI_v0::received_beacon(NCPControlInterface* interface, const WPAN::NetworkInstance& network)
+{
+	mReceivedBeacons.push_back(network);
+}
+
+void
+DBusIPCAPI_v0::scan_response_helper(
+    int ret,
+    DBusMessage *                                                   original_message
+)
+{
+	DBusMessage *reply = dbus_message_new_method_return(original_message);
+
+	if(reply) {
+		DBusMessageIter msg_iter;
+		dbus_message_append_args(
+			reply,
+			DBUS_TYPE_INT32, &ret,
+			DBUS_TYPE_INVALID
+			);
+
+		dbus_message_iter_init_append(reply, &msg_iter);
+
+		ipc_append_networks(&msg_iter, mReceivedBeacons);
+
+		dbus_connection_send(mConnection, reply, NULL);
+		dbus_message_unref(reply);
+	}
+	dbus_message_unref(original_message);
+}
+
+void
+DBusIPCAPI_v0::status_response_helper(
+    int ret, NCPControlInterface* interface, DBusMessage *message
+    )
+{
+	DBusMessage *reply = dbus_message_new_method_return(message);
+
+	if (reply) {
+		DBusMessageIter iter;
+		dbus_message_iter_init_append(reply, &iter);
+
+		DBusMessageIter dict;
+		boost::any value;
+		NCPState ncp_state = UNINITIALIZED;
+		std::string ncp_state_string;
+		const char* ncp_state_cstr = kWPANTUNDStateUninitialized;
+
+		dbus_message_iter_open_container(
+			&iter,
+			DBUS_TYPE_ARRAY,
+			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+			DBUS_TYPE_STRING_AS_STRING
+			DBUS_TYPE_VARIANT_AS_STRING
+			DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+			&dict
+		);
+
+		value = interface->get_property(kWPANTUNDProperty_NCPState);
+
+		if (!value.empty()) {
+			ncp_state_string = any_to_string(value);
+			ncp_state = string_to_ncp_state(ncp_state_string);
+			ncp_state_cstr = ncp_state_string.c_str();
+		}
+
+		append_dict_entry(&dict,
+						  kWPANTUNDProperty_NCPState,
+						  DBUS_TYPE_STRING,
+						  &ncp_state_cstr);
+
+		if (ncp_state_is_commissioned(ncp_state))
+		{
+			value = interface->get_property(kWPANTUNDProperty_NetworkName);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NetworkName, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_NetworkXPANID);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NetworkXPANID, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_NetworkPANID);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NetworkPANID, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_NCPChannel);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NCPChannel, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_IPv6LinkLocalAddress);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_IPv6LinkLocalAddress, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_IPv6MeshLocalAddress);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_IPv6MeshLocalAddress, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_NestLabs_LegacyMeshLocalAddress);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NestLabs_LegacyMeshLocalAddress, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_IPv6MeshLocalPrefix);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_IPv6MeshLocalPrefix, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_NestLabs_NetworkAllowingJoin);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NestLabs_NetworkAllowingJoin, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_NetworkNodeType);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NetworkNodeType, value);
+			}
+		}
+
+		value = interface->get_property(kWPANTUNDProperty_DaemonEnabled);
+		if (!value.empty()) {
+			append_dict_entry(&dict, kWPANTUNDProperty_DaemonEnabled, value);
+		}
+
+		value = interface->get_property(kWPANTUNDProperty_NCPVersion);
+		if (!value.empty()) {
+			append_dict_entry(&dict, kWPANTUNDProperty_NCPVersion, value);
+		}
+
+		value = interface->get_property(kWPANTUNDProperty_DaemonVersion);
+		if (!value.empty()) {
+			append_dict_entry(&dict, kWPANTUNDProperty_DaemonVersion, value);
+		}
+
+		value = interface->get_property(kWPANTUNDProperty_NCPHardwareAddress);
+		if (!value.empty()) {
+			append_dict_entry(&dict, kWPANTUNDProperty_NCPHardwareAddress, value);
+		}
+
+		dbus_message_iter_close_container(&iter, &dict);
+
+		dbus_connection_send(mConnection, reply, NULL);
+		dbus_message_unref(reply);
+	}
+	dbus_message_unref(message);
+}
+
+void
+DBusIPCAPI_v0::CallbackWithStatusArg1_Helper(
+    int status, const boost::any& value, DBusMessage *message
+)
+{
+	DBusMessage *reply = dbus_message_new_method_return(message);
+	DBusMessageIter iter;
+
+	syslog(LOG_DEBUG, "Sending getprop response");
+
+	dbus_message_iter_init_append(reply, &iter);
+
+	if (!status && value.empty()) {
+		status = kWPANTUNDStatus_PropertyEmpty;
+	}
+
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &status);
+
+	if (value.empty()) {
+		append_any_to_dbus_iter(&iter, std::string("<empty>"));
+	} else {
+		append_any_to_dbus_iter(&iter, value);
+	}
+
+	dbus_connection_send(mConnection, reply, NULL);
+	dbus_message_unref(message);
+	dbus_message_unref(reply);
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_join_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	const char* network_name = NULL;
+	int16_t node_type_int16 = ROUTER;
+	ValueMap options;
+	uint64_t xpanid;
+	uint16_t panid = 0xFFFF;
+	uint8_t channel = 0;
+
+	dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_STRING, &network_name,
+		DBUS_TYPE_INT16, &node_type_int16,
+		DBUS_TYPE_UINT64, &xpanid,
+		DBUS_TYPE_UINT16, &panid,
+		DBUS_TYPE_BYTE, &channel,
+		DBUS_TYPE_INVALID
+	);
+
+	require(network_name != NULL, bail);
+
+	options[kWPANTUNDProperty_NetworkName] = std::string(network_name);
+	options[kWPANTUNDProperty_NetworkXPANID] = xpanid;
+	options[kWPANTUNDProperty_NetworkPANID] = panid;
+	options[kWPANTUNDProperty_NCPChannel] = channel;
+
+	if (node_type_int16) {
+		options[kWPANTUNDProperty_NetworkNodeType] = (int)node_type_int16;
+	}
+
+	dbus_message_ref(message);
+
+	interface->join(
+		options,
+		boost::bind(
+			&DBusIPCAPI_v0::CallbackWithStatus_Helper,
+			this,
+			_1,
+			message
+		)
+	);
+
+bail:
+
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_form_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	const char* network_name;
+	ValueMap options;
+	int16_t node_type_int16 = 0;
+	NCPControlInterface::ChannelMask channel_mask = 0;
+	uint8_t *ula_prefix = NULL;
+	int ula_prefix_len = 0;
+
+	dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_STRING, &network_name,
+		DBUS_TYPE_INT16, &node_type_int16,
+		DBUS_TYPE_UINT32, &channel_mask,
+		DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &ula_prefix, &ula_prefix_len,
+		DBUS_TYPE_INVALID
+	);
+
+	if (node_type_int16) {
+		options[kWPANTUNDProperty_NetworkNodeType] = (int)node_type_int16;
+	}
+
+	if (channel_mask) {
+		options[kWPANTUNDProperty_NCPChannelMask] = channel_mask;
+	}
+
+	if (ula_prefix_len) {
+		options[kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix] = Data(ula_prefix, ula_prefix_len);
+	}
+
+	{	// The mesh local prefix can be set by setting it before forming.
+		boost::any value;
+		value = interface->get_property(kWPANTUNDProperty_IPv6MeshLocalPrefix);
+		if (!value.empty()) {
+			options[kWPANTUNDProperty_IPv6MeshLocalPrefix] = value;
+		}
+	}
+
+	options[kWPANTUNDProperty_NetworkName] = std::string(network_name);
+
+	dbus_message_ref(message);
+
+	interface->form(
+		options,
+		boost::bind(
+			&DBusIPCAPI_v0::CallbackWithStatus_Helper,
+			this,
+			_1,
+			message
+		)
+	);
+
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_begin_net_wake_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	uint8_t data = 0;
+	uint32_t flags = 0;
+
+	dbus_message_ref(message);
+	dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_BYTE, &data,
+		DBUS_TYPE_UINT32, &flags,
+		DBUS_TYPE_INVALID
+		);
+
+	interface->begin_net_wake(
+		data,
+		flags,
+		boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper, this, _1,
+					message)
+	);
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_permit_join_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	int32_t seconds = -1;
+	dbus_bool_t network_wide = FALSE;
+	uint8_t commissioning_traffic_type = 0xFF;
+	in_port_t commissioning_traffic_port = 0;
+
+	dbus_message_ref(message);
+	dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_INT32, &seconds,
+		DBUS_TYPE_BOOLEAN, &network_wide,
+		DBUS_TYPE_UINT16, &commissioning_traffic_port,
+		DBUS_TYPE_BYTE, &commissioning_traffic_type,
+		DBUS_TYPE_INVALID
+		);
+	commissioning_traffic_port = htons(commissioning_traffic_port);
+
+	if(seconds==-1)
+		seconds = 5*60;
+
+	interface->permit_join(
+		seconds,
+		commissioning_traffic_type,
+		commissioning_traffic_port,
+		network_wide,
+		boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper, this, _1,
+					message)
+		);
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_leave_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->leave(boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper,
+								 this, _1, message));
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_data_poll_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->data_poll(boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper,
+								 this, _1, message));
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_config_gateway_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	dbus_bool_t defaultRoute = FALSE;
+	uint32_t preferredLifetime = 0;
+	uint32_t validLifetime = 0;
+	uint8_t *prefix = NULL;
+	struct in6_addr addr = {};
+	int prefixLen = 0;
+
+	dbus_message_ref(message);
+	dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_BOOLEAN, &defaultRoute,
+		DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &prefix, &prefixLen,
+		DBUS_TYPE_UINT32, &preferredLifetime,
+		DBUS_TYPE_UINT32, &validLifetime,
+		DBUS_TYPE_INVALID
+	);
+
+	if (prefixLen > 16) {
+		prefixLen = 16;
+	}
+
+	memcpy(addr.s6_addr, prefix, prefixLen);
+
+	if (validLifetime == 0) {
+		interface->remove_on_mesh_prefix(
+			&addr,
+			boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper,this, _1, message)
+		);
+	} else {
+		interface->add_on_mesh_prefix(
+			&addr,
+			defaultRoute,
+			boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper,this, _1, message)
+		);
+	}
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_add_route_handler(
+   NCPControlInterface* interface,
+   DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	uint8_t *prefix = NULL;
+	struct in6_addr addr = {};
+	int prefix_len = 0;
+	uint16_t domain_id = 0;
+	int16_t priority_raw;
+	NCPControlInterface::ExternalRoutePriority priority;
+
+	dbus_message_ref(message);
+	dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &prefix, &prefix_len,
+		DBUS_TYPE_UINT16, &domain_id,
+		DBUS_TYPE_INT16, &priority_raw,
+		DBUS_TYPE_INVALID
+	);
+
+	if (prefix_len > 16) {
+		prefix_len = 16;
+	}
+
+	memcpy(addr.s6_addr, prefix, prefix_len);
+
+	priority = NCPControlInterface::ROUTE_MEDIUM_PREFERENCE;
+	if  (priority_raw > 0) {
+		priority = NCPControlInterface::ROUTE_HIGH_PREFERENCE;
+	} else if (priority_raw < 0) {
+		priority = NCPControlInterface::ROUTE_LOW_PREFRENCE;
+	}
+
+	interface->add_external_route(
+		&addr,
+		IPV6_PREFIX_BYTES_TO_BITS(prefix_len),
+		domain_id,
+		priority,
+		boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper, this, _1, message)
+	);
+
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_remove_route_handler(
+   NCPControlInterface* interface,
+   DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	uint8_t *prefix = NULL;
+	struct in6_addr addr = {};
+	int prefix_len = 0;
+	uint16_t domain_id = 0;
+
+	dbus_message_ref(message);
+	dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &prefix, &prefix_len,
+		DBUS_TYPE_UINT16, &domain_id,
+		DBUS_TYPE_INVALID
+	);
+
+	if (prefix_len > 16) {
+		prefix_len = 16;
+	}
+
+	memcpy(addr.s6_addr, prefix, prefix_len);
+
+	interface->remove_external_route(
+		&addr,
+		IPV6_PREFIX_BYTES_TO_BITS(prefix_len),
+		domain_id,
+		boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper, this, _1, message)
+	);
+
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_begin_low_power_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->begin_low_power(boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper,
+								 this, _1, message));
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_ping_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->refresh_state(boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper,
+								 this, _1, message));
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_host_did_wake_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->host_did_wake(boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper,
+								 this, _1, message));
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_stop_scan_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->netscan_stop(boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper,
+									 this, _1, message));
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_get_prop_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	const char* property_key_cstr = "";
+	std::string property_key;
+	dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_STRING, &property_key_cstr,
+		DBUS_TYPE_INVALID
+		);
+
+	property_key = property_key_cstr;
+
+	if (interface->translate_deprecated_property(property_key)) {
+		syslog(LOG_WARNING, "GetProp: Property \"%s\" is deprecated. Please use \"%s\" instead.", property_key_cstr, property_key.c_str());
+	}
+
+	dbus_message_ref(message);
+	interface->get_property(property_key,
+							boost::bind(&DBusIPCAPI_v0::CallbackWithStatusArg1_Helper, this,
+										_1, _2, message));
+
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_set_prop_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	DBusMessageIter iter;
+	const char* property_key_cstr = "";
+	std::string property_key;
+	boost::any property_value;
+
+	dbus_message_iter_init(message, &iter);
+
+	require (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING, bail);
+
+	dbus_message_iter_get_basic(&iter, &property_key_cstr);
+	dbus_message_iter_next(&iter);
+
+	property_value = any_from_dbus_iter(&iter);
+	property_key = property_key_cstr;
+
+	if (interface->translate_deprecated_property(property_key, property_value)) {
+		syslog(LOG_WARNING, "SetProp: Property \"%s\" is deprecated. Please use \"%s\" instead.", property_key_cstr, property_key.c_str());
+	}
+
+	dbus_message_ref(message);
+	interface->set_property(
+		property_key,
+		property_value,
+		boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper, this, _1,
+					message)
+		);
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+bail:
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_reset_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->reset(boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper,
+								 this, _1, message));
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_status_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	NCPState ncp_state = UNINITIALIZED;
+	boost::any value(interface->get_property(kWPANTUNDProperty_NCPState));
+
+	if (!value.empty()) {
+		ncp_state = string_to_ncp_state(any_to_string(value));
+	}
+
+	if (ncp_state_is_sleeping(ncp_state)
+	 || ncp_state_is_detached_from_ncp(ncp_state)
+	 || (ncp_state == UNINITIALIZED)
+	) {
+		status_response_helper(0, interface, message);
+	} else {
+		interface->refresh_state(boost::bind(&DBusIPCAPI_v0::
+										 status_response_helper, this, _1, interface, message));
+	}
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_active_scan_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	int32_t period = 0;
+	ValueMap options;
+	NCPControlInterface::ChannelMask channel_mask = 0;
+
+	dbus_message_ref(message);
+
+	dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_INT32, &period,
+		DBUS_TYPE_UINT32, &channel_mask,
+		DBUS_TYPE_INVALID
+	);
+
+	if (channel_mask) {
+		options[kWPANTUNDProperty_NCPChannelMask] = channel_mask;
+	}
+
+	if (period) {
+		// Ignoring period for now
+	}
+
+	mReceivedBeacons.clear();
+
+	interface->netscan_start(
+		options,
+		boost::bind(
+			&DBusIPCAPI_v0::scan_response_helper,
+			this,
+			_1,
+			message
+		)
+	);
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_resume_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->attach(boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper,
+								  this, _1, message));
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_mfg_finish_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	NCPMfgInterface_v0* mfg_interface(dynamic_cast<NCPMfgInterface_v0*>(interface));
+
+	if (mfg_interface) {
+		dbus_message_ref(message);
+
+		mfg_interface->mfg_finish(
+			boost::bind(
+				&DBusIPCAPI_v0::CallbackWithStatusArg1_Helper,
+				this,
+				_1,
+				_2,
+				message
+			)
+		);
+
+		ret = DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_mfg_begin_test_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	NCPMfgInterface_v0* mfg_interface(dynamic_cast<NCPMfgInterface_v0*>(interface));
+
+	if (mfg_interface) {
+		dbus_message_ref(message);
+
+		int16_t test_type = 0;
+
+		dbus_message_get_args(
+			message, NULL,
+			DBUS_TYPE_INT16, &test_type
+		);
+
+		mfg_interface->mfg_begin_test(
+			test_type,
+			boost::bind(
+				&DBusIPCAPI_v0::CallbackWithStatus_Helper,
+				this,
+				_1,
+				message
+			)
+		);
+
+		ret = DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_mfg_end_test_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	int16_t test_type = 0;
+	NCPMfgInterface_v0* mfg_interface(dynamic_cast<NCPMfgInterface_v0*>(interface));
+
+	if (mfg_interface) {
+		dbus_message_ref(message);
+
+		dbus_message_get_args(
+			message, NULL,
+			DBUS_TYPE_INT16, &test_type
+		);
+
+		mfg_interface->mfg_end_test(test_type, boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper,this, _1, message));
+
+		ret = DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_mfg_tx_packet_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	const uint8_t *packet_data = NULL;
+	int packet_length = 0;
+	int16_t repeat = 1;
+	NCPMfgInterface_v0* mfg_interface(dynamic_cast<NCPMfgInterface_v0*>(interface));
+
+	if (mfg_interface) {
+		dbus_message_ref(message);
+
+		dbus_message_get_args(
+			message, NULL,
+			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &packet_data, &packet_length,
+			DBUS_TYPE_INT16, &repeat,
+			DBUS_TYPE_INVALID
+		);
+
+		mfg_interface->mfg_tx_packet(
+			Data(packet_data, packet_length),
+			repeat,
+			boost::bind(&DBusIPCAPI_v0::CallbackWithStatus_Helper,this, _1, message)
+		);
+
+		ret = DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::message_handler(
+    NCPControlInterface* interface,
+    DBusConnection *        connection,
+    DBusMessage *           message
+    )
+{
+	if ((dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
+		&& dbus_message_has_interface(message, WPAN_TUNNEL_DBUS_INTERFACE)
+		&& mInterfaceCallbackTable.count(dbus_message_get_member(message))
+	) {
+		return mInterfaceCallbackTable[dbus_message_get_member(message)](
+			interface,
+			message
+		);
+	}
+
+	return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_mfg_clockmon_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	NCPMfgInterface_v0* mfg_interface(dynamic_cast<NCPMfgInterface_v0*>(interface));
+
+	if (mfg_interface) {
+		dbus_message_ref(message);
+
+		dbus_bool_t enabled;
+		uint32_t timerId;
+
+		dbus_message_get_args(
+			message, NULL,
+			DBUS_TYPE_BOOLEAN, &enabled,
+			DBUS_TYPE_UINT32, &timerId,
+			DBUS_TYPE_INVALID
+		);
+
+		mfg_interface->mfg_clockmon(
+			static_cast<bool>(enabled),
+			timerId,
+			boost::bind(
+				&DBusIPCAPI_v0::CallbackWithStatus_Helper,
+				this,
+				_1,
+				message
+			)
+		);
+
+		ret = DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_mfg_gpio_set_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	NCPMfgInterface_v0* mfg_interface(dynamic_cast<NCPMfgInterface_v0*>(interface));
+
+	if (mfg_interface) {
+		dbus_message_ref(message);
+
+		uint8_t port_pin;
+		uint8_t config;
+		uint8_t value;
+
+		dbus_message_get_args(
+			message, NULL,
+			DBUS_TYPE_BYTE, &port_pin,
+			DBUS_TYPE_BYTE, &config,
+			DBUS_TYPE_BYTE, &value,
+			DBUS_TYPE_INVALID
+		);
+
+		mfg_interface->mfg_gpio_set(
+			port_pin,
+			config,
+			value,
+			boost::bind(
+				&DBusIPCAPI_v0::CallbackWithStatus_Helper,
+				this,
+				_1,
+				message
+			)
+		);
+
+		ret = DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_mfg_gpio_get_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	NCPMfgInterface_v0* mfg_interface(dynamic_cast<NCPMfgInterface_v0*>(interface));
+
+	if (mfg_interface) {
+		dbus_message_ref(message);
+
+		uint8_t port_pin;
+
+		dbus_message_get_args(
+			message, NULL,
+			DBUS_TYPE_BYTE, &port_pin,
+			DBUS_TYPE_INVALID
+		);
+
+		mfg_interface->mfg_gpio_get(
+			port_pin,
+			boost::bind(
+				&DBusIPCAPI_v0::CallbackWithStatusArg1_Helper,
+				this,
+				_1,
+				_2,
+				message
+			)
+		);
+
+		ret = DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	return ret;
+}
+
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_mfg_channelcal_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	NCPMfgInterface_v0* mfg_interface(dynamic_cast<NCPMfgInterface_v0*>(interface));
+
+	if (mfg_interface) {
+		dbus_message_ref(message);
+
+		uint8_t channel;
+		uint32_t duration;
+
+		dbus_message_get_args(
+			message, NULL,
+			DBUS_TYPE_BYTE, &channel,
+			DBUS_TYPE_UINT32, &duration,
+			DBUS_TYPE_INVALID
+		);
+
+		mfg_interface->mfg_channelcal(
+			channel,
+			duration,
+			boost::bind(
+				&DBusIPCAPI_v0::CallbackWithStatus_Helper,
+				this,
+				_1,
+				message
+			)
+		);
+
+		ret = DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v0::interface_mfg_channelcal_get_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	NCPMfgInterface_v0* mfg_interface(dynamic_cast<NCPMfgInterface_v0*>(interface));
+
+	if (mfg_interface) {
+		dbus_message_ref(message);
+
+		uint8_t channel;
+
+		dbus_message_get_args(
+			message, NULL,
+			DBUS_TYPE_BYTE, &channel,
+			DBUS_TYPE_INVALID
+		);
+
+		mfg_interface->mfg_channelcal_get(
+			channel,
+			boost::bind(
+				&DBusIPCAPI_v0::CallbackWithStatusArg1_Helper,
+				this,
+				_1,
+				_2,
+				message
+			)
+		);
+
+		ret = DBUS_HANDLER_RESULT_HANDLED;
+	}
+
+	return ret;
+}
+
+void
+DBusIPCAPI_v0::ncp_state_changed(NCPControlInterface* interface)
+{
+	DBusMessage* signal;
+	boost::any value;
+	NCPState ncp_state = UNINITIALIZED;
+	std::string ncp_state_str;
+	const char* ncp_state_cstr = kWPANTUNDStateUninitialized;
+
+	value = interface->get_property(kWPANTUNDProperty_NCPState);
+
+	if (!value.empty()) {
+		ncp_state_str = any_to_string(value);
+		ncp_state = string_to_ncp_state(ncp_state_str);
+		ncp_state_cstr = ncp_state_str.c_str();
+	}
+
+	DBusMessageIter iter;
+
+	syslog(LOG_DEBUG,
+	       "DBus Sending Association State Changed to %s",
+	       ncp_state_cstr);
+	signal = dbus_message_new_signal(
+	    (std::string(WPAN_TUNNEL_DBUS_PATH) + "/" + interface->get_name()).c_str(),
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_IFACE_SIGNAL_STATE_CHANGED
+	    );
+	dbus_message_append_args(
+	    signal,
+	    DBUS_TYPE_STRING, &ncp_state_cstr,
+	    DBUS_TYPE_INVALID
+	    );
+
+	dbus_message_iter_init_append(signal, &iter);
+
+	DBusMessageIter dict;
+
+	dbus_message_iter_open_container(
+	    &iter,
+	    DBUS_TYPE_ARRAY,
+	    DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+	    DBUS_TYPE_STRING_AS_STRING
+	    DBUS_TYPE_VARIANT_AS_STRING
+	    DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+	    &dict
+	    );
+
+	append_dict_entry(&dict, kWPANTUNDProperty_DaemonEnabled, interface->get_property(kWPANTUNDProperty_DaemonEnabled));
+
+	if (ncp_state_is_commissioned(ncp_state)) {
+		ipc_append_network_properties(&dict,
+	                              interface->get_current_network_instance());
+		boost::any prefix = interface->get_property(kWPANTUNDProperty_IPv6MeshLocalPrefix);
+		if (!prefix.empty()) {
+			append_dict_entry(&dict, kWPANTUNDProperty_IPv6MeshLocalPrefix, prefix);
+		}
+
+		prefix = interface->get_property(kWPANTUNDProperty_NestLabs_LegacyMeshLocalAddress);
+		if (!prefix.empty()) {
+			append_dict_entry(&dict, kWPANTUNDProperty_NestLabs_LegacyMeshLocalAddress, prefix);
+		}
+
+		append_dict_entry(&dict, kWPANTUNDProperty_NetworkNodeType, interface->get_property(kWPANTUNDProperty_NetworkNodeType));
+
+		if (ncp_state >= ASSOCIATED) {
+			boost::any networkKey = interface->get_property(kWPANTUNDProperty_NetworkKey);
+			if (!networkKey.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NetworkKey, networkKey);
+			}
+		}
+	}
+
+	dbus_message_iter_close_container(&iter, &dict);
+
+	dbus_connection_send(mConnection, signal, NULL);
+	dbus_message_unref(signal);
+}
+
+
+static void
+ObjectPathUnregisterFunction_cb(DBusConnection *connection, void *user_data)
+{
+	delete (std::pair<NCPControlInterface*, DBusIPCAPI_v0*> *)user_data;
+}
+
+int
+DBusIPCAPI_v0::add_interface(NCPControlInterface* interface)
+{
+	static const DBusObjectPathVTable ipc_interface_vtable = {
+		&ObjectPathUnregisterFunction_cb,
+		&DBusIPCAPI_v0::dbus_message_handler,
+	};
+
+	std::string name = interface->get_name();
+	std::string path = std::string(WPAN_TUNNEL_DBUS_PATH) + "/" + name;
+
+	std::pair<NCPControlInterface*, DBusIPCAPI_v0*> *cb_data =
+	    new std::pair<NCPControlInterface*, DBusIPCAPI_v0*>(interface, this);
+
+	NCPMfgInterface_v0* mfg_interface(dynamic_cast<NCPMfgInterface_v0*>(interface));
+
+	require(dbus_connection_register_object_path(
+	            mConnection,
+	            path.c_str(),
+	            &ipc_interface_vtable,
+	            (void*)cb_data
+	            ), bail);
+
+	if (mfg_interface) {
+		mfg_interface->mOnMfgRXPacket.connect(
+			boost::bind(
+				&DBusIPCAPI_v0::mfg_rx_packet,
+				this,
+				interface,
+				_1,
+				_2,
+				_3
+			)
+		);
+	}
+
+	interface->mOnPropertyChanged.connect(
+	    boost::bind(
+			&DBusIPCAPI_v0::property_changed,
+			this,
+			interface,
+			_1,
+			_2
+		)
+	);
+
+	interface->mOnNetScanBeacon.connect(
+	    boost::bind(
+			&DBusIPCAPI_v0::received_beacon,
+			this,
+			interface,
+			_1
+		)
+	);
+
+bail:
+	return 0;
+}
+
+void
+DBusIPCAPI_v0::property_changed(NCPControlInterface* interface,const std::string& key, const boost::any& value)
+{
+	DBusMessage* signal;
+	DBusMessageIter iter;
+	std::string key_as_path;
+	std::string path;
+
+	// Transform the key into a DBus-compatible path
+	for (std::string::const_iterator i = key.begin();
+		i != key.end();
+		++i
+	) {
+		const char c = *i;
+		if (isalnum(c) || (c == '_')) {
+			key_as_path += c;
+		} else if (c == ':') {
+			key_as_path += '/';
+		} else if (c == '.') {
+			key_as_path += '_';
+		}
+	}
+
+	if (key == kWPANTUNDProperty_NestLabs_NetworkWakeRemaining) {
+		uint8_t data = static_cast<uint8_t>(any_to_int(interface->get_property(kWPANTUNDProperty_NestLabs_NetworkWakeData)));
+		net_wake_event(interface, data, any_to_int(value));
+	} else if (key == kWPANTUNDProperty_DaemonReadyForHostSleep) {
+		if (any_to_bool(value)) {
+			allow_sleep(interface);
+		} else {
+			prevent_sleep(interface);
+		}
+	} else if (key == kWPANTUNDProperty_NCPState) {
+		ncp_state_changed(interface);
+	} else if (key == kWPANTUNDProperty_NetworkNodeType) {
+		property_changed(interface, "NCPNodeType", value);
+	}
+
+	signal = dbus_message_new_signal(
+		(
+			std::string(WPAN_TUNNEL_DBUS_PATH) + "/" + interface->get_name()
+			+ "/" + WPAN_TUNNEL_DBUS_PATH_PROPERTIES + "/" + key_as_path
+		).c_str(),
+		WPAN_TUNNEL_DBUS_INTERFACE,
+		WPAN_IFACE_SIGNAL_PROPERTY_CHANGED
+	);
+
+	dbus_message_iter_init_append(signal, &iter);
+
+	append_any_to_dbus_iter(&iter, key);
+	append_any_to_dbus_iter(&iter, value);
+
+	dbus_connection_send(mConnection, signal, NULL);
+	dbus_message_unref(signal);
+}
+
+void
+DBusIPCAPI_v0::net_wake_event(NCPControlInterface* interface,uint8_t data, cms_t ms_remaining)
+{
+	DBusMessage* signal;
+
+	signal = dbus_message_new_signal(
+	    (std::string(WPAN_TUNNEL_DBUS_PATH) + "/" + interface->get_name()).c_str(),
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_IFACE_SIGNAL_NET_WAKE
+	    );
+	dbus_message_append_args(
+	    signal,
+	    DBUS_TYPE_BYTE, &data,
+	    DBUS_TYPE_INT32, &ms_remaining,
+	    DBUS_TYPE_INVALID
+	);
+
+	dbus_connection_send(mConnection, signal, NULL);
+	dbus_message_unref(signal);
+}
+
+void
+DBusIPCAPI_v0::mfg_rx_packet(NCPControlInterface* interface, Data packet, uint8_t lqi, int8_t rssi)
+{
+	DBusMessageIter iter;
+	DBusMessage* signal;
+
+	signal = dbus_message_new_signal(
+	    (std::string(WPAN_TUNNEL_DBUS_PATH) + "/" + interface->get_name()).c_str(),
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_IFACE_SIGNAL_MFG_RX
+	    );
+
+	dbus_message_iter_init_append(signal, &iter);
+
+	append_any_to_dbus_iter(&iter, packet);
+	append_any_to_dbus_iter(&iter, lqi);
+	append_any_to_dbus_iter(&iter, rssi);
+
+	dbus_connection_send(mConnection, signal, NULL);
+	dbus_message_unref(signal);
+}
+
+void
+DBusIPCAPI_v0::prevent_sleep(NCPControlInterface* interface)
+{
+	DBusMessage* signal;
+
+	signal = dbus_message_new_signal(
+	    (std::string(WPAN_TUNNEL_DBUS_PATH) + "/" + interface->get_name()).c_str(),
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_IFACE_SIGNAL_PREVENT_SLEEP
+	);
+	dbus_connection_send(mConnection, signal, NULL);
+	dbus_message_unref(signal);
+}
+
+void
+DBusIPCAPI_v0::allow_sleep(NCPControlInterface* interface)
+{
+	DBusMessage* signal;
+
+	signal = dbus_message_new_signal(
+	    (std::string(WPAN_TUNNEL_DBUS_PATH) + "/" + interface->get_name()).c_str(),
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_IFACE_SIGNAL_ALLOW_SLEEP
+	);
+	dbus_connection_send(mConnection, signal, NULL);
+	dbus_message_unref(signal);
+}
+
+
+DBusHandlerResult
+DBusIPCAPI_v0::dbus_message_handler(
+    DBusConnection *connection,
+    DBusMessage *   message,
+    void *                  user_data
+    )
+{
+	if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL) {
+		syslog(LOG_INFO, "Inbound DBus message for INTERFACE \"%s\" from \"%s\"", dbus_message_get_member(message), dbus_message_get_sender(message));
+	}
+	std::pair<NCPControlInterface*,
+	          DBusIPCAPI_v0*> *cb_data =
+	    (std::pair<NCPControlInterface*, DBusIPCAPI_v0*> *)user_data;
+	return cb_data->second->message_handler(cb_data->first,
+	                                                  connection,
+	                                                  message);
+}
diff --git a/src/ipc-dbus/DBusIPCAPI_v0.h b/src/ipc-dbus/DBusIPCAPI_v0.h
new file mode 100644
index 0000000..390d73c
--- /dev/null
+++ b/src/ipc-dbus/DBusIPCAPI_v0.h
@@ -0,0 +1,218 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef wpantund_DBusIPCAPI_v0_h
+#define wpantund_DBusIPCAPI_v0_h
+
+#include <map>
+#include <list>
+
+#include <dbus/dbus.h>
+
+#include <boost/bind.hpp>
+#include <boost/any.hpp>
+#include <boost/function.hpp>
+
+#include "NetworkInstance.h"
+#include "Data.h"
+#include "time-utils.h"
+
+namespace nl {
+namespace wpantund {
+
+class NCPControlInterface;
+
+class DBusIPCAPI_v0 {
+public:
+	DBusIPCAPI_v0(DBusConnection *connection);
+	~DBusIPCAPI_v0();
+
+	int add_interface(NCPControlInterface* interface);
+
+private:
+
+	DBusHandlerResult message_handler(
+		NCPControlInterface* interface,
+		DBusConnection *connection,
+		DBusMessage *message
+    );
+
+	static DBusHandlerResult dbus_message_handler(
+		DBusConnection *connection,
+		DBusMessage *message,
+		void *user_data
+	);
+
+	void init_callback_tables(void);
+
+	// ------------------------------------------------------------------------
+
+	void CallbackWithStatus_Helper(int ret, DBusMessage *original_message);
+	void CallbackWithStatusArg1_Helper(int ret, const boost::any& value, DBusMessage *original_message);
+
+	void status_response_helper(int ret, NCPControlInterface* interface, DBusMessage *original_message);
+	void scan_response_helper(int ret, DBusMessage *original_message);
+
+	// ------------------------------------------------------------------------
+
+	void ncp_state_changed(NCPControlInterface* interface);
+	void net_wake_event(NCPControlInterface* interface,uint8_t data, cms_t ms_remaining);
+	void prevent_sleep(NCPControlInterface* interface);
+	void allow_sleep(NCPControlInterface* interface);
+	void property_changed(NCPControlInterface* interface,const std::string& key, const boost::any& value);
+	void received_beacon(NCPControlInterface* interface, const WPAN::NetworkInstance& network);
+
+	void mfg_rx_packet(NCPControlInterface* interface, nl::Data packet, uint8_t lqi, int8_t rssi);
+
+	// ------------------------------------------------------------------------
+
+	DBusHandlerResult interface_join_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_form_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_begin_net_wake_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_permit_join_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_add_route_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_remove_route_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_leave_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_data_poll_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_config_gateway_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_begin_low_power_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_ping_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_host_did_wake_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_stop_scan_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_get_prop_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_set_prop_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_reset_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_status_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_active_scan_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_resume_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_mfg_begin_test_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_mfg_end_test_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_mfg_tx_packet_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_mfg_finish_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+	DBusHandlerResult interface_mfg_clockmon_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_mfg_gpio_set_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_mfg_gpio_get_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_mfg_channelcal_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_mfg_channelcal_get_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+private:
+	typedef DBusHandlerResult (interface_handler_cb)(
+		NCPControlInterface*,
+		DBusMessage *
+	);
+
+	DBusConnection *mConnection;
+	std::list<WPAN::NetworkInstance> mReceivedBeacons;
+	std::map<std::string, boost::function<interface_handler_cb> > mInterfaceCallbackTable;
+
+}; // class DBusIPCAPI_v0
+
+}; // namespace nl
+}; // namespace wpantund
+
+
+#endif
diff --git a/src/ipc-dbus/DBusIPCAPI_v1.cpp b/src/ipc-dbus/DBusIPCAPI_v1.cpp
new file mode 100644
index 0000000..1ac9160
--- /dev/null
+++ b/src/ipc-dbus/DBusIPCAPI_v1.cpp
@@ -0,0 +1,1239 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+#include <algorithm>
+
+#include <boost/bind.hpp>
+
+#include <dbus/dbus.h>
+
+#include "wpan-dbus-v1.h"
+#include "DBusIPCAPI_v1.h"
+#include "wpan-error.h"
+
+#include "NCPControlInterface.h"
+#include "NCPMfgInterface_v1.h"
+#include "assert-macros.h"
+
+#include "DBUSHelpers.h"
+#include "any-to.h"
+
+using namespace DBUSHelpers;
+using namespace nl;
+using namespace nl::wpantund;
+
+DBusIPCAPI_v1::DBusIPCAPI_v1(DBusConnection *connection)
+	:mConnection(connection)
+{
+	dbus_connection_ref(mConnection);
+	init_callback_tables();
+}
+
+DBusIPCAPI_v1::~DBusIPCAPI_v1()
+{
+	dbus_connection_unref(mConnection);
+}
+
+void
+DBusIPCAPI_v1::init_callback_tables()
+{
+#define INTERFACE_CALLBACK_CONNECT(cmd_name, member_func) \
+	mInterfaceCallbackTable[(cmd_name)] = boost::bind( \
+		&DBusIPCAPI_v1::member_func, this, _1, _2)
+
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_RESET, interface_reset_handler);
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_STATUS, interface_status_handler);
+
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_JOIN, interface_join_handler);
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_FORM, interface_form_handler);
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_LEAVE, interface_leave_handler);
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_ATTACH, interface_attach_handler);
+
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_ROUTE_ADD, interface_route_add_handler);
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_ROUTE_REMOVE, interface_route_remove_handler);
+
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_DATA_POLL, interface_data_poll_handler);
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_CONFIG_GATEWAY, interface_config_gateway_handler);
+
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_BEGIN_LOW_POWER, interface_begin_low_power_handler);
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_HOST_DID_WAKE, interface_host_did_wake_handler);
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_NET_SCAN_STOP, interface_net_scan_stop_handler);
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_NET_SCAN_START, interface_net_scan_start_handler);
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_ENERGY_SCAN_STOP, interface_energy_scan_stop_handler);
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_ENERGY_SCAN_START, interface_energy_scan_start_handler);
+
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_MFG, interface_mfg_handler);
+
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_PROP_GET, interface_get_prop_handler);
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_PROP_SET, interface_set_prop_handler);
+
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_PCAP_TO_FD, interface_pcap_to_fd_handler);
+	INTERFACE_CALLBACK_CONNECT(WPANTUND_IF_CMD_PCAP_TERMINATE, interface_pcap_terminate_handler);
+}
+
+static void
+ObjectPathUnregisterFunction_cb(DBusConnection *connection, void *user_data)
+{
+	delete (std::pair<NCPControlInterface*, DBusIPCAPI_v1*> *)user_data;
+}
+
+std::string
+DBusIPCAPI_v1::path_for_iface(NCPControlInterface* interface)
+{
+	return std::string(WPANTUND_DBUS_PATH) + "/" + interface->get_name();
+}
+
+int
+DBusIPCAPI_v1::add_interface(NCPControlInterface* interface)
+{
+	static const DBusObjectPathVTable ipc_interface_vtable = {
+		&ObjectPathUnregisterFunction_cb,
+		&DBusIPCAPI_v1::dbus_message_handler,
+	};
+
+	std::string name = interface->get_name();
+	std::string path = std::string(WPANTUND_DBUS_PATH) + "/" + name;
+
+	std::pair<NCPControlInterface*, DBusIPCAPI_v1*> *cb_data =
+	    new std::pair<NCPControlInterface*, DBusIPCAPI_v1*>(interface, this);
+
+	require(dbus_connection_register_object_path(
+	            mConnection,
+	            path.c_str(),
+	            &ipc_interface_vtable,
+	            (void*)cb_data
+	            ), bail);
+
+	interface->mOnPropertyChanged.connect(
+	    boost::bind(
+			&DBusIPCAPI_v1::property_changed,
+			this,
+			interface,
+			_1,
+			_2
+		)
+	);
+
+	interface->mOnNetScanBeacon.connect(
+	    boost::bind(
+			&DBusIPCAPI_v1::received_beacon,
+			this,
+			interface,
+			_1
+		)
+	);
+
+	interface->mOnEnergyScanResult.connect(
+		boost::bind(
+			&DBusIPCAPI_v1::received_energy_scan_result,
+			this,
+			interface,
+			_1
+		)
+	);
+
+
+bail:
+	return 0;
+}
+
+void
+DBusIPCAPI_v1::CallbackWithStatus_Helper(int ret, DBusMessage *original_message)
+{
+	DBusMessage *reply = dbus_message_new_method_return(original_message);
+
+	syslog(LOG_DEBUG, "Sending DBus response for \"%s\" to \"%s\"", dbus_message_get_member(original_message), dbus_message_get_sender(original_message));
+
+	if(reply) {
+		dbus_message_append_args(
+			reply,
+			DBUS_TYPE_INT32, &ret,
+			DBUS_TYPE_INVALID
+		);
+
+		dbus_connection_send(mConnection, reply, NULL);
+		dbus_message_unref(reply);
+	}
+	dbus_message_unref(original_message);
+}
+
+static void
+ipc_append_network_properties(
+    DBusMessageIter *iter, const WPAN::NetworkInstance& network
+    )
+{
+	const char* network_name = network.name.c_str();
+
+	if (network_name[0]) {
+		append_dict_entry(
+			iter,
+			kWPANTUNDProperty_NetworkName,
+			DBUS_TYPE_STRING,
+			&network_name
+		);
+	}
+
+	if (network.get_xpanid_as_uint64() != 0) {
+		uint64_t xpan_id = network.get_xpanid_as_uint64();
+		append_dict_entry(
+			iter,
+			kWPANTUNDProperty_NetworkXPANID,
+			DBUS_TYPE_UINT64,
+			&xpan_id
+		);
+	}
+
+	{
+		uint16_t pan_id = network.panid;
+		append_dict_entry(
+			iter,
+			kWPANTUNDProperty_NetworkPANID,
+			DBUS_TYPE_UINT16,
+			&pan_id
+		);
+	}
+
+	if (network.type != 0) {
+		int32_t type = network.type;
+		append_dict_entry(
+			iter,
+			kWPANTUNDProperty_NetworkNodeType,
+			DBUS_TYPE_INT32,
+			&type
+		);
+	}
+
+	if (network.channel) {
+		uint16_t channel = network.channel;
+		append_dict_entry(
+			iter,
+			kWPANTUNDProperty_NCPChannel,
+			DBUS_TYPE_INT16,
+			&channel
+		);
+
+		if (network.rssi != -128) {
+			int8_t rssi = network.rssi;
+			append_dict_entry(iter, "RSSI", DBUS_TYPE_BYTE, &rssi);
+		}
+
+		dbus_bool_t allowing_join = network.joinable;
+		append_dict_entry(
+			iter,
+			kWPANTUNDProperty_NestLabs_NetworkAllowingJoin,
+			DBUS_TYPE_BOOLEAN,
+			&allowing_join
+		);
+	}
+
+	if (network.get_hwaddr_as_uint64() != 0) {
+		append_dict_entry(
+			iter,
+			kWPANTUNDProperty_NCPHardwareAddress,
+			nl::Data(network.hwaddr, 8)
+		);
+	}
+}
+
+static void
+ipc_append_network_dict(
+    DBusMessageIter *iter, const WPAN::NetworkInstance& network
+    )
+{
+	DBusMessageIter dict;
+
+	dbus_message_iter_open_container(
+	    iter,
+	    DBUS_TYPE_ARRAY,
+	    DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+	    DBUS_TYPE_STRING_AS_STRING
+	    DBUS_TYPE_VARIANT_AS_STRING
+	    DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+	    &dict
+	    );
+	ipc_append_network_properties(&dict, network);
+
+	dbus_message_iter_close_container(iter, &dict);
+}
+
+void
+DBusIPCAPI_v1::received_beacon(NCPControlInterface* interface, const WPAN::NetworkInstance& network)
+{
+	DBusMessageIter iter;
+	DBusMessage* signal;
+
+	signal = dbus_message_new_signal(
+		path_for_iface(interface).c_str(),
+		WPANTUND_DBUS_APIv1_INTERFACE,
+		WPANTUND_IF_SIGNAL_NET_SCAN_BEACON
+    );
+
+	dbus_message_iter_init_append(signal, &iter);
+
+	ipc_append_network_dict(&iter, network);
+
+	dbus_connection_send(mConnection, signal, NULL);
+
+	dbus_message_unref(signal);
+}
+
+static void
+ipc_append_energy_scan_result_dict(
+    DBusMessageIter *iter, const EnergyScanResultEntry& energy_scan_result
+    )
+{
+	uint16_t channel = energy_scan_result.mChannel;
+	int16_t maxRssi = static_cast<int16_t>(energy_scan_result.mMaxRssi);
+	DBusMessageIter dict;
+
+	dbus_message_iter_open_container(
+	    iter,
+	    DBUS_TYPE_ARRAY,
+	    DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+	    DBUS_TYPE_STRING_AS_STRING
+	    DBUS_TYPE_VARIANT_AS_STRING
+	    DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+	    &dict
+	    );
+
+	append_dict_entry(&dict, kWPANTUNDProperty_NCPChannel, DBUS_TYPE_INT16, &channel);
+	append_dict_entry(&dict, "RSSI", DBUS_TYPE_BYTE, &maxRssi);
+
+	dbus_message_iter_close_container(iter, &dict);
+}
+
+void
+DBusIPCAPI_v1::received_energy_scan_result(NCPControlInterface* interface,
+                                          const EnergyScanResultEntry& energy_scan_result)
+{
+	DBusMessageIter iter;
+	DBusMessage* signal;
+
+	signal = dbus_message_new_signal(
+		path_for_iface(interface).c_str(),
+		WPANTUND_DBUS_APIv1_INTERFACE,
+		WPANTUND_IF_SIGNAL_ENERGY_SCAN_RESULT
+    );
+
+	dbus_message_iter_init_append(signal, &iter);
+
+	ipc_append_energy_scan_result_dict(&iter, energy_scan_result);
+
+	dbus_connection_send(mConnection, signal, NULL);
+
+	dbus_message_unref(signal);
+}
+
+void
+DBusIPCAPI_v1::property_changed(NCPControlInterface* interface,const std::string& key, const boost::any& value)
+{
+	DBusMessageIter iter;
+	DBusMessage* signal;
+	std::string key_as_path;
+	std::string path;
+
+	// Transform the key into a DBus-compatible path
+	for (std::string::const_iterator i = key.begin();
+		i != key.end();
+		++i
+	) {
+		const char c = *i;
+		if (isalnum(c) || (c == '_')) {
+			key_as_path += c;
+		} else if (c == ':') {
+			key_as_path += '/';
+		} else if (c == '.') {
+			key_as_path += '_';
+		}
+	}
+
+	path = path_for_iface(interface) + "/Property/" + key_as_path;
+
+	syslog(LOG_DEBUG, "DBusAPIv1:PropChanged: %s - value: %s", path.c_str(), any_to_string(value).c_str());
+
+	signal = dbus_message_new_signal(
+		path.c_str(),
+		WPANTUND_DBUS_APIv1_INTERFACE,
+		WPANTUND_IF_SIGNAL_PROP_CHANGED
+    );
+
+	if (signal) {
+		dbus_message_iter_init_append(signal, &iter);
+
+		append_any_to_dbus_iter(&iter, key);
+		append_any_to_dbus_iter(&iter, value);
+
+		dbus_connection_send(mConnection, signal, NULL);
+		dbus_message_unref(signal);
+	}
+}
+
+void
+DBusIPCAPI_v1::status_response_helper(
+    int ret, NCPControlInterface* interface, DBusMessage *message
+    )
+{
+	DBusMessage *reply = dbus_message_new_method_return(message);
+
+	if (reply) {
+		DBusMessageIter iter;
+		dbus_message_iter_init_append(reply, &iter);
+
+		DBusMessageIter dict;
+		boost::any value;
+		NCPState ncp_state = UNINITIALIZED;
+		std::string ncp_state_string;
+		const char* ncp_state_cstr = kWPANTUNDStateUninitialized;
+
+		dbus_message_iter_open_container(
+			&iter,
+			DBUS_TYPE_ARRAY,
+			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+			DBUS_TYPE_STRING_AS_STRING
+			DBUS_TYPE_VARIANT_AS_STRING
+			DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+			&dict
+		);
+
+		value = interface->get_property(kWPANTUNDProperty_NCPState);
+
+		if (!value.empty()) {
+			ncp_state_string = any_to_string(value);
+			ncp_state = string_to_ncp_state(ncp_state_string);
+			ncp_state_cstr = ncp_state_string.c_str();
+		}
+
+		append_dict_entry(&dict,
+						  kWPANTUNDProperty_NCPState,
+						  DBUS_TYPE_STRING,
+						  &ncp_state_cstr);
+
+		value = interface->get_property(kWPANTUNDProperty_DaemonEnabled);
+		if (!value.empty()) {
+			append_dict_entry(&dict, kWPANTUNDProperty_DaemonEnabled, value);
+		}
+
+		value = interface->get_property(kWPANTUNDProperty_NCPVersion);
+		if (!value.empty()) {
+			append_dict_entry(&dict, kWPANTUNDProperty_NCPVersion, value);
+		}
+
+		value = interface->get_property(kWPANTUNDProperty_DaemonVersion);
+		if (!value.empty()) {
+			append_dict_entry(&dict, kWPANTUNDProperty_DaemonVersion, value);
+		}
+
+		value = interface->get_property(kWPANTUNDProperty_ConfigNCPDriverName);
+		if (!value.empty()) {
+			append_dict_entry(&dict, kWPANTUNDProperty_ConfigNCPDriverName, value);
+		}
+
+		value = interface->get_property(kWPANTUNDProperty_NCPHardwareAddress);
+		if (!value.empty()) {
+			append_dict_entry(&dict, kWPANTUNDProperty_NCPHardwareAddress, value);
+		}
+
+		if (ncp_state_is_commissioned(ncp_state))
+		{
+			value = interface->get_property(kWPANTUNDProperty_NCPChannel);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NCPChannel, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_NetworkNodeType);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NetworkNodeType, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_NetworkName);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NetworkName, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_NetworkXPANID);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NetworkXPANID, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_NetworkPANID);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NetworkPANID, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_IPv6LinkLocalAddress);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_IPv6LinkLocalAddress, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_IPv6MeshLocalAddress);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_IPv6MeshLocalAddress, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_IPv6MeshLocalPrefix);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_IPv6MeshLocalPrefix, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_NestLabs_LegacyMeshLocalAddress);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NestLabs_LegacyMeshLocalAddress, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix, value);
+			}
+
+			value = interface->get_property(kWPANTUNDProperty_NestLabs_NetworkAllowingJoin);
+			if (!value.empty()) {
+				append_dict_entry(&dict, kWPANTUNDProperty_NestLabs_NetworkAllowingJoin, value);
+			}
+		}
+
+		dbus_message_iter_close_container(&iter, &dict);
+
+		dbus_connection_send(mConnection, reply, NULL);
+		dbus_message_unref(reply);
+	}
+	dbus_message_unref(message);
+}
+
+void
+DBusIPCAPI_v1::CallbackWithStatusArg1_Helper(
+    int status, const boost::any& value, DBusMessage *message
+)
+{
+	DBusMessage *reply = dbus_message_new_method_return(message);
+	DBusMessageIter iter;
+
+	dbus_message_iter_init_append(reply, &iter);
+
+	if (!status && value.empty()) {
+		status = kWPANTUNDStatus_PropertyEmpty;
+	}
+
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &status);
+
+	if (value.empty()) {
+		append_any_to_dbus_iter(&iter, std::string("<empty>"));
+	} else {
+		append_any_to_dbus_iter(&iter, value);
+	}
+
+	dbus_connection_send(mConnection, reply, NULL);
+	dbus_message_unref(message);
+	dbus_message_unref(reply);
+}
+
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_reset_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->reset(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
+								 this, _1, message));
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_status_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	NCPState ncp_state = UNINITIALIZED;
+	boost::any value(interface->get_property(kWPANTUNDProperty_NCPState));
+
+	if (!value.empty()) {
+		ncp_state = string_to_ncp_state(any_to_string(value));
+	}
+
+	if (ncp_state_is_sleeping(ncp_state)
+	 || ncp_state_is_detached_from_ncp(ncp_state)
+	 || (ncp_state == UNINITIALIZED)
+	) {
+		status_response_helper(0, interface, message);
+	} else {
+		interface->refresh_state(boost::bind(&DBusIPCAPI_v1::
+										 status_response_helper, this, _1, interface, message));
+	}
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_join_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	ValueMap options;
+	DBusMessageIter iter;
+
+	dbus_message_iter_init(message, &iter);
+
+	options = value_map_from_dbus_iter(&iter);
+
+	dbus_message_ref(message);
+
+	interface->join(
+		options,
+		boost::bind(
+			&DBusIPCAPI_v1::CallbackWithStatus_Helper,
+			this,
+			_1,
+			message
+		)
+	);
+
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_form_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	ValueMap options;
+	DBusMessageIter iter;
+
+	dbus_message_iter_init(message, &iter);
+
+	options = value_map_from_dbus_iter(&iter);
+
+	dbus_message_ref(message);
+
+	interface->form(
+		options,
+		boost::bind(
+			&DBusIPCAPI_v1::CallbackWithStatus_Helper,
+			this,
+			_1,
+			message
+		)
+	);
+
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_leave_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->leave(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
+								 this, _1, message));
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_attach_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->attach(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
+								  this, _1, message));
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_begin_low_power_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->begin_low_power(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
+								 this, _1, message));
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_host_did_wake_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->host_did_wake(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
+								 this, _1, message));
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_net_scan_stop_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->netscan_stop(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
+									 this, _1, message));
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_energy_scan_stop_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->energyscan_stop(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
+									 this, _1, message));
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_mfg_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	NCPMfgInterface_v1* mfg_interface(dynamic_cast<NCPMfgInterface_v1*>(interface));
+
+	const char *mfg_command_cstr = "";
+	std::string mfg_command;
+
+	dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_STRING, &mfg_command_cstr,
+		DBUS_TYPE_INVALID
+	);
+
+	mfg_command = mfg_command_cstr;
+
+	dbus_message_ref(message);
+
+	mfg_interface->mfg(
+		mfg_command,
+		boost::bind(
+			&DBusIPCAPI_v1::CallbackWithStatusArg1_Helper,
+			this,
+			_1,
+			_2,
+			message
+		)
+	);
+
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_get_prop_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	const char* property_key_cstr = "";
+	std::string property_key;
+	dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_STRING, &property_key_cstr,
+		DBUS_TYPE_INVALID
+		);
+
+	property_key = property_key_cstr;
+
+	if (interface->translate_deprecated_property(property_key)) {
+		syslog(LOG_WARNING, "PropGet: Property \"%s\" is deprecated. Please use \"%s\" instead.", property_key_cstr, property_key.c_str());
+	}
+
+	dbus_message_ref(message);
+
+	interface->get_property(
+		property_key,
+		boost::bind(
+			&DBusIPCAPI_v1::CallbackWithStatusArg1_Helper,
+			this,
+			_1,
+			_2,
+			message
+		)
+	);
+
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_set_prop_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	DBusMessageIter iter;
+	const char* property_key_cstr = "";
+	std::string property_key;
+	boost::any property_value;
+
+	dbus_message_iter_init(message, &iter);
+
+	require (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING, bail);
+
+	dbus_message_iter_get_basic(&iter, &property_key_cstr);
+	dbus_message_iter_next(&iter);
+
+	property_value = any_from_dbus_iter(&iter);
+	property_key = property_key_cstr;
+
+	if (interface->translate_deprecated_property(property_key, property_value)) {
+		syslog(LOG_WARNING, "PropSet: Property \"%s\" is deprecated. Please use \"%s\" instead.", property_key_cstr, property_key.c_str());
+	}
+
+	dbus_message_ref(message);
+
+	interface->set_property(
+		property_key,
+		property_value,
+		boost::bind(
+			&DBusIPCAPI_v1::CallbackWithStatus_Helper,
+			this,
+			_1,
+			message
+		)
+	);
+
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+bail:
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_net_scan_start_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	ValueMap options;
+	NCPControlInterface::ChannelMask channel_mask = 0;
+
+	dbus_message_ref(message);
+
+	dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_UINT32, &channel_mask,
+		DBUS_TYPE_INVALID
+	);
+
+	if (channel_mask) {
+		options[kWPANTUNDProperty_NCPChannelMask] = channel_mask;
+	}
+
+	interface->netscan_start(
+		options,
+		boost::bind(
+			&DBusIPCAPI_v1::CallbackWithStatus_Helper,
+			this,
+			_1,
+			message
+		)
+	);
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_energy_scan_start_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	ValueMap options;
+	NCPControlInterface::ChannelMask channel_mask = 0;
+
+	dbus_message_ref(message);
+
+	dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_UINT32, &channel_mask,
+		DBUS_TYPE_INVALID
+	);
+
+	if (channel_mask) {
+		options[kWPANTUNDProperty_NCPChannelMask] = channel_mask;
+	}
+
+	interface->energyscan_start(
+		options,
+		boost::bind(
+			&DBusIPCAPI_v1::CallbackWithStatus_Helper,
+			this,
+			_1,
+			message
+		)
+	);
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_pcap_to_fd_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	int fd = -1;
+
+	dbus_message_ref(message);
+
+	dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_UNIX_FD, &fd,
+		DBUS_TYPE_INVALID
+	);
+
+	interface->pcap_to_fd(
+		fd,
+		boost::bind(
+			&DBusIPCAPI_v1::CallbackWithStatus_Helper,
+			this,
+			_1,
+			message
+		)
+	);
+
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_pcap_terminate_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->pcap_terminate(
+		boost::bind(
+			&DBusIPCAPI_v1::CallbackWithStatus_Helper,
+			this,
+			_1,
+			message
+		)
+	);
+
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_data_poll_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	interface->data_poll(boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,
+								 this, _1, message));
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_config_gateway_handler(
+	NCPControlInterface* interface,
+	DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	dbus_bool_t default_route = FALSE;
+	uint32_t preferred_lifetime = 0;
+	uint32_t valid_lifetime = 0;
+	uint8_t *prefix(NULL);
+	int prefix_len_in_bytes(0);
+	struct in6_addr address = {};
+	bool did_succeed(false);
+
+	did_succeed = dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_BOOLEAN, &default_route,
+		DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &prefix, &prefix_len_in_bytes,
+		DBUS_TYPE_UINT32, &preferred_lifetime,
+		DBUS_TYPE_UINT32, &valid_lifetime,
+		DBUS_TYPE_INVALID
+	);
+
+	require(did_succeed, bail);
+	require(prefix_len_in_bytes <= sizeof(address), bail);
+	require(prefix_len_in_bytes >= 0, bail);
+
+	memcpy(address.s6_addr, prefix, prefix_len_in_bytes);
+
+	dbus_message_ref(message);
+
+	if (valid_lifetime == 0) {
+		interface->remove_on_mesh_prefix(
+			&address,
+			boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,this, _1, message)
+		);
+	} else {
+		interface->add_on_mesh_prefix(
+			&address,
+			default_route,
+			boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper,this, _1, message)
+		);
+	}
+
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+bail:
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_route_add_handler(
+   NCPControlInterface* interface,
+   DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	dbus_message_ref(message);
+
+	uint8_t *route_prefix(NULL);
+	int prefix_len_in_bytes(0);
+	uint16_t domain_id(0);
+	int16_t priority_raw(0);
+	NCPControlInterface::ExternalRoutePriority priority(NCPControlInterface::ROUTE_MEDIUM_PREFERENCE);
+	uint8_t prefix_len_in_bits(0);
+	struct in6_addr address = {};
+	bool did_succeed(false);
+
+	did_succeed = dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &route_prefix, &prefix_len_in_bytes,
+		DBUS_TYPE_UINT16, &domain_id,
+		DBUS_TYPE_INT16, &priority_raw,
+		DBUS_TYPE_BYTE, &prefix_len_in_bits,
+		DBUS_TYPE_INVALID
+	);
+
+	if (!did_succeed) {
+		// Likely using the old syntax that doesn't include the prefix length in bits
+		did_succeed = dbus_message_get_args(
+			message, NULL,
+			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &route_prefix, &prefix_len_in_bytes,
+			DBUS_TYPE_UINT16, &domain_id,
+			DBUS_TYPE_INT16, &priority_raw,
+			DBUS_TYPE_INVALID
+		);
+		prefix_len_in_bits = IPV6_PREFIX_BYTES_TO_BITS(prefix_len_in_bytes);
+	}
+
+	require(did_succeed, bail);
+	require(prefix_len_in_bytes <= sizeof(address), bail);
+	require(prefix_len_in_bytes >= 0, bail);
+
+	memcpy(address.s6_addr, route_prefix, prefix_len_in_bytes);
+
+	if  (priority_raw > 0) {
+		priority = NCPControlInterface::ROUTE_HIGH_PREFERENCE;
+	} else if (priority_raw < 0) {
+		priority = NCPControlInterface::ROUTE_LOW_PREFRENCE;
+	}
+
+	dbus_message_ref(message);
+
+	interface->add_external_route(
+		&address,
+		prefix_len_in_bits,
+		domain_id,
+		priority,
+		boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
+	);
+
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+bail:
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::interface_route_remove_handler(
+   NCPControlInterface* interface,
+   DBusMessage *        message
+) {
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	uint8_t *route_prefix = NULL;
+	int prefix_len_in_bytes(0);
+	uint8_t prefix_len_in_bits(0);
+	uint16_t domain_id = 0;
+	struct in6_addr address = {};
+	bool did_succeed(false);
+
+	did_succeed = dbus_message_get_args(
+		message, NULL,
+		DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &route_prefix, &prefix_len_in_bytes,
+		DBUS_TYPE_UINT16, &domain_id,
+		DBUS_TYPE_BYTE, &prefix_len_in_bits,
+		DBUS_TYPE_INVALID
+	);
+
+	if (!did_succeed) {
+		// Likely using the old syntax that doesn't include the prefix length in bits
+		did_succeed = dbus_message_get_args(
+			message, NULL,
+			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &route_prefix, &prefix_len_in_bytes,
+			DBUS_TYPE_UINT16, &domain_id,
+			DBUS_TYPE_INVALID
+		);
+		prefix_len_in_bits = IPV6_PREFIX_BYTES_TO_BITS(prefix_len_in_bytes);
+	}
+
+	require(did_succeed, bail);
+	require(prefix_len_in_bytes <= sizeof(address), bail);
+	require(prefix_len_in_bytes >= 0, bail);
+
+	memcpy(address.s6_addr, route_prefix, prefix_len_in_bytes);
+
+	dbus_message_ref(message);
+
+	interface->remove_external_route(
+		&address,
+		prefix_len_in_bits,
+		domain_id,
+		boost::bind(&DBusIPCAPI_v1::CallbackWithStatus_Helper, this, _1, message)
+	);
+
+	ret = DBUS_HANDLER_RESULT_HANDLED;
+
+bail:
+
+	return ret;
+}
+
+
+DBusHandlerResult
+DBusIPCAPI_v1::message_handler(
+    NCPControlInterface* interface,
+    DBusConnection *        connection,
+    DBusMessage *           message
+    )
+{
+	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+	if ((dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
+		&& (dbus_message_has_interface(message, WPANTUND_DBUS_APIv1_INTERFACE)
+			|| dbus_message_has_interface(message, WPANTUND_DBUS_NLAPIv1_INTERFACE))
+		&& mInterfaceCallbackTable.count(dbus_message_get_member(message))
+	) {
+		try {
+			ret = mInterfaceCallbackTable.at(dbus_message_get_member(message))(
+				interface,
+				message
+			);
+		} catch (std::invalid_argument x) {
+			DBusIPCAPI_v1::CallbackWithStatus_Helper(kWPANTUNDStatus_InvalidArgument,message);
+			ret = DBUS_HANDLER_RESULT_HANDLED;
+		}
+	}
+
+	return ret;
+}
+
+DBusHandlerResult
+DBusIPCAPI_v1::dbus_message_handler(
+    DBusConnection *connection,
+    DBusMessage *   message,
+    void *          user_data
+) {
+	if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL) {
+		syslog(LOG_INFO, "Inbound DBus message for INTERFACE \"%s\" from \"%s\"", dbus_message_get_member(message), dbus_message_get_sender(message));
+	}
+	std::pair<NCPControlInterface*,
+	          DBusIPCAPI_v1*> *cb_data =
+	    (std::pair<NCPControlInterface*, DBusIPCAPI_v1*> *)user_data;
+	return cb_data->second->message_handler(cb_data->first,
+	                                                  connection,
+	                                                  message);
+}
diff --git a/src/ipc-dbus/DBusIPCAPI_v1.h b/src/ipc-dbus/DBusIPCAPI_v1.h
new file mode 100644
index 0000000..79cf3a1
--- /dev/null
+++ b/src/ipc-dbus/DBusIPCAPI_v1.h
@@ -0,0 +1,205 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef wpantund_DBusIPCAPI_v1_h
+#define wpantund_DBusIPCAPI_v1_h
+
+#include <map>
+#include <list>
+
+#include <dbus/dbus.h>
+
+#include <boost/bind.hpp>
+#include <boost/any.hpp>
+#include <boost/function.hpp>
+
+#include "NetworkInstance.h"
+#include "NCPTypes.h"
+#include "Data.h"
+#include "time-utils.h"
+
+namespace nl {
+namespace wpantund {
+
+class NCPControlInterface;
+
+class DBusIPCAPI_v1 {
+public:
+	DBusIPCAPI_v1(DBusConnection *connection);
+	~DBusIPCAPI_v1();
+
+	int add_interface(NCPControlInterface* interface);
+
+private:
+
+	DBusHandlerResult message_handler(
+		NCPControlInterface* interface,
+		DBusConnection *connection,
+		DBusMessage *message
+    );
+
+	static DBusHandlerResult dbus_message_handler(
+		DBusConnection *connection,
+		DBusMessage *message,
+		void *user_data
+	);
+
+	void init_callback_tables(void);
+
+	std::string path_for_iface(NCPControlInterface* interface);
+
+	// ------------------------------------------------------------------------
+
+	void CallbackWithStatus_Helper(int ret, DBusMessage *original_message);
+	void CallbackWithStatusArg1_Helper(int ret, const boost::any& value, DBusMessage *original_message);
+
+	void status_response_helper(int ret, NCPControlInterface* interface, DBusMessage *original_message);
+
+	// TODO: Remove these...
+	//void scan_response_helper(int ret, DBusMessage *original_message);
+	//void energy_scan_response_helper(int ret, DBusMessage *original_message);
+
+	// ------------------------------------------------------------------------
+
+	void property_changed(NCPControlInterface* interface,const std::string& key, const boost::any& value);
+	void received_beacon(NCPControlInterface* interface, const WPAN::NetworkInstance& network);
+	void received_energy_scan_result(NCPControlInterface* interface, const EnergyScanResultEntry& energy_scan_result);
+
+	// ------------------------------------------------------------------------
+
+	DBusHandlerResult interface_route_add_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_route_remove_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_reset_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_status_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_join_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_form_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_leave_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_attach_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_begin_low_power_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_host_did_wake_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_pcap_to_fd_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_pcap_terminate_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_get_prop_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_set_prop_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_net_scan_start_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_net_scan_stop_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_energy_scan_start_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_energy_scan_stop_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_data_poll_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_config_gateway_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+	DBusHandlerResult interface_mfg_handler(
+		NCPControlInterface* interface,
+		DBusMessage *        message
+	);
+
+private:
+	typedef DBusHandlerResult (interface_handler_cb)(
+		NCPControlInterface*,
+		DBusMessage *
+	);
+
+	DBusConnection *mConnection;
+	std::map<std::string, boost::function<interface_handler_cb> > mInterfaceCallbackTable;
+}; // class DBusIPCAPI_v1
+
+}; // namespace nl
+}; // namespace wpantund
+
+
+#endif
diff --git a/src/ipc-dbus/Makefile.am b/src/ipc-dbus/Makefile.am
new file mode 100644
index 0000000..80f38af
--- /dev/null
+++ b/src/ipc-dbus/Makefile.am
@@ -0,0 +1,54 @@
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src \
+	-I$(top_srcdir)/src/util \
+	-I$(top_srcdir)/src/ipc-dbus \
+	-I$(top_srcdir)/src/wpantund \
+	-I$(top_srcdir)/third_party/assert-macros \
+	$(NULL)
+
+EXTRA_DIST = wpantund.conf
+
+DISTCLEANFILES = .deps Makefile
+
+AUTOMAKE_OPTIONS = subdir-objects
+
+dbusconfdir = $(DBUS_CONFDIR)
+
+dbusconf_DATA = wpantund.conf
+
+noinst_LTLIBRARIES = libwpantund-dbus.la
+
+libwpantund_dbus_la_SOURCES = \
+	DBUSIPCServer.cpp \
+	DBUSIPCServer.h \
+	DBusIPCAPI_v1.cpp \
+	DBusIPCAPI_v1.h \
+	wpan-dbus-v1.h \
+	DBusIPCAPI_v0.cpp \
+	DBusIPCAPI_v0.h \
+	wpan-dbus-v0.h \
+	../util/DBUSHelpers.cpp \
+	$(NULL)
+
+libwpantund_dbus_la_LIBADD =  $(DBUS_LIBS)
+libwpantund_dbus_la_CPPFLAGS = $(AM_CPPFLAGS) $(DBUS_CFLAGS)
+libwpantund_dbus_la_CXXFLAGS = $(BOOST_CXXFLAGS)
+
+pkginclude_HEADERS = wpan-dbus-v0.h wpan-dbus-v1.h
diff --git a/src/ipc-dbus/wpan-dbus-v0.h b/src/ipc-dbus/wpan-dbus-v0.h
new file mode 100644
index 0000000..9677316
--- /dev/null
+++ b/src/ipc-dbus/wpan-dbus-v0.h
@@ -0,0 +1,99 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef wpantund_wpan_dbus_v0_h
+#define wpantund_wpan_dbus_v0_h
+
+#include "wpan-properties.h"
+
+#if !defined(wpantund_DBusIPCAPI_v0_h) && !defined(BUILD_FEATURE_WPANTUND)
+// Disabling these warnings for now.
+// Will re-enable once more stuff has moved over.
+//#warning wpan-dbus-v0.h is deprecated. Please migrate to the API in wpan-dbus-v1.h.
+#endif
+
+#define WPAN_TUNNEL_DBUS_NAME   "com.nestlabs.WPANTunnelDriver"
+#define WPAN_TUNNEL_DBUS_INTERFACE  "com.nestlabs.WPANTunnelDriver"
+#define WPAN_TUNNEL_DBUS_PATH   "/com/nestlabs/WPANTunnelDriver"
+#define WPAN_TUNNEL_DBUS_VERSION   2
+#define WPAN_TUNNEL_DBUS_PATH_PROPERTIES "Properties"
+
+#define WPAN_TUNNEL_CMD_GET_INTERFACES  "GetInterfaces"
+#define WPAN_TUNNEL_CMD_GET_VERSION     "GetVersion"
+
+#define WPAN_TUNNEL_SIGNAL_INTERFACE_ADDED			"InterfaceAdded"
+#define WPAN_TUNNEL_SIGNAL_INTERFACE_REMOVED		"InterfaceRemoved"
+
+#define WPAN_IFACE_SIGNAL_STATE_CHANGED	"AssociationStateChanged"
+#define WPAN_IFACE_SIGNAL_PROPERTY_CHANGED	"PropertyChanged"
+#define WPAN_IFACE_SIGNAL_NET_WAKE	    "NetWake"
+#define WPAN_IFACE_SIGNAL_PREVENT_SLEEP	"PreventSleep"
+#define WPAN_IFACE_SIGNAL_ALLOW_SLEEP	"AllowSleep"
+
+#define WPAN_IFACE_CMD_JOIN             "Join"
+#define WPAN_IFACE_CMD_FORM             "Form"
+#define WPAN_IFACE_CMD_LEAVE            "Leave"
+#define WPAN_IFACE_CMD_ACTIVE_SCAN      "Scan"
+#define WPAN_IFACE_CMD_RESUME           "Resume"
+#define WPAN_IFACE_CMD_PERMIT_JOIN      "PermitJoin"
+#define WPAN_IFACE_CMD_STOP_SCAN        "StopScan"
+#define WPAN_IFACE_CMD_RESET            "Reset"
+#define WPAN_IFACE_CMD_STATUS           "Status"
+#define WPAN_IFACE_CMD_PING             "Ping"
+#define WPAN_IFACE_CMD_SCAN             "Scan"
+#define WPAN_IFACE_CMD_BEGIN_NET_WAKE   "BeginNetWake"
+#define WPAN_IFACE_CMD_CONFIG_GATEWAY   "ConfigGateway"
+#define WPAN_IFACE_CMD_ADD_ROUTE        "AddRoute"
+#define WPAN_IFACE_CMD_REMOVE_ROUTE     "RemoveRoute"
+#define WPAN_IFACE_CMD_DATA_POLL        "DataPoll"
+#define WPAN_IFACE_CMD_HOST_DID_WAKE    "HostDidWake"
+
+#define WPAN_IFACE_CMD_BEGIN_LOW_POWER  "BeginLowPower"
+
+/* The property "MfgTestMode" must be enabled in order to use these commands */
+#define WPAN_IFACE_CMD_MFG_FINISH      "MfgFinish"
+#define WPAN_IFACE_CMD_MFG_BEGIN_TEST  "MfgBeginTest"	// Argument is test type
+#define WPAN_IFACE_CMD_MFG_END_TEST    "MfgEndTest"		// Argument is test type
+#define WPAN_IFACE_CMD_MFG_TX_PACKET   "MfgTXPacket"	// Argument is packet
+#define WPAN_IFACE_SIGNAL_MFG_RX       "MfgRXPacket"    // packet, lqi, rssi
+#define WPAN_IFACE_CMD_MFG_CLOCKMON       "MfgClockMon"
+#define WPAN_IFACE_CMD_MFG_GPIO_SET       "MfgGPIOSet"
+#define WPAN_IFACE_CMD_MFG_GPIO_GET       "MfgGPIOGet"
+#define WPAN_IFACE_CMD_MFG_CHANNELCAL     "MfgChannelCal"
+#define WPAN_IFACE_CMD_MFG_CHANNELCAL_GET "MfgChannelCalGet"
+/* Also, there are the following properties that can be set when in MFG mode:
+ *	"Channel", "TXPower", "SYNOffset"
+ */
+
+
+#define WPAN_IFACE_CMD_GET_PROP         "GetProp"
+#define WPAN_IFACE_CMD_SET_PROP         "SetProp"
+
+
+#define WPAN_IFACE_PROTOCOL_TCPUDP      0xFF
+#define WPAN_IFACE_PROTOCOL_TCP         6
+#define WPAN_IFACE_PROTOCOL_UDP         17
+
+#define WPAN_IFACE_ROLE_UNKNOWN             0
+#define WPAN_IFACE_ROLE_ROUTER              2
+#define WPAN_IFACE_ROLE_END_DEVICE          3
+#define WPAN_IFACE_ROLE_SLEEPY_END_DEVICE   4
+#define WPAN_IFACE_ROLE_LURKER              6
+
+#endif
diff --git a/src/ipc-dbus/wpan-dbus-v1.h b/src/ipc-dbus/wpan-dbus-v1.h
new file mode 100644
index 0000000..2d573d8
--- /dev/null
+++ b/src/ipc-dbus/wpan-dbus-v1.h
@@ -0,0 +1,89 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef wpantund_wpan_dbus_v1_h
+#define wpantund_wpan_dbus_v1_h
+
+#include "wpan-properties.h"
+
+#define WPANTUND_DBUS_NAME                      "org.wpantund"
+#define WPANTUND_DBUS_PATH                      "/org/wpantund"
+
+// ============================================================================
+// Base Interface
+
+#define WPANTUND_DBUS_BASE_INTERFACE            "org.wpantund"
+
+#define WPANTUND_BASE_CMD_GET_INTERFACES        "GetInterfaces"
+
+#define WPANTUND_BASE_SIGNAL_INTERFACE_ADDED    "InterfaceAdded"
+#define WPANTUND_BASE_SIGNAL_INTERFACE_REMOVED  "InterfaceRemoved"
+
+#define WPANTUND_IF_GET_VERSION                 "GetVersion"
+
+// ============================================================================
+// Standard API Interface
+
+// Note that this API is not yet fully baked and may change before
+// being considered frozen.
+
+#define WPANTUND_DBUS_APIv1_INTERFACE         WPANTUND_DBUS_BASE_INTERFACE".v1"
+
+#define WPANTUND_IF_CMD_JOIN                  "Join"
+#define WPANTUND_IF_CMD_FORM                  "Form"
+#define WPANTUND_IF_CMD_LEAVE                 "Leave"
+#define WPANTUND_IF_CMD_ATTACH                "Attach"
+
+#define WPANTUND_IF_CMD_RESET                 "Reset"
+#define WPANTUND_IF_CMD_STATUS                "Status"
+
+#define WPANTUND_IF_CMD_ROUTE_ADD             "RouteAdd"
+#define WPANTUND_IF_CMD_ROUTE_REMOVE          "RouteRemove"
+#define WPANTUND_IF_CMD_CONFIG_GATEWAY        "ConfigGateway"
+#define WPANTUND_IF_CMD_DATA_POLL             "DataPoll"
+
+#define WPANTUND_IF_CMD_BEGIN_LOW_POWER       "BeginLowPower"
+#define WPANTUND_IF_CMD_HOST_DID_WAKE         "HostDidWake"
+
+#define WPANTUND_IF_CMD_PCAP_TO_FD            "PcapToFd"
+#define WPANTUND_IF_CMD_PCAP_TERMINATE        "PcapTerminate"
+
+#define WPANTUND_IF_CMD_NET_SCAN_START        "NetScanStart"
+#define WPANTUND_IF_CMD_NET_SCAN_STOP         "NetScanStop"
+#define WPANTUND_IF_SIGNAL_NET_SCAN_BEACON    "NetScanBeacon"
+
+#define WPANTUND_IF_CMD_ENERGY_SCAN_START     "EnergyScanStart"
+#define WPANTUND_IF_CMD_ENERGY_SCAN_STOP      "EnergyScanStop"
+#define WPANTUND_IF_SIGNAL_ENERGY_SCAN_RESULT "EnergyScanResult"
+
+#define WPANTUND_IF_CMD_PROP_GET              "PropGet"
+#define WPANTUND_IF_CMD_PROP_SET              "PropSet"
+#define WPANTUND_IF_SIGNAL_PROP_CHANGED       "PropChanged"
+
+// ============================================================================
+// NestLabs Internal API Interface
+
+#define WPANTUND_DBUS_NLAPIv1_INTERFACE       "com.nestlabs.wpantund.v1"
+
+#define WPANTUND_IF_CMD_PERMIT_JOIN           "PermitJoin"
+#define WPANTUND_IF_CMD_NETWORK_WAKE_BEGIN    "NetworkWakeBegin"
+
+#define WPANTUND_IF_CMD_MFG                   "Mfg"
+
+#endif
diff --git a/src/ipc-dbus/wpantund.conf b/src/ipc-dbus/wpantund.conf
new file mode 100644
index 0000000..bf26bf1
--- /dev/null
+++ b/src/ipc-dbus/wpantund.conf
@@ -0,0 +1,44 @@
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+    <policy user="root">
+        <allow own="org.wpantund"/>
+        <allow own="org.wpantund.wpanctl"/>
+
+        <allow send_interface="org.wpantund.Join"/>
+        <allow send_interface="org.wpantund.Form"/>
+        <allow send_interface="org.wpantund.Leave"/>
+        <allow send_interface="org.wpantund.Attach"/>
+        <allow send_interface="org.wpantund.Status"/>
+        <allow send_interface="org.wpantund.Reset"/>
+        <allow send_interface="org.wpantund.NetScanStart"/>
+        <allow send_interface="org.wpantund.NetScanStop"/>
+        <allow send_interface="org.wpantund.List"/>
+
+
+        <!-- Deprecated -->
+        <allow own="com.nestlabs.WPANTunnelDriver"/>
+        <allow own="com.nestlabs.WPANTunnelDriver.wpanctl"/>
+        <allow send_destination="com.nestlabs.WPANTunnelDriver"/>
+        <allow send_interface="com.nestlabs.WPANTunnelDriver.Join"/>
+        <allow send_interface="com.nestlabs.WPANTunnelDriver.Form"/>
+        <allow send_interface="com.nestlabs.WPANTunnelDriver.Leave"/>
+        <allow send_interface="com.nestlabs.WPANTunnelDriver.Resume"/>
+        <allow send_interface="com.nestlabs.WPANTunnelDriver.Scan"/>
+        <allow send_interface="com.nestlabs.WPANTunnelDriver.PermitJoin"/>
+        <allow send_interface="com.nestlabs.WPANTunnelDriver.Status"/>
+        <allow send_interface="com.nestlabs.WPANTunnelDriver.List"/>
+    </policy>
+    <policy at_console="true">
+        <allow send_destination="org.wpantund"/>
+
+        <!-- Deprecated -->
+        <allow send_destination="com.nestlabs.WPANTunnelDriver"/>
+    </policy>
+    <policy context="default">
+        <deny send_destination="org.wpantund"/>
+
+        <!-- Deprecated -->
+        <deny send_destination="com.nestlabs.WPANTunnelDriver"/>
+    </policy>
+</busconfig>
diff --git a/src/ncp-dummy/DummyNCPControlInterface.cpp b/src/ncp-dummy/DummyNCPControlInterface.cpp
new file mode 100644
index 0000000..518a70a
--- /dev/null
+++ b/src/ncp-dummy/DummyNCPControlInterface.cpp
@@ -0,0 +1,275 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+
+#include "DummyNCPControlInterface.h"
+#include "DummyNCPInstance.h"
+
+#include "wpantund.h"
+#include "config-file.h"
+#include "nlpt.h"
+#include "string-utils.h"
+#include "any-to.h"
+#include "time-utils.h"
+
+#include <cstring>
+#include <algorithm>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <syslog.h>
+#include <sys/time.h>
+
+#include <boost/bind.hpp>
+
+using namespace nl;
+using namespace nl::wpantund;
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+DummyNCPControlInterface::DummyNCPControlInterface(DummyNCPInstance* instance_pointer)
+	:mNCPInstance(instance_pointer)
+{
+}
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+void
+DummyNCPControlInterface::join(
+	const ValueMap& options,
+    CallbackWithStatus cb
+) {
+	// TODO: Writeme!
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+DummyNCPControlInterface::form(
+	const ValueMap& options,
+    CallbackWithStatus cb
+) {
+
+	// TODO: Writeme!
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+DummyNCPControlInterface::leave(CallbackWithStatus cb)
+{
+	// TODO: Writeme!
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+DummyNCPControlInterface::attach(CallbackWithStatus cb)
+{
+	// TODO: Writeme!
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+DummyNCPControlInterface::reset(CallbackWithStatus cb)
+{
+	// TODO: Writeme!
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+DummyNCPControlInterface::begin_net_wake(uint8_t data, uint32_t flags, CallbackWithStatus cb)
+{
+	// TODO: Writeme!
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+DummyNCPControlInterface::host_did_wake(CallbackWithStatus cb)
+{
+	// TODO: Writeme!
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+DummyNCPControlInterface::begin_low_power(CallbackWithStatus cb)
+{
+	// TODO: Writeme!
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+DummyNCPControlInterface::refresh_state(CallbackWithStatus cb)
+{
+	// TODO: Writeme!
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+DummyNCPControlInterface::data_poll(CallbackWithStatus cb)
+{
+	cb(kWPANTUNDStatus_FeatureNotImplemented); // TODO: Send data poll command
+}
+
+void
+DummyNCPControlInterface::add_on_mesh_prefix(
+	const struct in6_addr *prefix,
+	bool defaultRoute,
+	CallbackWithStatus cb
+) {
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+DummyNCPControlInterface::remove_on_mesh_prefix(
+	const struct in6_addr *prefix,
+	CallbackWithStatus cb
+) {
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+DummyNCPControlInterface::add_external_route(
+	const struct in6_addr *prefix,
+	int prefix_len_in_bits,
+	int domain_id,
+	ExternalRoutePriority priority,
+	CallbackWithStatus cb
+) {
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+DummyNCPControlInterface::remove_external_route(
+	const struct in6_addr *prefix,
+	int prefix_len_in_bits,
+	int domain_id,
+	CallbackWithStatus cb
+) {
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+DummyNCPControlInterface::permit_join(
+    int seconds,
+    uint8_t traffic_type,
+    in_port_t traffic_port,
+    bool network_wide,
+    CallbackWithStatus cb
+    )
+{
+	// TODO: Writeme!
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+DummyNCPControlInterface::netscan_start(
+    const ValueMap& options,
+    CallbackWithStatus cb
+) {
+	cb(kWPANTUNDStatus_FeatureNotImplemented); // TODO: Start network scan
+}
+
+void
+DummyNCPControlInterface::mfg(
+    const std::string& mfg_command,
+    CallbackWithStatusArg1 cb
+) {
+	cb(kWPANTUNDStatus_FeatureNotImplemented, 0); // TODO: Start mfg run
+}
+
+void
+DummyNCPControlInterface::netscan_stop(CallbackWithStatus cb)
+{
+	cb(kWPANTUNDStatus_FeatureNotImplemented); // TODO: Start network scan
+}
+
+void
+DummyNCPControlInterface::energyscan_start(
+    const ValueMap& options,
+    CallbackWithStatus cb
+) {
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+DummyNCPControlInterface::energyscan_stop(CallbackWithStatus cb)
+{
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+std::string
+DummyNCPControlInterface::get_name() {
+	return mNCPInstance->get_name();
+}
+
+const WPAN::NetworkInstance&
+DummyNCPControlInterface::get_current_network_instance()const
+{
+	return mNCPInstance->get_current_network_instance();
+}
+
+
+NCPInstance&
+DummyNCPControlInterface::get_ncp_instance()
+{
+	return (*mNCPInstance);
+}
+
+void
+DummyNCPControlInterface::pcap_to_fd(int fd, CallbackWithStatus cb)
+{
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+DummyNCPControlInterface::pcap_terminate(CallbackWithStatus cb)
+{
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+void
+DummyNCPControlInterface::get_property(
+    const std::string& in_key, CallbackWithStatusArg1 cb
+    )
+{
+	if (!mNCPInstance->is_initializing_ncp()) {
+		syslog(LOG_INFO, "get_property: key: \"%s\"", in_key.c_str());
+	}
+	mNCPInstance->get_property(in_key, cb);
+}
+
+void
+DummyNCPControlInterface::set_property(
+    const std::string&                      key,
+    const boost::any&                       value,
+    CallbackWithStatus      cb
+    )
+{
+	syslog(LOG_INFO, "set_property: key: \"%s\"", key.c_str());
+	mNCPInstance->set_property(key, value, cb);
+
+}
diff --git a/src/ncp-dummy/DummyNCPControlInterface.h b/src/ncp-dummy/DummyNCPControlInterface.h
new file mode 100644
index 0000000..5bac656
--- /dev/null
+++ b/src/ncp-dummy/DummyNCPControlInterface.h
@@ -0,0 +1,134 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __WPAN_DUMMY_NCP_H__
+#define __WPAN_DUMMY_NCP_H__ 1
+
+#include "NCPInstance.h"
+#include "NCPControlInterface.h"
+#include "nlpt.h"
+#include "Callbacks.h"
+#include "EventHandler.h"
+
+#include <queue>
+#include <set>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+namespace nl {
+namespace wpantund {
+
+class DummyNCPInstance;
+
+class DummyNCPControlInterface : public NCPControlInterface {
+public:
+	friend class DummyNCPInstance;
+
+	DummyNCPControlInterface(DummyNCPInstance* instance_pointer);
+	virtual ~DummyNCPControlInterface() { }
+
+	virtual const WPAN::NetworkInstance& get_current_network_instance(void)const;
+
+	virtual void join(
+		const ValueMap& options,
+	    CallbackWithStatus cb = NilReturn()
+	);
+
+	virtual void form(
+		const ValueMap& options,
+	    CallbackWithStatus cb = NilReturn()
+	);
+
+	virtual void leave(CallbackWithStatus cb = NilReturn());
+	virtual void attach(CallbackWithStatus cb = NilReturn());
+	virtual void begin_low_power(CallbackWithStatus cb = NilReturn());
+
+	virtual void netscan_start(const ValueMap& options, CallbackWithStatus cb = NilReturn());
+	virtual void netscan_stop(CallbackWithStatus cb = NilReturn());
+
+	virtual void energyscan_start(const ValueMap& options, CallbackWithStatus cb = NilReturn());
+	virtual void energyscan_stop(CallbackWithStatus cb = NilReturn());
+
+	virtual void mfg(const std::string& mfg_command, CallbackWithStatusArg1 cb = NilReturn());
+
+	virtual void begin_net_wake(uint8_t data, uint32_t flags, CallbackWithStatus cb = NilReturn());
+	virtual void reset(CallbackWithStatus cb = NilReturn());
+	virtual void permit_join(
+	    int seconds = 15 * 60,
+	    uint8_t commissioning_traffic_type = 0xFF,
+	    in_port_t commissioning_traffic_port = 0,
+	    bool network_wide = false,
+	    CallbackWithStatus      cb = NilReturn());
+
+	virtual void refresh_state(CallbackWithStatus cb = NilReturn());
+
+	virtual void get_property(
+	    const std::string& key, CallbackWithStatusArg1 cb);
+	virtual void set_property(
+	    const std::string&                      key,
+	    const boost::any&                       value,
+	    CallbackWithStatus      cb);
+	virtual void add_on_mesh_prefix(
+		const struct in6_addr *prefix,
+		bool defaultRoute,
+		CallbackWithStatus cb = NilReturn()
+	);
+
+	virtual void remove_on_mesh_prefix(
+		const struct in6_addr *prefix,
+		CallbackWithStatus cb = NilReturn()
+	);
+
+	virtual void add_external_route(
+		const struct in6_addr *prefix,
+		int prefix_len_in_bits,
+		int domain_id,
+		ExternalRoutePriority priority,
+		CallbackWithStatus cb = NilReturn()
+	);
+
+	virtual void remove_external_route(
+		const struct in6_addr *prefix,
+		int prefix_len_in_bits,
+		int domain_id,
+		CallbackWithStatus cb = NilReturn()
+	);
+
+	virtual void data_poll(CallbackWithStatus cb = NilReturn());
+	virtual void host_did_wake(CallbackWithStatus cb = NilReturn());
+
+	virtual std::string get_name();
+
+	virtual NCPInstance& get_ncp_instance(void);
+
+	virtual void pcap_to_fd(int fd, CallbackWithStatus cb = NilReturn());
+
+	virtual void pcap_terminate(CallbackWithStatus cb = NilReturn());
+
+private:
+
+	DummyNCPInstance* mNCPInstance;
+
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+
+#endif
diff --git a/src/ncp-dummy/DummyNCPInstance.cpp b/src/ncp-dummy/DummyNCPInstance.cpp
new file mode 100644
index 0000000..659057d
--- /dev/null
+++ b/src/ncp-dummy/DummyNCPInstance.cpp
@@ -0,0 +1,92 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "DummyNCPInstance.h"
+#include "time-utils.h"
+#include "assert-macros.h"
+#include <syslog.h>
+#include <errno.h>
+#include "socket-utils.h"
+#include <stdexcept>
+#include <sys/file.h>
+#include "SuperSocket.h"
+
+using namespace nl;
+using namespace wpantund;
+
+WPANTUND_DEFINE_NCPINSTANCE_PLUGIN(dummy, DummyNCPInstance);
+
+DummyNCPInstance::DummyNCPInstance(const Settings& settings) :
+	NCPInstanceBase(settings), mControlInterface(this)
+{
+}
+
+DummyNCPInstance::~DummyNCPInstance()
+{
+}
+
+int
+DummyNCPInstance::vprocess_event(int event, va_list args)
+{
+	EH_BEGIN();
+
+	EH_SLEEP_FOR(1);
+
+	change_ncp_state(OFFLINE);
+	signal_property_changed(kWPANTUNDProperty_NCPState, ncp_state_to_string(get_ncp_state()));
+
+	// Wait forever, this is the dummy plugin.
+	EH_WAIT_UNTIL(false);
+
+	EH_END();
+}
+
+char
+DummyNCPInstance::ncp_to_driver_pump()
+{
+	struct nlpt*const pt = &mNCPToDriverPumpPT;
+
+	NLPT_BEGIN(pt);
+	NLPT_END(pt);
+}
+
+char
+DummyNCPInstance::driver_to_ncp_pump()
+{
+	struct nlpt*const pt = &mNCPToDriverPumpPT;
+
+	NLPT_BEGIN(pt);
+	NLPT_END(pt);
+}
+
+bool
+DummyNCPInstance::setup_property_supported_by_class(const std::string& prop_name)
+{
+	return NCPInstanceBase::setup_property_supported_by_class(prop_name);
+}
+
+DummyNCPControlInterface&
+DummyNCPInstance::get_control_interface()
+{
+	return mControlInterface;
+}
diff --git a/src/ncp-dummy/DummyNCPInstance.h b/src/ncp-dummy/DummyNCPInstance.h
new file mode 100644
index 0000000..2d9d8d4
--- /dev/null
+++ b/src/ncp-dummy/DummyNCPInstance.h
@@ -0,0 +1,70 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__DummyNCPInstance__
+#define __wpantund__DummyNCPInstance__
+
+#include "NCPInstanceBase.h"
+#include "DummyNCPControlInterface.h"
+#include "nlpt.h"
+#include "SocketWrapper.h"
+#include "SocketAsyncOp.h"
+
+#include <queue>
+#include <set>
+#include <map>
+#include <errno.h>
+
+WPANTUND_DECLARE_NCPINSTANCE_PLUGIN(dummy, DummyNCPInstance);
+
+namespace nl {
+namespace wpantund {
+
+class DummyNCPControlInterface;
+
+class DummyNCPInstance : public NCPInstanceBase {
+	friend class DummyNCPControlInterface;
+
+public:
+	DummyNCPInstance(const Settings& settings = Settings());
+
+	virtual ~DummyNCPInstance();
+
+	virtual DummyNCPControlInterface& get_control_interface();
+
+	virtual int vprocess_event(int event, va_list args);
+
+protected:
+	virtual char ncp_to_driver_pump();
+	virtual char driver_to_ncp_pump();
+
+
+public:
+	static bool setup_property_supported_by_class(const std::string& prop_name);
+
+private:
+	DummyNCPControlInterface mControlInterface;
+}; // class DummyNCPInstance
+
+extern class DummyNCPInstance* gNCPInstance;
+
+}; // namespace wpantund
+}; // namespace nl
+
+#endif /* defined(__wpantund__DummyNCPInstance__) */
diff --git a/src/ncp-dummy/Makefile.am b/src/ncp-dummy/Makefile.am
new file mode 100644
index 0000000..8fbb626
--- /dev/null
+++ b/src/ncp-dummy/Makefile.am
@@ -0,0 +1,59 @@
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src \
+	-I$(top_srcdir)/src/util \
+	-I$(top_srcdir)/src/ncp-dummy \
+	-I$(top_srcdir)/src/wpantund \
+	-I$(top_srcdir)/third_party/pt \
+	-I$(top_srcdir)/third_party/assert-macros \
+	$(NULL)
+
+DISTCLEANFILES = \
+	.deps \
+	Makefile \
+	$(NULL)
+
+if BUILD_PLUGIN_NCP_DUMMY
+
+# Work-around the omnipotent automake nanny-state.
+mypkglibexecdir = $(pkglibexecdir)
+
+NCP_SOURCES = \
+	DummyNCPControlInterface.cpp \
+	DummyNCPControlInterface.h \
+	DummyNCPInstance.cpp \
+	DummyNCPInstance.h \
+	$(NULL)
+
+if STATIC_LINK_NCP_PLUGIN
+noinst_LTLIBRARIES = libncp-dummy.la
+libncp_dummy_la_SOURCES = $(NCP_SOURCES)
+libncp_dummy_la_CXXFLAGS = @BOOST_CXXFLAGS@
+else
+mypkglibexec_LTLIBRARIES = ncp-dummy.la
+ncp_dummy_la_LDFLAGS = \
+	-module \
+	-avoid-version \
+	-shared \
+	$(NULL)
+ncp_dummy_la_SOURCES = $(NCP_SOURCES)
+ncp_dummy_la_CXXFLAGS = @BOOST_CXXFLAGS@
+endif
+
+endif #BUILD_PLUGIN_NCP_dummy
diff --git a/src/ncp-spinel/Makefile.am b/src/ncp-spinel/Makefile.am
new file mode 100644
index 0000000..e66e9a4
--- /dev/null
+++ b/src/ncp-spinel/Makefile.am
@@ -0,0 +1,100 @@
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src \
+	-I$(top_srcdir)/src/util \
+	-I$(top_srcdir)/src/ncp-spinel \
+	-I$(top_srcdir)/src/wpantund \
+	-I$(top_srcdir)/third_party/pt \
+	-I$(top_srcdir)/third_party/assert-macros \
+	-I$(top_srcdir)/third_party/openthread/src/ncp \
+	$(NULL)
+
+DISTCLEANFILES = \
+	.deps \
+	Makefile \
+	$(NULL)
+
+EXTRA_DIST =                                         \
+	../../third_party/openthread/CONTRIBUTING.md     \
+	../../third_party/openthread/LICENSE             \
+	../../third_party/openthread/NOTICE              \
+	../../third_party/openthread/README.google       \
+	../../third_party/openthread/README.md           \
+	../../third_party/openthread/src/ncp/PROTOCOL.md \
+	../../third_party/openthread/src/ncp/spinel.c    \
+	../../third_party/openthread/src/ncp/spinel.h    \
+	../../third_party/openthread/tools/spi-hdlc-adapter/README.md          \
+	../../third_party/openthread/tools/spi-hdlc-adapter/spi-hdlc-adapter.c \
+	$(NULL)
+
+if BUILD_PLUGIN_NCP_SPINEL
+
+if HOST_IS_LINUX
+bin_PROGRAMS = spi-hdlc-adapter
+spi_hdlc_adapter_SOURCES = ../../third_party/openthread/tools/spi-hdlc-adapter/spi-hdlc-adapter.c
+endif
+
+# Work around the omnipotent automake nanny-state.
+mypkglibexecdir = $(pkglibexecdir)
+
+NCP_SOURCES = \
+	SpinelNCPControlInterface.cpp \
+	SpinelNCPControlInterface.h \
+	SpinelNCPInstance.cpp \
+	SpinelNCPInstance.h \
+	SpinelNCPInstance-DataPump.cpp \
+	SpinelNCPInstance-Protothreads.cpp \
+	SpinelNCPTask.cpp \
+	SpinelNCPTask.h \
+	SpinelNCPTaskDeepSleep.cpp \
+	SpinelNCPTaskGetNetworkTopology.h \
+	SpinelNCPTaskGetNetworkTopology.cpp \
+	SpinelNCPTaskGetMsgBufferCounters.h \
+	SpinelNCPTaskGetMsgBufferCounters.cpp \
+	SpinelNCPTaskDeepSleep.h \
+	SpinelNCPTaskForm.cpp \
+	SpinelNCPTaskForm.h \
+	SpinelNCPTaskJoin.cpp \
+	SpinelNCPTaskJoin.h \
+	SpinelNCPTaskLeave.cpp \
+	SpinelNCPTaskLeave.h \
+	SpinelNCPTaskScan.cpp \
+	SpinelNCPTaskScan.h \
+	SpinelNCPTaskSendCommand.cpp \
+	SpinelNCPTaskSendCommand.h \
+	SpinelNCPTaskWake.cpp \
+	SpinelNCPTaskWake.h \
+	$(top_srcdir)/third_party/openthread/src/ncp/spinel.c \
+	spinel-extra.c \
+	spinel-extra.h \
+	$(NULL)
+
+
+if STATIC_LINK_NCP_PLUGIN
+noinst_LTLIBRARIES = libncp-spinel.la
+libncp_spinel_la_SOURCES = $(NCP_SOURCES)
+libncp_spinel_la_CXXFLAGS = @BOOST_CXXFLAGS@
+else
+mypkglibexec_LTLIBRARIES = ncp-spinel.la
+ncp_spinel_la_LDFLAGS = -module -avoid-version -shared
+ncp_spinel_la_SOURCES = $(NCP_SOURCES)
+ncp_spinel_la_CXXFLAGS = @BOOST_CXXFLAGS@
+endif
+
+endif #BUILD_PLUGIN_NCP_SPINEL
diff --git a/src/ncp-spinel/SpinelNCPControlInterface.cpp b/src/ncp-spinel/SpinelNCPControlInterface.cpp
new file mode 100644
index 0000000..c8a5df3
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPControlInterface.cpp
@@ -0,0 +1,535 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+
+#include "SpinelNCPControlInterface.h"
+#include "SpinelNCPInstance.h"
+
+#include "wpantund.h"
+#include "config-file.h"
+#include "nlpt.h"
+#include "string-utils.h"
+#include "any-to.h"
+#include "time-utils.h"
+
+#include <cstring>
+#include <algorithm>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <syslog.h>
+#include <sys/time.h>
+
+#include <boost/bind.hpp>
+
+#include "spinel-extra.h"
+
+#include "SpinelNCPTask.h"
+#include "SpinelNCPTaskWake.h"
+#include "SpinelNCPTaskJoin.h"
+#include "SpinelNCPTaskForm.h"
+#include "SpinelNCPTaskLeave.h"
+#include "SpinelNCPTaskScan.h"
+#include "SpinelNCPTaskSendCommand.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+SpinelNCPControlInterface::SpinelNCPControlInterface(SpinelNCPInstance* instance_pointer)
+	:mNCPInstance(instance_pointer)
+{
+}
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+void
+SpinelNCPControlInterface::join(
+	const ValueMap& options,
+    CallbackWithStatus cb
+) {
+	mNCPInstance->start_new_task(boost::shared_ptr<SpinelNCPTask>(
+		new SpinelNCPTaskJoin(
+			mNCPInstance,
+			boost::bind(cb,_1),
+			options
+		)
+	));
+}
+
+void
+SpinelNCPControlInterface::form(
+	const ValueMap& options,
+    CallbackWithStatus cb
+) {
+	mNCPInstance->start_new_task(boost::shared_ptr<SpinelNCPTask>(
+		new SpinelNCPTaskForm(
+			mNCPInstance,
+			boost::bind(cb,_1),
+			options
+		)
+	));
+}
+
+void
+SpinelNCPControlInterface::leave(CallbackWithStatus cb)
+{
+	mNCPInstance->start_new_task(boost::shared_ptr<SpinelNCPTask>(
+		new SpinelNCPTaskLeave(
+			mNCPInstance,
+			boost::bind(cb,_1)
+		)
+	));
+}
+
+void
+SpinelNCPControlInterface::attach(CallbackWithStatus cb)
+{
+	mNCPInstance->start_new_task(
+		SpinelNCPTaskSendCommand::Factory(mNCPInstance)
+			.set_callback(cb)
+			.add_command(SpinelPackData(
+				SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S),
+				SPINEL_PROP_NET_IF_UP,
+				true
+			))
+			.add_command(SpinelPackData(
+				SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S),
+				SPINEL_PROP_NET_STACK_UP,
+				true
+			))
+			.finish()
+	);
+}
+
+void
+SpinelNCPControlInterface::reset(CallbackWithStatus cb)
+{
+	if (mNCPInstance->get_ncp_state() == FAULT) {
+		mNCPInstance->change_ncp_state(UNINITIALIZED);
+	}
+
+	mNCPInstance->start_new_task(SpinelNCPTaskSendCommand::Factory(mNCPInstance)
+		.set_callback(CallbackWithStatus(boost::bind(cb,kWPANTUNDStatus_Ok)))
+		.add_command(SpinelPackData(SPINEL_FRAME_PACK_CMD_RESET))
+		.finish()
+	);
+}
+
+void
+SpinelNCPControlInterface::begin_net_wake(uint8_t data, uint32_t flags, CallbackWithStatus cb)
+{
+	// TODO: Writeme!
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+SpinelNCPControlInterface::host_did_wake(CallbackWithStatus cb)
+{
+	// TODO: Writeme!
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+SpinelNCPControlInterface::begin_low_power(CallbackWithStatus cb)
+{
+	// TODO: Writeme!
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+void
+SpinelNCPControlInterface::refresh_state(CallbackWithStatus cb)
+{
+	mNCPInstance->start_new_task(SpinelNCPTaskSendCommand::Factory(mNCPInstance)
+		.set_callback(cb)
+		.add_command(SpinelPackData(SPINEL_FRAME_PACK_CMD_NOOP))
+		.finish()
+	);
+}
+
+void
+SpinelNCPControlInterface::data_poll(CallbackWithStatus cb)
+{
+	mNCPInstance->start_new_task(SpinelNCPTaskSendCommand::Factory(mNCPInstance)
+		.set_callback(cb)
+		.add_command(SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_GET, SPINEL_PROP_STREAM_NET))
+		.finish()
+	);
+}
+
+void
+SpinelNCPControlInterface::add_on_mesh_prefix(
+	const struct in6_addr *prefix,
+	bool defaultRoute,
+	CallbackWithStatus cb
+) {
+	uint8_t flags = 0;
+	SpinelNCPTaskSendCommand::Factory factory(mNCPInstance);
+
+	require_action(prefix != NULL, bail, cb(kWPANTUNDStatus_InvalidArgument));
+	require_action(mNCPInstance->mEnabled, bail, cb(kWPANTUNDStatus_InvalidWhenDisabled));
+
+	if (defaultRoute) {
+		flags |= SPINEL_NET_FLAG_DEFAULT_ROUTE;
+	}
+
+	flags |= SPINEL_NET_FLAG_PREFERRED | SPINEL_NET_FLAG_SLAAC | SPINEL_NET_FLAG_ON_MESH;
+
+	factory.set_callback(cb);
+	factory.set_lock_property(SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE);
+
+	factory.add_command(SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_INSERT(
+			SPINEL_DATATYPE_IPv6ADDR_S
+			SPINEL_DATATYPE_UINT8_S
+			SPINEL_DATATYPE_BOOL_S
+			SPINEL_DATATYPE_UINT8_S
+		),
+		SPINEL_PROP_THREAD_ON_MESH_NETS,
+		prefix,
+		IPV6_NETWORK_PREFIX_LENGTH,
+		true,
+		flags
+	));
+
+	mNCPInstance->start_new_task(factory.finish());
+
+bail:
+	return;
+}
+
+void
+SpinelNCPControlInterface::remove_on_mesh_prefix(
+	const struct in6_addr *prefix,
+	CallbackWithStatus cb
+) {
+	uint8_t flags = 0;
+	SpinelNCPTaskSendCommand::Factory factory(mNCPInstance);
+
+	require_action(prefix != NULL, bail, cb(kWPANTUNDStatus_InvalidArgument));
+	require_action(mNCPInstance->mEnabled, bail, cb(kWPANTUNDStatus_InvalidWhenDisabled));
+
+	factory.set_callback(cb);
+	factory.set_lock_property(SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE);
+
+	factory.add_command(SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_REMOVE(
+			SPINEL_DATATYPE_IPv6ADDR_S
+			SPINEL_DATATYPE_UINT8_S
+			SPINEL_DATATYPE_BOOL_S
+			SPINEL_DATATYPE_UINT8_S
+		),
+		SPINEL_PROP_THREAD_ON_MESH_NETS,
+		prefix,
+		IPV6_NETWORK_PREFIX_LENGTH,
+		true,
+		flags
+	));
+
+	mNCPInstance->start_new_task(factory.finish());
+
+bail:
+	return;
+}
+
+void
+SpinelNCPControlInterface::add_external_route(
+	const struct in6_addr *prefix,
+	int prefix_len_in_bits,
+	int domain_id,
+	ExternalRoutePriority priority,
+	CallbackWithStatus cb
+) {
+    const static int kPreferenceOffset = 6;
+	uint8_t flags = 0;
+
+	require_action(prefix != NULL, bail, cb(kWPANTUNDStatus_InvalidArgument));
+	require_action(prefix_len_in_bits >= 0, bail, cb(kWPANTUNDStatus_InvalidArgument));
+	require_action(prefix_len_in_bits <= IPV6_MAX_PREFIX_LENGTH, bail, cb(kWPANTUNDStatus_InvalidArgument));
+	require_action(mNCPInstance->mEnabled, bail, cb(kWPANTUNDStatus_InvalidWhenDisabled));
+
+	switch (priority) {
+	case ROUTE_HIGH_PREFERENCE:
+		flags = (1 << kPreferenceOffset);
+		break;
+
+	case ROUTE_MEDIUM_PREFERENCE:
+		flags = 0;
+		break;
+
+	case ROUTE_LOW_PREFRENCE:
+		flags = (3 << kPreferenceOffset);
+		break;
+	}
+
+	mNCPInstance->start_new_task(SpinelNCPTaskSendCommand::Factory(mNCPInstance)
+		.set_callback(cb)
+		.add_command(SpinelPackData(
+			SPINEL_FRAME_PACK_CMD_PROP_VALUE_INSERT(
+				SPINEL_DATATYPE_IPv6ADDR_S
+				SPINEL_DATATYPE_UINT8_S
+				SPINEL_DATATYPE_BOOL_S
+				SPINEL_DATATYPE_UINT8_S
+			),
+			SPINEL_PROP_THREAD_LOCAL_ROUTES,
+			prefix,
+			prefix_len_in_bits,
+			true,
+			flags
+		))
+		.set_lock_property(SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE)
+		.finish()
+	);
+
+bail:
+	return;
+}
+
+void
+SpinelNCPControlInterface::remove_external_route(
+	const struct in6_addr *prefix,
+	int prefix_len_in_bits,
+	int domain_id,
+	CallbackWithStatus cb
+) {
+	require_action(prefix != NULL, bail, cb(kWPANTUNDStatus_InvalidArgument));
+	require_action(prefix_len_in_bits >= 0, bail, cb(kWPANTUNDStatus_InvalidArgument));
+	require_action(prefix_len_in_bits <= IPV6_MAX_PREFIX_LENGTH, bail, cb(kWPANTUNDStatus_InvalidArgument));
+	require_action(mNCPInstance->mEnabled, bail, cb(kWPANTUNDStatus_InvalidWhenDisabled));
+
+	mNCPInstance->start_new_task(SpinelNCPTaskSendCommand::Factory(mNCPInstance)
+		.set_callback(cb)
+		.add_command(SpinelPackData(
+			SPINEL_FRAME_PACK_CMD_PROP_VALUE_REMOVE(
+				SPINEL_DATATYPE_IPv6ADDR_S
+				SPINEL_DATATYPE_UINT8_S
+				SPINEL_DATATYPE_BOOL_S
+				SPINEL_DATATYPE_UINT8_S
+			),
+			SPINEL_PROP_THREAD_LOCAL_ROUTES,
+			prefix,
+			prefix_len_in_bits,
+			true,
+			0
+		))
+		.set_lock_property(SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE)
+		.finish()
+	);
+
+bail:
+	return;
+}
+
+void
+SpinelNCPControlInterface::permit_join(
+    int seconds,
+    uint8_t traffic_type,
+    in_port_t traffic_port,
+    bool network_wide,
+    CallbackWithStatus cb
+    )
+{
+	SpinelNCPTaskSendCommand::Factory factory(mNCPInstance);
+	int ret = kWPANTUNDStatus_Ok;
+
+	if (!mNCPInstance->mEnabled) {
+		ret = kWPANTUNDStatus_InvalidWhenDisabled;
+		goto bail;
+	}
+
+	if (traffic_port == 0) {
+		// If no port was explicitly set, default to the discovered
+		// "Commissioner Port"  (“:MC”).
+		traffic_port = htons(mNCPInstance->mCommissionerPort);
+	}
+
+	ret = mNCPInstance->set_commissioniner(seconds, traffic_type, traffic_port);
+
+	require_noerr(ret, bail);
+
+	factory.set_callback(cb);
+
+	if (seconds > 0) {
+		factory.add_command(SpinelPackData(
+			SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT16_S),
+			SPINEL_PROP_THREAD_ASSISTING_PORTS,
+			ntohs(traffic_port)
+		));
+	} else {
+		factory.add_command(SpinelPackData(
+			SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_NULL_S),
+			SPINEL_PROP_THREAD_ASSISTING_PORTS
+		));
+	}
+
+	mNCPInstance->start_new_task(factory.finish());
+
+bail:
+	if (ret) {
+		cb(ret);
+	} else {
+		syslog(LOG_NOTICE, "PermitJoin: seconds=%d type=%d port=%d", seconds, traffic_type, ntohs(traffic_port));
+	}
+}
+
+void
+SpinelNCPControlInterface::netscan_start(
+    const ValueMap& options,
+    CallbackWithStatus cb
+) {
+	ChannelMask channel_mask(mNCPInstance->get_default_channel_mask());
+
+	if (options.count(kWPANTUNDProperty_NCPChannelMask)) {
+		channel_mask = any_to_int(options.at(kWPANTUNDProperty_NCPChannelMask));
+	}
+
+	mNCPInstance->start_new_task(boost::shared_ptr<SpinelNCPTask>(
+		new SpinelNCPTaskScan(
+			mNCPInstance,
+			boost::bind(cb,_1),
+			channel_mask
+		)
+	));
+}
+
+void
+SpinelNCPControlInterface::netscan_stop(CallbackWithStatus cb)
+{
+	cb(kWPANTUNDStatus_FeatureNotImplemented); // TODO: Start network scan
+}
+
+void
+SpinelNCPControlInterface::energyscan_start(
+    const ValueMap& options,
+    CallbackWithStatus cb
+) {
+	ChannelMask channel_mask(mNCPInstance->get_default_channel_mask());
+
+	if (options.count(kWPANTUNDProperty_NCPChannelMask)) {
+		channel_mask = any_to_int(options.at(kWPANTUNDProperty_NCPChannelMask));
+	}
+
+	mNCPInstance->start_new_task(boost::shared_ptr<SpinelNCPTask>(
+		new SpinelNCPTaskScan(
+			mNCPInstance,
+			boost::bind(cb,_1),
+			channel_mask,
+			SpinelNCPTaskScan::kDefaultScanPeriod,
+			SpinelNCPTaskScan::kScanTypeEnergy
+		)
+	));
+}
+
+void
+SpinelNCPControlInterface::energyscan_stop(CallbackWithStatus cb)
+{
+	cb(kWPANTUNDStatus_FeatureNotImplemented);
+}
+
+std::string
+SpinelNCPControlInterface::get_name() {
+	return mNCPInstance->get_name();
+}
+
+void
+SpinelNCPControlInterface::mfg(
+    const std::string& mfg_command,
+    CallbackWithStatusArg1 cb
+) {
+	mNCPInstance->start_new_task(
+		SpinelNCPTaskSendCommand::Factory(mNCPInstance)
+			.set_callback(cb)
+			.add_command(SpinelPackData(
+				SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UTF8_S),
+				SPINEL_PROP_NEST_STREAM_MFG,
+				mfg_command.c_str()
+			))
+			.set_reply_format(SPINEL_DATATYPE_UTF8_S)
+			.finish()
+	);
+}
+
+const WPAN::NetworkInstance&
+SpinelNCPControlInterface::get_current_network_instance()const
+{
+	return mNCPInstance->get_current_network_instance();
+}
+
+
+NCPInstance&
+SpinelNCPControlInterface::get_ncp_instance()
+{
+	return (*mNCPInstance);
+}
+
+void
+SpinelNCPControlInterface::pcap_to_fd(int fd, CallbackWithStatus cb)
+{
+	int ret = mNCPInstance->mPcapManager.insert_fd(fd);
+
+	if (ret < 0) {
+		syslog(LOG_ERR, "pcap_to_fd: Failed: \"%s\" (%d)", strerror(errno), errno);
+
+		cb(kWPANTUNDStatus_Failure);
+
+	} else {
+		cb(kWPANTUNDStatus_Ok);
+	}
+}
+
+void
+SpinelNCPControlInterface::pcap_terminate(CallbackWithStatus cb)
+{
+	mNCPInstance->mPcapManager.close_fd_set(mNCPInstance->mPcapManager.get_fd_set());
+	cb(kWPANTUNDStatus_Ok);
+}
+
+
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+void
+SpinelNCPControlInterface::get_property(
+    const std::string& in_key, CallbackWithStatusArg1 cb
+    )
+{
+	if (!mNCPInstance->is_initializing_ncp()) {
+		syslog(LOG_INFO, "get_property: key: \"%s\"", in_key.c_str());
+	}
+	mNCPInstance->get_property(in_key, cb);
+}
+
+void
+SpinelNCPControlInterface::set_property(
+    const std::string&                      key,
+    const boost::any&                       value,
+    CallbackWithStatus      cb
+    )
+{
+	syslog(LOG_INFO, "set_property: key: \"%s\"", key.c_str());
+	mNCPInstance->set_property(key, value, cb);
+}
diff --git a/src/ncp-spinel/SpinelNCPControlInterface.h b/src/ncp-spinel/SpinelNCPControlInterface.h
new file mode 100644
index 0000000..b91335a
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPControlInterface.h
@@ -0,0 +1,136 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __WPAN_DUMMY_NCP_H__
+#define __WPAN_DUMMY_NCP_H__ 1
+
+#include "NCPInstance.h"
+#include "NCPControlInterface.h"
+#include "NCPMfgInterface_v1.h"
+#include "nlpt.h"
+#include "Callbacks.h"
+#include "EventHandler.h"
+
+#include <queue>
+#include <set>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+namespace nl {
+namespace wpantund {
+
+class SpinelNCPInstance;
+
+class SpinelNCPControlInterface : public NCPControlInterface, public NCPMfgInterface_v1 {
+public:
+	friend class SpinelNCPInstance;
+
+	SpinelNCPControlInterface(SpinelNCPInstance* instance_pointer);
+	virtual ~SpinelNCPControlInterface() { }
+
+	virtual const WPAN::NetworkInstance& get_current_network_instance(void)const;
+
+	virtual void join(
+		const ValueMap& options,
+	    CallbackWithStatus cb = NilReturn()
+	);
+
+	virtual void form(
+		const ValueMap& options,
+	    CallbackWithStatus cb = NilReturn()
+	);
+
+	virtual void leave(CallbackWithStatus cb = NilReturn());
+	virtual void attach(CallbackWithStatus cb = NilReturn());
+	virtual void begin_low_power(CallbackWithStatus cb = NilReturn());
+
+	virtual void netscan_start(const ValueMap& options, CallbackWithStatus cb = NilReturn());
+	virtual void netscan_stop(CallbackWithStatus cb = NilReturn());
+
+	virtual void energyscan_start(const ValueMap& options, CallbackWithStatus cb = NilReturn());
+	virtual void energyscan_stop(CallbackWithStatus cb = NilReturn());
+
+	virtual void begin_net_wake(uint8_t data, uint32_t flags, CallbackWithStatus cb = NilReturn());
+	virtual void reset(CallbackWithStatus cb = NilReturn());
+	virtual void permit_join(
+	    int seconds = 15 * 60,
+	    uint8_t commissioning_traffic_type = 0xFF,
+	    in_port_t commissioning_traffic_port = 0,
+	    bool network_wide = false,
+	    CallbackWithStatus      cb = NilReturn());
+
+	virtual void refresh_state(CallbackWithStatus cb = NilReturn());
+
+	virtual void get_property(
+	    const std::string& key, CallbackWithStatusArg1 cb);
+	virtual void set_property(
+	    const std::string&                      key,
+	    const boost::any&                       value,
+	    CallbackWithStatus      cb);
+	virtual void add_on_mesh_prefix(
+		const struct in6_addr *prefix,
+		bool defaultRoute,
+		CallbackWithStatus cb = NilReturn()
+	);
+
+	virtual void remove_on_mesh_prefix(
+		const struct in6_addr *prefix,
+		CallbackWithStatus cb = NilReturn()
+	);
+
+	virtual void add_external_route(
+		const struct in6_addr *prefix,
+		int prefix_len_in_bits,
+		int domain_id,
+		ExternalRoutePriority priority,
+		CallbackWithStatus cb = NilReturn()
+	);
+
+	virtual void remove_external_route(
+		const struct in6_addr *prefix,
+		int prefix_len_in_bits,
+		int domain_id,
+		CallbackWithStatus cb = NilReturn()
+	);
+
+	virtual void data_poll(CallbackWithStatus cb = NilReturn());
+	virtual void host_did_wake(CallbackWithStatus cb = NilReturn());
+
+	virtual std::string get_name();
+
+	virtual NCPInstance& get_ncp_instance(void);
+
+	virtual void pcap_to_fd(int fd, CallbackWithStatus cb = NilReturn());
+
+	virtual void pcap_terminate(CallbackWithStatus cb = NilReturn());
+
+	/******************* NCPMfgInterface_v1 ********************/
+	virtual void mfg(const std::string& mfg_command, CallbackWithStatusArg1 cb = NilReturn());
+
+private:
+
+	SpinelNCPInstance* mNCPInstance;
+
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+
+#endif
diff --git a/src/ncp-spinel/SpinelNCPInstance-DataPump.cpp b/src/ncp-spinel/SpinelNCPInstance-DataPump.cpp
new file mode 100644
index 0000000..871dc25
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPInstance-DataPump.cpp
@@ -0,0 +1,545 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "SpinelNCPInstance.h"
+#include "time-utils.h"
+#include "assert-macros.h"
+#include <syslog.h>
+#include <errno.h>
+#include "socket-utils.h"
+#include <stdexcept>
+#include <sys/file.h>
+#include "SuperSocket.h"
+
+using namespace nl;
+using namespace wpantund;
+
+#define HDLC_BYTE_FLAG             0x7E
+#define HDLC_BYTE_ESC              0x7D
+#define HDLC_BYTE_XON              0x11
+#define HDLC_BYTE_XOFF             0x13
+#define HDLC_BYTE_SPECIAL          0xF8
+#define HDLC_ESCAPE_XFORM          0x20
+
+static bool
+hdlc_byte_needs_escape(uint8_t byte)
+{
+	switch(byte) {
+	case HDLC_BYTE_SPECIAL:
+	case HDLC_BYTE_ESC:
+	case HDLC_BYTE_FLAG:
+	case HDLC_BYTE_XOFF:
+	case HDLC_BYTE_XON:
+		return true;
+
+	default:
+		return false;
+	}
+}
+
+static uint16_t
+hdlc_crc16(uint16_t aFcs, uint8_t aByte)
+{
+#if 1
+	// CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-CCITT
+	// width=16 poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 check=0x2189 name="KERMIT"
+	// http://reveng.sourceforge.net/crc-catalogue/16.htm#crc.cat.kermit
+    static const uint16_t sFcsTable[256] =
+    {
+        0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+        0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+        0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+        0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+        0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+        0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+        0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+        0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+        0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+        0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+        0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+        0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+        0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+        0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+        0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+        0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+        0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+        0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+        0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+        0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+        0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+        0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+        0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+        0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+        0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+        0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+        0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+        0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+        0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+        0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+        0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+        0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+    };
+    return (aFcs >> 8) ^ sFcsTable[(aFcs ^ aByte) & 0xff];
+#else
+	// CRC-16/CCITT-FALSE, same CRC as 802.15.4
+	// width=16 poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 name="CRC-16/CCITT-FALSE"
+	// http://reveng.sourceforge.net/crc-catalogue/16.htm#crc.cat.crc-16-ccitt-false
+	aFcs = (uint16_t)((aFcs >> 8) | (aFcs << 8));
+	aFcs ^= aByte;
+	aFcs ^= ((aFcs & 0xff) >> 4);
+	aFcs ^= (aFcs << 12);
+	aFcs ^= ((aFcs & 0xff) << 5);
+	return aFcs;
+#endif
+}
+
+char
+SpinelNCPInstance::ncp_to_driver_pump()
+{
+	struct nlpt*const pt = &mNCPToDriverPumpPT;
+//	unsigned int prop_key = 0;
+	unsigned int command_value = 0;
+	uint8_t byte;
+
+	// Automatically detect socket resets and behave accordingly.
+	if (mSerialAdapter->did_reset()) {
+		syslog(LOG_NOTICE, "[-NCP-]: Socket Reset");
+		NLPT_INIT(&mNCPToDriverPumpPT);
+		NLPT_INIT(&mDriverToNCPPumpPT);
+
+		process_event(EVENT_NCP_CONN_RESET);
+	}
+
+	NLPT_BEGIN(pt);
+
+	// This macro abstracts the logic to read a single character into
+	// `data`, in a protothreads-friendly way.
+#define READ_CHARACTER(pt, data, on_fail) \
+	while(1) {                                  \
+		NLPT_WAIT_UNTIL_READABLE_OR_COND(pt, mSerialAdapter->get_read_fd(), mSerialAdapter->can_read()); \
+		ssize_t retlen = mSerialAdapter->read(data, 1); \
+		if (retlen < 0) { \
+			syslog(LOG_ERR, "[-NCP-]: Socket error on read: %s %d", \
+			       strerror((int)-retlen), (int)(-retlen)); \
+			signal_fatal_error(ERRORCODE_ERRNO); \
+			goto on_fail; \
+		} else if (retlen == 0) { \
+			continue; \
+		} \
+		break ; \
+	};
+
+	while (!ncp_state_is_detached_from_ncp(get_ncp_state())) {
+		mInboundHeader = 0;
+		mInboundFrameSize = 0;
+
+		// Yield until the socket is readable. We do a
+		// yield here instead of a wait because we want to
+		// only handle one packet per run through the main loop.
+		// Using `YIELD` instead of `WAIT` guarantees that we
+		// will yield control of the protothread at least once,
+		// even if the socket is already readable.
+		NLPT_YIELD_UNTIL_READABLE_OR_COND(pt, mSerialAdapter->get_read_fd(), mSerialAdapter->can_read());
+
+#if WPANTUND_SPINEL_USE_FLEN
+		do {
+			READ_CHARACTER(pt, (void*)&mInboundFrame[0], on_error);
+
+			if (HDLC_BYTE_FLAG != mInboundFrame[0]) {
+				// The dreaded extraneous character error.
+
+				// Log the error.
+				{
+					char printable = mInboundFrame[0];
+					if(iscntrl(printable) || printable<0)
+						printable = '.';
+
+					syslog(LOG_WARNING,
+						   "[NCP->] Extraneous Character: 0x%02X [%c] (%d)\n",
+						   (uint8_t)mInboundFrame[0],
+						   printable,
+						   (uint8_t)mInboundFrame[0]);
+				}
+
+				// Flush out all remaining data since this is a strong
+				// indication that something has gone horribly wrong.
+				while (mSerialAdapter->can_read()) {
+					READ_CHARACTER(pt, (void*)&mInboundFrame[0], on_error);
+				}
+
+				ncp_is_misbehaving();
+				goto on_error;
+			}
+		} while (UART_STREAM_FLAG != mInboundFrame[0]);
+
+		// Read the frame length
+		READ_CHARACTER(pt, (void*)((char*)&mInboundFrame+0), on_error);
+		READ_CHARACTER(pt, (void*)((char*)&mInboundFrame+1), on_error);
+
+		mInboundFrameSize = (mInboundFrame[0] << 8) + mInboundFrame[1];
+
+		require(mInboundFrameSize > 1, on_error);
+		require(mInboundFrameSize <= SPINEL_FRAME_MAX_SIZE, on_error);
+
+		// Read the rest of the packet.
+		NLPT_ASYNC_READ_STREAM(
+			pt,
+			mSerialAdapter.get(),
+			mInboundFrame,
+			mInboundFrameSize
+		);
+#else
+
+		mInboundFrameSize = 0;
+		mInboundFrameHDLCCRC = 0xffff;
+
+		do {
+			READ_CHARACTER(pt, &byte, on_error);
+
+			if (byte == HDLC_BYTE_FLAG) {
+				break;
+			}
+			if (byte == HDLC_BYTE_ESC) {
+				READ_CHARACTER(pt, &byte, on_error);
+				if (byte == HDLC_BYTE_FLAG) {
+					break;
+				} else {
+					byte ^= HDLC_ESCAPE_XFORM;
+				}
+			}
+
+			if (mInboundFrameSize >= 2) {
+				mInboundFrameHDLCCRC = hdlc_crc16(mInboundFrameHDLCCRC, mInboundFrame[mInboundFrameSize-2]);
+			}
+
+			require(mInboundFrameSize < sizeof(mInboundFrame), on_error);
+
+			mInboundFrame[mInboundFrameSize++] = byte;
+
+		} while(true);
+
+		if (mInboundFrameSize <= 2) {
+			continue;
+		}
+
+		mInboundFrameSize -= 2;
+		mInboundFrameHDLCCRC ^= 0xFFFF;
+		{
+			uint16_t frame_crc = (mInboundFrame[mInboundFrameSize]|(mInboundFrame[mInboundFrameSize+1]<<8));
+			if (mInboundFrameHDLCCRC != frame_crc) {
+
+				int i;
+				static const uint8_t kAsciiCR = 13;
+				static const uint8_t kAsciiBEL = 7;
+
+				syslog(LOG_ERR, "[NCP->]: Frame CRC Mismatch: Calc:0x%04X != Frame:0x%04X, Garbage on line?", mInboundFrameHDLCCRC, frame_crc);
+
+				// This frame might be an ASCII backtrace, so we check to
+				// see if all of the characters are ascii characters, and if
+				// so we dump out this packet directly to syslog.
+
+				mInboundFrameSize += 2;
+
+				for (i = 0; i < mInboundFrameSize; i++) {
+					// Acceptable control codes
+					if (mInboundFrame[i] >= kAsciiBEL && mInboundFrame[i] <= kAsciiCR) {
+						continue;
+					}
+					// NUL characters are OK.
+					if (mInboundFrame[i] == 0) {
+						continue;
+					}
+					// Acceptable characters
+					if (mInboundFrame[i] >= 32 && mInboundFrame[i] <= 127) {
+						continue;
+					}
+
+					syslog(LOG_ERR, "[NCP->]: Garbage is not ASCII ([%d]=%d)", i, mInboundFrame[i]);
+					break;
+				}
+
+				if (i == mInboundFrameSize) {
+					handle_ncp_log(mInboundFrame, mInboundFrameSize);
+				}
+
+				continue;
+			}
+		}
+
+#endif
+
+		if (pt->last_errno) {
+			syslog(LOG_ERR, "[-NCP-]: Socket error on read: %s", strerror(pt->last_errno));
+			errno = pt->last_errno;
+			signal_fatal_error(ERRORCODE_ERRNO);
+			goto on_error;
+		}
+
+		if (spinel_datatype_unpack(mInboundFrame, mInboundFrameSize, "Ci", &mInboundHeader, &command_value) > 0) {
+			if ((mInboundHeader&SPINEL_HEADER_FLAG) != SPINEL_HEADER_FLAG) {
+				// Unrecognized frame.
+				break;
+			}
+
+			if (SPINEL_HEADER_GET_IID(mInboundHeader) != 0) {
+				// We only support IID zero for now.
+				break;
+			}
+
+			handle_ncp_spinel_callback(command_value, mInboundFrame, mInboundFrameSize);
+		}
+	} // while (!ncp_state_is_detached_from_ncp(get_ncp_state()))
+
+on_error:;
+	// If we get here, we will restart the protothread at the next iteration.
+
+	NLPT_END(pt);
+}
+
+char
+SpinelNCPInstance::driver_to_ncp_pump()
+{
+	struct nlpt*const pt = &mDriverToNCPPumpPT;
+
+	NLPT_BEGIN(pt);
+
+	while (!ncp_state_is_detached_from_ncp(get_ncp_state())) {
+		// If there is an outbound callback at this
+		// point, then we assume it is stale and
+		// immediately clear it out.
+		if (!mOutboundCallback.empty()) {
+			mOutboundCallback(kWPANTUNDStatus_Canceled);
+			mOutboundCallback.clear();
+		}
+
+		// Wait for a packet to be available from interface OR management queue.
+		if (mOutboundBufferLen > 0) {
+			// If there is something in the outbound queue,
+			// we shouldn't try any of the checks below, since it
+			// will delay processing.
+
+		} else if (static_cast<bool>(mLegacyInterface) && is_legacy_interface_enabled()) {
+			NLPT_YIELD_UNTIL_READABLE2_OR_COND(
+				pt,
+				mPrimaryInterface->get_read_fd(),
+				mLegacyInterface->get_read_fd(),
+				(mOutboundBufferLen > 0)
+				|| mLegacyInterface->can_read()
+				|| mPrimaryInterface->can_read()
+			);
+
+		} else {
+			NLPT_YIELD_UNTIL_READABLE_OR_COND(
+				pt,
+				mPrimaryInterface->get_read_fd(),
+				mPrimaryInterface->can_read() || (mOutboundBufferLen > 0)
+			);
+		}
+
+		// Get packet or management command, and also
+		// perform any necessary filtering.
+		if (mOutboundBufferLen > 0) {
+			if (mOutboundBuffer[1] == SPINEL_CMD_PROP_VALUE_GET) {
+				spinel_prop_key_t key;
+				spinel_datatype_unpack(mOutboundBuffer, mOutboundBufferLen, "Cii", NULL, NULL, &key);
+				syslog(LOG_INFO, "[->NCP] CMD_PROP_VALUE_GET(%s) tid:%d", spinel_prop_key_to_cstr(key), SPINEL_HEADER_GET_TID(mOutboundBuffer[0]));
+			} else if (mOutboundBuffer[1] == SPINEL_CMD_PROP_VALUE_SET) {
+				spinel_prop_key_t key;
+				spinel_datatype_unpack(mOutboundBuffer, mOutboundBufferLen, "Cii", NULL, NULL, &key);
+				syslog(LOG_INFO, "[->NCP] CMD_PROP_VALUE_SET(%s) tid:%d", spinel_prop_key_to_cstr(key), SPINEL_HEADER_GET_TID(mOutboundBuffer[0]));
+			} else if (mOutboundBuffer[1] == SPINEL_CMD_PROP_VALUE_INSERT) {
+				spinel_prop_key_t key;
+				spinel_datatype_unpack(mOutboundBuffer, mOutboundBufferLen, "Cii", NULL, NULL, &key);
+				syslog(LOG_INFO, "[->NCP] CMD_PROP_VALUE_INSERT(%s) tid:%d", spinel_prop_key_to_cstr(key), SPINEL_HEADER_GET_TID(mOutboundBuffer[0]));
+			} else if (mOutboundBuffer[1] == SPINEL_CMD_PROP_VALUE_REMOVE) {
+				spinel_prop_key_t key;
+				spinel_datatype_unpack(mOutboundBuffer, mOutboundBufferLen, "Cii", NULL, NULL, &key);
+				syslog(LOG_INFO, "[->NCP] CMD_PROP_VALUE_REMOVE(%s) tid:%d", spinel_prop_key_to_cstr(key), SPINEL_HEADER_GET_TID(mOutboundBuffer[0]));
+			} else if (mOutboundBuffer[1] == SPINEL_CMD_NOOP) {
+				syslog(LOG_INFO, "[->NCP] CMD_NOOP tid:%d", SPINEL_HEADER_GET_TID(mOutboundBuffer[0]));
+			} else if (mOutboundBuffer[1] == SPINEL_CMD_RESET) {
+				syslog(LOG_INFO, "[->NCP] CMD_RESET tid:%d", SPINEL_HEADER_GET_TID(mOutboundBuffer[0]));
+			} else if (mOutboundBuffer[1] == SPINEL_CMD_NET_CLEAR) {
+				syslog(LOG_INFO, "[->NCP] CMD_NET_CLEAR tid:%d", SPINEL_HEADER_GET_TID(mOutboundBuffer[0]));
+			} else {
+				syslog(LOG_INFO, "[->NCP] Spinel command 0x%02X tid:%d", mOutboundBuffer[1], SPINEL_HEADER_GET_TID(mOutboundBuffer[0]));
+			}
+		} else {
+			// There is an IPv6 packet waiting on one of the tunnel interfaces.
+
+			if (mPrimaryInterface->can_read()) {
+				mOutboundBufferLen = (spinel_ssize_t)mPrimaryInterface->read(
+					&mOutboundBuffer[5],
+					sizeof(mOutboundBuffer)-5
+				);
+				mOutboundBufferType = FRAME_TYPE_DATA;
+			} else if (static_cast<bool>(mLegacyInterface)) {
+				mOutboundBufferLen = (spinel_ssize_t)mLegacyInterface->read(
+					&mOutboundBuffer[5],
+					sizeof(mOutboundBuffer)-5
+				);
+				mOutboundBufferType = FRAME_TYPE_LEGACY_DATA;
+			}
+
+			if (0 > mOutboundBufferLen) {
+				syslog(LOG_ERR,
+				       "driver_to_ncp_pump: Socket error on read: %s",
+				       strerror(errno));
+				signal_fatal_error(ERRORCODE_ERRNO);
+				break;
+			}
+
+			if (mOutboundBufferLen <= 0) {
+				// No packet...?
+				mOutboundBufferLen = 0;
+				continue;
+			}
+
+			if (!should_forward_ncpbound_frame(&mOutboundBufferType, &mOutboundBuffer[5], mOutboundBufferLen)) {
+				mOutboundBufferLen = 0;
+				continue;
+			}
+
+			if (get_ncp_state() == CREDENTIALS_NEEDED) {
+				mOutboundBufferType = FRAME_TYPE_INSECURE_DATA;
+			}
+
+			mOutboundBuffer[3] = (mOutboundBufferLen & 0xFF);
+			mOutboundBuffer[4] = ((mOutboundBufferLen >> 8) & 0xFF);
+
+			mOutboundBufferLen += 5;
+
+			mOutboundBuffer[0] = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0;
+			mOutboundBuffer[1] = SPINEL_CMD_PROP_VALUE_SET;
+
+			if (mOutboundBufferType == FRAME_TYPE_DATA) {
+				mOutboundBuffer[2] = SPINEL_PROP_STREAM_NET;
+
+			} else if (mOutboundBufferType == FRAME_TYPE_INSECURE_DATA) {
+				mOutboundBuffer[2] = SPINEL_PROP_STREAM_NET_INSECURE;
+
+			} else {
+				mOutboundBuffer[0] = SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_1;
+				mOutboundBuffer[2] = SPINEL_PROP_STREAM_NET;
+			}
+		}
+
+#if VERBOSE_DEBUG || 1
+		// Very verbose debugging. Dumps out all outbound packets.
+		{
+			char readable_buffer[300];
+			encode_data_into_string(mOutboundBuffer,
+			                        mOutboundBufferLen,
+			                        readable_buffer,
+			                        sizeof(readable_buffer),
+			                        0);
+			syslog(LOG_INFO, "\t↳ %s", (const char*)readable_buffer);
+		}
+#endif // VERBOSE_DEBUG
+
+
+#if WPANTUND_SPINEL_USE_FLEN
+		mOutboundBufferHeader[0] = HDLC_BYTE_FLAG;
+		mOutboundBufferHeader[1] = (mOutboundBufferLen >> 8);
+		mOutboundBufferHeader[2] = (mOutboundBufferLen & 0xFF);
+
+		mOutboundBufferSent = 0;
+
+		// Go ahead send
+		NLPT_ASYNC_WRITE_STREAM(
+			pt,
+			mSerialAdapter.get(),
+			mOutboundBufferHeader,
+			mOutboundBufferLen + sizeof(mOutboundBufferHeader)
+		);
+		mOutboundBufferSent += pt->byte_count;
+#else
+
+		mOutboundBufferEscapedLen = 1;
+		mOutboundBufferEscaped[0] = HDLC_BYTE_FLAG;
+		{
+			spinel_ssize_t i;
+			uint8_t byte;
+			uint16_t crc(0xFFFF);
+			for (i = 0; i < mOutboundBufferLen; i++) {
+				byte = mOutboundBuffer[i];
+				crc = hdlc_crc16(crc, byte);
+				if (hdlc_byte_needs_escape(byte)) {
+					mOutboundBufferEscaped[mOutboundBufferEscapedLen++] = HDLC_BYTE_ESC;
+					mOutboundBufferEscaped[mOutboundBufferEscapedLen++] = byte ^ HDLC_ESCAPE_XFORM;
+				} else {
+					mOutboundBufferEscaped[mOutboundBufferEscapedLen++] = byte;
+				}
+			}
+			crc ^= 0xFFFF;
+			byte = (crc & 0xFF);
+			if (hdlc_byte_needs_escape(byte)) {
+				mOutboundBufferEscaped[mOutboundBufferEscapedLen++] = HDLC_BYTE_ESC;
+				mOutboundBufferEscaped[mOutboundBufferEscapedLen++] = byte ^ HDLC_ESCAPE_XFORM;
+			} else {
+				mOutboundBufferEscaped[mOutboundBufferEscapedLen++] = byte;
+			}
+			byte = ((crc>>8) & 0xFF);
+			if (hdlc_byte_needs_escape(byte)) {
+				mOutboundBufferEscaped[mOutboundBufferEscapedLen++] = HDLC_BYTE_ESC;
+				mOutboundBufferEscaped[mOutboundBufferEscapedLen++] = byte ^ HDLC_ESCAPE_XFORM;
+			} else {
+				mOutboundBufferEscaped[mOutboundBufferEscapedLen++] = byte;
+			}
+			mOutboundBufferEscaped[mOutboundBufferEscapedLen++] = HDLC_BYTE_FLAG;
+		}
+
+		mOutboundBufferSent = 0;
+
+		// Go ahead send
+		NLPT_ASYNC_WRITE_STREAM(
+			pt,
+			mSerialAdapter.get(),
+			mOutboundBufferEscaped,
+			mOutboundBufferEscapedLen
+		);
+		mOutboundBufferSent += pt->byte_count;
+#endif
+
+		mOutboundBufferLen = 0;
+
+		require(pt->last_errno == 0, on_error);
+
+		// Go ahead and fire off the "did send" callback.
+		if (!mOutboundCallback.empty()) {
+			mOutboundCallback(kWPANTUNDStatus_Ok);
+			mOutboundCallback.clear();
+		}
+
+	} // while(true)
+
+on_error:
+	// If we get here, we will restart the protothread at the next iteration.
+
+	if (!mOutboundCallback.empty()) {
+		mOutboundCallback(kWPANTUNDStatus_Failure);
+		mOutboundCallback.clear();
+	}
+
+	NLPT_END(pt);
+}
diff --git a/src/ncp-spinel/SpinelNCPInstance-Protothreads.cpp b/src/ncp-spinel/SpinelNCPInstance-Protothreads.cpp
new file mode 100644
index 0000000..7586db1
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPInstance-Protothreads.cpp
@@ -0,0 +1,637 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "SpinelNCPInstance.h"
+#include "time-utils.h"
+#include "assert-macros.h"
+#include <syslog.h>
+#include <errno.h>
+#include "socket-utils.h"
+#include <stdexcept>
+#include <sys/file.h>
+#include "SuperSocket.h"
+#include "SpinelNCPTask.h"
+#include "spinel-extra.h"
+
+#include "SpinelNCPTaskSendCommand.h"
+#include "SpinelNCPTaskScan.h"
+#include "SpinelNCPTaskForm.h"
+#include "SpinelNCPTaskLeave.h"
+#include "SpinelNCPTaskJoin.h"
+#include "SpinelNCPTaskWake.h"
+#include "SpinelNCPTaskDeepSleep.h"
+
+using namespace nl;
+using namespace wpantund;
+
+int
+SpinelNCPInstance::vprocess_disabled(int event, va_list args)
+{
+	EH_BEGIN_SUB(&mSubPT);
+
+
+	while(!mEnabled) {
+		// If the association state is uninitialized, fail early.
+		if (get_ncp_state() == UNINITIALIZED) {
+			syslog(LOG_NOTICE, "Cannot attempt to sleep until NCP is initialized.");
+			EH_EXIT();
+		}
+
+		// Wait for any tasks or commands to complete.
+		EH_REQUIRE_WITHIN(
+			NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT,
+			mEnabled || is_busy(),
+			timeout_error
+		);
+
+		if (mEnabled) {
+			break;
+		}
+
+		if ((get_ncp_state() != DEEP_SLEEP) && (get_ncp_state() != FAULT)) {
+			start_new_task(boost::shared_ptr<SpinelNCPTask>(new SpinelNCPTaskDeepSleep(this, NilReturn())));
+
+			EH_WAIT_UNTIL_WITH_TIMEOUT(
+				NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT,
+				(get_ncp_state() == DEEP_SLEEP) || mTaskQueue.empty()
+			);
+		}
+
+		// If we didn't enter deep sleep then we need to bail early.
+		if ((get_ncp_state() != DEEP_SLEEP) && (get_ncp_state() != FAULT)) {
+			if (!ncp_state_is_initializing(get_ncp_state())) {
+				get_control_interface().reset();
+			}
+			EH_EXIT();
+		}
+
+		EH_WAIT_UNTIL(!IS_EVENT_FROM_NCP(event));
+
+		EH_REQUIRE_WITHIN(
+			NCP_DEEP_SLEEP_TICKLE_TIMEOUT,
+			(get_ncp_state() != DEEP_SLEEP)
+			|| mEnabled
+			|| IS_EVENT_FROM_NCP(event),
+			do_deep_sleep_tickle
+		);
+
+		continue;
+
+		// Exceptions
+
+do_deep_sleep_tickle:
+		// ...Go ahead and reset the NCP and state machine.
+		// This will make sure the NCP is in a known state
+		// and allow it to recover if the NCP is
+		// unresponsive.
+		syslog(LOG_WARNING, "DEEP-SLEEP-TICKLE: Resetting NCP . . .");
+
+		// Send a RESET.
+		CONTROL_REQUIRE_PREP_TO_SEND_COMMAND_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, timeout_error);
+		mOutboundBufferLen = spinel_datatype_pack(GetInstance(this)->mOutboundBuffer, sizeof(GetInstance(this)->mOutboundBuffer), "Ci", 0, SPINEL_CMD_RESET);
+		CONTROL_REQUIRE_OUTBOUND_BUFFER_FLUSHED_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, timeout_error);
+
+		mResetIsExpected = true;
+
+		// Wait for the response.
+		EH_REQUIRE_WITHIN(
+			NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT,
+			event == EVENT_NCP_RESET,
+			timeout_error
+		);
+
+		continue;
+
+timeout_error:
+		EH_EXIT();
+	}
+
+	set_ncp_power(true);
+
+	if (ncp_state_is_sleeping(get_ncp_state())) {
+		start_new_task(boost::shared_ptr<SpinelNCPTask>(
+			new SpinelNCPTaskWake(
+				this,
+				NilReturn()
+			)
+		));
+	}
+
+	EH_END();
+}
+
+int
+SpinelNCPInstance::vprocess_resume(int event, va_list args)
+{
+	Data command;
+	bool is_commissioned;
+	int ret;
+
+	EH_BEGIN_SUB(&mSubPT);
+
+	// Get the `SPINEL_PROP_NET_SAVED` property to check if the NCP is commissioned.
+
+	CONTROL_REQUIRE_PREP_TO_SEND_COMMAND_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+
+	command = SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_GET, SPINEL_PROP_NET_SAVED);
+	require(command.size() < sizeof(mOutboundBuffer), on_error);
+	memcpy(mOutboundBuffer, command.data(), command.size());
+	mOutboundBufferLen = static_cast<spinel_ssize_t>(command.size());
+	CONTROL_REQUIRE_OUTBOUND_BUFFER_FLUSHED_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+	CONTROL_REQUIRE_COMMAND_RESPONSE_WITHIN(NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT, on_error);
+
+	ret = peek_ncp_callback_status(event, args);
+	require_noerr(ret, on_error);
+
+	{
+		unsigned int key = va_arg(args, unsigned int);
+		const uint8_t* data_in = va_arg(args, const uint8_t*);
+		spinel_size_t data_len = va_arg_small(args, spinel_size_t);
+		spinel_ssize_t len = 0;
+
+		require(key == SPINEL_PROP_NET_SAVED, on_error);
+
+		len = spinel_datatype_unpack(data_in, data_len, SPINEL_DATATYPE_BOOL_S, &is_commissioned);
+		require(len > 0, on_error);
+	}
+
+	if (!is_commissioned) {
+		syslog(LOG_NOTICE, "NCP is NOT commissioned. Cannot resume.");
+		EH_EXIT();
+	}
+
+	syslog(LOG_NOTICE, "NCP is commissioned. Resuming...");
+
+	// Resume by setting `NET_IF_UP` and `NET_STACK_UP` to `true`
+
+	CONTROL_REQUIRE_PREP_TO_SEND_COMMAND_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+
+	command = SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S),
+		SPINEL_PROP_NET_IF_UP,
+		true
+	);
+
+	require(command.size() < sizeof(mOutboundBuffer), on_error);
+	memcpy(mOutboundBuffer, command.data(), command.size());
+	mOutboundBufferLen = static_cast<spinel_ssize_t>(command.size());
+	CONTROL_REQUIRE_OUTBOUND_BUFFER_FLUSHED_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+	CONTROL_REQUIRE_COMMAND_RESPONSE_WITHIN(NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT, on_error);
+	ret = peek_ncp_callback_status(event, args);
+	require_noerr(ret, on_error);
+
+	CONTROL_REQUIRE_PREP_TO_SEND_COMMAND_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+	command = SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S),
+		SPINEL_PROP_NET_STACK_UP,
+		true
+	);
+	require(command.size() < sizeof(mOutboundBuffer), on_error);
+	memcpy(mOutboundBuffer, command.data(), command.size());
+	mOutboundBufferLen = static_cast<spinel_ssize_t>(command.size());
+	CONTROL_REQUIRE_OUTBOUND_BUFFER_FLUSHED_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+	CONTROL_REQUIRE_COMMAND_RESPONSE_WITHIN(NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT, on_error);
+	ret = peek_ncp_callback_status(event, args);
+	require_noerr(ret, on_error);
+
+	EH_EXIT();
+
+on_error:
+
+	syslog(LOG_ERR, "NCP is misbehaving or unresponsive");
+	reinitialize_ncp();
+
+	EH_END();
+}
+
+int
+SpinelNCPInstance::vprocess_associated(int event, va_list args)
+{
+	// Conditions under which this protothread should be exited gracefully.
+	const bool should_exit = !mEnabled
+		|| !ncp_state_is_joining_or_joined(get_ncp_state());
+
+	EH_BEGIN_SUB(&mSubPT);
+
+	EH_WAIT_UNTIL_WITH_TIMEOUT(
+		NCP_TICKLE_TIMEOUT,
+		should_exit || !(IS_EVENT_FROM_NCP(event))
+	);
+
+	// This is not a typo. Despite the above "WAIT_UNTIL" looking
+	// very similar, it is not the same! DO NOT REMOVE!
+	EH_WAIT_UNTIL_WITH_TIMEOUT(
+		NCP_TICKLE_TIMEOUT,
+		should_exit
+	);
+
+	if (eh_did_timeout) {
+		syslog(LOG_INFO, "Tickle...");
+		CONTROL_REQUIRE_PREP_TO_SEND_COMMAND_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+		mOutboundBufferLen = spinel_datatype_pack(GetInstance(this)->mOutboundBuffer, sizeof(GetInstance(this)->mOutboundBuffer), "Ci", 0, SPINEL_CMD_NOOP);
+		CONTROL_REQUIRE_OUTBOUND_BUFFER_FLUSHED_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+
+		CONTROL_REQUIRE_COMMAND_RESPONSE_WITHIN(NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT, on_error);
+		mFailureCount = 0;
+	}
+
+	EH_EXIT();
+
+on_error:
+
+	syslog(LOG_ERR, "NCP is misbehaving or unresponsive");
+	reinitialize_ncp();
+
+	EH_END();
+}
+
+int
+SpinelNCPInstance::vprocess_offline(int event, va_list args)
+{
+	// Conditions under which this protothread should be exited gracefully.
+	const bool should_exit = ncp_state_is_interface_up(get_ncp_state())
+		|| !mEnabled
+		|| (mOutboundBufferLen>0);
+
+	float sleep_timeout = mAutoDeepSleepTimeout;
+
+	if (!mNetworkKey.empty() || (mNetworkKeyIndex != 0)) {
+		sleep_timeout += 60;
+	}
+
+	EH_BEGIN_SUB(&mSubPT);
+
+	// Wait for auto deep sleep to be turned on, or if there is an exit condition.
+	EH_WAIT_UNTIL(should_exit || mAutoDeepSleep);
+
+	// Wait for auto deep sleep to be turned off or for us to be not asleep, or if there is an exit condition
+	EH_WAIT_UNTIL(
+	   should_exit
+	   || !mAutoDeepSleep
+	   || !ncp_state_is_sleeping(get_ncp_state())
+	);
+
+	// Wait within a timeout for us to enter sleep state, or for auto deep sleep to be turned off, or
+	// if we have a command to send to NCP or receive a callback/event from NCP, or if there is an exit condition
+	EH_WAIT_UNTIL_WITH_TIMEOUT(
+		sleep_timeout,
+		should_exit
+		|| !mAutoDeepSleep
+		|| !mTaskQueue.empty()
+		|| (IS_EVENT_FROM_NCP(event))
+		|| ncp_state_is_sleeping(get_ncp_state())
+	);
+
+	if (eh_did_timeout) {
+		start_new_task(boost::shared_ptr<SpinelNCPTask>(new SpinelNCPTaskDeepSleep(this, NilReturn())));
+	}
+
+	EH_END();
+}
+
+int
+SpinelNCPInstance::vprocess_init(int event, va_list args)
+{
+	int status = 0;
+
+	if (event == EVENT_NCP_RESET) {
+		if (mDriverState == INITIALIZING) {
+			syslog(LOG_ERR, "Unexpected reset durring NCP initialization.");
+			mFailureCount++;
+			PT_INIT(&mSubPT);
+		} else if (mDriverState == INITIALIZING_WAITING_FOR_RESET) {
+			mDriverState = INITIALIZING;
+		}
+	}
+
+	EH_BEGIN_SUB(&mSubPT);
+
+	if (get_ncp_state() == UPGRADING) {
+		EH_WAIT_UNTIL(get_upgrade_status() != EINPROGRESS);
+
+		status = get_upgrade_status();
+
+		if (status == 0) {
+			syslog(LOG_INFO, "Firmware Update Complete.");
+		} else {
+			syslog(LOG_ERR, "Firmware Update Failed with Error %d", status);
+			mFailureCount++;
+
+			if (mFailureCount > mFailureThreshold) {
+				change_ncp_state(FAULT);
+			}
+		}
+	}
+
+	if (get_ncp_state() == FAULT) {
+		EH_EXIT();
+	}
+
+	syslog(LOG_INFO, "Initializing NCP");
+
+	set_initializing_ncp(true);
+
+	change_ncp_state(UNINITIALIZED);
+
+	set_ncp_power(true);
+
+	clear_nonpermanent_global_addresses();
+
+	mNCPVersionString = "";
+
+	mDriverState = INITIALIZING_WAITING_FOR_RESET;
+
+	if (mResetIsExpected) {
+		EH_WAIT_UNTIL_WITH_TIMEOUT(NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT, mResetIsExpected == false);
+
+		if (eh_did_timeout) {
+			// mResetIsExpected has been set for too long and we
+			// haven't gotten a reset yet. This can prevent us from sleeping.
+			// by incrementing the failure count here we will cause
+			// another reset to occur in the code below.
+			mFailureCount++;
+			mResetIsExpected = false;
+			syslog(LOG_ERR, "Was waiting for a reset, but we never got one.");
+		}
+	} else {
+		// Backoff delay. Normaly zero. May increase if we are in a reset loop.
+		EH_SLEEP_FOR(mRunawayResetBackoffManager.delay_for_unexpected_reset());
+	}
+
+	do {
+		EH_SLEEP_FOR(0.1);
+
+		if (mFailureCount > mFailureThreshold) {
+			syslog(LOG_ALERT, "The NCP is misbehaving: Repeatedly unable to initialize NCP. Entering fault state.");
+			change_ncp_state(FAULT);
+			EH_EXIT();
+		}
+
+		if ( mAutoUpdateFirmware
+		  && (mFailureCount > (mFailureThreshold - 1))
+		  && can_upgrade_firmware()
+		) {
+			syslog(LOG_ALERT, "The NCP is misbehaving: Attempting a firmware update");
+			upgrade_firmware();
+			EH_RESTART();
+		}
+
+		if ((event != EVENT_NCP_RESET) && (mFailureCount > 0)) {
+			syslog(LOG_ERR, "Resetting and trying again... (retry %d)", mFailureCount);
+
+			change_ncp_state(UNINITIALIZED);
+
+			mNetworkKey = Data();
+			mNetworkKeyIndex = 0;
+
+			reset_tasks(kWPANTUNDStatus_Canceled);
+
+			// Do a hard reset only on even attempts.
+			if ((mFailureCount & 1) == 0) {
+				hard_reset_ncp();
+			} else {
+				CONTROL_REQUIRE_PREP_TO_SEND_COMMAND_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+				mOutboundBufferLen = spinel_datatype_pack(GetInstance(this)->mOutboundBuffer, sizeof(GetInstance(this)->mOutboundBuffer), "Ci", 0, SPINEL_CMD_RESET);
+				CONTROL_REQUIRE_OUTBOUND_BUFFER_FLUSHED_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+			}
+
+			mDriverState = INITIALIZING_WAITING_FOR_RESET;
+
+			EH_REQUIRE_WITHIN(
+				NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT,
+				event == EVENT_NCP_RESET,
+				on_error
+			);
+
+			mDriverState = INITIALIZING;
+		}
+
+		// Get the protocol version
+		CONTROL_REQUIRE_PREP_TO_SEND_COMMAND_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+		GetInstance(this)->mOutboundBufferLen = spinel_cmd_prop_value_get(GetInstance(this)->mOutboundBuffer, sizeof(GetInstance(this)->mOutboundBuffer), SPINEL_PROP_PROTOCOL_VERSION);
+		CONTROL_REQUIRE_OUTBOUND_BUFFER_FLUSHED_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+
+		CONTROL_REQUIRE_COMMAND_RESPONSE_WITHIN(NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT, on_error);
+
+		status = peek_ncp_callback_status(event, args);
+		require_noerr(status, on_error);
+
+		if (get_ncp_state() == UNINITIALIZED) {
+			// Get the thread state
+			CONTROL_REQUIRE_PREP_TO_SEND_COMMAND_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+			GetInstance(this)->mOutboundBufferLen = spinel_cmd_prop_value_get(GetInstance(this)->mOutboundBuffer, sizeof(GetInstance(this)->mOutboundBuffer), SPINEL_PROP_NET_STACK_UP);
+			CONTROL_REQUIRE_OUTBOUND_BUFFER_FLUSHED_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+
+			CONTROL_REQUIRE_COMMAND_RESPONSE_WITHIN(NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT, on_error);
+
+			require(get_ncp_state() != UNINITIALIZED, on_error);
+		}
+
+		// If we are "joining" at this point, then we must start over.
+		// This will cause a reset to occur.
+		require(!ncp_state_is_joining(get_ncp_state()), on_error);
+
+		// This next line causes any resets received after this
+		// point to cause the control protothread to be restarted.
+		mDriverState = INITIALIZING;
+
+		if (mIsPcapInProgress) {
+			CONTROL_REQUIRE_PREP_TO_SEND_COMMAND_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+			GetInstance(this)->mOutboundBufferLen = spinel_cmd_prop_value_set_uint(GetInstance(this)->mOutboundBuffer, sizeof(GetInstance(this)->mOutboundBuffer), SPINEL_PROP_MAC_RAW_STREAM_ENABLED, 1);
+			CONTROL_REQUIRE_OUTBOUND_BUFFER_FLUSHED_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+
+			CONTROL_REQUIRE_COMMAND_RESPONSE_WITHIN(NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT, on_error);
+		}
+
+		if (mEnabled) {
+			// Refresh our internal copies of the following radio parameters:
+			static const spinel_prop_key_t keys_to_fetch[] = {
+				SPINEL_PROP_NCP_VERSION,
+				SPINEL_PROP_INTERFACE_TYPE,
+				SPINEL_PROP_VENDOR_ID,
+				SPINEL_PROP_CAPS,
+				SPINEL_PROP_HWADDR,
+				SPINEL_PROP_PHY_CHAN,
+				SPINEL_PROP_PHY_CHAN_SUPPORTED,
+				SPINEL_PROP_MAC_15_4_PANID,
+				SPINEL_PROP_MAC_15_4_LADDR,
+				SPINEL_PROP_NET_MASTER_KEY,
+				SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER,
+				SPINEL_PROP_NET_NETWORK_NAME,
+				SPINEL_PROP_NET_XPANID,
+				SPINEL_PROP_IPV6_LL_ADDR,
+				SPINEL_PROP_IPV6_ML_ADDR,
+				SPINEL_PROP_THREAD_ASSISTING_PORTS,
+				SPINEL_PROP_NET_IF_UP,
+				SPINEL_PROP_NET_STACK_UP,
+				SPINEL_PROP_NET_ROLE,
+			};
+
+			for (mSubPTIndex = 0; mSubPTIndex < sizeof(keys_to_fetch)/sizeof(keys_to_fetch[0]); mSubPTIndex++) {
+				CONTROL_REQUIRE_PREP_TO_SEND_COMMAND_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+				GetInstance(this)->mOutboundBufferLen = spinel_cmd_prop_value_get(GetInstance(this)->mOutboundBuffer, sizeof(GetInstance(this)->mOutboundBuffer), keys_to_fetch[mSubPTIndex]);
+				CONTROL_REQUIRE_OUTBOUND_BUFFER_FLUSHED_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+				CONTROL_REQUIRE_COMMAND_RESPONSE_WITHIN(NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT, on_error);
+
+				status = peek_ncp_callback_status(event, args);
+
+				if (status != 0) {
+					syslog(LOG_WARNING, "Unsuccessful fetching property \"%s\" from NCP: \"%s\" (%d)", spinel_prop_key_to_cstr(keys_to_fetch[mSubPTIndex]), spinel_status_to_cstr(static_cast<spinel_status_t>(status)), status);
+				}
+			}
+
+			// Restore all the saved settings
+			for (mSettingsIter = mSettings.begin(); mSettingsIter != mSettings.end(); mSettingsIter++) {
+
+				syslog(LOG_INFO, "Restoring property \"%s\" on NCP", mSettingsIter->first.c_str());
+
+				// Skip the settings if capability is not present.
+				if ((mSettingsIter->second.mCapability != 0) &&!mCapabilities.count(mSettingsIter->second.mCapability)) {
+					continue;
+				}
+
+				CONTROL_REQUIRE_PREP_TO_SEND_COMMAND_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+
+				if (mSettingsIter->second.mSpinelCommand.size() > sizeof(GetInstance(this)->mOutboundBuffer))
+				{
+					syslog(LOG_WARNING,
+						"Spinel command for restoring property \"%s\" does not fit in outbound buffer (require %d bytes but only %u bytes available)",
+						mSettingsIter->first.c_str(),
+						mSettingsIter->second.mSpinelCommand.size(),
+						sizeof(GetInstance(this)->mOutboundBuffer)
+					);
+
+					continue;
+				}
+
+				GetInstance(this)->mOutboundBufferLen = mSettingsIter->second.mSpinelCommand.size();
+				memcpy(GetInstance(this)->mOutboundBuffer, mSettingsIter->second.mSpinelCommand.data(), mSettingsIter->second.mSpinelCommand.size());
+
+				CONTROL_REQUIRE_OUTBOUND_BUFFER_FLUSHED_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+				CONTROL_REQUIRE_COMMAND_RESPONSE_WITHIN(NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT, on_error);
+
+				status = peek_ncp_callback_status(event, args);
+
+				if (status != 0) {
+					syslog(LOG_WARNING, "Unsuccessful in restoring property \"%s\" on NCP: \"%s\" (%d)", mSettingsIter->first.c_str(), spinel_status_to_cstr(static_cast<spinel_status_t>(status)), status);
+				}
+			}
+		}
+
+		break;
+
+on_error:
+		if (status) {
+			syslog(LOG_ERR, "Initialization error: %d", status);
+		}
+		EH_SLEEP_FOR(0.5);
+		mFailureCount++;
+	} while (true);
+
+	mIsPcapInProgress = false;
+	mFailureCount = 0;
+	mResetIsExpected = false;
+	set_initializing_ncp(false);
+	mDriverState = NORMAL_OPERATION;
+
+	syslog(LOG_NOTICE, "Finished initializing NCP");
+
+	EH_END();
+}
+
+int
+SpinelNCPInstance::vprocess_event(int event, va_list args)
+{
+	if (get_ncp_state() == FAULT) {
+		// We perform no processing in the fault state.
+		PT_INIT(&mControlPT);
+		return 0;
+	}
+
+	while (!mTaskQueue.empty()) {
+		va_list tmp;
+		boost::shared_ptr<SpinelNCPTask> current_task(mTaskQueue.front());
+		va_copy(tmp, args);
+		char ret = current_task->vprocess_event(event, tmp);
+		va_end(tmp);
+
+		if (ret == PT_ENDED || ret == PT_EXITED) {
+			mTaskQueue.pop_front();
+			continue;
+		}
+
+		break;
+	}
+
+	EH_BEGIN();
+
+	EH_SPAWN(&mSubPT, vprocess_init(event, args));
+
+	if (get_ncp_state() == FAULT) {
+		EH_EXIT();
+	}
+
+	EH_WAIT_UNTIL(mTaskQueue.empty());
+
+	// If we are offline and autoResume is enabled
+	if (mAutoResume && mEnabled && (get_ncp_state() == OFFLINE)) {
+		syslog(LOG_NOTICE, "AutoResume is enabled. Trying to resume.");
+		EH_SPAWN(&mSubPT, vprocess_resume(event, args));
+	}
+
+	while (1) {
+		// Yield for one loop cycle only. This prevents
+		// us from entering any endless loops.
+		EH_SLEEP_FOR(0);
+
+		if (ncp_state_is_initializing(get_ncp_state())) {
+			EH_RESTART();
+
+		} else if (!mEnabled) {
+			syslog(LOG_NOTICE, "Interface Disabled.");
+			EH_SPAWN(&mSubPT, vprocess_disabled(event, args));
+
+		} else if (ncp_state_is_joining_or_joined(get_ncp_state())) {
+			EH_SPAWN(&mSubPT, vprocess_associated(event, args));
+
+		} else if (!ncp_state_is_interface_up(get_ncp_state())) {
+			EH_SPAWN(&mSubPT, vprocess_offline(event, args));
+
+		} else {
+			syslog(
+				LOG_WARNING,
+				"Unexpected NCP state %d (%s)",
+				get_ncp_state(),
+				ncp_state_to_string(get_ncp_state()).c_str()
+			);
+
+			// Yield for one main loop cycle without
+			// specifying a timeout to avoid high CPU usage
+			// cases like this.
+			EH_YIELD();
+		}
+
+	} // while(1)
+
+	EH_END();
+}
diff --git a/src/ncp-spinel/SpinelNCPInstance.cpp b/src/ncp-spinel/SpinelNCPInstance.cpp
new file mode 100644
index 0000000..42eac92
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPInstance.cpp
@@ -0,0 +1,1784 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "SpinelNCPInstance.h"
+#include "time-utils.h"
+#include "assert-macros.h"
+#include <syslog.h>
+#include <errno.h>
+#include "socket-utils.h"
+#include <stdexcept>
+#include <sys/file.h>
+#include "SuperSocket.h"
+#include "SpinelNCPTask.h"
+#include "SpinelNCPTaskWake.h"
+#include "SpinelNCPTaskSendCommand.h"
+#include "SpinelNCPTaskJoin.h"
+#include "SpinelNCPTaskGetNetworkTopology.h"
+#include "SpinelNCPTaskGetMsgBufferCounters.h"
+#include "any-to.h"
+#include "spinel-extra.h"
+
+#define kWPANTUNDProperty_Spinel_CounterPrefix		"NCP:Counter:"
+
+using namespace nl;
+using namespace wpantund;
+
+WPANTUND_DEFINE_NCPINSTANCE_PLUGIN(spinel, SpinelNCPInstance);
+
+void
+SpinelNCPInstance::handle_ncp_log(const uint8_t* data_ptr, int data_len)
+{
+	static char linebuffer[NCP_DEBUG_LINE_LENGTH_MAX + 1];
+	static int linepos = 0;
+	while (data_len--) {
+		char nextchar = *data_ptr++;
+
+		if ((nextchar == '\t') || (nextchar >= 32)) {
+			linebuffer[linepos++] = nextchar;
+		}
+
+		if ( (linepos != 0)
+		  && ( (nextchar == '\n')
+			|| (nextchar == '\r')
+			|| (linepos >= (sizeof(linebuffer) - 1))
+		  )
+		)
+		{
+			// flush.
+			linebuffer[linepos] = 0;
+			syslog(LOG_WARNING, "NCP => %s\n", linebuffer);
+			linepos = 0;
+		}
+	}
+}
+
+void
+SpinelNCPInstance::start_new_task(const boost::shared_ptr<SpinelNCPTask> &task)
+{
+	if (ncp_state_is_detached_from_ncp(get_ncp_state())) {
+		task->finish(kWPANTUNDStatus_InvalidWhenDisabled);
+	} else if (PT_SCHEDULE(task->process_event(EVENT_STARTING_TASK))) {
+
+		if (ncp_state_is_sleeping(get_ncp_state())
+			&& (dynamic_cast<const SpinelNCPTaskWake*>(task.get()) == NULL)
+		) {
+			start_new_task(boost::shared_ptr<SpinelNCPTask>(new SpinelNCPTaskWake(this, NilReturn())));
+		}
+		mTaskQueue.push_back(task);
+	}
+}
+
+int
+nl::wpantund::spinel_status_to_wpantund_status(int spinel_status)
+{
+	wpantund_status_t ret;
+	switch (spinel_status) {
+	case SPINEL_STATUS_ALREADY:
+		ret = kWPANTUNDStatus_Already;
+		break;
+	case SPINEL_STATUS_BUSY:
+		ret = kWPANTUNDStatus_Busy;
+		break;
+	case SPINEL_STATUS_IN_PROGRESS:
+		ret = kWPANTUNDStatus_InProgress;
+		break;
+	case SPINEL_STATUS_JOIN_FAILURE:
+		ret = kWPANTUNDStatus_JoinFailedUnknown;
+		break;
+	case SPINEL_STATUS_JOIN_INCOMPATIBLE:
+		ret = kWPANTUNDStatus_JoinFailedAtScan;
+		break;
+	case SPINEL_STATUS_JOIN_SECURITY:
+		ret = kWPANTUNDStatus_JoinFailedAtAuthenticate;
+		break;
+	case SPINEL_STATUS_OK:
+		ret = kWPANTUNDStatus_Ok;
+		break;
+	case SPINEL_STATUS_PROP_NOT_FOUND:
+		ret = kWPANTUNDStatus_PropertyNotFound;
+		break;
+	case SPINEL_STATUS_INVALID_ARGUMENT:
+		ret = kWPANTUNDStatus_NCP_InvalidArgument;
+		break;
+	case SPINEL_STATUS_INVALID_STATE:
+		ret = kWPANTUNDStatus_InvalidForCurrentState;
+		break;
+
+	default:
+		ret = WPANTUND_NCPERROR_TO_STATUS(spinel_status);
+		break;
+	}
+
+	return ret;
+}
+
+int
+nl::wpantund::peek_ncp_callback_status(int event, va_list args)
+{
+	int ret = 0;
+
+	if (EVENT_NCP_PROP_VALUE_IS == event) {
+		va_list tmp;
+		va_copy(tmp, args);
+		unsigned int key = va_arg(tmp, unsigned int);
+		if (SPINEL_PROP_LAST_STATUS == key) {
+			const uint8_t* spinel_data_ptr = va_arg(tmp, const uint8_t*);
+			spinel_size_t spinel_data_len = va_arg(tmp, spinel_size_t);
+
+			if (spinel_datatype_unpack(spinel_data_ptr, spinel_data_len, "i", &ret) <= 0) {
+				ret = SPINEL_STATUS_PARSE_ERROR;
+			}
+		}
+		va_end(tmp);
+	} else if (EVENT_NCP_RESET == event) {
+		va_list tmp;
+		va_copy(tmp, args);
+		ret = va_arg(tmp, int);
+		va_end(tmp);
+	}
+
+	return ret;
+}
+
+SpinelNCPInstance::SpinelNCPInstance(const Settings& settings) :
+	NCPInstanceBase(settings), mControlInterface(this)
+{
+	mOutboundBufferLen = 0;
+	mInboundHeader = 0;
+	mSupprotedChannels.clear();
+
+	mIsPcapInProgress = false;
+	mNoMemStatusCounter = 0;
+	mLastTimeNoMemStatus = 0;
+	mSettings.clear();
+
+	if (!settings.empty()) {
+		int status;
+		Settings::const_iterator iter;
+
+		for(iter = settings.begin(); iter != settings.end(); iter++) {
+			if (!NCPInstanceBase::setup_property_supported_by_class(iter->first)) {
+				status = static_cast<NCPControlInterface&>(get_control_interface())
+					.set_property(iter->first, iter->second);
+
+				if (status != 0) {
+					syslog(LOG_WARNING, "Attempt to set property \"%s\" failed with err %d", iter->first.c_str(), status);
+				}
+			}
+		}
+	}
+}
+
+SpinelNCPInstance::~SpinelNCPInstance()
+{
+}
+
+
+bool
+SpinelNCPInstance::setup_property_supported_by_class(const std::string& prop_name)
+{
+	return NCPInstanceBase::setup_property_supported_by_class(prop_name);
+}
+
+SpinelNCPControlInterface&
+SpinelNCPInstance::get_control_interface()
+{
+	return mControlInterface;
+}
+
+uint32_t
+SpinelNCPInstance::get_default_channel_mask(void)
+{
+	uint32_t channel_mask = 0;
+	uint16_t i;
+
+	for (i = 0; i < 32; i++) {
+		if (mSupprotedChannels.find(i) != mSupprotedChannels.end()) {
+			channel_mask |= (1 << i);
+		}
+	}
+
+	return channel_mask;
+}
+
+std::set<std::string>
+SpinelNCPInstance::get_supported_property_keys()const
+{
+	std::set<std::string> properties (NCPInstanceBase::get_supported_property_keys());
+
+	properties.insert(kWPANTUNDProperty_ConfigNCPDriverName);
+	properties.insert(kWPANTUNDProperty_NCPChannel);
+	properties.insert(kWPANTUNDProperty_NCPChannelMask);
+	properties.insert(kWPANTUNDProperty_NCPFrequency);
+	properties.insert(kWPANTUNDProperty_NCPRSSI);
+	properties.insert(kWPANTUNDProperty_NCPExtendedAddress);
+
+	if (mCapabilities.count(SPINEL_CAP_NET_THREAD_1_0)) {
+		properties.insert(kWPANTUNDProperty_ThreadRLOC16);
+		properties.insert(kWPANTUNDProperty_ThreadRouterID);
+		properties.insert(kWPANTUNDProperty_ThreadLeaderAddress);
+		properties.insert(kWPANTUNDProperty_ThreadLeaderRouterID);
+		properties.insert(kWPANTUNDProperty_ThreadLeaderWeight);
+		properties.insert(kWPANTUNDProperty_ThreadLeaderLocalWeight);
+		properties.insert(kWPANTUNDProperty_ThreadNetworkData);
+		properties.insert(kWPANTUNDProperty_ThreadNetworkDataVersion);
+		properties.insert(kWPANTUNDProperty_ThreadStableNetworkData);
+		properties.insert(kWPANTUNDProperty_ThreadStableNetworkDataVersion);
+		properties.insert(kWPANTUNDProperty_ThreadLeaderNetworkData);
+		properties.insert(kWPANTUNDProperty_ThreadStableLeaderNetworkData);
+		properties.insert(kWPANTUNDProperty_ThreadChildTable);
+		properties.insert(kWPANTUNDProperty_ThreadNeighborTable);
+	}
+
+	if (mCapabilities.count(SPINEL_CAP_COUNTERS)) {
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_PKT_TOTAL");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_PKT_UNICAST");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_PKT_BROADCAST");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_PKT_ACK_REQ");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_PKT_ACKED");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_PKT_NO_ACK_REQ");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_PKT_DATA");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_PKT_DATA_POLL");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_PKT_BEACON");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_PKT_BEACON_REQ");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_PKT_OTHER");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_PKT_RETRY");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_ERR_CCA");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_ERR_ABORT");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_PKT_TOTAL");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_PKT_UNICAST");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_PKT_BROADCAST");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_PKT_DATA");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_PKT_DATA_POLL");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_PKT_BEACON");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_PKT_BEACON_REQ");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_PKT_OTHER");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_PKT_FILT_WL");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_PKT_FILT_DA");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_ERR_EMPTY");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_ERR_UKWN_NBR");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_ERR_NVLD_SADDR");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_ERR_SECURITY");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_ERR_BAD_FCS");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_ERR_OTHER");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_IP_SEC_TOTAL");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_IP_INSEC_TOTAL");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_IP_DROPPED");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_IP_SEC_TOTAL");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_IP_INSEC_TOTAL");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_IP_DROPPED");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "TX_SPINEL_TOTAL");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_SPINEL_TOTAL");
+		properties.insert(kWPANTUNDProperty_Spinel_CounterPrefix "RX_SPINEL_ERR");
+	}
+
+	if (mCapabilities.count(SPINEL_CAP_JAM_DETECT)) {
+		properties.insert(kWPANTUNDProperty_JamDetectionStatus);
+		properties.insert(kWPANTUNDProperty_JamDetectionEnable);
+		properties.insert(kWPANTUNDProperty_JamDetectionRssiThreshold);
+		properties.insert(kWPANTUNDProperty_JamDetectionWindow);
+		properties.insert(kWPANTUNDProperty_JamDetectionBusyPeriod);
+		properties.insert(kWPANTUNDProperty_JamDetectionDebugHistoryBitmap);
+	}
+
+	if (mCapabilities.count(SPINEL_CAP_NEST_LEGACY_INTERFACE))
+	{
+		properties.insert(kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix);
+	}
+
+	return properties;
+}
+
+cms_t
+SpinelNCPInstance::get_ms_to_next_event(void)
+{
+	cms_t cms = NCPInstanceBase::get_ms_to_next_event();
+
+	if (ncp_state_is_detached_from_ncp(get_ncp_state())) {
+		return CMS_DISTANT_FUTURE;
+	}
+
+	// If the control protothread hasn't even started, set cms to zero.
+	if (0 == mControlPT.lc) {
+		cms = 0;
+	}
+
+	if (!mTaskQueue.empty()) {
+		int tmp_cms = mTaskQueue.front()->get_ms_to_next_event();
+		if (tmp_cms < cms) {
+			cms = tmp_cms;
+		}
+	}
+
+	if (cms < 0) {
+		cms = 0;
+	}
+
+	return cms;
+}
+
+static void convert_rloc16_to_router_id(CallbackWithStatusArg1 cb, int status, const boost::any& value)
+{
+	uint8_t router_id = 0;
+
+	if (status == kWPANTUNDStatus_Ok) {
+		uint16_t rloc16 = any_to_int(value);
+		router_id = rloc16 >> 10;
+	}
+	cb(status, router_id);
+}
+
+static int unpack_jam_detect_history_bitmap(const uint8_t *data_in, spinel_size_t data_len, boost::any& value)
+{
+	spinel_ssize_t len;
+	uint32_t lower, higher;
+	uint64_t val;
+	int ret = kWPANTUNDStatus_Failure;
+
+	len = spinel_datatype_unpack(
+		data_in,
+		data_len,
+		SPINEL_DATATYPE_UINT32_S SPINEL_DATATYPE_UINT32_S,
+		&lower,
+		&higher
+	);
+
+	if (len > 0)
+	{
+		ret = kWPANTUNDStatus_Ok;
+		value = (static_cast<uint64_t>(higher) << 32) + static_cast<uint64_t>(lower);
+	}
+
+	return ret;
+}
+
+void
+SpinelNCPInstance::get_property(
+	const std::string& key,
+	CallbackWithStatusArg1 cb
+) {
+
+#define SIMPLE_SPINEL_GET(prop__, type__)                                \
+	start_new_task(SpinelNCPTaskSendCommand::Factory(this)               \
+		.set_callback(cb)                                                \
+		.add_command(                                                    \
+			SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_GET, prop__) \
+		)                                                                \
+		.set_reply_format(type__)                                        \
+		.finish()                                                        \
+	)
+
+	if (strcaseequal(key.c_str(), kWPANTUNDProperty_ConfigNCPDriverName)) {
+		cb(0, boost::any(std::string("spinel")));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NCPChannelMask)) {
+		cb(0, boost::any(get_default_channel_mask()));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NCPCCAThreshold)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_PHY_CCA_THRESHOLD, SPINEL_DATATYPE_INT8_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NCPFrequency)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_PHY_FREQ, SPINEL_DATATYPE_INT32_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NetworkKey)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_NET_MASTER_KEY, SPINEL_DATATYPE_DATA_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NCPExtendedAddress)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_MAC_EXTENDED_ADDR, SPINEL_DATATYPE_EUI64_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NetworkKeyIndex)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER, SPINEL_DATATYPE_UINT32_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NetworkIsCommissioned)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_NET_SAVED, SPINEL_DATATYPE_BOOL_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NCPRSSI)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_PHY_RSSI, SPINEL_DATATYPE_INT8_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadRLOC16)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_THREAD_RLOC16, SPINEL_DATATYPE_UINT16_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadRouterID)) {
+		cb = boost::bind(convert_rloc16_to_router_id, cb, _1, _2);
+		SIMPLE_SPINEL_GET(SPINEL_PROP_THREAD_RLOC16, SPINEL_DATATYPE_UINT16_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadLeaderAddress)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_THREAD_LEADER_ADDR, SPINEL_DATATYPE_IPv6ADDR_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadLeaderRouterID)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_THREAD_LEADER_RID, SPINEL_DATATYPE_UINT8_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadLeaderWeight)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_THREAD_LEADER_WEIGHT, SPINEL_DATATYPE_UINT8_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadLeaderLocalWeight)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_THREAD_LOCAL_LEADER_WEIGHT, SPINEL_DATATYPE_UINT8_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadNetworkData)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_THREAD_NETWORK_DATA, SPINEL_DATATYPE_DATA_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadNetworkDataVersion)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_THREAD_NETWORK_DATA_VERSION, SPINEL_DATATYPE_UINT8_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadStableNetworkData)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_THREAD_STABLE_NETWORK_DATA, SPINEL_DATATYPE_DATA_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadLeaderNetworkData)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_THREAD_LEADER_NETWORK_DATA, SPINEL_DATATYPE_DATA_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadStableLeaderNetworkData)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_THREAD_STABLE_LEADER_NETWORK_DATA, SPINEL_DATATYPE_DATA_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadStableNetworkDataVersion)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_THREAD_STABLE_NETWORK_DATA_VERSION, SPINEL_DATATYPE_UINT8_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_IPv6MeshLocalPrefix) && !buffer_is_nonzero(mNCPV6Prefix, sizeof(mNCPV6Prefix))) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_IPV6_ML_PREFIX, SPINEL_DATATYPE_IPv6ADDR_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_IPv6MeshLocalAddress) && !buffer_is_nonzero(mNCPV6Prefix, sizeof(mNCPV6Prefix))) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_IPV6_ML_ADDR, SPINEL_DATATYPE_IPv6ADDR_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_IPv6LinkLocalAddress) && !IN6_IS_ADDR_LINKLOCAL(&mNCPLinkLocalAddress)) {
+		SIMPLE_SPINEL_GET(SPINEL_PROP_IPV6_LL_ADDR, SPINEL_DATATYPE_IPv6ADDR_S);
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_JamDetectionStatus)) {
+		if (!mCapabilities.count(SPINEL_CAP_JAM_DETECT)) {
+			cb(kWPANTUNDStatus_FeatureNotSupported, boost::any(std::string("Jam Detection Feature Not Supported")));
+		} else {
+			SIMPLE_SPINEL_GET(SPINEL_PROP_JAM_DETECTED, SPINEL_DATATYPE_BOOL_S);
+		}
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_JamDetectionEnable)) {
+		if (!mCapabilities.count(SPINEL_CAP_JAM_DETECT)) {
+			cb(kWPANTUNDStatus_FeatureNotSupported, boost::any(std::string("Jam Detection Feature Not Supported")));
+		} else {
+			SIMPLE_SPINEL_GET(SPINEL_PROP_JAM_DETECT_ENABLE, SPINEL_DATATYPE_BOOL_S);
+		}
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_JamDetectionRssiThreshold)) {
+		if (!mCapabilities.count(SPINEL_CAP_JAM_DETECT)) {
+			cb(kWPANTUNDStatus_FeatureNotSupported, boost::any(std::string("Jam Detection Feature Not Supported")));
+		} else {
+			SIMPLE_SPINEL_GET(SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD, SPINEL_DATATYPE_INT8_S);
+		}
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_JamDetectionWindow)) {
+		if (!mCapabilities.count(SPINEL_CAP_JAM_DETECT)) {
+			cb(kWPANTUNDStatus_FeatureNotSupported, boost::any(std::string("Jam Detection Feature Not Supported")));
+		} else {
+			SIMPLE_SPINEL_GET(SPINEL_PROP_JAM_DETECT_WINDOW, SPINEL_DATATYPE_UINT8_S);
+		}
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_JamDetectionBusyPeriod)) {
+		if (!mCapabilities.count(SPINEL_CAP_JAM_DETECT)) {
+			cb(kWPANTUNDStatus_FeatureNotSupported, boost::any(std::string("Jam Detection Feature Not Supported")));
+		} else {
+			SIMPLE_SPINEL_GET(SPINEL_PROP_JAM_DETECT_BUSY, SPINEL_DATATYPE_UINT8_S);
+		}
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_JamDetectionDebugHistoryBitmap)) {
+		if (!mCapabilities.count(SPINEL_CAP_JAM_DETECT)) {
+			cb(kWPANTUNDStatus_FeatureNotSupported, boost::any(std::string("Jam Detection Feature Not Supported")));
+		} else {
+			start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+				.set_callback(cb)
+				.add_command(
+					SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_GET, SPINEL_PROP_JAM_DETECT_HISTORY_BITMAP)
+				)
+				.set_reply_unpacker(unpack_jam_detect_history_bitmap)
+				.finish()
+			);
+		}
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix)) {
+		if (!mCapabilities.count(SPINEL_CAP_NEST_LEGACY_INTERFACE)) {
+			cb(kWPANTUNDStatus_FeatureNotSupported, boost::any(std::string("Legacy Capability Not Supported by NCP")));
+		} else {
+			SIMPLE_SPINEL_GET(SPINEL_PROP_NEST_LEGACY_ULA_PREFIX, SPINEL_DATATYPE_DATA_S);
+		}
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadChildTable)) {
+		start_new_task(boost::shared_ptr<SpinelNCPTask>(
+			new SpinelNCPTaskGetNetworkTopology(
+				this,
+				cb,
+				SpinelNCPTaskGetNetworkTopology::kChildTable,
+				SpinelNCPTaskGetNetworkTopology::kResultFormat_StringArray
+			)
+		));
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadChildTableAsValMap)) {
+		start_new_task(boost::shared_ptr<SpinelNCPTask>(
+			new SpinelNCPTaskGetNetworkTopology(
+				this,
+				cb,
+				SpinelNCPTaskGetNetworkTopology::kChildTable,
+				SpinelNCPTaskGetNetworkTopology::kResultFormat_ValueMapArray
+			)
+		));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadNeighborTable)) {
+		start_new_task(boost::shared_ptr<SpinelNCPTask>(
+			new SpinelNCPTaskGetNetworkTopology(
+				this,
+				cb,
+				SpinelNCPTaskGetNetworkTopology::kNeighborTable,
+				SpinelNCPTaskGetNetworkTopology::kResultFormat_StringArray
+			)
+		));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadNeighborTableAsValMap)) {
+		start_new_task(boost::shared_ptr<SpinelNCPTask>(
+			new SpinelNCPTaskGetNetworkTopology(
+				this,
+				cb,
+				SpinelNCPTaskGetNetworkTopology::kNeighborTable,
+				SpinelNCPTaskGetNetworkTopology::kResultFormat_ValueMapArray
+			)
+		));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_OpenThreadMsgBufferCounters)) {
+		start_new_task(boost::shared_ptr<SpinelNCPTask>(
+			new SpinelNCPTaskGetMsgBufferCounters(
+				this,
+				cb,
+				SpinelNCPTaskGetMsgBufferCounters::kResultFormat_StringArray
+			)
+		));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_OpenThreadMsgBufferCountersAsString)) {
+		start_new_task(boost::shared_ptr<SpinelNCPTask>(
+			new SpinelNCPTaskGetMsgBufferCounters(
+				this,
+				cb,
+				SpinelNCPTaskGetMsgBufferCounters::kResultFormat_String
+			)
+		));
+
+	} else if (strncaseequal(key.c_str(), kWPANTUNDProperty_Spinel_CounterPrefix, sizeof(kWPANTUNDProperty_Spinel_CounterPrefix)-1)) {
+		int cntr_key = 0;
+
+#define CNTR_KEY(x)	\
+	else if (strcaseequal(key.c_str()+sizeof(kWPANTUNDProperty_Spinel_CounterPrefix)-1, # x)) { \
+		cntr_key = SPINEL_PROP_CNTR_ ## x; \
+	}
+
+		// Check to see if the counter name is an integer.
+		cntr_key = (int)strtol(key.c_str()+(int)sizeof(kWPANTUNDProperty_Spinel_CounterPrefix)-1, NULL, 0);
+
+		if ( (cntr_key > 0)
+		  && (cntr_key < SPINEL_PROP_CNTR__END-SPINEL_PROP_CNTR__BEGIN)
+		) {
+			// Counter name was a valid integer. Let's use it.
+			cntr_key += SPINEL_PROP_CNTR__BEGIN;
+		}
+
+		CNTR_KEY(TX_PKT_TOTAL)
+		CNTR_KEY(TX_PKT_UNICAST)
+		CNTR_KEY(TX_PKT_BROADCAST)
+		CNTR_KEY(TX_PKT_ACK_REQ)
+		CNTR_KEY(TX_PKT_ACKED)
+		CNTR_KEY(TX_PKT_NO_ACK_REQ)
+		CNTR_KEY(TX_PKT_DATA)
+		CNTR_KEY(TX_PKT_DATA_POLL)
+		CNTR_KEY(TX_PKT_BEACON)
+		CNTR_KEY(TX_PKT_BEACON_REQ)
+		CNTR_KEY(TX_PKT_OTHER)
+		CNTR_KEY(TX_PKT_RETRY)
+		CNTR_KEY(TX_ERR_CCA)
+		CNTR_KEY(TX_ERR_ABORT)
+		CNTR_KEY(RX_PKT_TOTAL)
+		CNTR_KEY(RX_PKT_UNICAST)
+		CNTR_KEY(RX_PKT_BROADCAST)
+		CNTR_KEY(RX_PKT_DATA)
+		CNTR_KEY(RX_PKT_DATA_POLL)
+		CNTR_KEY(RX_PKT_BEACON)
+		CNTR_KEY(RX_PKT_BEACON_REQ)
+		CNTR_KEY(RX_PKT_OTHER)
+		CNTR_KEY(RX_PKT_FILT_WL)
+		CNTR_KEY(RX_PKT_FILT_DA)
+		CNTR_KEY(RX_ERR_EMPTY)
+		CNTR_KEY(RX_ERR_UKWN_NBR)
+		CNTR_KEY(RX_ERR_NVLD_SADDR)
+		CNTR_KEY(RX_ERR_SECURITY)
+		CNTR_KEY(RX_ERR_BAD_FCS)
+		CNTR_KEY(RX_ERR_OTHER)
+		CNTR_KEY(TX_IP_SEC_TOTAL)
+		CNTR_KEY(TX_IP_INSEC_TOTAL)
+		CNTR_KEY(TX_IP_DROPPED)
+		CNTR_KEY(RX_IP_SEC_TOTAL)
+		CNTR_KEY(RX_IP_INSEC_TOTAL)
+		CNTR_KEY(RX_IP_DROPPED)
+		CNTR_KEY(TX_SPINEL_TOTAL)
+		CNTR_KEY(RX_SPINEL_TOTAL)
+		CNTR_KEY(RX_SPINEL_ERR)
+
+#undef CNTR_KEY
+
+		if (cntr_key != 0) {
+			SIMPLE_SPINEL_GET(cntr_key, SPINEL_DATATYPE_UINT32_S);
+		} else {
+			NCPInstanceBase::get_property(key, cb);
+		}
+	} else {
+		NCPInstanceBase::get_property(key, cb);
+	}
+}
+
+void
+SpinelNCPInstance::set_property(
+	const std::string& key,
+	const boost::any& value,
+	CallbackWithStatus cb
+) {
+	syslog(LOG_INFO, "set_property: key: \"%s\"", key.c_str());
+
+	// If we are disabled, then the only property we
+	// are allowed to set is kWPANTUNDProperty_DaemonEnabled.
+	if (!mEnabled && !strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonEnabled)) {
+		cb(kWPANTUNDStatus_InvalidWhenDisabled);
+		return;
+	}
+
+	try {
+		if (strcaseequal(key.c_str(), kWPANTUNDProperty_NCPChannel)) {
+			int channel = any_to_int(value);
+			mCurrentNetworkInstance.channel = channel;
+
+			start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+				.set_callback(cb)
+				.add_command(
+					SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT8_S), SPINEL_PROP_PHY_CHAN, channel)
+				)
+				.finish()
+			);
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NCPCCAThreshold)) {
+			int cca = any_to_int(value);
+			Data command = SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_INT8_S), SPINEL_PROP_PHY_CCA_THRESHOLD, cca);
+
+			mSettings[kWPANTUNDProperty_NCPCCAThreshold] = SettingsEntry(command);
+
+			start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+				.set_callback(cb)
+				.add_command(command)
+				.finish()
+			);
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NetworkPANID)) {
+			uint16_t panid = any_to_int(value);
+
+			start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+				.set_callback(cb)
+				.add_command(
+					SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT16_S), SPINEL_PROP_MAC_15_4_PANID, panid)
+				)
+				.finish()
+			);
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NetworkKey)) {
+			Data network_key = any_to_data(value);
+
+			if (!ncp_state_is_joining_or_joined(get_ncp_state())) {
+				mNetworkKey = network_key;
+				if (mNetworkKeyIndex == 0) {
+					mNetworkKeyIndex = 1;
+				}
+			}
+
+			if (get_ncp_state() == CREDENTIALS_NEEDED) {
+				ValueMap options;
+				options[kWPANTUNDProperty_NetworkKey] = value;
+				start_new_task(boost::shared_ptr<SpinelNCPTask>(
+					new SpinelNCPTaskJoin(
+						this,
+						boost::bind(cb,_1),
+						options
+					)
+				));
+			} else {
+				start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+					.set_callback(cb)
+					.add_command(
+						SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_DATA_S), SPINEL_PROP_NET_MASTER_KEY, network_key.data(), network_key.size())
+					)
+					.finish()
+				);
+			}
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NCPMACAddress)) {
+			Data eui64_value = any_to_data(value);
+
+			if (eui64_value.size() == sizeof(spinel_eui64_t)) {
+				start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+					.set_callback(cb)
+					.add_command(
+						SpinelPackData(
+							SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_EUI64_S),
+							SPINEL_PROP_MAC_15_4_LADDR,
+							eui64_value.data()
+						)
+					)
+					.finish()
+				);
+
+			} else {
+				cb(kWPANTUNDStatus_InvalidArgument);
+			}
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NCPExtendedAddress)) {
+			Data eui64_value = any_to_data(value);
+
+			if (eui64_value.size() == sizeof(spinel_eui64_t)) {
+				start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+					.set_callback(cb)
+					.add_command(
+						SpinelPackData(
+							SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_EUI64_S),
+							SPINEL_PROP_MAC_EXTENDED_ADDR,
+							eui64_value.data()
+						)
+					)
+					.finish()
+				);
+
+			} else {
+				cb(kWPANTUNDStatus_InvalidArgument);
+			}
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NetworkXPANID)) {
+			Data xpanid = any_to_data(value);
+
+			start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+				.set_callback(cb)
+				.add_command(
+					SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_DATA_S), SPINEL_PROP_NET_XPANID, xpanid.data(), xpanid.size())
+				)
+				.finish()
+			);
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NetworkKey)) {
+			Data network_key = any_to_data(value);
+
+			start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+				.set_callback(cb)
+				.add_command(
+					SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_DATA_S), SPINEL_PROP_NET_MASTER_KEY, network_key.data(), network_key.size())
+				)
+				.finish()
+			);
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NetworkKeyIndex)) {
+			uint32_t key_index = any_to_int(value);
+
+			start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+				.set_callback(cb)
+				.add_command(
+					SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT32_S), SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER, key_index)
+				)
+				.finish()
+			);
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NetworkName)) {
+			std::string str = any_to_string(value);
+
+			start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+				.set_callback(cb)
+				.add_command(SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UTF8_S), SPINEL_PROP_NET_NETWORK_NAME, str.c_str()))
+				.finish()
+			);
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ThreadPreferredRouterID)) {
+			uint8_t routerId = any_to_int(value);
+
+			start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+				.set_callback(cb)
+				.add_command(
+					SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT8_S), SPINEL_PROP_THREAD_PREFERRED_ROUTER_ID, routerId)
+				)
+				.finish()
+			);
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_JamDetectionEnable)) {
+			bool isEnabled = any_to_bool(value);
+			Data command = SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S), SPINEL_PROP_JAM_DETECT_ENABLE, isEnabled);
+
+			mSettings[kWPANTUNDProperty_JamDetectionEnable] = SettingsEntry(command, SPINEL_CAP_JAM_DETECT);
+
+			if (!mCapabilities.count(SPINEL_CAP_JAM_DETECT))
+			{
+				cb(kWPANTUNDStatus_FeatureNotSupported);
+			} else {
+				start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+					.set_callback(cb)
+					.add_command(command)
+					.finish()
+				);
+			}
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_JamDetectionRssiThreshold)) {
+			int8_t rssiThreshold = static_cast<int8_t>(any_to_int(value));
+			Data command = SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_INT8_S), SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD, rssiThreshold);
+
+			mSettings[kWPANTUNDProperty_JamDetectionRssiThreshold] = SettingsEntry(command, SPINEL_CAP_JAM_DETECT);
+
+			if (!mCapabilities.count(SPINEL_CAP_JAM_DETECT))
+			{
+				cb(kWPANTUNDStatus_FeatureNotSupported);
+			} else {
+				start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+					.set_callback(cb)
+					.add_command(command)
+					.finish()
+				);
+			}
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_JamDetectionWindow)) {
+			uint8_t window = static_cast<uint8_t>(any_to_int(value));
+			Data command = SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT8_S), SPINEL_PROP_JAM_DETECT_WINDOW, window);
+
+			mSettings[kWPANTUNDProperty_JamDetectionWindow] = SettingsEntry(command, SPINEL_CAP_JAM_DETECT);
+
+			if (!mCapabilities.count(SPINEL_CAP_JAM_DETECT))
+			{
+				cb(kWPANTUNDStatus_FeatureNotSupported);
+			} else {
+				start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+					.set_callback(cb)
+					.add_command(command)
+					.finish()
+				);
+			}
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_JamDetectionBusyPeriod)) {
+			uint8_t busyPeriod = static_cast<uint8_t>(any_to_int(value));
+			Data command = SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT8_S), SPINEL_PROP_JAM_DETECT_BUSY, busyPeriod);
+
+			mSettings[kWPANTUNDProperty_JamDetectionBusyPeriod] = SettingsEntry(command, SPINEL_CAP_JAM_DETECT);
+
+			if (!mCapabilities.count(SPINEL_CAP_JAM_DETECT))
+			{
+				cb(kWPANTUNDStatus_FeatureNotSupported);
+			} else {
+				start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+					.set_callback(cb)
+					.add_command(command)
+					.finish()
+				);
+			}
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix)) {
+			Data legacy_prefix = any_to_data(value);
+			Data command =
+				SpinelPackData(
+					SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_DATA_S),
+					SPINEL_PROP_NEST_LEGACY_ULA_PREFIX,
+					legacy_prefix.data(),
+					legacy_prefix.size()
+				);
+
+			mSettings[kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix] = SettingsEntry(command, SPINEL_CAP_NEST_LEGACY_INTERFACE);
+
+			if (!mCapabilities.count(SPINEL_CAP_NEST_LEGACY_INTERFACE))
+			{
+				cb(kWPANTUNDStatus_FeatureNotSupported);
+			} else {
+				start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+					.set_callback(cb)
+					.add_command(command)
+					.finish()
+				);
+			}
+
+		} else {
+			NCPInstanceBase::set_property(key, value, cb);
+		}
+
+	} catch (const boost::bad_any_cast &x) {
+		// We will get a bad_any_cast exception if the property is of
+		// the wrong type.
+		syslog(LOG_ERR,"set_property: Bad type for property \"%s\" (%s)", key.c_str(), x.what());
+		cb(kWPANTUNDStatus_InvalidArgument);
+	} catch (const std::invalid_argument &x) {
+		// We will get a bad_any_cast exception if the property is of
+		// the wrong type.
+		syslog(LOG_ERR,"set_property: Invalid argument for property \"%s\" (%s)", key.c_str(), x.what());
+		cb(kWPANTUNDStatus_InvalidArgument);
+	}
+
+}
+
+void
+SpinelNCPInstance::reset_tasks(wpantund_status_t status)
+{
+	NCPInstanceBase::reset_tasks(status);
+	while(!mTaskQueue.empty()) {
+		mTaskQueue.front()->finish(status);
+		mTaskQueue.pop_front();
+	}
+}
+
+void
+SpinelNCPInstance::handle_ncp_spinel_value_is(spinel_prop_key_t key, const uint8_t* value_data_ptr, spinel_size_t value_data_len)
+{
+	const uint8_t *original_value_data_ptr = value_data_ptr;
+	spinel_size_t original_value_data_len = value_data_len;
+
+	if (key == SPINEL_PROP_LAST_STATUS) {
+		spinel_status_t status = SPINEL_STATUS_OK;
+		spinel_datatype_unpack(value_data_ptr, value_data_len, "i", &status);
+		syslog(LOG_INFO,"[-NCP-]: Last status (%s, %d)", spinel_status_to_cstr(status), status);
+		if ((status >= SPINEL_STATUS_RESET__BEGIN) && (status <= SPINEL_STATUS_RESET__END)) {
+			syslog(LOG_NOTICE, "[-NCP-]: NCP was reset (%s, %d)", spinel_status_to_cstr(status), status);
+			process_event(EVENT_NCP_RESET, status);
+			if (!mResetIsExpected && (mDriverState == NORMAL_OPERATION)) {
+				wpantund_status_t wstatus = kWPANTUNDStatus_NCP_Reset;
+				switch(status) {
+				case SPINEL_STATUS_RESET_CRASH:
+				case SPINEL_STATUS_RESET_FAULT:
+				case SPINEL_STATUS_RESET_ASSERT:
+				case SPINEL_STATUS_RESET_WATCHDOG:
+				case SPINEL_STATUS_RESET_OTHER:
+					wstatus = kWPANTUNDStatus_NCP_Crashed;
+					break;
+				default:
+					break;
+				}
+				reset_tasks(wstatus);
+			}
+
+			if (mDriverState == NORMAL_OPERATION) {
+				reinitialize_ncp();
+			}
+			mResetIsExpected = false;
+			return;
+
+		} else if (status == SPINEL_STATUS_NOMEM) {
+			cms_t now = time_ms();
+			if (now - mLastTimeNoMemStatus > kMaxTimeBetweenNoMemStatus) {
+				mNoMemStatusCounter = 0;
+			}
+			mLastTimeNoMemStatus = now;
+			mNoMemStatusCounter++;
+
+			if (mNoMemStatusCounter == kMaxNonMemCountToReset)
+			{
+				mNoMemStatusCounter = 0;
+				syslog(LOG_WARNING, "NCP is out of memory for too long...Resetting the NCP!");
+				ncp_is_misbehaving();
+				return;
+			}
+		} else if (status == SPINEL_STATUS_INVALID_COMMAND) {
+			syslog(LOG_NOTICE, "[-NCP-]: COMMAND NOT RECOGNIZED");
+		}
+	} else if (key == SPINEL_PROP_NCP_VERSION) {
+		const char* ncp_version = NULL;
+		spinel_datatype_unpack(value_data_ptr, value_data_len, "U", &ncp_version);
+
+		set_ncp_version_string(ncp_version);
+
+
+	} else if (key == SPINEL_PROP_INTERFACE_TYPE) {
+		unsigned int interface_type = 0;
+		spinel_datatype_unpack(value_data_ptr, value_data_len, "i", &interface_type);
+
+		if (interface_type != SPINEL_PROTOCOL_TYPE_THREAD) {
+			syslog(LOG_CRIT, "[-NCP-]: NCP is using unsupported protocol type (%d)", interface_type);
+			change_ncp_state(FAULT);
+		}
+
+
+	} else if (key == SPINEL_PROP_PROTOCOL_VERSION) {
+		unsigned int protocol_version_major = 0;
+		unsigned int protocol_version_minor = 0;
+		spinel_datatype_unpack(value_data_ptr, value_data_len, "ii", &protocol_version_major, &protocol_version_minor);
+
+		if (protocol_version_major != SPINEL_PROTOCOL_VERSION_THREAD_MAJOR) {
+			syslog(LOG_CRIT, "[-NCP-]: NCP is using unsupported protocol version (NCP:%d, wpantund:%d)", protocol_version_major, SPINEL_PROTOCOL_VERSION_THREAD_MAJOR);
+			change_ncp_state(FAULT);
+		}
+
+		if (protocol_version_minor != SPINEL_PROTOCOL_VERSION_THREAD_MINOR) {
+			syslog(LOG_WARNING, "[-NCP-]: NCP is using different protocol minor version (NCP:%d, wpantund:%d)", protocol_version_minor, SPINEL_PROTOCOL_VERSION_THREAD_MINOR);
+		}
+
+	} else if (key == SPINEL_PROP_CAPS) {
+		const uint8_t* data_ptr = value_data_ptr;
+		spinel_size_t data_len = value_data_len;
+		std::set<unsigned int> capabilities;
+
+		while(data_len != 0) {
+			unsigned int value = 0;
+			spinel_ssize_t parse_len = spinel_datatype_unpack(data_ptr, data_len, SPINEL_DATATYPE_UINT_PACKED_S, &value);
+			if (parse_len <= 0) {
+				syslog(LOG_WARNING, "[-NCP-]: Capability Parse failure");
+				break;
+			}
+			capabilities.insert(value);
+
+			data_ptr += parse_len;
+			data_len -= parse_len;
+		}
+
+		if (capabilities != mCapabilities) {
+			mCapabilities = capabilities;
+		}
+
+	} else if (key == SPINEL_PROP_NET_NETWORK_NAME) {
+		const char* value = NULL;
+		spinel_datatype_unpack(value_data_ptr, value_data_len, "U", &value);
+		if (value && (mCurrentNetworkInstance.name != value)) {
+			mCurrentNetworkInstance.name = value;
+			signal_property_changed(kWPANTUNDProperty_NetworkName, mCurrentNetworkInstance.name);
+		}
+
+	} else if (key == SPINEL_PROP_IPV6_LL_ADDR) {
+		struct in6_addr *addr = NULL;
+		spinel_datatype_unpack(value_data_ptr, value_data_len, "6", &addr);
+		if ( NULL != addr
+		  && (0 != memcmp(mNCPLinkLocalAddress.s6_addr, addr->s6_addr, sizeof(mNCPLinkLocalAddress)))
+		) {
+			if (IN6_IS_ADDR_LINKLOCAL(&mNCPLinkLocalAddress)) {
+				remove_address(mNCPLinkLocalAddress);
+			}
+
+			memcpy((void*)mNCPLinkLocalAddress.s6_addr, (void*)addr->s6_addr, sizeof(mNCPLinkLocalAddress));
+
+			if (IN6_IS_ADDR_LINKLOCAL(&mNCPLinkLocalAddress)) {
+				add_address(mNCPLinkLocalAddress);
+			}
+
+			signal_property_changed(kWPANTUNDProperty_IPv6LinkLocalAddress, in6_addr_to_string(*addr));
+		}
+
+	} else if (key == SPINEL_PROP_IPV6_ML_ADDR) {
+		struct in6_addr *addr = NULL;
+		spinel_datatype_unpack(value_data_ptr, value_data_len, "6", &addr);
+		if (addr
+		 && buffer_is_nonzero(addr->s6_addr, 8)
+		 && (0 != memcmp(mNCPMeshLocalAddress.s6_addr, addr->s6_addr, sizeof(mNCPMeshLocalAddress)))
+		) {
+			if (buffer_is_nonzero(mNCPMeshLocalAddress.s6_addr, sizeof(mNCPMeshLocalAddress))) {
+				remove_address(mNCPMeshLocalAddress);
+			}
+			memcpy((void*)mNCPMeshLocalAddress.s6_addr, (void*)addr->s6_addr, sizeof(mNCPMeshLocalAddress));
+			signal_property_changed(kWPANTUNDProperty_IPv6MeshLocalAddress, in6_addr_to_string(*addr));
+			add_address(mNCPMeshLocalAddress);
+		}
+
+	} else if (key == SPINEL_PROP_IPV6_ML_PREFIX) {
+		struct in6_addr *addr = NULL;
+		spinel_datatype_unpack(value_data_ptr, value_data_len, "6", &addr);
+		if (addr
+		 && buffer_is_nonzero(addr->s6_addr, 8)
+		 && (0 != memcmp(mNCPV6Prefix, addr, sizeof(mNCPV6Prefix)))
+		) {
+			if (buffer_is_nonzero(mNCPMeshLocalAddress.s6_addr, sizeof(mNCPMeshLocalAddress))) {
+				remove_address(mNCPMeshLocalAddress);
+			}
+			memcpy((void*)mNCPV6Prefix, (void*)addr, sizeof(mNCPV6Prefix));
+			struct in6_addr prefix_addr (mNCPMeshLocalAddress);
+			// Zero out the lower 64 bits.
+			memset(prefix_addr.s6_addr+8, 0, 8);
+			signal_property_changed(kWPANTUNDProperty_IPv6MeshLocalPrefix, in6_addr_to_string(prefix_addr) + "/64");
+		}
+
+	} else if (key == SPINEL_PROP_IPV6_ADDRESS_TABLE) {
+		std::map<struct in6_addr, GlobalAddressEntry>::const_iterator iter;
+		std::map<struct in6_addr, GlobalAddressEntry> global_addresses(mGlobalAddresses);
+
+		while (value_data_len > 0) {
+			const uint8_t *entry_ptr = NULL;
+			spinel_size_t entry_len = 0;
+			spinel_ssize_t len = 0;
+			len = spinel_datatype_unpack(value_data_ptr, value_data_len, "D.", &entry_ptr, &entry_len);
+			if (len < 1) {
+				break;
+			}
+			global_addresses.erase(*reinterpret_cast<const struct in6_addr*>(entry_ptr));
+			handle_ncp_spinel_value_inserted(key, entry_ptr, entry_len);
+
+			value_data_ptr += len;
+			value_data_len -= len;
+		}
+
+		// Since this was the whole list, we need
+		// to remove the addresses that weren't in
+		// the list.
+		for (iter = global_addresses.begin(); iter!= global_addresses.end(); ++iter) {
+			if (!iter->second.mUserAdded) {
+				remove_address(iter->first);
+			}
+		}
+
+	} else if (key == SPINEL_PROP_HWADDR) {
+		nl::Data hwaddr(value_data_ptr, value_data_len);
+		if (value_data_len == sizeof(mMACHardwareAddress)) {
+			set_mac_hardware_address(value_data_ptr);
+		}
+
+	} else if (key == SPINEL_PROP_MAC_15_4_LADDR) {
+		nl::Data hwaddr(value_data_ptr, value_data_len);
+		if (value_data_len == sizeof(mMACAddress)) {
+			set_mac_address(value_data_ptr);
+		}
+
+	} else if (key == SPINEL_PROP_MAC_15_4_PANID) {
+		uint16_t panid;
+		spinel_datatype_unpack(value_data_ptr, value_data_len, SPINEL_DATATYPE_UINT16_S, &panid);
+		if (panid != mCurrentNetworkInstance.panid) {
+			mCurrentNetworkInstance.panid = panid;
+			signal_property_changed(kWPANTUNDProperty_NetworkPANID, panid);
+		}
+
+	} else if (key == SPINEL_PROP_NET_XPANID) {
+		nl::Data xpanid(value_data_ptr, value_data_len);
+		if ((value_data_len == 8) && 0 != memcmp(xpanid.data(), mCurrentNetworkInstance.xpanid, 8)) {
+			memcpy(mCurrentNetworkInstance.xpanid, xpanid.data(), 8);
+			signal_property_changed(kWPANTUNDProperty_NetworkXPANID, xpanid);
+		}
+
+	} else if (key == SPINEL_PROP_NET_MASTER_KEY) {
+		nl::Data network_key(value_data_ptr, value_data_len);
+		if (ncp_state_is_joining_or_joined(get_ncp_state())) {
+			if (network_key != mNetworkKey) {
+				mNetworkKey = network_key;
+				signal_property_changed(kWPANTUNDProperty_NetworkKey, mNetworkKey);
+			}
+		}
+
+	} else if (key == SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER) {
+		uint32_t network_key_index;
+		spinel_datatype_unpack(value_data_ptr, value_data_len, SPINEL_DATATYPE_UINT32_S, &network_key_index);
+		if (network_key_index != mNetworkKeyIndex) {
+			mNetworkKeyIndex = network_key_index;
+			signal_property_changed(kWPANTUNDProperty_NetworkKeyIndex, mNetworkKeyIndex);
+		}
+
+	} else if (key == SPINEL_PROP_PHY_CHAN) {
+		unsigned int value;
+		spinel_datatype_unpack(value_data_ptr, value_data_len, SPINEL_DATATYPE_UINT_PACKED_S, &value);
+		if (value != mCurrentNetworkInstance.channel) {
+			mCurrentNetworkInstance.channel = value;
+			signal_property_changed(kWPANTUNDProperty_NCPChannel, mCurrentNetworkInstance.channel);
+		}
+
+	} else if (key == SPINEL_PROP_PHY_CHAN_SUPPORTED) {
+
+		uint8_t channel;
+		spinel_ssize_t len = 0;
+
+		mSupprotedChannels.clear();
+
+		while (value_data_len > 0)
+		{
+			len = spinel_datatype_unpack(value_data_ptr, value_data_len, SPINEL_DATATYPE_UINT8_S, &channel);
+			mSupprotedChannels.insert(channel);
+
+			value_data_ptr += len;
+			value_data_len -= len;
+		}
+
+	} else if (key == SPINEL_PROP_PHY_TX_POWER) {
+		int8_t value;
+		spinel_datatype_unpack(value_data_ptr, value_data_len, SPINEL_DATATYPE_INT8_S, &value);
+		if (value != mTXPower) {
+			mTXPower = value;
+			signal_property_changed(kWPANTUNDProperty_NCPTXPower, mTXPower);
+		}
+
+	} else if (key == SPINEL_PROP_STREAM_DEBUG) {
+		handle_ncp_log(value_data_ptr, value_data_len);
+
+	} else if (key == SPINEL_PROP_NET_ROLE) {
+		uint8_t value;
+		spinel_datatype_unpack(value_data_ptr, value_data_len, SPINEL_DATATYPE_UINT8_S, &value);
+		syslog(LOG_INFO,"[-NCP-]: Net Role \"%s\" (%d)", spinel_net_role_to_cstr(value), value);
+
+		if ( ncp_state_is_joining(get_ncp_state())
+		  && (value != SPINEL_NET_ROLE_DETACHED)
+		) {
+			change_ncp_state(ASSOCIATED);
+		}
+
+		if (value == SPINEL_NET_ROLE_CHILD) {
+			if (mNodeType != END_DEVICE) {
+				mNodeType = END_DEVICE;
+				signal_property_changed(kWPANTUNDProperty_NetworkNodeType, node_type_to_string(mNodeType));
+			}
+
+		} else if (value == SPINEL_NET_ROLE_ROUTER) {
+			if (mNodeType != ROUTER) {
+				mNodeType = ROUTER;
+				signal_property_changed(kWPANTUNDProperty_NetworkNodeType, node_type_to_string(mNodeType));
+			}
+
+		} else if (value == SPINEL_NET_ROLE_LEADER) {
+			if (mNodeType != LEADER) {
+				mNodeType = LEADER;
+				signal_property_changed(kWPANTUNDProperty_NetworkNodeType, node_type_to_string(mNodeType));
+			}
+
+		} else if (value == SPINEL_NET_ROLE_DETACHED) {
+			if (ncp_state_is_associated(get_ncp_state())) {
+				change_ncp_state(ISOLATED);
+			}
+		}
+
+	} else if (key == SPINEL_PROP_NET_STACK_UP) {
+		bool is_stack_up;
+		spinel_datatype_unpack(value_data_ptr, value_data_len, SPINEL_DATATYPE_BOOL_S, &is_stack_up);
+
+		if (is_stack_up) {
+			if (!ncp_state_is_joining_or_joined(get_ncp_state())) {
+				change_ncp_state(ASSOCIATING);
+			}
+		} else {
+			if (!ncp_state_is_joining(get_ncp_state())) {
+				change_ncp_state(OFFLINE);
+			}
+		}
+
+	} else if (key == SPINEL_PROP_NET_IF_UP) {
+		bool is_if_up;
+		spinel_datatype_unpack(value_data_ptr, value_data_len, SPINEL_DATATYPE_BOOL_S, &is_if_up);
+
+		if (ncp_state_is_interface_up(get_ncp_state()) && !is_if_up) {
+			change_ncp_state(OFFLINE);
+		}
+
+	} else if (key == SPINEL_PROP_THREAD_ON_MESH_NETS) {
+		while (value_data_len > 0) {
+			spinel_ssize_t len = 0;
+			struct in6_addr *addr = NULL;
+			uint8_t prefix_len = 0;
+			bool stable;
+			uint8_t flags = 0;
+
+			len = spinel_datatype_unpack(
+				value_data_ptr,
+				value_data_len,
+				"T(6CbC).",
+				&addr,
+				&prefix_len,
+				&stable,
+				&flags
+			);
+
+			if (len < 1) {
+				break;
+			}
+
+			refresh_on_mesh_prefix(addr, prefix_len, stable, flags);
+
+			value_data_ptr += len;
+			value_data_len -= len;
+		}
+
+	} else if (key == SPINEL_PROP_THREAD_ASSISTING_PORTS) {
+		bool is_assisting = (value_data_len != 0);
+		uint16_t assisting_port(0);
+
+		if (is_assisting != get_current_network_instance().joinable) {
+			mCurrentNetworkInstance.joinable = is_assisting;
+			signal_property_changed(kWPANTUNDProperty_NestLabs_NetworkAllowingJoin, is_assisting);
+		}
+
+		if (is_assisting) {
+			int i;
+			syslog(LOG_NOTICE, "Network is joinable");
+			while (value_data_len > 0) {
+				i = spinel_datatype_unpack(value_data_ptr, value_data_len, SPINEL_DATATYPE_UINT16_S, &assisting_port);
+				if (i <= 0) {
+					break;
+				}
+				syslog(LOG_NOTICE, "Assisting on port %d", assisting_port);
+				value_data_ptr += i;
+				value_data_len -= i;
+			}
+		} else {
+			syslog(LOG_NOTICE, "Network is not joinable");
+		}
+
+	} else if (key == SPINEL_PROP_JAM_DETECTED) {
+		bool jamDetected = false;
+
+		spinel_datatype_unpack(value_data_ptr, value_data_len, SPINEL_DATATYPE_BOOL_S, &jamDetected);
+		signal_property_changed(kWPANTUNDProperty_JamDetectionStatus, jamDetected);
+
+		if (jamDetected) {
+			syslog(LOG_NOTICE, "Signal jamming is detected");
+		} else {
+			syslog(LOG_NOTICE, "Signal jamming cleared");
+		}
+
+	} else if (key == SPINEL_PROP_STREAM_RAW) {
+		if (mPcapManager.is_enabled()) {
+			const uint8_t* frame_ptr(NULL);
+			unsigned int frame_len(0);
+			const uint8_t* meta_ptr(NULL);
+			unsigned int meta_len(0);
+			spinel_ssize_t ret;
+			PcapPacket packet;
+			uint16_t flags = 0;
+
+			packet.set_timestamp().set_dlt(PCAP_DLT_IEEE802_15_4);
+
+			// Unpack the packet.
+			ret = spinel_datatype_unpack(
+				value_data_ptr,
+				value_data_len,
+				SPINEL_DATATYPE_DATA_S SPINEL_DATATYPE_DATA_S,
+				&frame_ptr,
+				&frame_len,
+				&meta_ptr,
+				&meta_len
+			);
+
+			require(ret > 0, bail);
+
+			// Unpack the metadata.
+			ret = spinel_datatype_unpack(
+				meta_ptr,
+				meta_len,
+				SPINEL_DATATYPE_INT8_S     // RSSI/TXPower
+				SPINEL_DATATYPE_INT8_S     // Noise Floor
+				SPINEL_DATATYPE_UINT16_S,  // Flags
+				NULL,   // Ignore RSSI/TXPower
+				NULL,	// Ignore Noise Floor
+				&flags
+			);
+
+			__ASSERT_MACROS_check(ret > 0);
+
+			if ((flags & SPINEL_MD_FLAG_TX) == SPINEL_MD_FLAG_TX)
+			{
+				// Ignore FCS for transmitted packets
+				frame_len -= 2;
+				packet.set_dlt(PCAP_DLT_IEEE802_15_4_NOFCS);
+			}
+
+			mPcapManager.push_packet(
+				packet
+					.append_ppi_field(PCAP_PPI_TYPE_SPINEL, meta_ptr, meta_len)
+					.append_payload(frame_ptr, frame_len)
+			);
+		}
+
+	} else if ((key == SPINEL_PROP_STREAM_NET) || (key == SPINEL_PROP_STREAM_NET_INSECURE)) {
+		const uint8_t* frame_ptr(NULL);
+		unsigned int frame_len(0);
+		spinel_ssize_t ret;
+		uint8_t frame_data_type = FRAME_TYPE_DATA;
+
+		if (SPINEL_PROP_STREAM_NET_INSECURE == key) {
+			frame_data_type = FRAME_TYPE_INSECURE_DATA;
+		}
+
+		ret = spinel_datatype_unpack(
+			value_data_ptr,
+			value_data_len,
+			SPINEL_DATATYPE_DATA_S SPINEL_DATATYPE_DATA_S,
+			&frame_ptr,
+			&frame_len,
+			NULL,
+			NULL
+		);
+
+		__ASSERT_MACROS_check(ret > 0);
+
+		// Analyze the packet to determine if it should be dropped.
+		if ((ret > 0) && should_forward_hostbound_frame(&frame_data_type, frame_ptr, frame_len)) {
+			if (static_cast<bool>(mLegacyInterface) && (frame_data_type == FRAME_TYPE_LEGACY_DATA)) {
+				handle_alt_ipv6_from_ncp(frame_ptr, frame_len);
+			} else {
+				handle_normal_ipv6_from_ncp(frame_ptr, frame_len);
+			}
+		}
+	} else if (key == SPINEL_PROP_THREAD_CHILD_TABLE) {
+		SpinelNCPTaskGetNetworkTopology::Table child_table;
+		SpinelNCPTaskGetNetworkTopology::Table::iterator it;
+
+		SpinelNCPTaskGetNetworkTopology::prase_child_table(value_data_ptr, value_data_len, child_table);
+
+		for (it = child_table.begin(); it != child_table.end(); it++)
+		{
+			syslog(LOG_INFO, "[-NCP-] Child: %s", it->get_as_string().c_str());
+		}
+	} else if (key == SPINEL_PROP_THREAD_LEADER_NETWORK_DATA) {
+		char net_data_cstr_buf[540];
+		encode_data_into_string(value_data_ptr, value_data_len, net_data_cstr_buf, sizeof(net_data_cstr_buf), 0);
+		syslog(LOG_INFO, "[-NCP-] Leader network data: %s", net_data_cstr_buf);
+	}
+
+bail:
+	process_event(EVENT_NCP_PROP_VALUE_IS, key, original_value_data_ptr, original_value_data_len);
+}
+
+void
+SpinelNCPInstance::refresh_on_mesh_prefix(struct in6_addr *prefix, uint8_t prefix_len, bool stable, uint8_t flags)
+{
+	if ( ((flags & (SPINEL_NET_FLAG_ON_MESH | SPINEL_NET_FLAG_SLAAC)) == (SPINEL_NET_FLAG_ON_MESH | SPINEL_NET_FLAG_SLAAC))
+	  && !lookup_address_for_prefix(NULL, *prefix, prefix_len)
+	) {
+		SpinelNCPTaskSendCommand::Factory factory(this);
+		struct in6_addr addr = make_slaac_addr_from_eui64(prefix->s6_addr, mMACAddress);
+
+		syslog(LOG_NOTICE, "Pushing a new address %s/%d to the NCP", in6_addr_to_string(addr).c_str(), prefix_len);
+
+		factory.set_lock_property(SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE);
+
+		factory.add_command(
+			SpinelPackData(
+				SPINEL_FRAME_PACK_CMD_PROP_VALUE_INSERT(
+					SPINEL_DATATYPE_IPv6ADDR_S   // Address
+					SPINEL_DATATYPE_UINT8_S      // Prefix Length
+					SPINEL_DATATYPE_UINT32_S     // Valid Lifetime
+					SPINEL_DATATYPE_UINT32_S     // Preferred Lifetime
+				),
+				SPINEL_PROP_IPV6_ADDRESS_TABLE,
+				&addr,
+				prefix_len,
+				UINT32_MAX,
+				UINT32_MAX
+			)
+		);
+
+		start_new_task(factory.finish());
+	}
+}
+
+void
+SpinelNCPInstance::handle_ncp_spinel_value_inserted(spinel_prop_key_t key, const uint8_t* value_data_ptr, spinel_size_t value_data_len)
+{
+	if (key == SPINEL_PROP_IPV6_ADDRESS_TABLE) {
+			struct in6_addr *addr = NULL;
+			uint8_t prefix_len = 0;
+			uint32_t valid_lifetime = 0xFFFFFFFF;
+			uint32_t preferred_lifetime = 0xFFFFFFFF;
+
+			spinel_datatype_unpack(value_data_ptr, value_data_len, "6CLL", &addr, &prefix_len, &valid_lifetime, &preferred_lifetime);
+
+			if (addr != NULL
+				&& buffer_is_nonzero(addr->s6_addr, 8)
+				&& !IN6_IS_ADDR_UNSPECIFIED(addr)
+			) {
+				static const uint8_t rloc_bytes[] = {0x00,0x00,0x00,0xFF,0xFE,0x00};
+				if (IN6_IS_ADDR_LINKLOCAL(addr)) {
+					if (0 != memcmp(rloc_bytes, addr->s6_addr+8, sizeof(rloc_bytes))) {
+						handle_ncp_spinel_value_is(SPINEL_PROP_IPV6_LL_ADDR, addr->s6_addr, sizeof(*addr));
+					}
+				} else if (0 == memcmp(mNCPV6Prefix, addr, sizeof(mNCPV6Prefix))) {
+					if (0 != memcmp(rloc_bytes, addr->s6_addr+8, sizeof(rloc_bytes))) {
+						handle_ncp_spinel_value_is(SPINEL_PROP_IPV6_ML_ADDR, addr->s6_addr, sizeof(*addr));
+					}
+				} else {
+					add_address(*addr, 64, valid_lifetime, preferred_lifetime);
+				}
+			}
+	} else if (key == SPINEL_PROP_THREAD_ON_MESH_NETS) {
+		struct in6_addr *addr = NULL;
+		uint8_t prefix_len = 0;
+		bool stable;
+		uint8_t flags = 0;
+		static const char flag_lookup[] = "ppPSDCRM";
+
+		spinel_datatype_unpack(
+			value_data_ptr,
+			value_data_len,
+			"6CbC",
+			&addr,
+			&prefix_len,
+			&stable,
+			&flags
+		);
+
+		syslog(LOG_NOTICE, "On-Mesh Network Added: %s/%d flags:%s", in6_addr_to_string(*addr).c_str(), prefix_len, flags_to_string(flags, flag_lookup).c_str());
+
+		refresh_on_mesh_prefix(addr, prefix_len, stable, flags);
+	}
+
+	process_event(EVENT_NCP_PROP_VALUE_INSERTED, key, value_data_ptr, value_data_len);
+}
+
+void
+SpinelNCPInstance::handle_ncp_state_change(NCPState new_ncp_state, NCPState old_ncp_state)
+{
+	NCPInstanceBase::handle_ncp_state_change(new_ncp_state, old_ncp_state);
+
+	if ( ncp_state_is_joining_or_joined(old_ncp_state)
+	  && (new_ncp_state == OFFLINE)
+	) {
+		// Mark this as false so that if we are actually doing
+		// a pcap right now it will force the details to be updated
+		// on the NCP at the next run through the main loop. This
+		// allows us to go back to promiscuous-mode sniffing at
+		// disconnect
+		mIsPcapInProgress = false;
+	}
+
+	if (ncp_state_is_associated(new_ncp_state)
+	 && !ncp_state_is_associated(old_ncp_state)
+	) {
+		start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+			.add_command(SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_GET, SPINEL_PROP_MAC_15_4_LADDR))
+			.add_command(SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_GET, SPINEL_PROP_IPV6_ML_ADDR))
+			.add_command(SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_GET, SPINEL_PROP_NET_XPANID))
+			.add_command(SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_GET, SPINEL_PROP_MAC_15_4_PANID))
+			.add_command(SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_GET, SPINEL_PROP_PHY_CHAN))
+			.finish()
+		);
+	} else if (ncp_state_is_joining(new_ncp_state)
+	 && !ncp_state_is_joining(old_ncp_state)
+	) {
+		if (!buffer_is_nonzero(mNCPV6Prefix, 8)) {
+			start_new_task(SpinelNCPTaskSendCommand::Factory(this)
+				.add_command(SpinelPackData(SPINEL_FRAME_PACK_CMD_PROP_VALUE_GET, SPINEL_PROP_IPV6_ML_PREFIX))
+				.finish()
+			);
+		}
+	}
+}
+
+void
+SpinelNCPInstance::handle_ncp_spinel_value_removed(spinel_prop_key_t key, const uint8_t* value_data_ptr, spinel_size_t value_data_len)
+{
+	process_event(EVENT_NCP_PROP_VALUE_REMOVED, key, value_data_ptr, value_data_len);
+}
+
+void
+SpinelNCPInstance::handle_ncp_spinel_callback(unsigned int command, const uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len)
+{
+	switch (command) {
+	case SPINEL_CMD_PROP_VALUE_IS:
+		{
+			spinel_prop_key_t key;
+			uint8_t* value_data_ptr = NULL;
+			spinel_size_t value_data_len = 0;
+			spinel_ssize_t ret;
+
+			ret = spinel_datatype_unpack(cmd_data_ptr, cmd_data_len, "CiiD", NULL, NULL, &key, &value_data_ptr, &value_data_len);
+
+			__ASSERT_MACROS_check(ret != -1);
+
+			if (ret == -1) {
+				return;
+			}
+
+			syslog(LOG_INFO, "[NCP->] CMD_PROP_VALUE_IS(%s) tid:%d", spinel_prop_key_to_cstr(key), SPINEL_HEADER_GET_TID(cmd_data_ptr[0]));
+
+			return handle_ncp_spinel_value_is(key, value_data_ptr, value_data_len);
+		}
+		break;
+
+	case SPINEL_CMD_PROP_VALUE_INSERTED:
+		{
+			spinel_prop_key_t key;
+			uint8_t* value_data_ptr;
+			spinel_size_t value_data_len;
+			spinel_ssize_t ret;
+
+			ret = spinel_datatype_unpack(cmd_data_ptr, cmd_data_len, "CiiD", NULL, NULL, &key, &value_data_ptr, &value_data_len);
+
+			__ASSERT_MACROS_check(ret != -1);
+
+			if (ret == -1) {
+				return;
+			}
+
+			syslog(LOG_INFO, "[NCP->] CMD_PROP_VALUE_INSERTED(%s) tid:%d", spinel_prop_key_to_cstr(key), SPINEL_HEADER_GET_TID(cmd_data_ptr[0]));
+
+			return handle_ncp_spinel_value_inserted(key, value_data_ptr, value_data_len);
+		}
+		break;
+
+	case SPINEL_CMD_PROP_VALUE_REMOVED:
+		{
+			spinel_prop_key_t key;
+			uint8_t* value_data_ptr;
+			spinel_size_t value_data_len;
+			spinel_ssize_t ret;
+
+			ret = spinel_datatype_unpack(cmd_data_ptr, cmd_data_len, "CiiD", NULL, NULL, &key, &value_data_ptr, &value_data_len);
+
+			__ASSERT_MACROS_check(ret != -1);
+
+			if (ret == -1) {
+				return;
+			}
+
+			syslog(LOG_INFO, "[NCP->] CMD_PROP_VALUE_REMOVED(%s) tid:%d", spinel_prop_key_to_cstr(key), SPINEL_HEADER_GET_TID(cmd_data_ptr[0]));
+
+			return handle_ncp_spinel_value_removed(key, value_data_ptr, value_data_len);
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	process_event(EVENT_NCP(command), cmd_data_ptr[0], cmd_data_ptr, cmd_data_len);
+}
+
+void
+SpinelNCPInstance::address_was_added(const struct in6_addr& addr, int prefix_len)
+{
+	if (!is_address_known(addr) && !IN6_IS_ADDR_LINKLOCAL(&addr)) {
+		SpinelNCPTaskSendCommand::Factory factory(this);
+		uint8_t flags = SPINEL_NET_FLAG_SLAAC
+					  | SPINEL_NET_FLAG_ON_MESH
+					  | SPINEL_NET_FLAG_PREFERRED;
+		CallbackWithStatus callback;
+
+		NCPInstanceBase::address_was_added(addr, prefix_len);
+
+		factory.set_lock_property(SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE);
+
+		callback = boost::bind(&SpinelNCPInstance::check_operation_status, this, "address_was_added()", _1);
+		factory.set_callback(callback);
+
+		factory.add_command(
+			SpinelPackData(
+				SPINEL_FRAME_PACK_CMD_PROP_VALUE_INSERT(
+					SPINEL_DATATYPE_IPv6ADDR_S   // Address
+					SPINEL_DATATYPE_UINT8_S      // Prefix Length
+					SPINEL_DATATYPE_UINT32_S     // Valid Lifetime
+					SPINEL_DATATYPE_UINT32_S     // Preferred Lifetime
+				),
+				SPINEL_PROP_IPV6_ADDRESS_TABLE,
+				&addr,
+				prefix_len,
+				UINT32_MAX,
+				UINT32_MAX
+			)
+		);
+
+		factory.add_command(
+			SpinelPackData(
+				SPINEL_FRAME_PACK_CMD_PROP_VALUE_INSERT(
+					SPINEL_DATATYPE_IPv6ADDR_S   // Address
+					SPINEL_DATATYPE_UINT8_S      // Prefix Length
+					SPINEL_DATATYPE_BOOL_S       // Stable?
+					SPINEL_DATATYPE_UINT8_S      // Flags
+				),
+				SPINEL_PROP_THREAD_ON_MESH_NETS,
+				&addr,
+				prefix_len,
+				true,
+				flags
+			)
+		);
+
+		start_new_task(factory.finish());
+	}
+}
+
+void
+SpinelNCPInstance::address_was_removed(const struct in6_addr& addr, int prefix_len)
+{
+	if (mPrimaryInterface->is_online() && is_address_known(addr)) {
+		SpinelNCPTaskSendCommand::Factory factory(this);
+
+		factory.set_lock_property(SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE);
+
+		factory.add_command(
+			SpinelPackData(
+				SPINEL_FRAME_PACK_CMD_PROP_VALUE_REMOVE(
+					SPINEL_DATATYPE_IPv6ADDR_S   // Address
+					SPINEL_DATATYPE_UINT8_S      // Prefix
+				),
+				SPINEL_PROP_IPV6_ADDRESS_TABLE,
+				&addr,
+				prefix_len
+			)
+		);
+
+		start_new_task(factory.finish());
+	}
+
+	NCPInstanceBase::address_was_removed(addr, prefix_len);
+}
+
+void
+SpinelNCPInstance::check_operation_status(std::string operation, int status)
+{
+	if (status == kWPANTUNDStatus_Timeout)
+	{
+		syslog(LOG_ERR, "Timed out while performing \"%s\" - Resetting NCP.", operation.c_str());
+		ncp_is_misbehaving();
+	}
+}
+
+bool
+SpinelNCPInstance::is_busy(void)
+{
+	return NCPInstanceBase::is_busy()
+		|| !mTaskQueue.empty();
+}
+
+
+void
+SpinelNCPInstance::process(void)
+{
+	NCPInstanceBase::process();
+
+	if (!is_initializing_ncp() && mTaskQueue.empty()) {
+		bool x = mPcapManager.is_enabled();
+
+		if (mIsPcapInProgress != x) {
+			SpinelNCPTaskSendCommand::Factory factory(this);
+
+			mIsPcapInProgress = x;
+
+			factory.add_command(SpinelPackData(
+				SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S),
+				SPINEL_PROP_MAC_RAW_STREAM_ENABLED,
+				mIsPcapInProgress
+			));
+
+			if (mIsPcapInProgress) {
+				factory.add_command(SpinelPackData(
+					SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S),
+					SPINEL_PROP_NET_IF_UP,
+					true
+				));
+				if (!ncp_state_is_joining_or_joined(get_ncp_state())) {
+					factory.add_command(SpinelPackData(
+						SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT8_S),
+						SPINEL_PROP_MAC_PROMISCUOUS_MODE,
+						SPINEL_MAC_PROMISCUOUS_MODE_FULL
+					));
+				}
+			} else {
+				factory.add_command(SpinelPackData(
+					SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT8_S),
+					SPINEL_PROP_MAC_PROMISCUOUS_MODE,
+					SPINEL_MAC_PROMISCUOUS_MODE_OFF
+				));
+			}
+
+			start_new_task(factory.finish());
+			NCPInstanceBase::process();
+		}
+	}
+}
diff --git a/src/ncp-spinel/SpinelNCPInstance.h b/src/ncp-spinel/SpinelNCPInstance.h
new file mode 100644
index 0000000..a50f039
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPInstance.h
@@ -0,0 +1,300 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__SpinelNCPInstance__
+#define __wpantund__SpinelNCPInstance__
+
+#include "NCPInstanceBase.h"
+#include "SpinelNCPControlInterface.h"
+#include "nlpt.h"
+#include "SocketWrapper.h"
+#include "SocketAsyncOp.h"
+
+#include <queue>
+#include <set>
+#include <map>
+#include <errno.h>
+#include "spinel.h"
+
+WPANTUND_DECLARE_NCPINSTANCE_PLUGIN(spinel, SpinelNCPInstance);
+
+#define EVENT_NCP_MARKER         0xAB000000
+#define EVENT_NCP(x)             ((x)|EVENT_NCP_MARKER)
+#define IS_EVENT_FROM_NCP(x)     (((x)&~0xFFFFFF) == EVENT_NCP_MARKER)
+
+
+#define EVENT_NCP_RESET                (0xFF0000|EVENT_NCP_MARKER)
+#define EVENT_NCP_PROP_VALUE_IS        (0xFF0001|EVENT_NCP_MARKER)
+#define EVENT_NCP_PROP_VALUE_INSERTED  (0xFF0002|EVENT_NCP_MARKER)
+#define EVENT_NCP_PROP_VALUE_REMOVED   (0xFF0003|EVENT_NCP_MARKER)
+
+#define NCP_FRAMING_OVERHEAD 3
+
+#define CONTROL_REQUIRE_EMPTY_OUTBOUND_BUFFER_WITHIN(seconds, error_label) do { \
+		EH_WAIT_UNTIL_WITH_TIMEOUT(seconds, (GetInstance(this)->mOutboundBufferLen <= 0) && GetInstance(this)->mOutboundCallback.empty()); \
+		require_string(!eh_did_timeout, error_label, "Timed out while waiting " # seconds " seconds for empty outbound buffer"); \
+	} while (0)
+
+#define CONTROL_REQUIRE_OUTBOUND_BUFFER_FLUSHED_WITHIN(seconds, error_label) do { \
+		static const int ___crsw_send_finished = 0xFF000000 | __LINE__; \
+		static const int ___crsw_send_failed = 0xFE000000 | __LINE__; \
+		__ASSERT_MACROS_check(GetInstance(this)->mOutboundCallback.empty()); \
+		require(GetInstance(this)->mOutboundBufferLen > 0, error_label); \
+		GetInstance(this)->mOutboundCallback = CALLBACK_FUNC_SPLIT( \
+			boost::bind(&NCPInstanceBase::process_event_helper, GetInstance(this), ___crsw_send_finished), \
+			boost::bind(&NCPInstanceBase::process_event_helper, GetInstance(this), ___crsw_send_failed) \
+		); \
+		GetInstance(this)->mOutboundBuffer[0] = mLastHeader; \
+		EH_WAIT_UNTIL_WITH_TIMEOUT(seconds, (event == ___crsw_send_finished) || (event == ___crsw_send_failed)); \
+		require_string(!eh_did_timeout, error_label, "Timed out while trying to send command"); \
+		require_string(event == ___crsw_send_finished, error_label, "Failure while trying to send command"); \
+	} while (0)
+
+#define CONTROL_REQUIRE_PREP_TO_SEND_COMMAND_WITHIN(timeout, error_label) do { \
+		CONTROL_REQUIRE_EMPTY_OUTBOUND_BUFFER_WITHIN(timeout, error_label); \
+		GetInstance(this)->mLastTID = SPINEL_GET_NEXT_TID(GetInstance(this)->mLastTID); \
+		mLastHeader = (SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0 | (GetInstance(this)->mLastTID << SPINEL_HEADER_TID_SHIFT)); \
+	} while (false)
+
+#define CONTROL_REQUIRE_COMMAND_RESPONSE_WITHIN(timeout, error_label) do { \
+		EH_REQUIRE_WITHIN(	\
+			timeout,	\
+			IS_EVENT_FROM_NCP(event) && GetInstance(this)->mInboundHeader == mLastHeader, \
+			error_label	\
+		);	\
+	} while (false)
+
+namespace nl {
+namespace wpantund {
+
+class SpinelNCPTask;
+class SpinelNCPControlInterface;
+
+class SpinelNCPInstance : public NCPInstanceBase {
+	friend class SpinelNCPControlInterface;
+	friend class SpinelNCPTask;
+	friend class SpinelNCPTaskDeepSleep;
+	friend class SpinelNCPTaskWake;
+	friend class SpinelNCPTaskJoin;
+	friend class SpinelNCPTaskForm;
+	friend class SpinelNCPTaskScan;
+	friend class SpinelNCPTaskLeave;
+	friend class SpinelNCPTaskSendCommand;
+	friend class SpinelNCPTaskGetNetworkTopology;
+	friend class SpinelNCPTaskGetMsgBufferCounters;
+
+public:
+
+	enum DriverState {
+		INITIALIZING,
+		INITIALIZING_WAITING_FOR_RESET,
+		NORMAL_OPERATION
+	};
+
+public:
+	SpinelNCPInstance(const Settings& settings = Settings());
+
+	virtual ~SpinelNCPInstance();
+
+	virtual SpinelNCPControlInterface& get_control_interface();
+
+	virtual int vprocess_event(int event, va_list args);
+
+
+protected:
+	virtual char ncp_to_driver_pump();
+	virtual char driver_to_ncp_pump();
+
+	void start_new_task(const boost::shared_ptr<SpinelNCPTask> &task);
+
+	virtual bool is_busy(void);
+
+protected:
+
+	int vprocess_init(int event, va_list args);
+	int vprocess_disabled(int event, va_list args);
+	int vprocess_associated(int event, va_list args);
+	int vprocess_resume(int event, va_list args);
+	int vprocess_offline(int event, va_list args);
+
+	void handle_ncp_spinel_callback(unsigned int command, const uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len);
+	void handle_ncp_spinel_value_is(spinel_prop_key_t key, const uint8_t* value_data_ptr, spinel_size_t value_data_len);
+	void handle_ncp_spinel_value_inserted(spinel_prop_key_t key, const uint8_t* value_data_ptr, spinel_size_t value_data_len);
+	void handle_ncp_spinel_value_removed(spinel_prop_key_t key, const uint8_t* value_data_ptr, spinel_size_t value_data_len);
+	void handle_ncp_state_change(NCPState new_ncp_state, NCPState old_ncp_state);
+
+	virtual void address_was_added(const struct in6_addr& addr, int prefix_len);
+	virtual void address_was_removed(const struct in6_addr& addr, int prefix_len);
+
+	void check_operation_status(std::string operation, int status);
+
+	uint32_t get_default_channel_mask(void);
+
+private:
+
+	void refresh_on_mesh_prefix(struct in6_addr *addr, uint8_t prefix_len, bool stable, uint8_t flags);
+
+public:
+	static bool setup_property_supported_by_class(const std::string& prop_name);
+
+	virtual std::set<std::string> get_supported_property_keys()const;
+
+	virtual void get_property(
+	    const std::string& key,
+	    CallbackWithStatusArg1 cb
+	);
+
+	virtual void set_property(
+	    const std::string& key,
+	    const boost::any& value,
+	    CallbackWithStatus cb
+	);
+
+	virtual cms_t get_ms_to_next_event(void);
+
+	virtual void reset_tasks(wpantund_status_t status = kWPANTUNDStatus_Canceled);
+
+	static void handle_ncp_log(const uint8_t* data_ptr, int data_len);
+
+	virtual void process(void);
+
+private:
+	struct SettingsEntry
+	{
+	public:
+		SettingsEntry(const Data &command = Data(), unsigned int capability = 0) :
+			mSpinelCommand(command),
+			mCapability(capability)
+		{
+		}
+
+		Data mSpinelCommand;
+		unsigned int mCapability;
+	};
+
+	/* Map from property key to setting entry
+	 *
+	 * The map contains all parameters/properties that are retained and
+	 * restored when NCP gets initialized.
+	 *
+	 * `Setting entry` contains an optional capability value and an associated
+	 * spinel command.
+	 *
+	 * If the `capability` is present in the list of NCP capabilities , then
+	 * the associated spinel command is sent to NCP after initialization.
+	 */
+	typedef std::map<std::string, SettingsEntry> SettingsMap;
+
+private:
+	SpinelNCPControlInterface mControlInterface;
+
+	uint8_t mLastTID;
+
+	uint8_t mLastHeader;
+
+	uint8_t mInboundFrame[SPINEL_FRAME_MAX_SIZE];
+	uint8_t mInboundHeader;
+	spinel_size_t mInboundFrameSize;
+	uint8_t mInboundFrameDataType;
+	const uint8_t* mInboundFrameDataPtr;
+	spinel_size_t mInboundFrameDataLen;
+	uint16_t mInboundFrameHDLCCRC;
+
+	uint8_t mOutboundBufferHeader[3];
+	uint8_t mOutboundBuffer[SPINEL_FRAME_MAX_SIZE];
+	uint8_t mOutboundBufferType;
+	spinel_ssize_t mOutboundBufferLen;
+	spinel_ssize_t mOutboundBufferSent;
+	uint8_t mOutboundBufferEscaped[SPINEL_FRAME_MAX_SIZE*2];
+	spinel_ssize_t mOutboundBufferEscapedLen;
+	boost::function<void(int)> mOutboundCallback;
+
+	int mTXPower;
+
+	std::set<unsigned int> mCapabilities;
+	uint32_t mDefaultChannelMask;
+
+	SettingsMap mSettings;
+	SettingsMap::iterator mSettingsIter;
+
+	DriverState mDriverState;
+
+	// Protothreads and related state
+	PT mSleepPT;
+	PT mSubPT;
+
+	int mSubPTIndex;
+
+	Data mNetworkKey;
+	uint32_t mNetworkKeyIndex;
+
+	bool mResetIsExpected;
+
+	bool mIsPcapInProgress;
+
+	// Task management
+	std::list<boost::shared_ptr<SpinelNCPTask> > mTaskQueue;
+
+	enum
+	{
+		kMaxTimeBetweenNoMemStatus = 60000, // (in ms) time between NOMEM status to consider it back-to-back.
+		kMaxNonMemCountToReset = 15,        // Number of back-to-back NOMEM status to reset
+	};
+
+	cms_t mLastTimeNoMemStatus;
+	uint16_t mNoMemStatusCounter;
+
+}; // class SpinelNCPInstance
+
+extern class SpinelNCPInstance* gNCPInstance;
+
+template<class C>
+inline SpinelNCPInstance* GetInstance(C *x)
+{
+	return x->mInstance;
+}
+
+template<>
+inline SpinelNCPInstance* GetInstance<SpinelNCPInstance>(SpinelNCPInstance *x)
+{
+	return x;
+}
+
+template<class C>
+inline nl::wpantund::SpinelNCPControlInterface* GetInterface(C *x)
+{
+	return x->mInterface;
+}
+
+template<>
+inline nl::wpantund::SpinelNCPControlInterface* GetInterface<nl::wpantund::SpinelNCPControlInterface>(nl::wpantund::SpinelNCPControlInterface *x)
+{
+	return x;
+}
+
+bool ncp_event_matches_header_from_args(int event, va_list args, uint8_t last_header);
+
+int peek_ncp_callback_status(int event, va_list args);
+
+int spinel_status_to_wpantund_status(int spinel_status);
+
+}; // namespace wpantund
+}; // namespace nl
+
+#endif /* defined(__wpantund__SpinelNCPInstance__) */
diff --git a/src/ncp-spinel/SpinelNCPTask.cpp b/src/ncp-spinel/SpinelNCPTask.cpp
new file mode 100644
index 0000000..e5635d7
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTask.cpp
@@ -0,0 +1,125 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include <syslog.h>
+#include <errno.h>
+#include "SpinelNCPTask.h"
+#include "SpinelNCPInstance.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+SpinelNCPTask::SpinelNCPTask(SpinelNCPInstance* _instance, CallbackWithStatusArg1 cb):
+	mInstance(_instance), mCB(cb), mNextCommandTimeout(NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT)
+{
+}
+
+SpinelNCPTask::~SpinelNCPTask()
+{
+	finish(kWPANTUNDStatus_Canceled);
+}
+
+void
+SpinelNCPTask::finish(int status, const boost::any& value)
+{
+	if (!mCB.empty()) {
+		mCB(status, value);
+		mCB = CallbackWithStatusArg1();
+	}
+}
+
+static bool
+spinel_callback_is_reset(int event, va_list args)
+{
+	int status = peek_ncp_callback_status(event, args);
+	return (status >= SPINEL_STATUS_RESET__BEGIN)
+	    && (status < SPINEL_STATUS_RESET__END);
+}
+
+int
+SpinelNCPTask::vprocess_send_command(int event, va_list args)
+{
+	EH_BEGIN_SUB(&mSubPT);
+
+	require(mNextCommand.size() < sizeof(GetInstance(this)->mOutboundBuffer), on_error);
+
+	CONTROL_REQUIRE_PREP_TO_SEND_COMMAND_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+	memcpy(GetInstance(this)->mOutboundBuffer, mNextCommand.data(), mNextCommand.size());
+	GetInstance(this)->mOutboundBufferLen = static_cast<spinel_ssize_t>(mNextCommand.size());
+	CONTROL_REQUIRE_OUTBOUND_BUFFER_FLUSHED_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+
+	if (mNextCommand[1] == SPINEL_CMD_RESET) {
+		mInstance->mResetIsExpected = true;
+		EH_REQUIRE_WITHIN(
+			mNextCommandTimeout,
+			IS_EVENT_FROM_NCP(event)
+			  && ( (GetInstance(this)->mInboundHeader == mLastHeader)
+			    || spinel_callback_is_reset(event, args)
+			  ),
+			on_error
+		);
+		mNextCommandRet = kWPANTUNDStatus_Ok;
+
+	} else {
+		CONTROL_REQUIRE_COMMAND_RESPONSE_WITHIN(mNextCommandTimeout, on_error);
+		mNextCommandRet = peek_ncp_callback_status(event, args);
+	}
+
+	if (mNextCommandRet) {
+		mNextCommandRet = spinel_status_to_wpantund_status(mNextCommandRet);
+	}
+
+	EH_EXIT();
+
+on_error:
+	mNextCommandRet = kWPANTUNDStatus_Timeout;
+
+	EH_END();
+}
+
+nl::Data
+nl::wpantund::SpinelPackData(const char* pack_format, ...)
+{
+	Data ret(64);
+
+	va_list args;
+	va_start(args, pack_format);
+
+	do {
+		spinel_ssize_t packed_size = spinel_datatype_vpack(ret.data(), (spinel_size_t)ret.size(), pack_format, args);
+
+		if (packed_size < 0) {
+			ret.clear();
+		} else if (packed_size > ret.size()) {
+			ret.resize(packed_size);
+			continue;
+		} else {
+			ret.resize(packed_size);
+		}
+		break;
+	} while(true);
+
+	va_end(args);
+	return ret;
+}
diff --git a/src/ncp-spinel/SpinelNCPTask.h b/src/ncp-spinel/SpinelNCPTask.h
new file mode 100644
index 0000000..5ad5bfc
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTask.h
@@ -0,0 +1,73 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__SpinelNCPTask__
+#define __wpantund__SpinelNCPTask__
+
+#include "NCPInstanceBase.h"
+#include "nlpt.h"
+#include "SocketWrapper.h"
+#include "SocketAsyncOp.h"
+
+#include <boost/enable_shared_from_this.hpp>
+#include <queue>
+#include <set>
+#include <map>
+#include <errno.h>
+#include "spinel.h"
+
+namespace nl {
+namespace wpantund {
+
+class SpinelNCPInstance;
+
+class SpinelNCPTask
+	: public boost::enable_shared_from_this<SpinelNCPTask>
+	, public boost::signals2::trackable
+	, public nl::EventHandler
+{
+public:
+	SpinelNCPTask(SpinelNCPInstance* _instance, CallbackWithStatusArg1 cb);
+	virtual ~SpinelNCPTask();
+
+	virtual int vprocess_event(int event, va_list args) = 0;
+
+	virtual void finish(int status, const boost::any& value = boost::any());
+
+	bool peek_callback_is_prop_value_is(int event, va_list args, spinel_prop_key_t);
+
+	SpinelNCPInstance* mInstance;
+
+	int vprocess_send_command(int event, va_list args);
+
+protected:
+	CallbackWithStatusArg1 mCB;
+	uint8_t mLastHeader;
+	PT mSubPT;
+	Data mNextCommand;
+	int mNextCommandRet;
+	int mNextCommandTimeout;
+};
+
+nl::Data SpinelPackData(const char* pack_format, ...);
+
+}; // namespace wpantund
+}; // namespace nl
+
+#endif /* defined(__wpantund__SpinelNCPInstance__) */
diff --git a/src/ncp-spinel/SpinelNCPTaskDeepSleep.cpp b/src/ncp-spinel/SpinelNCPTaskDeepSleep.cpp
new file mode 100644
index 0000000..947fabb
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskDeepSleep.cpp
@@ -0,0 +1,124 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *		This file contains the code that handles transitioning the
+ *      NCP into a deep-sleep state.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include <syslog.h>
+#include <errno.h>
+#include "SpinelNCPTaskDeepSleep.h"
+#include "SpinelNCPInstance.h"
+#include "spinel-extra.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+nl::wpantund::SpinelNCPTaskDeepSleep::SpinelNCPTaskDeepSleep(
+	SpinelNCPInstance* instance,
+	CallbackWithStatusArg1 cb
+):	SpinelNCPTask(instance, cb)
+{
+}
+
+void
+nl::wpantund::SpinelNCPTaskDeepSleep::finish(int status, const boost::any& value)
+{
+	mInstance->mResetIsExpected = false;
+
+	SpinelNCPTask::finish(status, value);
+}
+
+
+int
+nl::wpantund::SpinelNCPTaskDeepSleep::vprocess_event(int event, va_list args)
+{
+	int ret = kWPANTUNDStatus_Failure;
+
+	EH_BEGIN();
+
+	// The first event to a task is EVENT_STARTING_TASK. The following
+	// line makes sure that we don't start processing this task
+	// until it is properly scheduled. All tasks immediately receive
+	// the initial `EVENT_STARTING_TASK` event, but further events
+	// will only be received by that task once it is that task's turn
+	// to execute.
+	EH_WAIT_UNTIL(EVENT_STARTING_TASK != event);
+
+	// If we are still initializing, wait until we are finished.
+	EH_WAIT_UNTIL_WITH_TIMEOUT(mInstance->mDriverState == SpinelNCPInstance::NORMAL_OPERATION, NCP_DEFAULT_COMMAND_SEND_TIMEOUT);
+
+	if (mInstance->can_set_ncp_power()) {
+		mNextCommand = SpinelPackData(SPINEL_FRAME_PACK_CMD_NOOP);
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		// Wait for half a second after the last ncp-generated event before
+		// manually cutting the power, just to be conservative.
+		do {
+			EH_WAIT_UNTIL(!IS_EVENT_FROM_NCP(event));
+			EH_WAIT_UNTIL_WITH_TIMEOUT(0.5, IS_EVENT_FROM_NCP(event));
+		} while(!eh_did_timeout);
+
+		if (mInstance->set_ncp_power(false) == kWPANTUNDStatus_Ok) {
+			mInstance->change_ncp_state(DEEP_SLEEP);
+		} else {
+			syslog(LOG_ERR, "DeepSleep: set_ncp_power(false) failed.");
+
+			// Turning off the power manually didn't work for some reason.
+			// Turn it back on and we will try to do it via the API.
+			mInstance->set_ncp_power(true);
+		}
+	}
+
+	if (mInstance->get_ncp_state() != DEEP_SLEEP) {
+		syslog(LOG_NOTICE, "DeepSleep: Putting NCP to sleep.");
+
+		mNextCommand = SpinelPackData(
+			SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT8_S),
+			SPINEL_PROP_POWER_STATE,
+			SPINEL_POWER_STATE_DEEP_SLEEP
+		);
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+		ret = mNextCommandRet;
+		require_noerr(ret, on_error);
+
+		mInstance->change_ncp_state(DEEP_SLEEP);
+	}
+
+on_error:
+
+	if (mInstance->get_ncp_state() == DEEP_SLEEP) {
+		syslog(LOG_NOTICE, "NCP is asleep.");
+		ret = kWPANTUNDStatus_Ok;
+	} else {
+		syslog(LOG_WARNING, "NCP DID NOT GO TO SLEEP!");
+		if (kWPANTUNDStatus_Ok == ret) {
+			ret = kWPANTUNDStatus_Failure;
+		}
+	}
+
+	finish(ret);
+
+	EH_END();
+}
diff --git a/src/ncp-spinel/SpinelNCPTaskDeepSleep.h b/src/ncp-spinel/SpinelNCPTaskDeepSleep.h
new file mode 100644
index 0000000..7c269c8
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskDeepSleep.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__SpinelNCPTaskDeepSleep__
+#define __wpantund__SpinelNCPTaskDeepSleep__
+
+#include "SpinelNCPTask.h"
+#include "SpinelNCPInstance.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+namespace nl {
+namespace wpantund {
+
+class SpinelNCPTaskDeepSleep : public SpinelNCPTask
+{
+public:
+	SpinelNCPTaskDeepSleep(
+		SpinelNCPInstance* instance,
+		CallbackWithStatusArg1 cb
+	);
+	virtual int vprocess_event(int event, va_list args);
+	virtual void finish(int status, const boost::any& value = boost::any());
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+
+#endif /* defined(__wpantund__SpinelNCPTaskDeepSleep__) */
diff --git a/src/ncp-spinel/SpinelNCPTaskForm.cpp b/src/ncp-spinel/SpinelNCPTaskForm.cpp
new file mode 100644
index 0000000..d2ddf8c
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskForm.cpp
@@ -0,0 +1,413 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include <syslog.h>
+#include <errno.h>
+#include "SpinelNCPTaskForm.h"
+#include "SpinelNCPInstance.h"
+#include "SpinelNCPTaskScan.h"
+#include "any-to.h"
+#include "spinel-extra.h"
+#include "sec-random.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+nl::wpantund::SpinelNCPTaskForm::SpinelNCPTaskForm(
+	SpinelNCPInstance* instance,
+	CallbackWithStatusArg1 cb,
+	const ValueMap& options
+):	SpinelNCPTask(instance, cb), mOptions(options), mLastState(instance->get_ncp_state())
+{
+	if (!mOptions.count(kWPANTUNDProperty_NetworkPANID)) {
+		uint16_t panid;
+
+		sec_random_fill(reinterpret_cast<uint8_t*>(&panid), sizeof(panid));
+
+		mOptions[kWPANTUNDProperty_NetworkPANID] = panid;
+	}
+
+	if (!mOptions.count(kWPANTUNDProperty_NetworkXPANID)) {
+		uint64_t xpanid;
+
+		sec_random_fill(reinterpret_cast<uint8_t*>(&xpanid), sizeof(xpanid));
+
+		mOptions[kWPANTUNDProperty_NetworkXPANID] = xpanid;
+	}
+
+
+	if (!mOptions.count(kWPANTUNDProperty_IPv6MeshLocalAddress)) {
+		union {
+			uint64_t xpanid;
+			uint8_t bytes[1];
+		} x = { any_to_uint64((mOptions[kWPANTUNDProperty_NetworkXPANID])) };
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+		reverse_bytes(x.bytes, sizeof(x.xpanid));
+#endif
+
+		// Default ML Prefix to be derived from XPANID.
+		struct in6_addr mesh_local_prefix = {{{
+			0xfd, x.bytes[0], x.bytes[1], x.bytes[2], x.bytes[3], x.bytes[4], 0, 0
+		}}};
+
+		mOptions[kWPANTUNDProperty_IPv6MeshLocalAddress] = mesh_local_prefix;
+	}
+
+	if (instance->mNetworkKey.empty()) {
+		if (!mOptions.count(kWPANTUNDProperty_NetworkKey)) {
+			uint8_t net_key[NCP_NETWORK_KEY_SIZE];
+
+			sec_random_fill(net_key, sizeof(net_key));
+
+			mOptions[kWPANTUNDProperty_NetworkKey] = Data(net_key, sizeof(net_key));
+		}
+
+		if (!mOptions.count(kWPANTUNDProperty_NetworkKeyIndex)) {
+			mOptions[kWPANTUNDProperty_NetworkKeyIndex] = 1;
+		}
+	}
+}
+
+void
+nl::wpantund::SpinelNCPTaskForm::finish(int status, const boost::any& value)
+{
+	if (!ncp_state_is_associated(mInstance->get_ncp_state())) {
+		mInstance->change_ncp_state(mLastState);
+	}
+	SpinelNCPTask::finish(status, value);
+}
+
+int
+nl::wpantund::SpinelNCPTaskForm::vprocess_event(int event, va_list args)
+{
+	int ret = kWPANTUNDStatus_Failure;
+
+	EH_BEGIN();
+
+
+	if (!mInstance->mEnabled) {
+		ret = kWPANTUNDStatus_InvalidWhenDisabled;
+		finish(ret);
+		EH_EXIT();
+	}
+
+	if (mInstance->get_ncp_state() == UPGRADING) {
+		ret = kWPANTUNDStatus_InvalidForCurrentState;
+		finish(ret);
+		EH_EXIT();
+	}
+
+	// Wait for a bit to see if the NCP will enter the right state.
+	EH_REQUIRE_WITHIN(
+		NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT,
+		!ncp_state_is_initializing(mInstance->get_ncp_state()),
+		on_error
+	);
+
+	if (ncp_state_is_associated(mInstance->get_ncp_state())) {
+		ret = kWPANTUNDStatus_Already;
+		finish(ret);
+		EH_EXIT();
+	}
+
+	if (!mInstance->mCapabilities.count(SPINEL_CAP_ROLE_ROUTER)) {
+		// We can't form unless we are router-capable
+		ret = kWPANTUNDStatus_FeatureNotSupported;
+		finish(ret);
+		EH_EXIT();
+	}
+
+	// The first event to a task is EVENT_STARTING_TASK. The following
+	// line makes sure that we don't start processing this task
+	// until it is properly scheduled. All tasks immediately receive
+	// the initial `EVENT_STARTING_TASK` event, but further events
+	// will only be received by that task once it is that task's turn
+	// to execute.
+	EH_WAIT_UNTIL(EVENT_STARTING_TASK != event);
+
+	mLastState = mInstance->get_ncp_state();
+	mInstance->change_ncp_state(ASSOCIATING);
+
+	// Clear any previously saved network settings
+	mNextCommand = SpinelPackData(SPINEL_FRAME_PACK_CMD_NET_CLEAR);
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+	ret = mNextCommandRet;
+	require_noerr(ret, on_error);
+
+	// TODO: We should do a scan to make sure we pick a good channel
+	//       and don't have a panid collision.
+
+	// Set the channel
+	{
+		uint8_t channel;
+
+		if (mOptions.count(kWPANTUNDProperty_NCPChannel)) {
+			channel = any_to_int(mOptions[kWPANTUNDProperty_NCPChannel]);
+
+			// Make sure the channel is the supported channel set.
+			if (mInstance->mSupprotedChannels.find(channel) == mInstance->mSupprotedChannels.end()) {
+				syslog(LOG_ERR, "Channel %d is not supported by NCP. Supported channels mask is %08x",
+					mInstance->get_default_channel_mask()
+				);
+				ret = kWPANTUNDStatus_InvalidArgument;
+				goto on_error;
+			}
+
+		} else {
+			uint32_t mask;
+			uint32_t default_mask = mInstance->get_default_channel_mask();
+
+			if (mOptions.count(kWPANTUNDProperty_NCPChannelMask)) {
+				mask = any_to_int(mOptions[kWPANTUNDProperty_NCPChannelMask]);
+			} else {
+				mask = default_mask;
+			}
+
+			if ((mask & default_mask) == 0) {
+				syslog(LOG_ERR,	"Invalid channel mask 0x%08x. Supported channels mask is 0x%08x", mask, default_mask);
+				ret = kWPANTUNDStatus_InvalidArgument;
+				goto on_error;
+			}
+
+			mask &= default_mask;
+
+			// Randomly pick a channel from the given channel mask for now.
+			do {
+				sec_random_fill(&channel, 1);
+				channel = (channel % 32);
+			} while (0 == ((1 << channel) & mask));
+		}
+
+		mNextCommand = SpinelPackData(
+			SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT8_S),
+			SPINEL_PROP_PHY_CHAN,
+			channel
+		);
+	}
+
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+	ret = mNextCommandRet;
+
+	require_noerr(ret, on_error);
+
+	// Turn off promiscuous mode, if it happens to be on
+	mNextCommand = SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT8_S),
+		SPINEL_PROP_MAC_PROMISCUOUS_MODE,
+		SPINEL_MAC_PROMISCUOUS_MODE_OFF
+	);
+
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+	ret = mNextCommandRet;
+	check_noerr(ret);
+
+	if (mOptions.count(kWPANTUNDProperty_NetworkPANID)) {
+		mNextCommand = SpinelPackData(
+			SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT16_S),
+			SPINEL_PROP_MAC_15_4_PANID,
+			any_to_int(mOptions[kWPANTUNDProperty_NetworkPANID])
+		);
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		ret = mNextCommandRet;
+
+		require_noerr(ret, on_error);
+	}
+
+	if (mOptions.count(kWPANTUNDProperty_NetworkXPANID)) {
+		{
+			uint64_t xpanid(any_to_uint64((mOptions[kWPANTUNDProperty_NetworkXPANID])));
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+			reverse_bytes(reinterpret_cast<uint8_t*>(&xpanid), sizeof(xpanid));
+#endif
+
+			mNextCommand = SpinelPackData(
+				SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_DATA_S),
+				SPINEL_PROP_NET_XPANID,
+				&xpanid,
+				sizeof(xpanid)
+			);
+		}
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		ret = mNextCommandRet;
+
+		require_noerr(ret, on_error);
+	}
+
+	if (mOptions.count(kWPANTUNDProperty_NetworkName)) {
+		mNextCommand = SpinelPackData(
+			SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UTF8_S),
+			SPINEL_PROP_NET_NETWORK_NAME,
+			any_to_string(mOptions[kWPANTUNDProperty_NetworkName]).c_str()
+		);
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		ret = mNextCommandRet;
+
+		require_noerr(ret, on_error);
+	}
+
+	if (mOptions.count(kWPANTUNDProperty_NetworkKey)) {
+		{
+			nl::Data data(any_to_data(mOptions[kWPANTUNDProperty_NetworkKey]));
+			mNextCommand = SpinelPackData(
+				SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_DATA_S),
+				SPINEL_PROP_NET_MASTER_KEY,
+				data.data(),
+				data.size()
+			);
+		}
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		ret = mNextCommandRet;
+
+		require_noerr(ret, on_error);
+	}
+
+	if (mOptions.count(kWPANTUNDProperty_NetworkKeyIndex)) {
+		mNextCommand = SpinelPackData(
+			SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT32_S),
+			SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER,
+			any_to_int(mOptions[kWPANTUNDProperty_NetworkKeyIndex])
+		);
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		ret = mNextCommandRet;
+
+		require_noerr(ret, on_error);
+	}
+
+	if (mOptions.count(kWPANTUNDProperty_IPv6MeshLocalAddress)) {
+		{
+			struct in6_addr addr = any_to_ipv6(mOptions[kWPANTUNDProperty_IPv6MeshLocalAddress]);
+			mNextCommand = SpinelPackData(
+				SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_IPv6ADDR_S SPINEL_DATATYPE_UINT8_S),
+				SPINEL_PROP_IPV6_ML_PREFIX,
+				&addr,
+				64
+			);
+		}
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		ret = mNextCommandRet;
+
+		require_noerr(ret, on_error);
+	} else if (mOptions.count(kWPANTUNDProperty_IPv6MeshLocalPrefix)) {
+		{
+			struct in6_addr addr = any_to_ipv6(mOptions[kWPANTUNDProperty_IPv6MeshLocalPrefix]);
+			mNextCommand = SpinelPackData(
+				SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_IPv6ADDR_S SPINEL_DATATYPE_UINT8_S),
+				SPINEL_PROP_IPV6_ML_PREFIX,
+				&addr,
+				64
+			);
+		}
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		ret = mNextCommandRet;
+
+		require_noerr(ret, on_error);
+	}
+
+	if (mOptions.count(kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix)) {
+		if (mInstance->mCapabilities.count(SPINEL_CAP_NEST_LEGACY_INTERFACE)) {
+			{
+				nl::Data data(any_to_data(mOptions[kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix]));
+				mNextCommand = SpinelPackData(
+					SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_DATA_S),
+					SPINEL_PROP_NEST_LEGACY_ULA_PREFIX,
+					data.data(),
+					data.size()
+				);
+			}
+
+			EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+			ret = mNextCommandRet;
+
+			require_noerr(ret, on_error);
+		}
+	}
+
+	// Now bring up the network by bringing up the interface and the stack.
+
+	mNextCommand = SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S),
+		SPINEL_PROP_NET_IF_UP,
+		true
+	);
+
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+	ret = mNextCommandRet;
+
+	require(ret == kWPANTUNDStatus_Ok || ret == kWPANTUNDStatus_Already, on_error);
+
+	mNextCommand = SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S),
+		SPINEL_PROP_NET_STACK_UP,
+		true
+	);
+
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+	ret = mNextCommandRet;
+
+	require_noerr(ret, on_error);
+
+	EH_REQUIRE_WITHIN(
+		NCP_FORM_TIMEOUT,
+		ncp_state_is_associated(mInstance->get_ncp_state()),
+		on_error
+	);
+
+	ret = kWPANTUNDStatus_Ok;
+
+	finish(ret);
+
+	EH_EXIT();
+
+on_error:
+
+	if (ret == kWPANTUNDStatus_Ok) {
+		ret = kWPANTUNDStatus_Failure;
+	}
+
+	syslog(LOG_ERR, "Form failed: %d", ret);
+
+	finish(ret);
+
+	EH_END();
+}
diff --git a/src/ncp-spinel/SpinelNCPTaskForm.h b/src/ncp-spinel/SpinelNCPTaskForm.h
new file mode 100644
index 0000000..1fef8f4
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskForm.h
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__SpinelNCPTaskForm__
+#define __wpantund__SpinelNCPTaskForm__
+
+#include "SpinelNCPTask.h"
+#include "SpinelNCPInstance.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+namespace nl {
+namespace wpantund {
+
+class SpinelNCPTaskForm : public SpinelNCPTask
+{
+public:
+	SpinelNCPTaskForm(
+		SpinelNCPInstance* instance,
+		CallbackWithStatusArg1 cb,
+		const ValueMap& options
+	);
+	virtual int vprocess_event(int event, va_list args);
+	virtual void finish(int status, const boost::any& value = boost::any());
+
+private:
+	ValueMap mOptions;
+	NCPState mLastState;
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+
+#endif /* defined(__wpantund__SpinelNCPTaskForm__) */
diff --git a/src/ncp-spinel/SpinelNCPTaskGetMsgBufferCounters.cpp b/src/ncp-spinel/SpinelNCPTaskGetMsgBufferCounters.cpp
new file mode 100644
index 0000000..896a6e6
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskGetMsgBufferCounters.cpp
@@ -0,0 +1,266 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include <syslog.h>
+#include <errno.h>
+#include "SpinelNCPTaskGetMsgBufferCounters.h"
+#include "SpinelNCPInstance.h"
+#include "spinel-extra.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+nl::wpantund::SpinelNCPTaskGetMsgBufferCounters::SpinelNCPTaskGetMsgBufferCounters(
+	SpinelNCPInstance* instance,
+	CallbackWithStatusArg1 cb,
+	ResultFormat result_format
+):	SpinelNCPTask(instance, cb), mResultFormat(result_format)
+{
+}
+
+int
+nl::wpantund::SpinelNCPTaskGetMsgBufferCounters::vprocess_event(int event, va_list args)
+{
+	int ret = kWPANTUNDStatus_Failure;
+	unsigned int prop_key;
+	const uint8_t *data_in;
+	spinel_size_t data_len;
+	spinel_ssize_t len;
+	MsgBufferCounters counters;
+
+	EH_BEGIN();
+
+	if (!mInstance->mEnabled) {
+		ret = kWPANTUNDStatus_InvalidWhenDisabled;
+		finish(ret);
+		EH_EXIT();
+	}
+
+	if (mInstance->get_ncp_state() == UPGRADING) {
+		ret = kWPANTUNDStatus_InvalidForCurrentState;
+		finish(ret);
+		EH_EXIT();
+	}
+
+	// Wait for a bit to see if the NCP will enter the right state.
+	EH_REQUIRE_WITHIN(
+		NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT,
+		!ncp_state_is_initializing(mInstance->get_ncp_state()),
+		on_error
+	);
+
+	// The first event to a task is EVENT_STARTING_TASK. The following
+	// line makes sure that we don't start processing this task
+	// until it is properly scheduled. All tasks immediately receive
+	// the initial `EVENT_STARTING_TASK` event, but further events
+	// will only be received by that task once it is that task's turn
+	// to execute.
+	EH_WAIT_UNTIL(EVENT_STARTING_TASK != event);
+
+	mNextCommand = SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_GET,
+		SPINEL_PROP_MSG_BUFFER_COUNTERS
+	);
+
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+	ret = mNextCommandRet;
+
+	require_noerr(ret, on_error);
+
+	require(EVENT_NCP_PROP_VALUE_IS == event, on_error);
+
+	prop_key = va_arg(args, unsigned int);
+	data_in = va_arg(args, const uint8_t*);
+	data_len = va_arg_small(args, spinel_size_t);
+
+	require(prop_key == SPINEL_PROP_MSG_BUFFER_COUNTERS, on_error);
+
+	len = spinel_datatype_unpack(
+		data_in,
+		data_len,
+		"SSSSSSSSSSSSSSSS",
+		&counters.mTotalBuffers,
+		&counters.mFreeBuffers,
+		&counters.m6loSendMessages,
+		&counters.m6loSendBuffers,
+		&counters.m6loReassemblyMessages,
+		&counters.m6loReassemblyBuffers,
+		&counters.mIp6Messages,
+		&counters.mIp6Buffers,
+		&counters.mMplMessages,
+		&counters.mMplBuffers,
+		&counters.mMleMessages,
+		&counters.mMleBuffers,
+		&counters.mArpMessages,
+		&counters.mArpBuffers,
+		&counters.mCoapClientMessages,
+		&counters.mCoapClientBuffers
+	);
+
+	require(len >=0, on_error);
+
+	ret = kWPANTUNDStatus_Ok;
+
+	if (mResultFormat == kResultFormat_StringArray)
+	{
+		finish(ret, counters.get_as_string_array());
+	}
+	else if (mResultFormat == kResultFormat_String)
+	{
+		finish(ret, counters.get_as_string());
+	}
+	else if (mResultFormat == kResultFormat_ValueMap)
+	{
+		finish(ret, counters.get_as_valuemap());
+	}
+	else
+	{
+		finish(ret);
+	}
+
+	EH_EXIT();
+
+on_error:
+
+	if (ret == kWPANTUNDStatus_Ok) {
+		ret = kWPANTUNDStatus_Failure;
+	}
+
+	syslog(LOG_ERR, "Getting msg buffer counter failed: %d", ret);
+
+	finish(ret);
+
+	EH_END();
+}
+
+std::list<std::string>
+SpinelNCPTaskGetMsgBufferCounters::MsgBufferCounters::get_as_string_array(void) const
+{
+	std::list<std::string> slist;
+	char c_string[100];
+
+	snprintf(c_string, sizeof(c_string), "mTotalBuffers = %d", mTotalBuffers);
+	slist.push_back(c_string);
+	snprintf(c_string, sizeof(c_string), "mFreeBuffers = %d", mFreeBuffers);
+	slist.push_back(c_string);
+	snprintf(c_string, sizeof(c_string), "m6loSendMessages = %d", m6loSendMessages);
+	slist.push_back(c_string);
+	snprintf(c_string, sizeof(c_string), "m6loSendBuffers = %d", m6loSendBuffers);
+	slist.push_back(c_string);
+	snprintf(c_string, sizeof(c_string), "m6loReassemblyMessages = %d", m6loReassemblyMessages);
+	slist.push_back(c_string);
+	snprintf(c_string, sizeof(c_string), "m6loReassemblyBuffers = %d", m6loReassemblyBuffers);
+	slist.push_back(c_string);
+	snprintf(c_string, sizeof(c_string), "mIp6Messages = %d", mIp6Messages);
+	slist.push_back(c_string);
+	snprintf(c_string, sizeof(c_string), "mIp6Buffers = %d", mIp6Buffers);
+	slist.push_back(c_string);
+	snprintf(c_string, sizeof(c_string), "mMplMessages = %d", mMplMessages);
+	slist.push_back(c_string);
+	snprintf(c_string, sizeof(c_string), "mMplBuffers = %d", mMplBuffers);
+	slist.push_back(c_string);
+	snprintf(c_string, sizeof(c_string), "mMleMessages = %d", mMleMessages);
+	slist.push_back(c_string);
+	snprintf(c_string, sizeof(c_string), "mMleBuffers = %d", mMleBuffers);
+	slist.push_back(c_string);
+	snprintf(c_string, sizeof(c_string), "mArpMessages = %d", mArpMessages);
+	slist.push_back(c_string);
+	snprintf(c_string, sizeof(c_string), "mArpBuffers = %d", mArpBuffers);
+	slist.push_back(c_string);
+	snprintf(c_string, sizeof(c_string), "mCoapClientMessages = %d", mCoapClientMessages);
+	slist.push_back(c_string);
+	snprintf(c_string, sizeof(c_string), "mCoapClientBuffers = %d", mCoapClientBuffers);
+	slist.push_back(c_string);
+
+	return slist;
+}
+
+std::string
+SpinelNCPTaskGetMsgBufferCounters::MsgBufferCounters::get_as_string(void) const
+{
+	char c_string[800];
+
+	snprintf(c_string, sizeof(c_string),
+		"TotalBuffers = %-3d, "
+		"FreeBuffers = %-3d, "
+		"6loSendMessages = %-3d, "
+		"6loSendBuffers = %-3d, "
+		"6loReassemblyMessages = %-3d, "
+		"6loReassemblyBuffers = %-3d, "
+		"Ip6Messages = %-3d, "
+		"Ip6Buffers = %-3d, "
+		"MplMessages = %-3d, "
+		"MplBuffers = %-3d, "
+		"MleMessages = %-3d, "
+		"MleBuffers = %-3d, "
+		"ArpMessages = %-3d, "
+		"ArpBuffers = %-3d, "
+		"CoapClientMessages = %-3d, "
+		"CoapClientBuffers = %-3d, ",
+		mTotalBuffers,
+		mFreeBuffers,
+		m6loSendMessages,
+		m6loSendBuffers,
+		m6loReassemblyMessages,
+		m6loReassemblyBuffers,
+		mIp6Messages,
+		mIp6Buffers,
+		mMplMessages,
+		mMplBuffers,
+		mMleMessages,
+		mMleBuffers,
+		mArpMessages,
+		mArpBuffers,
+		mCoapClientMessages,
+		mCoapClientBuffers
+	);
+
+	return std::string(c_string);
+}
+
+ValueMap
+SpinelNCPTaskGetMsgBufferCounters::MsgBufferCounters::get_as_valuemap(void) const
+{
+	ValueMap vm;
+
+	vm["TotalBuffers"] = mTotalBuffers;
+	vm["FreeBuffers"] = mFreeBuffers;
+	vm["6loSendMessages"] = m6loSendMessages;
+	vm["6loSendBuffers"] = m6loSendBuffers;
+	vm["6loReassemblyMessages"] = m6loReassemblyMessages;
+	vm["6loReassemblyBuffers"] = m6loReassemblyBuffers;
+	vm["Ip6Messages"] = mIp6Messages;
+	vm["Ip6Buffers"] = mIp6Buffers;
+	vm["MplMessages"] = mMplMessages;
+	vm["MplBuffers"] = mMplBuffers;
+	vm["MleMessages"] = mMleMessages;
+	vm["MleBuffers"] = mMleBuffers;
+	vm["ArpMessages"] = mArpMessages;
+	vm["ArpBuffers"] = mArpBuffers;
+	vm["CoapClientMessages"] = mCoapClientMessages;
+	vm["CoapClientBuffers"] = mCoapClientBuffers;
+
+	return vm;
+}
diff --git a/src/ncp-spinel/SpinelNCPTaskGetMsgBufferCounters.h b/src/ncp-spinel/SpinelNCPTaskGetMsgBufferCounters.h
new file mode 100644
index 0000000..addc78d
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskGetMsgBufferCounters.h
@@ -0,0 +1,86 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__SpinelNCPTaskGetMsgBufferCounters__
+#define __wpantund__SpinelNCPTaskGetMsgBufferCounters__
+
+#include <list>
+#include <string>
+#include "ValueMap.h"
+#include "SpinelNCPTask.h"
+#include "SpinelNCPInstance.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+namespace nl {
+namespace wpantund {
+
+class SpinelNCPTaskGetMsgBufferCounters : public SpinelNCPTask
+{
+public:
+	enum ResultFormat
+	{
+		kResultFormat_String,        // Returns the counter info as a std::string (long line with all counters)
+		kResultFormat_StringArray,   // Returns the counter info as an array of std::string(s) (one per counter)
+		kResultFormat_ValueMap,      // Returns the counter info as a ValueMap dictionary.
+	};
+
+	SpinelNCPTaskGetMsgBufferCounters(
+		SpinelNCPInstance* instance,
+		CallbackWithStatusArg1 cb,
+		ResultFormat result_format = kResultFormat_ValueMap
+	);
+	virtual int vprocess_event(int event, va_list args);
+
+private:
+
+	struct MsgBufferCounters
+	{
+		uint16_t mTotalBuffers;           ///< The number of buffers in the pool.
+		uint16_t mFreeBuffers;            ///< The number of free message buffers.
+		uint16_t m6loSendMessages;        ///< The number of messages in the 6lo send queue.
+		uint16_t m6loSendBuffers;         ///< The number of buffers in the 6lo send queue.
+		uint16_t m6loReassemblyMessages;  ///< The number of messages in the 6LoWPAN reassembly queue.
+		uint16_t m6loReassemblyBuffers;   ///< The number of buffers in the 6LoWPAN reassembly queue.
+		uint16_t mIp6Messages;            ///< The number of messages in the IPv6 send queue.
+		uint16_t mIp6Buffers;             ///< The number of buffers in the IPv6 send queue.
+		uint16_t mMplMessages;            ///< The number of messages in the MPL send queue.
+		uint16_t mMplBuffers;             ///< The number of buffers in the MPL send queue.
+		uint16_t mMleMessages;            ///< The number of messages in the MLE send queue.
+		uint16_t mMleBuffers;             ///< The number of buffers in the MLE send queue.
+		uint16_t mArpMessages;            ///< The number of messages in the ARP send queue.
+		uint16_t mArpBuffers;             ///< The number of buffers in the ARP send queue.
+		uint16_t mCoapClientMessages;     ///< The number of messages in the CoAP client send queue.
+		uint16_t mCoapClientBuffers;      ///< The number of buffers in the CoAP client send queue.
+
+		std::string get_as_string(void) const;
+		std::list<std::string> get_as_string_array(void) const;
+		ValueMap get_as_valuemap(void) const;
+	};
+
+	ResultFormat mResultFormat;
+};
+
+
+}; // namespace wpantund
+}; // namespace nl
+
+
+#endif /* defined(__wpantund__SpinelNCPTaskGetMsgBufferCounters__) */
diff --git a/src/ncp-spinel/SpinelNCPTaskGetNetworkTopology.cpp b/src/ncp-spinel/SpinelNCPTaskGetNetworkTopology.cpp
new file mode 100644
index 0000000..44c34b3
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskGetNetworkTopology.cpp
@@ -0,0 +1,389 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include <syslog.h>
+#include <errno.h>
+#include "SpinelNCPTaskGetNetworkTopology.h"
+#include "SpinelNCPInstance.h"
+#include "spinel-extra.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+nl::wpantund::SpinelNCPTaskGetNetworkTopology::SpinelNCPTaskGetNetworkTopology(
+	SpinelNCPInstance* instance,
+	CallbackWithStatusArg1 cb,
+	Type table_type,
+	ResultFormat result_format
+):	SpinelNCPTask(instance, cb), mType(table_type), mTable(), mResultFormat(result_format)
+{
+}
+
+int
+nl::wpantund::SpinelNCPTaskGetNetworkTopology::prase_child_table(const uint8_t *data_in, spinel_size_t data_len,
+															Table& child_table)
+{
+	int ret = kWPANTUNDStatus_Ok;
+
+	child_table.clear();
+
+	while (data_len > 0)
+	{
+		spinel_ssize_t len = 0;
+		TableEntry child_info;
+		const spinel_eui64_t *eui64 = NULL;
+		uint8_t mode;
+
+		memset(&child_info, 0, sizeof(child_info));
+
+		child_info.mType = kChildTable;
+
+		len = spinel_datatype_unpack(
+			data_in,
+			data_len,
+			"T("
+				SPINEL_DATATYPE_EUI64_S         // EUI64 Address
+				SPINEL_DATATYPE_UINT16_S        // Rloc16
+				SPINEL_DATATYPE_UINT32_S        // Timeout
+				SPINEL_DATATYPE_UINT32_S        // Age
+				SPINEL_DATATYPE_UINT8_S         // Network Data Version
+				SPINEL_DATATYPE_UINT8_S         // Link Quality In
+				SPINEL_DATATYPE_INT8_S          // Average RSS
+				SPINEL_DATATYPE_UINT8_S         // Mode (flags)
+			")",
+			&eui64,
+			&child_info.mRloc16,
+			&child_info.mTimeout,
+			&child_info.mAge,
+			&child_info.mNetworkDataVersion,
+			&child_info.mLinkQualityIn,
+			&child_info.mAverageRssi,
+			&mode
+		);
+
+		if (len <= 0)
+		{
+			ret = kWPANTUNDStatus_Failure;
+			break;
+		}
+
+		memcpy(child_info.mExtAddress, eui64, sizeof(child_info.mExtAddress));
+
+		child_info.mRxOnWhenIdle = ((mode & kThreadMode_RxOnWhenIdle) != 0);
+		child_info.mSecureDataRequest = ((mode & kThreadMode_SecureDataRequest) != 0);
+		child_info.mFullFunction = ((mode & kThreadMode_FullFunctionDevice) != 0);
+		child_info.mFullNetworkData = ((mode & kThreadMode_FullNetworkData) != 0);
+
+		child_table.push_back(child_info);
+
+		data_in += len;
+		data_len -= len;
+	}
+
+	return ret;
+}
+
+int
+nl::wpantund::SpinelNCPTaskGetNetworkTopology::prase_neighbor_table(const uint8_t *data_in, spinel_size_t data_len,
+																			 Table& neighbor_table)
+{
+	int ret = kWPANTUNDStatus_Ok;
+
+	neighbor_table.clear();
+
+	while (data_len > 0)
+	{
+		spinel_ssize_t len = 0;
+		TableEntry neighbor_info;
+		const spinel_eui64_t *eui64 = NULL;
+		uint8_t mode;
+		bool is_child = false;
+
+		memset(&neighbor_info, 0, sizeof(neighbor_info));
+
+		neighbor_info.mType = kNeighborTable;
+
+		len = spinel_datatype_unpack(
+			data_in,
+			data_len,
+			"T("
+				SPINEL_DATATYPE_EUI64_S         // EUI64 Address
+				SPINEL_DATATYPE_UINT16_S        // Rloc16
+				SPINEL_DATATYPE_UINT32_S        // Age
+				SPINEL_DATATYPE_UINT8_S         // Link Quality In
+				SPINEL_DATATYPE_INT8_S          // Average RSS
+				SPINEL_DATATYPE_UINT8_S         // Mode (flags)
+				SPINEL_DATATYPE_BOOL_S          // Is Child
+				SPINEL_DATATYPE_UINT32_S        // Link Frame Counter
+				SPINEL_DATATYPE_UINT32_S        // MLE Frame Counter
+			")",
+			&eui64,
+			&neighbor_info.mRloc16,
+			&neighbor_info.mAge,
+			&neighbor_info.mLinkQualityIn,
+			&neighbor_info.mAverageRssi,
+			&mode,
+			&is_child,
+			&neighbor_info.mLinkFrameCounter,
+			&neighbor_info.mMleFrameCounter
+		);
+
+		if (len <= 0)
+		{
+			ret = kWPANTUNDStatus_Failure;
+			break;
+		}
+
+		memcpy(neighbor_info.mExtAddress, eui64, sizeof(neighbor_info.mExtAddress));
+
+		neighbor_info.mRxOnWhenIdle = ((mode & kThreadMode_RxOnWhenIdle) != 0);
+		neighbor_info.mSecureDataRequest = ((mode & kThreadMode_SecureDataRequest) != 0);
+		neighbor_info.mFullFunction = ((mode & kThreadMode_FullFunctionDevice) != 0);
+		neighbor_info.mFullNetworkData = ((mode & kThreadMode_FullNetworkData) != 0);
+		neighbor_info.mIsChild = is_child;
+
+		neighbor_table.push_back(neighbor_info);
+
+		data_in += len;
+		data_len -= len;
+	}
+
+	return ret;
+}
+
+int
+nl::wpantund::SpinelNCPTaskGetNetworkTopology::vprocess_event(int event, va_list args)
+{
+	int ret = kWPANTUNDStatus_Failure;
+	unsigned int prop_key;
+	const uint8_t *data_in;
+	spinel_size_t data_len;
+
+	EH_BEGIN();
+
+	if (!mInstance->mEnabled) {
+		ret = kWPANTUNDStatus_InvalidWhenDisabled;
+		finish(ret);
+		EH_EXIT();
+	}
+
+	if (mInstance->get_ncp_state() == UPGRADING) {
+		ret = kWPANTUNDStatus_InvalidForCurrentState;
+		finish(ret);
+		EH_EXIT();
+	}
+
+	// Wait for a bit to see if the NCP will enter the right state.
+	EH_REQUIRE_WITHIN(
+		NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT,
+		!ncp_state_is_initializing(mInstance->get_ncp_state()),
+		on_error
+	);
+
+	// The first event to a task is EVENT_STARTING_TASK. The following
+	// line makes sure that we don't start processing this task
+	// until it is properly scheduled. All tasks immediately receive
+	// the initial `EVENT_STARTING_TASK` event, but further events
+	// will only be received by that task once it is that task's turn
+	// to execute.
+	EH_WAIT_UNTIL(EVENT_STARTING_TASK != event);
+
+	mNextCommand = SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_GET,
+		(mType == kChildTable) ? SPINEL_PROP_THREAD_CHILD_TABLE : SPINEL_PROP_THREAD_NEIGHBOR_TABLE
+	);
+
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+	ret = mNextCommandRet;
+
+	require_noerr(ret, on_error);
+
+	require(EVENT_NCP_PROP_VALUE_IS == event, on_error);
+
+	prop_key = va_arg(args, unsigned int);
+	data_in = va_arg(args, const uint8_t*);
+	data_len = va_arg_small(args, spinel_size_t);
+
+	if (mType == kChildTable) {
+		require(prop_key == SPINEL_PROP_THREAD_CHILD_TABLE, on_error);
+		prase_child_table(data_in, data_len, mTable);
+	} else {
+		require(prop_key == SPINEL_PROP_THREAD_NEIGHBOR_TABLE, on_error);
+		prase_neighbor_table(data_in, data_len, mTable);
+	}
+
+	ret = kWPANTUNDStatus_Ok;
+
+	if (mResultFormat == kResultFormat_StringArray)
+	{
+		std::list<std::string> result;
+		Table::iterator it;
+
+		for (it = mTable.begin(); it != mTable.end(); it++)
+		{
+			result.push_back(it->get_as_string());
+		}
+
+		finish(ret, result);
+	}
+	else if (mResultFormat == kResultFormat_ValueMapArray)
+	{
+		std::list<ValueMap> result;
+		Table::iterator it;
+
+		for (it = mTable.begin(); it != mTable.end(); it++)
+		{
+			result.push_back(it->get_as_valuemap());
+		}
+
+		finish(ret, result);
+	}
+	else
+	{
+		finish(ret);
+	}
+
+	mTable.clear();
+
+	EH_EXIT();
+
+on_error:
+
+	if (ret == kWPANTUNDStatus_Ok) {
+		ret = kWPANTUNDStatus_Failure;
+	}
+
+	syslog(LOG_ERR, "Getting child/neighbor table failed: %d", ret);
+
+	finish(ret);
+
+	mTable.clear();
+
+	EH_END();
+}
+
+std::string
+SpinelNCPTaskGetNetworkTopology::TableEntry::get_as_string(void) const
+{
+	char c_string[800];
+
+	if (mType == kChildTable) {
+		snprintf(c_string, sizeof(c_string),
+			 "%02X%02X%02X%02X%02X%02X%02X%02X, "
+			 kWPANTUNDValueMapKey_NetworkTopology_RLOC16              ": %04x, "
+			 kWPANTUNDValueMapKey_NetworkTopology_NetworkDataVersion  ": %-3d, "
+			 kWPANTUNDValueMapKey_NetworkTopology_LinkQualityIn       ": %-2d, "
+			 kWPANTUNDValueMapKey_NetworkTopology_AverageRssi         ": %-3d, "
+			 kWPANTUNDValueMapKey_NetworkTopology_Timeout             ": %-5u, "
+			 kWPANTUNDValueMapKey_NetworkTopology_Age                 ": %-5u, "
+			 kWPANTUNDValueMapKey_NetworkTopology_RxOnWhenIdle        ": %s, "
+			 kWPANTUNDValueMapKey_NetworkTopology_FullFunction        ": %s, "
+			 kWPANTUNDValueMapKey_NetworkTopology_SecureDataRequest   ": %s, "
+			 kWPANTUNDValueMapKey_NetworkTopology_FullNetworkData     ": %s",
+			mExtAddress[0], mExtAddress[1], mExtAddress[2], mExtAddress[3],
+			mExtAddress[4], mExtAddress[5], mExtAddress[6], mExtAddress[7],
+			mRloc16,
+			mNetworkDataVersion,
+			mLinkQualityIn,
+			mAverageRssi,
+			mTimeout,
+			mAge,
+			mRxOnWhenIdle ? "yes" : "no",
+			mFullFunction ? "yes" : "no",
+			mSecureDataRequest ? "yes" : "no",
+			mFullNetworkData ? "yes" : "no"
+		);
+
+	} else {
+		snprintf(c_string, sizeof(c_string),
+			 "%02X%02X%02X%02X%02X%02X%02X%02X, "
+			 kWPANTUNDValueMapKey_NetworkTopology_RLOC16             ": %04x, "
+			 kWPANTUNDValueMapKey_NetworkTopology_LinkQualityIn      ": %-2d, "
+			 kWPANTUNDValueMapKey_NetworkTopology_AverageRssi        ": %-3d, "
+			 kWPANTUNDValueMapKey_NetworkTopology_Age                ": %-5u, "
+			 kWPANTUNDValueMapKey_NetworkTopology_LinkFrameCounter   ": %-5u, "
+			 kWPANTUNDValueMapKey_NetworkTopology_MleFrameCounter    ": %-5u, "
+			 kWPANTUNDValueMapKey_NetworkTopology_IsChild            ": %s, "
+			 kWPANTUNDValueMapKey_NetworkTopology_RxOnWhenIdle       ": %s, "
+			 kWPANTUNDValueMapKey_NetworkTopology_FullFunction       ": %s, "
+			 kWPANTUNDValueMapKey_NetworkTopology_SecureDataRequest  ": %s, "
+			 kWPANTUNDValueMapKey_NetworkTopology_FullNetworkData    ": %s",
+			mExtAddress[0], mExtAddress[1], mExtAddress[2], mExtAddress[3],
+			mExtAddress[4], mExtAddress[5], mExtAddress[6], mExtAddress[7],
+			mRloc16,
+			mLinkQualityIn,
+			mAverageRssi,
+			mAge,
+			mLinkFrameCounter,
+			mMleFrameCounter,
+			mIsChild ? "yes" : "no",
+			mRxOnWhenIdle ? "yes" : "no",
+			mFullFunction ? "yes" : "no",
+			mSecureDataRequest ? "yes" : "no",
+			mFullNetworkData ? "yes" : "no"
+		);
+	}
+
+	return std::string(c_string);
+}
+
+ValueMap
+SpinelNCPTaskGetNetworkTopology::TableEntry::get_as_valuemap(void) const
+{
+    ValueMap entryMap;
+    uint64_t addr;
+    
+    addr  = (uint64_t) mExtAddress[7];
+    addr |= (uint64_t) mExtAddress[6] << 8;
+    addr |= (uint64_t) mExtAddress[5] << 16;
+    addr |= (uint64_t) mExtAddress[4] << 24;
+    addr |= (uint64_t) mExtAddress[3] << 32;
+    addr |= (uint64_t) mExtAddress[2] << 40;
+    addr |= (uint64_t) mExtAddress[1] << 48;
+    addr |= (uint64_t) mExtAddress[0] << 56;
+
+#define SPINEL_TOPO_MAP_INSERT(KEY, VAL) entryMap.insert( std::pair<std::string, boost::any>( KEY, VAL ) )
+    
+    SPINEL_TOPO_MAP_INSERT( kWPANTUNDValueMapKey_NetworkTopology_ExtAddress,         addr               );
+    SPINEL_TOPO_MAP_INSERT( kWPANTUNDValueMapKey_NetworkTopology_RLOC16,             mRloc16            );
+    SPINEL_TOPO_MAP_INSERT( kWPANTUNDValueMapKey_NetworkTopology_LinkQualityIn,      mLinkQualityIn     );
+    SPINEL_TOPO_MAP_INSERT( kWPANTUNDValueMapKey_NetworkTopology_AverageRssi,        mAverageRssi       );
+    SPINEL_TOPO_MAP_INSERT( kWPANTUNDValueMapKey_NetworkTopology_Age,                mAge               );
+    SPINEL_TOPO_MAP_INSERT( kWPANTUNDValueMapKey_NetworkTopology_RxOnWhenIdle,       mRxOnWhenIdle      );
+    SPINEL_TOPO_MAP_INSERT( kWPANTUNDValueMapKey_NetworkTopology_FullFunction,       mFullFunction      );
+    SPINEL_TOPO_MAP_INSERT( kWPANTUNDValueMapKey_NetworkTopology_SecureDataRequest,  mSecureDataRequest );
+    SPINEL_TOPO_MAP_INSERT( kWPANTUNDValueMapKey_NetworkTopology_FullNetworkData,    mFullNetworkData   );
+
+    if (mType == kChildTable) {
+	SPINEL_TOPO_MAP_INSERT( kWPANTUNDValueMapKey_NetworkTopology_Timeout,            mTimeout            );
+	SPINEL_TOPO_MAP_INSERT( kWPANTUNDValueMapKey_NetworkTopology_NetworkDataVersion, mNetworkDataVersion );
+    } else {    
+	SPINEL_TOPO_MAP_INSERT( kWPANTUNDValueMapKey_NetworkTopology_LinkFrameCounter, mLinkFrameCounter );
+	SPINEL_TOPO_MAP_INSERT( kWPANTUNDValueMapKey_NetworkTopology_MleFrameCounter,  mMleFrameCounter  );
+	SPINEL_TOPO_MAP_INSERT( kWPANTUNDValueMapKey_NetworkTopology_IsChild,          mIsChild          );
+    }
+    
+    return entryMap;
+}
diff --git a/src/ncp-spinel/SpinelNCPTaskGetNetworkTopology.h b/src/ncp-spinel/SpinelNCPTaskGetNetworkTopology.h
new file mode 100644
index 0000000..bdab0cd
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskGetNetworkTopology.h
@@ -0,0 +1,117 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__SpinelNCPTaskGetNetworkTopology__
+#define __wpantund__SpinelNCPTaskGetNetworkTopology__
+
+#include <list>
+#include <string>
+#include "ValueMap.h"
+#include "SpinelNCPTask.h"
+#include "SpinelNCPInstance.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+namespace nl {
+namespace wpantund {
+
+class SpinelNCPTaskGetNetworkTopology : public SpinelNCPTask
+{
+public:
+
+	enum Type
+	{
+		kChildTable,                   // Get the child table
+		kNeighborTable                 // Get the neighbor table
+	};
+
+	enum ResultFormat
+	{
+		kResultFormat_StringArray,     // Returns the child/neighbor table as an array of std::string(s) (one per child).
+		kResultFormat_ValueMapArray,   // Returns the child/neighbor table as an array of ValueMap dictionary.
+	};
+
+	enum
+	{
+		kThreadMode_RxOnWhenIdle        = (1 << 3),
+		kThreadMode_SecureDataRequest   = (1 << 2),
+		kThreadMode_FullFunctionDevice  = (1 << 1),
+		kThreadMode_FullNetworkData     = (1 << 0),
+	};
+
+	// This struct defines a common table entry to store either a child info or a neighbor info
+	struct TableEntry
+	{
+		Type      mType;     // Indicates if this entry is for a child or a neighbor
+
+		// Common fields for both child info and neighbor info
+		uint8_t   mExtAddress[8];
+		uint32_t  mAge;
+		uint16_t  mRloc16;
+		uint8_t   mLinkQualityIn;
+		int8_t    mAverageRssi;
+		bool      mRxOnWhenIdle : 1;
+		bool      mSecureDataRequest : 1;
+		bool      mFullFunction : 1;
+		bool      mFullNetworkData : 1;
+
+		// Child info only
+		uint32_t  mTimeout;
+		uint8_t   mNetworkDataVersion;
+
+		// Neighbor info only
+		uint32_t  mLinkFrameCounter;
+		uint32_t  mMleFrameCounter;
+		bool      mIsChild : 1;
+
+	public:
+		std::string get_as_string(void) const;
+		ValueMap get_as_valuemap(void) const;
+	};
+
+	typedef std::list<TableEntry> Table;
+
+public:
+	SpinelNCPTaskGetNetworkTopology(
+		SpinelNCPInstance *instance,
+		CallbackWithStatusArg1 cb,
+		Type table_type = kChildTable,
+		ResultFormat result_format = kResultFormat_StringArray
+	);
+	virtual int vprocess_event(int event, va_list args);
+
+	// Parses the spinel child table property and updates the child_table
+	static int prase_child_table(const uint8_t *data_in, spinel_size_t data_len, Table& child_table);
+
+	// Parses the spinel neighbor table property and updates the neighbor_table
+	static int prase_neighbor_table(const uint8_t *data_in, spinel_size_t data_len, Table& neighbor_table);
+
+private:
+	Type mType;
+	Table mTable;
+	ResultFormat mResultFormat;
+};
+
+
+}; // namespace wpantund
+}; // namespace nl
+
+
+#endif /* defined(__wpantund__SpinelNCPTaskGetNetworkTopology__) */
diff --git a/src/ncp-spinel/SpinelNCPTaskJoin.cpp b/src/ncp-spinel/SpinelNCPTaskJoin.cpp
new file mode 100644
index 0000000..98c3902
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskJoin.cpp
@@ -0,0 +1,371 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include <syslog.h>
+#include <errno.h>
+#include "SpinelNCPTaskJoin.h"
+#include "SpinelNCPInstance.h"
+#include "any-to.h"
+#include "spinel-extra.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+nl::wpantund::SpinelNCPTaskJoin::SpinelNCPTaskJoin(
+	SpinelNCPInstance* instance,
+	CallbackWithStatusArg1 cb,
+	const ValueMap& options
+):	SpinelNCPTask(instance, cb), mOptions(options), mLastState(instance->get_ncp_state())
+{
+}
+
+void
+nl::wpantund::SpinelNCPTaskJoin::finish(int status, const boost::any& value)
+{
+	SpinelNCPTask::finish(status, value);
+	if ( (status != kWPANTUNDStatus_InProgress)
+	  && !ncp_state_is_associated(mInstance->get_ncp_state())
+	) {
+		mInstance->change_ncp_state(mLastState);
+	}
+}
+
+int
+nl::wpantund::SpinelNCPTaskJoin::vprocess_event(int event, va_list args)
+{
+	int ret = kWPANTUNDStatus_Failure;
+	int last_status = peek_ncp_callback_status(event, args);
+
+	EH_BEGIN();
+
+
+	if (!mInstance->mEnabled) {
+		ret = kWPANTUNDStatus_InvalidWhenDisabled;
+		finish(ret);
+		EH_EXIT();
+	}
+
+	if (mInstance->get_ncp_state() == UPGRADING) {
+		ret = kWPANTUNDStatus_InvalidForCurrentState;
+		finish(ret);
+		EH_EXIT();
+	}
+
+	// Wait for a bit to see if the NCP will enter the right state.
+	EH_REQUIRE_WITHIN(
+		NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT,
+		!ncp_state_is_initializing(mInstance->get_ncp_state()),
+		on_error
+	);
+
+	if (ncp_state_is_associated(mInstance->get_ncp_state())) {
+		ret = kWPANTUNDStatus_Already;
+		finish(ret);
+		EH_EXIT();
+	}
+
+	// The first event to a task is EVENT_STARTING_TASK. The following
+	// line makes sure that we don't start processing this task
+	// until it is properly scheduled. All tasks immediately receive
+	// the initial `EVENT_STARTING_TASK` event, but further events
+	// will only be received by that task once it is that task's turn
+	// to execute.
+	EH_WAIT_UNTIL(EVENT_STARTING_TASK != event);
+
+	// Clear any previously saved network settings
+	mNextCommand = SpinelPackData(SPINEL_FRAME_PACK_CMD_NET_CLEAR);
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+	ret = mNextCommandRet;
+	require_noerr(ret, on_error);
+
+
+	mLastState = mInstance->get_ncp_state();
+	mInstance->change_ncp_state(ASSOCIATING);
+
+	if (mOptions.count(kWPANTUNDProperty_NetworkNodeType)) {
+		NodeType node_type;
+		bool isRouterRoleEnabled;
+
+		node_type = string_to_node_type(any_to_string(mOptions[kWPANTUNDProperty_NetworkNodeType]));
+
+		if ((node_type == ROUTER) || (node_type == LEADER)) {
+			if (!mInstance->mCapabilities.count(SPINEL_CAP_ROLE_ROUTER)) {
+				// We cannot join as a router/leader unless we are router-capable
+				ret = kWPANTUNDStatus_FeatureNotSupported;
+				goto on_error;
+			}
+			isRouterRoleEnabled = true;
+
+		} else if (node_type == END_DEVICE) {
+			isRouterRoleEnabled = false;
+
+		} else if (node_type == SLEEPY_END_DEVICE) {
+			if (!mInstance->mCapabilities.count(SPINEL_CAP_ROLE_SLEEPY)) {
+				ret = kWPANTUNDStatus_FeatureNotSupported;
+				goto on_error;
+			}
+			isRouterRoleEnabled = false;
+
+		} else if (node_type == LURKER) {
+			if (!mInstance->mCapabilities.count(SPINEL_CAP_NEST_LEGACY_INTERFACE)) {
+				ret = kWPANTUNDStatus_FeatureNotSupported;
+				goto on_error;
+			}
+			isRouterRoleEnabled = true;
+
+		} else {
+			ret = kWPANTUNDStatus_InvalidArgument;
+			goto on_error;
+		}
+
+		mNextCommand = SpinelPackData(
+			SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S),
+			SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED,
+			isRouterRoleEnabled
+		);
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		ret = mNextCommandRet;
+
+		require_noerr(ret, on_error);
+	}
+
+	// Turn off promiscuous mode, if it happens to be on
+	mNextCommand = SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT8_S),
+		SPINEL_PROP_MAC_PROMISCUOUS_MODE,
+		SPINEL_MAC_PROMISCUOUS_MODE_OFF
+	);
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+	ret = mNextCommandRet;
+	check_noerr(ret);
+
+	if (mOptions.count(kWPANTUNDProperty_NCPChannel)) {
+		mNextCommand = SpinelPackData(
+			SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT8_S),
+			SPINEL_PROP_PHY_CHAN,
+			any_to_int(mOptions[kWPANTUNDProperty_NCPChannel])
+		);
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		ret = mNextCommandRet;
+
+		require_noerr(ret, on_error);
+
+	}
+
+	if (mOptions.count(kWPANTUNDProperty_NetworkPANID)) {
+		mNextCommand = SpinelPackData(
+			SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT16_S),
+			SPINEL_PROP_MAC_15_4_PANID,
+			any_to_int(mOptions[kWPANTUNDProperty_NetworkPANID])
+		);
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		ret = mNextCommandRet;
+
+		require_noerr(ret, on_error);
+	}
+
+	if (mOptions.count(kWPANTUNDProperty_NetworkXPANID)) {
+		{
+			uint64_t xpanid(any_to_uint64((mOptions[kWPANTUNDProperty_NetworkXPANID])));
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+			reverse_bytes(reinterpret_cast<uint8_t*>(&xpanid), sizeof(xpanid));
+#endif
+
+			mNextCommand = SpinelPackData(
+				SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_DATA_S),
+				SPINEL_PROP_NET_XPANID,
+				&xpanid,
+				sizeof(xpanid)
+			);
+		}
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		ret = mNextCommandRet;
+
+		require_noerr(ret, on_error);
+	}
+
+	if (mOptions.count(kWPANTUNDProperty_NetworkName)) {
+		mNextCommand = SpinelPackData(
+			SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UTF8_S),
+			SPINEL_PROP_NET_NETWORK_NAME,
+			any_to_string(mOptions[kWPANTUNDProperty_NetworkName]).c_str()
+		);
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		ret = mNextCommandRet;
+
+		require_noerr(ret, on_error);
+	}
+
+	if (mOptions.count(kWPANTUNDProperty_NetworkKey)) {
+		{
+			nl::Data data(any_to_data(mOptions[kWPANTUNDProperty_NetworkKey]));
+			mNextCommand = SpinelPackData(
+				SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_DATA_S),
+				SPINEL_PROP_NET_MASTER_KEY,
+				data.data(),
+				data.size()
+			);
+		}
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		ret = mNextCommandRet;
+
+		require_noerr(ret, on_error);
+	}
+
+	if (mOptions.count(kWPANTUNDProperty_NetworkKeyIndex)) {
+		mNextCommand = SpinelPackData(
+			SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT32_S),
+			SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER,
+			any_to_int(mOptions[kWPANTUNDProperty_NetworkKeyIndex])
+		);
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		ret = mNextCommandRet;
+
+		require_noerr(ret, on_error);
+	}
+
+	if (mOptions.count(kWPANTUNDProperty_IPv6MeshLocalAddress)) {
+		{
+			struct in6_addr addr = any_to_ipv6(mOptions[kWPANTUNDProperty_IPv6MeshLocalAddress]);
+			mNextCommand = SpinelPackData(
+				SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_IPv6ADDR_S SPINEL_DATATYPE_UINT8_S),
+				SPINEL_PROP_IPV6_ML_PREFIX,
+				&addr,
+				64
+			);
+		}
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		ret = mNextCommandRet;
+
+		require_noerr(ret, on_error);
+	} else if (mOptions.count(kWPANTUNDProperty_IPv6MeshLocalPrefix)) {
+		{
+			struct in6_addr addr = any_to_ipv6(mOptions[kWPANTUNDProperty_IPv6MeshLocalPrefix]);
+			mNextCommand = SpinelPackData(
+				SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_IPv6ADDR_S SPINEL_DATATYPE_UINT8_S),
+				SPINEL_PROP_IPV6_ML_PREFIX,
+				&addr,
+				64
+			);
+		}
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		ret = mNextCommandRet;
+
+		require_noerr(ret, on_error);
+	}
+
+
+	// Now bring up the network by bringing up the interface and the stack.
+
+	mNextCommand = SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S),
+		SPINEL_PROP_NET_IF_UP,
+		true
+	);
+
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+	ret = mNextCommandRet;
+
+	require((ret == kWPANTUNDStatus_Ok) || (ret == kWPANTUNDStatus_Already), on_error);
+
+	mNextCommand = SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S),
+		SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING,
+		true
+	);
+
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+	ret = mNextCommandRet;
+
+	check_noerr(ret);
+
+	mNextCommand = SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S),
+		SPINEL_PROP_NET_STACK_UP,
+		true
+	);
+
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+	ret = mNextCommandRet;
+
+	require_noerr(ret, on_error);
+
+	EH_REQUIRE_WITHIN(
+		NCP_JOIN_TIMEOUT,
+		((last_status >= SPINEL_STATUS_JOIN__BEGIN) && (last_status < SPINEL_STATUS_JOIN__END))
+		|| ncp_state_is_associated(mInstance->get_ncp_state()),
+		on_error
+	);
+
+	ret = last_status
+		? WPANTUND_NCPERROR_TO_STATUS(last_status)
+		: kWPANTUNDStatus_Ok;
+
+	if ( (last_status == SPINEL_STATUS_JOIN_SECURITY)
+	  || (last_status == SPINEL_STATUS_JOIN_FAILURE)
+	) {
+		mInstance->change_ncp_state(CREDENTIALS_NEEDED);
+		ret = kWPANTUNDStatus_InProgress;
+	} else if ((last_status >= SPINEL_STATUS_JOIN__BEGIN) && (last_status < SPINEL_STATUS_JOIN__END)) {
+		ret = kWPANTUNDStatus_JoinFailedUnknown;
+	}
+
+	finish(ret);
+
+	EH_EXIT();
+
+on_error:
+
+	if (ret == kWPANTUNDStatus_Ok) {
+		ret = kWPANTUNDStatus_Failure;
+	}
+
+	syslog(LOG_ERR, "Join failed: %d", ret);
+
+	finish(ret);
+
+	EH_END();
+}
diff --git a/src/ncp-spinel/SpinelNCPTaskJoin.h b/src/ncp-spinel/SpinelNCPTaskJoin.h
new file mode 100644
index 0000000..e5534f4
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskJoin.h
@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__SpinelNCPTaskJoin__
+#define __wpantund__SpinelNCPTaskJoin__
+
+#include "SpinelNCPTask.h"
+#include "SpinelNCPInstance.h"
+#include "ValueMap.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+namespace nl {
+namespace wpantund {
+
+class SpinelNCPTaskJoin : public SpinelNCPTask
+{
+public:
+	SpinelNCPTaskJoin(
+		SpinelNCPInstance* instance,
+		CallbackWithStatusArg1 cb,
+		const ValueMap& options
+	);
+	virtual int vprocess_event(int event, va_list args);
+	virtual void finish(int status, const boost::any& value = boost::any());
+
+
+private:
+	ValueMap mOptions;
+	NCPState mLastState;
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+
+#endif /* defined(__wpantund__SpinelNCPTaskJoin__) */
diff --git a/src/ncp-spinel/SpinelNCPTaskLeave.cpp b/src/ncp-spinel/SpinelNCPTaskLeave.cpp
new file mode 100644
index 0000000..d9ec8ad
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskLeave.cpp
@@ -0,0 +1,144 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include <syslog.h>
+#include <errno.h>
+#include "SpinelNCPTaskLeave.h"
+#include "SpinelNCPInstance.h"
+#include "spinel-extra.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+nl::wpantund::SpinelNCPTaskLeave::SpinelNCPTaskLeave(
+	SpinelNCPInstance* instance,
+	CallbackWithStatusArg1 cb
+):	SpinelNCPTask(instance, cb)
+{
+}
+
+int
+nl::wpantund::SpinelNCPTaskLeave::vprocess_event(int event, va_list args)
+{
+	int ret = kWPANTUNDStatus_Failure;
+
+	EH_BEGIN();
+
+	if (!mInstance->mEnabled) {
+		ret = kWPANTUNDStatus_InvalidWhenDisabled;
+		finish(ret);
+		EH_EXIT();
+	}
+
+	if (mInstance->get_ncp_state() == UPGRADING) {
+		ret = kWPANTUNDStatus_InvalidForCurrentState;
+		finish(ret);
+		EH_EXIT();
+	}
+
+	// Wait for a bit to see if the NCP will enter the right state.
+	EH_REQUIRE_WITHIN(
+		NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT,
+		!ncp_state_is_initializing(mInstance->get_ncp_state()),
+		on_error
+	);
+
+	// The first event to a task is EVENT_STARTING_TASK. The following
+	// line makes sure that we don't start processing this task
+	// until it is properly scheduled. All tasks immediately receive
+	// the initial `EVENT_STARTING_TASK` event, but further events
+	// will only be received by that task once it is that task's turn
+	// to execute.
+	EH_WAIT_UNTIL(EVENT_STARTING_TASK != event);
+
+	mNextCommand = SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S),
+		SPINEL_PROP_NET_STACK_UP,
+		false
+	);
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+	ret = mNextCommandRet;
+	require_noerr(ret, on_error);
+
+	mNextCommand = SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S),
+		SPINEL_PROP_NET_IF_UP,
+		false
+	);
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+	ret = mNextCommandRet;
+	require_noerr(ret, on_error);
+
+	// Clear any saved network settings.
+	mNextCommand = SpinelPackData(SPINEL_FRAME_PACK_CMD_NET_CLEAR);
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+	ret = mNextCommandRet;
+	require_noerr(ret, on_error);
+
+	mInstance->mNetworkKey = Data();
+	mInstance->mNetworkKeyIndex = 0;
+
+	// Issue a Reset
+	mNextCommand = SpinelPackData(SPINEL_FRAME_PACK_CMD_RESET);
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+	ret = mNextCommandRet;
+	require_noerr(ret, on_error);
+
+	// Wait for re-initialization of NCP to start.
+	EH_REQUIRE_WITHIN(
+		NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT,
+		ncp_state_is_initializing(mInstance->get_ncp_state()),
+		on_error
+	);
+
+	// Wait for re-initialization to complete.
+	EH_REQUIRE_WITHIN(
+		NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT,
+		!ncp_state_is_initializing(mInstance->get_ncp_state()) &&
+		(mInstance->mDriverState == SpinelNCPInstance::NORMAL_OPERATION),
+		on_error
+	);
+
+	ret = kWPANTUNDStatus_Ok;
+
+	syslog(LOG_INFO, "Leave succeeded");
+
+	finish(ret);
+
+	EH_EXIT();
+
+on_error:
+
+	if (ret == kWPANTUNDStatus_Ok) {
+		ret = kWPANTUNDStatus_Failure;
+	}
+
+	syslog(LOG_ERR, "Leave failed: %d", ret);
+
+	mInstance->reinitialize_ncp();
+
+	finish(ret);
+
+	EH_END();
+}
diff --git a/src/ncp-spinel/SpinelNCPTaskLeave.h b/src/ncp-spinel/SpinelNCPTaskLeave.h
new file mode 100644
index 0000000..964b373
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskLeave.h
@@ -0,0 +1,46 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__SpinelNCPTaskLeave__
+#define __wpantund__SpinelNCPTaskLeave__
+
+#include "SpinelNCPTask.h"
+#include "SpinelNCPInstance.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+namespace nl {
+namespace wpantund {
+
+class SpinelNCPTaskLeave : public SpinelNCPTask
+{
+public:
+	SpinelNCPTaskLeave(
+		SpinelNCPInstance* instance,
+		CallbackWithStatusArg1 cb
+	);
+	virtual int vprocess_event(int event, va_list args);
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+
+#endif /* defined(__wpantund__SpinelNCPTaskLeave__) */
diff --git a/src/ncp-spinel/SpinelNCPTaskScan.cpp b/src/ncp-spinel/SpinelNCPTaskScan.cpp
new file mode 100644
index 0000000..e726d06
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskScan.cpp
@@ -0,0 +1,239 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include <syslog.h>
+#include <errno.h>
+#include "SpinelNCPTaskScan.h"
+#include "SpinelNCPInstance.h"
+#include "spinel-extra.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+nl::wpantund::SpinelNCPTaskScan::SpinelNCPTaskScan(
+	SpinelNCPInstance* instance,
+	CallbackWithStatusArg1 cb,
+	uint32_t channel_mask,
+	uint16_t scan_period,
+	ScanType scan_type
+):	SpinelNCPTask(instance, cb), mChannelMaskLen(0), mScanPeriod(scan_period), mScanType(scan_type)
+{
+	uint8_t i;
+
+	for (i = 0; i < 32; i++) {
+		if (channel_mask & (1<<i)) {
+			mChannelMaskData[mChannelMaskLen++] = i;
+		}
+	}
+}
+
+void
+nl::wpantund::SpinelNCPTaskScan::finish(int status, const boost::any& value)
+{
+	SpinelNCPTask::finish(status, value);
+}
+
+
+int
+nl::wpantund::SpinelNCPTaskScan::vprocess_event(int event, va_list args)
+{
+	int ret = 0;
+
+	EH_BEGIN();
+
+
+	if (!mInstance->mEnabled) {
+		ret = kWPANTUNDStatus_InvalidWhenDisabled;
+		finish(ret);
+		EH_EXIT();
+	}
+
+	if (mInstance->get_ncp_state() == UPGRADING) {
+		ret = kWPANTUNDStatus_InvalidForCurrentState;
+		finish(ret);
+		EH_EXIT();
+	}
+
+	// Wait for a bit to see if the NCP will enter the right state.
+	EH_REQUIRE_WITHIN(
+		NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT,
+		!ncp_state_is_initializing(mInstance->get_ncp_state())
+		&& (mInstance->get_ncp_state() != ASSOCIATING)
+		&& (mInstance->get_ncp_state() != CREDENTIALS_NEEDED),
+		on_error
+	);
+
+	// The first event to a task is EVENT_STARTING_TASK. The following
+	// line makes sure that we don't start processing this task
+	// until it is properly scheduled. All tasks immediately receive
+	// the initial `EVENT_STARTING_TASK` event, but further events
+	// will only be received by that task once it is that task's turn
+	// to execute.
+	EH_WAIT_UNTIL(EVENT_STARTING_TASK != event);
+
+
+	// Set channel mask
+	mNextCommand = SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_DATA_S),
+		SPINEL_PROP_MAC_SCAN_MASK,
+		mChannelMaskData,
+		mChannelMaskLen
+	);
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+	ret = mNextCommandRet;
+	require_noerr(ret, on_error);
+
+
+	// Set delay period
+	mNextCommand = SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT16_S),
+		SPINEL_PROP_MAC_SCAN_PERIOD,
+		mScanPeriod
+	);
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+	ret = mNextCommandRet;
+	require_noerr(ret, on_error);
+
+
+	// Start the scan.
+	mNextCommand = SpinelPackData(
+		SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT8_S),
+		SPINEL_PROP_MAC_SCAN_STATE,
+		(mScanType == kScanTypeNet) ? SPINEL_SCAN_STATE_BEACON : SPINEL_SCAN_STATE_ENERGY
+	);
+	EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+	ret = mNextCommandRet;
+	require_noerr(ret, on_error);
+
+	do {
+		EH_REQUIRE_WITHIN(
+			15,
+			event == EVENT_NCP_PROP_VALUE_IS
+			|| event == EVENT_NCP_PROP_VALUE_INSERTED,
+			on_error
+		);
+
+		spinel_prop_key_t prop_key = va_arg_small(args, spinel_prop_key_t);
+		const uint8_t* data_ptr = va_arg(args, const uint8_t*);
+		spinel_size_t data_len = va_arg(args, spinel_size_t);
+
+		if ((prop_key == SPINEL_PROP_MAC_SCAN_BEACON) && (mScanType == kScanTypeNet)) {
+			const spinel_eui64_t* laddr = NULL;
+			const char* networkid = "";
+			const uint8_t* xpanid = NULL;
+			unsigned int xpanid_len = 0;
+			unsigned int proto = 0;
+			uint16_t panid = 0xFFFF;
+			uint16_t saddr = 0xFFFF;
+			uint8_t chan = 0;
+			uint8_t lqi = 0x00;
+			int8_t rssi = 0x00;
+			uint8_t flags = 0x00;
+
+			syslog(LOG_DEBUG, "Got a beacon");
+
+			spinel_datatype_unpack(
+				data_ptr,
+				data_len,
+				"CcT(ESSC.)T(iCUD.).",
+				&chan,
+				&rssi,
+
+				&laddr,
+				&saddr,
+				&panid,
+				&lqi,
+
+				&proto,
+				&flags,
+				&networkid,
+				&xpanid, &xpanid_len
+			);
+
+			if ((xpanid_len != 8) && (xpanid_len != 0)) {
+				break;
+			}
+
+			WPAN::NetworkInstance network(
+				networkid,
+				xpanid,
+				panid,
+				chan,
+				(flags & SPINEL_BEACON_THREAD_FLAG_JOINABLE)
+			);
+			network.rssi = rssi;
+			network.type = proto;
+			network.lqi = lqi;
+			network.saddr = saddr;
+
+			if (laddr) {
+				memcpy(network.hwaddr, laddr, sizeof(network.hwaddr));
+			}
+
+			mInstance->get_control_interface().mOnNetScanBeacon(network);
+
+		} else if ((prop_key == SPINEL_PROP_MAC_ENERGY_SCAN_RESULT) && (mScanType == kScanTypeEnergy)) {
+			EnergyScanResultEntry result;
+
+			syslog(LOG_DEBUG, "Got an Energy Scan result");
+
+			spinel_datatype_unpack(
+				data_ptr,
+				data_len,
+				"Cc",
+				&result.mChannel,
+				&result.mMaxRssi
+			);
+
+			mInstance->get_control_interface().mOnEnergyScanResult(result);
+
+		} else if (prop_key == SPINEL_PROP_MAC_SCAN_STATE) {
+			int scan_state;
+			spinel_datatype_unpack(data_ptr, data_len, "i", &scan_state);
+
+			if (scan_state == SPINEL_SCAN_STATE_IDLE) {
+				break;
+			}
+		}
+
+		// Change the event type to 'IDLE' so that we
+		// don't try to process this event once than once.
+		event = EVENT_IDLE;
+	} while(true);
+
+	finish(ret);
+
+	EH_EXIT();
+
+on_error:
+	if (ret == kWPANTUNDStatus_Ok) {
+		ret = kWPANTUNDStatus_Failure;
+	}
+
+	syslog(LOG_ERR, "Scan failed: %d", ret);
+
+	finish(ret);
+
+	EH_END();
+}
diff --git a/src/ncp-spinel/SpinelNCPTaskScan.h b/src/ncp-spinel/SpinelNCPTaskScan.h
new file mode 100644
index 0000000..e7c35f6
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskScan.h
@@ -0,0 +1,65 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__SpinelNCPTaskScan__
+#define __wpantund__SpinelNCPTaskScan__
+
+#include "SpinelNCPTask.h"
+#include "SpinelNCPInstance.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+namespace nl {
+namespace wpantund {
+
+class SpinelNCPTaskScan : public SpinelNCPTask
+{
+public:
+	enum ScanType {
+		kScanTypeNet = 0,
+		kScanTypeEnergy,
+	};
+
+	enum {
+		kDefaultScanPeriod = 200,
+	};
+
+	SpinelNCPTaskScan(
+		SpinelNCPInstance* instance,
+		CallbackWithStatusArg1 cb,
+		uint32_t channel_mask,
+		uint16_t channel_scan_period = kDefaultScanPeriod,   // per channel in ms
+		ScanType scan_type = kScanTypeNet
+	);
+	virtual int vprocess_event(int event, va_list args);
+	virtual void finish(int status, const boost::any& value = boost::any());
+
+private:
+	uint8_t mChannelMaskData[32];
+	uint8_t mChannelMaskLen;
+	uint16_t mScanPeriod;  // per channel
+	ScanType mScanType;
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+
+#endif /* defined(__wpantund__SpinelNCPTaskScan__) */
diff --git a/src/ncp-spinel/SpinelNCPTaskSendCommand.cpp b/src/ncp-spinel/SpinelNCPTaskSendCommand.cpp
new file mode 100644
index 0000000..be729bc
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskSendCommand.cpp
@@ -0,0 +1,369 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include <syslog.h>
+#include <errno.h>
+#include "SpinelNCPTaskSendCommand.h"
+#include "SpinelNCPInstance.h"
+#include "spinel-extra.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+static int simple_unpacker(const uint8_t* data_in, spinel_size_t data_len, const std::string& pack_format,
+							boost::any& result);
+
+SpinelNCPTaskSendCommand::Factory::Factory(SpinelNCPInstance* instance):
+	mInstance(instance),
+	mCb(NilReturn()),
+	mTimeout(NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT),
+	mLockProperty(0)
+{
+}
+
+SpinelNCPTaskSendCommand::Factory&
+SpinelNCPTaskSendCommand::Factory::set_callback(const CallbackWithStatusArg1 &cb)
+{
+	mCb = cb;
+	return *this;
+}
+
+SpinelNCPTaskSendCommand::Factory&
+SpinelNCPTaskSendCommand::Factory::set_callback(const CallbackWithStatus &cb)
+{
+	mCb = boost::bind(cb, _1);
+	return *this;
+}
+
+SpinelNCPTaskSendCommand::Factory&
+SpinelNCPTaskSendCommand::Factory::add_command(const Data& command)
+{
+	mCommandList.insert(mCommandList.end(), command);
+	return *this;
+}
+
+SpinelNCPTaskSendCommand::Factory&
+SpinelNCPTaskSendCommand::Factory::set_timeout(int timeout)
+{
+	mTimeout = timeout;
+	return *this;
+}
+
+SpinelNCPTaskSendCommand::Factory&
+SpinelNCPTaskSendCommand::Factory::set_reply_format(const std::string& packed_format)
+{
+	mReplyUnpacker = boost::bind(simple_unpacker, _1, _2, packed_format, _3);
+	return *this;
+}
+
+SpinelNCPTaskSendCommand::Factory&
+SpinelNCPTaskSendCommand::Factory::set_reply_unpacker(const ReplyUnpacker& reply_unpacker)
+{
+	mReplyUnpacker = reply_unpacker;
+	return *this;
+}
+
+SpinelNCPTaskSendCommand::Factory&
+SpinelNCPTaskSendCommand::Factory::set_lock_property(int lock_property)
+{
+	mLockProperty = lock_property;
+	return *this;
+}
+
+boost::shared_ptr<SpinelNCPTask>
+SpinelNCPTaskSendCommand::Factory::finish(void)
+{
+	return boost::shared_ptr<SpinelNCPTask>(new SpinelNCPTaskSendCommand(*this));
+}
+
+nl::wpantund::SpinelNCPTaskSendCommand::SpinelNCPTaskSendCommand(
+	const Factory& factory
+):	SpinelNCPTask(factory.mInstance, factory.mCb),
+	mCommandList(factory.mCommandList),
+	mLockProperty(factory.mLockProperty),
+	mReplyUnpacker(factory.mReplyUnpacker),
+	mRetVal(kWPANTUNDStatus_Failure)
+{
+	mNextCommandTimeout = factory.mTimeout;
+}
+
+static boost::any
+spinel_iter_to_any(spinel_datatype_iter_t *iter)
+{
+	boost::any ret;
+	spinel_status_t status;
+
+	switch(iter->pack_format[0]) {
+	case SPINEL_DATATYPE_BOOL_C:
+		{
+			bool val(0);
+			status = spinel_datatype_iter_unpack(iter, &val);
+			require_noerr(status, bail);
+			ret = val;
+		}
+		break;
+
+	case SPINEL_DATATYPE_UINT8_C:
+		{
+			uint8_t val(0);
+			status = spinel_datatype_iter_unpack(iter, &val);
+			require_noerr(status, bail);
+			ret = val;
+		}
+		break;
+
+	case SPINEL_DATATYPE_INT8_C:
+		{
+			int8_t val(0);
+			status = spinel_datatype_iter_unpack(iter, &val);
+			require_noerr(status, bail);
+			ret = (int)val;
+		}
+		break;
+
+	case SPINEL_DATATYPE_UINT16_C:
+		{
+			uint16_t val(0);
+			status = spinel_datatype_iter_unpack(iter, &val);
+			require_noerr(status, bail);
+			ret = val;
+		}
+		break;
+
+	case SPINEL_DATATYPE_INT16_C:
+		{
+			int16_t val(0);
+			status = spinel_datatype_iter_unpack(iter, &val);
+			require_noerr(status, bail);
+			ret = val;
+		}
+		break;
+
+	case SPINEL_DATATYPE_UINT32_C:
+		{
+			uint32_t val(0);
+			status = spinel_datatype_iter_unpack(iter, &val);
+			require_noerr(status, bail);
+			ret = val;
+		}
+		break;
+
+	case SPINEL_DATATYPE_INT32_C:
+		{
+			int32_t val(0);
+			status = spinel_datatype_iter_unpack(iter, &val);
+			require_noerr(status, bail);
+			ret = val;
+		}
+		break;
+
+	case SPINEL_DATATYPE_UINT_PACKED_C:
+		{
+			unsigned int val(0);
+			status = spinel_datatype_iter_unpack(iter, &val);
+			require_noerr(status, bail);
+			ret = val;
+		}
+		break;
+
+	case SPINEL_DATATYPE_IPv6ADDR_C:
+		{
+			struct in6_addr *val = NULL;
+			status = spinel_datatype_iter_unpack(iter, &val);
+			require_noerr(status, bail);
+			ret = in6_addr_to_string(*val);
+		}
+		break;
+
+	case SPINEL_DATATYPE_EUI64_C:
+		{
+			const spinel_eui64_t *val(NULL);
+			status = spinel_datatype_iter_unpack(iter, &val);
+			require_noerr(status, bail);
+			ret = Data(val->bytes, sizeof(val->bytes));
+		}
+		break;
+
+	case SPINEL_DATATYPE_EUI48_C:
+		{
+			const spinel_eui48_t *val(NULL);
+			status = spinel_datatype_iter_unpack(iter, &val);
+			require_noerr(status, bail);
+			ret = Data(val->bytes, sizeof(val->bytes));
+		}
+		break;
+
+	case SPINEL_DATATYPE_DATA_C:
+		{
+			const uint8_t *val_ptr(NULL);
+			spinel_size_t val_len;
+			status = spinel_datatype_iter_unpack(iter, &val_ptr, &val_len);
+			require_noerr(status, bail);
+			ret = Data(val_ptr, val_len);
+		}
+		break;
+
+	case SPINEL_DATATYPE_UTF8_C:
+		{
+			const char *val(NULL);
+			status = spinel_datatype_iter_unpack(iter, &val);
+			require_noerr(status, bail);
+			ret = std::string(val);
+		}
+		break;
+
+	case SPINEL_DATATYPE_STRUCT_C:
+		goto bail;
+
+	case SPINEL_DATATYPE_ARRAY_C:
+		// TODO: Recursively parse this
+		goto bail;
+
+	default:
+		goto bail;
+
+	}
+
+bail:
+	return ret;
+}
+
+static boost::any
+spinel_packed_to_any(const uint8_t* data_in, spinel_size_t data_len, const char* pack_format)
+{
+	spinel_datatype_iter_t spinel_iter = {};
+	spinel_datatype_iter_start(&spinel_iter, data_in, data_len, pack_format);
+
+	return spinel_iter_to_any(&spinel_iter);
+}
+
+static int
+simple_unpacker(const uint8_t* data_in, spinel_size_t data_len, const std::string& pack_format, boost::any& result)
+{
+	int retval = kWPANTUNDStatus_Ok;
+
+	try {
+		result = spinel_packed_to_any(data_in, data_len, pack_format.c_str());
+
+	} catch(...) {
+		retval = kWPANTUNDStatus_Failure;
+	}
+
+	return retval;
+}
+
+int
+nl::wpantund::SpinelNCPTaskSendCommand::vprocess_event(int event, va_list args)
+{
+	EH_BEGIN();
+
+	mRetVal = kWPANTUNDStatus_Failure;
+
+	// The first event to a task is EVENT_STARTING_TASK. The following
+	// line makes sure that we don't start processing this task
+	// until it is properly scheduled. All tasks immediately receive
+	// the initial `EVENT_STARTING_TASK` event, but further events
+	// will only be received by that task once it is that task's turn
+	// to execute.
+	EH_WAIT_UNTIL(EVENT_STARTING_TASK != event);
+
+	if (mLockProperty != 0) {
+		mNextCommand = SpinelPackData(
+			SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S),
+			mLockProperty,
+			true
+		);
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		mRetVal = mNextCommandRet;
+
+		// In case of BUSY error status (meaning the `ALLOW_LOCAL_NET_DATA_CHANGE`
+		// was already true), allow the operation to proceed.
+
+		require((mRetVal == kWPANTUNDStatus_Ok) || (mRetVal == kWPANTUNDStatus_Busy), on_error);
+	}
+
+	mRetVal = kWPANTUNDStatus_Ok;
+
+	mCommandIter = mCommandList.begin();
+
+	while ( (mRetVal == kWPANTUNDStatus_Ok)
+	     && (mCommandList.end() != mCommandIter)
+	) {
+		mNextCommand = *mCommandIter++;
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+	}
+
+	mRetVal = mNextCommandRet;
+
+	require_noerr(mRetVal, on_error);
+
+	if ( mReplyUnpacker
+	  && (kWPANTUNDStatus_Ok == mRetVal)
+	  && (EVENT_NCP_PROP_VALUE_IS == event)
+	) {
+		// Handle the packed response from the last command
+
+		unsigned int key = va_arg(args, unsigned int);
+		const uint8_t* data_in = va_arg(args, const uint8_t*);
+		spinel_size_t data_len = va_arg_small(args, spinel_size_t);
+		(void) key; // Ignored
+
+		mRetVal = mReplyUnpacker(data_in, data_len, mReturnValue);
+	}
+
+on_error:
+
+	if (mRetVal != kWPANTUNDStatus_Ok) {
+		syslog(LOG_ERR, "SendCommand task encountered an error: %d (0x%08X)", mRetVal, mRetVal);
+	}
+
+	// Even in case of failure we proceed to set mLockProperty
+	// to `false`. The error status is checked after this. It is stored in
+	// a class instance variable `mRetVal` so that the value is preserved
+	// over the protothread EH_SPAWN() call.
+
+	if (mLockProperty != 0) {
+		mNextCommand = SpinelPackData(
+			SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_BOOL_S),
+			mLockProperty,
+			false
+		);
+
+		EH_SPAWN(&mSubPT, vprocess_send_command(event, args));
+
+		if (mNextCommandRet != kWPANTUNDStatus_Ok)
+		{
+			mRetVal = mNextCommandRet;
+		}
+
+		check_noerr(mNextCommandRet);
+	}
+
+	finish(mRetVal, mReturnValue);
+
+	EH_END();
+}
diff --git a/src/ncp-spinel/SpinelNCPTaskSendCommand.h b/src/ncp-spinel/SpinelNCPTaskSendCommand.h
new file mode 100644
index 0000000..2f81c9d
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskSendCommand.h
@@ -0,0 +1,90 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__SpinelNCPTaskSendCommand__
+#define __wpantund__SpinelNCPTaskSendCommand__
+
+#include "SpinelNCPTask.h"
+#include "SpinelNCPInstance.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+namespace nl {
+namespace wpantund {
+
+class SpinelNCPTaskSendCommand : public SpinelNCPTask
+{
+public:
+	typedef boost::function<int (const uint8_t*, spinel_size_t, boost::any&)> ReplyUnpacker;
+
+	class Factory {
+	public:
+
+		friend class SpinelNCPTaskSendCommand;
+
+		Factory(SpinelNCPInstance* instance);
+
+		Factory& set_callback(const CallbackWithStatusArg1 &cb);
+		Factory& set_callback(const CallbackWithStatus &cb);
+		Factory& add_command(const Data& command);
+		Factory& set_timeout(int timeout);
+
+		/* For simple (single type) reply formats, we can use the
+		 * `set_reply_format()` and specify the spinel packing format.
+		 * For more complicated reply format (e.g., multiple types, structs)
+		 * a `ReplyUnpakcer` function pointer can be specified using
+		 * `set_reply_unpacker()` which is then used to decode/unpack
+		 * the reply spinel message into a `boost::any` output result.
+		 */
+		Factory& set_reply_format(const std::string& packed_format);
+		Factory& set_reply_unpacker(const ReplyUnpacker &reply_unpacker);
+
+		Factory& set_lock_property(int lock_property = SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE);
+
+		boost::shared_ptr<SpinelNCPTask> finish(void);
+
+	private:
+		SpinelNCPInstance* mInstance;
+		CallbackWithStatusArg1 mCb;
+		std::list<Data> mCommandList;
+		int mTimeout;
+		ReplyUnpacker mReplyUnpacker;
+		int mLockProperty;
+	};
+
+	SpinelNCPTaskSendCommand(const Factory& factory);
+
+	virtual int vprocess_event(int event, va_list args);
+
+private:
+
+	std::list<Data> mCommandList;
+	std::list<Data>::const_iterator mCommandIter;
+	int mLockProperty;
+	ReplyUnpacker mReplyUnpacker;
+	int mRetVal;
+	boost::any mReturnValue;
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+
+#endif /* defined(__wpantund__SpinelNCPTaskSendCommand__) */
diff --git a/src/ncp-spinel/SpinelNCPTaskWake.cpp b/src/ncp-spinel/SpinelNCPTaskWake.cpp
new file mode 100644
index 0000000..8e20672
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskWake.cpp
@@ -0,0 +1,97 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include <syslog.h>
+#include <errno.h>
+#include "SpinelNCPTaskWake.h"
+#include "SpinelNCPInstance.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+nl::wpantund::SpinelNCPTaskWake::SpinelNCPTaskWake(
+	SpinelNCPInstance* instance,
+	CallbackWithStatusArg1 cb
+):	SpinelNCPTask(instance, cb)
+{
+}
+
+void
+nl::wpantund::SpinelNCPTaskWake::finish(int status, const boost::any& value)
+{
+	mInstance->mResetIsExpected = false;
+
+	SpinelNCPTask::finish(status, value);
+}
+
+
+int
+nl::wpantund::SpinelNCPTaskWake::vprocess_event(int event, va_list args)
+{
+	int ret = kWPANTUNDStatus_Failure;
+
+	EH_BEGIN();
+
+	// The first event to a task is EVENT_STARTING_TASK. The following
+	// line makes sure that we don't start processing this task
+	// until it is properly scheduled. All tasks immediately receive
+	// the initial `EVENT_STARTING_TASK` event, but further events
+	// will only be received by that task once it is that task's turn
+	// to execute.
+	EH_WAIT_UNTIL(EVENT_STARTING_TASK != event);
+
+	mInstance->set_ncp_power(true);
+	mInstance->mResetIsExpected = true;
+
+	CONTROL_REQUIRE_PREP_TO_SEND_COMMAND_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+	GetInstance(this)->mOutboundBufferLen = spinel_datatype_pack(GetInstance(this)->mOutboundBuffer, sizeof(GetInstance(this)->mOutboundBuffer), "Ci", 0, SPINEL_CMD_NOOP);
+	CONTROL_REQUIRE_OUTBOUND_BUFFER_FLUSHED_WITHIN(NCP_DEFAULT_COMMAND_SEND_TIMEOUT, on_error);
+
+	EH_REQUIRE_WITHIN(
+		NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT,
+		!ncp_state_is_sleeping(mInstance->get_ncp_state())
+		  && (!ncp_state_is_initializing(mInstance->get_ncp_state())),
+		on_error
+	);
+
+	ret = kWPANTUNDStatus_Ok;
+
+	finish(ret);
+
+	EH_EXIT();
+
+on_error:
+
+	if (ret == kWPANTUNDStatus_Ok) {
+		ret = kWPANTUNDStatus_Failure;
+	}
+
+	syslog(LOG_ERR, "Wake failed: %d", ret);
+
+	mInstance->reinitialize_ncp();
+
+	finish(ret);
+
+	EH_END();
+}
diff --git a/src/ncp-spinel/SpinelNCPTaskWake.h b/src/ncp-spinel/SpinelNCPTaskWake.h
new file mode 100644
index 0000000..52bd07f
--- /dev/null
+++ b/src/ncp-spinel/SpinelNCPTaskWake.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__SpinelNCPTaskWake__
+#define __wpantund__SpinelNCPTaskWake__
+
+#include "SpinelNCPTask.h"
+#include "SpinelNCPInstance.h"
+
+using namespace nl;
+using namespace nl::wpantund;
+
+namespace nl {
+namespace wpantund {
+
+class SpinelNCPTaskWake : public SpinelNCPTask
+{
+public:
+	SpinelNCPTaskWake(
+		SpinelNCPInstance* instance,
+		CallbackWithStatusArg1 cb
+	);
+	virtual int vprocess_event(int event, va_list args);
+	virtual void finish(int status, const boost::any& value = boost::any());
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+
+#endif /* defined(__wpantund__SpinelNCPTaskWake__) */
diff --git a/src/ncp-spinel/spinel-extra.c b/src/ncp-spinel/spinel-extra.c
new file mode 100644
index 0000000..fe586ff
--- /dev/null
+++ b/src/ncp-spinel/spinel-extra.c
@@ -0,0 +1,380 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// ----------------------------------------------------------------------------
+// MARK: -
+// MARK: Headers
+
+#include "spinel-extra.h"
+
+#include <assert.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+#ifndef assert_printf
+#define assert_printf(fmt, ...) \
+fprintf(stderr, \
+        __FILE__ ":%d: " fmt "\n", \
+        __LINE__, \
+        __VA_ARGS__)
+#endif
+
+#ifndef require_action
+#define require_action(c, l, a) \
+    do { if (!(c)) { \
+        assert_printf("Requirement Failed (%s)", # c); \
+        a; \
+        goto l; \
+    } } while (0)
+#endif
+
+#ifndef require
+#define require(c, l)   require_action(c, l, {})
+#endif
+
+// ----------------------------------------------------------------------------
+// MARK: -
+// MARK: Datatype Iterator
+
+spinel_status_t
+spinel_datatype_iter_start(spinel_datatype_iter_t* iter, const uint8_t* data_in, spinel_size_t data_len, const char* pack_format)
+{
+	iter->data_ptr = data_in;
+	iter->data_len = data_len;
+	iter->pack_format = pack_format;
+
+	return SPINEL_STATUS_OK;
+}
+
+spinel_status_t
+spinel_datatype_iter_next(spinel_datatype_iter_t* iter)
+{
+	spinel_status_t ret = SPINEL_STATUS_PARSE_ERROR;
+	spinel_datatype_iter_t scratchpad = *iter;
+
+	if (!iter->data_ptr || !iter->data_len || !iter->pack_format) {
+		ret = SPINEL_STATUS_EMPTY;
+		goto bail;
+	}
+
+	switch ((spinel_datatype_t)*scratchpad.pack_format) {
+	case SPINEL_DATATYPE_INT8_C:
+	case SPINEL_DATATYPE_UINT8_C:
+		require(scratchpad.data_len >= sizeof(uint8_t), bail);
+		scratchpad.data_ptr += sizeof(uint8_t);
+		scratchpad.data_len -= sizeof(uint8_t);
+		scratchpad.pack_format++;
+		break;
+
+	case SPINEL_DATATYPE_INT16_C:
+	case SPINEL_DATATYPE_UINT16_C:
+		require(scratchpad.data_len >= sizeof(uint16_t), bail);
+		scratchpad.data_ptr += sizeof(uint16_t);
+		scratchpad.data_len -= sizeof(uint16_t);
+		scratchpad.pack_format++;
+		break;
+
+	case SPINEL_DATATYPE_INT32_C:
+	case SPINEL_DATATYPE_UINT32_C:
+		require(scratchpad.data_len >= sizeof(uint32_t), bail);
+		scratchpad.data_ptr += sizeof(uint32_t);
+		scratchpad.data_len -= sizeof(uint32_t);
+		scratchpad.pack_format++;
+		break;
+
+	case SPINEL_DATATYPE_IPv6ADDR_C:
+		require(scratchpad.data_len >= sizeof(spinel_ipv6addr_t), bail);
+		scratchpad.data_ptr += sizeof(spinel_ipv6addr_t);
+		scratchpad.data_len -= sizeof(spinel_ipv6addr_t);
+		scratchpad.pack_format++;
+		break;
+
+	case SPINEL_DATATYPE_EUI64_C:
+		require(scratchpad.data_len >= sizeof(spinel_eui64_t), bail);
+		scratchpad.data_ptr += sizeof(spinel_eui64_t);
+		scratchpad.data_len -= sizeof(spinel_eui64_t);
+		scratchpad.pack_format++;
+		break;
+
+	case SPINEL_DATATYPE_EUI48_C:
+		require(scratchpad.data_len >= sizeof(spinel_eui48_t), bail);
+		scratchpad.data_ptr += sizeof(spinel_eui48_t);
+		scratchpad.data_len -= sizeof(spinel_eui48_t);
+		scratchpad.pack_format++;
+		break;
+
+	case SPINEL_DATATYPE_UINT_PACKED_C:
+		{
+			spinel_ssize_t pui_len = spinel_packed_uint_decode(scratchpad.data_ptr, scratchpad.data_len, NULL);
+			require(pui_len > 0, bail);
+			scratchpad.data_ptr += pui_len;
+			scratchpad.data_len -= pui_len;
+			scratchpad.pack_format++;
+		}
+		break;
+
+
+	case SPINEL_DATATYPE_UTF8_C:
+		break;
+
+	case SPINEL_DATATYPE_STRUCT_C:
+	case SPINEL_DATATYPE_ARRAY_C:
+		scratchpad.pack_format = spinel_next_packed_datatype(scratchpad.pack_format)-1;
+
+	case SPINEL_DATATYPE_DATA_C:
+		{
+			if ((scratchpad.pack_format[1] == ')')
+			 || (scratchpad.pack_format[1] == 0)
+			) {
+				// Special case: data is size of the rest of the buffer!
+				scratchpad.data_ptr += scratchpad.data_len;
+				scratchpad.data_len -= scratchpad.data_len;
+			} else {
+				uint32_t block_len = 0;
+				spinel_ssize_t pui_len = spinel_packed_uint_decode(scratchpad.data_ptr, scratchpad.data_len, &block_len);
+
+				require(pui_len > 0, bail);
+				require(block_len < SPINEL_FRAME_MAX_SIZE, bail);
+
+				scratchpad.data_ptr += pui_len+block_len;
+				scratchpad.data_len -= pui_len+block_len;
+
+				require(scratchpad.data_len >= block_len, bail);
+			}
+		}
+	case SPINEL_DATATYPE_VOID_C:
+		scratchpad.pack_format++;
+
+	default:
+		// Unsupported Type!
+		goto bail;
+	}
+
+	while (scratchpad.pack_format[0] == SPINEL_DATATYPE_VOID_C) {
+		scratchpad.pack_format++;
+	}
+
+	if ((*scratchpad.pack_format == ')')
+	 || (*scratchpad.pack_format == 0)
+	 || (scratchpad.data_len == 0)
+	) {
+		ret = SPINEL_STATUS_EMPTY;
+	} else {
+		ret = SPINEL_STATUS_OK;
+	}
+
+	if (iter->container == SPINEL_DATATYPE_ARRAY_C) {
+		iter->data_ptr = scratchpad.data_ptr;
+		iter->data_len = scratchpad.data_len;
+	} else {
+		*iter = scratchpad;
+	}
+
+bail:
+	return ret;
+}
+
+spinel_status_t
+spinel_datatype_iter_open_container(const spinel_datatype_iter_t* iter, spinel_datatype_iter_t* subiter)
+{
+	spinel_status_t ret = SPINEL_STATUS_PARSE_ERROR;
+	int depth = 0;
+
+	require(iter->data_len > 2, bail);
+
+	switch ((spinel_datatype_t)*iter->pack_format) {
+	case SPINEL_DATATYPE_STRUCT_C:
+	case SPINEL_DATATYPE_ARRAY_C:
+		break;
+
+	default:
+		ret = SPINEL_STATUS_INVALID_ARGUMENT;
+		goto bail;
+		break;
+	}
+
+	*subiter = *iter;
+	subiter->container = iter->pack_format[0];
+
+	do {
+		switch(subiter->pack_format[1]) {
+		case '(': depth++; break;
+		case ')': depth++; break;
+		case 0: depth = 0; break;
+		}
+	} while(depth > 0);
+
+	require(subiter->pack_format[1] == ')', bail);
+	subiter->pack_format++;
+
+	if ((subiter->pack_format[1] != ')') && (subiter->pack_format[1] != 0))
+	{
+		// We aren't the special case. Extract the length.
+		uint32_t block_len = 0;
+		spinel_ssize_t pui_len = spinel_packed_uint_decode(subiter->data_ptr, subiter->data_len, &block_len);
+
+		require(pui_len > 0, bail);
+		require(block_len < SPINEL_FRAME_MAX_SIZE, bail);
+
+		subiter->data_ptr += pui_len;
+		subiter->data_len -= pui_len;
+
+		require(block_len <= subiter->data_len, bail);
+
+		subiter->data_len = block_len;
+	}
+	subiter->pack_format = iter->pack_format+2;
+
+	ret = SPINEL_STATUS_OK;
+
+bail:
+	return ret;
+}
+
+spinel_status_t
+spinel_datatype_iter_unpack(const spinel_datatype_iter_t* iter, ...)
+{
+	spinel_status_t ret = SPINEL_STATUS_PARSE_ERROR;
+	va_list args;
+	va_start(args, iter);
+	const char pack_format[2] = { iter->pack_format[0], 0 };
+
+	if (0 <= spinel_datatype_vunpack(iter->data_ptr, iter->data_len, pack_format, args)) {
+		ret = SPINEL_STATUS_OK;
+	}
+
+	va_end(args);
+	return ret;
+}
+
+spinel_status_t
+spinel_datatype_iter_vunpack(const spinel_datatype_iter_t* iter, va_list args)
+{
+	spinel_status_t ret = SPINEL_STATUS_PARSE_ERROR;
+
+	if (0 <= spinel_datatype_vunpack(iter->data_ptr, iter->data_len, iter->pack_format, args)) {
+		ret = SPINEL_STATUS_OK;
+	}
+
+	return ret;
+}
+
+spinel_datatype_t
+spinel_datatype_iter_get_type(const spinel_datatype_iter_t* iter)
+{
+	return iter->pack_format != NULL
+		? (spinel_datatype_t)*iter->pack_format
+		: SPINEL_DATATYPE_NULL_C;
+}
+
+// ----------------------------------------------------------------------------
+// MARK: -
+// MARK: Command Generators
+
+spinel_ssize_t
+spinel_cmd_prop_value_set_uint(uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len, spinel_prop_key_t prop_key, unsigned int x)
+{
+    return spinel_datatype_pack(
+        cmd_data_ptr,
+        cmd_data_len,
+        SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT_PACKED_S),
+        prop_key,
+        x
+    );
+}
+
+spinel_ssize_t
+spinel_cmd_prop_value_set_data(uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len, spinel_prop_key_t prop_key, const uint8_t* x_ptr, spinel_size_t x_len)
+{
+    return spinel_datatype_pack(
+        cmd_data_ptr,
+        cmd_data_len,
+        SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_DATA_S),
+        prop_key,
+        x_ptr,
+        x_len
+    );
+}
+
+spinel_ssize_t
+spinel_cmd_prop_value_set_utf8(uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len, spinel_prop_key_t prop_key, const char* x)
+{
+    return spinel_datatype_pack(
+        cmd_data_ptr,
+        cmd_data_len,
+        SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_DATA_S),
+        prop_key,
+        x
+    );
+}
+
+spinel_ssize_t
+spinel_cmd_prop_value_set_uint16(uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len, spinel_prop_key_t prop_key, uint16_t x)
+{
+    return spinel_datatype_pack(
+        cmd_data_ptr,
+        cmd_data_len,
+        SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_UINT16_S),
+        prop_key,
+        x
+    );
+}
+
+spinel_ssize_t
+spinel_cmd_prop_value_set_ipv6addr(uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len, spinel_prop_key_t prop_key, const spinel_ipv6addr_t* x_ptr)
+{
+    return spinel_datatype_pack(
+        cmd_data_ptr,
+        cmd_data_len,
+        SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_IPv6ADDR_S),
+        prop_key,
+        x_ptr
+    );
+}
+
+spinel_ssize_t
+spinel_cmd_prop_value_set_eui64(uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len, spinel_prop_key_t prop_key, const spinel_eui64_t* x_ptr)
+{
+    return spinel_datatype_pack(
+        cmd_data_ptr,
+        cmd_data_len,
+        SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(SPINEL_DATATYPE_EUI64_S),
+        prop_key,
+        x_ptr
+    );
+}
+
+spinel_ssize_t
+spinel_cmd_prop_value_get(uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len, spinel_prop_key_t prop_key)
+{
+    spinel_ssize_t ret;
+    ret = spinel_datatype_pack(
+        cmd_data_ptr,
+        cmd_data_len,
+        SPINEL_FRAME_PACK_CMD_PROP_VALUE_GET,
+        prop_key
+    );
+    return ret;
+}
diff --git a/src/ncp-spinel/spinel-extra.h b/src/ncp-spinel/spinel-extra.h
new file mode 100644
index 0000000..25f3e71
--- /dev/null
+++ b/src/ncp-spinel/spinel-extra.h
@@ -0,0 +1,79 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef SPINEL_EXTRA_HEADER_INCLUDED
+#define SPINEL_EXTRA_HEADER_INCLUDED 1
+
+#include "spinel.h"
+
+__BEGIN_DECLS
+
+// ----------------------------------------------------------------------------
+
+typedef struct {
+	const uint8_t* data_ptr;
+	int data_len;
+	const char* pack_format;
+	spinel_datatype_t container;
+} spinel_datatype_iter_t;
+
+SPINEL_API_EXTERN spinel_status_t spinel_datatype_iter_start(spinel_datatype_iter_t* iter, const uint8_t* data_in, spinel_size_t data_len, const char* pack_format);
+SPINEL_API_EXTERN spinel_status_t spinel_datatype_iter_next(spinel_datatype_iter_t* iter);
+SPINEL_API_EXTERN spinel_status_t spinel_datatype_iter_open_container(const spinel_datatype_iter_t* iter, spinel_datatype_iter_t* subiter);
+SPINEL_API_EXTERN spinel_status_t spinel_datatype_iter_unpack(const spinel_datatype_iter_t* iter, ...);
+SPINEL_API_EXTERN spinel_status_t spinel_datatype_iter_vunpack(const spinel_datatype_iter_t* iter, va_list args);
+SPINEL_API_EXTERN spinel_datatype_t spinel_datatype_iter_get_type(const spinel_datatype_iter_t* iter);
+
+// ----------------------------------------------------------------------------
+
+#define SPINEL_FRAME_PACK_CMD(x)                     "Ci" x,SPINEL_HEADER_FLAG
+#define SPINEL_FRAME_PACK_CMD_NOOP                   SPINEL_FRAME_PACK_CMD(SPINEL_DATATYPE_NULL_S),SPINEL_CMD_NOOP
+#define SPINEL_FRAME_PACK_CMD_RESET                  SPINEL_FRAME_PACK_CMD(SPINEL_DATATYPE_NULL_S),SPINEL_CMD_RESET
+#define SPINEL_FRAME_PACK_CMD_NET_CLEAR              SPINEL_FRAME_PACK_CMD(SPINEL_DATATYPE_NULL_S),SPINEL_CMD_NET_CLEAR
+#define SPINEL_FRAME_PACK_CMD_PROP_VALUE_GET         SPINEL_FRAME_PACK_CMD(SPINEL_DATATYPE_UINT_PACKED_S),SPINEL_CMD_PROP_VALUE_GET
+#define SPINEL_FRAME_PACK_CMD_PROP_TYPE_GET          SPINEL_FRAME_PACK_CMD(SPINEL_DATATYPE_UINT_PACKED_S),SPINEL_CMD_PROP_TYPE_GET
+#define SPINEL_FRAME_PACK_CMD_PROP_VALUE_SET(x)      SPINEL_FRAME_PACK_CMD(SPINEL_DATATYPE_UINT_PACKED_S x),SPINEL_CMD_PROP_VALUE_SET
+#define SPINEL_FRAME_PACK_CMD_PROP_VALUE_INSERT(x)   SPINEL_FRAME_PACK_CMD(SPINEL_DATATYPE_UINT_PACKED_S x),SPINEL_CMD_PROP_VALUE_INSERT
+#define SPINEL_FRAME_PACK_CMD_PROP_VALUE_REMOVE(x)   SPINEL_FRAME_PACK_CMD(SPINEL_DATATYPE_UINT_PACKED_S x),SPINEL_CMD_PROP_VALUE_REMOVE
+#define SPINEL_FRAME_PACK_CMD_PROP_VALUE_IS(x)       SPINEL_FRAME_PACK_CMD(SPINEL_DATATYPE_UINT_PACKED_S x),SPINEL_CMD_PROP_VALUE_IS
+#define SPINEL_FRAME_PACK_CMD_PROP_TYPE_IS           SPINEL_FRAME_PACK_CMD(SPINEL_DATATYPE_UINT_PACKED_S SPINEL_DATATYPE_UINT8_S),SPINEL_CMD_PROP_TYPE_IS
+#define SPINEL_FRAME_PACK_CMD_PROP_VALUE_INSERTED(x) SPINEL_FRAME_PACK_CMD(SPINEL_DATATYPE_UINT_PACKED_S x),SPINEL_CMD_PROP_VALUE_INSERTED
+#define SPINEL_FRAME_PACK_CMD_PROP_VALUE_REMOVED(x)  SPINEL_FRAME_PACK_CMD(SPINEL_DATATYPE_UINT_PACKED_S x),SPINEL_CMD_PROP_VALUE_REMOVED
+
+SPINEL_API_EXTERN spinel_ssize_t spinel_cmd_prop_value_set_data(uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len, spinel_prop_key_t prop_key, const uint8_t* x_ptr, spinel_size_t x_len);
+
+SPINEL_API_EXTERN spinel_ssize_t spinel_cmd_prop_value_set_utf8(uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len, spinel_prop_key_t prop_key, const char* x);
+
+SPINEL_API_EXTERN spinel_ssize_t spinel_cmd_prop_value_set_uint(uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len, spinel_prop_key_t prop_key, unsigned int x);
+
+SPINEL_API_EXTERN spinel_ssize_t spinel_cmd_prop_value_set_uint16(uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len, spinel_prop_key_t prop_key, uint16_t x);
+
+SPINEL_API_EXTERN spinel_ssize_t spinel_cmd_prop_value_set_ipv6addr(uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len, spinel_prop_key_t prop_key, const spinel_ipv6addr_t* x_ptr);
+
+SPINEL_API_EXTERN spinel_ssize_t spinel_cmd_prop_value_set_eui64(uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len, spinel_prop_key_t prop_key, const spinel_eui64_t* x_ptr);
+
+SPINEL_API_EXTERN spinel_ssize_t spinel_cmd_prop_value_get(uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len, spinel_prop_key_t prop_key);
+
+SPINEL_API_EXTERN spinel_ssize_t spinel_cmd_prop_type_get(uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len, spinel_prop_key_t prop_key);
+
+SPINEL_API_EXTERN spinel_ssize_t spinel_cmd_prop_type_get(uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len, spinel_prop_key_t prop_key);
+
+__END_DECLS
+
+#endif // SPINEL_EXTRA_HEADER_INCLUDED
diff --git a/src/scripts/Makefile.am b/src/scripts/Makefile.am
new file mode 100644
index 0000000..b407dc0
--- /dev/null
+++ b/src/scripts/Makefile.am
@@ -0,0 +1,29 @@
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+DISTCLEANFILES = \
+	.deps \
+	Makefile \
+	$(NULL)
+
+EXTRA_DIST = \
+	wpanretain.sh \
+	$(NULL)
+
+pkgdata_DATA = \
+	wpanretain.sh \
+	$(NULL)
diff --git a/src/scripts/wpanretain.sh b/src/scripts/wpanretain.sh
new file mode 100755
index 0000000..5638d6f
--- /dev/null
+++ b/src/scripts/wpanretain.sh
@@ -0,0 +1,378 @@
+#! /bin/sh
+
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+display_usage ()
+{
+	echo "Thread Network Retain - Save/Recall thread network info"
+	echo ""
+	echo "Usage: $(basename $0) [primary-net-info-file] [secondary-net-info-file] [wpanctl path] [command]"
+	echo ""
+	echo "    Command:"
+	echo "        'S' or 'save'   : Save current network info."
+	echo "        'R' or 'recall' : Recall/Restore previously saved network info."
+	echo "        'E' or 'erase'  : Erase previously saved network info."
+	echo ""
+	echo "     [primary-net-info-file] and [secondary-net-info-file] give full path to files to store network info."
+	echo "     [wpanctl path] gives the full path to 'wpanctl'."
+	echo ""
+}
+
+# Check the input args
+
+if [ $# -ne 4 ]; then
+	display_usage
+	exit 1
+fi
+
+primary_file_name="$1"
+secondary_file_name="$2"
+wpanctl_command="$3"
+retain_command=$4
+
+# List of all wpantund properties saved
+WPANTUND_PROP_NAME="Network:Name"
+WPANTUND_PROP_KEY="Network:Key"
+WPANTUND_PROP_PANID="Network:PANID"
+WPANTUND_PROP_XPANID="Network:XPANID"
+WPANTUND_PROP_CHANNEL="NCP:Channel"
+WPANTUND_PROP_MACADDR="NCP:MACAddress"
+WPANTUND_PROP_NODE_TYPE="Network:NodeType"
+WPANTUND_PROP_KEY_INDEX="Network:KeyIndex"
+WPANTUND_PROP_ROUTER_ID="Thread:RouterID"
+WPANTUND_PROP_PREFERRED_ROUTER_ID="Thread:PreferredRouterID"
+
+MAX_ROUTER_ID=60
+
+cur_name=
+cur_key=
+cur_panid=
+cur_xpanid=
+cur_channel=
+cur_macaddr=
+cur_type=
+cur_keyindex=
+cur_routerid=
+
+new_name=
+new_key=
+new_panid=
+new_xpanid=
+new_channel=
+new_macaddr=
+new_type=
+new_keyindex=
+new_routerid=
+
+# Populate the new network info variables by reading the values from wpanctl
+get_new_network_info_from_wpantund ()
+{
+	val=$($wpanctl_command get -v $WPANTUND_PROP_NAME)
+	val=${val#\"}
+	new_name=${val%\"}
+
+	val=$($wpanctl_command get $WPANTUND_PROP_KEY)
+	val=${val#*\[}
+	new_key=${val%\]*}
+
+	val=$($wpanctl_command get $WPANTUND_PROP_PANID)
+	new_panid=$(echo "$val" | sed -e 's/.*=[[:space:]]*//')
+
+	val=$($wpanctl_command get $WPANTUND_PROP_XPANID)
+	new_xpanid=$(echo "$val" | sed -e 's/.*=[[:space:]]*0x//')
+
+	val=$($wpanctl_command get $WPANTUND_PROP_CHANNEL)
+	new_channel=$(echo "$val" | sed -e 's/.*=[[:space:]]*//')
+
+	val=$($wpanctl_command get $WPANTUND_PROP_MACADDR)
+	val=${val#*\[}
+	new_macaddr=${val%\]*}
+
+	val=$($wpanctl_command get $WPANTUND_PROP_NODE_TYPE)
+	new_type=$(echo "$val" | sed -e 's/.*=[[:space:]]*//')
+
+	val=$($wpanctl_command get $WPANTUND_PROP_KEY_INDEX)
+	new_keyindex=$(echo "$val" | sed -e 's/.*=[[:space:]]*//')
+
+	val=$($wpanctl_command get -v $WPANTUND_PROP_ROUTER_ID)
+	new_routerid=$(printf "%d" $val)
+}
+
+restore_network_info_on_wpantund ()
+{
+	# Calculate a new router id value by adding one to it
+	# This ensures router id is different upon every reset/restore
+	router_id=$(($cur_routerid+1))
+
+	if [ "$router_id" -ge "$MAX_ROUTER_ID" ]
+	then
+		router_id=0
+	fi
+	$wpanctl_command set $WPANTUND_PROP_PREFERRED_ROUTER_ID $router_id
+
+	$wpanctl_command set $WPANTUND_PROP_MACADDR $cur_macaddr
+	$wpanctl_command set $WPANTUND_PROP_NAME $cur_name
+	$wpanctl_command set $WPANTUND_PROP_KEY -d $cur_key
+	$wpanctl_command set $WPANTUND_PROP_PANID $cur_panid
+	$wpanctl_command set $WPANTUND_PROP_XPANID -d $cur_xpanid
+	$wpanctl_command set $WPANTUND_PROP_CHANNEL $cur_channel
+	$wpanctl_command set $WPANTUND_PROP_NODE_TYPE $cur_type
+	$wpanctl_command set $WPANTUND_PROP_KEY_INDEX $cur_keyindex
+
+	$wpanctl_command attach
+}
+
+verify_cur_info ()
+{
+	if [ -z "$cur_name" ] ||		\
+	   [ -z "$cur_key" ] || 		\
+	   [ -z "$cur_panid" ] || 		\
+	   [ -z "$cur_xpanid" ] ||		\
+	   [ -z "$cur_channel" ] || 	\
+	   [ -z "$cur_macaddr" ] || 	\
+	   [ -z "$cur_type" ] ||		\
+	   [ -z "$cur_keyindex" ] || 	\
+	   [ -z "$cur_routerid" ]
+	then
+		return 1
+	fi
+
+	return 0
+}
+
+verify_new_info ()
+{
+
+	if [ -z "$new_name" ] ||		\
+	   [ -z "$new_key" ] || 		\
+	   [ -z "$new_panid" ] || 		\
+	   [ -z "$new_xpanid" ] ||		\
+	   [ -z "$new_channel" ] || 	\
+	   [ -z "$new_macaddr" ] || 	\
+	   [ -z "$new_type" ] ||		\
+	   [ -z "$new_keyindex" ] ||    \
+	   [ -z "$new_routerid" ]
+	then
+		return 1
+	fi
+
+	return 0
+}
+
+is_new_info_same_as_cur_info ()
+{
+	if [ "$cur_name" != "$new_name" ] || \
+	   [ "$cur_key" != "$new_key" ] || \
+	   [ "$cur_panid" != "$new_panid" ] || \
+	   [ "$cur_xpanid" != "$new_xpanid" ] || \
+	   [ "$cur_channel" != "$new_channel" ] || \
+	   [ "$cur_macaddr" != "$new_macaddr" ] || \
+	   [ "$cur_type" != "$new_type" ] || \
+	   [ "$cur_keyindex" != "$new_keyindex" ] || \
+	   [ "$cur_routerid" != "$new_routerid" ]
+	then
+		return 1
+	fi
+
+	return 0
+}
+
+# Reads and parses the network info from a file and populate old network info variables
+#     First arg ($1) is the file name
+read_cur_network_info_from_file ()
+{
+	if [ -r $1 ]; then
+
+		while IFS="\= " read -r key value; do
+
+			case $key in
+			$WPANTUND_PROP_NAME)
+			  cur_name=$value
+			  ;;
+			$WPANTUND_PROP_KEY)
+			  cur_key=$value
+			  ;;
+			$WPANTUND_PROP_PANID)
+			  cur_panid=$value
+			  ;;
+			$WPANTUND_PROP_XPANID)
+			  cur_xpanid=$value
+			  ;;
+			$WPANTUND_PROP_CHANNEL)
+			  cur_channel=$value
+			  ;;
+			$WPANTUND_PROP_MACADDR)
+			  cur_macaddr=$value
+			  ;;
+			$WPANTUND_PROP_NODE_TYPE)
+			  cur_type=$value
+			  ;;
+			$WPANTUND_PROP_KEY_INDEX)
+			  cur_keyindex=$value
+			  ;;
+			$WPANTUND_PROP_ROUTER_ID)
+			  cur_routerid=$value
+			  ;;
+			esac
+
+		done < $1
+	fi
+}
+
+# Writes the new info into a given file name (first arg should be filename)
+write_new_info_to_file ()
+{
+	fname=$1
+
+	if [ -e $fname ]; then
+		rm $fname > /dev/null 2>&1
+	fi
+
+	mkdir -p $(dirname "$fname")
+
+	# Write all the contents to the file
+
+	echo "${WPANTUND_PROP_NAME} = $new_name" >> $fname
+	echo "${WPANTUND_PROP_KEY} = $new_key" >> $fname
+	echo "${WPANTUND_PROP_PANID} = $new_panid" >> $fname
+	echo "${WPANTUND_PROP_XPANID} = $new_xpanid" >> $fname
+	echo "${WPANTUND_PROP_CHANNEL} = $new_channel" >> $fname
+	echo "${WPANTUND_PROP_MACADDR} = $new_macaddr" >> $fname
+	echo "${WPANTUND_PROP_NODE_TYPE} = $new_type" >> $fname
+	echo "${WPANTUND_PROP_KEY_INDEX} = $new_keyindex" >> $fname
+	echo "${WPANTUND_PROP_ROUTER_ID} = $new_routerid" >> $fname
+
+	# Add a time stamp
+	echo "# Saved on " $(date) >> $fname
+}
+
+# For test and debugging only
+display_cur_network_info ()
+{
+	echo "cur_name is"  $cur_name
+	echo "cur_key is"  $cur_key
+	echo "cur_panid is" $cur_panid
+	echo "cur_xpanid is" $cur_xpanid
+	echo "cur_channel is" $cur_channel
+	echo "cur_macaddr is" $cur_macaddr
+	echo "cur_type is" $cur_type
+	echo "cur_keyindex is"  $cur_keyindex
+	echo "cur_routerid is"  $cur_routerid
+}
+
+# For test and debugging only
+display_new_network_info ()
+{
+	echo "new_name is"  $new_name
+	echo "new_key is"  $new_key
+	echo "new_panid is" $new_panid
+	echo "new_xpanid is" $new_xpanid
+	echo "new_channel is" $new_channel
+	echo "new_macaddr is" $new_macaddr
+	echo "new_type is" $new_type
+	echo "new_keyindex is" $new_keyindex
+	echo "new_routerid is" $new_routerid
+}
+
+save_network_info ()
+{
+	get_new_network_info_from_wpantund
+
+	read_cur_network_info_from_file $primary_file_name
+
+	if verify_new_info; then
+
+		if is_new_info_same_as_cur_info; then
+			echo "Saved network info in \"$primary_file_name\" is up-to-date and valid."
+		else
+
+			write_new_info_to_file $secondary_file_name
+
+			# verify the file content match what was written
+
+			read_cur_network_info_from_file $secondary_file_name
+
+			if is_new_info_same_as_cur_info; then
+
+				cp $secondary_file_name $primary_file_name
+
+				echo  "Successfully saved network info in \"$primary_file_name\" and \"$secondary_file_name\""
+
+			else
+				echo "ERROR: Could not save the network data"
+			fi
+			# need to figure out if it fails what to do...
+		fi
+
+	else
+		echo "ERROR: Network info from wpantund is not valid"
+	fi
+}
+
+erase_network_info ()
+{
+	if [ -e $primary_file_name ]; then
+		rm $primary_file_name
+	fi
+
+	if [ -e $secondary_file_name ]; then
+		rm $secondary_file_name
+	fi
+
+	echo "Successfully erased network data in \"$primary_file_name\" and \"$secondary_file_name\"".
+}
+
+recall_network_info ()
+{
+	read_cur_network_info_from_file $primary_file_name
+
+	# if no valid data from the main file, try to read from the second (backup) file
+	verify_cur_info || read_cur_network_info_from_file $secondary_file_name
+
+	if verify_cur_info; then
+
+		restore_network_info_on_wpantund
+
+		echo "Successfully recalled network info from \"$primary_file_name\""
+	else
+		echo "No valid saved network info to recall."
+	fi
+}
+
+case $retain_command in
+
+R|recall)
+  recall_network_info
+  ;;
+
+S|save)
+  save_network_info
+  ;;
+
+E|erase)
+  erase_network_info
+  ;;
+
+*)
+  echo "Error: Unknown command \"$retain_command\""
+  echo " "
+  display_usage
+  ;;
+esac
+
+exit 0
diff --git a/src/util/CallbackStore.hpp b/src/util/CallbackStore.hpp
new file mode 100644
index 0000000..f0b4163
--- /dev/null
+++ b/src/util/CallbackStore.hpp
@@ -0,0 +1,115 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Class for handling one-time callbacks. Deprecated.
+ *
+ */
+
+#ifndef wpantund_callback_store_h
+#define wpantund_callback_store_h
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <map>
+#include <boost/signals2/signal.hpp>
+#include <boost/bind.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
+
+template <class Key = std::string>
+class CallbackStore {
+public:
+	typedef boost::signals2::signal<void(int, const uint8_t* data, size_t len)>  signal_type;
+	typedef boost::shared_ptr<signal_type>  mapped_type;
+	typedef Key key_type;
+	typedef std::map<key_type, mapped_type> map_type;
+
+private:
+	map_type _map;
+
+public:
+	CallbackStore() {
+	}
+
+	void
+	add(const Key& name, const boost::function<void(int)>& func)
+	{
+		if(!_map[name])
+			_map[name] = mapped_type(new signal_type());
+
+		_map[name]->connect(boost::bind(func, _1));
+	}
+
+	void
+	add( const Key& name, const boost::function3<void, int, const uint8_t*, size_t>& func)
+	{
+		if(!_map[name])
+			_map[name] = mapped_type(new signal_type());
+
+		_map[name]->connect(func);
+	}
+
+	void
+	set(const Key& name, const mapped_type& signal)
+	{
+		if (static_cast<bool>(signal))
+			_map[name] = signal;
+	}
+
+
+	size_t
+	count(const Key& name)const {
+		if (_map.count(name) == 0 || NULL == _map.find(name)->second.get())
+			return 0;
+		return _map.find(name)->second->num_slots();
+	}
+
+	void
+	handle(const Key& name, int val, const uint8_t* data, size_t len)
+	{
+		mapped_type signal;
+		if(_map[name]) {
+			signal.swap(_map[name]);
+			_map.erase(name);
+			(*signal)(val, data, len);
+		}
+	}
+
+	mapped_type
+	unhandle(const Key& name)
+	{
+		mapped_type signal;
+		if (_map[name]) {
+			signal.swap(_map[name]);
+			_map.erase(name);
+		}
+		return signal;
+	}
+
+	void
+	handle_all(int val)
+	{
+		map_type map(_map);
+		for (typename map_type::iterator iter=map.begin(); iter!=map.end(); iter++) {
+			handle(iter->first, val, NULL, 0);
+		}
+	}
+};
+
+#endif
diff --git a/src/util/Callbacks.h b/src/util/Callbacks.h
new file mode 100644
index 0000000..a48b9f5
--- /dev/null
+++ b/src/util/Callbacks.h
@@ -0,0 +1,74 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Type definitions and utility functions related to callback objects.
+ *
+ */
+
+#ifndef wpantund_Callbacks_h
+#define wpantund_Callbacks_h
+
+#ifndef __STDC_CONSTANT_MACROS
+#define __STDC_CONSTANT_MACROS 1
+#endif
+
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+#include <boost/signals2/signal.hpp>
+#include <boost/bind.hpp>
+#include <boost/any.hpp>
+
+#include "NilReturn.h"
+
+namespace nl {
+
+typedef boost::function<void(void)> CallbackSimple;
+typedef boost::function<void(int)> CallbackWithStatus;
+typedef boost::function<void(int, const boost::any&)> CallbackWithStatusArg1;
+
+typedef boost::signals2::signal<void(int)> SignalWithStatus;
+
+static inline void
+split_cb_on_status(int status, CallbackSimple cb_success, CallbackWithStatus cb_error = nl::NilReturn())
+{
+	if (status == 0) {
+		cb_success();
+	} else {
+		cb_error(status);
+	}
+}
+
+#define CALLBACK_FUNC_SPLIT(success,failure) \
+		CallbackWithStatus( \
+			boost::bind( \
+				&split_cb_on_status, \
+				_1, \
+				CallbackSimple(success), \
+				CallbackWithStatus(failure) \
+			) \
+		)
+
+}; // namespace nl
+
+#endif
diff --git a/src/util/DBUSHelpers.cpp b/src/util/DBUSHelpers.cpp
new file mode 100644
index 0000000..e394ab9
--- /dev/null
+++ b/src/util/DBUSHelpers.cpp
@@ -0,0 +1,458 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Implementation of various helper functions related to DBus
+ *      funcitonality.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "DBUSHelpers.h"
+#include "Data.h"
+#include <syslog.h>
+#include <string>
+#include <list>
+#include <map>
+#include <set>
+#include <exception>
+#include <stdexcept>
+#include "ValueMap.h"
+
+using namespace DBUSHelpers;
+
+nl::ValueMap
+DBUSHelpers::value_map_from_dbus_iter(DBusMessageIter *iter)
+{
+	nl::ValueMap ret;
+	DBusMessageIter sub_iter, dict_iter;
+
+	if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY) {
+		throw std::invalid_argument("Wrong type for value map");
+	}
+
+	dbus_message_iter_recurse(iter, &sub_iter);
+
+	if (dbus_message_iter_get_arg_type(&sub_iter) != DBUS_TYPE_DICT_ENTRY) {
+		throw std::invalid_argument("Wrong type for value map");
+	}
+
+	do {
+		const char* key_cstr;
+		dbus_message_iter_recurse(&sub_iter, &dict_iter);
+
+		if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_STRING) {
+			throw std::invalid_argument("Wrong type for value map");
+		}
+
+		dbus_message_iter_get_basic(&dict_iter, &key_cstr);
+		dbus_message_iter_next(&dict_iter);
+
+		ret[key_cstr] = any_from_dbus_iter(&dict_iter);
+	} while (dbus_message_iter_next(&sub_iter));
+
+	return ret;
+}
+
+boost::any
+DBUSHelpers::any_from_dbus_iter(DBusMessageIter *iter)
+{
+	boost::any ret;
+
+	switch (dbus_message_iter_get_arg_type(iter)) {
+	case DBUS_TYPE_ARRAY: {
+		DBusMessageIter sub_iter;
+		dbus_message_iter_recurse(iter, &sub_iter);
+		if (dbus_message_iter_get_arg_type(&sub_iter) == DBUS_TYPE_BYTE) {
+			const uint8_t* value = NULL;
+			int nelements = 0;
+			dbus_message_iter_get_fixed_array(&sub_iter, &value, &nelements);
+			ret = nl::Data(value, nelements);
+		} else if (dbus_message_iter_get_arg_type(&sub_iter) == DBUS_TYPE_DICT_ENTRY) {
+			ret = value_map_from_dbus_iter(iter);
+		} else {
+			syslog(LOG_NOTICE,
+			       "Unsupported DBUS array type for any: %d",
+			       dbus_message_iter_get_arg_type(&sub_iter));
+		}
+	} break;
+	case DBUS_TYPE_VARIANT: {
+		DBusMessageIter sub_iter;
+		dbus_message_iter_recurse(iter, &sub_iter);
+		ret = any_from_dbus_iter(&sub_iter);
+	} break;
+	case DBUS_TYPE_STRING: {
+		const char* v;
+		dbus_message_iter_get_basic(iter, &v);
+		ret = std::string(v);
+	} break;
+	case DBUS_TYPE_BOOLEAN: {
+		dbus_bool_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		ret = bool(v);
+	} break;
+	case DBUS_TYPE_BYTE: {
+		uint8_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		ret = v;
+	} break;
+	case DBUS_TYPE_DOUBLE: {
+		double v;
+		dbus_message_iter_get_basic(iter, &v);
+		ret = v;
+	} break;
+	case DBUS_TYPE_UINT16: {
+		uint16_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		ret = v;
+	} break;
+	case DBUS_TYPE_INT16: {
+		int16_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		ret = v;
+	} break;
+	case DBUS_TYPE_UINT32: {
+		uint32_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		ret = v;
+	} break;
+	case DBUS_TYPE_INT32: {
+		int32_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		ret = v;
+	} break;
+	case DBUS_TYPE_UINT64: {
+		uint16_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		ret = v;
+	} break;
+	case DBUS_TYPE_INT64: {
+		int64_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		ret = v;
+	} break;
+	}
+
+	return ret;
+}
+
+void
+DBUSHelpers::append_any_to_dbus_iter(
+    DBusMessageIter *iter, const boost::any &value
+    )
+{
+	if (value.type() == typeid(std::string)) {
+		std::string v = boost::any_cast<std::string>(value);
+		const char* cstr = v.c_str();
+		dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &cstr);
+	} else if (value.type() == typeid(char*)) {
+		std::string v = boost::any_cast<char*>(value);
+		const char* cstr = v.c_str();
+		dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &cstr);
+	} else if (value.type() == typeid(bool)) {
+		dbus_bool_t v = boost::any_cast<bool>(value);
+		dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &v);
+	} else if (value.type() == typeid(uint8_t)) {
+		uint8_t v = boost::any_cast<uint8_t>(value);
+		dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &v);
+	} else if (value.type() == typeid(int8_t)) {
+		int16_t v = boost::any_cast<int8_t>(value);
+		dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &v);
+	} else if (value.type() == typeid(uint16_t)) {
+		uint16_t v = boost::any_cast<uint16_t>(value);
+		dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &v);
+	} else if (value.type() == typeid(int16_t)) {
+		int16_t v = boost::any_cast<int16_t>(value);
+		dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &v);
+	} else if (value.type() == typeid(uint32_t)) {
+		uint32_t v = boost::any_cast<uint32_t>(value);
+		dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &v);
+	} else if (value.type() == typeid(int32_t)) {
+		int32_t v = boost::any_cast<int32_t>(value);
+		dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &v);
+	} else if (value.type() == typeid(uint64_t)) {
+		uint64_t v = boost::any_cast<uint64_t>(value);
+		dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &v);
+	} else if (value.type() == typeid(int64_t)) {
+		int64_t v = boost::any_cast<int64_t>(value);
+		dbus_message_iter_append_basic(iter, DBUS_TYPE_INT64, &v);
+	} else if (value.type() == typeid(double)) {
+		double v = boost::any_cast<double>(value);
+		dbus_message_iter_append_basic(iter, DBUS_TYPE_DOUBLE, &v);
+	} else if (value.type() == typeid(float)) {
+		double v = boost::any_cast<float>(value);
+		dbus_message_iter_append_basic(iter, DBUS_TYPE_DOUBLE, &v);
+	} else if (value.type() == typeid(std::list<std::string>)) {
+		DBusMessageIter array_iter;
+		const std::list<std::string>& list_of_strings =
+		    boost::any_cast< std::list<std::string> >(value);
+		std::list<std::string>::const_iterator list_iter;
+		dbus_message_iter_open_container(
+		    iter,
+		    DBUS_TYPE_ARRAY,
+		    DBUS_TYPE_STRING_AS_STRING,
+		    &array_iter
+		    );
+
+		for (list_iter = list_of_strings.begin();
+		     list_iter != list_of_strings.end();
+		     list_iter++) {
+			const char* cstr = list_iter->c_str();
+			dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING,
+			                               &cstr);
+		}
+
+		dbus_message_iter_close_container(iter, &array_iter);
+
+	} else if (value.type() == typeid(std::set<std::string>)) {
+		DBusMessageIter array_iter;
+		const std::set<std::string>& set_of_strings =
+		    boost::any_cast< std::set<std::string> >(value);
+		std::set<std::string>::const_iterator set_iter;
+		dbus_message_iter_open_container(
+		    iter,
+		    DBUS_TYPE_ARRAY,
+		    DBUS_TYPE_STRING_AS_STRING,
+		    &array_iter
+		    );
+
+		for (set_iter = set_of_strings.begin();
+		     set_iter != set_of_strings.end();
+		     set_iter++) {
+			const char* cstr = set_iter->c_str();
+			dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING,
+			                               &cstr);
+		}
+
+		dbus_message_iter_close_container(iter, &array_iter);
+	} else if (value.type() == typeid(nl::Data)) {
+		DBusMessageIter array_iter;
+		const nl::Data& vector = boost::any_cast< nl::Data >(value);
+		nl::Data::const_iterator vector_iter;
+		dbus_message_iter_open_container(
+		    iter,
+		    DBUS_TYPE_ARRAY,
+		    DBUS_TYPE_BYTE_AS_STRING,
+		    &array_iter
+		    );
+
+		for (vector_iter = vector.begin();
+		     vector_iter != vector.end();
+		     vector_iter++) {
+			dbus_message_iter_append_basic(&array_iter,
+			                               DBUS_TYPE_BYTE,
+			                               &*vector_iter);
+		}
+
+		dbus_message_iter_close_container(iter, &array_iter);
+	} else if (value.type() == typeid(std::vector<uint8_t>)) {
+		DBusMessageIter array_iter;
+		const std::vector<uint8_t>& vector =
+		    boost::any_cast< std::vector<uint8_t> >(value);
+		std::vector<uint8_t>::const_iterator vector_iter;
+		dbus_message_iter_open_container(
+		    iter,
+		    DBUS_TYPE_ARRAY,
+		    DBUS_TYPE_BYTE_AS_STRING,
+		    &array_iter
+		    );
+
+		for (vector_iter = vector.begin();
+		     vector_iter != vector.end();
+		     vector_iter++) {
+			dbus_message_iter_append_basic(&array_iter,
+			                               DBUS_TYPE_BYTE,
+			                               &*vector_iter);
+		}
+
+		dbus_message_iter_close_container(iter, &array_iter);
+	} else if (value.type() == typeid(std::set<int>)) {
+		DBusMessageIter array_iter;
+		const std::set<int>& container =
+		    boost::any_cast< std::set<int> >(value);
+		std::set<int>::const_iterator container_iter;
+		dbus_message_iter_open_container(
+		    iter,
+		    DBUS_TYPE_ARRAY,
+		    DBUS_TYPE_INT32_AS_STRING,
+		    &array_iter
+		    );
+
+		for (container_iter = container.begin();
+		     container_iter != container.end();
+		     container_iter++) {
+			dbus_message_iter_append_basic(&array_iter,
+			                               DBUS_TYPE_INT32,
+			                               &*container_iter);
+		}
+
+		dbus_message_iter_close_container(iter, &array_iter);
+	} else if (value.type() == typeid(nl::ValueMap)) {
+		DBusMessageIter array_iter;
+		const nl::ValueMap& value_map = boost::any_cast<nl::ValueMap>(value);
+		nl::ValueMap::const_iterator value_map_iter;
+
+		// Open a container as "Dictionary/Array of Strings to Variants" (dbus type "a{sv}")
+		dbus_message_iter_open_container(
+			iter,
+			DBUS_TYPE_ARRAY,
+			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+				DBUS_TYPE_STRING_AS_STRING
+				DBUS_TYPE_VARIANT_AS_STRING
+			DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+			&array_iter
+			);
+
+		for (value_map_iter = value_map.begin(); value_map_iter != value_map.end(); ++value_map_iter) {
+			append_dict_entry(&array_iter, value_map_iter->first.c_str(), value_map_iter->second);
+		}
+
+		dbus_message_iter_close_container(iter, &array_iter);
+	} else if (value.type() == typeid(std::list<nl::ValueMap>)) {
+		DBusMessageIter array_iter;
+		const std::list<nl::ValueMap>& value_map_list = boost::any_cast< std::list<nl::ValueMap> >(value);
+		std::list<nl::ValueMap>::const_iterator list_iter;
+
+		// Open a container as "Array of Dictionaries/Arrays of Strings to Variants" (dbus type "aa{sv}")
+		dbus_message_iter_open_container(
+			iter,
+			DBUS_TYPE_ARRAY,
+			DBUS_TYPE_ARRAY_AS_STRING
+				DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+					DBUS_TYPE_STRING_AS_STRING
+					DBUS_TYPE_VARIANT_AS_STRING
+				DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
+			&array_iter
+			);
+
+		for (list_iter = value_map_list.begin(); list_iter != value_map_list.end(); ++list_iter) {
+			append_any_to_dbus_iter(&array_iter, *list_iter);
+		}
+
+		dbus_message_iter_close_container(iter, &array_iter);
+	} else {
+		throw std::invalid_argument("Unsupported type");
+	}
+}
+
+std::string
+DBUSHelpers::any_to_dbus_type_string(const boost::any &value)
+{
+	if (value.type() == typeid(std::string)) {
+		return DBUS_TYPE_STRING_AS_STRING;
+	} else if (value.type() == typeid(bool)) {
+		return DBUS_TYPE_BOOLEAN_AS_STRING;
+	} else if (value.type() == typeid(uint8_t)) {
+		return DBUS_TYPE_BYTE_AS_STRING;
+	} else if (value.type() == typeid(int8_t)) {
+		return DBUS_TYPE_INT16_AS_STRING;
+	} else if (value.type() == typeid(uint16_t)) {
+		return DBUS_TYPE_UINT16_AS_STRING;
+	} else if (value.type() == typeid(int16_t)) {
+		return DBUS_TYPE_INT16_AS_STRING;
+	} else if (value.type() == typeid(uint32_t)) {
+		return DBUS_TYPE_UINT32_AS_STRING;
+	} else if (value.type() == typeid(int32_t)) {
+		return DBUS_TYPE_INT32_AS_STRING;
+	} else if (value.type() == typeid(uint64_t)) {
+		return DBUS_TYPE_UINT64_AS_STRING;
+	} else if (value.type() == typeid(int64_t)) {
+		return DBUS_TYPE_INT64_AS_STRING;
+	} else if (value.type() == typeid(double)) {
+		return DBUS_TYPE_DOUBLE_AS_STRING;
+	} else if (value.type() == typeid(float)) {
+		return DBUS_TYPE_DOUBLE_AS_STRING;
+	} else if (value.type() == typeid(nl::Data)) {
+		return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
+	} else if (value.type() == typeid(std::vector<uint8_t>)) {
+		return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
+	} else if (value.type() == typeid(std::list<std::string>)) {
+		return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING;
+	} else if (value.type() == typeid(std::set<std::string>)) {
+		return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING;
+	} else if (value.type() == typeid(nl::ValueMap)) {
+		return std::string(DBUS_TYPE_ARRAY_AS_STRING) +
+					DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING +
+						DBUS_TYPE_STRING_AS_STRING +
+						DBUS_TYPE_VARIANT_AS_STRING +
+					DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
+	} else if (value.type() == typeid(std::list<nl::ValueMap>)) {
+		return  std::string(DBUS_TYPE_ARRAY_AS_STRING) +
+					DBUS_TYPE_ARRAY_AS_STRING +
+						DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING +
+							DBUS_TYPE_STRING_AS_STRING +
+							DBUS_TYPE_VARIANT_AS_STRING +
+						DBUS_DICT_ENTRY_END_CHAR_AS_STRING;
+	}
+
+	return "";
+}
+
+void
+DBUSHelpers::append_dict_entry(
+    DBusMessageIter *dict, const char *key, const boost::any& value
+    )
+{
+	DBusMessageIter entry;
+	DBusMessageIter value_iter;
+	std::string sig = any_to_dbus_type_string(value);
+
+	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
+
+	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+
+	dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
+	                                 sig.c_str(), &value_iter);
+
+	append_any_to_dbus_iter(&value_iter, value);
+
+	dbus_message_iter_close_container(&entry, &value_iter);
+
+	dbus_message_iter_close_container(dict, &entry);
+}
+
+void
+DBUSHelpers::append_dict_entry(
+    DBusMessageIter *dict, const char *key, char type, void *val
+    )
+{
+	DBusMessageIter entry;
+	DBusMessageIter value_iter;
+	char sig[2] = { type, '\0' };
+
+	if (type == DBUS_TYPE_STRING) {
+		const char *str = *((const char**)val);
+		if (str == NULL)
+			return;
+	}
+
+	dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
+
+	dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+
+	dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT, sig,
+	                                 &value_iter);
+
+	dbus_message_iter_append_basic(&value_iter, type, val);
+
+	dbus_message_iter_close_container(&entry, &value_iter);
+
+	dbus_message_iter_close_container(dict, &entry);
+}
diff --git a/src/util/DBUSHelpers.h b/src/util/DBUSHelpers.h
new file mode 100644
index 0000000..3925319
--- /dev/null
+++ b/src/util/DBUSHelpers.h
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Declaration of various helper functions related to DBus
+ *      funcitonality.
+ *
+ */
+
+#ifndef __wpantund__DBUSHelpers__
+#define __wpantund__DBUSHelpers__
+
+#include <boost/any.hpp>
+#include <dbus/dbus.h>
+#include <string>
+#include "ValueMap.h"
+
+namespace DBUSHelpers {
+nl::ValueMap value_map_from_dbus_iter(DBusMessageIter *iter);
+boost::any any_from_dbus_iter(DBusMessageIter *iter);
+void append_any_to_dbus_iter(DBusMessageIter *iter, const boost::any &value);
+std::string any_to_dbus_type_string(const boost::any &value);
+void append_dict_entry(DBusMessageIter *dict, const char *key, const boost::any& value);
+void append_dict_entry(DBusMessageIter *dict, const char *key, char type, void *val);
+};
+
+#endif /* defined(__wpantund__DBUSHelpers__) */
diff --git a/src/util/Data.cpp b/src/util/Data.cpp
new file mode 100644
index 0000000..e4541ae
--- /dev/null
+++ b/src/util/Data.cpp
@@ -0,0 +1,23 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Empty.
+ *
+ */
+
+#include "Data.h"
diff --git a/src/util/Data.h b/src/util/Data.h
new file mode 100644
index 0000000..f94637f
--- /dev/null
+++ b/src/util/Data.h
@@ -0,0 +1,71 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Class definition for binary data container.
+ *
+ */
+
+#ifndef __wpantund__Data__
+#define __wpantund__Data__
+
+#include <vector>
+#include <stdint.h>
+#include <stdlib.h>
+
+namespace nl {
+class Data : public std::vector<uint8_t> {
+public:
+	Data(const std::vector<uint8_t>& x) : std::vector<uint8_t>(x) {
+	}
+	Data(
+	    const uint8_t* ptr, size_t len
+	    ) : std::vector<uint8_t>(ptr, ptr + len) {
+	}
+
+	template<typename _InputIterator>
+	Data(_InputIterator __first, _InputIterator __last)
+	: std::vector<uint8_t>(__first, __last) { }
+
+	Data(size_t len = 0) : std::vector<uint8_t>(len) {
+	}
+
+	Data& append(const Data& d) {
+		insert(end(),d.begin(),d.end());
+		return *this;
+	}
+
+	Data& append(const uint8_t* ptr, size_t len) {
+		insert(end(),ptr,ptr+len);
+		return *this;
+	}
+
+	void pop_front(size_t len) {
+		erase(begin(), begin()+len);
+	}
+
+	uint8_t* data() {
+		return &*begin();
+	}
+
+	const uint8_t* data() const {
+		return &*begin();
+	}
+};
+};
+
+#endif /* defined(__wpantund__Data__) */
diff --git a/src/util/EventHandler.cpp b/src/util/EventHandler.cpp
new file mode 100644
index 0000000..3ddbe59
--- /dev/null
+++ b/src/util/EventHandler.cpp
@@ -0,0 +1,76 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "EventHandler.h"
+
+using namespace nl;
+
+EventHandler::EventHandler():
+	mControlPT(), mControlTime()
+{
+	PT_INIT(&mControlPT);
+}
+
+EventHandler::~EventHandler()
+{
+}
+
+cms_t
+EventHandler::get_ms_to_next_event()
+{
+	cms_t cms = CMS_DISTANT_FUTURE;
+
+	if (mControlTime) {
+		cms = mControlTime - time_ms();
+
+		if (cms < 0) {
+			cms = 0;
+		}
+	}
+
+	return cms;
+
+}
+
+void
+EventHandler::schedule_next_event(float seconds_until_event)
+{
+	mControlTime = time_ms() + (cms_t)(seconds_until_event * MSEC_PER_SEC);
+}
+
+void
+EventHandler::unschedule_next_event(void)
+{
+	mControlTime = 0;
+}
+
+int
+EventHandler::process_event(int event, ...)
+{
+	int ret;
+	va_list args;
+	va_start(args, event);
+	ret = vprocess_event(event, args);
+	va_end(args);
+	return ret;
+}
diff --git a/src/util/EventHandler.h b/src/util/EventHandler.h
new file mode 100644
index 0000000..af430a5
--- /dev/null
+++ b/src/util/EventHandler.h
@@ -0,0 +1,110 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__EventHandler__
+#define __wpantund__EventHandler__
+
+#include <cstdio>
+#include <cstdarg>
+#include <boost/signals2/signal.hpp>
+
+#include "assert-macros.h"
+#include "time-utils.h"
+#include "nlpt.h"
+
+namespace nl {
+
+#define EVENT_NULL		0
+#define EVENT_IDLE		1
+#define EVENT_STARTING_TASK		2
+
+#define EH_BEGIN_SUB(pt)	{ bool eh_did_timeout(false); PT*const __eh_pt = (pt); (void)eh_did_timeout; PT_BEGIN(__eh_pt)
+#define EH_BEGIN()			EH_BEGIN_SUB(&mControlPT)
+#define EH_END()			PT_END(__eh_pt) }
+
+#define EH_SPAWN(child, proc)	PT_SPAWN(__eh_pt, (child), (proc))
+
+// Explicitly terminate the protothread.
+#define EH_EXIT()		PT_EXIT(__eh_pt)
+
+// Explicitly restart the protothread.
+#define EH_RESTART()	PT_RESTART(__eh_pt)
+
+// Yield execution for one cycle.
+#define EH_YIELD()		PT_YIELD(__eh_pt)
+
+// Suspend execution until condition `c` is satisfied.
+#define EH_WAIT_UNTIL(c) PT_WAIT_UNTIL(__eh_pt, c)
+
+// Suspend execution until condition `c` is satisfied.
+#define EH_YIELD_UNTIL(c) PT_YIELD_UNTIL(__eh_pt, c)
+
+// Unconditionally suspend execution for `s` seconds.
+#define EH_SLEEP_FOR(s) do { \
+		schedule_next_event(s); \
+		EH_YIELD_UNTIL(EventHandler::get_ms_to_next_event() == 0); \
+		unschedule_next_event(); \
+	} while (0)
+
+// Wait for condition `c` be satisfied for no more than `s` seconds.
+#define EH_WAIT_UNTIL_WITH_TIMEOUT(s, c) do { \
+		eh_did_timeout = false; \
+		schedule_next_event(s); \
+		EH_WAIT_UNTIL((c) || (eh_did_timeout=(EventHandler::get_ms_to_next_event() == 0))); \
+		unschedule_next_event(); \
+	} while (0)
+
+// Require that condition `c` be satisfied within `s` seconds. If not, goto `l`.
+#define EH_REQUIRE_WITHIN(s, c, l) do { \
+		EH_WAIT_UNTIL_WITH_TIMEOUT(s, c); \
+		require_string(!eh_did_timeout, l, # c); \
+	} while (0)
+
+
+// This class is the base class for tasks (like joining or forming).
+// They allow you to implement complex, stateful processes without being
+// too unwieldly.
+class EventHandler
+{
+public:
+	typedef struct pt PT;
+
+	EventHandler();
+
+	virtual ~EventHandler();
+
+	virtual cms_t get_ms_to_next_event();
+
+	virtual int vprocess_event(int event, va_list args) = 0;
+
+	int process_event(int event, ...);
+
+	void schedule_next_event(float seconds_until_event);
+	void unschedule_next_event(void);
+
+public:
+	PT mControlPT;
+
+private:
+	cms_t mControlTime;
+};
+
+}; // namespace nl
+
+#endif /* defined(__wpantund__EventHandler__) */
diff --git a/src/util/IPv6Helpers.cpp b/src/util/IPv6Helpers.cpp
new file mode 100644
index 0000000..21fd2d5
--- /dev/null
+++ b/src/util/IPv6Helpers.cpp
@@ -0,0 +1,64 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file contains helper glue code for manipulating IPv6 addresses.
+ *
+ */
+
+#include "IPv6Helpers.h"
+
+std::string
+in6_addr_to_string(const struct in6_addr &addr)
+{
+	char address_string[INET6_ADDRSTRLEN] = "::";
+	inet_ntop(AF_INET6, (const void *)&addr, address_string, sizeof(address_string));
+	return std::string(address_string);
+}
+
+struct in6_addr
+make_slaac_addr_from_eui64(const uint8_t prefix[8], const uint8_t eui64[8])
+{
+	struct in6_addr ret;
+
+	// Construct the IPv6 address from the prefix and EUI64.
+	memcpy(&ret.s6_addr[0], prefix, 8);
+	memcpy(&ret.s6_addr[8], eui64, 8);
+
+	// Flip the administratively assigned bit.
+	ret.s6_addr[8] ^= 0x02;
+
+	return ret;
+}
+
+void
+in6_addr_apply_mask(struct in6_addr &address, uint8_t mask)
+{
+	if (mask > 128) {
+		mask = 128;
+	}
+
+	memset(
+		(void*)(address.s6_addr + ((mask + 7) / 8)),
+		0,
+		16 - ((mask + 7) / 8)
+	);
+
+	if (mask % 8) {
+		address.s6_addr[mask / 8] &= ~(0xFF >> (mask % 8));
+	}
+}
diff --git a/src/util/IPv6Helpers.h b/src/util/IPv6Helpers.h
new file mode 100644
index 0000000..2bc3ef6
--- /dev/null
+++ b/src/util/IPv6Helpers.h
@@ -0,0 +1,72 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file contains helper glue code for manipulating IPv6 addresses.
+ *
+ */
+
+#ifndef wpantund_IPv6Helpers_h
+#define wpantund_IPv6Helpers_h
+
+#include <stdint.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <string>
+
+#define MINIMUM_IPV6_PACKET_SIZE	40
+
+#define IPV6_MAX_PREFIX_LENGTH                  128
+#define IPV6_NETWORK_PREFIX_LENGTH              64
+
+#define IPV6_PREFIX_BITS_TO_BYTES(x)		((static_cast<uint8_t>(x)+7)/8)
+#define IPV6_PREFIX_BYTES_TO_BITS(x)		(static_cast<uint8_t>(x)*8)
+
+#define IPV6_MAX_LIFETIME					UINT32_MAX
+
+static inline bool
+operator==(const struct in6_addr &lhs, const struct in6_addr &rhs)
+{
+	return 0 == memcmp((const void*)&lhs, (const void*)&rhs, sizeof(rhs));
+}
+
+static inline bool
+operator!=(const struct in6_addr &lhs, const struct in6_addr &rhs)
+{
+	return !(lhs == rhs);
+}
+
+static inline bool
+operator<(const struct in6_addr &lhs, const struct in6_addr &rhs)
+{
+	return memcmp(lhs.s6_addr, rhs.s6_addr, sizeof(struct in6_addr)) < 0;
+}
+
+static inline bool
+is_valid_ipv6_packet(const uint8_t* packet, ssize_t len) {
+	return (len > MINIMUM_IPV6_PACKET_SIZE)
+		&& (packet[0] & 0xF0) == 0x60; // IPv6 Version
+}
+
+std::string in6_addr_to_string(const struct in6_addr &addr);
+
+struct in6_addr make_slaac_addr_from_eui64(const uint8_t prefix[8], const uint8_t eui64[8]);
+
+void in6_addr_apply_mask(struct in6_addr &address, uint8_t mask);
+
+
+#endif
diff --git a/src/util/IPv6PacketMatcher.cpp b/src/util/IPv6PacketMatcher.cpp
new file mode 100644
index 0000000..9455ad7
--- /dev/null
+++ b/src/util/IPv6PacketMatcher.cpp
@@ -0,0 +1,550 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "IPv6PacketMatcher.h"
+#include <syslog.h>
+#include <stdio.h>
+
+#ifndef IPV6_PACKET_MATCHER_DEBUG
+#define IPV6_PACKET_MATCHER_DEBUG 0
+#endif
+
+using namespace nl;
+
+const uint8_t IPv6PacketMatcherRule::TYPE_ALL = 0xFF;
+const uint8_t IPv6PacketMatcherRule::TYPE_NONE = 0xFE;
+const uint8_t IPv6PacketMatcherRule::TYPE_UDP = 17;
+const uint8_t IPv6PacketMatcherRule::TYPE_TCP = 6;
+const uint8_t IPv6PacketMatcherRule::TYPE_ICMP = 58;
+const uint8_t IPv6PacketMatcherRule::TYPE_HOP_BY_HOP = 0;
+
+const uint8_t IPv6PacketMatcherRule::SUBTYPE_ALL = 0xFF;
+const uint8_t IPv6PacketMatcherRule::SUBTYPE_ICMP_NEIGHBOR_ADV = 136;
+const uint8_t IPv6PacketMatcherRule::SUBTYPE_ICMP_NEIGHBOR_SOL = 135;
+const uint8_t IPv6PacketMatcherRule::SUBTYPE_ICMP_ROUTER_SOL = 133;
+const uint8_t IPv6PacketMatcherRule::SUBTYPE_ICMP_ROUTER_ADV = 134;
+
+#define IPV6_HEADER_LENGTH              40
+#define IPV6_TCP_HEADER_CHECKSUM_OFFSET (IPV6_HEADER_LENGTH + 16)
+#define IPV6_UDP_HEADER_CHECKSUM_OFFSET (IPV6_HEADER_LENGTH + 6)
+
+#define PACKET_IS_IPV6(x)        ((static_cast<const uint8_t*>(x)[0] & 0xF0) == 0x60)
+#define IPV6_GET_TYPE(x)         (static_cast<const uint8_t*>(x)[6])
+#define IPV6_GET_SRC_PORT(x)     (in_port_t)(*(const uint16_t*)((const uint8_t*)(x)+40))
+#define IPV6_GET_DEST_PORT(x)    (in_port_t)(*(const uint16_t*)((const uint8_t*)(x)+42))
+#define IPV6_GET_SRC_ADDR(t,f)   memcpy(&t, static_cast<const uint8_t*>(f) + 8, 16)
+#define IPV6_GET_DEST_ADDR(t,f)  memcpy(&t, static_cast<const uint8_t*>(f) + 24, 16)
+#define IPV6_ICMP_GET_SUBTYPE(x) (static_cast<const uint8_t*>(x)[40])
+#define IPv6_TCP_GET_CHECKSUM(p,l)  IPV6_GET_UINT16(p, l, IPV6_TCP_HEADER_CHECKSUM_OFFSET)
+#define IPv6_UDP_GET_CHECKSUM(p,l)  IPV6_GET_UINT16(p, l, IPV6_UDP_HEADER_CHECKSUM_OFFSET)
+
+static inline uint16_t IPV6_GET_UINT16(const uint8_t *packet, ssize_t len, size_t offset)
+{
+	uint16_t ret;
+
+	ret = (len >= offset + sizeof(uint16_t))
+		? (packet[offset]<<8) | (packet[offset + 1]<<0)
+		: 0;
+
+	return ret;
+}
+
+static void ipv6_add_extra_description(char *buffer, size_t buffer_size, const uint8_t *packet, ssize_t len)
+{
+	uint8_t type(IPV6_GET_TYPE(packet));
+
+	switch (type)
+	{
+	case IPv6PacketMatcherRule::TYPE_TCP:
+		snprintf(buffer, buffer_size, "(cksum 0x%04x)", IPv6_TCP_GET_CHECKSUM(packet, len));
+		break;
+
+	case IPv6PacketMatcherRule::TYPE_UDP:
+		snprintf(buffer, buffer_size, "(cksum 0x%04x)", IPv6_UDP_GET_CHECKSUM(packet, len));
+		break;
+
+	default:
+		buffer[0] = 0;
+	}
+}
+
+void
+IPv6PacketMatcherRule::clear()
+{
+	memset((void*)this, 0, sizeof(*this));
+	type = TYPE_ALL;
+	subtype = SUBTYPE_ALL;
+}
+
+IPv6PacketMatcherRule&
+IPv6PacketMatcherRule::update_from_inbound_packet(const uint8_t* packet)
+{
+	struct in6_addr address;
+
+	clear();
+
+	if (!PACKET_IS_IPV6(packet)) {
+		goto bail;
+	}
+
+	type = IPV6_GET_TYPE(packet);
+
+	subtype = IPv6PacketMatcherRule::SUBTYPE_ALL;
+
+	if (type == IPv6PacketMatcherRule::TYPE_TCP || type == IPv6PacketMatcherRule::TYPE_UDP) {
+		remote_port = IPV6_GET_SRC_PORT(packet);
+		remote_port_match = true;
+
+		local_port = IPV6_GET_DEST_PORT(packet);
+		local_port_match = true;
+	} else {
+		remote_port = 0;
+		remote_port_match = false;
+		local_port = 0;
+		local_port_match = false;
+		if (type == IPv6PacketMatcherRule::TYPE_ICMP) {
+			subtype = IPV6_ICMP_GET_SUBTYPE(packet);
+		}
+	}
+
+	IPV6_GET_DEST_ADDR(address, packet);
+	if (!IN6_IS_ADDR_MULTICAST(&address)) {
+		local_address = address;
+		local_match_mask = 128;
+	} else {
+		local_match_mask = 0;
+	}
+
+	IPV6_GET_SRC_ADDR(address, packet);
+	remote_address = address;
+	remote_match_mask = 128;
+
+bail:
+	return *this;
+}
+
+
+bool
+IPv6PacketMatcherRule::match_inbound(const uint8_t* packet) const
+{
+	if (!PACKET_IS_IPV6(packet)) {
+		return false;
+	}
+
+	if (type == TYPE_NONE) {
+		return false;
+	}
+
+	if (type != IPv6PacketMatcherRule::TYPE_ALL) {
+		if (type != IPV6_GET_TYPE(packet)) {
+			return false;
+		}
+		if (subtype != IPv6PacketMatcherRule::SUBTYPE_ALL) {
+			if (subtype != IPV6_ICMP_GET_SUBTYPE(packet)) {
+				return false;
+			}
+		}
+	}
+
+	if (local_port_match) {
+		in_port_t port(IPV6_GET_DEST_PORT(packet));
+		if (port != local_port)
+			return false;
+	}
+
+	if (remote_port_match) {
+		in_port_t port(IPV6_GET_SRC_PORT(packet));
+		if (port != remote_port)
+			return false;
+	}
+
+	if (local_match_mask) {
+		struct in6_addr address;
+		IPV6_GET_DEST_ADDR(address, packet);
+		in6_addr_apply_mask(address, local_match_mask);
+		if (address != local_address)
+			return false;
+	}
+
+	if (remote_match_mask) {
+		struct in6_addr address;
+		IPV6_GET_SRC_ADDR(address, packet);
+		in6_addr_apply_mask(address, remote_match_mask);
+		if (address != remote_address)
+			return false;
+	}
+	return true;
+}
+
+IPv6PacketMatcherRule&
+IPv6PacketMatcherRule::update_from_outbound_packet(const uint8_t* packet)
+{
+	struct in6_addr address;
+
+	clear();
+
+	if (!PACKET_IS_IPV6(packet)) {
+		goto bail;
+	}
+
+	type = IPV6_GET_TYPE(packet);
+
+	subtype = IPv6PacketMatcherRule::SUBTYPE_ALL;
+
+	if (type == IPv6PacketMatcherRule::TYPE_TCP || type == IPv6PacketMatcherRule::TYPE_UDP) {
+		remote_port = IPV6_GET_DEST_PORT(packet);
+		remote_port_match = true;
+
+		local_port = IPV6_GET_SRC_PORT(packet);
+		local_port_match = true;
+	} else {
+		remote_port = 0;
+		remote_port_match = false;
+		local_port = 0;
+		local_port_match = false;
+		if (type == IPv6PacketMatcherRule::TYPE_ICMP) {
+			subtype = IPV6_ICMP_GET_SUBTYPE(packet);
+		}
+	}
+
+	IPV6_GET_SRC_ADDR(address, packet);
+	local_address = address;
+	local_match_mask = 128;
+
+	IPV6_GET_DEST_ADDR(address, packet);
+	remote_address = address;
+	remote_match_mask = 128;
+
+bail:
+	return *this;
+}
+
+bool
+IPv6PacketMatcherRule::match_outbound(const uint8_t* packet) const
+{
+	if (!PACKET_IS_IPV6(packet)) {
+		return false;
+	}
+
+	if (type == TYPE_NONE) {
+		return false;
+	}
+
+	if (type != IPv6PacketMatcherRule::TYPE_ALL) {
+		if (type != IPV6_GET_TYPE(packet)) {
+			return false;
+		}
+		if (subtype != IPv6PacketMatcherRule::SUBTYPE_ALL) {
+			if (subtype != IPV6_ICMP_GET_SUBTYPE(packet)) {
+				return false;
+			}
+		}
+	}
+
+	if (local_port_match) {
+		in_port_t port(IPV6_GET_SRC_PORT(packet));
+		if (port != local_port) {
+			return false;
+		}
+	}
+
+	if (remote_port_match) {
+		in_port_t port(IPV6_GET_DEST_PORT(packet));
+		if (port != remote_port) {
+			return false;
+		}
+	}
+
+	if (local_match_mask) {
+		struct in6_addr address;
+		IPV6_GET_SRC_ADDR(address, packet);
+		in6_addr_apply_mask(address, local_match_mask);
+		if (address != local_address) {
+			return false;
+		}
+	}
+
+	if (remote_match_mask) {
+		struct in6_addr address;
+		IPV6_GET_DEST_ADDR(address, packet);
+		in6_addr_apply_mask(address, remote_match_mask);
+		if (address != remote_address) {
+			return false;
+		}
+	}
+	return true;
+}
+
+bool
+IPv6PacketMatcherRule::operator==(const IPv6PacketMatcherRule& lhs) const
+{
+#if IPV6_PACKET_MATCHER_DEBUG
+	syslog(LOG_DEBUG, "IPv6PacketMatcherRule operator==():\n");
+
+#define __DUMP(x,f,t) syslog(LOG_DEBUG, "\t lhs." #x "=" f "\t%s\trhs." #x "=" f "\n",(t)lhs.x,(lhs.x < x)?">":(x > lhs.x)?">":"==",(t)x);
+#define __DUMP_NTOHS(x,f) syslog(LOG_DEBUG, "\t lhs." #x "=" f "\t%s\trhs." #x "=" f "\n",ntohs(lhs.x),(ntohs(lhs.x) < ntohs(x))?">":(ntohs(x) > ntohs(lhs.x))?">":"==",ntohs(x));
+#define __DUMP_MEM(x) syslog(LOG_DEBUG, "\t lhs." #x "\t%s\trhs." #x "\n",(memcmp(&x, &lhs.x, 16) < 0)?">":(memcmp(&x, &lhs.x, 16) > 0)?">":"==");
+
+	__DUMP(type,"%d",int);
+	__DUMP(subtype,"%d",int);
+	__DUMP_NTOHS(local_port,"%d");
+	__DUMP(local_port_match,"%d",int);
+	__DUMP(local_match_mask,"%d",int);
+	__DUMP_MEM(local_address);
+
+	__DUMP_NTOHS(remote_port,"%d");
+	__DUMP(remote_port_match,"%d",int);
+	__DUMP(remote_match_mask,"%d",int);
+	__DUMP_MEM(remote_address);
+
+#undef __DUMP
+#undef __DUMP_NTOHS
+#undef __DUMP_MEM
+
+#endif // IPV6_PACKET_MATCHER_DEBUG
+
+	if (type != lhs.type) {
+		return false;
+	}
+	if (subtype != lhs.subtype) {
+		return false;
+	}
+	if (local_port != lhs.local_port) {
+		return false;
+	}
+	if (local_port_match != lhs.local_port_match) {
+		return false;
+	}
+	if (local_match_mask != lhs.local_match_mask) {
+		return false;
+	}
+	if (local_address != lhs.local_address) {
+		return false;
+	}
+	if (remote_port != lhs.remote_port) {
+		return false;
+	}
+	if (remote_port_match != lhs.remote_port_match) {
+		return false;
+	}
+	if (remote_match_mask != lhs.remote_match_mask) {
+		return false;
+	}
+	if (remote_address != lhs.remote_address) {
+		return false;
+	}
+	return true;
+
+	return 0 == memcmp(this,
+	                   &lhs,
+	                   (uint8_t*)&remote_match_mask - (uint8_t*)this + 1);
+}
+
+bool
+IPv6PacketMatcherRule::operator<(const IPv6PacketMatcherRule& lhs) const
+{
+	if (type < lhs.type) {
+		return true;
+	} else if (type > lhs.type) {
+		return false;
+	}
+
+	if (subtype < lhs.subtype) {
+		return true;
+	} else if (subtype > lhs.subtype) {
+		return false;
+	}
+
+	if (local_port < lhs.local_port) {
+		return true;
+	} else if (local_port > lhs.local_port) {
+		return false;
+	}
+
+	if (local_port_match < lhs.local_port_match) {
+		return true;
+	} else if (local_port_match > lhs.local_port_match) {
+		return false;
+	}
+
+	if (local_match_mask < lhs.local_match_mask) {
+		return true;
+	} else if (local_match_mask > lhs.local_match_mask) {
+		return false;
+	}
+
+	if (memcmp(&local_address, &lhs.local_address, 16) < 0) {
+		return true;
+	} else if (memcmp(&local_address, &lhs.local_address, 16) > 0) {
+		return false;
+	}
+
+	if (remote_port < lhs.remote_port) {
+		return true;
+	} else if (remote_port > lhs.remote_port) {
+		return false;
+	}
+
+	if (remote_port_match < lhs.remote_port_match) {
+		return true;
+	} else if (remote_port_match > lhs.remote_port_match) {
+		return false;
+	}
+
+	if (remote_match_mask < lhs.remote_match_mask) {
+		return true;
+	} else if (remote_match_mask > lhs.remote_match_mask) {
+		return false;
+	}
+
+	if (memcmp(&remote_address, &lhs.remote_address, 16) < 0) {
+		return true;
+	} else if (memcmp(&remote_address, &lhs.remote_address, 16) > 0) {
+		return false;
+	}
+
+	return false;
+}
+
+IPv6PacketMatcher::const_iterator
+IPv6PacketMatcher::match_outbound(const uint8_t* packet) const
+{
+	iterator iter;
+	for(iter = begin(); iter != end(); ++iter) {
+		if(iter->match_outbound(packet)) {
+			break;
+		}
+	}
+	return iter;
+}
+
+IPv6PacketMatcher::const_iterator
+IPv6PacketMatcher::match_inbound(const uint8_t* packet) const
+{
+	iterator iter;
+	for(iter = begin(); iter != end(); ++iter) {
+		if(iter->match_inbound(packet)) {
+			break;
+		}
+	}
+	return iter;
+}
+
+void
+nl::dump_outbound_ipv6_packet(const uint8_t* packet, ssize_t len, const char* extra, bool dropped)
+{
+	if(!(setlogmask(0)&LOG_MASK(LOG_INFO))) {
+		return;
+	}
+	char to_addr_cstr[INET6_ADDRSTRLEN] = "::";
+	char from_addr_cstr[INET6_ADDRSTRLEN] = "::";
+	uint8_t type(IPV6_GET_TYPE(packet));
+	char type_extra[32];
+	struct in6_addr addr;
+
+	ipv6_add_extra_description(type_extra, sizeof(type_extra), packet, len);
+
+	syslog(LOG_INFO,
+		   "[->NCP] IPv6 len:%d type:%d%s [%s]%s",
+		   (int)len,
+		   type,
+		   type_extra,
+		   extra,
+		   dropped?" [DROPPED]":""
+	);
+
+	IPV6_GET_SRC_ADDR(addr, packet);
+	inet_ntop(AF_INET6, addr.s6_addr, from_addr_cstr, sizeof(from_addr_cstr));
+
+	IPV6_GET_DEST_ADDR(addr, packet);
+	inet_ntop(AF_INET6, addr.s6_addr, to_addr_cstr, sizeof(to_addr_cstr));
+
+	if ((type == IPv6PacketMatcherRule::TYPE_TCP)
+		|| (type == IPv6PacketMatcherRule::TYPE_UDP)
+	) {
+		in_port_t to_port(IPV6_GET_DEST_PORT(packet));
+		in_port_t from_port(IPV6_GET_SRC_PORT(packet));
+
+		syslog(LOG_INFO,
+			   "\tto(remote):[%s]:%d",
+			   to_addr_cstr,
+			   htons(to_port));
+
+		syslog(LOG_INFO,
+			   "\tfrom(local):[%s]:%d",
+			   from_addr_cstr,
+			   htons(from_port));
+	} else {
+		syslog(LOG_INFO, "\tto(remote):[%s]", to_addr_cstr);
+		syslog(LOG_INFO, "\tfrom(local):[%s]", from_addr_cstr);
+	}
+}
+
+void
+nl::dump_inbound_ipv6_packet(const uint8_t* packet, ssize_t len, const char* extra, bool dropped)
+{
+	if(!(setlogmask(0)&LOG_MASK(LOG_INFO))) {
+		return;
+	}
+	char to_addr_cstr[INET6_ADDRSTRLEN] = "::";
+	char from_addr_cstr[INET6_ADDRSTRLEN] = "::";
+	uint8_t type(IPV6_GET_TYPE(packet));
+	char type_extra[32];
+	struct in6_addr addr;
+
+	ipv6_add_extra_description(type_extra, sizeof(type_extra), packet, len);
+
+	syslog(LOG_INFO,
+		   "[NCP->] IPv6 len:%d type:%d%s [%s]%s",
+		   (int)len,
+		   type,
+		   type_extra,
+		   extra,
+		   dropped?" [DROPPED]":""
+	);
+
+	IPV6_GET_SRC_ADDR(addr, packet);
+	inet_ntop(AF_INET6, addr.s6_addr, from_addr_cstr, sizeof(from_addr_cstr));
+
+	IPV6_GET_DEST_ADDR(addr, packet);
+	inet_ntop(AF_INET6, addr.s6_addr, to_addr_cstr, sizeof(to_addr_cstr));
+	if ((type == IPv6PacketMatcherRule::TYPE_TCP)
+		|| (type == IPv6PacketMatcherRule::TYPE_UDP)
+	) {
+		in_port_t to_port(IPV6_GET_DEST_PORT(packet));
+		in_port_t from_port(IPV6_GET_SRC_PORT(packet));
+
+		syslog(LOG_INFO,
+			   "\tto(local):[%s]:%d",
+			   to_addr_cstr,
+			   htons(to_port));
+
+		syslog(LOG_INFO,
+			   "\tfrom(remote):[%s]:%d",
+			   from_addr_cstr,
+			   htons(from_port));
+	} else {
+		syslog(LOG_INFO, "\tto(local):[%s]", to_addr_cstr);
+		syslog(LOG_INFO, "\tfrom(remote):[%s]", from_addr_cstr);
+	}
+}
diff --git a/src/util/IPv6PacketMatcher.h b/src/util/IPv6PacketMatcher.h
new file mode 100644
index 0000000..f8e218a
--- /dev/null
+++ b/src/util/IPv6PacketMatcher.h
@@ -0,0 +1,84 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__IPv6PacketMatcherRule__
+#define __wpantund__IPv6PacketMatcherRule__
+
+#include <stdint.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <set>
+#include "IPv6Helpers.h"
+
+
+namespace nl {
+
+void dump_outbound_ipv6_packet(const uint8_t* packet, ssize_t len, const char* extra, bool dropped = false);
+void dump_inbound_ipv6_packet(const uint8_t* packet, ssize_t len, const char* extra, bool dropped = false);
+
+struct IPv6PacketMatcherRule {
+	static const uint8_t TYPE_ALL;
+	static const uint8_t TYPE_NONE;
+	static const uint8_t TYPE_UDP;
+	static const uint8_t TYPE_TCP;
+	static const uint8_t TYPE_ICMP;
+	static const uint8_t TYPE_HOP_BY_HOP;
+	static const uint8_t SUBTYPE_ALL;
+	static const uint8_t SUBTYPE_ICMP_NEIGHBOR_ADV;
+	static const uint8_t SUBTYPE_ICMP_NEIGHBOR_SOL;
+	static const uint8_t SUBTYPE_ICMP_ROUTER_ADV;
+	static const uint8_t SUBTYPE_ICMP_ROUTER_SOL;
+
+	uint8_t type;
+	uint8_t subtype;
+	in_port_t local_port;
+	bool local_port_match;
+	struct in6_addr local_address;
+	uint8_t local_match_mask;
+
+	in_port_t remote_port;
+	bool remote_port_match;
+	struct in6_addr remote_address;
+	uint8_t remote_match_mask;
+
+	void clear();
+	IPv6PacketMatcherRule&        update_from_inbound_packet(const uint8_t* packet);
+	bool                            match_inbound(const uint8_t* packet) const;
+	IPv6PacketMatcherRule&        update_from_outbound_packet(const uint8_t* packet);
+	bool                            match_outbound(const uint8_t* packet) const;
+	bool operator==(const IPv6PacketMatcherRule& lhs) const;
+	bool operator<(const IPv6PacketMatcherRule& lhs) const;
+
+	bool operator!=(const IPv6PacketMatcherRule& lhs) const { return !(*this == lhs); }
+	bool operator>=(const IPv6PacketMatcherRule& lhs) const { return !(*this < lhs); }
+
+	bool operator<=(const IPv6PacketMatcherRule& lhs) const { return (*this < lhs) || (*this == lhs); }
+	bool operator>(const IPv6PacketMatcherRule& lhs) const { return !(*this <= lhs); }
+};
+
+class IPv6PacketMatcher : public std::set<IPv6PacketMatcherRule> {
+public:
+
+	const_iterator match_outbound(const uint8_t* packet) const;
+	const_iterator match_inbound(const uint8_t* packet) const;
+};
+
+}; // namespace nl
+
+#endif /* defined(__wpantund__IPv6PacketMatcherRule__) */
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
new file mode 100644
index 0000000..2ae3942
--- /dev/null
+++ b/src/util/Makefile.am
@@ -0,0 +1,72 @@
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+EXTRA_DIST = \
+	config-file.c \
+	nlpt-select.c \
+	socket-utils.c \
+	string-utils.c \
+	time-utils.c \
+	tunnel.c \
+	DBUSHelpers.cpp \
+	Data.cpp \
+	EventHandler.cpp \
+	IPv6PacketMatcher.cpp \
+	SocketAdapter.cpp \
+	SocketWrapper.cpp \
+	SuperSocket.cpp \
+	TunnelIPv6Interface.cpp \
+	UnixSocket.cpp \
+	any-to.cpp \
+	Callbacks.h \
+	DBUSHelpers.h \
+	Data.h \
+	EventHandler.h \
+	IPv6Helpers.h \
+	IPv6Helpers.cpp \
+	IPv6PacketMatcher.h \
+	NilReturn.h \
+	SocketAdapter.h \
+	SocketAsyncOp.h \
+	SocketWrapper.h \
+	SuperSocket.h \
+	TunnelIPv6Interface.h \
+	UnixSocket.h \
+	any-to.h \
+	args.h \
+	config-file.h \
+	nlpt-select.h \
+	nlpt.h \
+	socket-utils.h \
+	string-utils.h \
+	time-utils.h \
+	tunnel.h \
+	CallbackStore.hpp \
+	RingBuffer.h \
+	ValueMap.h \
+	ValueMap.cpp \
+	ObjectPool.h \
+	Timer.h \
+	Timer.cpp \
+	sec-random.h \
+	sec-random.c \
+	$(NULL)
+
+DISTCLEANFILES = \
+	.deps \
+	Makefile \
+	$(NULL)
diff --git a/src/util/NilReturn.h b/src/util/NilReturn.h
new file mode 100644
index 0000000..c736be8
--- /dev/null
+++ b/src/util/NilReturn.h
@@ -0,0 +1,36 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef wpantund_NilReturn_h
+#define wpantund_NilReturn_h
+
+
+namespace nl {
+class NilReturn {
+public:
+	void operator()(void) {
+	}
+	void operator()(int) {
+	}
+	template<typename ARG_X, typename ARG_Y> void operator()(ARG_X, ARG_Y) {
+	}
+};
+};
+
+#endif
diff --git a/src/util/ObjectPool.h b/src/util/ObjectPool.h
new file mode 100644
index 0000000..493b3a1
--- /dev/null
+++ b/src/util/ObjectPool.h
@@ -0,0 +1,92 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      A simple object pool implementation
+ *
+ */
+
+#ifndef wpantund_ObjectPool_h
+#define wpantund_ObjectPool_h
+
+#include <list>
+
+namespace nl {
+
+template <typename T, int I = 64>
+class ObjectPool
+{
+public:
+	typedef T element_type;
+	typedef int size_type;
+
+	static const size_type pool_size = I;
+
+public:
+	ObjectPool(): mFreeElementList()
+	{
+		free_all();
+	}
+
+	// Free all elements in the object pool
+	void free_all(void)
+	{
+		size_type count = pool_size;
+		element_type *element_ptr;
+
+		mFreeElementList.clear();
+
+		element_ptr = &mElementPool[pool_size - 1];
+		while(count--) {
+			mFreeElementList.push_back(element_ptr);
+			element_ptr--;
+		}
+	}
+
+	// Attempts to allocate a new object from pool, returns NULL if no object available.
+	element_type *alloc(void)
+	{
+		element_type *element_ptr = NULL;
+		if (!mFreeElementList.empty()) {
+			element_ptr = mFreeElementList.front();
+			mFreeElementList.pop_front();
+		}
+		return element_ptr;
+	}
+
+	// Frees a previously allocated pool object.
+	void free(element_type *element_ptr)
+	{
+		if (is_ptr_in_pool(element_ptr)) {
+			mFreeElementList.push_back(element_ptr);
+		}
+	}
+
+private:
+	element_type mElementPool[pool_size];
+	std::list<element_type *>mFreeElementList;
+
+	bool is_ptr_in_pool(const element_type *ptr) const
+	{
+		return ((ptr >= mElementPool) && (ptr < mElementPool + pool_size));
+	}
+
+};
+
+}; // namespace nl
+
+#endif // wpantund_ObjectPool_h
diff --git a/src/util/RingBuffer.h b/src/util/RingBuffer.h
new file mode 100644
index 0000000..d842e48
--- /dev/null
+++ b/src/util/RingBuffer.h
@@ -0,0 +1,396 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Ring-buffer implementation (not thread-safe)
+ *
+ */
+
+#ifndef wpantund_RingBuffer_h
+#define wpantund_RingBuffer_h
+
+#include <stdint.h>
+#include <stdexcept>
+
+namespace nl {
+
+// NOTE: The below implementation of RingBuffer<> is NOT thread-safe.
+
+template <typename T = uint8_t, int I = 512>
+class RingBuffer
+{
+public:
+
+	typedef T value_type;
+	typedef int size_type;
+
+	static const size_type buffer_size = I;
+
+public:
+
+	RingBuffer()
+	{
+		clear();
+	}
+
+	size_type size() const
+	{
+		return mCount;
+	}
+
+	size_type space_available() const
+	{
+		return buffer_size - mCount;
+	}
+
+	bool empty() const
+	{
+		return (mCount == 0);
+	}
+
+	bool full() const
+	{
+		return (mCount == buffer_size);
+	}
+
+	size_type max_size() const
+	{
+		return buffer_size;
+	}
+
+	const value_type* data_ptr()const {
+		return &mBuffer[mReadIdx];
+	}
+
+	size_type size_of_data_ptr()const {
+		size_type ret;
+
+		if (mWriteIdx >= mReadIdx) {
+			ret = mWriteIdx - mReadIdx;
+		} else {
+			ret = buffer_size - mReadIdx;
+		}
+
+		return ret;
+	}
+
+	template <typename S> void
+	push(const value_type* values, S value_count)
+	{
+		if (space_available() < value_count) {
+			throw std::overflow_error("not enough room in ring buffer");
+		}
+
+		while(value_count--) {
+			mBuffer[mWriteIdx] = *values++;
+			mWriteIdx++;
+			mWriteIdx %= buffer_size; // Should be optimized by compiler as a mask
+			mCount++;
+		}
+	}
+
+	template <typename S> size_type
+	pop(S value_count)
+	{
+		size_type bytes_read = size();
+
+		if (bytes_read < value_count) {
+			value_count = bytes_read;
+		} else {
+			bytes_read = static_cast<size_type>(value_count);
+		}
+
+		while (value_count--) {
+			mReadIdx++;
+			mReadIdx %= buffer_size; // Should be optimized by compiler as a mask
+			mCount--;
+		}
+
+		if (mReadIdx == mWriteIdx) {
+			mReadIdx = mWriteIdx = 0;
+		}
+
+		return bytes_read;
+	}
+
+	template <typename S> size_type
+	pull(value_type* values, S value_count)
+	{
+		size_type bytes_read = size();
+
+		if (bytes_read < value_count) {
+			value_count = bytes_read;
+		} else {
+			bytes_read = static_cast<size_type>(value_count);
+		}
+
+		while (value_count--) {
+			*values++ = mBuffer[mReadIdx];
+			mReadIdx++;
+			mReadIdx %= buffer_size; // Should be optimized by compiler as a mask
+			mCount--;
+		}
+
+		return bytes_read;
+	}
+
+	// Returns a pointer to the front (head) element in ring buffer if the ring buffer
+	// is not empty, or returns NULL if buffer is empty.
+	const value_type *front() const
+	{
+		return (mCount == 0)? NULL : &mBuffer[mReadIdx];
+	}
+
+	// Returns a pointer to the back (tail) element in ring buffer if the ring buffer
+	// is not empty, or returns NULL if buffer is empty.
+	const value_type *back() const
+	{
+		if (mCount == 0) {
+			return NULL;
+		}
+
+		if (mWriteIdx == 0)  {
+			return &mBuffer[buffer_size - 1];
+		}
+
+		return &mBuffer[mWriteIdx - 1];
+	}
+
+	// Attempts to write the new value in the ring buffer, if buffer is full
+	// and write fails, returns false, otherwise returns true.
+	bool write(const value_type& value)
+	{
+		if (mCount == buffer_size) {
+			return false;
+		}
+
+		mBuffer[mWriteIdx] = value;
+		mWriteIdx++;
+		mWriteIdx %= buffer_size;
+		mCount++;
+
+		return true;
+	}
+
+	// Force writes the new value in the ring buffer. May overwrite an earlier value and move
+	// the read index forward (if buffer is full).
+	void force_write(const value_type& value)
+	{
+		mBuffer[mWriteIdx] = value;
+		mWriteIdx++;
+		mWriteIdx %= buffer_size;
+
+		if (mCount == buffer_size) {
+			mReadIdx = mWriteIdx;
+		} else {
+			mCount++;
+		}
+	}
+
+	// Reads one element from the head of ring buffer and removes it. If buffer
+	// is empty returns false, otherwise returns true.
+	bool read(value_type& value)
+	{
+		value_type *f = front();
+
+		if (f) {
+			value = *f;
+		}
+
+		return remove();
+	}
+
+	// Removes the element from front of the ring buffer. If buffer is empty
+	// and the remove operation fails, returns false, otherwise returns true.
+	bool remove()
+	{
+		if (mCount == 0) {
+			return false;
+		}
+
+		mReadIdx++;
+		mReadIdx %= buffer_size;
+		mCount--;
+
+		return true;
+	}
+
+	// Clears the ring buffer.
+	void clear()
+	{
+		mReadIdx = mWriteIdx = 0;
+		mCount = 0;
+	}
+
+private:
+	class IteratorBase
+	{
+	protected:
+		IteratorBase(const value_type *ptr, const RingBuffer *ring_buffer_ptr)
+		{
+			mIterPtr = ptr;
+			mRingBufferPtr = ring_buffer_ptr;
+		}
+
+		IteratorBase(const IteratorBase &it)
+		{
+			mIterPtr = it.mIterPtr;
+			mRingBufferPtr = it.mRingBufferPtr;
+		}
+
+	public:
+		bool operator==(const IteratorBase &lhs)
+		{
+			return (mIterPtr == lhs.mIterPtr) && (mRingBufferPtr == lhs.mRingBufferPtr);
+		}
+
+		bool operator!=(const IteratorBase &lhs)
+		{
+			return !((*this) == lhs);
+		}
+
+		const value_type *get_ptr()     { return mIterPtr;  }
+
+		const value_type& operator* ()  { return *mIterPtr; }
+		const value_type* operator-> () { return mIterPtr;  }
+
+	protected:
+		const value_type *mIterPtr;
+		const RingBuffer *mRingBufferPtr;
+	};
+
+public:
+	// An iterator for going through the elements in the ring buffer from front to back.
+	class Iterator : public IteratorBase
+	{
+	public:
+		Iterator() : IteratorBase(NULL, NULL) { }
+		Iterator(const Iterator &it) : IteratorBase(it) { }
+
+		Iterator& operator++() {
+			advance();
+			return *this;
+		}
+
+		Iterator operator++(int val) {
+			(void)val;
+			Iterator it(*this);
+			advance();
+			return it;
+		}
+
+		void advance(void)
+		{
+			const RingBuffer *rb = this->mRingBufferPtr;
+			if (rb)
+			{
+				this->mIterPtr++;
+				if (this->mIterPtr == &rb->mBuffer[rb->buffer_size]) {
+					this->mIterPtr = &rb->mBuffer[0];
+				}
+
+				if (this->mIterPtr == &rb->mBuffer[rb->mWriteIdx]) {
+					this->mIterPtr = NULL;
+				}
+			}
+		}
+
+	private:
+		Iterator(const value_type *ptr, const RingBuffer *ring_buffer_ptr) :
+			IteratorBase(ptr, ring_buffer_ptr) { }
+
+		friend Iterator RingBuffer::begin() const;
+		friend Iterator RingBuffer::end() const;
+	};
+
+	// A reverse iterator for going through the elements in the ring buffer from back to front.
+	class ReverseIterator : public IteratorBase
+	{
+	public:
+		ReverseIterator() : IteratorBase(NULL, NULL) { }
+		ReverseIterator(const Iterator &it) : IteratorBase(it) { }
+
+		ReverseIterator& operator++() {
+			advance();
+			return *this;
+		}
+
+		ReverseIterator operator++(int val) {
+			(void)val;
+			ReverseIterator it(*this);
+			advance();
+			return it;
+		}
+
+		void advance(void)
+		{
+			const RingBuffer *rb = this->mRingBufferPtr;
+			if (rb)
+			{
+				if (this->mIterPtr == &rb->mBuffer[rb->mReadIdx]) {
+					this->mIterPtr = NULL;
+				} else {
+					if (this->mIterPtr == &rb->mBuffer[0]) {
+						this->mIterPtr = &rb->mBuffer[rb->buffer_size - 1];
+					} else {
+						this->mIterPtr--;
+					}
+				}
+			}
+		}
+
+	private:
+		ReverseIterator(const value_type *ptr, const RingBuffer *ring_buffer_ptr) :
+			IteratorBase(ptr, ring_buffer_ptr) { }
+
+		friend ReverseIterator RingBuffer::rbegin() const;
+		friend ReverseIterator RingBuffer::rend() const;
+	};
+
+	// Returns a RingBuffer::Iterator to the beginning of the buffer
+	Iterator begin() const
+	{
+		return Iterator(front(), this);
+	}
+
+	// Returns a RingBuffer::Iterator marking the end/tail of the buffer
+	Iterator end() const
+	{
+		return Iterator(NULL, this);
+	}
+
+	// Returns a RingBuffer::ReverseIterator pointing to back/tail of the buffer.
+	ReverseIterator rbegin() const
+	{
+		return ReverseIterator(back(), this);
+	}
+
+	// Returns a RingBuffer::ReverseIterator pointing to end/head of the buffer.
+	ReverseIterator rend() const
+	{
+		return ReverseIterator(NULL, this);
+	}
+
+private:
+	size_type mReadIdx, mWriteIdx;
+	size_type mCount;
+	value_type mBuffer[buffer_size];
+};
+
+}; // namespace nl
+
+#endif
diff --git a/src/util/SocketAdapter.cpp b/src/util/SocketAdapter.cpp
new file mode 100644
index 0000000..b0b8d62
--- /dev/null
+++ b/src/util/SocketAdapter.cpp
@@ -0,0 +1,129 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file contains the implementation of the SocketAdapter class,
+ *      which is a base class for implementing "soft" sockets that
+ *      use other sockets (for things like reliability layers, etc).
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "SocketAdapter.h"
+#include <errno.h>
+
+using namespace nl;
+
+const boost::shared_ptr<SocketWrapper>&
+SocketAdapter::set_parent(boost::shared_ptr<SocketWrapper> parent)
+{
+	return mParent = parent;
+}
+
+const boost::shared_ptr<SocketWrapper>&
+SocketAdapter::get_parent()
+{
+	return mParent;
+}
+
+SocketAdapter::SocketAdapter(boost::shared_ptr<SocketWrapper> parent)
+	:mParent(parent)
+{
+}
+
+int
+SocketAdapter::hibernate(void)
+{
+	return mParent ? mParent->hibernate() : -EINVAL;
+}
+
+ssize_t
+SocketAdapter::write(const void* data, size_t len)
+{
+	return mParent ? mParent->write(data, len) : -EINVAL;
+}
+
+ssize_t
+SocketAdapter::read(void* data, size_t len)
+{
+	return mParent ? mParent->read(data, len) : -EINVAL;
+}
+
+bool
+SocketAdapter::can_read(void)const
+{
+	return mParent ? mParent->can_read() : false;
+}
+
+bool
+SocketAdapter::can_write(void)const
+{
+	return mParent ? mParent->can_write() : false;
+}
+
+int
+SocketAdapter::get_read_fd(void)const
+{
+	return mParent ? mParent->get_read_fd() : -EINVAL;
+}
+
+int
+SocketAdapter::get_write_fd(void)const
+{
+	return mParent ? mParent->get_write_fd() : -EINVAL;
+}
+
+int
+SocketAdapter::process(void)
+{
+	return mParent ? mParent->process() : 0;
+}
+
+void
+SocketAdapter::reset()
+{
+	if(mParent)
+		mParent->reset();
+}
+
+void
+SocketAdapter::send_break()
+{
+	if(mParent)
+		mParent->send_break();
+};
+
+bool
+SocketAdapter::did_reset()
+{
+	return mParent ? mParent->did_reset() : false;
+}
+
+cms_t
+SocketAdapter::get_ms_to_next_event(void)const
+{
+	return mParent ? mParent->get_ms_to_next_event() : CMS_DISTANT_FUTURE;
+}
+
+int
+SocketAdapter::update_fd_set(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *error_fd_set, int *max_fd, cms_t *timeout)
+{
+	return mParent ? mParent->update_fd_set(read_fd_set, write_fd_set, error_fd_set, max_fd, timeout) : 0;
+}
diff --git a/src/util/SocketAdapter.h b/src/util/SocketAdapter.h
new file mode 100644
index 0000000..3e896af
--- /dev/null
+++ b/src/util/SocketAdapter.h
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file contains the declaration of the SocketAdapter class,
+ *      which is a base class for implementing "soft" sockets that
+ *      use other sockets (for things like reliability layers, etc).
+ *
+ */
+
+#ifndef __wpantund__SocketAdapter__
+#define __wpantund__SocketAdapter__
+
+#include "SocketWrapper.h"
+
+namespace nl {
+class SocketAdapter : public SocketWrapper {
+public:
+	virtual ~SocketAdapter() {}
+	virtual const boost::shared_ptr<SocketWrapper>& set_parent(boost::shared_ptr<SocketWrapper> parent);
+	const boost::shared_ptr<SocketWrapper>& get_parent();
+
+	virtual ssize_t write(const void* data, size_t len);
+	virtual ssize_t read(void* data, size_t len);
+	virtual bool can_read(void)const;
+	virtual bool can_write(void)const;
+	virtual int get_read_fd(void)const;
+	virtual int get_write_fd(void)const;
+	virtual int process(void);
+	virtual cms_t get_ms_to_next_event(void)const;
+	virtual void send_break();
+
+	virtual void reset();
+	virtual bool did_reset();
+	virtual int update_fd_set(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *error_fd_set, int *max_fd, cms_t *timeout);
+
+	virtual int hibernate(void);
+
+protected:
+	SocketAdapter(boost::shared_ptr<SocketWrapper> parent);
+	boost::shared_ptr<SocketWrapper> mParent;
+}; // class SocketAdapter
+
+
+}; // namespace nl
+
+#endif /* defined(__wpantund__SocketAdapter__) */
diff --git a/src/util/SocketAsyncOp.h b/src/util/SocketAsyncOp.h
new file mode 100644
index 0000000..cffbefb
--- /dev/null
+++ b/src/util/SocketAsyncOp.h
@@ -0,0 +1,167 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__SocketAsyncOp__
+#define __wpantund__SocketAsyncOp__
+
+#include <stdint.h>
+#include "SocketWrapper.h"
+#include "nlpt.h"
+#include <errno.h>
+
+namespace nl {
+
+static inline int
+read_stream_pt(struct nlpt *pt, nl::SocketWrapper* socket, void* data, size_t len)
+{
+	const int fd = socket->get_read_fd();
+
+	PT_BEGIN(&pt->sub_pt);
+	pt->byte_count = 0;
+	pt->last_errno = 0;
+
+	while (pt->byte_count < len) {
+		ssize_t bytes_read;
+
+		// Wait for the socket to become readable...
+		_nlpt_setup_read_fd_source(pt, fd);
+		PT_WAIT_UNTIL(&pt->sub_pt, nlpt_hook_check_read_fd_source(pt, fd) || socket->can_read());
+		_nlpt_cleanup_read_fd_source(pt, fd);
+
+		// Read what is left of the packet on the socket.
+		bytes_read = socket->read(
+			static_cast<void*>(static_cast<uint8_t*>(data) + pt->byte_count),
+			len - pt->byte_count
+		);
+
+		if (0 > bytes_read) {
+			pt->last_errno = errno;
+			break;
+		}
+
+		pt->byte_count += bytes_read;
+	}
+
+	PT_END(&pt->sub_pt);
+}
+
+static inline int
+write_stream_pt(struct nlpt *pt, nl::SocketWrapper* socket, const void* data, size_t len)
+{
+	const int fd = socket->get_write_fd();
+
+	PT_BEGIN(&pt->sub_pt);
+	pt->byte_count = 0;
+	pt->last_errno = 0;
+
+	while (pt->byte_count < len) {
+		ssize_t bytes_written;
+
+		// Wait for the socket to become writable...
+		_nlpt_setup_write_fd_source(pt, fd);
+		PT_WAIT_UNTIL(&pt->sub_pt, nlpt_hook_check_write_fd_source(pt, fd) || socket->can_write());
+		_nlpt_cleanup_write_fd_source(pt, fd);
+
+		// Attempt to write out what is left of the packet to the socket.
+		bytes_written = socket->write(
+			static_cast<const void*>(static_cast<const uint8_t*>(data) + pt->byte_count),
+			len - pt->byte_count
+		);
+
+		if (0 > bytes_written) {
+			pt->last_errno = errno;
+			break;
+		}
+
+		pt->byte_count += bytes_written;
+	}
+
+	PT_END(&pt->sub_pt);
+}
+
+static inline int
+write_packet_pt(struct nlpt *pt, nl::SocketWrapper* socket, const void* data, size_t len)
+{
+	const int fd = socket->get_write_fd();
+
+	PT_BEGIN(&pt->sub_pt);
+	ssize_t bytes_written;
+	pt->byte_count = 0;
+	pt->last_errno = 0;
+
+	// Wait for the socket to become writable...
+	_nlpt_setup_write_fd_source(pt, fd);
+	PT_WAIT_UNTIL(&pt->sub_pt, nlpt_hook_check_write_fd_source(pt, fd) || socket->can_write());
+	_nlpt_cleanup_write_fd_source(pt, fd);
+
+	// Write out the packet
+	bytes_written = socket->write(
+		static_cast<const void*>(static_cast<const uint8_t*>(data) + pt->byte_count),
+		len - pt->byte_count
+	);
+
+	if (0 > bytes_written) {
+		pt->last_errno = errno;
+	} else {
+		pt->byte_count += bytes_written;
+	}
+
+	PT_END(&pt->sub_pt);
+}
+
+#define NLPT_ASYNC_READ_STREAM(pt, sock, data, len) \
+		PT_SPAWN( \
+			&(pt)->pt, \
+			&(pt)->sub_pt, \
+			::nl::read_stream_pt( \
+				(pt), \
+				(sock), \
+				static_cast<void*>(data), \
+				(len) \
+			) \
+		)
+
+#define NLPT_ASYNC_WRITE_STREAM(pt, sock, data, len) \
+		PT_SPAWN( \
+			&(pt)->pt, \
+			&(pt)->sub_pt, \
+			::nl::write_stream_pt( \
+				(pt), \
+				(sock), \
+				static_cast<const void*>(data), \
+				(len) \
+			) \
+		)
+
+#define NLPT_ASYNC_WRITE_PACKET(pt, sock, data, len) \
+		PT_SPAWN( \
+			&(pt)->pt, \
+			&(pt)->sub_pt, \
+			::nl::write_packet_pt( \
+				(pt), \
+				(sock), \
+				static_cast<const void*>(data), \
+				(len) \
+			) \
+		)
+
+}; // namespace nl
+
+
+#endif /* defined(__wpantund__SocketAsyncOp__) */
diff --git a/src/util/SocketWrapper.cpp b/src/util/SocketWrapper.cpp
new file mode 100644
index 0000000..ec42008
--- /dev/null
+++ b/src/util/SocketWrapper.cpp
@@ -0,0 +1,111 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file contains the default implementations for certain members
+ *      of the SocketWrapper class, which is the virtual base class for using
+ *      things like TCP sockets, serial file descriptors, or even other
+ *      processes.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "SocketWrapper.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <termios.h>
+#include <poll.h>
+#include <errno.h>
+#include <syslog.h>
+#include <sys/file.h>
+
+using namespace nl;
+
+SocketWrapper::~SocketWrapper()
+{
+}
+
+bool
+SocketWrapper::can_read(void)const
+{
+	return false;
+}
+
+bool
+SocketWrapper::can_write(void)const
+{
+	return false;
+}
+
+int
+SocketWrapper::set_log_level(int log_level)
+{
+	return -ENOTSUP;
+}
+
+int
+SocketWrapper::get_read_fd(void)const
+{
+	return -1;
+}
+
+int
+SocketWrapper::get_write_fd(void)const
+{
+	return -1;
+}
+
+cms_t
+SocketWrapper::get_ms_to_next_event(void)const
+{
+	return CMS_DISTANT_FUTURE;
+}
+
+void
+SocketWrapper::send_break(void)
+{
+}
+
+void
+SocketWrapper::reset(void)
+{
+}
+
+int
+SocketWrapper::hibernate(void)
+{
+	return -1;
+}
+
+bool
+SocketWrapper::did_reset(void)
+{
+	return false;
+}
+
+int
+SocketWrapper::update_fd_set(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *error_fd_set, int *max_fd, cms_t *timeout)
+{
+	if (timeout != NULL) {
+		*timeout = std::min(*timeout, get_ms_to_next_event());
+	}
+	return 0;
+}
diff --git a/src/util/SocketWrapper.h b/src/util/SocketWrapper.h
new file mode 100644
index 0000000..449f934
--- /dev/null
+++ b/src/util/SocketWrapper.h
@@ -0,0 +1,70 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file declares the SocketWrapper class, which is the virtual
+ *      base class for using things like TCP sockets, serial file descriptors,
+ *      or even other processes.
+ *
+ */
+
+#ifndef __wpantund__SocketWrapper__
+#define __wpantund__SocketWrapper__
+
+#include <stdint.h>
+#include <cstring>
+#include <boost/shared_ptr.hpp>
+#include <climits>
+#include <string>
+#include <sys/select.h>
+#include "time-utils.h"
+
+namespace nl {
+
+class SocketWrapper {
+public:
+	virtual ~SocketWrapper();
+	virtual ssize_t write(const void* data, size_t len) = 0;
+	virtual ssize_t read(void* data, size_t len) = 0;
+	virtual bool can_read(void)const;
+	virtual bool can_write(void)const;
+	virtual int process(void) = 0;
+	virtual int set_log_level(int log_level);
+
+	virtual int get_read_fd(void)const;
+	virtual int get_write_fd(void)const;
+	virtual cms_t get_ms_to_next_event(void)const;
+
+	virtual void send_break(void);
+
+	virtual void reset(void);
+	virtual bool did_reset(void);
+
+	//! Any ancilary file descriptors to update. Only really needed for adapters.
+	virtual int update_fd_set(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *error_fd_set, int *max_fd, cms_t *timeout);
+
+public:
+	//! Special function which closes the file descriptors. Not supported on all sockets. Call `reset()` to undo.
+	virtual int hibernate(void);
+
+}; // class SocketWrapper
+
+
+}; // namespace nl
+
+
+#endif /* defined(__wpantund__SocketWrapper__) */
diff --git a/src/util/SuperSocket.cpp b/src/util/SuperSocket.cpp
new file mode 100644
index 0000000..d4b2f82
--- /dev/null
+++ b/src/util/SuperSocket.cpp
@@ -0,0 +1,129 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file defindes the SuperSocket class, which provides an
+ *      easy way to create various types of sockets using a convenient
+ *      path syntax.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+
+#include "SuperSocket.h"
+#include "socket-utils.h"
+#include "time-utils.h"
+#include <stdexcept>
+#include <syslog.h>
+#include <errno.h>
+#include <unistd.h>
+#include <termios.h>
+#include <sys/file.h>
+
+using namespace nl;
+
+SuperSocket::SuperSocket(const std::string& path)
+	:UnixSocket(-1, false), mPath(path)
+{
+	int fd = open_super_socket(path.c_str());
+
+	mFDRead = mFDWrite = fd;
+
+	if (0 > fd) {
+		syslog(LOG_ERR, "Unable to open socket with path <%s>, errno=%d (%s)", path.c_str(), errno, strerror(errno));
+		throw std::runtime_error("Unable to open socket");
+	}
+
+	// Lock the file descriptor if it is to a device. It does not make sense
+	// to allow someone else to use this file descriptor at the same time,
+	// or to use the device while someone else is using it.
+	if ( (SUPER_SOCKET_TYPE_DEVICE == get_super_socket_type_from_path(path.c_str()))
+	  && (flock(fd, LOCK_EX|LOCK_NB) < 0)
+	) {
+		// The only error we care about is EWOULDBLOCK. EINVAL is fine,
+		// it just means this file descriptor doesn't support locking.
+		if (EWOULDBLOCK == errno) {
+			syslog(LOG_ERR, "Socket \"%s\" is locked by another process", path.c_str());
+			throw std::runtime_error("Socket is locked by another process");
+		}
+	}
+}
+
+SuperSocket::~SuperSocket()
+{
+	SuperSocket::hibernate();
+}
+
+boost::shared_ptr<SocketWrapper>
+SuperSocket::create(const std::string& path)
+{
+	return boost::shared_ptr<SocketWrapper>(new SuperSocket(path));
+}
+
+int
+SuperSocket::hibernate(void)
+{
+	if (mFDRead >= 0) {
+		// Unlock the FD.
+		IGNORE_RETURN_VALUE(flock(mFDRead, LOCK_UN));
+
+		// Close the existing FD.
+		IGNORE_RETURN_VALUE(close_super_socket(mFDRead));
+	}
+
+	mFDRead = -1;
+	mFDWrite = -1;
+
+	return 0;
+}
+
+void
+SuperSocket::reset()
+{
+	syslog(LOG_DEBUG, "SuperSocket::reset()");
+
+	SuperSocket::hibernate();
+
+	// Sleep for 200ms to wait for things to settle down.
+	usleep(MSEC_PER_SEC * 200);
+
+	mFDRead = mFDWrite = open_super_socket(mPath.c_str());
+
+	if (mFDRead < 0) {
+		// Unable to reopen socket...!
+		syslog(LOG_ERR, "SuperSocket::Reset: Unable to reopen socket <%s>, errno=%d (%s)", mPath.c_str(), errno, strerror(errno));
+		throw std::runtime_error("Unable to reopen socket");
+	}
+
+	// Lock the file descriptor. It does not make sense to allow someone else
+	// to use this file descriptor at the same time, or to use the device
+	// while someone else is using it.
+	if ( (SUPER_SOCKET_TYPE_DEVICE == get_super_socket_type_from_path(mPath.c_str()))
+	  && (flock(mFDRead, LOCK_EX|LOCK_NB) < 0)
+	) {
+		// The only error we care about is EWOULDBLOCK. EINVAL is fine,
+		// it just means this file descriptor doesn't support locking.
+		if (EWOULDBLOCK == errno) {
+			syslog(LOG_ERR, "Socket is locked by another process");
+			throw std::runtime_error("Socket is locked by another process");
+		}
+	}
+}
diff --git a/src/util/SuperSocket.h b/src/util/SuperSocket.h
new file mode 100644
index 0000000..078efbf
--- /dev/null
+++ b/src/util/SuperSocket.h
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file declares the SuperSocket class, which provides an
+ *      easy way to create various types of sockets using a convenient
+ *      path syntax.
+ *
+ */
+
+#ifndef __wpantund__SuperSocket__
+#define __wpantund__SuperSocket__
+
+#include "UnixSocket.h"
+
+namespace nl {
+class SuperSocket : public UnixSocket {
+protected:
+	SuperSocket(const std::string& path);
+
+public:
+	virtual ~SuperSocket();
+
+	static boost::shared_ptr<SocketWrapper> create(const std::string& path);
+
+	virtual void reset();
+
+	virtual int hibernate(void);
+
+protected:
+	std::string mPath;
+}; // class SuperSocket
+
+}; // namespace nl
+
+#endif /* defined(__wpantund__SuperSocket__) */
diff --git a/src/util/Timer.cpp b/src/util/Timer.cpp
new file mode 100644
index 0000000..1909967
--- /dev/null
+++ b/src/util/Timer.cpp
@@ -0,0 +1,226 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Implementation of callback timer.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include "Timer.h"
+
+using namespace nl;
+
+const Timer::Interval Timer::kOneMilliSecond = 1;
+const Timer::Interval Timer::kOneSecond      = Timer::kOneMilliSecond * 1000;
+const Timer::Interval Timer::kOneMinute      = Timer::kOneSecond * 60;
+const Timer::Interval Timer::kOneHour        = Timer::kOneMinute * 60;
+const Timer::Interval Timer::kOneDay         = Timer::kOneHour * 24;
+
+Timer *const Timer::kListEndMarker = (Timer *)(&Timer::mListHead);
+Timer *Timer::mListHead = kListEndMarker;
+
+static void
+null_timer_callback(Timer *timer)
+{
+	return;
+}
+
+Timer::Timer() :
+	mFireTime()
+{
+	mType = kOneShot;
+	mInterval = 0;
+	mNext = NULL;
+	mCallback = &null_timer_callback;
+}
+
+Timer::~Timer()
+{
+	remove(this);
+}
+
+void
+Timer::schedule(Interval interval, const Timer::Callback& callback, Type type)
+{
+	remove(this);
+
+	require_string(interval > 0, bail, "Timer::schedule() - Input interval is invalid (is 0 or negative).");
+
+	mInterval = interval;
+	mCallback = callback;
+	mType = type;
+
+	mFireTime.set(interval + time_ms());
+	add(this);
+
+bail:
+	return;
+}
+
+void
+Timer::cancel(void)
+{
+	remove(this);
+}
+
+bool
+Timer::is_expired(void) const
+{
+	return mFireTime.is_now_or_in_past();
+}
+
+Timer::Interval
+Timer::get_interval(void) const
+{
+	return mInterval;
+}
+
+Timer::Type
+Timer::get_type(void) const
+{
+	return mType;
+}
+
+void
+Timer::add(Timer *timer)
+{
+	Timer *cur;
+
+	// If the list is empty, insert the new timer as the new head of the list.
+	if (mListHead == kListEndMarker) {
+		timer->mNext = kListEndMarker;
+		mListHead = timer;
+		return;
+	}
+
+	// If the new timer fire-time is before the head timer's fire-time, insert it as the new head.
+	if (timer->mFireTime < mListHead->mFireTime) {
+		timer->mNext = mListHead;
+		mListHead = timer;
+		return;
+	}
+
+	// Go through the list and find the proper place to insert the new timer.
+	for (cur = mListHead; cur->mNext != kListEndMarker; cur = cur->mNext) {
+		if (timer->mFireTime < cur->mNext->mFireTime) {
+			// Inset the new timer in between cur and cur->next
+			timer->mNext = cur->mNext;
+			cur->mNext = timer;
+			return;
+		}
+	}
+
+	// New timer's fire-time is after all other timers in the list, so insert it at the end.
+	timer->mNext = kListEndMarker;
+	cur->mNext = timer;
+}
+
+void
+Timer::remove(Timer *timer)
+{
+	Timer *cur;
+
+	// If timer is not on the list, there is nothing to do.
+	if (timer->mNext == NULL) {
+		goto bail;
+	}
+
+	// If timer is the head of the list, remove it and update the head.
+	if (mListHead == timer) {
+		mListHead = timer->mNext;
+		timer->mNext = NULL;
+		goto bail;
+	}
+
+	// Go through the list and find the timer.
+	for (cur = mListHead; cur != kListEndMarker; cur = cur->mNext) {
+		if (cur->mNext == timer) {
+			cur->mNext = timer->mNext;
+			timer->mNext = NULL;
+			goto bail;
+		}
+	}
+
+	// We should never get here, as the timer with a non-null mNext should be on the list
+	// If we get here, assert and bail.
+	require_string(false, bail, "Timer::remove() - Timer was not found on the list.");
+
+bail:
+	return;
+}
+
+int
+Timer::process(void)
+{
+	Timer *timer;
+
+	// Process all expired timers
+	for (timer = mListHead; (timer != kListEndMarker) && timer->is_expired(); timer = mListHead) {
+		// Remove the timer from the list and update the head.
+		mListHead = timer->mNext;
+		timer->mNext = NULL;
+
+		// Restart the timer if it is periodic.
+		if (timer->mType == kPeriodicFixedRate) {
+			// For fixed-rate, restart the timer from last fire time.
+			timer->mFireTime.set(timer->mInterval + timer->mFireTime.get());
+			add(timer);
+		} else if (timer->mType == kPeriodicFixedDelay) {
+			// For fixed-delay, restart the timer from now.
+			timer->mFireTime.set(timer->mInterval + time_ms());
+			add(timer);
+		}
+
+		// Invoke the callback.
+		timer->mCallback(timer);
+	}
+
+	return 0;
+}
+
+int
+Timer::update_timeout(cms_t *timeout)
+{
+	if (timeout != NULL) {
+		cms_t cms = get_ms_to_next_event();
+
+		if (cms < *timeout) {
+			*timeout = cms;
+		}
+	}
+
+	return 0;
+}
+
+cms_t
+Timer::get_ms_to_next_event(void)
+{
+	cms_t cms = CMS_DISTANT_FUTURE;
+
+	if (mListHead != kListEndMarker) {
+		cms = mListHead->mFireTime.get_ms_till_time();
+		if (cms < 0) {
+			cms = 0;
+		}
+	}
+	return cms;
+}
diff --git a/src/util/Timer.h b/src/util/Timer.h
new file mode 100644
index 0000000..7c33096
--- /dev/null
+++ b/src/util/Timer.h
@@ -0,0 +1,128 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file declares a callback timer module for use in wpantund.
+ *
+ */
+
+#ifndef __wpantund__Timer__
+#define __wpantund__Timer__
+
+#include <list>
+#include <boost/function.hpp>
+
+#include "time-utils.h"
+
+namespace nl {
+
+// A callback timer class for use in wpantund.
+class Timer {
+public:
+	// Timer interval in ms - defined as int32_t --> can go up to 24.8 days
+	typedef cms_t Interval;
+
+	// A timer callback
+	typedef boost::function<void (Timer *)> Callback;
+
+	// Timer type
+	enum Type {
+		kOneShot,              // One-shot timer (runs once and expires)
+		kPeriodicFixedRate,    // Restart the timer from last fire time
+		kPeriodicFixedDelay    // Restart the timer after processing the timer
+	};
+
+	// Time interval constants
+	static const Interval kOneMilliSecond;
+	static const Interval kOneSecond;
+	static const Interval kOneMinute;
+	static const Interval kOneHour;
+	static const Interval kOneDay;
+
+public:
+	Timer();
+	virtual ~Timer();
+
+	// Schedules the timer with given interval/period. At fire-time the given callback is invoked.
+	//    Three types of timers are supported: One-shot, fixed-rate periodic, fixed-delay periodic.
+	//    Timer gets started at the time of the call to schedule(). For periodic timer, the first
+	//    invocation of the callback happens after the first interval/period expires.
+	//    A subsequent call to schedule() will stop an already running timer and overwrite all the
+	//    timer parameters (interval, callback, and its type), basically starting a new timer.
+	void schedule(Interval interval, const Callback &callback, Type type = kOneShot);
+
+	// Cancels/Stops the timer (callback will not be invoked).
+	//    If timer is already expired or stopped, calling cancel() does nothing (and is ok).
+	void cancel(void);
+
+	// Returns true if the timer is expired or not running, otherwise returns false.
+	bool is_expired(void) const;
+
+	// Returns the current interval/period of the timer
+	Interval get_interval(void) const;
+
+	// Returns the type of the timer.
+	Type get_type(void) const;
+
+
+public:
+	static int process(void);
+	static int update_timeout(cms_t *timeout);
+
+private:
+	struct ClockTime {
+	public:
+		ClockTime()           { mTime = 0;    }
+		ClockTime(cms_t time) { mTime = time; }
+
+		void set(cms_t time)  { mTime = time; }
+		cms_t get(void) 	  { return mTime; }
+
+		bool operator<(const ClockTime& lhs)  const  { return (mTime - lhs.mTime) < 0;  }
+		bool operator<=(const ClockTime& lhs) const  { return (mTime - lhs.mTime) <= 0; }
+		bool operator==(const ClockTime &lhs) const  { return (mTime == lhs.mTime);     }
+
+		bool is_now_or_in_past(void)  const    { return (*this) <= now(); }
+		bool is_in_future(void) const          { return now() < (*this); }
+
+		cms_t get_ms_till_time(void) const     { return mTime - time_ms(); }
+
+		static ClockTime now(void)  { return ClockTime(time_ms()); }
+
+	private:
+		cms_t mTime;
+	};
+
+	ClockTime mFireTime;
+	cms_t mInterval;
+	Callback mCallback;
+	Type mType;
+	Timer *mNext;       // for linked-list
+
+private:
+	static void remove(Timer *timer);       // Removes timer from linked-list
+	static void add(Timer *timer);          // Adds timer to list (list sorted based on fire-time)
+
+	static cms_t get_ms_to_next_event(void);
+
+	static Timer * mListHead;   			// Head of the LinkedList
+	static Timer * const kListEndMarker;	// Marker for end of list
+};
+
+}; // namespace nl
+
+#endif  // ifndef __wpantund__Timer__
diff --git a/src/util/TunnelIPv6Interface.cpp b/src/util/TunnelIPv6Interface.cpp
new file mode 100644
index 0000000..d74a8a3
--- /dev/null
+++ b/src/util/TunnelIPv6Interface.cpp
@@ -0,0 +1,421 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file contains the implementation for a C++ wrapper around the
+ *      `tunnel.c`/`tunnel.h` interface.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include "TunnelIPv6Interface.h"
+#include <syslog.h>
+#include "IPv6Helpers.h"
+
+#if __linux__
+#include <asm/types.h>
+#include <linux/if_link.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <fcntl.h>
+#endif
+
+#include <sys/select.h>
+
+#ifndef O_NONBLOCK
+#define O_NONBLOCK          O_NDELAY
+#endif
+
+TunnelIPv6Interface::TunnelIPv6Interface(const std::string& interface_name, int mtu):
+	UnixSocket(tunnel_open(interface_name.c_str()), true),
+	mInterfaceName(interface_name),
+	mLastError(0),
+	mNetlinkFD(-1)
+{
+	if (0 > mFDRead) {
+		throw std::invalid_argument("Unable to open tunnel interface");
+	}
+
+	{
+		char ActualInterfaceName[TUNNEL_MAX_INTERFACE_NAME_LEN] = "";
+		int ret = 0;
+		ret = tunnel_get_name(mFDRead, ActualInterfaceName, sizeof(ActualInterfaceName));
+		if (ret) {
+			syslog(LOG_WARNING,
+				   "TunnelIPv6Interface: Couldn't get tunnel name! errno=%d, %s",
+				   errno,
+				   strerror(errno));
+		} else if (mInterfaceName != ActualInterfaceName) {
+			syslog(LOG_WARNING,
+				   "TunnelIPv6Interface: Couldn't create tunnel named \"%s\", got \"%s\" instead!",
+				   mInterfaceName.c_str(),
+				   ActualInterfaceName);
+			mInterfaceName = ActualInterfaceName;
+		}
+	}
+
+	tunnel_set_mtu(mFDRead, mtu);
+
+	setup_signals();
+}
+
+TunnelIPv6Interface::~TunnelIPv6Interface()
+{
+	close(mNetlinkFD);
+}
+
+#if __linux__ // --------------------------------------------------------------
+
+#define LCG32(x)		((uint32_t)(x)*1664525+1013904223)
+
+void
+TunnelIPv6Interface::setup_signals()
+{
+	int status;
+	int fd;
+	struct sockaddr_nl la;
+
+	fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
+
+	require(fd != -1, bail);
+
+	memset(&la, 0, sizeof(la));
+	la.nl_family = AF_NETLINK;
+	la.nl_pad = 0;
+	la.nl_groups = RTMGRP_LINK | RTMGRP_IPV6_IFADDR;
+
+	// We calculate the PID in a pseudo-random way based on the
+	// address pointer and the actual process ID.
+	la.nl_pid = LCG32(getpid()) ^ LCG32((uint32_t)reinterpret_cast<uintptr_t>(this));
+
+	status = bind(fd, (struct sockaddr*) &la, sizeof(la));
+
+	require(status != -1, bail);
+
+	// Success!
+	IGNORE_RETURN_VALUE(fcntl(fd, F_SETFL, O_NONBLOCK));
+
+	mNetlinkFD = fd;
+	fd = -1;
+
+bail:
+
+	// Cleanup (If necessary)
+	if (fd > 0) {
+		close(fd);
+	}
+
+	return;
+}
+
+int
+TunnelIPv6Interface::process(void)
+{
+	uint8_t buffer[1024];
+	ssize_t buffer_len(-1);
+
+	if (mNetlinkFD >= 0) {
+		buffer_len = recv(mNetlinkFD, buffer, sizeof(buffer), 0);
+	}
+
+	if (buffer_len > 0) {
+		struct nlmsghdr *nlp;
+		struct rtmsg *rtp;
+		int rta_len;
+		struct rtattr *rta;
+
+		nlp = (struct nlmsghdr *)buffer;
+		for (;NLMSG_OK(nlp, buffer_len); nlp=NLMSG_NEXT(nlp, buffer_len))
+		{
+			if (nlp->nlmsg_type == RTM_NEWADDR || nlp->nlmsg_type == RTM_DELADDR) {
+				struct ifaddrmsg *ifaddr = (struct ifaddrmsg *)NLMSG_DATA(nlp);
+				char ifnamebuf[IF_NAMESIZE];
+				const char *ifname = if_indextoname(ifaddr->ifa_index, ifnamebuf);
+				struct in6_addr addr;
+
+				if ((ifname == NULL) || (get_interface_name() != ifname)) {
+					continue;
+				}
+
+				// get RTNETLINK message header
+				// get start of attributes
+				rta = (struct rtattr *) IFA_RTA(ifaddr);
+
+				// get length of attributes
+				rta_len = IFA_PAYLOAD(nlp);
+
+				for(;RTA_OK(rta, rta_len); rta = RTA_NEXT(rta, rta_len)) {
+					switch(rta->rta_type) {
+					case IFA_ADDRESS:
+					case IFA_LOCAL:
+					case IFA_BROADCAST:
+					case IFA_ANYCAST:
+						memcpy(addr.s6_addr, RTA_DATA(rta), sizeof(addr));
+
+						if (nlp->nlmsg_type == RTM_NEWADDR) {
+							mAddressWasAdded(addr, ifaddr->ifa_prefixlen);
+						} else if (nlp->nlmsg_type == RTM_DELADDR) {
+							mAddressWasRemoved(addr, ifaddr->ifa_prefixlen);
+						}
+						break;
+					default:
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	return nl::UnixSocket::process();
+}
+
+#else // ----------------------------------------------------------------------
+
+void
+TunnelIPv6Interface::setup_signals()
+{
+	// Unknown platform.
+}
+
+int
+TunnelIPv6Interface::process(void)
+{
+	return nl::UnixSocket::process();
+}
+
+#endif // ---------------------------------------------------------------------
+
+int
+TunnelIPv6Interface::update_fd_set(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *error_fd_set, int *max_fd, cms_t *timeout)
+{
+	if (read_fd_set && (mNetlinkFD >= 0)) {
+		FD_SET(mNetlinkFD, read_fd_set);
+
+		if ((max_fd != NULL)) {
+			*max_fd = std::max(*max_fd, mNetlinkFD);
+		}
+	}
+
+	return nl::UnixSocket::update_fd_set(read_fd_set, write_fd_set, error_fd_set, max_fd, timeout);
+}
+
+const std::string&
+TunnelIPv6Interface::get_interface_name(void)
+{
+	return mInterfaceName;
+}
+
+int
+TunnelIPv6Interface::get_last_error(void)
+{
+	return mLastError;
+}
+
+bool
+TunnelIPv6Interface::is_online(void)
+{
+	return tunnel_is_online(mFDRead);
+}
+
+int
+TunnelIPv6Interface::set_online(bool online)
+{
+	int ret = 0;
+
+	if (online) {
+		syslog(LOG_INFO, "Bringing interface %s online. . .", mInterfaceName.c_str());
+
+		require_action((ret = tunnel_bring_online(mFDRead)) == 0, bail, mLastError = errno);
+		require_action(tunnel_is_online(mFDRead), bail, mLastError = errno);
+
+		require_action_string(tunnel_is_online(mFDRead), bail, mLastError = errno, "Tunnel went offline unexpectedly!");
+
+		std::set<struct in6_addr>::const_iterator iter;
+		for (iter = mAddresses.begin(); iter != mAddresses.end(); ++iter) {
+			(void)tunnel_add_address(mFDRead, iter->s6_addr, 64);
+		}
+	} else {
+		syslog(LOG_INFO, "Taking interface %s offline. . .", mInterfaceName.c_str());
+
+		require_action((ret = tunnel_bring_offline(mFDRead)) == 0, bail, mLastError = errno);
+	}
+
+bail:
+	return ret;
+}
+
+void
+TunnelIPv6Interface::reset(void)
+{
+	syslog(LOG_INFO, "Resetting interface %s. . .", mInterfaceName.c_str());
+
+	while (!mAddresses.empty()) {
+		const struct in6_addr addr(*mAddresses.begin());
+		remove_address(&addr);
+	}
+
+	set_online(false);
+}
+
+
+bool
+TunnelIPv6Interface::add_address(const struct in6_addr *addr, int prefixlen)
+{
+	bool ret = false;
+
+	require_action(!IN6_IS_ADDR_UNSPECIFIED(addr), bail, mLastError = EINVAL);
+
+	if (!mAddresses.count(*addr)) {
+		syslog(
+			LOG_INFO,
+		   "TunnelIPv6Interface: Adding address \"%s\" to interface \"%s\".",
+		   in6_addr_to_string(*addr).c_str(),
+		   mInterfaceName.c_str()
+		);
+
+		mAddresses.insert(*addr);
+
+		if (is_online()) {
+			require_noerr_action(tunnel_add_address(mFDRead, addr->s6_addr, prefixlen), bail, mLastError = errno);
+		}
+	}
+
+
+	ret = true;
+
+bail:
+	return ret;
+
+}
+
+
+bool
+TunnelIPv6Interface::remove_address(const struct in6_addr *addr, int prefixlen)
+{
+	bool ret = false;
+
+	require_action(!IN6_IS_ADDR_UNSPECIFIED(addr), bail, mLastError = EINVAL);
+
+	syslog(
+		LOG_INFO,
+	   "TunnelIPv6Interface: Removing address \"%s\" from interface \"%s\".",
+	   in6_addr_to_string(*addr).c_str(),
+	   mInterfaceName.c_str()
+	);
+
+	mAddresses.erase(*addr);
+
+	if (tunnel_remove_address(mFDRead, addr->s6_addr) != 0) {
+		mLastError = errno;
+		goto bail;
+	}
+
+	ret = true;
+
+bail:
+	return ret;
+
+}
+
+bool
+TunnelIPv6Interface::add_route(const struct in6_addr *route, int prefixlen)
+{
+	bool ret = false;
+
+	syslog(
+		LOG_INFO,
+		"TunnelIPv6Interface: Adding route prefix \"%s/%d\" -> \"%s\".",
+		in6_addr_to_string(*route).c_str(),
+		prefixlen,
+		mInterfaceName.c_str()
+	);
+
+	if (is_online()) {
+		require_noerr_action(tunnel_add_route(mFDRead, route->s6_addr, prefixlen), bail, mLastError = errno);
+	}
+
+	ret = true;
+
+bail:
+	return ret;
+}
+
+bool
+TunnelIPv6Interface::remove_route(const struct in6_addr *route, int prefixlen)
+{
+	bool ret = false;
+
+	syslog(
+		LOG_INFO,
+		"TunnelIPv6Interface: Removing route prefix \"%s/%d\" -> \"%s\".",
+		in6_addr_to_string(*route).c_str(),
+		prefixlen,
+		mInterfaceName.c_str()
+	);
+
+	if (is_online()) {
+		require_noerr_action(tunnel_remove_route(mFDRead, route->s6_addr, prefixlen), bail, mLastError = errno);
+	}
+
+	ret = true;
+
+bail:
+	return ret;
+}
+
+ssize_t
+TunnelIPv6Interface::read(void* data, size_t len)
+{
+	ssize_t ret = nl::UnixSocket::read(data, len);
+	uint8_t *data_bytes = static_cast<uint8_t*>(data);
+
+	// Remove any subheader, if present.
+	if ((ret >= 4) && (data_bytes[0] == 0) && (data_bytes[1] == 0)) {
+		ret -= 4;
+		memmove(data, static_cast<const void*>(data_bytes + 4), ret);
+	}
+
+	return ret;
+}
+
+ssize_t
+TunnelIPv6Interface::write(const void* data, size_t len)
+{
+#ifdef __APPLE__
+	const uint8_t* const data_bytes = static_cast<const uint8_t*>(data);
+
+	if ((data_bytes[0] != 0) || (data_bytes[0] != 0)) {
+		// The utun interface on OS X needs this header.
+		// Linux seems to be able to infer the type of the packet
+		// with no problems.
+		uint8_t packet[len + 4];
+		packet[0] = 0;
+		packet[1] = 0;
+		packet[2] = (PF_INET6 << 8) & 0xFF;
+		packet[3] = (PF_INET6 << 0) & 0xFF;
+		memcpy(static_cast<void*>(packet + 4), data, len);
+		ssize_t ret = nl::UnixSocket::write(packet, len + 4);
+		return (ret >= 4)?(ret - 4):(-1);
+	}
+#endif
+	return nl::UnixSocket::write(data, len);
+}
diff --git a/src/util/TunnelIPv6Interface.h b/src/util/TunnelIPv6Interface.h
new file mode 100644
index 0000000..5b87715
--- /dev/null
+++ b/src/util/TunnelIPv6Interface.h
@@ -0,0 +1,86 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file contains the interface for a C++ wrapper around the
+ *      `tunnel.c`/`tunnel.h` interface.
+ *
+ */
+
+#ifndef __wpantund__TunnelInterface__
+#define __wpantund__TunnelInterface__
+
+#include "tunnel.h"
+#include <cstdio>
+#include <string>
+#include <errno.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include "UnixSocket.h"
+#include <set>
+#include "IPv6Helpers.h"
+#include <boost/signals2/signal.hpp>
+
+class TunnelIPv6Interface : public nl::UnixSocket
+{
+
+public:
+	TunnelIPv6Interface(const std::string& interface_name = "", int mtu = 1280);
+
+	virtual ~TunnelIPv6Interface();
+
+	const std::string& get_interface_name(void);
+
+	int get_last_error(void);
+
+	bool is_online(void);
+	int set_online(bool isOnline);
+
+
+
+	const struct in6_addr& get_realm_local_address()const;
+
+	bool add_address(const struct in6_addr *addr, int prefixlen = 64);
+	bool remove_address(const struct in6_addr *addr, int prefixlen = 64);
+
+	bool add_route(const struct in6_addr *route, int prefixlen = 64);
+	bool remove_route(const struct in6_addr *route, int prefixlen = 64);
+
+	virtual void reset();
+	virtual ssize_t write(const void* data, size_t len);
+	virtual ssize_t read(void* data, size_t len);
+
+	virtual int process(void);
+	virtual int update_fd_set(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *error_fd_set, int *max_fd, cms_t *timeout);
+
+public: // Signals
+
+	boost::signals2::signal<void(const struct in6_addr&, int)> mAddressWasAdded;
+	boost::signals2::signal<void(const struct in6_addr&, int)> mAddressWasRemoved;
+
+private:
+	void setup_signals();
+
+private:
+	std::string mInterfaceName;
+	int mLastError;
+
+	int mNetlinkFD;
+
+	std::set<struct in6_addr> mAddresses;
+};
+#endif /* defined(__wpantund__TunnelInterface__) */
diff --git a/src/util/UnixSocket.cpp b/src/util/UnixSocket.cpp
new file mode 100644
index 0000000..bfd27ea
--- /dev/null
+++ b/src/util/UnixSocket.cpp
@@ -0,0 +1,187 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "UnixSocket.h"
+#include <errno.h>
+#include "socket-utils.h"
+#include <termios.h>
+#include <sys/file.h>
+#include <syslog.h>
+#include <poll.h>
+
+using namespace nl;
+
+#define SOCKET_DEBUG_BYTES_PER_LINE			16
+
+UnixSocket::UnixSocket(int rfd, int wfd, bool should_close)
+	:mShouldClose(should_close), mFDRead(rfd), mFDWrite(wfd), mLogLevel(-1)
+{
+}
+
+UnixSocket::UnixSocket(int fd, bool should_close)
+	:mShouldClose(should_close), mFDRead(fd), mFDWrite(fd), mLogLevel(-1)
+{
+}
+
+UnixSocket::~UnixSocket()
+{
+	if (mShouldClose) {
+		close(mFDRead);
+
+		if(mFDWrite != mFDRead) {
+			close(mFDWrite);
+		}
+	}
+}
+
+boost::shared_ptr<SocketWrapper>
+UnixSocket::create(int rfd, int wfd, bool should_close)
+{
+	return boost::shared_ptr<SocketWrapper>(new UnixSocket(rfd,wfd,should_close));
+}
+
+boost::shared_ptr<SocketWrapper>
+UnixSocket::create(int fd, bool should_close)
+{
+	return UnixSocket::create(fd, fd, should_close);
+}
+
+ssize_t
+UnixSocket::write(const void* data, size_t len)
+{
+	ssize_t ret = ::write(mFDWrite, data, len);
+	if(ret<0) {
+		ret = -errno;
+	} else if(ret == 0) {
+		ret = fd_has_error(mFDWrite);
+#if DEBUG
+	} else if (mLogLevel != -1) {
+		const uint8_t* byte = (uint8_t*)data;
+		ssize_t i = 0;
+
+		while(i<ret) {
+			ssize_t j = 0;
+			char dump_string[SOCKET_DEBUG_BYTES_PER_LINE*3+1];
+
+			for (j = 0;i<ret && j<SOCKET_DEBUG_BYTES_PER_LINE;i++,j++) {
+				sprintf(dump_string+j*3, "%02X ", byte[i]);
+			}
+
+			syslog(mLogLevel, "UnixSocket: %3d Byte(s) sent to FD%d:   %s%s", (int)j, mFDWrite, dump_string, (i<ret)?" ...":"");
+		}
+#endif
+	}
+	return ret;
+}
+
+ssize_t
+UnixSocket::read(void* data, size_t len)
+{
+	ssize_t ret = ::read(mFDRead, data, len);
+	if(ret<0) {
+		if(EAGAIN == errno) {
+			ret = 0;
+		} else {
+			ret = -errno;
+		}
+#if DEBUG
+	} else if ((ret > 0) && (mLogLevel != -1)) {
+		const uint8_t* byte = (uint8_t*)data;
+		ssize_t i = 0;
+
+		while(i<ret) {
+			ssize_t j = 0;
+			char dump_string[SOCKET_DEBUG_BYTES_PER_LINE*3+1];
+
+			for (j = 0;i<ret && j<SOCKET_DEBUG_BYTES_PER_LINE;i++,j++) {
+				sprintf(dump_string+j*3, "%02X ", byte[i]);
+			}
+
+			syslog(mLogLevel, "UnixSocket: %3d Byte(s) read from FD%d: %s%s", (int)j, mFDWrite, dump_string, (i<ret)?" ...":"");
+		}
+#endif
+	}
+
+	if(ret==0) {
+		ret = fd_has_error(mFDRead);
+	}
+
+	return ret;
+}
+
+bool
+UnixSocket::can_read(void)const
+{
+	bool ret = false;
+	const int flags = POLLRDNORM|POLLERR|POLLNVAL|POLLHUP;
+	struct pollfd pollfd = { mFDRead, flags, 0 };
+	int count = poll(&pollfd, 1, 0);
+	ret = (count>0) && ((pollfd.revents & flags) != 0);
+	return ret;
+}
+
+bool
+UnixSocket::can_write(void)const
+{
+	const int flags = POLLOUT|POLLERR|POLLNVAL|POLLHUP;
+	struct pollfd pollfd = { mFDWrite, flags, 0 };
+
+	return (poll(&pollfd, 1, 0)>0) && ((pollfd.revents & flags) != 0);
+}
+
+void
+UnixSocket::send_break()
+{
+	if (isatty(mFDWrite)) {
+#if DEBUG
+		syslog(mLogLevel, "UnixSocket: Sending BREAK");
+#endif
+		tcsendbreak(mFDWrite, 0);
+	}
+};
+
+int
+UnixSocket::get_read_fd(void)const
+{
+	return mFDRead;
+}
+
+int
+UnixSocket::get_write_fd(void)const
+{
+	return mFDWrite;
+}
+
+int
+UnixSocket::process(void)
+{
+	return 0;
+}
+
+int
+UnixSocket::set_log_level(int log_level)
+{
+	mLogLevel = log_level;
+
+	return 0;
+}
diff --git a/src/util/UnixSocket.h b/src/util/UnixSocket.h
new file mode 100644
index 0000000..9ab990e
--- /dev/null
+++ b/src/util/UnixSocket.h
@@ -0,0 +1,56 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__UnixSocket__
+#define __wpantund__UnixSocket__
+
+#include "SocketWrapper.h"
+#include <stdio.h>
+#include <unistd.h>
+
+namespace nl {
+class UnixSocket : public SocketWrapper {
+protected:
+	UnixSocket(int rfd, int wfd, bool should_close);
+	UnixSocket(int fd, bool should_close);
+
+public:
+	static boost::shared_ptr<SocketWrapper> create(int fd, bool should_close = false);
+	static boost::shared_ptr<SocketWrapper> create(int rfd, int wfd, bool should_close = false);
+	virtual ~UnixSocket();
+	virtual ssize_t write(const void* data, size_t len);
+	virtual ssize_t read(void* data, size_t len);
+	virtual bool can_read(void)const;
+	virtual bool can_write(void)const;
+	virtual int get_read_fd(void)const;
+	virtual int get_write_fd(void)const;
+	virtual int process(void);
+	virtual void send_break();
+	virtual int set_log_level(int log_level);
+
+protected:
+	bool mShouldClose;
+	int mFDRead;
+	int mFDWrite;
+	int mLogLevel;
+}; // class UnixSocket
+
+}; // namespace nl
+
+#endif /* defined(__wpantund__UnixSocket__) */
diff --git a/src/util/ValueMap.cpp b/src/util/ValueMap.cpp
new file mode 100644
index 0000000..923ffe9
--- /dev/null
+++ b/src/util/ValueMap.cpp
@@ -0,0 +1,42 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      ValueMap is a dictionary-like key-value store
+ *
+ */
+
+#include "ValueMap.h"
+
+nl::ValueMap
+nl::ValueMapWithKeysAndValues(const char* key, ...)
+{
+	ValueMap ret;
+	va_list args;
+	va_start(args, key);
+	while (key != NULL) {
+		boost::any* value = va_arg(args, boost::any*);
+		if (value == NULL) {
+			ret[key] = boost::any();
+		} else {
+			ret[key] = *value;
+		}
+		key = va_arg(args, const char*);
+	}
+	va_end(args);
+	return ret;
+}
diff --git a/src/util/ValueMap.h b/src/util/ValueMap.h
new file mode 100644
index 0000000..135ede5
--- /dev/null
+++ b/src/util/ValueMap.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      ValueMap is a dictionary-like key-value store
+ *
+ */
+
+#ifndef wpantund_ValueMap_h
+#define wpantund_ValueMap_h
+
+#include <boost/any.hpp>
+#include <cstdarg>
+#include <map>
+#include <string>
+
+namespace nl {
+
+typedef std::map<std::string, boost::any> ValueMap;
+
+extern ValueMap ValueMapWithKeysAndValues(const char* key, ...);
+
+}; // namespace nl
+
+#endif
diff --git a/src/util/any-to.cpp b/src/util/any-to.cpp
new file mode 100644
index 0000000..6e6e77d
--- /dev/null
+++ b/src/util/any-to.cpp
@@ -0,0 +1,322 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Implementation of utility functions related to boost::any.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include "any-to.h"
+#include <exception>
+#include <stdexcept>
+#include <ctype.h>
+#include <list>
+#include "string-utils.h"
+
+using namespace nl;
+
+nl::Data any_to_data(const boost::any& value)
+{
+	nl::Data ret;
+
+	if (value.type() == typeid(std::string)) {
+		std::string key_string = boost::any_cast<std::string>(value);
+		uint8_t data[key_string.size()/2];
+
+		int length = parse_string_into_data(data,
+											key_string.size()/2,
+											key_string.c_str());
+
+		ret = nl::Data(data, length);
+	} else if (value.type() == typeid(nl::Data)) {
+		ret = boost::any_cast<nl::Data>(value);
+	} else if (value.type() == typeid(uint64_t)) {
+		union {
+			uint64_t val;
+			uint8_t data[sizeof(uint64_t)];
+		} x;
+
+		x.val = boost::any_cast<uint64_t>(value);
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+		reverse_bytes(x.data, sizeof(uint64_t));
+#endif
+
+		ret.append(x.data,sizeof(uint64_t));
+	} else {
+		ret = nl::Data(boost::any_cast<std::vector<uint8_t> >(value));
+	}
+	return ret;
+}
+
+int any_to_int(const boost::any& value)
+{
+	int32_t ret = 0;
+
+	if (value.type() == typeid(std::string)) {
+		std::string key_string = boost::any_cast<std::string>(value);
+		ret = (int)strtol(key_string.c_str(), NULL, 0);
+	} else if (value.type() == typeid(uint8_t)) {
+		ret = boost::any_cast<uint8_t>(value);
+	} else if (value.type() == typeid(int8_t)) {
+		ret = boost::any_cast<int8_t>(value);
+	} else if (value.type() == typeid(uint16_t)) {
+		ret = boost::any_cast<uint16_t>(value);
+	} else if (value.type() == typeid(int16_t)) {
+		ret = boost::any_cast<int16_t>(value);
+	} else if (value.type() == typeid(uint32_t)) {
+		ret = boost::any_cast<uint32_t>(value);
+	} else if (value.type() == typeid(int32_t)) {
+		ret = boost::any_cast<int32_t>(value);
+	} else if (value.type() == typeid(bool)) {
+		ret = boost::any_cast<bool>(value);
+	} else if (value.type() == typeid(unsigned int)) {
+		ret = boost::any_cast<unsigned int>(value);
+	} else {
+		ret = boost::any_cast<int>(value);
+	}
+	return ret;
+}
+
+struct in6_addr
+any_to_ipv6(const boost::any& value)
+{
+	struct in6_addr ret = {};
+
+	if (value.type() == typeid(std::string)) {
+		std::string str(boost::any_cast<std::string>(value));
+		size_t lastchar(str.find_first_not_of("0123456789abcdefABCDEF:."));
+		int bytes;
+
+		if (lastchar != std::string::npos) {
+			str.erase(str.begin() + lastchar, str.end());
+		}
+
+		bytes = inet_pton(
+			AF_INET6,
+			str.c_str(),
+			ret.s6_addr
+		);
+		if (bytes <= 0) {
+			throw std::invalid_argument("String not IPv6 address");
+		}
+	} else if (value.type() == typeid(nl::Data)) {
+		nl::Data data(boost::any_cast<nl::Data>(value));
+		if (data.size() <= sizeof(ret)) {
+			memcpy(ret.s6_addr, data.data(), data.size());
+		}
+	} else {
+		ret = boost::any_cast<struct in6_addr>(value);
+	}
+
+	return ret;
+}
+
+uint64_t
+any_to_uint64(const boost::any& value)
+{
+	uint64_t ret(0);
+
+	if (value.type() == typeid(std::string)) {
+		const std::string& key_string = boost::any_cast<std::string>(value);
+
+		if (key_string.size() != 16) {
+			throw std::invalid_argument("String not 16 characters long");
+		}
+
+		ret = static_cast<uint64_t>(strtoull(key_string.c_str(), NULL, 16));
+
+	} else if (value.type() == typeid(nl::Data)) {
+		const nl::Data& data = boost::any_cast<nl::Data>(value);
+		union {
+			uint64_t val;
+			uint8_t data[sizeof(uint64_t)];
+		} x;
+
+		if (data.size() != sizeof(uint64_t)) {
+			throw std::invalid_argument("Data not 8 bytes long");
+		}
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+		memcpyrev(x.data, data.data(), sizeof(uint64_t));
+#else
+		memcpy(x.data, data.data(), sizeof(uint64_t));
+#endif
+
+		ret = x.val;
+
+	} else {
+		ret = boost::any_cast<uint64_t>(value);
+	}
+
+
+	return ret;
+}
+
+bool any_to_bool(const boost::any& value)
+{
+	bool ret = 0;
+
+	if (value.type() == typeid(std::string)) {
+		std::string key_string = boost::any_cast<std::string>(value);
+		if (key_string=="true" || key_string=="yes" || key_string=="1" || key_string == "TRUE" || key_string == "YES")
+			ret = true;
+		else if (key_string=="false" || key_string=="no" || key_string=="0" || key_string == "FALSE" || key_string == "NO")
+			ret = false;
+		else
+			ret = (bool)strtol(key_string.c_str(), NULL, 0);
+	} else if (value.type() == typeid(bool)) {
+		ret = boost::any_cast<bool>(value);
+	} else {
+		ret = any_to_int(value) != 0;
+	}
+	return ret;
+}
+
+std::string any_to_string(const boost::any& value)
+{
+	std::string ret;
+
+	if (value.type() == typeid(std::string)) {
+		ret = boost::any_cast<std::string>(value);
+	} else if (value.type() == typeid(uint8_t)) {
+		char tmp[10];
+		snprintf(tmp, sizeof(tmp), "%u", boost::any_cast<uint8_t>(value));
+		ret = tmp;
+	} else if (value.type() == typeid(int8_t)) {
+		char tmp[10];
+		snprintf(tmp, sizeof(tmp), "%d", boost::any_cast<int8_t>(value));
+		ret = tmp;
+	} else if (value.type() == typeid(uint16_t)) {
+		char tmp[10];
+		snprintf(tmp, sizeof(tmp), "%u", boost::any_cast<uint16_t>(value));
+		ret = tmp;
+	} else if (value.type() == typeid(int16_t)) {
+		char tmp[10];
+		snprintf(tmp, sizeof(tmp), "%d", boost::any_cast<int16_t>(value));
+		ret = tmp;
+	} else if (value.type() == typeid(uint32_t)) {
+		char tmp[10];
+		snprintf(tmp, sizeof(tmp), "%u", (unsigned int)boost::any_cast<uint32_t>(value));
+		ret = tmp;
+	} else if (value.type() == typeid(int32_t)) {
+		char tmp[10];
+		snprintf(tmp, sizeof(tmp), "%d", (int)boost::any_cast<int32_t>(value));
+		ret = tmp;
+	} else if (value.type() == typeid(uint64_t)) {
+		char tmp[20];
+		uint64_t u64_val = boost::any_cast<uint64_t>(value);
+		snprintf(tmp,
+		         sizeof(tmp),
+		         "%08x%08x",
+		         static_cast<uint32_t>(u64_val >> 32),
+		         static_cast<uint32_t>(u64_val & 0xFFFFFFFF));
+		ret = tmp;
+	} else if (value.type() == typeid(unsigned int)) {
+		char tmp[10];
+		snprintf(tmp, sizeof(tmp), "%u", boost::any_cast<unsigned int>(value));
+		ret = tmp;
+	} else if (value.type() == typeid(int)) {
+		char tmp[10];
+		snprintf(tmp, sizeof(tmp), "%d", boost::any_cast<int>(value));
+		ret = tmp;
+	} else if (value.type() == typeid(bool)) {
+		ret = (boost::any_cast<bool>(value))? "true" : "false";
+	} else if (value.type() == typeid(nl::Data)) {
+		nl::Data data = boost::any_cast<nl::Data>(value);
+		ret = std::string(data.size()*2,0);
+
+		// Reserve the zero termination
+		ret.reserve(data.size()*2+1);
+
+		encode_data_into_string(data.data(),
+								data.size(),
+								&ret[0],
+								ret.capacity(),
+								0);
+	} else if (value.type() == typeid(std::list<std::string>)) {
+		std::list<std::string> l = boost::any_cast<std::list<std::string> >(value);
+		if (!l.empty()) {
+			std::list<std::string>::const_iterator iter;
+			ret = "{\n";
+			for (iter = l.begin(); iter != l.end(); ++iter) {
+				ret += "\t\"" + *iter + "\"\n";
+			}
+			ret += "}";
+		} else {
+			ret = "{ }";
+		}
+	} else {
+		ret += "<";
+		ret += value.type().name();
+		ret += ">";
+	}
+	return ret;
+}
+
+std::set<int>
+any_to_int_set(const boost::any& value)
+{
+	std::set<int> ret;
+
+	if (value.type() == typeid(std::string)) {
+		std::string key_string = boost::any_cast<std::string>(value);
+		if (key_string.empty()) {
+			// Empty set. Do nothing.
+		} else if (key_string.find(',') != std::string::npos) {
+			// List of values. Not yet supported.
+			throw std::invalid_argument("integer mask string format not yet implemented");
+		} else if (isdigit(key_string[0])) {
+			// Special case, only one value.
+			ret.insert((int)strtol(key_string.c_str(), NULL, 0));
+		} else {
+			throw std::invalid_argument(key_string);
+		}
+	} else if (value.type() == typeid(uint8_t)) {
+		ret.insert(boost::any_cast<uint8_t>(value));
+	} else if (value.type() == typeid(int8_t)) {
+		ret.insert(boost::any_cast<int8_t>(value));
+	} else if (value.type() == typeid(uint16_t)) {
+		ret.insert(boost::any_cast<uint16_t>(value));
+	} else if (value.type() == typeid(int16_t)) {
+		ret.insert(boost::any_cast<int16_t>(value));
+	} else if (value.type() == typeid(uint32_t)) {
+		ret.insert(boost::any_cast<uint32_t>(value));
+	} else if (value.type() == typeid(int32_t)) {
+		ret.insert(boost::any_cast<int32_t>(value));
+	} else if (value.type() == typeid(bool)) {
+		ret.insert(boost::any_cast<bool>(value));
+	} else if (value.type() == typeid(std::list<int>)) {
+		std::list<int> number_list(boost::any_cast< std::list<int> >(value));
+		ret.insert(number_list.begin(), number_list.end());
+	} else if (value.type() == typeid(std::list<boost::any>)) {
+		std::list<boost::any> any_list(boost::any_cast< std::list<boost::any> >(value));
+		std::list<boost::any>::const_iterator iter;
+		for(iter = any_list.begin(); iter != any_list.end(); ++iter) {
+			ret.insert(any_to_int(*iter));
+		}
+	} else {
+		ret = boost::any_cast< std::set<int> >(value);
+	}
+	return ret;
+}
diff --git a/src/util/any-to.h b/src/util/any-to.h
new file mode 100644
index 0000000..19e7936
--- /dev/null
+++ b/src/util/any-to.h
@@ -0,0 +1,39 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Declaration of utility functions related to boost::any.
+ *
+ */
+
+#ifndef wpantund_any_to_h
+#define wpantund_any_to_h
+
+#include <string>
+#include <boost/any.hpp>
+#include "Data.h"
+#include <set>
+#include <arpa/inet.h>
+
+extern nl::Data any_to_data(const boost::any& value);
+extern int any_to_int(const boost::any& value);
+extern uint64_t any_to_uint64(const boost::any& value);
+extern struct in6_addr any_to_ipv6(const boost::any& value);
+extern bool any_to_bool(const boost::any& value);
+extern std::string any_to_string(const boost::any& value);
+extern std::set<int> any_to_int_set(const boost::any& value);
+#endif
diff --git a/src/util/args.h b/src/util/args.h
new file mode 100644
index 0000000..e606f5b
--- /dev/null
+++ b/src/util/args.h
@@ -0,0 +1,74 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef UTIL_ARGS_HEADER_INCLUDED
+#define UTIL_ARGS_HEADER_INCLUDED 1
+
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+
+typedef struct {
+	char shortarg;
+	const char* longarg;
+	const char* param;
+	const char* desc;
+} arg_list_item_t;
+
+static inline void
+print_arg_list_help(
+    const arg_list_item_t arg_list[],
+    const char*                             command_name,
+    const char*                             syntax
+    )
+{
+	int i;
+
+	printf("Syntax:\n");
+	printf("   %s %s\n", command_name, syntax);
+	printf("Options:\n");
+	for (i = 0; arg_list[i].desc; ++i) {
+		if (arg_list[i].shortarg)
+			printf("   -%c", arg_list[i].shortarg);
+		else
+			printf("     ");
+
+		if (arg_list[i].longarg) {
+			if (arg_list[i].shortarg)
+				printf("/");
+			else
+				printf(" ");
+
+			printf("--%s%s",
+			       arg_list[i].longarg,
+			       &"                    "[strlen(arg_list[i].longarg)]);
+		} else {
+			printf("                       ");
+		}
+
+		if (arg_list[i].param != NULL) {
+			printf(" %s [%s]\n", arg_list[i].desc, arg_list[i].param);
+		} else {
+			printf(" %s\n", arg_list[i].desc);
+		}
+
+	}
+}
+
+#endif // UTIL_ARGS_HEADER_INCLUDED
diff --git a/src/util/config-file.c b/src/util/config-file.c
new file mode 100644
index 0000000..7dc24e2
--- /dev/null
+++ b/src/util/config-file.c
@@ -0,0 +1,142 @@
+/*
+ *
+ *    Copyright (c) 2010-2012 Nest Labs, 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 file implements a configuration file parser.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef ASSERT_MACROS_USE_SYSLOG
+#define ASSERT_MACROS_USE_SYSLOG 1
+#endif
+
+#include "assert-macros.h"
+
+#include "config-file.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <ctype.h>
+#include <poll.h>
+#include <sys/select.h>
+#include <libgen.h>
+#include <syslog.h>
+
+#include "fgetln.h"
+#include "string-utils.h"
+
+#define strcaseequal(x, y)   (strcasecmp(x, y) == 0)
+
+char*
+get_next_arg(char *buf, char **rest)
+{
+	char* ret = NULL;
+	char quote_type = 0;
+	char* write_iter = NULL;
+
+	// Trim whitespace
+	while (isspace(*buf)) {
+		buf++;
+	};
+
+	// Skip if we are empty or the start of a comment.
+	if ((*buf == 0) || (*buf == '#')) {
+		goto bail;
+	}
+
+	write_iter = ret = buf;
+
+	while (*buf != 0) {
+		if (quote_type != 0) {
+			// We are in the middle of a quote, so we are
+			// looking for matching end of the quote.
+			if (*buf == quote_type) {
+				quote_type = 0;
+				buf++;
+				continue;
+			}
+		} else {
+			if (*buf == '"' || *buf == '\'') {
+				quote_type = *buf++;
+				continue;
+			}
+
+			// Stop parsing arguments if we hit unquoted whitespace.
+			if (isspace(*buf)) {
+				buf++;
+				break;
+			}
+		}
+
+		// Allow for slash-escaping
+		if ((buf[0] == '\\') && (buf[1] != 0)) {
+			buf++;
+		}
+
+		*write_iter++ = *buf++;
+	}
+
+	*write_iter = 0;
+
+bail:
+	if (rest) {
+		*rest = buf;
+	}
+	return ret;
+}
+
+int
+read_config(
+    const char* filename,
+	config_param_set_func setter,
+	void* context
+) {
+	int ret = 0;
+
+	FILE* file = fopen(filename, "r");
+	char* line = NULL;
+	size_t line_len = 0;
+	int line_number = 0;
+
+	if (file == NULL) {
+		ret = -1;
+		goto bail;
+	}
+
+	syslog(LOG_INFO, "Reading configuration from \"%s\" . . .", filename);
+
+	while (!feof(file) && (line = fgetln(file, &line_len)) && !ret) {
+		char *key = get_next_arg(line, &line);
+		char *value = get_next_arg(line, &line);
+		line_number++;
+		if (!key) {
+			continue;
+		}
+		ret = setter(context, key, value);
+	}
+
+bail:
+	if (file) {
+		fclose(file);
+	}
+	return ret;
+}
diff --git a/src/util/config-file.h b/src/util/config-file.h
new file mode 100644
index 0000000..aac5f65
--- /dev/null
+++ b/src/util/config-file.h
@@ -0,0 +1,29 @@
+/*
+ *
+ *    Copyright (c) 2010-2012 Nest Labs, 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 is the header for the configuration file parser.
+ *
+ */
+
+#ifndef __WPAN_CONFIG_FILE_H__
+#define __WPAN_CONFIG_FILE_H__ 1
+
+__BEGIN_DECLS
+extern char* get_next_arg(char *buf, char **rest);
+
+typedef int (*config_param_set_func)(void* context, const char* key, const char* value);
+
+extern int read_config(const char* filename, config_param_set_func setter, void* context);
+__END_DECLS
+
+#endif // __WPAN_CONFIG_FILE_H__
diff --git a/src/util/nlpt-select.c b/src/util/nlpt-select.c
new file mode 100644
index 0000000..f53281d
--- /dev/null
+++ b/src/util/nlpt-select.c
@@ -0,0 +1,141 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Flavor of protothreads for handling asynchronous I/O, via select()
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _XOPEN_SOURCE 1 // For the "fds_bits" member of "fd_set"
+
+#include <stdio.h>
+#include <stdint.h>
+#include "nlpt.h"
+#include "nlpt-select.h"
+#include "assert-macros.h"
+
+static void
+fd_set_merge(const fd_set *src, fd_set *dest, int fd_count)
+{
+	int i;
+	const int32_t* src_data = (const int32_t*)src->fds_bits;
+	int32_t* dest_data = (int32_t*)dest->fds_bits;
+
+	for (i = (fd_count+31)/32; i > 0 ; --i) {
+		*dest_data++ |= *src_data++;
+	}
+}
+
+void
+nlpt_select_update_fd_set(
+	const struct nlpt* nlpt,
+	fd_set *read_fd_set,
+	fd_set *write_fd_set,
+	fd_set *error_fd_set,
+	int *max_fd
+) {
+	if ((max_fd != NULL) && (*max_fd < nlpt->max_fd)) {
+		*max_fd = nlpt->max_fd;
+	}
+
+	if (read_fd_set != NULL) {
+		fd_set_merge(&nlpt->read_fds, read_fd_set, nlpt->max_fd + 1);
+	}
+
+	if (write_fd_set != NULL) {
+		fd_set_merge(&nlpt->write_fds, write_fd_set, nlpt->max_fd + 1);
+	}
+
+	if (error_fd_set != NULL) {
+		fd_set_merge(&nlpt->error_fds, error_fd_set, nlpt->max_fd + 1);
+	}
+}
+
+bool
+_nlpt_checkpoll(int fd, short poll_flags)
+{
+	bool ret = false;
+
+	if (fd >= 0) {
+		struct pollfd pollfd = { fd, poll_flags, 0 };
+		IGNORE_RETURN_VALUE( poll(&pollfd, 1, 0) );
+		ret = ((pollfd.revents & poll_flags) != 0);
+	}
+
+	return ret;
+}
+
+void
+_nlpt_cleanup_all(struct nlpt* nlpt)
+{
+	nlpt->max_fd = -1;
+	FD_ZERO(&nlpt->read_fds);
+	FD_ZERO(&nlpt->write_fds);
+	FD_ZERO(&nlpt->error_fds);
+}
+
+void
+_nlpt_cleanup_read_fd_source(struct nlpt* nlpt, int fd)
+{
+	if (fd >= 0) {
+		FD_CLR(fd, &nlpt->read_fds);
+		FD_CLR(fd, &nlpt->error_fds);
+	}
+}
+
+void
+_nlpt_cleanup_write_fd_source(struct nlpt* nlpt, int fd)
+{
+	if (fd >= 0) {
+		FD_CLR(fd, &nlpt->write_fds);
+		FD_CLR(fd, &nlpt->error_fds);
+	}
+}
+
+void
+_nlpt_setup_read_fd_source(struct nlpt* nlpt, int fd)
+{
+	if (fd >= 0) {
+		if (fd > nlpt->max_fd) {
+			nlpt->max_fd = fd;
+		}
+		FD_SET(fd, &nlpt->read_fds);
+		FD_SET(fd, &nlpt->error_fds);
+	}
+}
+
+void
+_nlpt_setup_write_fd_source(struct nlpt* nlpt, int fd)
+{
+	if (fd >= 0) {
+		if (fd > nlpt->max_fd) {
+			nlpt->max_fd = fd;
+		}
+		FD_SET(fd, &nlpt->write_fds);
+		FD_SET(fd, &nlpt->error_fds);
+	}
+}
+
+void
+_nlpt_init(struct nlpt* nlpt)
+{
+	_nlpt_cleanup_all(nlpt);
+}
diff --git a/src/util/nlpt-select.h b/src/util/nlpt-select.h
new file mode 100644
index 0000000..0508f2e
--- /dev/null
+++ b/src/util/nlpt-select.h
@@ -0,0 +1,75 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Flavor of protothreads for handling asynchronous I/O, via select()
+ *
+ */
+
+#ifndef wpantund_nlpt_select_h
+#define wpantund_nlpt_select_h
+
+#include <stdbool.h>
+#include <poll.h>
+#include <sys/select.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+struct nlpt {
+	struct pt pt;
+	struct pt sub_pt;
+	size_t byte_count;
+	int last_errno;
+
+	fd_set read_fds;
+	fd_set write_fds;
+	fd_set error_fds;
+	int max_fd;
+};
+
+/* ========================================================================= */
+/* Private, Back-end-specific functions */
+
+extern void _nlpt_init(struct nlpt* nlpt);
+extern void _nlpt_cleanup_all(struct nlpt* nlpt);
+extern void _nlpt_cleanup_read_fd_source(struct nlpt* nlpt, int fd);
+extern void _nlpt_cleanup_write_fd_source(struct nlpt* nlpt, int fd);
+extern void _nlpt_setup_read_fd_source(struct nlpt* nlpt, int fd);
+extern void _nlpt_setup_write_fd_source(struct nlpt* nlpt, int fd);
+
+/* ========================================================================= */
+/* Protected, Back-end-specific hooks (for async I/O) */
+
+extern bool nlpt_hook_check_read_fd_source(struct nlpt* nlpt, int fd);
+extern bool nlpt_hook_check_write_fd_source(struct nlpt* nlpt, int fd);
+
+/* ========================================================================= */
+/* Public, Back-end-specific functions (for async I/O) */
+
+extern void nlpt_select_update_fd_set(
+	const struct nlpt* nlpt,
+	fd_set *read_fd_set,
+	fd_set *write_fd_set,
+	fd_set *error_fd_set,
+	int *max_fd
+);
+extern bool _nlpt_checkpoll(int fd, short poll_flags);
+
+__END_DECLS
+
+#endif
diff --git a/src/util/nlpt.h b/src/util/nlpt.h
new file mode 100644
index 0000000..2b438a6
--- /dev/null
+++ b/src/util/nlpt.h
@@ -0,0 +1,129 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Flavor of protothreads for handling asynchronous I/O.
+ *
+ */
+
+#ifndef wpantund_nlpt_h
+#define wpantund_nlpt_h
+
+#include "pt.h"
+
+#if USING_GLIB
+#include "nlpt-glib.h"
+#else
+#include "nlpt-select.h"
+#endif
+
+#define NLPT_INIT(nlpt) do { memset(nlpt, 0, sizeof(*nlpt)); PT_INIT(&(nlpt)->pt); _nlpt_init(nlpt); } while (0)
+
+#define NLPT_THREAD(name_args)          PT_THREAD(name_args)
+#define NLPT_BEGIN(nlpt)                PT_BEGIN(&(nlpt)->pt)
+#define NLPT_END(nlpt)                  PT_END(&(nlpt)->pt)
+#define NLPT_SPAWN(nlpt, child, thread) PT_SPAWN(&(nlpt)->pt, &(child)->pt, thread)
+#define NLPT_WAIT_UNTIL(nlpt, cond)     PT_WAIT_UNTIL(&(nlpt)->pt, cond)
+#define NLPT_WAIT_WHILE(nlpt, cond)     PT_WAIT_WHILE(&(nlpt)->pt, cond)
+#define NLPT_RESTART(nlpt)              PT_RESTART(&(nlpt)->pt)
+#define NLPT_EXIT(nlpt)                 PT_EXIT(&(nlpt)->pt)
+#define NLPT_YIELD(nlpt)                PT_YIELD(&(nlpt)->pt)
+#define NLPT_YIELD_UNTIL(nlpt, cond)    PT_YIELD_UNTIL(&(nlpt)->pt, cond)
+
+//! Waits until one of the two given file descriptors are readable or the condition is satisfied.
+#define NLPT_WAIT_UNTIL_READABLE2_OR_COND(nlpt, fd_, fd2_, c) \
+	do {                                                     \
+		_nlpt_setup_read_fd_source(nlpt, fd_); \
+		_nlpt_setup_read_fd_source(nlpt, fd2_); \
+		NLPT_WAIT_UNTIL(nlpt, \
+						 nlpt_hook_check_read_fd_source(nlpt, fd_) \
+						 || nlpt_hook_check_read_fd_source(nlpt, fd2_) \
+						 || (c)); \
+		_nlpt_cleanup_read_fd_source(nlpt, fd2_); \
+		_nlpt_cleanup_read_fd_source(nlpt, fd_); \
+	} while (0)
+
+#define NLPT_WAIT_UNTIL_READABLE_OR_COND(nlpt, fd_, c) \
+	do {                                                     \
+		_nlpt_setup_read_fd_source(nlpt, fd_); \
+		NLPT_WAIT_UNTIL(nlpt, \
+						 nlpt_hook_check_read_fd_source(nlpt, fd_) || (c)); \
+		_nlpt_cleanup_read_fd_source(nlpt, fd_); \
+	} while (0)
+
+#define NLPT_WAIT_UNTIL_WRITABLE_OR_COND(nlpt, fd_, c) \
+	do {                                                     \
+		_nlpt_setup_write_fd_source(nlpt, fd_); \
+		NLPT_WAIT_UNTIL(nlpt, \
+						 nlpt_hook_check_write_fd_source(nlpt, fd_) || (c)); \
+		_nlpt_cleanup_write_fd_source(nlpt, fd_); \
+	} while (0)
+
+#define NLPT_YIELD_UNTIL_READABLE2_OR_COND(nlpt, fd_, fd2_, c) \
+	do {                                                     \
+		_nlpt_setup_read_fd_source(nlpt, fd_); \
+		_nlpt_setup_read_fd_source(nlpt, fd2_); \
+		NLPT_YIELD_UNTIL(nlpt, \
+						 nlpt_hook_check_read_fd_source(nlpt, fd_) \
+						 || nlpt_hook_check_read_fd_source(nlpt, fd2_) \
+						 || (c)); \
+		_nlpt_cleanup_read_fd_source(nlpt, fd2_); \
+		_nlpt_cleanup_read_fd_source(nlpt, fd_); \
+	} while (0)
+
+#define NLPT_YIELD_UNTIL_READABLE_OR_COND(nlpt, fd_, c) \
+	do {                                                     \
+		_nlpt_setup_read_fd_source(nlpt, fd_); \
+		NLPT_YIELD_UNTIL(nlpt, \
+						 nlpt_hook_check_read_fd_source(nlpt, fd_) || (c)); \
+		_nlpt_cleanup_read_fd_source(nlpt, fd_); \
+	} while (0)
+
+#define NLPT_YIELD_UNTIL_WRITABLE_OR_COND(nlpt, fd_, c) \
+	do {                                                     \
+		_nlpt_setup_write_fd_source(nlpt, fd_); \
+		NLPT_YIELD_UNTIL(nlpt, \
+						 nlpt_hook_check_write_fd_source(nlpt, fd_) || (c)); \
+		_nlpt_cleanup_write_fd_source(nlpt, fd_); \
+	} while (0)
+
+#define NLPT_WAIT_UNTIL_READABLE(nlpt, fd) \
+	NLPT_WAIT_UNTIL_READABLE_OR_COND( \
+	    nlpt, \
+	    fd, \
+	    0)
+
+#define NLPT_WAIT_UNTIL_WRITABLE(nlpt, fd) \
+	NLPT_WAIT_UNTIL_WRITABLE_OR_COND( \
+	    nlpt, \
+	    fd, \
+	    0)
+
+#define NLPT_YIELD_UNTIL_READABLE(nlpt, fd) \
+	NLPT_YIELD_UNTIL_READABLE_OR_COND( \
+	    nlpt, \
+	    fd, \
+	    0)
+
+#define NLPT_YIELD_UNTIL_WRITABLE(nlpt, fd) \
+	NLPT_YIELD_UNTIL_WRITABLE_OR_COND( \
+	    nlpt, \
+	    fd, \
+	    0)
+
+
+#endif
diff --git a/src/util/sec-random.c b/src/util/sec-random.c
new file mode 100644
index 0000000..7e73f51
--- /dev/null
+++ b/src/util/sec-random.c
@@ -0,0 +1,60 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "sec-random.h"
+
+static FILE* gSecRandomFile;
+
+int
+sec_random_init(void)
+{
+	if (gSecRandomFile == NULL) {
+		const char* random_source_filename = getenv("SEC_RANDOM_SOURCE_FILE");
+
+		if (!random_source_filename) {
+			random_source_filename = "/dev/urandom";
+		}
+
+		gSecRandomFile = fopen(random_source_filename, "r");
+
+		if (gSecRandomFile == NULL) {
+			return -1;
+		}
+	}
+	return 0;
+}
+
+int
+sec_random_fill(uint8_t* buffer, int length)
+{
+	int ret = sec_random_init();
+
+	if (ret >= 0) {
+		ret = (int)fread(buffer, length, 1, gSecRandomFile);
+	}
+
+	return ret;
+}
diff --git a/src/util/sec-random.h b/src/util/sec-random.h
new file mode 100644
index 0000000..6d89c33
--- /dev/null
+++ b/src/util/sec-random.h
@@ -0,0 +1,33 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef SEC_RANDOM_HEADER_INCLUDED
+#define SEC_RANDOM_HEADER_INCLUDED 1
+
+#include <sys/cdefs.h>
+#include <stdint.h>
+
+__BEGIN_DECLS
+
+int sec_random_init(void);
+int sec_random_fill(uint8_t* buffer, int length);
+
+__END_DECLS
+
+#endif // SEC_RANDOM_HEADER_INCLUDED
diff --git a/src/util/socket-utils.c b/src/util/socket-utils.c
new file mode 100644
index 0000000..c829aef
--- /dev/null
+++ b/src/util/socket-utils.c
@@ -0,0 +1,949 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define _GNU_SOURCE 1
+
+#include "assert-macros.h"
+
+#include <stdio.h>
+#include "socket-utils.h"
+#include <ctype.h>
+#include <syslog.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <termios.h>
+#include <fcntl.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <ctype.h>
+#include <signal.h>
+
+#if HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+
+#if HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#if HAVE_PTY_H
+#include <pty.h>
+#endif
+
+#if HAVE_UTIL_H
+#include <util.h>
+#endif
+
+#if HAVE_SYS_PRCTL_H
+#include <sys/prctl.h>
+#endif
+
+
+#if !defined(HAVE_PTSNAME) && __APPLE__
+#define HAVE_PTSNAME 1
+#endif
+
+#if !HAVE_GETDTABLESIZE
+#define getdtablesize()     (int)sysconf(_SC_OPEN_MAX)
+#endif
+
+#ifndef O_NONBLOCK
+#define O_NONBLOCK          O_NDELAY
+#endif
+
+#include <poll.h>
+
+static struct {
+	int fd;
+	pid_t pid;
+} gSystemSocketTable[5];
+
+static void
+system_socket_table_close_alarm_(int sig)
+{
+	static const char message[] = "\nclose_super_socket: Unable to terminate child in a timely manner, watchdog fired\n";
+
+	// Can't use syslog here, write to stderr instead.
+	(void)write(STDERR_FILENO, message, sizeof(message) - 1);
+
+	_exit(EXIT_FAILURE);
+}
+
+static void
+system_socket_table_atexit_(void)
+{
+	int i;
+
+	for (i = 0; i < sizeof(gSystemSocketTable)/sizeof(gSystemSocketTable[0]); i++) {
+		if (gSystemSocketTable[i].pid != 0) {
+			kill(gSystemSocketTable[i].pid, SIGTERM);
+		}
+	}
+}
+
+static void
+system_socket_table_add_(int fd, pid_t pid)
+{
+	static bool did_init = false;
+	int i;
+
+	if (!did_init) {
+		atexit(&system_socket_table_atexit_);
+		did_init = true;
+	}
+
+	for (i = 0; i < sizeof(gSystemSocketTable)/sizeof(gSystemSocketTable[0]); i++) {
+		if (gSystemSocketTable[i].pid == 0) {
+			break;
+		}
+	}
+
+	// If we have more than 5 of these types of sockets
+	// open, then there is likely a serious problem going
+	// on that we should immediately deal with.
+	assert(i < sizeof(gSystemSocketTable)/sizeof(gSystemSocketTable[0]));
+
+	if (i < sizeof(gSystemSocketTable)/sizeof(gSystemSocketTable[0])) {
+		gSystemSocketTable[i].fd = fd;
+		gSystemSocketTable[i].pid = pid;
+	}
+}
+
+int
+close_super_socket(int fd)
+{
+	int i;
+	int ret;
+	for (i = 0; i < sizeof(gSystemSocketTable)/sizeof(gSystemSocketTable[0]); i++) {
+		if ( gSystemSocketTable[i].fd == fd
+		  && gSystemSocketTable[i].pid != 0
+		) {
+			break;
+		}
+	}
+
+	ret = close(fd);
+
+	if (i < sizeof(gSystemSocketTable)/sizeof(gSystemSocketTable[0])) {
+		pid_t pid = gSystemSocketTable[i].pid;
+		int x = 0, j = 0;
+
+		kill(gSystemSocketTable[i].pid, SIGHUP);
+
+		for (j = 0; j < 100; ++j) {
+			pid = waitpid(gSystemSocketTable[i].pid, &x, WNOHANG);
+			if (pid > 0) {
+				break;
+			}
+			usleep(100000);
+		}
+
+		if (pid <= 0) {
+			// Five second watchdog.
+			void (*prev_alarm_handler)(int) = signal(SIGALRM, &system_socket_table_close_alarm_);
+			unsigned int prev_alarm_remaining = alarm(5);
+
+			syslog(LOG_WARNING, "close_super_socket: PID %d didn't respond to SIGHUP, trying SIGTERM", gSystemSocketTable[i].pid);
+
+			kill(gSystemSocketTable[i].pid, SIGTERM);
+
+			do {
+				errno = 0;
+				pid = waitpid(gSystemSocketTable[i].pid, &x, 0);
+			} while ((pid == -1) && (errno == EINTR));
+
+			// Disarm watchdog.
+			alarm(prev_alarm_remaining);
+			signal(SIGALRM, prev_alarm_handler);
+		}
+
+		if (pid == -1) {
+			perror(strerror(errno));
+		}
+
+
+		gSystemSocketTable[i].pid = 0;
+		gSystemSocketTable[i].fd = -1;
+	}
+
+	return ret;
+}
+
+int
+fd_has_error(int fd)
+{
+	const int flags = (POLLPRI|POLLRDBAND|POLLERR|POLLHUP|POLLNVAL);
+	struct pollfd pollfd = { fd, flags, 0 };
+	int count = poll(&pollfd, 1, 0);
+
+	if (count<0) {
+		return -errno;
+	} else if (count > 0) {
+		if (pollfd.revents&POLLHUP) {
+			return -EPIPE;
+		}
+
+		if (pollfd.revents&(POLLRDBAND|POLLPRI)) {
+			return -EPIPE;
+		}
+
+		if (pollfd.revents&POLLNVAL) {
+			return -EINVAL;
+		}
+
+		if (pollfd.revents&POLLERR) {
+			return -EIO;
+		}
+	}
+	return 0;
+}
+
+int gSocketWrapperBaud = 115200;
+
+static bool
+socket_name_is_system_command(const char* socket_name)
+{
+	return strncmp(socket_name,SOCKET_SYSTEM_COMMAND_PREFIX,strlen(SOCKET_SYSTEM_COMMAND_PREFIX)) == 0
+	    || strncmp(socket_name,SOCKET_SYSTEM_FORKPTY_COMMAND_PREFIX,strlen(SOCKET_SYSTEM_FORKPTY_COMMAND_PREFIX)) == 0
+	    || strncmp(socket_name,SOCKET_SYSTEM_SOCKETPAIR_COMMAND_PREFIX,strlen(SOCKET_SYSTEM_SOCKETPAIR_COMMAND_PREFIX)) == 0
+	;
+}
+
+static bool
+socket_name_is_port(const char* socket_name)
+{
+	// It's a port if the string is just a number.
+	while (*socket_name) {
+		if (!isdigit(*socket_name++)) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static bool
+socket_name_is_inet(const char* socket_name)
+{
+	// It's an inet address if it Contains no slashes or starts with a '['.
+	if (*socket_name == '[') {
+		return true;
+	}
+	do {
+		if (*socket_name == '/') {
+			return false;
+		}
+	} while (*++socket_name);
+	return !socket_name_is_port(socket_name) && !socket_name_is_system_command(socket_name);
+}
+
+bool
+socket_name_is_device(const char* socket_name)
+{
+	return !socket_name_is_system_command(socket_name) && !socket_name_is_inet(socket_name);
+}
+
+int
+lookup_sockaddr_from_host_and_port(
+    struct sockaddr_in6* outaddr, const char* host, const char* port
+    )
+{
+	int ret = 0;
+	struct addrinfo hint = {
+	};
+
+	hint.ai_flags = AI_ADDRCONFIG | AI_V4MAPPED | AI_ALL;
+	hint.ai_family = AF_INET6;
+
+	struct addrinfo *results = NULL;
+	struct addrinfo *iter = NULL;
+
+	if (!port) {
+		port = "4951";
+	}
+
+	if (!host) {
+		host = "::1";
+	}
+
+	syslog(LOG_INFO, "Looking up [%s]:%s", host, port);
+
+	if (isdigit(port[0]) && strcmp(host, "::1") == 0) {
+		// Special case to avoid calling getaddrinfo() when
+		// we really don't need to.
+		memset(outaddr, 0, sizeof(struct sockaddr_in6));
+		outaddr->sin6_family = AF_INET6;
+		outaddr->sin6_addr.s6_addr[15] = 1;
+		outaddr->sin6_port = htons(atoi(port));
+	} else if (isdigit(port[0]) && inet_addr(host) != 0) {
+		in_addr_t v4addr = inet_addr(host);
+		memset(outaddr, 0, sizeof(struct sockaddr_in6));
+		outaddr->sin6_family = AF_INET6;
+		outaddr->sin6_addr.s6_addr[10] = 0xFF;
+		outaddr->sin6_addr.s6_addr[11] = 0xFF;
+		outaddr->sin6_port = htons(atoi(port));
+		memcpy(outaddr->sin6_addr.s6_addr + 12, &v4addr, sizeof(v4addr));
+		outaddr->sin6_port = htons(atoi(port));
+	} else {
+		int error = getaddrinfo(host, port, &hint, &results);
+
+		require_action_string(
+		    !error,
+		    bail,
+		    ret = -1,
+		    gai_strerror(error)
+		    );
+
+		for (iter = results;
+		     iter && (iter->ai_family != AF_INET6);
+		     iter = iter->ai_next) ;
+
+		require_action(NULL != iter, bail, ret = -1);
+
+		memcpy(outaddr, iter->ai_addr, iter->ai_addrlen);
+	}
+
+bail:
+	if (results)
+		freeaddrinfo(results);
+
+	return ret;
+}
+
+#if HAVE_FORKPTY
+static int
+diagnose_forkpty_problem()
+{
+	int ret = -1;
+	// COM-S-7530: Do some more diagnostics on the situation, because
+	// sort of failure is weird. We step through some of the same sorts of
+	// things that forkpty would do so that we can see where we are failing.
+	int pty_master_fd = -1;
+	int pty_slave_fd = -1;
+	do {
+		if( access( "/dev/ptmx", F_OK ) < 0 ) {
+			syslog(LOG_WARNING, "Call to access(\"/dev/ptmx\",F_OK) failed: %s (%d)", strerror(errno), errno);
+			perror("access(\"/dev/ptmx\",F_OK)");
+		}
+
+		if( access( "/dev/ptmx", R_OK|W_OK ) < 0 ) {
+			syslog(LOG_WARNING, "Call to access(\"/dev/ptmx\",R_OK|W_OK) failed: %s (%d)", strerror(errno), errno);
+			perror("access(\"/dev/ptmx\",R_OK|W_OK)");
+		}
+
+		pty_master_fd = posix_openpt(O_NOCTTY | O_RDWR);
+
+		if (pty_master_fd < 0) {
+			syslog(LOG_CRIT, "Call to posix_openpt() failed: %s (%d)", strerror(errno), errno);
+			perror("posix_openpt(O_NOCTTY | O_RDWR)");
+			break;
+		}
+
+		if (grantpt(pty_master_fd) < 0) {
+			syslog(LOG_CRIT, "Call to grantpt() failed: %s (%d)", strerror(errno), errno);
+			perror("grantpt");
+		}
+
+		if (unlockpt(pty_master_fd) < 0) {
+			syslog(LOG_CRIT, "Call to unlockpt() failed: %s (%d)", strerror(errno), errno);
+			perror("unlockpt");
+		}
+
+#if HAVE_PTSNAME
+		if (NULL == ptsname(pty_master_fd)) {
+			syslog(LOG_CRIT, "Call to ptsname() failed: %s (%d)", strerror(errno), errno);
+			perror("ptsname");
+			break;
+		}
+
+		pty_slave_fd = open(ptsname(pty_master_fd), O_RDWR | O_NOCTTY);
+
+		if (pty_slave_fd < 0) {
+			syslog(LOG_CRIT, "Call to open(\"%s\",O_RDWR|O_NOCTTY) failed: %s (%d)", ptsname(pty_master_fd), strerror(errno), errno);
+			perror("open(ptsname(pty_master_fd),O_RDWR|O_NOCTTY)");
+			break;
+		}
+#endif
+
+		ret = 0;
+	} while(0);
+	close(pty_master_fd);
+	close(pty_slave_fd);
+	return ret;
+}
+
+static int
+open_system_socket_forkpty(const char* command)
+{
+	int ret_fd = -1;
+	int stderr_copy_fd;
+	pid_t pid;
+	struct termios tios = { .c_cflag = CS8|HUPCL|CREAD|CLOCAL };
+
+	cfmakeraw(&tios);
+
+	// Duplicate stderr so that we can hook it back up in the forked process.
+	stderr_copy_fd = dup(STDERR_FILENO);
+	if (stderr_copy_fd < 0) {
+		syslog(LOG_ERR, "Call to dup() failed: %s (%d)", strerror(errno), errno);
+		goto cleanup_and_fail;
+	}
+
+	pid = forkpty(&ret_fd, NULL, &tios, NULL);
+	if (pid < 0) {
+		syslog(LOG_ERR, "Call to forkpty() failed: %s (%d)", strerror(errno), errno);
+
+		if (0 == diagnose_forkpty_problem()) {
+			syslog(LOG_CRIT, "FORKPTY() FAILED BUT NOTHING WAS OBVIOUSLY WRONG!!!");
+		}
+
+		goto cleanup_and_fail;
+	}
+
+	// Check to see if we are the forked process or not.
+	if (0 == pid) {
+		// We are the forked process.
+		const int dtablesize = getdtablesize();
+		int i;
+
+#if defined(_LINUX_PRCTL_H)
+		prctl(PR_SET_PDEATHSIG, SIGHUP);
+#endif
+
+		// Re-instate our original stderr.
+		dup2(stderr_copy_fd, STDERR_FILENO);
+
+		syslog(LOG_DEBUG, "Forked!");
+
+		// Re-instate our original stderr (clobbered by login_tty)
+		dup2(stderr_copy_fd, STDERR_FILENO);
+
+		// Set the shell environment variable if it isn't set already.
+		setenv("SHELL", SOCKET_UTILS_DEFAULT_SHELL, 0);
+
+		// Close all file descriptors larger than STDERR_FILENO.
+		for (i = (STDERR_FILENO + 1); i < dtablesize; i++) {
+			close(i);
+		}
+
+		syslog(LOG_NOTICE,"About to exec \"%s\"",command);
+
+		execl(getenv("SHELL"),getenv("SHELL"),"-c",command,NULL);
+
+		syslog(LOG_ERR,"Failed for fork and exec of \"%s\": %s (%d)", command, strerror(errno), errno);
+
+		_exit(errno);
+	}
+
+	// Clean up our copy of stderr
+	close(stderr_copy_fd);
+
+#if HAVE_PTSNAME
+	// See http://stackoverflow.com/questions/3486491/
+	close(open(ptsname(ret_fd), O_RDWR | O_NOCTTY));
+#endif
+
+	system_socket_table_add_(ret_fd, pid);
+
+	return ret_fd;
+
+cleanup_and_fail:
+	{
+		int prevErrno = errno;
+
+		close(ret_fd);
+		close(stderr_copy_fd);
+
+		errno = prevErrno;
+	}
+	return -1;
+}
+#endif // HAVE_FORKPTY
+
+#ifdef PF_UNIX
+
+int
+fork_unixdomain_socket(int* fd_pointer)
+{
+	int fd[2] = { -1, -1 };
+	int i;
+	pid_t pid = -1;
+
+	if (socketpair(PF_UNIX, SOCK_STREAM, 0, fd) < 0) {
+		syslog(LOG_ERR, "Call to socketpair() failed: %s (%d)", strerror(errno), errno);
+		goto bail;
+	}
+
+	pid = fork();
+	if (pid < 0) {
+		syslog(LOG_ERR, "Call to fork() failed: %s (%d)", strerror(errno), errno);
+		goto bail;
+	}
+
+	// Check to see if we are the forked process or not.
+	if (0 == pid) {
+		const int dtablesize = getdtablesize();
+		// We are the forked process.
+
+#if defined(_LINUX_PRCTL_H)
+		prctl(PR_SET_PDEATHSIG, SIGHUP);
+#endif
+
+		close(fd[0]);
+
+		dup2(fd[1], STDIN_FILENO);
+		dup2(fd[1], STDOUT_FILENO);
+
+		syslog(LOG_DEBUG, "Forked!");
+
+        // Close all file descriptors larger than STDERR_FILENO.
+        for (i = (STDERR_FILENO + 1); i < dtablesize; i++) {
+            close(i);
+		}
+
+		*fd_pointer = STDIN_FILENO;
+	} else {
+		close(fd[1]);
+		*fd_pointer = fd[0];
+	}
+
+	fd[0] = -1;
+	fd[1] = -1;
+
+bail:
+
+	{
+		int prevErrno = errno;
+		if (fd[0] >= 0) {
+			close(fd[0]);
+		}
+		if (fd[1] >= 0) {
+			close(fd[1]);
+		}
+		errno = prevErrno;
+	}
+
+	return pid;
+}
+
+static int
+open_system_socket_unix_domain(const char* command)
+{
+	int fd = -1;
+	pid_t pid = -1;
+
+	pid = fork_unixdomain_socket(&fd);
+
+	if (pid < 0) {
+		syslog(LOG_ERR, "Call to fork() failed: %s (%d)", strerror(errno), errno);
+		goto cleanup_and_fail;
+	}
+
+	// Check to see if we are the forked process or not.
+	if (0 == pid) {
+		// Set the shell environment variable if it isn't set already.
+		setenv("SHELL","/bin/sh",0);
+
+		syslog(LOG_NOTICE, "About to exec \"%s\"", command);
+
+		execl(getenv("SHELL"), getenv("SHELL"),"-c", command, NULL);
+
+		syslog(LOG_ERR, "Failed for fork and exec of \"%s\": %s (%d)", command, strerror(errno), errno);
+
+		_exit(EXIT_FAILURE);
+	}
+
+	system_socket_table_add_(fd, pid);
+
+	return fd;
+
+cleanup_and_fail:
+
+	if (fd >= 0) {
+		int prevErrno = errno;
+
+		close(fd);
+
+		errno = prevErrno;
+	}
+
+	return -1;
+}
+#endif // PF_UNIX
+
+static int
+open_system_socket(const char* command)
+{
+	int ret_fd = -1;
+
+#if HAVE_FORKPTY
+	ret_fd = open_system_socket_forkpty(command);
+#endif
+
+#if defined(PF_UNIX)
+	// Fall back to unix-domain socket-based mechanism:
+	if (ret_fd < 0) {
+		ret_fd = open_system_socket_unix_domain(command);
+	}
+#endif
+
+#if !HAVE_FORKPTY && !defined(PF_UNIX)
+	assert_printf("%s","Process pipe sockets are not supported in current configuration");
+	errno = ENOTSUP;
+#endif
+
+	return ret_fd;
+}
+
+int
+get_super_socket_type_from_path(const char* socket_name)
+{
+	int socket_type = SUPER_SOCKET_TYPE_UNKNOWN;
+
+	if (strncasecmp(socket_name, SOCKET_SYSTEM_COMMAND_PREFIX, sizeof(SOCKET_SYSTEM_COMMAND_PREFIX)-1) == 0) {
+		socket_type = SUPER_SOCKET_TYPE_SYSTEM;
+	} else if (strncasecmp(socket_name, SOCKET_SYSTEM_FORKPTY_COMMAND_PREFIX, sizeof(SOCKET_SYSTEM_FORKPTY_COMMAND_PREFIX)-1) == 0) {
+		socket_type = SUPER_SOCKET_TYPE_SYSTEM_FORKPTY;
+	} else if (strncasecmp(socket_name, SOCKET_SYSTEM_SOCKETPAIR_COMMAND_PREFIX, sizeof(SOCKET_SYSTEM_SOCKETPAIR_COMMAND_PREFIX)-1) == 0) {
+		socket_type = SUPER_SOCKET_TYPE_SYSTEM_SOCKETPAIR;
+	} else if (strncasecmp(socket_name, SOCKET_FD_COMMAND_PREFIX, sizeof(SOCKET_FD_COMMAND_PREFIX)-1) == 0) {
+		socket_type = SUPER_SOCKET_TYPE_FD;
+	} else if (strncasecmp(socket_name, SOCKET_FILE_COMMAND_PREFIX, sizeof(SOCKET_FILE_COMMAND_PREFIX)-1) == 0) {
+		socket_type = SUPER_SOCKET_TYPE_DEVICE;
+	} else if (strncasecmp(socket_name, SOCKET_SERIAL_COMMAND_PREFIX, sizeof(SOCKET_SERIAL_COMMAND_PREFIX)-1) == 0) {
+		socket_type = SUPER_SOCKET_TYPE_DEVICE;
+	} else if (strncasecmp(socket_name, SOCKET_TCP_COMMAND_PREFIX, sizeof(SOCKET_TCP_COMMAND_PREFIX)-1) == 0) {
+		socket_type = SUPER_SOCKET_TYPE_TCP;
+	} else if (socket_name_is_inet(socket_name) || socket_name_is_port(socket_name)) {
+		socket_type = SUPER_SOCKET_TYPE_TCP;
+	} else if (socket_name_is_device(socket_name)) {
+		socket_type = SUPER_SOCKET_TYPE_DEVICE;
+	}
+	return socket_type;
+}
+
+int
+baud_rate_to_termios_constant(int baud)
+{
+	int ret;
+	// Standard "TERMIOS" uses constants to get and set
+	// the baud rate, but we use the actual baud rate.
+	// This function converts from the actual baud rate
+	// to the constant supported by this platform. It
+	// returns zero if the baud rate is unsupported.
+	switch(baud) {
+	case 9600:
+		ret = B9600;
+		break;
+	case 19200:
+		ret = B19200;
+		break;
+	case 38400:
+		ret = B38400;
+		break;
+	case 57600:
+		ret = B57600;
+		break;
+	case 115200:
+		ret = B115200;
+		break;
+#ifdef B230400
+	case 230400:
+		ret = B230400;
+		break;
+#endif
+	default:
+		ret = 0;
+		break;
+	}
+	return ret;
+}
+
+int
+open_super_socket(const char* socket_name)
+{
+	int fd = -1;
+	char* host = NULL; // Needs to be freed if set
+	const char* port = NULL;
+	char* options = strchr(socket_name, ',');
+	char* filename = strchr(socket_name, ':');
+	bool socket_name_is_well_formed = true; // True if socket has type name and options
+	int socket_type = get_super_socket_type_from_path(socket_name);
+
+	// Move past the colon, if there was one.
+	if (NULL != filename && socket_name[0] != '[') {
+		filename++;
+	} else {
+		filename = "";
+	}
+
+	if (socket_type == SUPER_SOCKET_TYPE_DEVICE) {
+		socket_name_is_well_formed =
+			(strncasecmp(socket_name, SOCKET_SERIAL_COMMAND_PREFIX, sizeof(SOCKET_SERIAL_COMMAND_PREFIX)-1) == 0)
+			|| (strncasecmp(socket_name, SOCKET_FILE_COMMAND_PREFIX, sizeof(SOCKET_FILE_COMMAND_PREFIX)-1) == 0);
+	}
+
+	if (socket_type == SUPER_SOCKET_TYPE_TCP) {
+		socket_name_is_well_formed =
+			(strncasecmp(socket_name, SOCKET_TCP_COMMAND_PREFIX, sizeof(SOCKET_TCP_COMMAND_PREFIX)-1) == 0);
+		if (!socket_name_is_well_formed) {
+			filename = (char*)socket_name;
+		}
+	}
+
+	if (!socket_name_is_well_formed) {
+		filename = (char*)socket_name;
+		if (socket_type == SUPER_SOCKET_TYPE_DEVICE) {
+			options = ",default";
+		} else {
+			options = NULL;
+		}
+	}
+
+	filename = strdup(filename);
+
+	if (NULL == filename) {
+		perror("strdup");
+		syslog(LOG_ERR, "strdup failed. \"%s\" (%d)", strerror(errno), errno);
+		goto bail;
+	}
+
+	// Make sure we zero terminate the file name before
+	// any options. (this is why we needed to strdup)
+	if (socket_name_is_well_formed && (NULL != options)) {
+		const char* ptr = strchr(socket_name, ':');
+		if (NULL == ptr) {
+			ptr = socket_name;
+		} else {
+			ptr++;
+		}
+		filename[options-ptr] = 0;
+	}
+
+	if (SUPER_SOCKET_TYPE_SYSTEM == socket_type) {
+		fd = open_system_socket(filename);
+#if HAVE_FORKPTY
+	} else if (SUPER_SOCKET_TYPE_SYSTEM_FORKPTY == socket_type) {
+		fd = open_system_socket_forkpty(filename);
+#endif
+	} else if (SUPER_SOCKET_TYPE_SYSTEM_SOCKETPAIR == socket_type) {
+		fd = open_system_socket_unix_domain(filename);
+	} else if (SUPER_SOCKET_TYPE_FD == socket_type) {
+		fd = dup((int)strtol(filename, NULL, 0));
+	} else if (SUPER_SOCKET_TYPE_DEVICE == socket_type) {
+		fd = open(filename, O_RDWR | O_NOCTTY | O_NONBLOCK);
+
+		if (fd >= 0) {
+			fcntl(fd, F_SETFL, O_NONBLOCK);
+			tcflush(fd, TCIOFLUSH);
+		}
+	} else if (SUPER_SOCKET_TYPE_TCP == socket_type) {
+		struct sockaddr_in6 addr;
+
+		if (socket_name_is_port(socket_name)) {
+			port = socket_name;
+		} else {
+			ssize_t i;
+			if (filename[0] == '[') {
+				host = strdup(filename + 1);
+			} else {
+				host = strdup(filename);
+			}
+			for (i = strlen(host) - 1; i >= 0; --i) {
+				if (host[i] == ':' && port == NULL) {
+					host[i] = 0;
+					port = host + i + 1;
+					continue;
+				}
+				if (host[i] == ']') {
+					host[i] = 0;
+					break;
+				}
+				if (!isdigit(host[i]))
+					break;
+			}
+		}
+
+		if (0 != lookup_sockaddr_from_host_and_port(&addr, host, port)) {
+			syslog(LOG_ERR, "Unable to lookup \"%s\"", socket_name);
+			goto bail;
+		}
+
+		fd = socket(AF_INET6, SOCK_STREAM, 0);
+
+		if (fd < 0) {
+			syslog(LOG_ERR, "Unable to open socket. \"%s\" (%d)", strerror(errno), errno);
+			goto bail;
+		}
+
+		if (0 != connect(fd, (struct sockaddr*)&addr, sizeof(addr))) {
+			syslog(LOG_ERR, "Call to connect() failed. \"%s\" (%d)", strerror(errno), errno);
+			close(fd);
+			fd = -1;
+			goto bail;
+		}
+	} else {
+		syslog(LOG_ERR, "I don't know how to open \"%s\" (socket type %d)", socket_name, (int)socket_type);
+	}
+
+	if (fd < 0) {
+		syslog(LOG_ERR, "Unable to open socket. \"%s\" (%d) (filename = %s, type = %d)", strerror(errno), errno, filename, (int)socket_type);
+		goto bail;
+	}
+
+	// Configure the socket.
+	{
+		int flags = fcntl(fd, F_GETFL);
+		int i;
+		struct termios tios;
+		fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+
+#ifdef SO_NOSIGPIPE
+		int set = 0;
+		setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int));
+#endif
+
+#define FETCH_TERMIOS() do { if(0 != tcgetattr(fd, &tios)) { \
+			syslog(LOG_DEBUG, "tcgetattr() failed. \"%s\" (%d)", strerror(errno), errno); \
+		} } while(0)
+
+#define COMMIT_TERMIOS() do { if(0 != tcsetattr(fd, TCSANOW, &tios)) { \
+			syslog(LOG_DEBUG, "tcsetattr() failed. \"%s\" (%d)", strerror(errno), errno); \
+		} } while(0)
+
+		// Parse the options, if any
+		for (; NULL != options; options = strchr(options+1, ',')) {
+			if (strncasecmp(options, ",b", 2) == 0 && isdigit(options[2])) {
+				// Change Baud rate
+				int baud = baud_rate_to_termios_constant((int)strtol(options+2,NULL,10));
+				FETCH_TERMIOS();
+				cfsetspeed(&tios, baud);
+				COMMIT_TERMIOS();
+			} else if (strncasecmp(options, ",default", strlen(",default")) == 0) {
+				FETCH_TERMIOS();
+				for (i=0; i < NCCS; i++) {
+					tios.c_cc[i] = _POSIX_VDISABLE;
+				}
+
+				tios.c_cflag = (CS8|HUPCL|CREAD|CLOCAL);
+				tios.c_iflag = 0;
+				tios.c_oflag = 0;
+				tios.c_lflag = 0;
+
+				cfmakeraw(&tios);
+				cfsetspeed(&tios, baud_rate_to_termios_constant(gSocketWrapperBaud));
+				COMMIT_TERMIOS();
+			} else if (strncasecmp(options, ",raw", 4) == 0) {
+				// Raw mode
+				FETCH_TERMIOS();
+				cfmakeraw(&tios);
+				COMMIT_TERMIOS();
+			} else if (strncasecmp(options, ",clocal=", 8) == 0) {
+				FETCH_TERMIOS();
+				options = strchr(options,'=');
+				if (options[1] == '1') {
+					tios.c_cflag |= CLOCAL;
+				} else if (options[1] == '0') {
+					tios.c_cflag &= ~CLOCAL;
+				}
+				COMMIT_TERMIOS();
+			} else if (strncasecmp(options, ",ixoff=", 6) == 0) {
+				FETCH_TERMIOS();
+				options = strchr(options,'=');
+				if (options[1] == '1') {
+					tios.c_iflag |= IXOFF;
+				} else if (options[1] == '0') {
+					tios.c_iflag &= ~IXOFF;
+				}
+				COMMIT_TERMIOS();
+			} else if (strncasecmp(options, ",ixon=", 6) == 0) {
+				FETCH_TERMIOS();
+				options = strchr(options,'=');
+				if (options[1] == '1') {
+					tios.c_iflag |= IXON;
+				} else if (options[1] == '0') {
+					tios.c_iflag &= ~IXON;
+				}
+				COMMIT_TERMIOS();
+			} else if (strncasecmp(options, ",ixany=", 6) == 0) {
+				FETCH_TERMIOS();
+				options = strchr(options,'=');
+				if (options[1] == '1') {
+					tios.c_iflag |= IXANY;
+				} else if (options[1] == '0') {
+					tios.c_iflag &= ~IXANY;
+				}
+				COMMIT_TERMIOS();
+			} else if (strncasecmp(options, ",crtscts=", 9) == 0) {
+				FETCH_TERMIOS();
+				options = strchr(options,'=');
+				// Hardware flow control
+				if (options[1] == '1') {
+					syslog(LOG_DEBUG, "Using hardware flow control for serial socket.");
+					tios.c_cflag |= CRTSCTS;
+				} else if (options[1] == '0') {
+					tios.c_cflag &= ~CRTSCTS;
+				}
+				COMMIT_TERMIOS();
+
+#ifdef CCTS_OFLOW
+			} else if (strncasecmp(options, ",ccts_oflow=", 12) == 0) {
+				FETCH_TERMIOS();
+				options = strchr(options,'=');
+				// Hardware output flow control
+				if (options[1] == '1') {
+					syslog(LOG_DEBUG, "Using hardware output flow control for serial socket.");
+					tios.c_cflag |= CCTS_OFLOW;
+				} else if (options[1] == '0') {
+					tios.c_cflag &= ~CCTS_OFLOW;
+				}
+				COMMIT_TERMIOS();
+#endif
+#ifdef CRTS_IFLOW
+			} else if (strncasecmp(options, ",crts_iflow=", 12) == 0) {
+				FETCH_TERMIOS();
+				options = strchr(options,'=');
+				// Hardware input flow control
+				if (options[1] == '1') {
+					syslog(LOG_DEBUG, "Using hardware input flow control for serial socket.");
+					tios.c_cflag |= CRTS_IFLOW;
+				} else if (options[1] == '0') {
+					tios.c_cflag &= ~CRTS_IFLOW;
+				}
+				COMMIT_TERMIOS();
+#endif
+			} else {
+				syslog(LOG_ERR, "Unknown option (%s)", options);
+			}
+		}
+	}
+bail:
+	free(filename);
+	free(host);
+	return fd;
+}
diff --git a/src/util/socket-utils.h b/src/util/socket-utils.h
new file mode 100644
index 0000000..3a9a825
--- /dev/null
+++ b/src/util/socket-utils.h
@@ -0,0 +1,66 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef wpantund_socket_utils_h
+#define wpantund_socket_utils_h
+
+#include <stdbool.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#define SOCKET_SYSTEM_COMMAND_PREFIX	"system:"
+#define SOCKET_FD_COMMAND_PREFIX	"fd:"
+#define SOCKET_FILE_COMMAND_PREFIX	"file:"
+#define SOCKET_SERIAL_COMMAND_PREFIX	"serial:"
+#define SOCKET_TCP_COMMAND_PREFIX	"tcp:"
+#define SOCKET_SYSTEM_FORKPTY_COMMAND_PREFIX	"system-forkpty:"
+#define SOCKET_SYSTEM_SOCKETPAIR_COMMAND_PREFIX	"system-socketpair:"
+
+#ifndef SOCKET_UTILS_DEFAULT_SHELL
+#define SOCKET_UTILS_DEFAULT_SHELL         "/bin/sh"
+#endif
+
+__BEGIN_DECLS
+extern int gSocketWrapperBaud;
+bool socket_name_is_device(const char* socket_name);
+int lookup_sockaddr_from_host_and_port( struct sockaddr_in6* outaddr, const char* host, const char* port);
+int open_super_socket(const char* socket_name);
+int close_super_socket(int fd);
+int fd_has_error(int fd);
+
+enum {
+	SUPER_SOCKET_TYPE_UNKNOWN,
+	SUPER_SOCKET_TYPE_SYSTEM,
+	SUPER_SOCKET_TYPE_SYSTEM_FORKPTY,
+	SUPER_SOCKET_TYPE_SYSTEM_SOCKETPAIR,
+	SUPER_SOCKET_TYPE_FD,
+	SUPER_SOCKET_TYPE_TCP,
+	SUPER_SOCKET_TYPE_DEVICE
+};
+
+int get_super_socket_type_from_path(const char* path);
+
+int fork_unixdomain_socket(int* fd_pointer);
+
+__END_DECLS
+
+
+#endif
diff --git a/src/util/string-utils.c b/src/util/string-utils.c
new file mode 100644
index 0000000..d3f13c3
--- /dev/null
+++ b/src/util/string-utils.c
@@ -0,0 +1,299 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file defines utility functions for manipulating and comparing
+ *      C-strings or other buffers.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include "string-utils.h"
+#include <ctype.h>
+#include <inttypes.h>
+#include <stdlib.h>
+
+#define __USE_GNU // Needed for `strcasestr`
+#include <string.h>
+
+void
+memcpyrev(void *dest_, const void *src_, size_t len)
+{
+	uint8_t* const dest = dest_;
+	const uint8_t* const src = src_;
+	int i;
+
+	for (i = 0; i < len; i++) {
+		dest[i] = src[len - 1 - i];
+	}
+}
+
+int
+memcmprev(const void *dest_, const void *src_, size_t len)
+{
+	const uint8_t* const dest = dest_;
+	const uint8_t* const src = src_;
+	int ret = 0;
+	int i;
+
+	for (i = 0; i < len && !ret; i++) {
+		ret = dest[i] - src[len - 1 - i];
+	}
+	return ret;
+}
+
+void
+reverse_bytes(uint8_t *bytes, size_t count)
+{
+	int i;
+
+	for (i = 0; i < count / 2; i++) {
+		uint8_t x = bytes[i];
+		bytes[i] = bytes[count - i - 1];
+		bytes[count - i - 1] = x;
+	}
+}
+
+int
+parse_string_into_data(uint8_t* buffer, size_t len, const char* c_str)
+{
+	int ret = 0;
+
+	if (NULL == buffer) {
+		len = 0;
+	}
+
+	while (*c_str != 0) {
+		char c = tolower(*c_str++);
+		if (!(isdigit(c) || (c >= 'a' && c <= 'f'))) {
+			continue;
+		}
+		c = isdigit(c) ? (c - '0') : (c - 'a' + 10);
+		if (len > 0) {
+			*buffer = (c << 4);
+			len--;
+		}
+		ret++;
+		if (!*c_str) {
+			break;
+		}
+		c = tolower(*c_str++);
+		if (!(isdigit(c) || (c >= 'a' && c <= 'f'))) {
+			continue;
+		}
+		c = isdigit(c) ? (c - '0') : (c - 'a' + 10);
+		*buffer++ |= c;
+	}
+
+	return ret;
+}
+
+int
+encode_data_into_string(
+    const uint8_t*  buffer,
+    size_t len,
+    char*                   c_str,
+    size_t c_str_max_len,
+    int pad_to
+    ) {
+	int ret = 0;
+
+	c_str_max_len--;
+	while (len && (c_str_max_len > 4)) {
+		uint8_t byte = *buffer++;
+		len--;
+		pad_to--;
+		*c_str++ = int_to_hex_digit(byte >> 4);
+		*c_str++ = int_to_hex_digit(byte & 0xF);
+		c_str_max_len -= 2;
+		ret += 2;
+	}
+
+	while (pad_to > 0 && (c_str_max_len > 4)) {
+		pad_to--;
+		*c_str++ = '0';
+		*c_str++ = '0';
+		c_str_max_len -= 2;
+		ret += 2;
+	}
+
+	c_str_max_len--;
+	*c_str++ = 0;
+	return ret;
+}
+
+bool
+strtobool(const char* string)
+{
+	bool ret = false;
+	switch(string[0]) {
+	case 'y':
+	case 'Y':
+	case 't':
+	case 'T':
+		ret = true;
+		break;
+
+	case 'n':
+	case 'N':
+	case 'f':
+	case 'F':
+		ret = false;
+		break;
+
+	default:
+		ret = (strtol(string, NULL, 0) != 0);
+		break;
+	}
+	return ret;
+}
+
+uint32_t
+strtomask_uint32(const char* in_string)
+{
+	char *tmp_string = strdup(in_string);
+	char *chan_ranges;      // points to a channel num or a range of channels
+	char *dash_location;    // points to location of the dash in a range of channels
+	uint8_t channel_start = 0;
+	uint8_t channel_stop = 0;
+	uint32_t mask = 0;
+
+	chan_ranges = strtok(tmp_string, ",");
+	while(chan_ranges != NULL) {
+		// loop to parse channels by comma (,)
+		// each fragment may include a range (-) of channels
+
+		dash_location = strchr(chan_ranges, '-');
+		if (dash_location != NULL) {
+			// process a range of channels
+			*dash_location = '\0';
+			dash_location++;
+			if (atoi(chan_ranges) < atoi(dash_location)) {
+				channel_start = atoi(chan_ranges);
+				channel_stop = atoi(dash_location);
+			} else {
+				channel_stop = atoi(chan_ranges);
+				channel_start = atoi(dash_location);
+			}
+
+			while (channel_start <= channel_stop) {
+				mask |= (1 << channel_start);
+				channel_start++;
+			}
+		} else {
+			// no range, just add channel to the scan mask
+
+			mask |= (1 << strtol(chan_ranges, NULL, 0));
+		}
+		chan_ranges = strtok(NULL, ",");
+	}
+	free(tmp_string);
+	return mask;
+}
+
+#include <syslog.h>
+
+int
+strtologmask(const char* value, int prev_mask)
+{
+	int mask = (int)strtol(value, NULL, 0);
+
+	if (mask == 0) {
+		mask = prev_mask;
+
+		if(strcasestr(value, "all") != NULL) {
+			if (strcasestr(value, "-all") != NULL) {
+				mask &= 0;
+			} else {
+				mask |= ~0;
+			}
+		}
+		if (strcasestr(value, "emerg") != NULL) {
+			if (strcasestr(value, "-emerg") != NULL) {
+				mask &= ~LOG_MASK(LOG_EMERG);
+			} else {
+				mask |= LOG_MASK(LOG_EMERG);
+			}
+		}
+		if (strcasestr(value, "alert") != NULL) {
+			if (strcasestr(value, "-alert") != NULL) {
+				mask &= ~LOG_MASK(LOG_ALERT);
+			} else {
+				mask |= LOG_MASK(LOG_ALERT);
+			}
+		}
+		if (strcasestr(value, "crit") != NULL) {
+			if (strcasestr(value, "-crit") != NULL) {
+				mask &= ~LOG_MASK(LOG_CRIT);
+			} else {
+				mask |= LOG_MASK(LOG_CRIT);
+			}
+		}
+		if (strcasestr(value, "err") != NULL) {
+			if (strcasestr(value, "-err") != NULL) {
+				mask &= ~LOG_MASK(LOG_ERR);
+			} else {
+				mask |= LOG_MASK(LOG_ERR);
+			}
+		}
+		if (strcasestr(value, "warn") != NULL) {
+			if (strcasestr(value, "-warn") != NULL) {
+				mask &= ~LOG_MASK(LOG_WARNING);
+			} else {
+				mask |= LOG_MASK(LOG_WARNING);
+			}
+		}
+		if (strcasestr(value, "notice") != NULL) {
+			if (strcasestr(value, "-notice") != NULL) {
+				mask &= ~LOG_MASK(LOG_NOTICE);
+			} else {
+				mask |= LOG_MASK(LOG_NOTICE);
+			}
+		}
+		if (strcasestr(value, "info") != NULL) {
+			if (strcasestr(value, "-info") != NULL) {
+				mask &= ~LOG_MASK(LOG_INFO);
+			} else {
+				mask |= LOG_MASK(LOG_INFO);
+			}
+		}
+		if (strcasestr(value, "debug") != NULL) {
+			if (strcasestr(value, "-debug") != NULL) {
+				mask &= ~LOG_MASK(LOG_DEBUG);
+			} else {
+				mask |= LOG_MASK(LOG_DEBUG);
+			}
+		}
+	}
+
+	return mask;
+}
+
+bool
+buffer_is_nonzero(const uint8_t* buffer, size_t len)
+{
+	while (len--) {
+		if (*buffer++ != 0) {
+			return true;
+		}
+	}
+	return false;
+}
diff --git a/src/util/string-utils.h b/src/util/string-utils.h
new file mode 100644
index 0000000..528fbd2
--- /dev/null
+++ b/src/util/string-utils.h
@@ -0,0 +1,58 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file declares utility functions for manipulating and comparing
+ *      C-strings or other buffers.
+ *
+ */
+
+#ifndef wpantund_string_utils_h
+#define wpantund_string_utils_h
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/cdefs.h>
+
+#define strcaseequal(x, y)   (strcasecmp(x, y) == 0)
+#define strncaseequal(x, y, n)   (strncasecmp(x, y, n) == 0)
+#define strequal(x, y)   (strcmp(x, y) == 0)
+#define strnequal(x, y, n)   (strncmp(x, y, n) == 0)
+
+__BEGIN_DECLS
+extern void memcpyrev(void* dest, const void *src, size_t len);
+extern int memcmprev(const void* dest, const void *src, size_t len);
+extern void reverse_bytes(uint8_t *bytes, size_t count);
+extern int parse_string_into_data(uint8_t* buffer, size_t len, const char* c_str);
+extern int encode_data_into_string(const uint8_t*  buffer, size_t len, char* c_str, size_t c_str_max_len, int pad_to);
+extern int strtologmask(const char* value, int prev_mask);
+extern bool buffer_is_nonzero(const uint8_t* buffer, size_t len);
+
+static inline char
+int_to_hex_digit(uint8_t x)
+{
+	return "0123456789ABCDEF"[x & 0xF];
+}
+
+uint32_t strtomask_uint32(const char* in_string);
+
+extern bool strtobool(const char* string);
+
+__END_DECLS
+
+#endif
diff --git a/src/util/time-utils.c b/src/util/time-utils.c
new file mode 100644
index 0000000..40c4bd7
--- /dev/null
+++ b/src/util/time-utils.c
@@ -0,0 +1,70 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "time-utils.h"
+#include <sys/time.h>
+
+cms_t
+time_ms(void)
+{
+#if HAVE_CLOCK_GETTIME
+	struct timespec tv = { 0 };
+	int ret;
+
+	ret = clock_gettime(CLOCK_MONOTONIC, &tv);
+
+	return (cms_t)(tv.tv_sec * MSEC_PER_SEC) + (cms_t)(tv.tv_nsec / NSEC_PER_MSEC);
+#else
+	struct timeval tv = { 0 };
+	gettimeofday(&tv, NULL);
+	return (cms_t)(tv.tv_sec * MSEC_PER_SEC) + (cms_t)(tv.tv_usec / USEC_PER_MSEC);
+#endif
+}
+
+time_t
+time_get_monotonic(void)
+{
+#if HAVE_CLOCK_GETTIME
+	struct timespec ts;
+	int ret;
+
+	ret = clock_gettime(CLOCK_MONOTONIC, &ts);
+
+	return ret == 0 ? ts.tv_sec : 0;
+#else
+	return time(NULL);
+#endif // !__linux__
+}
+
+cms_t
+cms_until_time(time_t time)
+{
+	time -= time_get_monotonic();
+
+	if (time > (TIME_DISTANT_FUTURE / MSEC_PER_SEC)) {
+		// Overflow.
+		return CMS_DISTANT_FUTURE;
+	}
+
+	return (cms_t)(time * MSEC_PER_SEC);
+}
diff --git a/src/util/time-utils.h b/src/util/time-utils.h
new file mode 100644
index 0000000..0dcae86
--- /dev/null
+++ b/src/util/time-utils.h
@@ -0,0 +1,66 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef wpantund_timeutils_h
+#define wpantund_timeutils_h
+
+#ifndef __STDC_CONSTANT_MACROS
+#define __STDC_CONSTANT_MACROS 1
+#endif
+
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/cdefs.h>
+#include <time.h>
+
+#ifndef MSEC_PER_SEC
+#define MSEC_PER_SEC	1000
+#endif
+
+#ifndef USEC_PER_MSEC
+#define USEC_PER_MSEC	1000
+#endif
+
+#ifndef NSEC_PER_MSEC
+#define NSEC_PER_MSEC	1000000
+#endif
+
+#ifndef CMS_DISTANT_FUTURE
+#define CMS_DISTANT_FUTURE			INT32_MAX
+#endif
+
+#ifndef TIME_DISTANT_FUTURE
+#define TIME_DISTANT_FUTURE			INTPTR_MAX
+#endif
+
+#define CMS_SINCE(x)	(time_ms() - (x))
+
+__BEGIN_DECLS
+typedef int32_t cms_t;
+
+extern cms_t time_ms(void);
+extern time_t time_get_monotonic(void);
+extern cms_t cms_until_time(time_t time);
+__END_DECLS
+
+#endif
diff --git a/src/util/tunnel.c b/src/util/tunnel.c
new file mode 100644
index 0000000..e503981
--- /dev/null
+++ b/src/util/tunnel.c
@@ -0,0 +1,644 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *		This file implements the code which managed the TUN interface.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef ASSERT_MACROS_USE_SYSLOG
+#define ASSERT_MACROS_USE_SYSLOG 1
+#endif
+
+#include "assert-macros.h"
+#include "pt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "tunnel.h"
+#include <syslog.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+#ifndef __APPLE__
+#include <linux/if_tun.h>
+#endif
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <net/route.h> // AF_ROUTE things
+
+#ifdef __APPLE__
+#include <netinet6/in6_var.h>
+#include <netinet6/nd6.h>   // ND6_INFINITE_LIFETIME
+#include <net/if_dl.h>      // struct sockaddr_dl
+#include <net/if_utun.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/kern_control.h>
+#include <sys/ioctl.h>
+#include <sys/sys_domain.h>
+#include <sys/kern_event.h>
+#define IFEF_NOAUTOIPV6LL   0x2000  /* Interface IPv6 LinkLocal address not provided by kernel */
+#endif
+
+#ifndef TUNNEL_TUNTAP_DEVICE
+#define TUNNEL_TUNTAP_DEVICE               "/dev/net/tun"
+#endif
+
+int
+tunnel_open(const char* tun_name)
+{
+	int fd = -1;
+	char *device = NULL;
+
+	if ((tun_name == NULL) || (tun_name[0] == 0)) {
+		tun_name = TUNNEL_DEFAULT_INTERFACE_NAME;
+	}
+
+	syslog(LOG_INFO, "Opening tun interface socket with name \"%s\"", tun_name);
+
+#if defined(UTUN_CONTROL_NAME)
+	int error = 0;
+	fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
+	struct sockaddr_ctl addr;
+
+	/* get/set the id */
+	struct ctl_info info;
+	memset(&info, 0, sizeof(info));
+	strncpy(info.ctl_name, UTUN_CONTROL_NAME, strlen(UTUN_CONTROL_NAME));
+	error = ioctl(fd, CTLIOCGINFO, &info);
+
+	if (error) {
+		syslog(LOG_ERR, "Failed to open utun interface: %s", strerror(errno));
+		close(fd);
+		fd = -1;
+		goto bail;
+	}
+
+	addr.sc_id = info.ctl_id;
+	addr.sc_len = sizeof(addr);
+	addr.sc_family = AF_SYSTEM;
+	addr.ss_sysaddr = AF_SYS_CONTROL;
+	addr.sc_unit = 0;  /* allocate dynamically */
+
+	if (strncmp(tun_name, "utun", 4) == 0)
+		addr.sc_unit = (int)strtol(tun_name + 4, NULL, 10) + 1;
+
+	error = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
+
+	if (error && errno == EBUSY) {
+		addr.sc_unit = 0;  /* allocate dynamically */
+		error = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
+	}
+
+	if (error) {
+		syslog(LOG_ERR, "Failed to open tun interface: %s", strerror(errno));
+		close(fd);
+		fd = -1;
+		goto bail;
+	}
+
+	tunnel_bring_offline(fd);
+
+	goto bail;
+
+#else
+
+#ifdef __APPLE__
+	if (strncmp(tun_name, "utun", 4) == 0)
+		tun_name = "tun0";
+	asprintf(&device, "/dev/%s", tun_name);
+#else
+	device = strdup(TUNNEL_TUNTAP_DEVICE);
+#endif
+
+	require(NULL != device, bail);
+
+	fd = open(device, O_RDWR | O_NONBLOCK);
+
+	if (0 > fd) {
+		syslog(LOG_ERR, "Failed to open tun interface: %s", strerror(errno));
+		perror("open-tun");
+		goto bail;
+	}
+#endif
+
+#ifdef TUNSETIFF
+	struct ifreq ifr = { .ifr_flags = IFF_TUN | IFF_NO_PI };
+	strncpy(ifr.ifr_name, tun_name, IFNAMSIZ);
+
+	require(0 == ioctl(fd, TUNSETIFF, (void*)&ifr), bail);
+
+	// Verify that the name was set. If it wasn't
+	// we need to fail.
+	char name[20] = "";
+
+	if (tunnel_get_name(fd, name, sizeof(name)) != 0) {
+		syslog(LOG_ERR, "Unable to set name on tun interface: %s", strerror(errno));
+		perror("open-tun");
+		close(fd);
+		fd = -1;
+		goto bail;
+	}
+
+	if (name[0] == 0) {
+		syslog(LOG_ERR, "Unable to set name on tun interface");
+		close(fd);
+		fd = -1;
+		goto bail;
+	}
+
+#endif
+
+bail:
+	free(device);
+	return fd;
+}
+
+void
+tunnel_close(int fd)
+{
+	close(fd);
+}
+
+int
+tunnel_get_name(
+    int fd, char* name, int maxlen
+    )
+{
+	int ret = -1;
+
+	if (maxlen && name) name[0] = 0;
+#if defined(UTUN_CONTROL_NAME)
+	socklen_t len = maxlen;
+	if (0 == getsockopt(fd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME, name, &len)) {
+		ret = 0;
+		goto bail;
+	}
+#elif defined(TUNGETIFF)
+	struct ifreq ifr = { };
+	require(0 == ioctl(fd, TUNGETIFF, (void*)&ifr), bail);
+	strncpy(name, ifr.ifr_name, maxlen);
+#else
+	struct stat st;
+	ret = fstat(fd, &st);
+	if (ret) {
+		perror("tunnel_get_name: fstat failed.");
+		goto bail;
+	}
+	devname_r(st.st_rdev, S_IFCHR, name, (int)maxlen);
+#endif
+	ret = 0;
+bail:
+	return ret;
+}
+
+static int
+_tunnel_get_iff(
+    int fd, struct ifreq *ifr
+    )
+{
+	int ret = -1;
+
+	ret = tunnel_get_name(fd, ifr->ifr_name, sizeof(ifr->ifr_name));
+
+	return ret;
+}
+
+
+bool
+tunnel_is_online(int fd)
+{
+	bool ret = false;
+	int status = -1;
+	int reqfd = -1;
+	struct ifreq ifr = { };
+
+	/* get interface name */
+	_tunnel_get_iff(fd, &ifr);
+
+	reqfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
+
+	status = ioctl(reqfd, SIOCGIFFLAGS, &ifr);
+	require_string(status == 0, bail, strerror(errno));
+
+	ret = ((ifr.ifr_flags & IFF_UP) == IFF_UP);
+
+bail:
+	close(reqfd);
+	return ret;
+}
+
+int
+tunnel_bring_online(int fd)
+{
+	int ret = -1;
+	int reqfd = -1;
+	struct ifreq ifr = { };
+
+	/* get interface name */
+	_tunnel_get_iff(fd, &ifr);
+
+	reqfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
+
+	ret = ioctl(reqfd, SIOCGIFFLAGS, &ifr);
+	require_string(ret == 0, bail, strerror(errno));
+
+	ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
+	ret = ioctl(reqfd, SIOCSIFFLAGS, &ifr);
+	require_string(ret == 0, bail, strerror(errno));
+
+bail:
+	close(reqfd);
+	return ret;
+}
+
+int
+tunnel_bring_offline(int fd)
+{
+	int ret = -1;
+	int reqfd = -1;
+	struct ifreq ifr = { };
+
+	/* get interface name */
+	_tunnel_get_iff(fd, &ifr);
+
+	reqfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
+
+	ret = ioctl(reqfd, SIOCGIFFLAGS, &ifr);
+	require_string(ret == 0, bail, strerror(errno));
+
+	ifr.ifr_flags &= ~(IFF_UP);
+	ret = ioctl(reqfd, SIOCSIFFLAGS, &ifr);
+	require_string(ret == 0, bail, strerror(errno));
+
+bail:
+	close(reqfd);
+	return ret;
+}
+
+int
+tunnel_set_mtu(
+    int fd, uint16_t mtu
+    )
+{
+	int ret = -1;
+	int reqfd = -1;
+	struct ifreq ifr = { };
+
+	/* get interface name */
+	_tunnel_get_iff(fd, &ifr);
+
+	reqfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
+
+	ifr.ifr_mtu = mtu;
+
+	ret = ioctl(reqfd, SIOCSIFMTU, &ifr);
+
+	if (ret)
+		perror("tapdev: Uable to set MTU, call to ioctl failed.");
+
+	close(reqfd);
+	return ret;
+}
+#ifndef SIOCSIFLLADDR
+#define SIOCSIFLLADDR SIOCSIFHWADDR
+#endif
+
+
+static inline void
+apply_mask(
+    struct in6_addr *address, uint8_t mask
+    )
+{
+	// Coverty might complain in this function, but don't believe it.
+	// This code has been reviewed carefully and should not misbehave.
+
+	if (mask > 128) {
+		mask = 128;
+	}
+
+	memset(
+		(void*)(address->s6_addr + ((mask + 7) / 8)),
+	    0,
+	    16 - ((mask + 7) / 8)
+	);
+
+	if (mask % 8) {
+		address->s6_addr[mask / 8] &= ~(0xFF >> (mask % 8));
+	}
+}
+
+int
+tunnel_add_address(
+    int fd, const uint8_t addr[16], int prefixlen
+    )
+{
+	int ret = -1;
+	int reqfd = -1;
+
+	reqfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
+
+#ifdef __APPLE__
+
+	/************* Add address *************/
+
+	struct in6_aliasreq addreq6 = { };
+
+	ret = tunnel_get_name(fd, addreq6.ifra_name, sizeof(addreq6.ifra_name));
+
+	if (ret) {
+		perror("tunnel_add_address: Uable to get interface name.");
+		goto bail;
+	}
+
+	addreq6.ifra_addr.sin6_family = AF_INET6;
+	addreq6.ifra_addr.sin6_len = sizeof(addreq6.ifra_addr);
+	memcpy((void*)&addreq6.ifra_addr.sin6_addr, addr, 16);
+
+	addreq6.ifra_prefixmask.sin6_family = AF_INET6;
+	addreq6.ifra_prefixmask.sin6_len = sizeof(addreq6.ifra_prefixmask);
+	memset((void*)&addreq6.ifra_prefixmask.sin6_addr, 0xFF, 16);
+	apply_mask(&addreq6.ifra_prefixmask.sin6_addr, prefixlen);
+
+	addreq6.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
+	addreq6.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
+	addreq6.ifra_lifetime.ia6t_expire = ND6_INFINITE_LIFETIME;
+	addreq6.ifra_lifetime.ia6t_preferred = ND6_INFINITE_LIFETIME;
+
+	addreq6.ifra_flags |= IN6_IFF_NODAD;
+
+	ret = ioctl(reqfd, SIOCAIFADDR_IN6, &addreq6);
+	if (ret && errno != EALREADY)
+		goto bail;
+
+#else
+
+	/* Linux */
+
+	// In linux, we need to remove the address first.
+	tunnel_remove_address(fd, addr);
+
+#define ifreq_offsetof(x)  offsetof(struct ifreq, x)
+
+	struct in6_ifreq {
+		struct in6_addr ifr6_addr;
+		__u32 ifr6_prefixlen;
+		unsigned int ifr6_ifindex;
+	};
+
+	struct ifreq ifr = { };
+	struct sockaddr_in6 sai;
+	int sockfd;
+	struct in6_ifreq ifr6;
+
+	/* get interface name */
+	_tunnel_get_iff(fd, &ifr);
+
+	memset(&sai, 0, sizeof(struct sockaddr));
+	sai.sin6_family = AF_INET6;
+	sai.sin6_port = 0;
+
+	memcpy((void*)&sai.sin6_addr, addr, 16);
+
+	memcpy((char*)&ifr6.ifr6_addr, (char*)&sai.sin6_addr,
+	       sizeof(struct in6_addr));
+
+	if (ioctl(reqfd, SIOGIFINDEX, &ifr) < 0)
+		perror("SIOGIFINDEX");
+	ifr6.ifr6_ifindex = ifr.ifr_ifindex;
+	ifr6.ifr6_prefixlen = 64;
+	ret = ioctl(reqfd, SIOCSIFADDR, &ifr6);
+	if (ret && errno != EALREADY)
+		goto bail;
+	ret = 0;
+
+#endif
+	ret = 0;
+bail:
+	if (ret) {
+		syslog(LOG_INFO, "tunnel_add_address: errno=%d (%s)", errno, strerror(errno));
+	}
+	if (reqfd >= 0)
+		close(reqfd);
+
+	return ret;
+}
+
+int
+tunnel_remove_address(
+    int fd, const uint8_t addr[16]
+    )
+{
+	int ret = -1;
+
+	int reqfd = -1;
+
+	reqfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
+
+	struct sockaddr_in6 sai = { };
+
+	memset(&sai, 0, sizeof(struct sockaddr));
+	sai.sin6_family = AF_INET6;
+	sai.sin6_port = 0;
+	memcpy((void*)&sai.sin6_addr, addr, 16);
+
+	/************* Remove address *************/
+
+#ifdef __APPLE__
+	sai.sin6_len = sizeof(sai);
+
+
+	struct in6_ifreq ifreq6 = { };
+	ret = tunnel_get_name(fd, ifreq6.ifr_name, sizeof(ifreq6.ifr_name));
+
+	if (ret)
+		goto bail;
+
+	ifreq6.ifr_addr = sai;
+
+	if (-1 == ioctl(reqfd, SIOCDIFADDR_IN6, &ifreq6)) {
+		ret = -errno;
+		goto bail;
+	}
+
+#else
+	int ifindex = 0;
+	{
+		struct ifreq ifr = { };
+
+		/* get interface name */
+		_tunnel_get_iff(fd, &ifr);
+
+		if (ioctl(reqfd, SIOGIFINDEX, &ifr) < 0)
+			perror("SIOGIFINDEX");
+
+		ifindex = ifr.ifr_ifindex;
+	}
+
+	struct in6_ifreq {
+		struct in6_addr ifr6_addr;
+		__u32 ifr6_prefixlen;
+		unsigned int ifr6_ifindex;
+	};
+
+	struct in6_ifreq ifr6;
+
+	ifr6.ifr6_addr = sai.sin6_addr;
+	ifr6.ifr6_ifindex = ifindex;
+	ifr6.ifr6_prefixlen = 64;
+
+	if (ioctl(reqfd, SIOCDIFADDR, &ifr6) < 0) {
+		ret = -errno;
+		goto bail;
+	}
+#endif
+	ret = 0;
+
+bail:
+	if (reqfd >= 0)
+		close(reqfd);
+
+	return ret;
+}
+
+
+int
+tunnel_add_route(
+    int fd, const uint8_t route[16], int prefixlen
+    )
+{
+	int ret = -1;
+	int reqfd = -1;
+
+	reqfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
+
+#ifdef __APPLE__
+
+	/************* Add ROUTE TODO *************/
+
+#else
+	/* Linux */
+
+	struct ifreq ifr;
+	struct in6_rtmsg rt;
+
+	memset(&ifr, 0, sizeof(struct ifreq));
+
+	/* get interface name */
+	_tunnel_get_iff(fd, &ifr);
+
+	memset(&rt, 0, sizeof(struct in6_rtmsg));
+	memcpy(rt.rtmsg_dst.s6_addr, route, sizeof(struct in6_addr));
+	rt.rtmsg_dst_len = prefixlen;
+	rt.rtmsg_flags = RTF_UP;
+	if (prefixlen == 128) {
+		rt.rtmsg_flags |= RTF_HOST;
+	}
+	rt.rtmsg_metric = 512;
+
+	if (ioctl(reqfd, SIOGIFINDEX, &ifr) < 0)
+		perror("SIOGIFINDEX");
+
+	rt.rtmsg_ifindex = ifr.ifr_ifindex;
+
+	ret = ioctl(reqfd, SIOCADDRT, &rt);
+	if (ret && errno != EALREADY && errno != EEXIST)
+		goto bail;
+
+#endif
+
+	ret = 0;
+bail:
+	if (ret) {
+		syslog(LOG_INFO, "tunnel_add_route: errno=%d (%s)", errno, strerror(errno));
+	}
+	if (reqfd >= 0)
+		close(reqfd);
+
+	return ret;
+}
+
+int
+tunnel_remove_route(
+    int fd, const uint8_t route[16], int prefixlen
+    )
+{
+    int ret = -1;
+    int reqfd = -1;
+
+    reqfd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
+
+#ifdef __APPLE__
+
+    /************* Remove ROUTE TODO *************/
+
+#else
+    /* Linux */
+
+    struct ifreq ifr;
+    struct in6_rtmsg rt;
+
+    memset(&ifr, 0, sizeof(struct ifreq));
+
+    /* get interface name */
+    _tunnel_get_iff(fd, &ifr);
+
+    memset(&rt, 0, sizeof(struct in6_rtmsg));
+    memcpy(rt.rtmsg_dst.s6_addr, route, sizeof(struct in6_addr));
+    rt.rtmsg_dst_len = prefixlen;
+    rt.rtmsg_flags = RTF_UP;
+    if (prefixlen == 128) {
+        rt.rtmsg_flags |= RTF_HOST;
+    }
+    rt.rtmsg_metric = 512;
+
+    if (ioctl(reqfd, SIOGIFINDEX, &ifr) < 0)
+        perror("SIOGIFINDEX");
+
+    rt.rtmsg_ifindex = ifr.ifr_ifindex;
+
+    ret = ioctl(reqfd, SIOCDELRT, &rt);
+    if (ret && errno != EALREADY && errno != EEXIST)
+        goto bail;
+
+#endif
+
+    ret = 0;
+bail:
+    if (ret) {
+        syslog(LOG_INFO, "tunnel_remove_route: errno=%d (%s)", errno, strerror(errno));
+    }
+    if (reqfd >= 0)
+        close(reqfd);
+
+    return ret;
+}
diff --git a/src/util/tunnel.h b/src/util/tunnel.h
new file mode 100644
index 0000000..64ecd57
--- /dev/null
+++ b/src/util/tunnel.h
@@ -0,0 +1,59 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *		This file implements the code which managed the TUN interface.
+ *
+ */
+
+
+#ifndef wpantund_tunnel_h
+#define wpantund_tunnel_h
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __APPLE__
+#define TUNNEL_DEFAULT_INTERFACE_NAME   "utun2"
+#else
+#define TUNNEL_DEFAULT_INTERFACE_NAME   "wpan0"
+#endif
+
+#define TUNNEL_MAX_INTERFACE_NAME_LEN	60
+
+__BEGIN_DECLS
+extern int tunnel_open(const char* tun_name);
+extern int tunnel_get_name(
+    int fd, char* name, int maxlen);
+extern int tunnel_set_mtu(
+    int fd, uint16_t mtu);
+extern int tunnel_add_address(
+    int fd, const uint8_t addr[16], int prefixlen);
+extern int tunnel_remove_address(
+    int fd, const uint8_t addr[16]);
+extern void tunnel_close(int fd);
+extern int tunnel_bring_online(int fd);
+extern int tunnel_bring_offline(int fd);
+extern bool tunnel_is_online(int fd);
+extern int tunnel_add_route(
+    int fd, const uint8_t route[16], int prefixlen);
+extern int tunnel_remove_route(
+    int fd, const uint8_t route[16], int prefixlen);
+__END_DECLS
+
+
+#endif
diff --git a/src/version.c.in b/src/version.c.in
new file mode 100644
index 0000000..dcefa39
--- /dev/null
+++ b/src/version.c.in
@@ -0,0 +1,26 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "version.h"
+
+const char *internal_build_source_version = SOURCE_VERSION;
+const char *internal_build_date = __DATE__ " " __TIME__;
diff --git a/src/version.h b/src/version.h
new file mode 100644
index 0000000..be8524c
--- /dev/null
+++ b/src/version.h
@@ -0,0 +1,29 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef INTERNAL_VERSION_H__
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+extern const char *internal_build_source_version;
+extern const char *internal_build_date;
+__END_DECLS
+
+#endif // INTERNAL_VERSION_H__
diff --git a/src/wpanctl/Makefile.am b/src/wpanctl/Makefile.am
new file mode 100644
index 0000000..95c1972
--- /dev/null
+++ b/src/wpanctl/Makefile.am
@@ -0,0 +1,100 @@
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src \
+	-I$(top_srcdir)/src/ipc-dbus \
+	-I$(top_srcdir)/src/util \
+	-I$(top_srcdir)/src/wpantund \
+	-I$(top_srcdir)/third_party/fgetln \
+	-I$(top_srcdir)/third_party/assert-macros \
+	$(NULL)
+
+DISTCLEANFILES = .deps Makefile
+
+bin_PROGRAMS = wpanctl
+
+wpanctl_SOURCES = \
+	wpanctl.c \
+	wpanctl-cmds.h \
+	../util/config-file.c \
+	../util/string-utils.c \
+	wpanctl-utils.c \
+	tool-cmd-scan.c \
+	tool-cmd-join.c \
+	tool-cmd-form.c \
+	tool-cmd-mfg.c \
+	tool-cmd-leave.c \
+	tool-cmd-permit-join.c \
+	tool-cmd-list.c \
+	tool-cmd-status.c \
+	tool-cmd-resume.c \
+	tool-cmd-reset.c \
+	tool-cmd-getprop.c \
+	tool-cmd-setprop.c \
+	tool-cmd-begin-low-power.c \
+	tool-cmd-begin-net-wake.c \
+	tool-cmd-cd.c \
+	tool-cmd-poll.c \
+	tool-cmd-config-gateway.c \
+	tool-cmd-host-did-wake.c \
+	tool-cmd-add-route.c \
+	tool-cmd-remove-route.c \
+	wpanctl-utils.h \
+	tool-cmd-scan.h \
+	tool-cmd-join.h \
+	tool-cmd-form.h \
+	tool-cmd-leave.h \
+	tool-cmd-mfg.h \
+	tool-cmd-permit-join.h \
+	tool-cmd-list.h \
+	tool-cmd-status.h \
+	tool-cmd-resume.h \
+	tool-cmd-reset.h \
+	tool-cmd-getprop.h \
+	tool-cmd-setprop.h \
+	tool-cmd-begin-low-power.h \
+	tool-cmd-begin-net-wake.h \
+	tool-cmd-cd.h \
+	tool-cmd-poll.h \
+	tool-cmd-config-gateway.h \
+	tool-cmd-host-did-wake.h \
+	tool-cmd-add-route.h \
+	tool-cmd-remove-route.h \
+	tool-cmd-pcap.h \
+	tool-cmd-pcap.c \
+	$(NULL)
+
+wpanctl_LDADD = \
+	$(DBUS_LIBS) \
+	$(LIBREADLINE_LIBS) \
+	$(NULL)
+
+wpanctl_CPPFLAGS = \
+	$(AM_CPPFLAGS) \
+	$(DBUS_CFLAGS) \
+	$(LIBREADLINE_CPPFLAGS) \
+	$(NULL)
+
+
+SOURCE_VERSION=$(shell git describe --dirty --always --match "[0-9].*" 2> /dev/null)
+BUILT_SOURCES  = $(top_builddir)/$(subdir)/version.c
+CLEANFILES = $(top_builddir)/$(subdir)/version.c
+.INTERMEDIATE: wpanctl-version.$(OBJEXT)
+$(top_builddir)/$(subdir)/version.c: ../version.c.in Makefile
+	sed 's/SOURCE_VERSION/"$(SOURCE_VERSION)"/' < $< > $@
+wpanctl_SOURCES += $(top_builddir)/$(subdir)/version.c
diff --git a/src/wpanctl/tool-cmd-add-route.c b/src/wpanctl/tool-cmd-add-route.c
new file mode 100644
index 0000000..c615c2f
--- /dev/null
+++ b/src/wpanctl/tool-cmd-add-route.c
@@ -0,0 +1,258 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file implements "add-route" command in wpanctl.
+ *
+ */
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-add-route.h"
+#include "assert-macros.h"
+#include "args.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v1.h"
+#include "string-utils.h"
+
+#include <arpa/inet.h>
+#include <errno.h>
+
+const char add_route_cmd_syntax[] = "[args] <prefix>";
+
+static const arg_list_item_t add_route_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'p', "priority", "(>0 for high, 0 for medium, <0 for low)", "Assign route priority"},
+	{'l', "length", "in bytes", "Specifies the route prefix length (default is 8)"},
+	{'d', "domain", NULL, "Domain id for the route (default is zero)"},
+	{0}
+};
+
+int tool_cmd_add_route(int argc, char* argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
+
+	DBusConnection* connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+
+	const char *route_prefix = NULL;
+	int prefix_len = 8;
+	int16_t priority = 0;
+	uint16_t domain_id = 0;
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"priority", required_argument, 0, 'p'},
+			{"length", required_argument, 0, 'l'},
+			{"domain", required_argument, 0, 'd'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "hp:l:d:", long_options,
+				&option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(add_route_option_list, argv[0],
+					    add_route_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 'p':
+			priority = (int16_t) strtol(optarg, NULL, 0);
+			break;
+
+		case 'l' :
+			prefix_len = (int) strtol(optarg, NULL, 0);
+			break;
+
+		case 'd':
+			domain_id = (uint16_t) strtol(optarg, NULL, 0);
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		route_prefix = argv[optind];
+		optind++;
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+		        "%s: error: Unexpected extra argument: \"%s\"\n",
+		        argv[0], argv[optind]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPANTUND_DBUS_PATH,
+		         gInterfaceName);
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPANTUND_DBUS_APIv1_INTERFACE,
+		    WPANTUND_IF_CMD_ROUTE_ADD
+		);
+
+		if ((route_prefix != NULL) && (0 <= prefix_len) && (prefix_len <= 16)) {
+			uint8_t prefix_bytes[16];
+
+			memset(prefix_bytes, 0, sizeof(prefix_bytes));
+
+			// So the prefix could either be
+			// specified like an IPv6 address, or
+			// specified as a bunch of hex numbers.
+			// We use the presence of a colon (':')
+			// to differentiate.
+			if (strstr(route_prefix, ":")) {
+
+				// Address-style
+				int bits = inet_pton(AF_INET6, route_prefix, prefix_bytes);
+				if (bits < 0) {
+					fprintf(stderr,
+					        "Bad prefix \"%s\", errno=%d (%s)\n",
+					        route_prefix,
+					        errno,
+					        strerror(errno));
+					goto bail;
+				} else if (bits == 0) {
+					fprintf(stderr, "Bad prefix \"%s\"\n", route_prefix);
+					goto bail;
+				}
+			} else {
+				// DATA-style
+				int length = parse_string_into_data(prefix_bytes,
+				                                    16,
+				                                    route_prefix);
+				if(length<=0) {
+					fprintf(stderr, "Bad prefix \"%s\"\n", route_prefix);
+					goto bail;
+				}
+			}
+
+			fprintf(stderr, "Adding route prefix \"%s\" with len %d, priority \"%s\", domain-id %d.\n",
+				route_prefix, prefix_len,
+				(priority > 0)? "high" : ((priority < 0)? "low" : "medium"),
+				domain_id
+			);
+
+			uint8_t *addr = prefix_bytes;
+			uint8_t len = (uint8_t)prefix_len;
+
+			dbus_message_append_args(
+			    message,
+			    DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &addr, len,
+			    DBUS_TYPE_INVALID
+			);
+		} else {
+			dbus_message_append_args(
+			    message,
+			    DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, "", 0,
+			    DBUS_TYPE_INVALID
+			);
+		}
+
+		dbus_message_append_args(
+		    message,
+		    DBUS_TYPE_UINT16, &domain_id,
+		    DBUS_TYPE_INT16, &priority,
+		    DBUS_TYPE_INVALID
+		);
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		);
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_get_args(reply, &error,
+		                      DBUS_TYPE_INT32, &ret,
+		                      DBUS_TYPE_INVALID
+		                      );
+
+		if (!ret) {
+			fprintf(stderr, "Route prefix added.\n");
+		} else {
+			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
+			print_error_diagnosis(ret);
+		}
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-add-route.h b/src/wpanctl/tool-cmd-add-route.h
new file mode 100644
index 0000000..be200ec
--- /dev/null
+++ b/src/wpanctl/tool-cmd-add-route.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file declares function related to "add-route" command
+ *      in wpanctl.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_ADD_ROUTE_H
+#define WPANCTL_TOOL_CMD_ADD_ROUTE_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_add_route(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-begin-low-power.c b/src/wpanctl/tool-cmd-begin-low-power.c
new file mode 100644
index 0000000..7dc3250
--- /dev/null
+++ b/src/wpanctl/tool-cmd-begin-low-power.c
@@ -0,0 +1,168 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-begin-low-power.h"
+#include "assert-macros.h"
+#include "args.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v1.h"
+
+const char begin_low_power_cmd_syntax[] = "[args]";
+
+static const arg_list_item_t begin_low_power_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+	{0}
+};
+
+int tool_cmd_begin_low_power(int argc, char* argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = 30 * 1000;
+	DBusConnection* connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "ht:", long_options, &option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(begin_low_power_option_list, argv[0],
+					    begin_low_power_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+		        "%s: error: Unexpected extra argument: \"%s\"\n",
+			argv[0], argv[optind]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPANTUND_DBUS_PATH,
+		         gInterfaceName);
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPANTUND_DBUS_APIv1_INTERFACE,
+		    WPANTUND_IF_CMD_BEGIN_LOW_POWER
+		    );
+
+		fprintf(stderr, "Sending %s command. . .\n", WPANTUND_IF_CMD_BEGIN_LOW_POWER);
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_get_args(reply, &error,
+		                      DBUS_TYPE_INT32, &ret,
+		                      DBUS_TYPE_INVALID
+		                      );
+		if (ret == 6)
+			ret = 0;
+
+		if (ret) {
+			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
+			print_error_diagnosis(ret);
+		}
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-begin-low-power.h b/src/wpanctl/tool-cmd-begin-low-power.h
new file mode 100644
index 0000000..79bdc3f
--- /dev/null
+++ b/src/wpanctl/tool-cmd-begin-low-power.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_LURK_H
+#define WPANCTL_TOOL_CMD_LURK_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_begin_low_power(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-begin-net-wake.c b/src/wpanctl/tool-cmd-begin-net-wake.c
new file mode 100644
index 0000000..405f11c
--- /dev/null
+++ b/src/wpanctl/tool-cmd-begin-net-wake.c
@@ -0,0 +1,186 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file...
+ *
+ */
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-begin-net-wake.h"
+#include "assert-macros.h"
+#include "args.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v0.h"
+
+const char begin_net_wake_cmd_syntax[] = "[args] <data>";
+
+static const arg_list_item_t begin_net_wake_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+	{0}
+};
+
+int tool_cmd_begin_net_wake(int argc, char *argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
+	DBusConnection* connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+
+	bool has_net_wake_data = false;
+	uint8_t net_wake_data = 0;
+	uint32_t net_wake_flags = -1;
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "ht:", long_options, &option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(begin_net_wake_option_list,
+					    argv[0], begin_net_wake_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		if (!has_net_wake_data) {
+			net_wake_data = strtol(argv[optind], NULL, 0);
+			has_net_wake_data = true;
+			optind++;
+		}
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+		        "%s: error: Unexpected extra argument: \"%s\"\n",
+		        argv[0], argv[optind]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPAN_TUNNEL_DBUS_PATH,
+		         gInterfaceName);
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPAN_TUNNEL_DBUS_INTERFACE,
+		    WPAN_IFACE_CMD_BEGIN_NET_WAKE
+		    );
+
+		dbus_message_append_args(
+		    message,
+		    DBUS_TYPE_BYTE, &net_wake_data,
+		    DBUS_TYPE_UINT32, &net_wake_flags,
+		    DBUS_TYPE_INVALID
+		    );
+
+		fprintf(stderr,
+				"Begin Net Wake, data = 0x%02X\n",
+				net_wake_data);
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_get_args(reply, &error,
+		                      DBUS_TYPE_INT32, &ret,
+		                      DBUS_TYPE_INVALID
+		                      );
+
+		if (ret) {
+			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, (ret<0)?strerror(-ret):"");
+			print_error_diagnosis(ret);
+		}
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-begin-net-wake.h b/src/wpanctl/tool-cmd-begin-net-wake.h
new file mode 100644
index 0000000..0c09648
--- /dev/null
+++ b/src/wpanctl/tool-cmd-begin-net-wake.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_BEGIN_NET_WAKE_H
+#define WPANCTL_TOOL_CMD_BEGIN_NET_WAKE_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_begin_net_wake(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-cd.c b/src/wpanctl/tool-cmd-cd.c
new file mode 100644
index 0000000..9c7d7b0
--- /dev/null
+++ b/src/wpanctl/tool-cmd-cd.c
@@ -0,0 +1,48 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "wpanctl-utils.h"
+#include "tool-cmd-cd.h"
+#include <string.h>
+
+int tool_cmd_cd(int argc, char* argv[])
+{
+	int ret = 0;
+
+	if ((2 == argc) && (0 == strcmp(argv[1], "--help"))) {
+		fprintf(stderr,
+		        "%s: Help not yet implemented for this command.\n",
+		        argv[0]);
+		ret = ERRORCODE_HELP;
+	}
+
+	if (argc == 1) {
+		printf("%s\n", gInterfaceName);
+		ret = ERRORCODE_HELP;
+	} else if (argc == 2) {
+		strncpy(gInterfaceName, argv[1], sizeof(gInterfaceName) - 1);
+	}
+
+bail:
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-cd.h b/src/wpanctl/tool-cmd-cd.h
new file mode 100644
index 0000000..82959c2
--- /dev/null
+++ b/src/wpanctl/tool-cmd-cd.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_CD_H
+#define WPANCTL_TOOL_CMD_CD_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_cd(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-config-gateway.c b/src/wpanctl/tool-cmd-config-gateway.c
new file mode 100644
index 0000000..2258cf2
--- /dev/null
+++ b/src/wpanctl/tool-cmd-config-gateway.c
@@ -0,0 +1,264 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-config-gateway.h"
+#include "assert-macros.h"
+#include "args.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v1.h"
+#include "string-utils.h"
+
+#include <arpa/inet.h>
+#include <errno.h>
+
+const char config_gateway_cmd_syntax[] = "[args] <prefix>";
+
+static const arg_list_item_t config_gateway_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+
+	{'p', "preferred-lifetime", "seconds",
+	 "Set the preferred lifetime (Default: infinite)"},
+	{'v', "valid-lifetime", "seconds",
+	 "Set the valid lifetime (Default: infinite)"},
+	{'d', "default", NULL, "Indicates that we can be a default route"},
+	{0}
+};
+
+int tool_cmd_config_gateway(int argc, char* argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
+	DBusConnection* connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+	dbus_bool_t defaultRoute = FALSE;
+	uint32_t preferredLifetime = 0xFFFFFFFF;
+	uint32_t validLifetime = 0xFFFFFFFF;
+	const char* prefix = NULL;
+	uint8_t prefix_length = 64;
+	char address_string[INET6_ADDRSTRLEN] = "::";
+	uint8_t prefix_bytes[16] = {};
+	uint8_t *addr = prefix_bytes;
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{"preferred-lifetime", required_argument, 0, 'p'},
+			{"valid-lifetime", required_argument, 0, 'v'},
+			{"default", no_argument, 0, 'd'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "ht:p:v:d", long_options,
+				&option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(config_gateway_option_list, argv[0],
+					    config_gateway_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 'd':
+			defaultRoute = TRUE;
+			break;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+
+		case 'p':
+			preferredLifetime = (uint32_t) strtol(optarg, NULL, 0);
+			break;
+
+		case 'v':
+			validLifetime = (uint32_t) strtol(optarg, NULL, 0);
+			break;
+
+		}
+	}
+
+	if (optind < argc) {
+		if (!prefix) {
+			prefix = argv[optind];
+			optind++;
+		}
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+		        "%s: error: Unexpected extra argument: \"%s\"\n",
+		        argv[0], argv[optind]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPANTUND_DBUS_PATH,
+		         gInterfaceName);
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPANTUND_DBUS_APIv1_INTERFACE,
+		    WPANTUND_IF_CMD_CONFIG_GATEWAY
+		    );
+
+		dbus_message_append_args(
+		    message,
+		    DBUS_TYPE_BOOLEAN, &defaultRoute,
+		    DBUS_TYPE_INVALID
+		);
+
+		if(prefix) {
+
+			// So the prefix could either be
+			// specified like an IPv6 address, or
+			// specified as a bunch of hex numbers.
+			// We use the presence of a colon (':')
+			// to differentiate.
+			if(strstr(prefix,":")) {
+
+				// Address-style
+				int bits = inet_pton(AF_INET6,prefix,prefix_bytes);
+				if(bits<0) {
+					fprintf(stderr,
+					        "Bad Prefix \"%s\", errno=%d (%s)\n",
+					        prefix,
+					        errno,
+					        strerror(errno));
+					goto bail;
+				} else if(!bits) {
+					fprintf(stderr, "Bad prefix \"%s\"\n", prefix);
+					goto bail;
+				}
+			} else {
+				// DATA-style
+				int length = parse_string_into_data(prefix_bytes,
+				                                    8,
+				                                    prefix);
+				if(length<=0) {
+					fprintf(stderr, "Bad prefix \"%s\"\n", prefix);
+					goto bail;
+				}
+			}
+
+			inet_ntop(AF_INET6, (const void *)&prefix_bytes, address_string, sizeof(address_string));
+
+			fprintf(stderr, "Using prefix \"%s\"\n", address_string);
+
+		}
+
+		addr = prefix_bytes;
+
+		dbus_message_append_args(
+		    message,
+			DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &addr, 16,
+		    DBUS_TYPE_UINT32, &preferredLifetime,
+		    DBUS_TYPE_UINT32, &validLifetime,
+		    DBUS_TYPE_INVALID
+		);
+
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_get_args(reply, &error,
+		                      DBUS_TYPE_INT32, &ret,
+		                      DBUS_TYPE_INVALID
+		                      );
+
+		if (!ret) {
+			fprintf(stderr, "Gateway configured.\n");
+		} else {
+			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
+			print_error_diagnosis(ret);
+		}
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-config-gateway.h b/src/wpanctl/tool-cmd-config-gateway.h
new file mode 100644
index 0000000..748232a
--- /dev/null
+++ b/src/wpanctl/tool-cmd-config-gateway.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_CONFIG_GATEWAY_H
+#define WPANCTL_TOOL_CMD_CONFIG_GATEWAY_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_config_gateway(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-form.c b/src/wpanctl/tool-cmd-form.c
new file mode 100644
index 0000000..a3bed76
--- /dev/null
+++ b/src/wpanctl/tool-cmd-form.c
@@ -0,0 +1,277 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-form.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v0.h"
+#include "args.h"
+#include "string-utils.h"
+
+#include <arpa/inet.h>
+#include <errno.h>
+
+const char form_cmd_syntax[] = "[args] [network-name]";
+
+static const arg_list_item_t form_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+	{'c', "channel", "channel", "Set the desired channel"},
+	{'T', "type", "node-type: router(r,2), end-device(end,e,3), sleepy-end-device(sleepy,sed,4), nl-lurker(lurker,l,6)",
+		"Join as a specific node type" },
+//	{'u', "ula-prefix", "ULA Prefix", "Specify a specific *LEGACY* ULA prefix"},
+	{'M', "mesh-local-prefix", "Mesh-Local IPv6 Prefix", "Specify a non-default mesh-local IPv6 prefix"},
+	{'L', "legacy-prefix", "Legacy IPv6 Prefix", "Specify a specific *LEGACY* IPv6 prefix"},
+	{0}
+};
+
+int tool_cmd_form(int argc, char* argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
+	DBusConnection* connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+	const char* network_name = NULL;
+	const char* ula_prefix = NULL;
+	uint16_t node_type = WPAN_IFACE_ROLE_ROUTER; // Default to router for form
+	uint32_t channel_mask = 0;
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{"channel", required_argument, 0, 'c'},
+			{"ula-prefix", required_argument, 0, 'u'},
+			{"mesh-local-prefix", required_argument, 0, 'M'},
+			{"legacy-prefix", required_argument, 0, 'L'},
+			{"type", required_argument, 0, 'T'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "hc:t:T:u:", long_options,
+				&option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(form_option_list, argv[0],
+					    form_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+
+		case 'c':
+			channel_mask = (1 << strtol(optarg, NULL, 0));
+			break;
+
+		case 'M':
+			fprintf(stderr,
+					"%s: error: Setting the mesh local address at the command line isn't yet implemented. Set it as a property instead.\n",
+					argv[0]);
+			ret = ERRORCODE_BADARG;
+			goto bail;
+			break;
+
+		case 'L':
+		case 'u':
+			ula_prefix = optarg;
+			break;
+
+		case 'T':
+			node_type = node_type_str2int(optarg);
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		if (!network_name) {
+			network_name = argv[optind];
+			optind++;
+		}
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+			"%s: error: Unexpected extra argument: \"%s\"\n",
+			argv[0], argv[optind]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (!network_name) {
+		fprintf(stderr, "%s: error: Missing network name.\n", argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPAN_TUNNEL_DBUS_PATH,
+		         gInterfaceName);
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPAN_TUNNEL_DBUS_INTERFACE,
+		    WPAN_IFACE_CMD_FORM
+		    );
+
+		dbus_message_append_args(
+		    message,
+		    DBUS_TYPE_STRING, &network_name,
+		    DBUS_TYPE_INT16, &node_type,
+		    DBUS_TYPE_UINT32, &channel_mask,
+		    DBUS_TYPE_INVALID
+		    );
+
+		if(ula_prefix) {
+			uint8_t ula_bytes[16] = {};
+
+			// So the ULA prefix could either be
+			// specified like an IPv6 address, or
+			// specified as a bunch of hex numbers.
+			// We use the presence of a colon (':')
+			// to differentiate.
+			if(strstr(ula_prefix,":")) {
+
+				// Address-style
+				int bits = inet_pton(AF_INET6,ula_prefix,ula_bytes);
+				if(bits<0) {
+					fprintf(stderr,
+					        "Bad ULA \"%s\", errno=%d (%s)\n",
+					        ula_prefix,
+					        errno,
+					        strerror(errno));
+					goto bail;
+				} else if(!bits) {
+					fprintf(stderr, "Bad ULA \"%s\"\n", ula_prefix);
+					goto bail;
+				}
+			} else {
+				// DATA-style
+				int length = parse_string_into_data(ula_bytes,
+				                                    8,
+				                                    ula_prefix);
+				if(length<=0) {
+					fprintf(stderr, "Bad ULA \"%s\"\n", ula_prefix);
+					goto bail;
+				}
+			}
+
+			fprintf(stderr, "Using ULA prefix \"%s\"\n", ula_prefix);
+
+			uint8_t *addr = ula_bytes;
+			dbus_message_append_args(
+			    message,
+			    DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &addr, 8,
+			    DBUS_TYPE_INVALID
+			    );
+		}
+
+		fprintf(stderr,
+		        "Forming WPAN \"%s\" as node type \"%s\"\n",
+		        network_name,
+		        node_type_int2str(node_type));
+
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_get_args(reply, &error,
+		                      DBUS_TYPE_INT32, &ret,
+		                      DBUS_TYPE_INVALID
+		                      );
+
+		if (!ret) {
+			fprintf(stderr, "Successfully formed!\n");
+		} else {
+			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
+			print_error_diagnosis(ret);
+		}
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-form.h b/src/wpanctl/tool-cmd-form.h
new file mode 100644
index 0000000..781f77f
--- /dev/null
+++ b/src/wpanctl/tool-cmd-form.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_FORM_H
+#define WPANCTL_TOOL_CMD_FORM_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_form(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-getprop.c b/src/wpanctl/tool-cmd-getprop.c
new file mode 100644
index 0000000..7cb59df
--- /dev/null
+++ b/src/wpanctl/tool-cmd-getprop.c
@@ -0,0 +1,240 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-getprop.h"
+#include "assert-macros.h"
+#include "args.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v1.h"
+
+const char getprop_cmd_syntax[] = "[args] <property-name>";
+
+static const arg_list_item_t getprop_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+	{'a', "all", NULL, "Print all supported properties"},
+	{'v', "value-only", NULL, "Print only the value of the property"},
+	{0}
+};
+
+int tool_cmd_getprop(int argc, char *argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = 10 * 1000;
+	DBusConnection *connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+	const char *property_name = NULL;
+	bool get_all = false;
+	bool value_only = false;
+
+	dbus_error_init(&error);
+
+	optind = 0;
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{"all", no_argument, 0, 'a'},
+			{"value-only", no_argument, 0, 'v'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "ht:av", long_options,
+				&option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(getprop_option_list, argv[0],
+					    getprop_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+
+		case 'a':
+			get_all = true;
+			break;
+
+		case 'v':
+			value_only = true;
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		property_name = argv[optind];
+	}
+
+	if (optind == argc) {
+		property_name = "";
+		get_all = true;
+	}
+
+	if ((optind < argc) && get_all) {
+		fprintf(stderr,
+		        "%s: error: Can't specify a specific property and request all properties at the same time.\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (optind + 1 < argc) {
+		int cmd_and_flags = optind;
+		int j;
+		for (j = optind; j < argc; j++) {
+			optind = 0;
+			argv[cmd_and_flags] = argv[j];
+			ret = tool_cmd_getprop(cmd_and_flags + 1, argv);
+		}
+		goto bail;
+	}
+
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPANTUND_DBUS_PATH,
+		         gInterfaceName);
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPANTUND_DBUS_APIv1_INTERFACE,
+		    WPANTUND_IF_CMD_PROP_GET
+		    );
+
+		dbus_message_append_args(
+		    message,
+		    DBUS_TYPE_STRING, &property_name,
+		    DBUS_TYPE_INVALID
+		    );
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_iter_init(reply, &iter);
+
+		// Get return code
+		dbus_message_iter_get_basic(&iter, &ret);
+
+		if (ret) {
+			const char* error_cstr = NULL;
+
+			// Try to see if there is an error explanation we can extract
+			dbus_message_iter_next(&iter);
+			if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) {
+				dbus_message_iter_get_basic(&iter, &error_cstr);
+			}
+
+			if(!error_cstr || error_cstr[0] == 0) {
+				error_cstr = (ret<0)?strerror(-ret):"Get failed";
+			}
+
+			fprintf(stderr, "%s: %s (%d)\n", property_name, error_cstr, ret);
+			goto bail;
+		}
+
+		// Move to the property
+		dbus_message_iter_next(&iter);
+
+		if (get_all) {
+			dbus_message_iter_recurse(&iter, &list_iter);
+
+			for (;
+			     dbus_message_iter_get_arg_type(&list_iter) == DBUS_TYPE_STRING;
+			     dbus_message_iter_next(&list_iter)) {
+				char* args[3] = { argv[0] };
+				dbus_message_iter_get_basic(&list_iter, &args[1]);
+				ret = tool_cmd_getprop(2, args);
+			}
+		} else {
+			if(!value_only && property_name[0])
+				fprintf(stdout, "%s = ", property_name);
+			dump_info_from_iter(stdout, &iter, 0, false, false);
+		}
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-getprop.h b/src/wpanctl/tool-cmd-getprop.h
new file mode 100644
index 0000000..bb94223
--- /dev/null
+++ b/src/wpanctl/tool-cmd-getprop.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_GETPROP_H
+#define WPANCTL_TOOL_CMD_GETPROP_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_getprop(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-host-did-wake.c b/src/wpanctl/tool-cmd-host-did-wake.c
new file mode 100644
index 0000000..27ea87b
--- /dev/null
+++ b/src/wpanctl/tool-cmd-host-did-wake.c
@@ -0,0 +1,166 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-host-did-wake.h"
+#include "assert-macros.h"
+#include "args.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v1.h"
+
+const char host_did_wake_cmd_syntax[] = "[args]";
+
+static const arg_list_item_t host_did_wake_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+	{0}
+};
+
+int tool_cmd_host_did_wake(int argc, char* argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = 10 * 1000;
+	DBusConnection* connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "ht:", long_options, &option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(host_did_wake_option_list, argv[0],
+					    host_did_wake_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+		        "%s: error: Unexpected extra argument: \"%s\"\n",
+			argv[0], argv[optind]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPANTUND_DBUS_PATH,
+		         gInterfaceName);
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPANTUND_DBUS_APIv1_INTERFACE,
+		    WPANTUND_IF_CMD_HOST_DID_WAKE
+		    );
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_get_args(reply, &error,
+		                      DBUS_TYPE_INT32, &ret,
+		                      DBUS_TYPE_INVALID
+		                      );
+		if (ret == 6)
+			ret = 0;
+
+		if (ret) {
+			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
+			print_error_diagnosis(ret);
+		}
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-host-did-wake.h b/src/wpanctl/tool-cmd-host-did-wake.h
new file mode 100644
index 0000000..f11e848
--- /dev/null
+++ b/src/wpanctl/tool-cmd-host-did-wake.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_HOST_DID_WAKE_H
+#define WPANCTL_TOOL_CMD_HOST_DID_WAKE_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_host_did_wake(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-join.c b/src/wpanctl/tool-cmd-join.c
new file mode 100644
index 0000000..a5d6d42
--- /dev/null
+++ b/src/wpanctl/tool-cmd-join.c
@@ -0,0 +1,269 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-join.h"
+#include "tool-cmd-scan.h"
+#include "assert-macros.h"
+#include "args.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v0.h"
+
+#include <errno.h>
+
+const char join_cmd_syntax[] = "[args] [network-name]";
+
+static const arg_list_item_t join_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+	{'T', "type", "node-type: router(r,2), end-device(end,e,3), sleepy-end-device(sleepy,sed,4), nl-lurker(lurker,l,6)",
+		"Join as a specific node type"},
+	{'p', "panid", "panid", "Specify a specific PAN ID"},
+	{'x', "xpanid", "xpanid", "Specify a specific Extended PAN ID"},
+	{'c', "channel", "channel", "Specify a specific channel"},
+	{0}
+};
+
+int tool_cmd_join(int argc, char* argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
+	DBusConnection* connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+	uint16_t node_type = WPAN_IFACE_ROLE_END_DEVICE;
+	struct wpan_network_info_s target_network = {};
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{"type", required_argument, 0, 'T'},
+			{"panid", required_argument, 0, 'p'},
+			{"xpanid", required_argument, 0, 'x'},
+			{"channel", required_argument, 0, 'c'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "hc:t:T:x:p:", long_options,
+				&option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(join_option_list, argv[0],
+					    join_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+
+		case 'p':
+			target_network.pan_id = strtol(optarg, NULL, 16);
+			break;
+
+		case 'c':
+			target_network.channel = strtol(optarg, NULL, 0);
+			break;
+
+		case 'x':
+			target_network.xpanid = strtoull(optarg, NULL, 16);
+			break;
+
+		case 'T':
+			node_type = node_type_str2int(optarg);
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		if (!target_network.network_name[0]) {
+			int index;
+			if (1 == sscanf(argv[optind], "%d",
+					&index) && index
+			    && (index <= gScannedNetworkCount)) {
+				target_network = gScannedNetworks[index - 1];
+			} else {
+				strncpy(target_network.network_name,
+					argv[optind], 16);
+				target_network.network_name[16] = 0;
+			}
+			optind++;
+		}
+	}
+
+	if (optind < argc) {
+		if (!target_network.xpanid) {
+			target_network.xpanid = strtoull(argv[optind], NULL, 16);
+			optind++;
+		}
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+			"%s: error: Unexpected extra argument: \"%s\"\n",
+			argv[0], argv[optind]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (!target_network.network_name[0]) {
+		fprintf(stderr, "%s: error: Missing network name.\n", argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPAN_TUNNEL_DBUS_PATH,
+		         gInterfaceName);
+		char* network_name = target_network.network_name;
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPAN_TUNNEL_DBUS_INTERFACE,
+		    WPAN_IFACE_CMD_JOIN
+		    );
+
+		fprintf(stderr,
+		        "Joining \"%s\" %016llX as node type \"%s\"\n",
+		        target_network.network_name,
+		        (unsigned long long)target_network.xpanid,
+		        node_type_int2str(node_type));
+
+		dbus_message_append_args(
+		    message,
+		    DBUS_TYPE_STRING, &network_name,
+		    DBUS_TYPE_INVALID
+		    );
+
+		dbus_message_append_args(
+		    message,
+		    DBUS_TYPE_INT16, &node_type,
+		    DBUS_TYPE_INVALID
+		    );
+
+		dbus_message_append_args(
+		    message,
+		    DBUS_TYPE_UINT64, &target_network.xpanid,
+		    DBUS_TYPE_INVALID
+		    );
+
+		dbus_message_append_args(
+		    message,
+		    DBUS_TYPE_UINT16, &target_network.pan_id,
+		    DBUS_TYPE_INVALID
+		    );
+
+		dbus_message_append_args(
+		    message,
+		    DBUS_TYPE_BYTE, &target_network.channel,
+		    DBUS_TYPE_INVALID
+		    );
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_get_args(reply, &error,
+		                      DBUS_TYPE_INT32, &ret,
+		                      DBUS_TYPE_INVALID
+		                      );
+
+		if (!ret) {
+			fprintf(stderr, "Successfully Joined!\n");
+		} else if ((ret == -EINPROGRESS) || (ret == kWPANTUNDStatus_InProgress)) {
+			fprintf(stderr,
+			        "Partial (insecure) join. Credentials needed. Update key to continue.\n");
+			ret = 0;
+		} else {
+			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
+
+			print_error_diagnosis(ret);
+		}
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-join.h b/src/wpanctl/tool-cmd-join.h
new file mode 100644
index 0000000..4cbff53
--- /dev/null
+++ b/src/wpanctl/tool-cmd-join.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_JOIN_H
+#define WPANCTL_TOOL_CMD_JOIN_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_join(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-leave.c b/src/wpanctl/tool-cmd-leave.c
new file mode 100644
index 0000000..fa1be89
--- /dev/null
+++ b/src/wpanctl/tool-cmd-leave.c
@@ -0,0 +1,165 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-leave.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v1.h"
+#include "args.h"
+
+const char leave_cmd_syntax[] = "[args]";
+
+static const arg_list_item_t leave_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+	{0}
+};
+
+int tool_cmd_leave(int argc, char* argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = 10 * 1000;
+	DBusConnection* connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "ht:", long_options, &option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(leave_option_list, argv[0],
+					    leave_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+		        "%s: error: Unexpected extra argument: \"%s\"\n",
+			argv[0], argv[optind]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPANTUND_DBUS_PATH,
+		         gInterfaceName);
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPANTUND_DBUS_APIv1_INTERFACE,
+		    WPANTUND_IF_CMD_LEAVE
+		    );
+
+		fprintf(stderr, "Leaving current WPAN. . .\n");
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_get_args(reply, &error,
+		                      DBUS_TYPE_INT32, &ret,
+		                      DBUS_TYPE_INVALID
+		                      );
+
+		if (ret) {
+			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
+			print_error_diagnosis(ret);
+		}
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-leave.h b/src/wpanctl/tool-cmd-leave.h
new file mode 100644
index 0000000..d113169
--- /dev/null
+++ b/src/wpanctl/tool-cmd-leave.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_LEAVE_H
+#define WPANCTL_TOOL_CMD_LEAVE_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_leave(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-list.c b/src/wpanctl/tool-cmd-list.c
new file mode 100644
index 0000000..7f6a0e0
--- /dev/null
+++ b/src/wpanctl/tool-cmd-list.c
@@ -0,0 +1,164 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-list.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v0.h"
+#include "args.h"
+
+const char list_cmd_syntax[] = "[args] <duration>]";
+
+static const arg_list_item_t list_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+	{0}
+};
+
+int tool_cmd_list(int argc, char* argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
+	DBusConnection* connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "ht:", long_options, &option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(list_option_list, argv[0],
+					    list_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+		        "%s: error: Unexpected extra argument: \"%s\"\n",
+			argv[0], argv[optind]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+
+		message = dbus_message_new_method_call(
+		    WPAN_TUNNEL_DBUS_NAME,
+		    WPAN_TUNNEL_DBUS_PATH,
+		    WPAN_TUNNEL_DBUS_INTERFACE,
+		    WPAN_TUNNEL_CMD_GET_INTERFACES
+		    );
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_iter_init(reply, &iter);
+
+		if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
+			fprintf(stderr,
+			        "%s: error: Bad type for interface list (%c)\n",
+			        argv[0],
+			        dbus_message_iter_get_element_type(&iter));
+			ret = ERRORCODE_UNKNOWN;
+			goto bail;
+		}
+
+		dbus_message_iter_recurse(&iter, &list_iter);
+
+		for (;
+		     dbus_message_iter_get_arg_type(&list_iter) == DBUS_TYPE_ARRAY;
+		     dbus_message_iter_next(&list_iter)
+		) {
+			DBusMessageIter item_iter;
+			char *interface_name;
+			char *dbus_name;
+
+			dbus_message_iter_recurse(&list_iter, &item_iter);
+
+			dbus_message_iter_get_basic(&item_iter, &interface_name);
+			dbus_message_iter_next(&item_iter);
+			dbus_message_iter_get_basic(&item_iter, &dbus_name);
+
+			printf("%s (%s)\n", interface_name, dbus_name);
+		}
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-list.h b/src/wpanctl/tool-cmd-list.h
new file mode 100644
index 0000000..9e414c5
--- /dev/null
+++ b/src/wpanctl/tool-cmd-list.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_LIST_H
+#define WPANCTL_TOOL_CMD_LIST_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_list(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-mfg.c b/src/wpanctl/tool-cmd-mfg.c
new file mode 100644
index 0000000..c0cc04c
--- /dev/null
+++ b/src/wpanctl/tool-cmd-mfg.c
@@ -0,0 +1,133 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-status.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v1.h"
+#include "args.h"
+
+int tool_cmd_mfg(int argc, char *argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = 10 * 1000;
+        char output[100];
+	DBusConnection *connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	const char* result_cstr = NULL;
+	DBusError error;
+
+	dbus_error_init(&error);
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(error.name == NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPANTUND_DBUS_PATH,
+		         gInterfaceName);
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPANTUND_DBUS_NLAPIv1_INTERFACE,
+		    WPANTUND_IF_CMD_MFG
+		);
+
+		char string[100];
+		if (argc == 1)
+			sprintf(string, "%s", argv[0]);
+		if (argc == 2)
+			sprintf(string, "%s %s", argv[0], argv[1]);
+		if (argc == 3)
+			sprintf(string, "%s %s %s", argv[0], argv[1], argv[2]);
+		if (argc == 4)
+			sprintf(string, "%s %s %s %s", argv[0], argv[1], argv[2], argv[3]);
+		char *cmd = string;
+		dbus_message_append_args(
+		    message,
+		    DBUS_TYPE_STRING, &cmd,
+		    DBUS_TYPE_INVALID
+		    );
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_iter_init(reply, &iter);
+
+		dbus_message_iter_get_basic(&iter, &ret);
+
+		dbus_message_iter_next(&iter);
+
+		if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) {
+			dbus_message_iter_get_basic(&iter, &result_cstr);
+			printf("%s", result_cstr);
+		} else {
+			dump_info_from_iter(stdout, &iter, 0, false, false);
+		}
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-mfg.h b/src/wpanctl/tool-cmd-mfg.h
new file mode 100644
index 0000000..8eb6b8a
--- /dev/null
+++ b/src/wpanctl/tool-cmd-mfg.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_MFG_H
+#define WPANCTL_TOOL_CMD_MFG_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_mfg(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-pcap.c b/src/wpanctl/tool-cmd-pcap.c
new file mode 100644
index 0000000..da1bdbf
--- /dev/null
+++ b/src/wpanctl/tool-cmd-pcap.c
@@ -0,0 +1,337 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <getopt.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "wpanctl-utils.h"
+#include "tool-cmd-pcap.h"
+#include "assert-macros.h"
+#include "args.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v1.h"
+
+const char pcap_cmd_syntax[] = "[args] <capture-file>";
+
+static const arg_list_item_t pcap_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+	{'f', NULL, NULL, "Allow packet capture to controlling TTY"},
+	{0}
+};
+
+
+static int
+do_pcap_to_fd(int fd, int timeout, DBusError *error)
+{
+	int ret = ERRORCODE_UNKNOWN;
+	DBusConnection *connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+	char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, error);
+
+	if (connection == NULL) {
+		if (error != NULL) {
+			dbus_error_free(error);
+			dbus_error_init(error);
+		}
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, error);
+	}
+
+	require(connection != NULL, bail);
+
+	ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+
+	require_noerr(ret, bail);
+
+	snprintf(
+		path,
+		sizeof(path),
+		"%s/%s",
+		WPANTUND_DBUS_PATH,
+		gInterfaceName
+	);
+
+	message = dbus_message_new_method_call(
+		interface_dbus_name,
+		path,
+		WPANTUND_DBUS_APIv1_INTERFACE,
+		WPANTUND_IF_CMD_PCAP_TO_FD
+	);
+
+	dbus_message_append_args(
+		message,
+		DBUS_TYPE_UNIX_FD, &fd,
+		DBUS_TYPE_INVALID
+	);
+
+	ret = ERRORCODE_TIMEOUT;
+
+	reply = dbus_connection_send_with_reply_and_block(
+		connection,
+		message,
+		timeout,
+		error
+	);
+
+	require(reply != NULL, bail);
+
+	dbus_message_get_args(
+		reply,
+		error,
+		DBUS_TYPE_INT32, &ret,
+		DBUS_TYPE_INVALID
+	);
+
+bail:
+
+	if (connection) {
+		dbus_connection_unref(connection);
+	}
+
+	if (message) {
+		dbus_message_unref(message);
+	}
+
+	if (reply) {
+		dbus_message_unref(reply);
+	}
+
+	return ret;
+}
+
+//! Checks to see if the given FD is the controlling TTY.
+bool
+is_descriptor_ctty(int fd)
+{
+	bool ret = false;
+
+	if (isatty(fd)) {
+		char tty_name_copy[L_ctermid] = "";
+		const char *tty_name = ttyname(fd);
+
+		if (tty_name == NULL) {
+			goto bail;
+		}
+
+		// Just use snprintf as a safe string copy.
+		// It is more portable than strlcpy and we don't care about
+		// performance in this context.
+		snprintf(tty_name_copy, sizeof(tty_name_copy), "%s", tty_name);
+
+		if (NULL == (tty_name = ttyname(STDIN_FILENO))) {
+			goto bail;
+		}
+
+		ret = (0 == strcmp(tty_name_copy, tty_name));
+	}
+
+bail:
+	return ret;
+}
+
+int
+tool_cmd_pcap(int argc, char *argv[])
+{
+	static const int set = 1;
+	int ret = 0;
+	int timeout = 10 * 1000;
+
+	int fd_out = -1;
+	int fd_pair[2] = { -1, -1 };
+	bool force_ctty = false;
+	bool stdout_was_closed = false;
+
+	DBusError error;
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		int c;
+
+		c = getopt_long(argc, argv, "fht:", long_options, &option_index);
+
+		if (c == -1) {
+			break;
+		}
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(pcap_option_list, argv[0],
+					    pcap_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 'f':
+			force_ctty = true;
+			break;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+		}
+	}
+
+	// We use a socket pair for the socket we hand to wpantund,
+	// so that the termination of this process will stop packet
+	// capture.
+	if (socketpair(PF_UNIX, SOCK_DGRAM, 0, fd_pair) < 0) {
+		perror("socketpair");
+		ret = ERRORCODE_UNKNOWN;
+		goto bail;
+	}
+
+	if (optind < argc) {
+		// Capture packets to a file path
+
+		fd_out = open(argv[optind], O_WRONLY|O_CREAT|O_TRUNC, 0666);
+
+		optind++;
+
+	} else {
+		// Capture packets to stdout
+
+		if (!force_ctty && is_descriptor_ctty(STDOUT_FILENO)) {
+			fprintf(stderr, "%s: error: Cowardly refusing write binary data to controlling tty, use -f to override\n", argv[0]);
+			ret = ERRORCODE_REFUSED;
+			goto bail;
+		}
+
+		// Update fd_out, close the original stdout.
+		fd_out = dup(STDOUT_FILENO);
+		close(STDOUT_FILENO);
+		stdout_was_closed = true;
+	}
+
+	if (optind < argc) {
+		fprintf(
+			stderr,
+		    "%s: error: Unexpected extra argument: \"%s\"\n",
+			argv[0],
+			argv[optind]
+		);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (fd_out < 0) {
+		fprintf(
+			stderr,
+			"%s: error: Unable to open file for pcap: \"%s\"\n",
+			argv[0],
+			strerror(errno)
+		);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(
+			stderr,
+		    "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		    argv[0]
+		);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	// Have wpantund start writing PCAP data to one end of our socket pair.
+	ret = do_pcap_to_fd(fd_pair[1], timeout, &error);
+
+	if (ret) {
+		if (error.message != NULL) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+		}
+		goto bail;
+	}
+
+	// Close this side of the socket pair so that we can
+	// detect if wpantund closed the socket.
+	close(fd_pair[1]);
+
+#ifdef SO_NOSIGPIPE
+	// Turn off sigpipe so we can gracefully exit.
+	setsockopt(fd_pair[0], SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
+	setsockopt(fd_out, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
+#endif
+
+	fprintf(stderr, "%s: Capture started\n", argv[0]);
+
+	// Data pump
+	while (true) {
+		char buffer[2048];
+		ssize_t buffer_len;
+
+		// Read in from datagram socket
+		buffer_len = read(fd_pair[0], buffer, sizeof(buffer));
+
+		if (buffer_len <= 0) {
+			break;
+		}
+
+		// Write out the buffer to our file descriptor
+		buffer_len = write(fd_out, buffer, buffer_len);
+		if (buffer_len <= 0) {
+			break;
+		}
+	}
+
+	fprintf(stderr, "%s: Capture terminated\n", argv[0]);
+
+bail:
+
+	if (ret) {
+		fprintf(stderr, "pcap: failed with error %d. %s\n", ret, wpantund_status_to_cstr(ret));
+		print_error_diagnosis(ret);
+	}
+
+	// Clean up.
+
+	close(fd_out);
+
+	close(fd_pair[0]);
+
+	close(fd_pair[1]);
+
+	dbus_error_free(&error);
+
+	if (stdout_was_closed) {
+		exit (ret);
+	}
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-pcap.h b/src/wpanctl/tool-cmd-pcap.h
new file mode 100644
index 0000000..5c26df6
--- /dev/null
+++ b/src/wpanctl/tool-cmd-pcap.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_PCAP_H
+#define WPANCTL_TOOL_CMD_PCAP_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_pcap(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-permit-join.c b/src/wpanctl/tool-cmd-permit-join.c
new file mode 100644
index 0000000..d7dcbb3
--- /dev/null
+++ b/src/wpanctl/tool-cmd-permit-join.c
@@ -0,0 +1,225 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-permit-join.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v0.h"
+#include "args.h"
+
+const char permit_join_cmd_syntax[] = "[args] <duration> [commissioning-port]";
+
+static const arg_list_item_t permit_join_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+	{'n', "network-wide", NULL, "Permit joining network-wide"},
+	{'c', "tcp", NULL, "Permit only TCP for commissioning traffic"},
+	{'d', "udp", NULL, "Permit only UDP for commissioning traffic"},
+	{0}
+};
+
+int tool_cmd_permit_join(int argc, char* argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
+	DBusConnection* connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+	int32_t period = -1;
+	dbus_bool_t network_wide = FALSE;
+	uint16_t commissioning_traffic_port = 0;
+	uint8_t commissioning_traffic_type = 0xFF;
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{"network-wide", no_argument, 0, 'n'},
+			{"tcp", no_argument, 0, 'c'},
+			{"udp", no_argument, 0, 'd'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "ht:ncd", long_options,
+				&option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(permit_join_option_list,
+					    argv[0], permit_join_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+
+		case 'n':
+			network_wide = TRUE;
+			break;
+
+		case 'c':
+			commissioning_traffic_type = 6;
+			break;
+
+		case 'd':
+			commissioning_traffic_type = 17;
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		if (period == -1) {
+			period = strtol(argv[optind], NULL, 0);
+			optind++;
+		}
+	}
+
+	if (optind < argc) {
+		if (!commissioning_traffic_port) {
+			commissioning_traffic_port =
+			    strtol(argv[optind], NULL, 0);
+			optind++;
+		}
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+			"%s: error: Unexpected extra argument: \"%s\"\n",
+			argv[0], argv[optind]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (period == -1)
+		period = 240;
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+			"%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+			argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPAN_TUNNEL_DBUS_PATH,
+		         gInterfaceName);
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPAN_TUNNEL_DBUS_INTERFACE,
+		    WPAN_IFACE_CMD_PERMIT_JOIN
+		    );
+
+		dbus_message_append_args(
+		    message,
+		    DBUS_TYPE_INT32, &period,
+		    DBUS_TYPE_BOOLEAN, &network_wide,
+		    DBUS_TYPE_UINT16, &commissioning_traffic_port,
+		    DBUS_TYPE_BYTE, &commissioning_traffic_type,
+		    DBUS_TYPE_INVALID
+		    );
+
+		if (commissioning_traffic_port)
+			fprintf(stderr,
+			        "Permitting Joining on the current WPAN for %d seconds, commissioning traffic on %s port %d. . .\n",
+			        period,
+			        (commissioning_traffic_type ==
+			         6) ? "TCP" : (commissioning_traffic_type == 17) ? "UDP" : "TCP/UDP",
+			        commissioning_traffic_port);
+		else
+			fprintf(stderr,
+			        "Permitting Joining on the current WPAN for %d seconds. . .\n",
+			        period);
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_get_args(reply, &error,
+		                      DBUS_TYPE_INT32, &ret,
+		                      DBUS_TYPE_INVALID
+		                      );
+
+		if (ret) {
+			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
+			print_error_diagnosis(ret);
+		}
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-permit-join.h b/src/wpanctl/tool-cmd-permit-join.h
new file mode 100644
index 0000000..a95f7b2
--- /dev/null
+++ b/src/wpanctl/tool-cmd-permit-join.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_PERMIT_JOIN_H
+#define WPANCTL_TOOL_CMD_PERMIT_JOIN_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_permit_join(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-poll.c b/src/wpanctl/tool-cmd-poll.c
new file mode 100644
index 0000000..389ff04
--- /dev/null
+++ b/src/wpanctl/tool-cmd-poll.c
@@ -0,0 +1,168 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-poll.h"
+#include "assert-macros.h"
+#include "args.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v1.h"
+
+const char poll_cmd_syntax[] = "[args]";
+
+static const arg_list_item_t poll_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+	{0}
+};
+
+int tool_cmd_poll(int argc, char *argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = 10 * 1000;
+	DBusConnection *connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "ht:", long_options, &option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(poll_option_list, argv[0],
+					    poll_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+		        "%s: error: Unexpected extra argument: \"%s\"\n",
+			argv[0], argv[optind]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPANTUND_DBUS_PATH,
+		         gInterfaceName);
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPANTUND_DBUS_APIv1_INTERFACE,
+		    WPANTUND_IF_CMD_DATA_POLL
+		    );
+
+		fprintf(stderr, "Polling parent node for IP traffic. . .\n");
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_get_args(reply, &error,
+		                      DBUS_TYPE_INT32, &ret,
+		                      DBUS_TYPE_INVALID
+		                      );
+		if (ret == 6)
+			ret = 0;
+
+		if (ret) {
+			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
+			print_error_diagnosis(ret);
+		}
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-poll.h b/src/wpanctl/tool-cmd-poll.h
new file mode 100644
index 0000000..681f585
--- /dev/null
+++ b/src/wpanctl/tool-cmd-poll.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_POLL_H
+#define WPANCTL_TOOL_CMD_POLL_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_poll(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-remove-route.c b/src/wpanctl/tool-cmd-remove-route.c
new file mode 100644
index 0000000..aac30a8
--- /dev/null
+++ b/src/wpanctl/tool-cmd-remove-route.c
@@ -0,0 +1,248 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file implements the "remove-route" command in wpanctl
+ *
+ */
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-remove-route.h"
+#include "assert-macros.h"
+#include "args.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v1.h"
+#include "string-utils.h"
+
+#include <arpa/inet.h>
+#include <errno.h>
+
+const char remove_route_cmd_syntax[] = "[args] <prefix>";
+
+static const arg_list_item_t remove_route_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'l', "length", "in bytes", "Specifies the route prefix length (default is 8)"},
+	{'d', "domain", NULL, "Domain id for the route (default is zero)"},
+	{0}
+};
+
+int tool_cmd_remove_route(int argc, char* argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
+
+	DBusConnection* connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+
+	const char *route_prefix = NULL;
+	int prefix_len = 8;
+	uint16_t domain_id = 0;
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"length", required_argument, 0, 'l'},
+			{"domain", required_argument, 0, 'd'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "hl:d:", long_options,
+				&option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(remove_route_option_list, argv[0],
+					    remove_route_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 'l' :
+			prefix_len = (int) strtol(optarg, NULL, 0);
+			break;
+
+		case 'd':
+			domain_id = (uint16_t) strtol(optarg, NULL, 0);
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		route_prefix = argv[optind];
+		optind++;
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+		        "%s: error: Unexpected extra argument: \"%s\"\n",
+		        argv[0], argv[optind]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPANTUND_DBUS_PATH,
+		         gInterfaceName);
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPANTUND_DBUS_APIv1_INTERFACE,
+		    WPANTUND_IF_CMD_ROUTE_REMOVE
+		);
+
+		if ((route_prefix != NULL) && (0 <= prefix_len) && (prefix_len <= 16)) {
+			uint8_t prefix_bytes[16];
+
+			memset(prefix_bytes, 0, sizeof(prefix_bytes));
+
+			// So the prefix could either be
+			// specified like an IPv6 address, or
+			// specified as a bunch of hex numbers.
+			// We use the presence of a colon (':')
+			// to differentiate.
+			if (strstr(route_prefix, ":")) {
+
+				// Address-style
+				int bits = inet_pton(AF_INET6, route_prefix, prefix_bytes);
+				if (bits < 0) {
+					fprintf(stderr,
+					        "Bad prefix \"%s\", errno=%d (%s)\n",
+					        route_prefix,
+					        errno,
+					        strerror(errno));
+					goto bail;
+				} else if (bits == 0) {
+					fprintf(stderr, "Bad prefix \"%s\"\n", route_prefix);
+					goto bail;
+				}
+			} else {
+				// DATA-style
+				int length = parse_string_into_data(prefix_bytes,
+				                                    16,
+				                                    route_prefix);
+				if(length<=0) {
+					fprintf(stderr, "Bad prefix \"%s\"\n", route_prefix);
+					goto bail;
+				}
+			}
+
+			fprintf(stderr, "Removing route prefix \"%s\" with len %d, domain-id %d.\n",
+				route_prefix, prefix_len, domain_id
+			);
+
+			uint8_t *addr = prefix_bytes;
+			uint8_t len = (uint8_t)prefix_len;
+
+			dbus_message_append_args(
+			    message,
+			    DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &addr, len,
+			    DBUS_TYPE_INVALID
+			);
+		} else {
+			dbus_message_append_args(
+			    message,
+			    DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, "", 0,
+			    DBUS_TYPE_INVALID
+			);
+		}
+
+		dbus_message_append_args(
+		    message,
+		    DBUS_TYPE_UINT16, &domain_id,
+		    DBUS_TYPE_INVALID
+		);
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		);
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_get_args(reply, &error,
+		                      DBUS_TYPE_INT32, &ret,
+		                      DBUS_TYPE_INVALID
+		                      );
+
+		if (!ret) {
+			fprintf(stderr, "Route prefix removed.\n");
+		} else {
+			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
+			print_error_diagnosis(ret);
+		}
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-remove-route.h b/src/wpanctl/tool-cmd-remove-route.h
new file mode 100644
index 0000000..ec10115
--- /dev/null
+++ b/src/wpanctl/tool-cmd-remove-route.h
@@ -0,0 +1,31 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file declares the methods for "remove-route" command
+ *      in wpanctl.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_REMOVE_ROUTE_H
+#define WPANCTL_TOOL_CMD_REMOVE_ROUTE_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_remove_route(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-reset.c b/src/wpanctl/tool-cmd-reset.c
new file mode 100644
index 0000000..8406b00
--- /dev/null
+++ b/src/wpanctl/tool-cmd-reset.c
@@ -0,0 +1,164 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-scan.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v1.h"
+#include "args.h"
+
+const char reset_cmd_syntax[] = "[args]";
+
+static const arg_list_item_t reset_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+	{0}
+};
+
+int tool_cmd_reset(int argc, char *argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = 10 * 1000;
+	DBusConnection* connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "ht:", long_options, &option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(reset_option_list, argv[0],
+					    reset_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+		        "%s: error: Unexpected extra argument: \"%s\"\n",
+			argv[0], argv[optind]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			print_error_diagnosis(ret);
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPANTUND_DBUS_PATH,
+		         gInterfaceName);
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPANTUND_DBUS_APIv1_INTERFACE,
+		    WPANTUND_IF_CMD_RESET
+		    );
+
+		fprintf(stderr, "Resetting NCP. . .\n");
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_get_args(reply, &error,
+		                      DBUS_TYPE_INT32, &ret,
+		                      DBUS_TYPE_INVALID
+		                      );
+
+		if (ret == 6)
+			ret = 0;
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-reset.h b/src/wpanctl/tool-cmd-reset.h
new file mode 100644
index 0000000..7283b28
--- /dev/null
+++ b/src/wpanctl/tool-cmd-reset.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_RESET_H
+#define WPANCTL_TOOL_CMD_RESET_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_reset(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-resume.c b/src/wpanctl/tool-cmd-resume.c
new file mode 100644
index 0000000..db4972b
--- /dev/null
+++ b/src/wpanctl/tool-cmd-resume.c
@@ -0,0 +1,165 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-resume.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v1.h"
+#include "args.h"
+
+const char resume_cmd_syntax[] = "[args]";
+
+static const arg_list_item_t resume_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+	{0}
+};
+
+int tool_cmd_resume(int argc, char *argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = 10 * 1000;
+	DBusConnection *connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "ht:", long_options, &option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(resume_option_list, argv[0],
+					    resume_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+		        "%s: error: Unexpected extra argument: \"%s\"\n",
+			argv[0], argv[optind]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			print_error_diagnosis(ret);
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPANTUND_DBUS_PATH,
+		         gInterfaceName);
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPANTUND_DBUS_APIv1_INTERFACE,
+		    WPANTUND_IF_CMD_ATTACH
+		    );
+
+		fprintf(stderr, "Resuming saved WPAN. . .\n");
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_get_args(reply, &error,
+		                      DBUS_TYPE_INT32, &ret,
+		                      DBUS_TYPE_INVALID
+		                      );
+		if (ret) {
+			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
+			print_error_diagnosis(ret);
+		}
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-resume.h b/src/wpanctl/tool-cmd-resume.h
new file mode 100644
index 0000000..991d277
--- /dev/null
+++ b/src/wpanctl/tool-cmd-resume.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_RESUME_H
+#define WPANCTL_TOOL_CMD_RESUME_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_resume(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-scan.c b/src/wpanctl/tool-cmd-scan.c
new file mode 100644
index 0000000..962b0e8
--- /dev/null
+++ b/src/wpanctl/tool-cmd-scan.c
@@ -0,0 +1,367 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-scan.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v1.h"
+#include "string-utils.h"
+#include "args.h"
+
+const char scan_cmd_syntax[] = "[args] [seconds-to-scan]";
+
+static const arg_list_item_t scan_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+	{'c', "channel", "channel", "Set the desired channel"},
+	{'e', "energy", NULL, "Perform an energy scan"},
+	{0}
+};
+
+int gScannedNetworkCount = 0;
+struct wpan_network_info_s gScannedNetworks[SCANNED_NET_BUFFER_SIZE];
+
+static bool sEnergyScan;
+
+static void
+print_scan_header(void)
+{
+	if (sEnergyScan) {
+		printf("    Ch | RSSI\n");
+		printf("   ----+-------\n");
+
+		return;
+	}
+
+	printf(
+		"   | Joinable | NetworkName        | PAN ID | Ch | XPanID           | HWAddr           | RSSI\n");
+	printf(
+		"---+----------+--------------------+--------+----+------------------+------------------+------\n");
+
+}
+
+static DBusHandlerResult
+dbus_beacon_handler(
+    DBusConnection *connection,
+    DBusMessage *   message,
+    void *          user_data
+) {
+	DBusMessageIter iter;
+	int ret;
+	struct wpan_network_info_s network_info;
+
+	if (!dbus_message_is_signal(message, WPANTUND_DBUS_APIv1_INTERFACE, WPANTUND_IF_SIGNAL_NET_SCAN_BEACON)) {
+		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	}
+
+	dbus_message_iter_init(message, &iter);
+
+	ret = parse_network_info_from_iter(&network_info, &iter);
+
+	require_noerr(ret, bail);
+
+	if (network_info.network_name[0]) {
+		if (gScannedNetworkCount < SCANNED_NET_BUFFER_SIZE) {
+			gScannedNetworks[gScannedNetworkCount++] = network_info;
+			printf("%2d", gScannedNetworkCount);
+		} else {
+			printf("--");  //This means that we cannot act on the PAN as we do not save the info
+		}
+	} else {
+		printf("  ");
+	}
+
+	printf(" | %s", network_info.allowing_join ? "     YES" : "      NO");
+
+	if (network_info.network_name[0]) {
+		printf(" | \"%s\"%s",
+			   network_info.network_name,
+			   &"                "[strlen(network_info.network_name)]);
+	} else {
+		printf(" | ------ NONE ------");
+	}
+
+	printf(" | 0x%04X", network_info.pan_id);
+	printf(" | %2d", network_info.channel);
+	printf(" | %016llX", (unsigned long long)network_info.xpanid);
+	printf(" | %02X%02X%02X%02X%02X%02X%02X%02X",
+		   network_info.hwaddr[0],
+		   network_info.hwaddr[1],
+		   network_info.hwaddr[2],
+		   network_info.hwaddr[3],
+		   network_info.hwaddr[4],
+		   network_info.hwaddr[5],
+		   network_info.hwaddr[6],
+		   network_info.hwaddr[7]);
+	printf(" | %4d", network_info.rssi);
+	printf("\n");
+
+bail:
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+dbus_energy_scan_handler(
+    DBusConnection *connection,
+    DBusMessage *   message,
+    void *          user_data
+) {
+	DBusMessageIter iter;
+	int ret;
+	int16_t channel;
+	int8_t maxRssi;
+
+	if (!dbus_message_is_signal(message, WPANTUND_DBUS_APIv1_INTERFACE, WPANTUND_IF_SIGNAL_ENERGY_SCAN_RESULT)) {
+		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+	}
+
+	dbus_message_iter_init(message, &iter);
+
+	ret = parse_energy_scan_result_from_iter(&channel, &maxRssi, &iter);
+
+	require_noerr(ret, bail);
+
+	printf("  %4d | %4d\n", channel, maxRssi);
+
+bail:
+	return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+dbus_signal_handler(
+    DBusConnection *connection,
+    DBusMessage *   message,
+    void *          user_data
+) {
+	if (sEnergyScan) {
+		return dbus_energy_scan_handler(connection, message, user_data);
+	}
+
+	return dbus_beacon_handler(connection, message, user_data);
+}
+
+static const char gDBusObjectManagerMatchString[] =
+	"type='signal'"
+//	",interface='" WPANTUND_DBUS_APIv1_INTERFACE "'"
+	;
+
+
+int tool_cmd_scan(int argc, char *argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
+	DBusConnection* connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusPendingCall *pending = NULL;
+	DBusError error;
+	int32_t scan_period = 0;
+	uint32_t channel_mask = 0;
+
+	dbus_error_init(&error);
+
+	sEnergyScan = false;
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{"channel", required_argument, 0, 'c'},
+			{"energy", no_argument, 0, 'e'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "hc:t:e", long_options,
+				&option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(scan_option_list, argv[0],
+					    scan_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+
+		case 'c':
+			channel_mask = strtomask_uint32(optarg);
+			break;
+
+		case 'e':
+			sEnergyScan = true;
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		if (scan_period == 0) {
+			scan_period = strtol(argv[optind], NULL, 0);
+			optind++;
+		}
+	}
+
+	if (optind < argc) {
+			fprintf(stderr,
+			        "%s: error: Unexpected extra argument: \"%s\"\n",
+			argv[0], argv[optind]);
+			ret = ERRORCODE_BADARG;
+			goto bail;
+		}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	dbus_bus_add_match(connection, gDBusObjectManagerMatchString, &error);
+
+	require_string(error.name == NULL, bail, error.message);
+
+	dbus_connection_add_filter(connection, &dbus_signal_handler, NULL, NULL);
+
+	{
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		DBusMessageIter iter;
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+
+		if (ret != 0) {
+			print_error_diagnosis(ret);
+			goto bail;
+		}
+
+		snprintf(
+			path,
+			sizeof(path),
+			"%s/%s",
+			WPANTUND_DBUS_PATH,
+			gInterfaceName
+		);
+
+		message = dbus_message_new_method_call(
+			interface_dbus_name,
+			path,
+			WPANTUND_DBUS_APIv1_INTERFACE,
+			sEnergyScan? WPANTUND_IF_CMD_ENERGY_SCAN_START : WPANTUND_IF_CMD_NET_SCAN_START
+		);
+
+		dbus_message_append_args(
+			message,
+			DBUS_TYPE_UINT32, &channel_mask,
+			DBUS_TYPE_INVALID
+		);
+
+		print_scan_header();
+
+		if (!sEnergyScan) {
+			gScannedNetworkCount = 0;
+		}
+
+		if(!dbus_connection_send_with_reply(
+		    connection,
+		    message,
+			&pending,
+		    timeout
+	    )) {
+			fprintf(stderr, "%s: error: IPC failure\n", argv[0]);
+			ret = ERRORCODE_UNKNOWN;
+			goto bail;
+		}
+
+		while ((dbus_connection_get_dispatch_status(connection) == DBUS_DISPATCH_DATA_REMAINS)
+			|| dbus_connection_has_messages_to_send(connection)
+			|| !dbus_pending_call_get_completed(pending)
+		) {
+			dbus_connection_read_write_dispatch(connection, 5000 /*ms*/);
+		}
+
+		reply = dbus_pending_call_steal_reply(pending);
+
+		require(reply!=NULL, bail);
+
+
+		dbus_message_iter_init(reply, &iter);
+
+		if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32) {
+			fprintf(stderr, "%s: error: Server returned a bad response ('%c')\n",
+			        argv[0], dbus_message_iter_get_arg_type(&iter));
+			ret = ERRORCODE_UNKNOWN;
+			goto bail;
+		}
+
+		// Get return code
+		dbus_message_iter_get_basic(&iter, &ret);
+
+		if (ret) {
+			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
+			print_error_diagnosis(ret);
+			goto bail;
+		}
+	}
+
+
+bail:
+
+	if (reply) {
+		dbus_message_unref(reply);
+	}
+
+	if (pending != NULL) {
+		dbus_pending_call_unref(pending);
+	}
+
+	if (message) {
+		dbus_message_unref(message);
+	}
+
+	if (connection) {
+		dbus_bus_remove_match(connection, gDBusObjectManagerMatchString, NULL);
+		dbus_connection_remove_filter(connection,&dbus_signal_handler,NULL);
+		dbus_connection_unref(connection);
+	}
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-scan.h b/src/wpanctl/tool-cmd-scan.h
new file mode 100644
index 0000000..0029a66
--- /dev/null
+++ b/src/wpanctl/tool-cmd-scan.h
@@ -0,0 +1,32 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_SCAN_H
+#define WPANCTL_TOOL_CMD_SCAN_H
+
+#define SCANNED_NET_BUFFER_SIZE	250
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_scan(int argc, char* argv[]);
+
+extern int gScannedNetworkCount;
+extern struct wpan_network_info_s gScannedNetworks[];
+
+#endif
diff --git a/src/wpanctl/tool-cmd-setprop.c b/src/wpanctl/tool-cmd-setprop.c
new file mode 100644
index 0000000..b366fa1
--- /dev/null
+++ b/src/wpanctl/tool-cmd-setprop.c
@@ -0,0 +1,242 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-setprop.h"
+#include "assert-macros.h"
+#include "args.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v1.h"
+#include "string-utils.h"
+
+const char setprop_cmd_syntax[] = "[args] <property-name> <property-value>";
+
+static const arg_list_item_t setprop_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+	{'d', "data", NULL, "Value is binary data (in hex)"},
+	{'s', "string", NULL, "Value is a string"},
+	{'v', "value", "property-value", "Useful when the value starts with a '-'"},
+	{0}
+};
+
+int tool_cmd_setprop(int argc, char* argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = 30 * 1000;
+	DBusConnection* connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+	const char* property_name = NULL;
+	char* property_value = NULL;
+
+	enum {
+		kPropertyType_String,
+		kPropertyType_Data,
+	} property_type = kPropertyType_String;
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{"data", no_argument, 0, 'd'},
+			{"string", no_argument, 0, 's'},
+			{"value", required_argument, 0, 'v'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "ht:dsv:", long_options,
+				&option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(setprop_option_list,
+					    argv[0], setprop_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+
+		case 'd':
+			property_type = kPropertyType_Data;
+			break;
+
+		case 's':
+			property_type = kPropertyType_String;
+			break;
+
+		case 'v':
+			property_value = optarg;
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		if (!property_name) {
+			property_name = argv[optind];
+			optind++;
+		}
+	}
+
+	if (optind < argc) {
+		if (!property_value) {
+			property_value = argv[optind];
+			optind++;
+		}
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+			"%s: error: Unexpected extra argument: \"%s\"\n",
+			argv[0], argv[optind]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (!property_name) {
+		fprintf(stderr, "%s: error: Missing property name.\n", argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (!property_value) {
+		fprintf(stderr, "%s: error: Missing property value.\n", argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			print_error_diagnosis(ret);
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPANTUND_DBUS_PATH,
+		         gInterfaceName);
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPANTUND_DBUS_APIv1_INTERFACE,
+		    WPANTUND_IF_CMD_PROP_SET
+		    );
+
+		dbus_message_append_args(
+		    message,
+		    DBUS_TYPE_STRING, &property_name,
+		    DBUS_TYPE_INVALID
+		    );
+
+		if (property_type == kPropertyType_String) {
+			dbus_message_append_args(
+			    message,
+			    DBUS_TYPE_STRING, &property_value,
+			    DBUS_TYPE_INVALID
+			    );
+		} else if (property_type == kPropertyType_Data) {
+			int length = parse_string_into_data((uint8_t*)property_value,
+			                                    strlen(property_value),
+			                                    property_value);
+			dbus_message_append_args(
+			    message,
+			    DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &property_value, length,
+			    DBUS_TYPE_INVALID
+			    );
+		} else {
+			fprintf(stderr, "%s: error: Bad property type\n", argv[0]);
+			ret = ERRORCODE_UNKNOWN;
+			goto bail;
+		}
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_get_args(reply, &error,
+		                      DBUS_TYPE_INT32, &ret,
+		                      DBUS_TYPE_INVALID
+		                      );
+		if (ret)
+			fprintf(stderr, "%s failed with error %d. %s\n", argv[0], ret, wpantund_status_to_cstr(ret));
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-setprop.h b/src/wpanctl/tool-cmd-setprop.h
new file mode 100644
index 0000000..e20322d
--- /dev/null
+++ b/src/wpanctl/tool-cmd-setprop.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_SETPROP_H
+#define WPANCTL_TOOL_CMD_SETPROP_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_setprop(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/tool-cmd-status.c b/src/wpanctl/tool-cmd-status.c
new file mode 100644
index 0000000..0a57d4e
--- /dev/null
+++ b/src/wpanctl/tool-cmd-status.c
@@ -0,0 +1,159 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <getopt.h>
+#include "wpanctl-utils.h"
+#include "tool-cmd-status.h"
+#include "assert-macros.h"
+#include "wpan-dbus-v1.h"
+#include "args.h"
+
+const char status_cmd_syntax[] = "[args]";
+
+static const arg_list_item_t status_option_list[] = {
+	{'h', "help", NULL, "Print Help"},
+	{'t', "timeout", "ms", "Set timeout period"},
+	{0}
+};
+
+int tool_cmd_status(int argc, char *argv[])
+{
+	int ret = 0;
+	int c;
+	int timeout = 10 * 1000;
+	DBusConnection *connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+
+	dbus_error_init(&error);
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"timeout", required_argument, 0, 't'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "ht:", long_options, &option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+			print_arg_list_help(status_option_list, argv[0],
+					    status_cmd_syntax);
+			ret = ERRORCODE_HELP;
+			goto bail;
+
+		case 't':
+			timeout = strtol(optarg, NULL, 0);
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+		        "%s: error: Unexpected extra argument: \"%s\"\n",
+			argv[0], argv[optind]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	if (gInterfaceName[0] == 0) {
+		fprintf(stderr,
+		        "%s: error: No WPAN interface set (use the `cd` command, or the `-I` argument for `wpanctl`).\n",
+		        argv[0]);
+		ret = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+		char path[DBUS_MAXIMUM_NAME_LENGTH+1];
+		char interface_dbus_name[DBUS_MAXIMUM_NAME_LENGTH+1];
+		ret = lookup_dbus_name_from_interface(interface_dbus_name, gInterfaceName);
+		if (ret != 0) {
+			print_error_diagnosis(ret);
+			goto bail;
+		}
+		snprintf(path,
+		         sizeof(path),
+		         "%s/%s",
+		         WPANTUND_DBUS_PATH,
+		         gInterfaceName);
+
+		message = dbus_message_new_method_call(
+		    interface_dbus_name,
+		    path,
+		    WPANTUND_DBUS_APIv1_INTERFACE,
+		    WPANTUND_IF_CMD_STATUS
+		    );
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", argv[0], error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_iter_init(reply, &iter);
+
+		fprintf(stdout, "%s => ", gInterfaceName);
+		dump_info_from_iter(stdout, &iter, 0, false, false);
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
diff --git a/src/wpanctl/tool-cmd-status.h b/src/wpanctl/tool-cmd-status.h
new file mode 100644
index 0000000..8b69576
--- /dev/null
+++ b/src/wpanctl/tool-cmd-status.h
@@ -0,0 +1,27 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_TOOL_CMD_STATUS_H
+#define WPANCTL_TOOL_CMD_STATUS_H
+
+#include "wpanctl-utils.h"
+
+int tool_cmd_status(int argc, char* argv[]);
+
+#endif
diff --git a/src/wpanctl/wpanctl-cmds.h b/src/wpanctl/wpanctl-cmds.h
new file mode 100644
index 0000000..d738cda
--- /dev/null
+++ b/src/wpanctl/wpanctl-cmds.h
@@ -0,0 +1,161 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef wpantund_wpanctl_cmds_h
+#define wpantund_wpanctl_cmds_h
+
+#include "tool-cmd-scan.h"
+#include "tool-cmd-join.h"
+#include "tool-cmd-form.h"
+#include "tool-cmd-leave.h"
+#include "tool-cmd-permit-join.h"
+#include "tool-cmd-list.h"
+#include "tool-cmd-status.h"
+#include "tool-cmd-mfg.h"
+#include "tool-cmd-resume.h"
+#include "tool-cmd-reset.h"
+#include "tool-cmd-begin-low-power.h"
+#include "tool-cmd-begin-net-wake.h"
+#include "tool-cmd-host-did-wake.h"
+#include "tool-cmd-getprop.h"
+#include "tool-cmd-setprop.h"
+#include "tool-cmd-cd.h"
+#include "tool-cmd-poll.h"
+#include "tool-cmd-config-gateway.h"
+#include "tool-cmd-add-route.h"
+#include "tool-cmd-remove-route.h"
+#include "tool-cmd-pcap.h"
+
+#include "wpanctl-utils.h"
+
+#define WPANCTL_CLI_COMMANDS \
+	{ \
+		"join", \
+		"Join a WPAN.", \
+		&tool_cmd_join \
+	}, \
+	{ "connect", "", &tool_cmd_join, 1 }, \
+	{ \
+		"form", \
+		"Form a new WPAN.", \
+		&tool_cmd_form \
+	}, \
+	{ \
+		"attach", \
+		"Attach/resume a previously commissioned network", \
+		&tool_cmd_resume \
+	}, \
+	{ "resume", "", &tool_cmd_resume, 1 }, \
+	{ \
+		"reset", \
+		"Reset the NCP", \
+		&tool_cmd_reset \
+	}, \
+	{ \
+		"begin-low-power", \
+		"Enter low-power mode", \
+		&tool_cmd_begin_low_power \
+	}, \
+	{ "lurk", "", &tool_cmd_begin_low_power, 1 }, \
+	{ "wake", "", &tool_cmd_status, 1 }, \
+	{ \
+		"leave", \
+		"Abandon the currently connected WPAN.", \
+		&tool_cmd_leave \
+	}, \
+	{ "disconnect", "", &tool_cmd_leave, 1 }, \
+	{ \
+		"poll", \
+		"Poll the parent immediately to see if there is IP traffic", \
+		&tool_cmd_poll \
+	}, \
+	{ \
+		"config-gateway", \
+		"Configure gateway", \
+		&tool_cmd_config_gateway \
+	}, \
+	{ \
+		"add-route", \
+		"Add external route prefix", \
+		&tool_cmd_add_route \
+	}, \
+	{ \
+		"remove-route", \
+		"Remove external route prefix", \
+		&tool_cmd_remove_route \
+	}, \
+	{ \
+		"list", \
+		"List available interfaces.", \
+		&tool_cmd_list \
+	}, \
+	{ "ls", "", &tool_cmd_list, 1 }, \
+	{ \
+		"status", \
+		"Retrieve the status of the interface.", \
+		&tool_cmd_status \
+	}, \
+	{ \
+		"permit-join", \
+		"Permit other devices to join the current network.", \
+		&tool_cmd_permit_join \
+	}, \
+	{ "pj", "", &tool_cmd_permit_join, 1 }, \
+	{ "permit", "", &tool_cmd_permit_join, 1 }, \
+	{ \
+		"scan", \
+		"Scan for nearby networks.", \
+		&tool_cmd_scan \
+	}, \
+	{ \
+		"mfg", \
+		"Execute manufacturing command.", \
+		&tool_cmd_mfg \
+	}, \
+	{ \
+		"getprop", \
+		"Get a property.", \
+		&tool_cmd_getprop \
+	}, \
+	{ "get", "", &tool_cmd_getprop, 1 }, \
+	{ \
+		"setprop", \
+		"Set a property.", \
+		&tool_cmd_setprop \
+	}, \
+	{ "set", "", &tool_cmd_setprop, 1 }, \
+	{ \
+		"begin-net-wake", \
+		"Initiate a network wakeup", \
+		&tool_cmd_begin_net_wake \
+	}, \
+	{ \
+		"host-did-wake", \
+		"Perform any host-wakeup related tasks", \
+		&tool_cmd_host_did_wake \
+	}, \
+	{ \
+		"pcap", \
+		"Start a packet capture", \
+		&tool_cmd_pcap \
+	}, \
+	{ "cd",   "Change current interface (command mode)", \
+	  &tool_cmd_cd                                            }
+
+#endif
diff --git a/src/wpanctl/wpanctl-utils.c b/src/wpanctl/wpanctl-utils.c
new file mode 100644
index 0000000..4ef2c8a
--- /dev/null
+++ b/src/wpanctl/wpanctl-utils.c
@@ -0,0 +1,615 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include "string-utils.h"
+#include "wpanctl-utils.h"
+#include "wpan-dbus-v0.h"
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <ctype.h>
+
+#ifdef __APPLE__
+char gInterfaceName[32] = "utun2";
+#else
+char gInterfaceName[32] = "wpan0";
+#endif
+int gRet = 0;
+
+void dump_info_from_iter(FILE* file, DBusMessageIter *iter, int indent, bool bare, bool indentFirstLine)
+{
+	DBusMessageIter sub_iter;
+	int i;
+
+	if (!bare && indentFirstLine) for (i = 0; i < indent; i++) fprintf(file, "\t");
+
+	switch (dbus_message_iter_get_arg_type(iter)) {
+	case DBUS_TYPE_DICT_ENTRY:
+		dbus_message_iter_recurse(iter, &sub_iter);
+		dump_info_from_iter(file, &sub_iter, indent + 1, true, false);
+		fprintf(file, " => ");
+		dbus_message_iter_next(&sub_iter);
+		dump_info_from_iter(file, &sub_iter, indent + 1, bare, false);
+		bare = true;
+		break;
+	case DBUS_TYPE_ARRAY:
+		dbus_message_iter_recurse(iter, &sub_iter);
+		if (dbus_message_iter_get_arg_type(&sub_iter) == DBUS_TYPE_BYTE ||
+		    dbus_message_iter_get_arg_type(&sub_iter) == DBUS_TYPE_INVALID) {
+			fprintf(file, "[");
+			indent = 0;
+		} else {
+			fprintf(file, "[\n");
+		}
+
+		for (;
+		     dbus_message_iter_get_arg_type(&sub_iter) != DBUS_TYPE_INVALID;
+		     dbus_message_iter_next(&sub_iter)
+		) {
+			dump_info_from_iter(file,
+			                    &sub_iter,
+			                    indent + 1,
+			                    dbus_message_iter_get_arg_type(&sub_iter) == DBUS_TYPE_BYTE,
+								true);
+		}
+		for (i = 0; i < indent; i++) fprintf(file, "\t");
+		fprintf(file, "]");
+
+		break;
+	case DBUS_TYPE_VARIANT:
+		dbus_message_iter_recurse(iter, &sub_iter);
+		dump_info_from_iter(file, &sub_iter, indent, bare, false);
+		bare = true;
+		break;
+	case DBUS_TYPE_STRING:
+	{
+		const char* string;
+		dbus_message_iter_get_basic(iter, &string);
+		fprintf(file, "\"%s\"", string);
+	}
+	break;
+
+	case DBUS_TYPE_BYTE:
+	{
+		uint8_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		if (!bare) {
+			fprintf(file, "0x%02X", v);
+		} else {
+			fprintf(file, "%02X", v);
+		}
+	}
+	break;
+	case DBUS_TYPE_UINT16:
+	{
+		uint16_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		fprintf(file, "0x%04X", v);
+	}
+	break;
+	case DBUS_TYPE_INT16:
+	{
+		int16_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		fprintf(file, "%d", v);
+	}
+	break;
+	case DBUS_TYPE_UINT32:
+	{
+		uint32_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		fprintf(file, "%d", v);
+	}
+	break;
+	case DBUS_TYPE_BOOLEAN:
+	{
+		dbus_bool_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		fprintf(file, "%s", v ? "true" : "false");
+	}
+	break;
+	case DBUS_TYPE_INT32:
+	{
+		int32_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		fprintf(file, "%d", v);
+	}
+	break;
+	case DBUS_TYPE_UINT64:
+	{
+		uint64_t v;
+		dbus_message_iter_get_basic(iter, &v);
+		fprintf(file, "0x%016llX", (unsigned long long)v);
+	}
+	break;
+	default:
+		fprintf(file, "<%s>",
+		        dbus_message_type_to_string(dbus_message_iter_get_arg_type(iter)));
+		break;
+	}
+	if (!bare)
+		fprintf(file, "\n");
+}
+
+int parse_network_info_from_iter(struct wpan_network_info_s *network_info, DBusMessageIter *iter)
+{
+	int ret = 0;
+	DBusMessageIter outer_iter;
+	DBusMessageIter dict_iter;
+
+	if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_ARRAY) {
+		dbus_message_iter_recurse(iter, &outer_iter);
+		iter = &outer_iter;
+	}
+
+	memset(network_info, 0, sizeof(*network_info));
+
+	for (;
+	     dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID;
+	     dbus_message_iter_next(iter)) {
+		DBusMessageIter value_iter;
+		char* key;
+
+		if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY) {
+			fprintf(stderr,
+			        "error: Bad type for network (%c)\n",
+			        dbus_message_iter_get_arg_type(iter));
+			ret = ERRORCODE_UNKNOWN;
+			goto bail;
+		}
+
+		dbus_message_iter_recurse(iter, &dict_iter);
+
+		if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_STRING) {
+			fprintf(stderr,
+			        "error: Bad type for network list (%c)\n",
+			        dbus_message_iter_get_arg_type(&dict_iter));
+			ret = ERRORCODE_UNKNOWN;
+			goto bail;
+		}
+
+		// Get the key
+		dbus_message_iter_get_basic(&dict_iter, &key);
+		dbus_message_iter_next(&dict_iter);
+
+		if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_VARIANT) {
+			fprintf(stderr,
+			        "error: Bad type for network list (%c)\n",
+			        dbus_message_iter_get_arg_type(&dict_iter));
+			ret = ERRORCODE_UNKNOWN;
+			goto bail;
+		}
+
+		dbus_message_iter_recurse(&dict_iter, &value_iter);
+
+		if (strcmp(key, kWPANTUNDProperty_NetworkName) == 0) {
+			char* network_name = NULL;
+			dbus_message_iter_get_basic(&value_iter, &network_name);
+			snprintf(network_info->network_name,
+			         sizeof(network_info->network_name), "%s", network_name);
+		} else if (strcmp(key, kWPANTUNDProperty_NCPChannel) == 0) {
+			dbus_message_iter_get_basic(&value_iter, &network_info->channel);
+		} else if (strcmp(key, kWPANTUNDProperty_NetworkPANID) == 0) {
+			dbus_message_iter_get_basic(&value_iter, &network_info->pan_id);
+		} else if (strcmp(key, kWPANTUNDProperty_NestLabs_NetworkAllowingJoin) == 0) {
+			dbus_message_iter_get_basic(&value_iter,
+			                            &network_info->allowing_join);
+		} else if (strcmp(key, "RSSI") == 0) {
+			dbus_message_iter_get_basic(&value_iter, &network_info->rssi);
+		} else if (strcmp(key, kWPANTUNDProperty_NetworkXPANID) == 0) {
+			dbus_message_iter_get_basic(&value_iter, &network_info->xpanid);
+		} else if (strcmp(key, kWPANTUNDProperty_NetworkNodeType) == 0) {
+			dbus_message_iter_get_basic(&value_iter, &network_info->type);
+		} else if (strcmp(key, kWPANTUNDProperty_NCPHardwareAddress) == 0) {
+			DBusMessageIter sub_iter;
+			dbus_message_iter_recurse(&value_iter, &sub_iter);
+			if (dbus_message_iter_get_arg_type(&sub_iter) == DBUS_TYPE_BYTE) {
+				const uint8_t* value = NULL;
+				int nelements = 0;
+				dbus_message_iter_get_fixed_array(&sub_iter, &value,
+				                                  &nelements);
+				if (nelements == 8)
+					memcpy(network_info->hwaddr, value, nelements);
+			}
+		} else {
+#if DEBUG
+			fprintf(stderr,
+			        "info: %s -> (%c)\n",
+			        key,
+			        dbus_message_iter_get_arg_type(&value_iter));
+#endif
+		}
+	}
+
+bail:
+	if (ret) fprintf(stderr, "Network parse failed.\n");
+	return ret;
+}
+
+int parse_energy_scan_result_from_iter(int16_t *channel, int8_t *maxRssi, DBusMessageIter *iter)
+{
+	int ret = 0;
+	DBusMessageIter outer_iter;
+	DBusMessageIter dict_iter;
+
+	if (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_ARRAY) {
+		dbus_message_iter_recurse(iter, &outer_iter);
+		iter = &outer_iter;
+	}
+
+	*channel = 0;
+	*maxRssi = 0;
+
+	for (;
+	     dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INVALID;
+	     dbus_message_iter_next(iter)) {
+		DBusMessageIter value_iter;
+		char* key;
+
+		if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_DICT_ENTRY) {
+			fprintf(stderr,
+			        "error: Bad type for energy scan result (%c)\n",
+			        dbus_message_iter_get_arg_type(iter));
+			ret = ERRORCODE_UNKNOWN;
+			goto bail;
+		}
+
+		dbus_message_iter_recurse(iter, &dict_iter);
+
+		if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_STRING) {
+			fprintf(stderr,
+			        "error: Bad type for energy scan result (%c)\n",
+			        dbus_message_iter_get_arg_type(&dict_iter));
+			ret = ERRORCODE_UNKNOWN;
+			goto bail;
+		}
+
+		// Get the key
+		dbus_message_iter_get_basic(&dict_iter, &key);
+		dbus_message_iter_next(&dict_iter);
+
+		if (dbus_message_iter_get_arg_type(&dict_iter) != DBUS_TYPE_VARIANT) {
+			fprintf(stderr,
+			        "error: Bad type for energy scan result (%c)\n",
+			        dbus_message_iter_get_arg_type(&dict_iter));
+			ret = ERRORCODE_UNKNOWN;
+			goto bail;
+		}
+
+		dbus_message_iter_recurse(&dict_iter, &value_iter);
+
+		if (strcmp(key, kWPANTUNDProperty_NCPChannel) == 0) {
+			dbus_message_iter_get_basic(&value_iter, channel);
+		} else if (strcmp(key, "RSSI") == 0) {
+			dbus_message_iter_get_basic(&value_iter, maxRssi);
+		} else {
+#if DEBUG
+			fprintf(stderr,
+			        "info: %s -> (%c)\n",
+			        key,
+			        dbus_message_iter_get_arg_type(&value_iter));
+#endif
+		}
+	}
+
+bail:
+	if (ret) fprintf(stderr, "Energy scan result parse failed.\n");
+	return ret;
+}
+
+int
+lookup_dbus_name_from_interface(char* dbus_bus_name, const char* interface_name)
+{
+	int ret = kWPANTUNDStatus_InterfaceNotFound;
+	int i;
+	int timeout = DEFAULT_TIMEOUT_IN_SECONDS * 1000;
+	DBusConnection* connection = NULL;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	DBusError error;
+
+	dbus_error_init(&error);
+
+	memset(dbus_bus_name, 0, DBUS_MAXIMUM_NAME_LENGTH+1);
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	{
+		DBusMessageIter iter;
+		DBusMessageIter list_iter;
+
+		message = dbus_message_new_method_call(
+		    WPAN_TUNNEL_DBUS_NAME,
+		    WPAN_TUNNEL_DBUS_PATH,
+		    WPAN_TUNNEL_DBUS_INTERFACE,
+		    WPAN_TUNNEL_CMD_GET_INTERFACES
+		    );
+
+		reply = dbus_connection_send_with_reply_and_block(
+		    connection,
+		    message,
+		    timeout,
+		    &error
+		    );
+
+		if (!reply) {
+			fprintf(stderr, "%s: error: %s\n", "lookup_dbus_name_from_interface", error.message);
+			ret = ERRORCODE_TIMEOUT;
+			goto bail;
+		}
+
+		dbus_message_iter_init(reply, &iter);
+
+		if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
+			fprintf(stderr,
+			        "%s: error: Bad type for interface list (%c)\n",
+			        "lookup_dbus_name_from_interface",
+			        dbus_message_iter_get_element_type(&iter));
+			ret = ERRORCODE_UNKNOWN;
+			goto bail;
+		}
+
+		dbus_message_iter_recurse(&iter, &list_iter);
+
+		for (;
+		     dbus_message_iter_get_arg_type(&list_iter) == DBUS_TYPE_ARRAY;
+		     dbus_message_iter_next(&list_iter)
+		) {
+			DBusMessageIter item_iter;
+			char *item_interface_name = NULL;
+			char *item_dbus_name = NULL;
+
+			dbus_message_iter_recurse(&list_iter, &item_iter);
+
+			dbus_message_iter_get_basic(&item_iter, &item_interface_name);
+			dbus_message_iter_next(&item_iter);
+			dbus_message_iter_get_basic(&item_iter, &item_dbus_name);
+			if ((NULL != item_interface_name)
+				&& (NULL != item_dbus_name)
+				&& (strcmp(item_interface_name, interface_name) == 0)
+			) {
+				strncpy(dbus_bus_name, item_dbus_name, DBUS_MAXIMUM_NAME_LENGTH);
+				ret = 0;
+				break;
+			}
+		}
+	}
+
+bail:
+
+	if (connection)
+		dbus_connection_unref(connection);
+
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
+
+const char*
+wpantund_status_to_cstr(int status)
+{
+	if (status<0) {
+		return strerror(status);
+	}
+	if (WPANTUND_STATUS_IS_NCPERROR(status)) {
+		return "NCP-Specific Errorcode";
+	}
+	switch(status) {
+	case kWPANTUNDStatus_Ok: return "Ok";
+	case kWPANTUNDStatus_Failure: return "Failure";
+	case kWPANTUNDStatus_Timeout: return "Timeout";
+	case kWPANTUNDStatus_SocketReset: return "SocketReset";
+	case kWPANTUNDStatus_InvalidArgument: return "InvalidArgument";
+	case kWPANTUNDStatus_Busy: return "Busy";
+	case kWPANTUNDStatus_InvalidWhenDisabled: return "InvalidWhenDisabled";
+	case kWPANTUNDStatus_InvalidForCurrentState: return "InvalidForCurrentState";
+	case kWPANTUNDStatus_PropertyEmpty: return "PropertyEmpty";
+	case kWPANTUNDStatus_InvalidType: return "InvalidType";
+	case kWPANTUNDStatus_FeatureNotSupported: return "FeatureNotSupported";
+	case kWPANTUNDStatus_FeatureNotImplemented: return "FeatureNotImplemented";
+	case kWPANTUNDStatus_PropertyNotFound: return "PropertyNotFound";
+	case kWPANTUNDStatus_Canceled: return "Canceled";
+	case kWPANTUNDStatus_InProgress: return "InProgress";
+	case kWPANTUNDStatus_NCP_Crashed: return "NCPCrashed";
+	case kWPANTUNDStatus_JoinFailedAtScan: return "JoinFailedAtScan";
+	case kWPANTUNDStatus_JoinFailedAtAuthenticate: return "JoinFailedAtAuthenticate";
+	case kWPANTUNDStatus_Already: return "Already";
+	case kWPANTUNDStatus_TryAgainLater: return "TryAgainLater";
+	case kWPANTUNDStatus_InvalidRange: return "InvalidRange";
+	case kWPANTUNDStatus_MissingXPANID: return "MissingXPANID";
+	case kWPANTUNDStatus_InterfaceNotFound: return "InterfaceNotFound";
+	default: break;
+	}
+	return "";
+}
+
+void print_error_diagnosis(int error)
+{
+	switch(error) {
+	case kWPANTUNDStatus_InterfaceNotFound:
+		fprintf(stderr, "\nDIAGNOSIS: The requested operation can't be completed because the given\n"
+						"network interface doesn't exist or it isn't managed by wpantund. If you are\n"
+						"using wpanctl in interactive mode, you can use the `ls` command to get a list\n"
+						"of valid interfaces and use the `cd` command to select a valid interface.\n"
+						"Otherwise, use the `-I` argument to wpanctl to select a valid interface.\n"
+						"\n"
+		);
+		break;
+
+	case kWPANTUNDStatus_Busy:
+	case -EBUSY:
+		fprintf(stderr, "\nDIAGNOSIS: The requested operation can't be completed because the NCP\n"
+						"is busy doing something else, like scanning or joining. If you are persistently\n"
+						"getting this error, try resetting the NCP via the \"reset\" command. You can\n"
+						"help diagnose why this is occuring using the \"state\" command.\n"
+						"\n"
+		);
+		break;
+
+
+	case kWPANTUNDStatus_Canceled:
+	case -ECONNABORTED:
+		fprintf(stderr, "\nDIAGNOSIS: This action was aborted due to a change in the NCP's state.\n"
+						"This can occur if the interface is disabled while you were trying to join,\n"
+						"or if AutoDeepSleep kicked in for some reason.\n"
+						"\n"
+		);
+		break;
+
+	case kWPANTUNDStatus_NCP_Crashed:
+	case -ECONNRESET:
+		fprintf(stderr, "\nDIAGNOSIS: The NCP has unexpectedly crashed and rebooted. Please see the\n"
+						"wpantund logs for more information and try again.\n"
+						"\n"
+		);
+		break;
+
+	case kWPANTUNDStatus_InvalidArgument:
+	case -EINVAL:
+		fprintf(stderr, "\nDIAGNOSIS: This error indicates that either the device in a state where your\n"
+						"request makes no sense or the parameters of your request were invalid. Check your\n"
+						"arguments and verify that you are allowed to perform the given operation when the\n"
+						"NCP is in its current state.\n"
+						"\n"
+		);
+		break;
+
+	case kWPANTUNDStatus_InvalidWhenDisabled:
+		fprintf(stderr, "\nDIAGNOSIS: This error indicates that this operation is not valid when the interface\n"
+						"is disabled. Enable the interface first and try again. You can enable the interface\n"
+						"with the command `setprop enabled true`.\n"
+						"\n"
+		);
+		break;
+
+	case kWPANTUNDStatus_InvalidForCurrentState:
+	case kWPANTUNDStatus_InProgress:
+	case -EALREADY:
+		fprintf(stderr, "\nDIAGNOSIS: This error indicates that the device is not in a state where\n"
+						"it can complete your request, typically because a request is already in progress or\n"
+						"the NCP is already in the requested state.\n"
+						"If you are getting this error persistently, you should try reseting the network\n"
+						"settings on the NCP (via the \"leave\" command). The \"status\" command can be\n"
+						"helpful to further diagnose the issue.\n"
+						"\n"
+		);
+		break;
+
+	case kWPANTUNDStatus_JoinFailedAtScan:
+		fprintf(stderr, "\nDIAGNOSIS: This error indicates that the NCP could not find a device in\n"
+						"range that would allow it to join the given network. This can occur if\n"
+						"the closest device on the network you are trying to join is out of range,\n"
+						"the devices on the network you are trying to join are running an\n"
+						"incompatible network stack, or if there are no devices on the target\n"
+						"network which are permitting joining.\n"
+						"\n"
+		);
+		break;
+
+	case kWPANTUNDStatus_JoinFailedAtAuthenticate:
+		fprintf(stderr, "\nDIAGNOSIS: Join failed while authenticating. This is typically due to using the wrong\n"
+		                "key or because this NCP's network stack is not compatible with this network.\n"
+						"\n"
+		);
+		break;
+	}
+
+	if (WPANTUND_STATUS_IS_NCPERROR(error)) {
+		fprintf(stderr, "\nDIAGNOSIS: This error is specific to this specific type of NCP. The error\n"
+		                "code is %d (0x%02X). Consult the NCP documentation for an explantion of this\n"
+						"error code.\n"
+						"\n", WPANTUND_STATUS_TO_NCPERROR(error), WPANTUND_STATUS_TO_NCPERROR(error)
+		);
+	}
+}
+
+uint16_t
+node_type_str2int(const char *node_type)
+{
+	uint16_t type;
+
+	if (strcasecmp(node_type, "router") == 0) {
+		return WPAN_IFACE_ROLE_ROUTER;
+	} else if (strcasecmp(node_type, "r") == 0) {
+		return WPAN_IFACE_ROLE_ROUTER;
+
+	} else if (strcasecmp(node_type, "end-device") == 0) {
+		return WPAN_IFACE_ROLE_END_DEVICE;
+	} else if (strcasecmp(node_type, "end") == 0) {
+		return WPAN_IFACE_ROLE_END_DEVICE;
+	} else if (strcasecmp(node_type, "e") == 0) {
+		return WPAN_IFACE_ROLE_END_DEVICE;
+
+	} else if (strcasecmp(node_type, "sleepy-end-device") == 0) {
+		return WPAN_IFACE_ROLE_SLEEPY_END_DEVICE;
+	} else if (strcasecmp(node_type, "sleepy") == 0) {
+		return WPAN_IFACE_ROLE_SLEEPY_END_DEVICE;
+	} else if (strcasecmp(node_type, "sed") == 0) {
+		return WPAN_IFACE_ROLE_SLEEPY_END_DEVICE;
+	} else if (strcasecmp(node_type, "s") == 0) {
+		return WPAN_IFACE_ROLE_SLEEPY_END_DEVICE;
+
+	} else if (strcasecmp(node_type, "lurker") == 0) {
+		return WPAN_IFACE_ROLE_LURKER;
+	} else if (strcasecmp(node_type, "nl-lurker") == 0) {
+		return WPAN_IFACE_ROLE_LURKER;
+	} else if (strcasecmp(node_type, "l") == 0) {
+		return WPAN_IFACE_ROLE_LURKER;
+
+	} else {
+		// At this moment it should be a number
+		return strtol(node_type, NULL, 0);
+	}
+}
+
+const char *
+node_type_int2str(uint16_t node_type)
+{
+	switch (node_type)
+	{
+	case WPAN_IFACE_ROLE_ROUTER:            return "router";
+	case WPAN_IFACE_ROLE_END_DEVICE:        return "end-device";
+	case WPAN_IFACE_ROLE_SLEEPY_END_DEVICE: return "sleepy-end-device";
+	case WPAN_IFACE_ROLE_LURKER:            return "nl-lurker";
+	default: break;
+	}
+
+	return "unknown";
+}
diff --git a/src/wpanctl/wpanctl-utils.h b/src/wpanctl/wpanctl-utils.h
new file mode 100644
index 0000000..f107d5c
--- /dev/null
+++ b/src/wpanctl/wpanctl-utils.h
@@ -0,0 +1,84 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef WPANCTL_UTILS_H
+#define WPANCTL_UTILS_H
+
+#include <dbus/dbus.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "wpan-error.h"
+
+#define ERRORCODE_OK            (0)
+#define ERRORCODE_HELP          (1)
+#define ERRORCODE_BADARG        (2)
+#define ERRORCODE_NOCOMMAND     (3)
+#define ERRORCODE_UNKNOWN       (4)
+#define ERRORCODE_BADCOMMAND    (5)
+#define ERRORCODE_NOREADLINE    (6)
+#define ERRORCODE_QUIT          (7)
+#define ERRORCODE_BADCONFIG     (8)
+#define ERRORCODE_ERRNO         (9)
+#define ERRORCODE_NOT_IMPLEMENTED           (10)
+#define ERRORCODE_TIMEOUT           (11)
+#define ERRORCODE_BADVERSION     (12)
+#define ERRORCODE_ALLOC           (13)
+#define ERRORCODE_NOTFOUND     (14)
+#define ERRORCODE_REFUSED     (15)
+
+#define ERRORCODE_INTERRUPT     (128 + SIGINT)
+#define ERRORCODE_SIGHUP        (128 + SIGHUP)
+
+#define DEFAULT_TIMEOUT_IN_SECONDS      60
+
+struct command_info_s {
+	const char* name;
+	const char* desc;
+	int (*entrypoint)(
+	    int argc, char* argv[]);
+	int isHidden;
+};
+
+struct wpan_network_info_s {
+	char network_name[17];
+	dbus_bool_t allowing_join;
+	uint16_t pan_id;
+	int16_t channel;
+	uint64_t xpanid;
+	int8_t rssi;
+	uint8_t type;
+	uint8_t hwaddr[8];
+};
+
+const char* wpantund_status_to_cstr(int status);
+void print_error_diagnosis(int error);
+int parse_network_info_from_iter(struct wpan_network_info_s *network_info, DBusMessageIter *iter);
+int parse_energy_scan_result_from_iter(int16_t *channel, int8_t *maxRssi, DBusMessageIter *iter);
+int lookup_dbus_name_from_interface(char* dbus_bus_name, const char* interface_name);
+void dump_info_from_iter(FILE* file, DBusMessageIter *iter, int indent, bool bare, bool indentFirstLine);
+uint16_t node_type_str2int(const char *node_type);
+const char *node_type_int2str(uint16_t node_type);
+
+extern char gInterfaceName[32];
+extern int gRet;
+
+#endif
diff --git a/src/wpanctl/wpanctl.c b/src/wpanctl/wpanctl.c
new file mode 100644
index 0000000..a1a97ab
--- /dev/null
+++ b/src/wpanctl/wpanctl.c
@@ -0,0 +1,684 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *		This file implements the main program entry point for the
+ *		WPAN control utility, `wpanctl`.
+ *
+ */
+
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#undef ASSERT_MACROS_USE_SYSLOG
+#define ASSERT_MACROS_USE_SYSLOG 0
+
+#include <getopt.h>
+#include "assert-macros.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <ctype.h>
+#include <libgen.h>
+#include <time.h>
+
+#include <dbus/dbus.h>
+
+#if HAVE_LIBREADLINE
+#include <readline/readline.h>
+#include <readline/history.h>
+#endif // HAVE_LIBREADLINE
+
+#include <poll.h>
+#include "args.h"
+#include "config-file.h"
+#include "wpanctl-cmds.h"
+#include "version.h"
+#include "string-utils.h"
+#include "wpanctl-utils.h"
+
+#include "wpan-dbus-v0.h"
+
+static bool istty = true;
+int gDebugMode = 0;
+
+static arg_list_item_t option_list[] = {
+	{ 'h', "help",          NULL,
+	  "Print Help"                                                                   },
+	{ 'v', "version",       NULL,
+	  "Print Version Information"                                    },
+	{ 'f', NULL,            "filename",
+	  "Read commands from file"                                              },
+	{ 'I', "interface", "iface",
+	  "Set interface to use"                                                 },
+	{ 0, "ignore-mismatch", NULL, "Ignore driver version mismatch" },
+	{ 0 }
+};
+
+void print_commands();
+int exec_command(
+    int argc, char * argv[]);
+
+static int
+tool_cmd_help(
+    int argc, char* argv[]
+    )
+{
+	if ((2 == argc) && (0 == strcmp(argv[1], "--help"))) {
+		printf("Help not yet implemented for this command.\n");
+		return ERRORCODE_HELP;
+	}
+
+	if ((argc == 2) && argv[1][0] != '-') {
+		const char *argv2[2] = {
+			argv[1],
+			"--help"
+		};
+		return exec_command(2, (char**)argv2);
+	} else {
+		print_commands();
+	}
+	return ERRORCODE_HELP;
+}
+
+static int tool_cmd_clear(int argc, char *argv[])
+{
+	if (system("clear") == -1) {
+		printf("\n\n\n\n\n\n\n\n");
+	}
+	return 0;
+}
+
+struct command_info_s commandList[] = {
+	WPANCTL_CLI_COMMANDS,
+	{"quit", "Terminate command line mode.", NULL},
+	{"help", "Display this help.", &tool_cmd_help},
+	{"clear", "Clear shell.", &tool_cmd_clear},
+	{"?", NULL, &tool_cmd_help, 1},
+	{NULL}
+};
+
+void
+print_commands()
+{
+	int i;
+
+	printf("Commands:\n");
+	for (i = 0; commandList[i].name; ++i) {
+		if (commandList[i].isHidden)
+			continue;
+		printf(
+		    "   %s %s%s\n",
+		    commandList[i].name,
+		    &"                          "[strlen(commandList[i].name)],
+		    commandList[i].desc
+		    );
+	}
+}
+
+struct command_info_s * find_cmd(char *cmd_name)
+{
+	int idx;
+	for (idx = 0; commandList[idx].name; idx++) {
+		if (strcmp(cmd_name, commandList[idx].name) == 0) {
+			return commandList + idx;
+		}
+	}
+	return NULL;
+}
+
+int exec_command(int argc, char * argv[])
+{
+	int ret = 0;
+	struct command_info_s *cmd_entry;
+
+	require(argc, bail);
+
+	if ((strcmp(argv[0], "quit") == 0) || (strcmp(argv[0], "exit") == 0) ||
+			(strcmp(argv[0], "q") == 0)) {
+		ret = ERRORCODE_QUIT;
+		goto bail;
+	}
+
+	if ((cmd_entry = find_cmd(argv[0])) == NULL) {
+		fprintf(stderr, "The command \"%s\" is not recognised.\n",
+			argv[0]);
+		ret = ERRORCODE_BADCOMMAND;
+		goto bail;
+	}
+
+	if (cmd_entry->entrypoint == NULL) {
+		fprintf(stderr,
+		        "The command \"%s\" is not yet implemented.\n",
+		        cmd_entry->name);
+		ret = ERRORCODE_NOCOMMAND;
+		goto bail;
+	}
+
+	ret = cmd_entry->entrypoint(argc, argv);
+bail:
+	return ret;
+}
+
+#if HAVE_LIBREADLINE
+static bool history_disabled;
+char* wpanctl_generator(const char* text, int state)
+{
+	static int idx, len;
+	const char *name;
+
+	if (!state) {
+		idx = 0;
+		len = strlen(text);
+	}
+
+	while ((name = commandList[idx].name)) {
+		idx++;
+
+		if (commandList[idx - 1].isHidden)
+			continue;
+
+		if (strncmp(name, text, len) == 0)
+			return strdup(name);
+	}
+
+	return NULL;
+}
+
+static char** wpanctl_completion(const char *text, int start, int end)
+{
+	if (start != 0)
+		return NULL;
+
+	return rl_completion_matches(text, wpanctl_generator);
+}
+#endif // HAVE_LIBREADLINE
+
+void
+process_input_line(char *l)
+{
+	char *inputstring;
+	char *argv2[100];
+	char **ap = argv2;
+	int argc2 = 0;
+
+	if (!l[0]) {
+		l = NULL;
+		goto bail;
+	}
+	l = strdup(l);
+#if HAVE_LIBREADLINE
+	if (!history_disabled) {
+		add_history(l);
+	}
+#endif // HAVE_LIBREADLINE
+
+	inputstring = l;
+
+	while ((*ap = get_next_arg(inputstring, &inputstring))) {
+		if (**ap != '\0') {
+			ap++;
+			argc2++;
+		}
+	}
+	if (argc2 > 0) {
+		gRet = exec_command(argc2, argv2);
+		if (gRet == ERRORCODE_QUIT)
+			goto bail;
+		else if (gRet == ERRORCODE_ERRNO)
+			fprintf(stderr, "errno=%d %s\n", errno, strerror(errno));
+		else if (gRet < 0 && (gRet != ERRORCODE_HELP))
+			fprintf(stderr, "Error %d %s\n", gRet, strerror(-gRet));
+		else if (gRet && (gRet != ERRORCODE_HELP))
+			fprintf(stderr, "Error %d (0x%02X)\n", gRet, gRet);
+
+#if HAVE_LIBREADLINE
+		if (!history_disabled)
+			write_history(getenv("WPANCTL_HISTORY_FILE"));
+#endif // HAVE_LIBREADLINE
+	}
+
+bail:
+	free(l);
+	return;
+}
+
+#if HAVE_LIBREADLINE
+static char*
+get_current_prompt()
+{
+	static char prompt[64] = {};
+
+	if (!gInterfaceName[0]) {
+		snprintf(prompt,
+		         sizeof(prompt),
+		         "wpanctl> "
+		         );
+	} else {
+		snprintf(prompt,
+		         sizeof(prompt),
+		         "wpanctl:%s> ",
+		         gInterfaceName
+		         );
+	}
+	return prompt;
+}
+
+void
+process_input_readline(char *l)
+{
+	process_input_line(l);
+	if (istty) {
+#if HAVE_RL_SET_PROMPT
+		if (gRet == ERRORCODE_QUIT)
+			rl_set_prompt("");
+		else
+#endif
+		rl_callback_handler_install(
+		    get_current_prompt(), &process_input_readline);
+	}
+}
+#endif // HAVE_LIBREADLINE
+
+#pragma mark -
+
+#if HAVE_LIBREADLINE
+
+static int
+initialize_readline()
+{
+	int ret = 0;
+
+	require_action(NULL != readline, bail, ret = ERRORCODE_NOREADLINE);
+	rl_initialize();
+
+	rl_readline_name = "wpanctl";
+	//rl_completer_word_break_characters = " \t\n\"\\'`@$><|&{("; // Removed '=' ';'
+
+	using_history();
+	read_history(getenv("WPANCTL_HISTORY_FILE"));
+	rl_instream = stdin;
+
+	rl_callback_handler_install(get_current_prompt(), &process_input_readline);
+
+	rl_attempted_completion_function = wpanctl_completion;
+
+bail:
+	return ret;
+}
+#endif
+
+static void
+print_version()
+{
+	printf("wpanctl " PACKAGE_VERSION );
+	if ((internal_build_source_version[0] == 0) || strequal(SOURCE_VERSION, internal_build_source_version)) {
+		if (strequal(PACKAGE_VERSION, SOURCE_VERSION)) {
+			printf(" (%s)\n", internal_build_date);
+		} else {
+			printf(" (" SOURCE_VERSION "; %s)\n", internal_build_date);
+		}
+	} else {
+		if (strequal(SOURCE_VERSION, PACKAGE_VERSION) || strequal(PACKAGE_VERSION, internal_build_source_version)) {
+			printf(" (%s; %s)\n", internal_build_source_version, internal_build_date);
+		} else {
+			printf(" (" SOURCE_VERSION "/%s; %s)\n", internal_build_source_version, internal_build_date);
+		}
+	}
+}
+
+static int
+wpan_dbus_version_check(DBusConnection* connection)
+{
+	int timeout = 5 * 1000; // Five second timeout
+	int ret = ERRORCODE_BADVERSION;
+	DBusMessage *message = NULL;
+	DBusMessage *reply = NULL;
+	uint32_t version = 0;
+	DBusError error;
+
+	dbus_error_init(&error);
+
+	message = dbus_message_new_method_call(
+	    getenv("WPANCTL_DBUS_NAME"),
+	    WPAN_TUNNEL_DBUS_PATH,
+	    WPAN_TUNNEL_DBUS_INTERFACE,
+	    WPAN_TUNNEL_CMD_GET_VERSION
+	    );
+
+	if (!message) {
+		fprintf(stderr, "error: Unable to allocate dbus message\n");
+		ret = ERRORCODE_ALLOC;
+		goto bail;
+	}
+
+	reply = dbus_connection_send_with_reply_and_block(
+	    connection,
+	    message,
+	    timeout,
+	    &error
+	    );
+
+	if (!reply) {
+		fprintf(stderr, "error: %s\n", error.message);
+		ret = ERRORCODE_TIMEOUT;
+		goto bail;
+	}
+
+	dbus_message_get_args(
+	    reply, NULL,
+	    DBUS_TYPE_UINT32, &version,
+	    DBUS_TYPE_INVALID
+	);
+
+	if (gDebugMode >= 1) {
+		fprintf(stderr, "DEBUG: Version check, wpanctl=%d, wpantund=%d\n", WPAN_TUNNEL_DBUS_VERSION, version);
+	}
+
+	if(version != WPAN_TUNNEL_DBUS_VERSION) {
+		fprintf(stderr, "error: `wpantund` version (%d) doesn't match `wpanctl` version (%d).\n", version, WPAN_TUNNEL_DBUS_VERSION);
+		goto bail;
+	}
+
+	ret = 0;
+
+bail:
+	if (message)
+		dbus_message_unref(message);
+
+	if (reply)
+		dbus_message_unref(reply);
+
+	dbus_error_free(&error);
+
+	return ret;
+}
+
+#pragma mark -
+
+
+int main(int argc, char * argv[])
+{
+	int c;
+	bool ignore_driver_version_mismatch = false;
+	DBusError error;
+	DBusConnection* connection;
+
+	dbus_error_init(&error);
+
+	srandom(time(NULL));
+
+	while (1) {
+		static struct option long_options[] = {
+			{"help", no_argument, 0, 'h'},
+			{"version", no_argument, 0, 'v'},
+			{"ignore-mismatch", no_argument, 0, 'i'},
+			{"debug", no_argument, 0, 'd'},
+			{"interface", required_argument, 0, 'I'},
+			{"file", required_argument, 0, 'f'},
+			{0, 0, 0, 0}
+		};
+
+		int option_index = 0;
+
+		if ((optind < argc) && (find_cmd(argv[optind]) != NULL)) {
+			// This is where the wpanctl command starts; skip
+			// parsing the flags since they may belong to the command
+			break;
+	}
+
+		c = getopt_long(argc, argv, "hvidI:f:", long_options,
+				&option_index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 'h':
+		print_version();
+		print_arg_list_help(option_list,
+		                    argv[0],
+		                    "[options] <sub-command> [args]");
+		print_commands();
+		gRet = ERRORCODE_HELP;
+		goto bail;
+
+		case 'v':
+			print_version();
+			gRet = 0;
+			goto bail;
+
+		case 'd':
+			gDebugMode++;
+			break;
+
+		case 'I':
+			snprintf(gInterfaceName, sizeof(gInterfaceName),
+				 "%s", optarg);
+			break;
+
+		case 'i':
+			ignore_driver_version_mismatch = true;
+			break;
+
+		case 'f':
+#if HAVE_LIBREADLINE
+			if (NULL == freopen(optarg, "r", stdin))
+			{
+				fprintf(stderr,
+						"%s: error: Unable to open file \"%s\".\n",
+						argv[0], optarg);
+				return ERRORCODE_BADARG;
+			}
+#else
+			fprintf(stderr,
+				"%s: Cannot read from file \"%s\" : Missing readline library.\n",
+				argv[0], optarg);
+			return ERRORCODE_BADARG;
+#endif
+		default:
+		break;
+	}
+	}
+
+	istty = isatty(fileno(stdin));
+
+	if (gDebugMode >= 1) {
+		fprintf(stderr, "DEBUG: isatty(fileno(stdin)) = %d\n", istty);
+	}
+
+	if (gDebugMode >= 1) {
+		fprintf(stderr, "DEBUG: Will use interface '%s'.\n", gInterfaceName);
+	}
+
+	if (getenv("WPANCTL_DBUS_NAME") && gDebugMode>=1)
+		fprintf(stderr, "DEBUG: Using dbus \"%s\"\n", getenv("WPANCTL_DBUS_NAME"));
+
+	setenv("WPANCTL_DBUS_NAME", WPAN_TUNNEL_DBUS_NAME, 0);
+
+	if (gDebugMode >= 1) {
+		fprintf(stderr, "DEBUG: Getting DBusConnection via dbus_bus_get(DBUS_BUS_STARTER). . .\n");
+	}
+
+	connection = dbus_bus_get(DBUS_BUS_STARTER, &error);
+
+	if (!connection) {
+		if (gDebugMode >= 1) {
+			fprintf(stderr, "DEBUG: dbus_bus_get(DBUS_BUS_STARTER) didn't work, trying dbus_bus_get(DBUS_BUS_SYSTEM). . .\n");
+		}
+		dbus_error_free(&error);
+		dbus_error_init(&error);
+		connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
+	}
+
+	require_string(connection != NULL, bail, error.message);
+
+	if (gDebugMode >= 1) {
+		fprintf(stderr, "DEBUG: DBusConnection: %p\n", connection);
+	}
+
+	if (gDebugMode >= 1) {
+		fprintf(stderr, "DEBUG: Registering DBusConnection. . .\n");
+	}
+
+	dbus_bus_register(connection, &error);
+	require_string(error.name == NULL, bail, error.message);
+
+	if (gDebugMode >= 1) {
+		fprintf(stderr, "DEBUG: DBusConnection registered.\n");
+	}
+
+	if (gDebugMode >= 1) {
+		fprintf(stderr, "DEBUG: Requesting DBus name \"%s\". . .\n",WPAN_TUNNEL_DBUS_NAME ".wpanctl");
+	}
+
+	dbus_bus_request_name(connection,
+	                      WPAN_TUNNEL_DBUS_NAME ".wpanctl",
+	                      0,
+	                      &error);
+
+	if (gDebugMode >= 1) {
+		if (error.name != NULL) {
+			fprintf(stderr, "DEBUG: Requesting DBus name \"%s\" failed (no biggie): %s\n",WPAN_TUNNEL_DBUS_NAME ".wpanctl", error.name);
+		} else {
+			fprintf(stderr, "DEBUG: Requesting DBus name \"%s\" succeded.\n",WPAN_TUNNEL_DBUS_NAME ".wpanctl");
+		}
+	}
+
+	// Don't fail if we can't get the name. It isn't a big deal.
+	//require_string(error.name == NULL, bail, error.message);
+
+	if (gDebugMode >= 1) {
+		fprintf(stderr, "DEBUG: Performing wpantund version check. . .\n");
+	}
+
+	// Make sure that we are compatible with the copy of wpantund
+	// that is currently running.
+	gRet = wpan_dbus_version_check(connection);
+
+	if (gRet != 0) {
+		fprintf(stderr,
+		        "%s: error: `wpantund` is either not running, locked up, or incompatible with this version of `wpanctl`.\n",
+		        argv[0]
+		        );
+		if (!ignore_driver_version_mismatch)
+			goto bail;
+	} else {
+		if (gDebugMode >= 1) {
+			fprintf(stderr,
+				"DEBUG: wpantund version check succeded.\n");
+		}
+	}
+
+	if (optind < argc) {
+			if (gDebugMode >= 1) {
+			fprintf(stderr, "DEBUG: Executing command '%s'. . .\n",
+				argv[optind]);
+		}
+
+		argc -= optind;
+		argv += optind;
+
+		optind = 0;
+		gRet = exec_command(argc, argv);
+		goto bail;
+	}
+
+	if (istty) {
+#if !HAVE_LIBREADLINE
+		fprintf(stderr,
+		        "%s: error: Interactive mode disabled: Compiled without libeditline or libreadline support.\n",
+		        argv[0]
+		        );
+		print_arg_list_help(option_list,
+		                    argv[0],
+		                    "[options] <sub-command> [args]");
+		print_commands();
+		gRet = ERRORCODE_NOCOMMAND;
+		goto bail;
+#else   // HAVE_LIBREADLINE
+		setenv("WPANCTL_HISTORY_FILE", tilde_expand("~/.wpanctl_history"), 0);
+
+		gRet = initialize_readline();
+		if(gRet) {
+			fprintf(stderr,
+			        "%s: error: Failed to initialize readline: %d\n",
+			        argv[0], gRet
+			        );
+			goto bail;
+		}
+#endif  // HAVE_LIBREADLINE
+	}
+
+	// Command mode.
+	while ((gRet != ERRORCODE_QUIT) && !feof(stdin)) {
+		optind = 0;
+#if HAVE_LIBREADLINE
+		if (istty) {
+			int dbus_fd = -1;
+
+			dbus_connection_get_unix_fd(connection, &dbus_fd);
+
+			struct pollfd polltable[2] = {
+				{ fileno(stdin), POLLIN | POLLHUP,               0                         },
+				{ dbus_fd,               POLLIN | POLLHUP,               0                         },
+			};
+
+			if (poll(
+			        polltable,
+			        (dbus_fd >= 0) ? 2 : 1,
+			        1000
+			        ) < 0
+			    ) {
+				if (errno == EINTR) {
+					// We just caught a signal.
+					// Do nothing.
+				} else {
+					break;
+				}
+			}
+
+			if (polltable[0].revents)
+				rl_callback_read_char();
+		} else
+#endif  // HAVE_LIBREADLINE
+		{
+			char linebuffer[200];
+			process_input_line(fgets(linebuffer, sizeof(linebuffer), stdin));
+		}
+
+		dbus_connection_read_write_dispatch(connection, 0);
+	}
+	printf("\n");
+
+bail:
+#if HAVE_LIBREADLINE
+	rl_callback_handler_remove();
+#endif  // HAVE_LIBREADLINE
+	if (gRet == ERRORCODE_QUIT)
+		gRet = 0;
+
+	return gRet;
+}
diff --git a/src/wpantund/FirmwareUpgrade.cpp b/src/wpantund/FirmwareUpgrade.cpp
new file mode 100644
index 0000000..9937edb
--- /dev/null
+++ b/src/wpantund/FirmwareUpgrade.cpp
@@ -0,0 +1,433 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Firmware Upgrade Manager
+ *
+ */
+
+/*
+
+This class does what may, at first, appear to be somewhat
+reminiscent of a "Rube Goldberg" contraption: When we
+set the check and upgrade commands, we end up forking and
+spinning off entirely new processes which we communicate
+with via a socket/pipe. Why on earth would I do this?
+
+The answer is security. While wpantund doesn't drop
+privileges yet, it will have that capability one day.
+This setup allows the upgrade and check scripts to run
+in a privileged fashion while the rest of wpantund runs
+with lower privileges. The idea is that wpantund would be
+run initially in a privileged context and then, after
+setting up this object, drop privileges.
+
+There are other places where we will likely want to have
+this sort of behavior (meaning that this doesn't yield any
+immediate increase in security), but this is a good start
+in that direction.
+
+-- RQ 2015-10-23
+
+*/
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "FirmwareUpgrade.h"
+#include "socket-utils.h"
+#include <errno.h>
+#include <syslog.h>
+#include "fgetln.h"
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+
+#if HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+using namespace nl::wpantund;
+
+FirmwareUpgrade::FirmwareUpgrade(): mUpgradeStatus(0), mFirmwareCheckFD(-1), mFirmwareUpgradeFD(-1)
+{
+}
+
+FirmwareUpgrade::~FirmwareUpgrade()
+{
+	close_check_fd();
+	close_upgrade_fd();
+}
+
+void
+FirmwareUpgrade::close_check_fd(void)
+{
+	if (mFirmwareCheckFD >= 0) {
+		IGNORE_RETURN_VALUE(write(mFirmwareCheckFD, "X\n", 1));
+		close(mFirmwareCheckFD);
+		mFirmwareCheckFD = -1;
+	}
+}
+
+void
+FirmwareUpgrade::close_upgrade_fd(void)
+{
+	if (mFirmwareUpgradeFD >= 0) {
+		IGNORE_RETURN_VALUE(write(mFirmwareUpgradeFD, "X", 1));
+		close(mFirmwareUpgradeFD);
+		mFirmwareUpgradeFD = -1;
+	}
+}
+
+bool
+FirmwareUpgrade::is_firmware_upgrade_required(const std::string& version)
+{
+	bool ret = false;
+	uint8_t c = 1;
+
+	require(!version.empty(), bail);
+
+	require_quiet(mFirmwareCheckFD >= 0, bail);
+
+	require_string(write(mFirmwareCheckFD, version.c_str(), version.size()) >= 0, bail, strerror(errno));
+
+	require_string(write(mFirmwareCheckFD, "\n", 1) == 1, bail, strerror(errno));
+
+	require_string(read(mFirmwareCheckFD, &c, 1) == 1, bail, strerror(errno));
+
+	ret = (c == 0);
+
+bail:
+
+	// If this check determined that a firmware upgrade was not required,
+	// go ahead and close out our check process so that we don't
+	// waste resources.
+	if (ret == false) {
+		close_check_fd();
+		close_upgrade_fd();
+	}
+
+	return ret;
+}
+
+void
+FirmwareUpgrade::upgrade_firmware(void)
+{
+	require(mUpgradeStatus != EINPROGRESS, bail);
+
+	mUpgradeStatus = EINVAL;
+
+	require(mFirmwareUpgradeFD >= 0, bail);
+
+	require_string(write(mFirmwareUpgradeFD, "1", 1) == 1, bail, strerror(errno));
+
+	mUpgradeStatus = EINPROGRESS;
+
+bail:
+	return;
+}
+
+void
+FirmwareUpgrade::set_firmware_upgrade_command(const std::string& command)
+{
+	int status = -1;
+	pid_t pid = -1;
+
+	if (mFirmwareUpgradeFD >= 0) {
+		close(mFirmwareUpgradeFD);
+		mFirmwareUpgradeFD = -1;
+	}
+
+	pid = fork_unixdomain_socket(&mFirmwareUpgradeFD);
+
+	if (pid < 0) {
+		return;
+	}
+
+	if (pid == 0) {
+		int stdout_fd_copy = dup(STDOUT_FILENO);
+		int stdin_fd_copy = dup(STDIN_FILENO);
+		FILE* stdin_copy = NULL;
+		FILE* stdout_copy = NULL;
+
+		dup2(STDERR_FILENO,STDOUT_FILENO);
+		close(STDIN_FILENO);
+
+		if (stdin_fd_copy >= 0) {
+			stdin_copy = fdopen(stdin_fd_copy, "r");
+		}
+
+		if (stdout_fd_copy >= 0) {
+			stdout_copy = fdopen(stdout_fd_copy, "w");
+		}
+
+		// Double fork to avoid leaking zombie processes.
+		pid = fork();
+		if (pid < 0) {
+			syslog(LOG_ERR, "Call to fork() failed: %s (%d)", strerror(errno), errno);
+
+			_exit(errno);
+		}
+
+		if (0 == pid)
+		{
+			// Set the shell environment variable if it isn't set already.
+			setenv("SHELL",SOCKET_UTILS_DEFAULT_SHELL,0);
+
+			while ((ferror(stdin_copy) == 0) && (feof(stdin_copy) == 0)) {
+				int c;
+				int ret;
+
+				c = fgetc(stdin_copy);
+
+				switch (c) {
+				case '1':
+					// Go ahead and leave the parent's process group
+					setsid();
+
+					// Execute the requested command.
+					ret = system(command.c_str());
+
+					// Inform our parent process of the return value for the command.
+					fputc(WEXITSTATUS(ret), stdout_copy);
+					fflush(stdout_copy);
+					break;
+
+				case 'X':
+					fputc(0, stdout_copy);
+					fflush(stdout_copy);
+					_exit(EXIT_SUCCESS);
+					break;
+
+				default:
+					fputc(1, stdout_copy);
+					fflush(stdout_copy);
+					_exit(EXIT_FAILURE);
+					break;
+				}
+			}
+
+			_exit(EXIT_FAILURE);
+		}
+
+		_exit(EXIT_SUCCESS);
+	}
+
+	// Wait for the first fork to return, and place the return value in errno
+	if (waitpid(pid, &status, 0) < 0) {
+		syslog(LOG_ERR, "Call to waitpid() failed: %s (%d)", strerror(errno), errno);
+	}
+
+	if (0 != WEXITSTATUS(status)) {
+		// If this has happened then the double fork failed. Clean up
+		// and pass this status along to the caller as errno.
+
+		syslog(LOG_ERR, "Child process failed: %s (%d)", strerror(WEXITSTATUS(status)), WEXITSTATUS(status));
+
+		close(mFirmwareUpgradeFD);
+		mFirmwareUpgradeFD = -1;
+
+		errno = WEXITSTATUS(status);
+
+	} else {
+		int saved_flags = fcntl(mFirmwareUpgradeFD, F_GETFL, 0);
+		fcntl(mFirmwareUpgradeFD, F_SETFL, saved_flags | O_NONBLOCK);
+	}
+}
+
+void
+FirmwareUpgrade::set_firmware_check_command(const std::string& command)
+{
+	int status = -1;
+	pid_t pid = -1;
+
+	if (mFirmwareCheckFD >= 0) {
+		close(mFirmwareCheckFD);
+		mFirmwareCheckFD = -1;
+	}
+
+	pid = fork_unixdomain_socket(&mFirmwareCheckFD);
+
+	if (pid < 0) {
+		return;
+	}
+
+	if (pid == 0) {
+		int stdout_fd_copy = dup(STDOUT_FILENO);
+		int stdin_fd_copy = dup(STDIN_FILENO);
+		FILE* stdin_copy = NULL;
+		FILE* stdout_copy = NULL;
+
+		dup2(STDERR_FILENO,STDOUT_FILENO);
+
+		if (stdin_fd_copy >= 0) {
+			close(STDIN_FILENO);
+			stdin_copy = fdopen(stdin_fd_copy, "r");
+		}
+
+		if (stdout_fd_copy >= 0) {
+			stdout_copy = fdopen(stdout_fd_copy, "w");
+		}
+
+		// Double fork to avoid leaking zombie processes.
+		pid = fork();
+		if (pid < 0) {
+			syslog(LOG_ERR, "Call to fork() failed: %s (%d)", strerror(errno), errno);
+
+			_exit(errno);
+		}
+
+		if (0 == pid)
+		{
+			// Set the shell environment variable if it isn't set already.
+			setenv("SHELL",SOCKET_UTILS_DEFAULT_SHELL,0);
+
+			while ((ferror(stdin_copy) == 0) && (feof(stdin_copy) == 0)) {
+				int ret;
+				const char* line = NULL;
+				size_t line_len = 0;
+				std::string escaped_line;
+
+				line = fgetln(stdin_copy, &line_len);
+
+				if (!line || (line_len == 0)) {
+					continue;
+				}
+
+				if ((line[0] == 'X') && (line[1] == 0)) {
+					fputc(0, stdout_copy);
+					fflush(stdout_copy);
+					_exit(EXIT_SUCCESS);
+				}
+
+				// Open quotation
+				escaped_line = " '";
+
+				// Sanitize and escape the string
+				for(;line_len != 0;line_len--, line++) {
+					char c = *line;
+					if ((c < 32) && (c != '\t') && (c != '\n') && (c != '\r')) {
+						// Control characters aren't allowed.
+						syslog(LOG_ERR, "FirmwareCheck: Prohibited character (%d) in version string", c);
+						fputc('E', stdout_copy);
+						fflush(stdout_copy);
+						_exit(EXIT_FAILURE);
+					}
+					switch (c) {
+					case '\'':
+						escaped_line += "'\''";
+						break;
+					case '\n':
+					case '\r':
+						break;
+					default:
+						escaped_line += c;
+						break;
+					}
+				}
+
+				// Close quotation
+				escaped_line += "'";
+
+				ret = system((command + escaped_line).c_str());
+
+				fputc(WEXITSTATUS(ret), stdout_copy);
+				fflush(stdout_copy);
+			}
+
+			_exit(EXIT_FAILURE);
+		}
+
+		_exit(EXIT_SUCCESS);
+	}
+
+	// Wait for the first fork to return, and place the return value in errno
+	if (waitpid(pid, &status, 0) < 0) {
+		syslog(LOG_ERR, "Call to waitpid() failed: %s (%d)", strerror(errno), errno);
+	}
+
+	if (0 != WEXITSTATUS(status)) {
+		// If this has happened then the double fork failed. Clean up
+		// and pass this status along to the caller as errno.
+
+		syslog(LOG_ERR, "Child process failed: %s (%d)", strerror(WEXITSTATUS(status)), WEXITSTATUS(status));
+
+		close(mFirmwareCheckFD);
+		mFirmwareCheckFD = -1;
+
+		errno = WEXITSTATUS(status);
+	}
+}
+
+bool
+FirmwareUpgrade::can_upgrade_firmware(void)
+{
+	return (mFirmwareUpgradeFD >= 0);
+}
+
+int
+FirmwareUpgrade::get_upgrade_status(void)
+{
+	return mUpgradeStatus;
+}
+
+int
+FirmwareUpgrade::update_fd_set(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *error_fd_set, int *max_fd, cms_t *timeout)
+{
+	if ((mUpgradeStatus == EINPROGRESS) && (mFirmwareUpgradeFD >= 0)) {
+		if (read_fd_set != NULL) {
+			FD_SET(mFirmwareUpgradeFD, read_fd_set);
+		}
+		if (error_fd_set != NULL) {
+			FD_SET(mFirmwareUpgradeFD, error_fd_set);
+		}
+		if (max_fd != NULL) {
+			*max_fd = std::max(*max_fd, mFirmwareUpgradeFD);
+		}
+	}
+
+	return 0;
+}
+
+void
+FirmwareUpgrade::process(void)
+{
+	if (mUpgradeStatus == EINPROGRESS) {
+		ssize_t bytes_read;
+		uint8_t value;
+
+		bytes_read = read(mFirmwareUpgradeFD, &value, 1);
+
+		if ((bytes_read < 0) && (errno != EWOULDBLOCK)) {
+			mUpgradeStatus = errno;
+		} else if (bytes_read == 1) {
+			mUpgradeStatus = value;
+
+			// If the upgrade status was successful, go ahead and close
+			// down both checks so that we don't waste resources. This
+			// also has the added benefit of preventing upgrade loops.
+			if (mUpgradeStatus == 0) {
+				close_check_fd();
+				close_upgrade_fd();
+			}
+		}
+	}
+}
diff --git a/src/wpantund/FirmwareUpgrade.h b/src/wpantund/FirmwareUpgrade.h
new file mode 100644
index 0000000..33d1e83
--- /dev/null
+++ b/src/wpantund/FirmwareUpgrade.h
@@ -0,0 +1,69 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Firmware Upgrade Manager
+ *
+ */
+
+#ifndef __wpantund__FirmwareUpgrade__
+#define __wpantund__FirmwareUpgrade__
+
+#include <stdio.h>
+#include <sys/select.h>
+#include <string>
+#include "time-utils.h"
+
+namespace nl {
+namespace wpantund {
+
+class FirmwareUpgrade {
+public:
+	FirmwareUpgrade();
+	~FirmwareUpgrade();
+
+	bool is_firmware_upgrade_required(const std::string& version);
+	void upgrade_firmware(void);
+
+	void set_firmware_upgrade_command(const std::string& command);
+	void set_firmware_check_command(const std::string& command);
+
+	// May return:
+	//  * `0`: An upgrade was not started or the upgrade completed successfully.
+	//	* `EINPROGRESS`: An upgrade is currently in process.
+	//  * Any Other Value: An error occured when attempting to upgrade.
+	int get_upgrade_status(void);
+
+	int update_fd_set(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *error_fd_set, int *max_fd, cms_t *timeout);
+	void process(void);
+
+	bool can_upgrade_firmware(void);
+
+private:
+	void close_check_fd(void);
+	void close_upgrade_fd(void);
+
+private:
+	int mUpgradeStatus;
+	int mFirmwareCheckFD;
+	int mFirmwareUpgradeFD;
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+#endif /* defined(__wpantund__FirmwareUpgrade__) */
diff --git a/src/wpantund/IPCServer.h b/src/wpantund/IPCServer.h
new file mode 100644
index 0000000..895234a
--- /dev/null
+++ b/src/wpantund/IPCServer.h
@@ -0,0 +1,46 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef wpantund_ipc_server_h
+#define wpantund_ipc_server_h
+
+#include <sys/select.h>
+#include <unistd.h>
+#include "time-utils.h"
+
+namespace nl {
+namespace wpantund {
+
+class NCPControlInterface;
+
+class IPCServer {
+public:
+	virtual ~IPCServer() {}
+	virtual cms_t get_ms_to_next_event(void) = 0;
+	virtual void process(void) = 0;
+
+	virtual int update_fd_set(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *error_fd_set, int *max_fd, cms_t *timeout) = 0;
+
+	virtual int add_interface(NCPControlInterface* instance) = 0;
+};
+
+};
+};
+
+#endif
diff --git a/src/wpantund/Makefile.am b/src/wpantund/Makefile.am
new file mode 100644
index 0000000..12c2858
--- /dev/null
+++ b/src/wpantund/Makefile.am
@@ -0,0 +1,120 @@
+#
+# Copyright (c) 2016 Nest Labs, Inc.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)/src \
+	-I$(top_srcdir)/src/util \
+	-I$(top_srcdir)/src/ipc-dbus \
+	-I$(top_srcdir)/third_party/fgetln \
+	-I$(top_srcdir)/third_party/pt \
+	-I$(top_srcdir)/third_party/assert-macros \
+	$(NULL)
+
+DISTCLEANFILES = \
+	.deps \
+	Makefile \
+	$(NULL)
+
+EXTRA_DIST = \
+	wpantund.conf \
+	$(NULL)
+
+pkginclude_HEADERS = \
+	wpan-properties.h \
+	wpan-error.h \
+	$(NULL)
+
+sysconf_DATA = wpantund.conf
+
+sbin_PROGRAMS = wpantund
+
+wpantund_SOURCES = \
+	wpantund.cpp \
+	wpantund.h \
+	IPCServer.h \
+	NCPConstants.h \
+	NCPControlInterface.cpp \
+	NCPControlInterface.h \
+	NCPInstance.cpp \
+	NCPInstance.h \
+	NCPInstanceBase.cpp \
+	NCPInstanceBase.h \
+	NCPMfgInterface_v0.h \
+	NCPMfgInterface_v1.h \
+	NetworkInstance.h \
+	NCPConstants.h \
+	FirmwareUpgrade.h \
+	FirmwareUpgrade.cpp \
+	StatCollector.h \
+	StatCollector.cpp \
+	RunawayResetBackoffManager.cpp \
+	RunawayResetBackoffManager.h \
+	NCPInstanceBase-NetInterface.cpp \
+	NCPInstanceBase-Addresses.cpp \
+	NCPInstanceBase-AsyncIO.cpp \
+	NCPTypes.h \
+	NCPTypes.cpp \
+	NetworkRetain.h \
+	NetworkRetain.cpp \
+	Pcap.h \
+	Pcap.cpp \
+	../util/IPv6PacketMatcher.cpp \
+	../util/IPv6Helpers.cpp \
+	../util/tunnel.c \
+	../util/config-file.c \
+	../util/socket-utils.c \
+	../util/any-to.cpp \
+	../util/string-utils.c \
+	../util/time-utils.c \
+	../util/nlpt-select.c \
+	../util/Data.cpp \
+	../util/SocketWrapper.cpp \
+	../util/SocketAdapter.cpp \
+	../util/UnixSocket.cpp \
+	../util/SuperSocket.cpp \
+	../util/EventHandler.cpp \
+	../util/TunnelIPv6Interface.cpp \
+	../util/ValueMap.cpp \
+	../util/Timer.cpp \
+	../util/sec-random.c \
+	$(NULL)
+
+wpantund_LDADD =  $(DBUS_LIBS)
+wpantund_LDADD += ../ipc-dbus/libwpantund-dbus.la
+
+if STATIC_LINK_NCP_PLUGIN
+wpantund_LDADD += ../ncp-@default_ncp_plugin@/libncp-@default_ncp_plugin@.la
+else
+wpantund_LDADD += $(LIBDL_LIBS)
+wpantund_LDFLAGS = @EXPORT_DYNAMIC_LDFLAGS@
+endif
+
+wpantund_CPPFLAGS = $(AM_CPPFLAGS) $(DBUS_CFLAGS)
+wpantund_CXXFLAGS = $(BOOST_CXXFLAGS)
+
+SOURCE_VERSION=$(shell                                            \
+	git describe --dirty --always --match "[0-9].*" 2> /dev/null  \
+)
+
+BUILT_SOURCES  = $(top_builddir)/$(subdir)/version.c
+CLEANFILES     = $(top_builddir)/$(subdir)/version.c
+.INTERMEDIATE:   wpantund-version.$(OBJEXT)
+
+$(top_builddir)/$(subdir)/version.c: ../version.c.in Makefile
+	sed 's/SOURCE_VERSION/"$(SOURCE_VERSION)"/' < $< > $@
+
+wpantund_SOURCES += $(top_builddir)/$(subdir)/version.c
diff --git a/src/wpantund/NCPConstants.h b/src/wpantund/NCPConstants.h
new file mode 100644
index 0000000..311b199
--- /dev/null
+++ b/src/wpantund/NCPConstants.h
@@ -0,0 +1,37 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef wpantund_NCPConstants_h
+#define wpantund_NCPConstants_h
+
+#define NCP_DEFAULT_COMMAND_RESPONSE_TIMEOUT    5  // seconds
+#define NCP_DEFAULT_COMMAND_SEND_TIMEOUT        5  // seconds
+#define NCP_TICKLE_TIMEOUT                      60 // seconds
+#define NCP_DEEP_SLEEP_TICKLE_TIMEOUT          (60*70) // Seventy minutes
+#define NCP_FORM_TIMEOUT						60 // seconds
+#define NCP_JOIN_TIMEOUT						30 // seconds
+
+#define NCP_NETWORK_KEY_SIZE         16
+
+#define BUSY_DEBOUNCE_TIME_IN_MS         200
+#define MAX_INSOMNIA_TIME_IN_MS                 (MSEC_PER_SEC * 60 * 3)
+
+#define NCP_DEBUG_LINE_LENGTH_MAX		400
+
+#endif
diff --git a/src/wpantund/NCPControlInterface.cpp b/src/wpantund/NCPControlInterface.cpp
new file mode 100644
index 0000000..19176be
--- /dev/null
+++ b/src/wpantund/NCPControlInterface.cpp
@@ -0,0 +1,409 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *		Abstract base class for NCP implementations.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include "NCPControlInterface.h"
+#include "NCPInstance.h"
+#include "tunnel.h"
+#include <syslog.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <boost/bind.hpp>
+#include "version.h"
+#include "any-to.h"
+#include "wpan-error.h"
+
+#ifndef SOURCE_VERSION
+#define SOURCE_VERSION		PACKAGE_VERSION
+#endif
+
+using namespace nl;
+using namespace wpantund;
+
+std::string
+NCPControlInterface::external_route_priority_to_string(ExternalRoutePriority route_priority)
+{
+	switch(route_priority) {
+		case ROUTE_LOW_PREFRENCE:
+			return std::string("low preference");
+
+		case ROUTE_MEDIUM_PREFERENCE:
+			return std::string("Medium (normal) preference");
+
+		case ROUTE_HIGH_PREFERENCE:
+			return std::string("High preference");
+	}
+	return std::string("Unknown route preference");
+}
+
+NCPControlInterface::~NCPControlInterface() {
+}
+
+struct GetPropertyHelper {
+	boost::any *dest;
+	bool *          didFire;
+
+	void operator()(
+	    int status, const boost::any& value
+	    ) const
+	{
+		if (dest) {
+			if (status == 0)
+				*dest = value;
+			*didFire = true;
+		}
+		delete this;
+	}
+};
+
+boost::any
+NCPControlInterface::get_property(const std::string& key)
+{
+	// In this function, we want to immediately return the value
+	// for the given key. Since the actual get_property() function
+	// returns the value as a callback, we may not actually
+	// be able to do this. What we do here is give a callback
+	// object that contains a pointer to our return value.
+	// After we call get_property(), we then zero out that
+	// pointer. For properties which get updated immediately, our
+	// return value will be updated automatically. For properties
+	// which can't be fetched immediately, we return an empty value.
+	// The "GetPropertyHelper" class makes sure that when the
+	// callback eventually does fire that it doesn't break anything.
+
+	boost::any ret;
+	bool didFire = false;
+	struct GetPropertyHelper *helper = new GetPropertyHelper;
+
+	helper->dest = &ret;
+	helper->didFire = &didFire;
+	get_property(key, boost::bind(&GetPropertyHelper::operator(),
+	                              helper,
+	                              _1,
+	                              _2));
+	if (!didFire) {
+		helper->dest = 0;
+		helper->didFire = 0;
+	}
+	return ret;
+}
+
+std::string
+NCPControlInterface::get_name() {
+	return boost::any_cast<std::string>(get_property(kWPANTUNDProperty_ConfigTUNInterfaceName));
+}
+
+
+struct SetPropertyHelper {
+	int* dest;
+	bool* didFire;
+
+	void operator()(int status) const
+	{
+		if (dest) {
+			*dest = status;
+			*didFire = true;
+		}
+		delete this;
+	}
+};
+
+#define kWPANTUNDPropertyNCPSocketName             "NCPSocketName"
+#define kWPANTUNDPropertyNCPSocketBaud             "NCPSocketBaud"
+#define kWPANTUNDPropertyNCPDriverName             "NCPDriverName"
+#define kWPANTUNDPropertyNCPHardResetPath          "NCPHardResetPath"
+#define kWPANTUNDPropertyNCPPowerPath              "NCPPowerPath"
+#define kWPANTUNDPropertyWPANInterfaceName         "WPANInterfaceName"
+#define kWPANTUNDPropertyPIDFile                   "PIDFile"
+#define kWPANTUNDPropertyFirmwareCheckCommand      "FirmwareCheckCommand"
+#define kWPANTUNDPropertyFirmwareUpgradeCommand    "FirmwareUpgradeCommand"
+#define kWPANTUNDPropertyTerminateOnFault          "TerminateOnFault"
+#define kWPANTUNDPropertyPrivDropToUser            "PrivDropToUser"
+#define kWPANTUNDPropertyChroot                    "Chroot"
+#define kWPANTUNDPropertyNCPReliabilityLayer       "NCPReliabilityLayer"
+
+// Version Properties
+#define kWPANTUNDPropertyNCPVersion                "NCPVersion"
+#define kWPANTUNDPropertyDriverVersion             "DriverVersion"
+
+// Driver State Properties
+#define kWPANTUNDPropertyAssociationState          "AssociationState"    // [RO]
+#define kWPANTUNDPropertyEnabled                   "Enabled"             // [RW]
+#define kWPANTUNDPropertyAutoresume                "AutoResume"          // [RW]
+#define kWPANTUNDPropertyAutoUpdateFirmware        "AutoUpdateFirmware"  // [RW]
+
+// PHY-layer parameters
+#define kWPANTUNDPropertyHWAddr                    "HWAddr"
+#define kWPANTUNDPropertyChannel                   "Channel"
+#define kWPANTUNDPropertyTXPower                   "TXPower"
+#define kWPANTUNDPropertyNCPTXPowerLimit           "NCPTXPowerLimit"
+#define kWPANTUNDPropertyCCAThreshold              "CCAThreshold"
+#define kWPANTUNDPropertyDefaultChannelMask        "DefaultChannelMask"
+
+// MAC-layer (and higher) parameters
+#define kWPANTUNDPropertyNetworkName               "NetworkName"         // [RO]
+#define kWPANTUNDPropertyXPANID                    "XPANID"              // [RO]
+#define kWPANTUNDPropertyPANID                     "PANID"               // [RO]
+#define kWPANTUNDPropertyNodeType                  "NodeType"            // [RW]
+#define kWPANTUNDPropertyNetworkKey                "NetworkKey"          // [RW]
+#define kWPANTUNDPropertyNetworkKeyIndex           "NetworkKeyIndex"     // [RW]
+#define kWPANTUNDPropertyMeshLocalPrefix           "MeshLocalPrefix"     // [RO]
+#define kWPANTUNDPropertyAllowingJoin              "AllowingJoin"        // [RO]
+#define kWPANTUNDPropertyIsAssociated              "IsAssociated"        // [RO]
+
+// Power Management Properties
+#define kWPANTUNDPropertyIsOKToSleep               "IsOKToSleep"
+#define kWPANTUNDPropertyUseDeepSleepOnLowPower    "UseDeepSleepOnLowPower"
+#define kWPANTUNDPropertyAlwaysResetToWake         "AlwaysResetToWake"
+#define kWPANTUNDPropertyAutoDeepSleep             "AutoDeepSleep"
+#define kWPANTUNDPropertySleepPollInterval         "SleepPollInterval"
+
+// Debugging and logging
+#define kWPANTUNDPropertySyslogMask                "SyslogMask"
+#define kWPANTUNDPropertyNCPDebug                  "NCPDebug"
+
+// Properties related to manufacturing test commands
+#define kWPANTUNDPropertyMfgTestMode               "MfgTestMode"
+#define kWPANTUNDPropertyMfgSYNOffset              "MfgSYNOffset"
+#define kWPANTUNDPropertyMfgRepeatRandomTXInterval "MfgRepeatRandomTXInterval"
+#define kWPANTUNDPropertyMfgRepeatRandomTXLen      "MfgRepeatRandomTXLen"
+#define kWPANTUNDPropertyMfgFirstPacketRSSI        "MfgFirstPacketRSSI"
+#define kWPANTUNDPropertyMfgFirstPacketLQI         "MfgFirstPacketLQI"
+
+
+// Nest-Specific Properties
+#define kWPANTUNDPropertyPassthruPort              "PassthruPort"
+#define kWPANTUNDPropertyTransmitHookActive        "TransmitHookActive"
+#define kWPANTUNDPropertyUseLegacyChannel          "UseLegacyChannel"
+#define kWPANTUNDPropertyLegacyPrefix              "LegacyPrefix"
+#define kWPANTUNDPropertyNetWakeData               "NetWakeData"
+#define kWPANTUNDPropertyNetWakeRemaining          "NetWakeRemaining"
+#define kWPANTUNDPropertyActiveWakeupBlacklist     "ActiveWakeupBlacklist"
+#define kWPANTUNDPropertyLegacyInterfaceEnabled    "LegacyInterfaceEnabled"
+#define kWPANTUNDPropertyPrefix                    "Prefix"
+
+#define kWPANTUNDPropertyGlobalIPAddresses         "GlobalIPAddresses"
+#define kWPANTUNDPropertyGlobalIPAddressList       "GlobalIPAddressList"
+
+int
+NCPControlInterface::set_property(const std::string& key, const boost::any& value)
+{
+	// In this function, we want to immediately return the status
+	// of the set operation. Since the actual set_property() function
+	// returns the status as a callback, we may not actually
+	// be able to do this. What we do here is give a callback
+	// object that contains a pointer to our return value.
+	// After we call set_property(), we then zero out that
+	// pointer. For properties which get updated immediately, our
+	// return value will be updated automatically. For properties
+	// which can't be fetched immediately, we return -EINPROGRESS.
+	// The "SetPropertyHelper" class makes sure that when the
+	// callback eventually does fire that it doesn't break anything.
+
+	int ret = kWPANTUNDStatus_InProgress;
+	bool didFire = false;
+	struct SetPropertyHelper *helper = new SetPropertyHelper;
+
+	helper->dest = &ret;
+	helper->didFire = &didFire;
+	set_property(key, value, boost::bind(&SetPropertyHelper::operator(),
+	                              helper,
+	                              _1));
+	if (!didFire) {
+		helper->dest = 0;
+		helper->didFire = 0;
+	}
+	return ret;
+}
+
+
+bool
+NCPControlInterface::translate_deprecated_property(std::string& key, boost::any& value)
+{
+	bool ret = false;
+	if (strcaseequal(key.c_str(), kWPANTUNDPropertyPrefix)) {
+		key = kWPANTUNDProperty_IPv6MeshLocalPrefix;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyNCPSocketName )) {
+		key =  kWPANTUNDProperty_ConfigNCPSocketPath ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyNCPSocketBaud )) {
+		key =  kWPANTUNDProperty_ConfigNCPSocketBaud ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyNCPDriverName )) {
+		key =  kWPANTUNDProperty_ConfigNCPDriverName ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyNCPHardResetPath )) {
+		key =  kWPANTUNDProperty_ConfigNCPHardResetPath ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyNCPPowerPath )) {
+		key =  kWPANTUNDProperty_ConfigNCPPowerPath ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyWPANInterfaceName )) {
+		key =  kWPANTUNDProperty_ConfigTUNInterfaceName ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyPIDFile )) {
+		key =  kWPANTUNDProperty_ConfigDaemonPIDFile ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyFirmwareCheckCommand )) {
+		key =  kWPANTUNDProperty_ConfigNCPFirmwareCheckCommand ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyFirmwareUpgradeCommand )) {
+		key =  kWPANTUNDProperty_ConfigNCPFirmwareUpgradeCommand ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyTerminateOnFault )) {
+		key =  kWPANTUNDProperty_DaemonTerminateOnFault ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyPrivDropToUser )) {
+		key =  kWPANTUNDProperty_ConfigDaemonPrivDropToUser ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyChroot )) {
+		key =  kWPANTUNDProperty_ConfigDaemonChroot ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyNCPReliabilityLayer )) {
+		key =  kWPANTUNDProperty_ConfigNCPReliabilityLayer ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyNCPVersion )) {
+		key =  kWPANTUNDProperty_NCPVersion ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyDriverVersion )) {
+		key =  kWPANTUNDProperty_DaemonVersion ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyAssociationState )) {
+		key =  kWPANTUNDProperty_NCPState ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyEnabled )) {
+		key =  kWPANTUNDProperty_DaemonEnabled ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyAutoresume )) {
+		key =  kWPANTUNDProperty_DaemonAutoAssociateAfterReset ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyAutoUpdateFirmware )) {
+		key =  kWPANTUNDProperty_DaemonAutoFirmwareUpdate ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyHWAddr )) {
+		key =  kWPANTUNDProperty_NCPHardwareAddress ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyChannel )) {
+		key =  kWPANTUNDProperty_NCPChannel ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyTXPower )) {
+		key =  kWPANTUNDProperty_NCPTXPower ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyNCPTXPowerLimit )) {
+		key =  kWPANTUNDProperty_NCPTXPowerLimit ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyCCAThreshold )) {
+		key =  kWPANTUNDProperty_NCPCCAThreshold ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyDefaultChannelMask )) {
+		key =  kWPANTUNDProperty_NCPChannelMask ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyNetworkName )) {
+		key =  kWPANTUNDProperty_NetworkName ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyXPANID )) {
+		key =  kWPANTUNDProperty_NetworkXPANID ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyPANID )) {
+		key =  kWPANTUNDProperty_NetworkPANID ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyNodeType )) {
+		key =  kWPANTUNDProperty_NetworkNodeType ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyNetworkKey )) {
+		key =  kWPANTUNDProperty_NetworkKey ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyNetworkKeyIndex )) {
+		key =  kWPANTUNDProperty_NetworkKeyIndex ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyMeshLocalPrefix )) {
+		key =  kWPANTUNDProperty_IPv6MeshLocalPrefix ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyAllowingJoin )) {
+		key =  kWPANTUNDProperty_NestLabs_NetworkAllowingJoin ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyIsAssociated )) {
+		key =  kWPANTUNDProperty_NetworkIsCommissioned ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyIsOKToSleep )) {
+		key =  kWPANTUNDProperty_DaemonReadyForHostSleep ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyUseDeepSleepOnLowPower )) {
+		key =  kWPANTUNDProperty_NestLabs_HackUseDeepSleepOnLowPower ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyAlwaysResetToWake )) {
+		key =  kWPANTUNDProperty_NestLabs_HackAlwaysResetToWake ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyAutoDeepSleep )) {
+		key =  kWPANTUNDProperty_DaemonAutoDeepSleep ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertySleepPollInterval )) {
+		key =  kWPANTUNDProperty_NCPSleepyPollInterval ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertySyslogMask )) {
+		key =  kWPANTUNDProperty_DaemonSyslogMask ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyPassthruPort )) {
+		key =  kWPANTUNDProperty_NestLabs_NetworkPassthruPort ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyTransmitHookActive )) {
+		key =  kWPANTUNDProperty_NestLabs_NCPTransmitHookActive ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyLegacyPrefix )) {
+		key =  kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyNetWakeData )) {
+		key =  kWPANTUNDProperty_NestLabs_NetworkWakeData ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyNetWakeRemaining )) {
+		key =  kWPANTUNDProperty_NestLabs_NetworkWakeRemaining ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyActiveWakeupBlacklist ) || strcaseequal(key.c_str(), "ActiveWakeupMask")) {
+		key =  kWPANTUNDProperty_NestLabs_NetworkWakeBlacklist ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyLegacyInterfaceEnabled )) {
+		key =  kWPANTUNDProperty_NestLabs_LegacyEnabled ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyUseLegacyChannel )) {
+		key =  kWPANTUNDProperty_NestLabs_LegacyPreferInterface ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyGlobalIPAddresses )) {
+		key =  kWPANTUNDProperty_IPv6AllAddresses ;
+		ret = true;
+	} else if (strcaseequal(key.c_str(),  kWPANTUNDPropertyGlobalIPAddressList )) {
+		key =  kWPANTUNDProperty_DebugIPv6GlobalIPAddressList ;
+		ret = true;
+	}
+	return ret;
+}
+
+bool
+NCPControlInterface::translate_deprecated_property(std::string& key)
+{
+	boost::any unused;
+	return translate_deprecated_property(key, unused);
+}
diff --git a/src/wpantund/NCPControlInterface.h b/src/wpantund/NCPControlInterface.h
new file mode 100644
index 0000000..5e65490
--- /dev/null
+++ b/src/wpantund/NCPControlInterface.h
@@ -0,0 +1,254 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef wpantund_WPAN_NCPControlInterface_h
+#define wpantund_WPAN_NCPControlInterface_h
+
+#ifndef __STDC_CONSTANT_MACROS
+#define __STDC_CONSTANT_MACROS 1
+#endif
+
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <boost/signals2/signal.hpp>
+#include <boost/any.hpp>
+#include <list>
+#include <arpa/inet.h>
+#include "time-utils.h"
+
+#include <pthread.h>
+
+#include "NetworkInstance.h"
+#include "NCPTypes.h"
+#include <cstring>
+#include "IPv6PacketMatcher.h"
+#include "Data.h"
+#include "NilReturn.h"
+#include "NCPConstants.h"
+#include "Callbacks.h"
+#include "wpan-properties.h"
+#include "ValueMap.h"
+
+namespace nl {
+namespace wpantund {
+
+#define USE_DEFAULT_TX_POWER               INT32_MIN
+#define USE_DEFAULT_CCA_THRESHOLD          INT32_MIN
+#define USE_DEFAULT_TX_POWER_MODE          INT32_MIN
+#define USE_DEFAULT_TRANSMIT_HOOK_ACTIVE   INT32_MIN
+
+typedef std::set<int> IntegerSet;
+
+class NCPInstance;
+
+class NCPControlInterface {
+public:
+
+	typedef uint32_t ChannelMask;
+
+	enum ExternalRoutePriority {
+		ROUTE_LOW_PREFRENCE = -1,
+		ROUTE_MEDIUM_PREFERENCE = 0,
+		ROUTE_HIGH_PREFERENCE = 1,
+	};
+
+public:
+	// ========================================================================
+	// Static Functions
+
+
+	static std::string external_route_priority_to_string(ExternalRoutePriority route_priority);
+
+public:
+	// ========================================================================
+	// Public Virtual Member Functions
+
+	//! Returns the network instance currently associated with the NCP.
+	virtual const WPAN::NetworkInstance& get_current_network_instance(void)const = 0;
+
+public:
+	// ========================================================================
+	// NCP Command Virtual Member Functions
+
+	virtual void join(
+		const ValueMap& options,
+	    CallbackWithStatus cb = NilReturn()
+	) = 0;
+
+	virtual void form(
+		const ValueMap& options,
+	    CallbackWithStatus cb = NilReturn()
+	) = 0;
+
+	virtual void leave(CallbackWithStatus cb = NilReturn()) = 0;
+
+	virtual void attach(CallbackWithStatus cb = NilReturn()) = 0;
+
+	virtual void reset(CallbackWithStatus cb = NilReturn()) = 0;
+
+	virtual void refresh_state(CallbackWithStatus cb = NilReturn()) = 0;
+
+	virtual void get_property(
+	    const std::string& key,
+	    CallbackWithStatusArg1 cb
+	) = 0;
+
+	virtual void set_property(
+	    const std::string& key,
+	    const boost::any& value,
+	    CallbackWithStatus cb
+	) = 0;
+
+	virtual void add_on_mesh_prefix(
+		const struct in6_addr *prefix,
+		bool defaultRoute,
+		CallbackWithStatus cb = NilReturn()
+	) = 0;
+
+	virtual void remove_on_mesh_prefix(
+		const struct in6_addr *prefix,
+		CallbackWithStatus cb = NilReturn()
+	) = 0;
+
+	virtual void add_external_route(
+		const struct in6_addr *prefix,
+		int prefix_len_in_bits,
+		int domain_id,
+		ExternalRoutePriority priority,
+		CallbackWithStatus cb = NilReturn()
+	) = 0;
+
+	virtual void remove_external_route(
+		const struct in6_addr *prefix,
+		int prefix_len_in_bits,
+		int domain_id,
+		CallbackWithStatus cb = NilReturn()
+	) = 0;
+
+	virtual void pcap_to_fd(
+		int fd,
+		CallbackWithStatus cb = NilReturn()
+	) = 0;
+
+	virtual void pcap_terminate(
+		CallbackWithStatus cb = NilReturn()
+	) = 0;
+
+public:
+	// ========================================================================
+	// Scan-related Member Functions
+
+	virtual void netscan_start(const ValueMap& options, CallbackWithStatus cb = NilReturn()) = 0;
+
+	virtual void netscan_stop(CallbackWithStatus cb = NilReturn()) = 0;
+
+	boost::signals2::signal<void(const WPAN::NetworkInstance&)> mOnNetScanBeacon;
+
+public:
+	// ========================================================================
+	// EnergyScan-related Member Functions
+
+	virtual void energyscan_start(const ValueMap& options, CallbackWithStatus cb = NilReturn()) = 0;
+
+	virtual void energyscan_stop(CallbackWithStatus cb = NilReturn()) = 0;
+
+	boost::signals2::signal<void(const EnergyScanResultEntry&)> mOnEnergyScanResult;
+
+public:
+	// ========================================================================
+	// Power-related Member Functions
+
+	virtual void begin_low_power(CallbackWithStatus cb = NilReturn()) = 0;
+
+	virtual void host_did_wake(CallbackWithStatus cb = NilReturn()) = 0;
+
+	virtual void data_poll(CallbackWithStatus cb = NilReturn()) = 0;
+
+
+public:
+	// ========================================================================
+	// Nest-Specific Member Functions
+
+	virtual void begin_net_wake(
+		uint8_t data = 0,
+		uint32_t flags = 0,
+		CallbackWithStatus cb = NilReturn()
+	) = 0;
+
+	virtual void permit_join(
+	    int seconds = 15 * 60,
+	    uint8_t commissioning_traffic_type = 0xFF,
+	    in_port_t commissioning_traffic_port = 0,
+	    bool network_wide = false,
+	    CallbackWithStatus cb = NilReturn()
+	) = 0;
+
+
+public:
+	// ========================================================================
+	// Convenience methods
+
+	boost::any get_property(const std::string& key);
+
+	int set_property(const std::string& key, const boost::any& value);
+
+	virtual std::string get_name();
+
+public:
+	// ========================================================================
+	// Other
+
+	static bool translate_deprecated_property(std::string& key, boost::any& value);
+
+	static bool translate_deprecated_property(std::string& key);
+
+
+public:
+	// ========================================================================
+	// Signals
+
+	//! Fires whenever value of certain properties changed (e.g. NodeType).
+	boost::signals2::signal<void(const std::string& key, const boost::any& value)> mOnPropertyChanged;
+
+public:
+	// ========================================================================
+	// Nest-Specific Signals
+
+	//! Fires when the network wake state has changed or been updated.
+	boost::signals2::signal<void(uint8_t data, cms_t ms_remaining)> mOnNetWake;
+
+protected:
+	// ========================================================================
+	// Protected Virtual Member Functions
+
+	virtual ~NCPControlInterface();
+
+	//! Returns the associated NCP instance.
+	virtual NCPInstance& get_ncp_instance(void) = 0;
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+#endif
diff --git a/src/wpantund/NCPInstance.cpp b/src/wpantund/NCPInstance.cpp
new file mode 100644
index 0000000..1b198cc
--- /dev/null
+++ b/src/wpantund/NCPInstance.cpp
@@ -0,0 +1,149 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include "NCPInstance.h"
+#include "tunnel.h"
+#include <syslog.h>
+#include <errno.h>
+
+#ifndef HAVE_DLFCN_H
+#define HAVE_DLFCN_H	defined(__APPLE__)
+#endif
+
+#ifndef PKGLIBEXECDIR
+#define PKGLIBEXECDIR	"/usr/local/libexec/wpantund"
+#endif
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#ifndef RTLD_DEFAULT
+#define RTLD_DEFAULT	((void*)0)
+#endif
+#ifndef RTLD_NEXT
+#define RTLD_NEXT		((void*)-1l)
+#endif
+#endif
+
+#if WPANTUND_PLUGIN_STATICLY_LINKED
+#undef HAVE_DLFCN_H
+#endif
+
+#ifndef WPANTUND_DEFAULT_NCP_PLUGIN
+#if WPANTUND_PLUGIN_STATICLY_LINKED
+#define WPANTUND_DEFAULT_NCP_PLUGIN "default"
+#else
+#define WPANTUND_DEFAULT_NCP_PLUGIN "spinel"
+#endif
+#endif
+
+using namespace nl;
+using namespace wpantund;
+
+typedef nl::wpantund::NCPInstance* (*NCPInstanceAllocatorType)(const nl::wpantund::NCPInstance::Settings& settings);
+
+NCPInstance*
+NCPInstance::alloc(const Settings& settings)
+{
+	NCPInstance* ret = NULL;
+	std::string ncp_driver_name = WPANTUND_DEFAULT_NCP_PLUGIN;
+	std::string symbol_name = "wpantund_ncpinstance_default_alloc";
+	NCPInstanceAllocatorType allocator = NULL;
+
+	if (settings.count(kWPANTUNDProperty_ConfigNCPDriverName)) {
+		ncp_driver_name = settings.find(kWPANTUNDProperty_ConfigNCPDriverName)->second;
+	}
+
+	if (ncp_driver_name == "default") {
+		ncp_driver_name = WPANTUND_DEFAULT_NCP_PLUGIN;
+	}
+
+#if WPANTUND_PLUGIN_STATICLY_LINKED
+	// Statically-linked plugin
+	if ((allocator == NULL) && (ncp_driver_name == WPANTUND_DEFAULT_NCP_PLUGIN)) {
+		allocator = &wpantund_ncpinstance_default_alloc;
+	}
+#else
+	// Dynamically-loaded plugin
+	std::string plugin_path;
+
+	if ((ncp_driver_name.find('/') != std::string::npos)
+	 || (ncp_driver_name.find('.') != std::string::npos)
+	) {
+		plugin_path = ncp_driver_name;
+	} else {
+		plugin_path = std::string("ncp-") + ncp_driver_name + ".so";
+		symbol_name = std::string("wpantund_ncpinstance_") +ncp_driver_name + "_alloc";
+
+		if( access( (std::string(PKGLIBEXECDIR "/") + plugin_path).c_str(), X_OK ) != -1 ) {
+			plugin_path = std::string(PKGLIBEXECDIR "/") + plugin_path;
+		}
+
+		allocator = (NCPInstanceAllocatorType)dlsym(RTLD_DEFAULT, symbol_name.c_str());
+	}
+
+	if (allocator == NULL) {
+		// We failed to immediately look up the allocator function,
+		// so lets see if we can find a plug-in that we can open,
+		// and then try again.
+
+		void* dl_handle = NULL;
+
+		dl_handle = dlopen(plugin_path.c_str(), RTLD_NOW|RTLD_LOCAL);
+
+		if (dl_handle == NULL) {
+			syslog(LOG_ERR, "Couldn't open plugin \"%s\", %s", plugin_path.c_str(), dlerror());
+		} else {
+			allocator = (NCPInstanceAllocatorType)dlsym(dl_handle, symbol_name.c_str());
+		}
+	}
+
+#endif
+
+	require_string(allocator != NULL, bail, "Unknown NCP Driver");
+
+	ret = (*allocator)(settings);
+
+bail:
+	if (ret == NULL) {
+		syslog(LOG_ERR, "Unable to load NCP driver \"%s\".", ncp_driver_name.c_str());
+	}
+
+	return ret;
+}
+
+NCPInstance::~NCPInstance()
+{
+}
+
+void
+NCPInstance::signal_fatal_error(int err)
+{
+	if (err == ERRORCODE_ERRNO) {
+		syslog(LOG_CRIT, "NCPInstance: errno %d \"%s\"\n", errno, strerror(
+				   errno));
+	} else {
+		syslog(LOG_CRIT, "NCPInstance: error %d\n", err);
+	}
+	mOnFatalError(err);
+}
diff --git a/src/wpantund/NCPInstance.h b/src/wpantund/NCPInstance.h
new file mode 100644
index 0000000..62a363b
--- /dev/null
+++ b/src/wpantund/NCPInstance.h
@@ -0,0 +1,122 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__NCPInstance__
+#define __wpantund__NCPInstance__
+
+#define BOOST_SIGNALS_NO_DEPRECATION_WARNING 1
+
+#ifndef __STDC_CONSTANT_MACROS
+#define __STDC_CONSTANT_MACROS 1
+#endif
+
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <stdint.h>
+#include <string>
+#include <vector>
+#include <boost/signals2/signal.hpp>
+#include <boost/any.hpp>
+#include <list>
+#include <arpa/inet.h>
+
+#include "NetworkInstance.h"
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <cstring>
+#include "IPv6PacketMatcher.h"
+#include "Data.h"
+#include "NilReturn.h"
+#include "NCPControlInterface.h"
+#include "tunnel.h"
+#include "SocketAdapter.h"
+#include "TunnelIPv6Interface.h"
+#include "NCPConstants.h"
+#include "wpan-error.h"
+#include "StatCollector.h"
+
+#define ERRORCODE_OK            (0)
+#define ERRORCODE_HELP          (1)
+#define ERRORCODE_BADARG        (2)
+#define ERRORCODE_NOCOMMAND     (3)
+#define ERRORCODE_UNKNOWN       (4)
+#define ERRORCODE_BADCOMMAND    (5)
+#define ERRORCODE_NOREADLINE    (6)
+#define ERRORCODE_QUIT          (7)
+#define ERRORCODE_BADCONFIG     (8)
+#define ERRORCODE_ERRNO         (9)
+
+#define ERRORCODE_INTERRUPT     (128 + SIGINT)
+#define ERRORCODE_SIGHUP        (128 + SIGHUP)
+
+#define WTD_WEAK                __attribute__((weak))
+
+#define WPANTUND_DECLARE_NCPINSTANCE_PLUGIN(short_name, class_name) \
+	extern "C" nl::wpantund::NCPInstance* wpantund_ncpinstance_ ## short_name ## _alloc(const nl::wpantund::NCPInstance::Settings& settings)
+
+#define WPANTUND_DEFINE_NCPINSTANCE_PLUGIN(short_name, class_name) \
+	nl::wpantund::NCPInstance* \
+	wpantund_ncpinstance_ ## short_name ## _alloc(const nl::wpantund::NCPInstance::Settings& settings) { \
+		return new class_name(settings); \
+	} \
+	nl::wpantund::NCPInstance* \
+	wpantund_ncpinstance_default_alloc(const nl::wpantund::NCPInstance::Settings& settings) { \
+		return new class_name(settings); \
+	}
+
+namespace nl {
+
+namespace wpantund {
+class NCPControlInterface;
+
+class NCPInstance {
+public:
+	typedef std::map<std::string, std::string> Settings;
+
+public:
+	static NCPInstance* alloc(
+		const Settings& settings = Settings()
+	);
+
+	virtual ~NCPInstance();
+
+	virtual const std::string &get_name(void) = 0;
+	virtual NCPControlInterface& get_control_interface(void) = 0;
+	virtual StatCollector& get_stat_collector(void) = 0;
+
+	virtual void set_socket_adapter(const boost::shared_ptr<SocketAdapter> &adapter) = 0;
+
+	virtual cms_t get_ms_to_next_event(void) = 0;
+	virtual void process(void) = 0;
+	virtual int update_fd_set(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *error_fd_set, int *max_fd, cms_t *timeout) = 0;
+
+public:
+	void signal_fatal_error(int err);
+	SignalWithStatus mOnFatalError;
+}; // class NCPInstance
+
+}; // namespace wpantund
+}; // namespace nl
+
+extern "C" nl::wpantund::NCPInstance* wpantund_ncpinstance_default_alloc(const nl::wpantund::NCPInstance::Settings& settings);
+
+#endif /* defined(__wpantund__NCPInstance__) */
diff --git a/src/wpantund/NCPInstanceBase-Addresses.cpp b/src/wpantund/NCPInstanceBase-Addresses.cpp
new file mode 100644
index 0000000..d79a520
--- /dev/null
+++ b/src/wpantund/NCPInstanceBase-Addresses.cpp
@@ -0,0 +1,205 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include "NCPInstanceBase.h"
+#include "tunnel.h"
+#include <syslog.h>
+#include <errno.h>
+#include "nlpt.h"
+#include <algorithm>
+#include "socket-utils.h"
+#include "SuperSocket.h"
+
+using namespace nl;
+using namespace wpantund;
+
+
+
+void
+NCPInstanceBase::refresh_global_addresses()
+{
+	// Here is where we would do any periodic global address bookkeeping,
+	// which doesn't appear to be necessary yet but may become necessary
+	// in the future.
+}
+
+void
+NCPInstanceBase::clear_nonpermanent_global_addresses()
+{
+	std::map<struct in6_addr, GlobalAddressEntry>::iterator iter;
+
+	// We want to remove all of the addresses that were
+	// not user-added.
+	//
+	// This loop looks a little weird because we are mutating
+	// the container as we are iterating through it. Whenever
+	// we mutate the container we have to start over.
+	do {
+		for (iter = mGlobalAddresses.begin(); iter != mGlobalAddresses.end(); ++iter) {
+			// Skip the removal of user-added addresses.
+			if (iter->second.mUserAdded) {
+				continue;
+			}
+
+			mPrimaryInterface->remove_address(&iter->first);
+			mGlobalAddresses.erase(iter);
+
+			// The following assignment is needed to avoid
+			// an invalid iterator comparison in the outer loop.
+			iter = mGlobalAddresses.begin();
+
+			// Break out of the inner loop so that we start over.
+			break;
+		}
+	} while(iter != mGlobalAddresses.end());
+}
+
+void
+NCPInstanceBase::restore_global_addresses()
+{
+	std::map<struct in6_addr, GlobalAddressEntry>::const_iterator iter;
+	std::map<struct in6_addr, GlobalAddressEntry> global_addresses(mGlobalAddresses);
+
+	mGlobalAddresses.clear();
+
+	for (iter = global_addresses.begin(); iter!= global_addresses.end(); ++iter) {
+		if (iter->second.mUserAdded) {
+			address_was_added(iter->first, 64);
+		}
+		mGlobalAddresses.insert(*iter);
+
+		mPrimaryInterface->add_address(&iter->first);
+	}
+}
+
+void
+NCPInstanceBase::add_address(const struct in6_addr &address, uint8_t prefix, uint32_t valid_lifetime, uint32_t preferred_lifetime)
+{
+	GlobalAddressEntry entry = GlobalAddressEntry();
+
+	if (mGlobalAddresses.count(address)) {
+		syslog(LOG_INFO, "Updating IPv6 Address...");
+		entry = mGlobalAddresses[address];
+	} else {
+		syslog(LOG_INFO, "Adding IPv6 Address...");
+		mPrimaryInterface->add_address(&address);
+	}
+
+	entry.mValidLifetime = valid_lifetime;
+	entry.mPreferredLifetime = preferred_lifetime;
+	entry.mValidLifetimeExpiration = ((valid_lifetime == UINT32_MAX)
+		? TIME_DISTANT_FUTURE
+		: time_get_monotonic() + valid_lifetime
+	);
+	entry.mPreferredLifetimeExpiration = ((valid_lifetime == UINT32_MAX)
+		? TIME_DISTANT_FUTURE
+		: time_get_monotonic() + preferred_lifetime
+	);
+
+	mGlobalAddresses[address] = entry;
+}
+
+void
+NCPInstanceBase::remove_address(const struct in6_addr &address)
+{
+	mGlobalAddresses.erase(address);
+	mPrimaryInterface->remove_address(&address);
+}
+
+bool
+NCPInstanceBase::is_address_known(const struct in6_addr &address)
+{
+	bool ret(mGlobalAddresses.count(address) != 0);
+
+	return ret;
+}
+
+bool
+NCPInstanceBase::lookup_address_for_prefix(struct in6_addr *address, const struct in6_addr &prefix, int prefix_len_in_bits)
+{
+	struct in6_addr masked_prefix(prefix);
+
+	in6_addr_apply_mask(masked_prefix, prefix_len_in_bits);
+
+	std::map<struct in6_addr, GlobalAddressEntry>::const_iterator iter;
+	for (iter = mGlobalAddresses.begin(); iter != mGlobalAddresses.end(); ++iter) {
+		struct in6_addr iter_prefix(iter->first);
+		in6_addr_apply_mask(iter_prefix, prefix_len_in_bits);
+
+		if (iter_prefix == masked_prefix) {
+			if (address != NULL) {
+				*address = iter->first;
+			}
+			return true;
+		}
+	}
+	return false;
+}
+
+void
+NCPInstanceBase::address_was_added(const struct in6_addr& addr, int prefix_len)
+{
+	char addr_cstr[INET6_ADDRSTRLEN] = "::";
+	inet_ntop(
+		AF_INET6,
+		&addr,
+		addr_cstr,
+		sizeof(addr_cstr)
+	);
+
+	syslog(LOG_NOTICE, "\"%s\" was added to \"%s\"", addr_cstr, mPrimaryInterface->get_interface_name().c_str());
+
+	if (mGlobalAddresses.count(addr) == 0) {
+		const GlobalAddressEntry entry = {
+			UINT32_MAX,          // .mValidLifetime
+			TIME_DISTANT_FUTURE, // .mValidLifetimeExpiration
+			UINT32_MAX,          // .mPreferredLifetime
+			TIME_DISTANT_FUTURE, // .mPreferredLifetimeExpiration
+			0,                   // .mFlags
+			1,                   // .mUserAdded
+		};
+
+		mGlobalAddresses[addr] = entry;
+	}
+}
+
+void
+NCPInstanceBase::address_was_removed(const struct in6_addr& addr, int prefix_len)
+{
+	char addr_cstr[INET6_ADDRSTRLEN] = "::";
+	inet_ntop(
+		AF_INET6,
+		&addr,
+		addr_cstr,
+		sizeof(addr_cstr)
+	);
+
+	if ((mGlobalAddresses.count(addr) != 0)
+	 && (mPrimaryInterface->is_online() || !mGlobalAddresses[addr].mUserAdded)
+	) {
+		mGlobalAddresses.erase(addr);
+	}
+
+	syslog(LOG_NOTICE, "\"%s\" was removed from \"%s\"", addr_cstr, mPrimaryInterface->get_interface_name().c_str());
+}
diff --git a/src/wpantund/NCPInstanceBase-AsyncIO.cpp b/src/wpantund/NCPInstanceBase-AsyncIO.cpp
new file mode 100644
index 0000000..5d1955a
--- /dev/null
+++ b/src/wpantund/NCPInstanceBase-AsyncIO.cpp
@@ -0,0 +1,238 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include "NCPInstanceBase.h"
+#include "tunnel.h"
+#include <syslog.h>
+#include <errno.h>
+#include "nlpt.h"
+#include <algorithm>
+#include "socket-utils.h"
+#include "SuperSocket.h"
+
+using namespace nl;
+using namespace wpantund;
+
+bool
+NCPInstanceBase::can_set_ncp_power(void)
+{
+	return mPowerFD >= 0;
+}
+
+int
+NCPInstanceBase::set_ncp_power(bool power)
+{
+	ssize_t ret = -1;
+
+	if (mPowerFD >= 0) {
+		// Since controlling the power such a low-level
+		// operation, we break with our usual "no blocking calls"
+		// rule here for code clarity and to avoid
+		// unnecessary complexity.
+
+		IGNORE_RETURN_VALUE( lseek(mPowerFD, 0, SEEK_SET));
+
+		if (power) {
+			ret = write(mPowerFD, static_cast<const void*>(&mPowerFD_PowerOn), 1);
+		} else {
+			ret = write(mPowerFD, static_cast<const void*>(&mPowerFD_PowerOff), 1);
+		}
+
+		require_string(ret >= 0, bail, strerror(errno));
+
+		// We assign the return value of `write()` here
+		// to `ret` because we don't care if writing the `\n`
+		// fails. This happens when writing directly to GPIO
+		// files. We write the "\n" anyway to make it easier
+		// for non-GPIO sockets to parse.
+		IGNORE_RETURN_VALUE( write(mPowerFD, static_cast<const void*>("\n"), 1) );
+	}
+
+	if (ret > 0) {
+		ret = 0;
+	}
+
+bail:
+
+	return static_cast<int>(ret);
+}
+
+void
+NCPInstanceBase::hard_reset_ncp(void)
+{
+	NLPT_INIT(&mDriverToNCPPumpPT);
+	NLPT_INIT(&mNCPToDriverPumpPT);
+
+	if (mResetFD >= 0) {
+		// Since hardware resets are such a low-level
+		// operation, we break with our usual "no blocking calls"
+		// rule here for code clarity and to avoid
+		// unnecessary complexity.
+
+		ssize_t wret = -1;
+
+		IGNORE_RETURN_VALUE( lseek(mResetFD, 0, SEEK_SET) );
+
+		wret = write(mResetFD, static_cast<const void*>(&mResetFD_BeginReset), 1);
+
+		check_string(wret != -1, strerror(errno));
+
+		// We don't assign the return value of `write()` here
+		// to `ret` because we don't care if writing the `\n`
+		// fails. This happens when writing directly to GPIO
+		// files. We write the "\n" anyway to make it easier
+		// for non-GPIO sockets to parse.
+		IGNORE_RETURN_VALUE( write(mResetFD, static_cast<const void*>("\n"), 1) );
+
+		usleep(20 * USEC_PER_MSEC);
+
+		IGNORE_RETURN_VALUE( lseek(mResetFD, 0, SEEK_SET) );
+
+		wret = write(mResetFD, static_cast<const void*>(&mResetFD_EndReset), 1);
+
+		check_string(wret != -1, strerror(errno));
+
+		IGNORE_RETURN_VALUE( write(mResetFD, static_cast<const void*>("\n"), 1) );
+	} else {
+		mSerialAdapter->reset();
+	}
+}
+
+void
+NCPInstanceBase::set_socket_adapter(const boost::shared_ptr<SocketAdapter> &adapter)
+{
+	if(adapter) {
+		adapter->set_parent(mRawSerialAdapter);
+		mSerialAdapter = adapter;
+	} else {
+		mSerialAdapter = mRawSerialAdapter;
+	}
+}
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+cms_t
+NCPInstanceBase::get_ms_to_next_event(void)
+{
+	cms_t ret(EventHandler::get_ms_to_next_event());
+
+	mSerialAdapter->update_fd_set(NULL, NULL, NULL, NULL, &ret);
+	mPrimaryInterface->update_fd_set(NULL, NULL, NULL, NULL, &ret);
+	mFirmwareUpgrade.update_fd_set(NULL, NULL, NULL, NULL, &ret);
+
+	if (mWasBusy && (mLastChangedBusy != 0)) {
+		cms_t temp_cms(MAX_INSOMNIA_TIME_IN_MS - (time_ms() - mLastChangedBusy));
+		if (temp_cms < ret) {
+			ret = temp_cms;
+		}
+
+		if (ret > BUSY_DEBOUNCE_TIME_IN_MS && !is_busy()) {
+			ret = BUSY_DEBOUNCE_TIME_IN_MS;
+		}
+	}
+
+	if (ret < 0) {
+		ret = 0;
+	}
+
+	return ret;
+}
+
+int
+NCPInstanceBase::update_fd_set(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *error_fd_set, int *max_fd, cms_t *timeout)
+{
+	int ret = -1;
+
+	if (timeout != NULL) {
+		*timeout = std::min(*timeout, get_ms_to_next_event());
+	}
+
+	ret = mFirmwareUpgrade.update_fd_set(read_fd_set, write_fd_set, error_fd_set, max_fd, timeout);
+
+	require_noerr(ret, bail);
+
+	ret = mPcapManager.update_fd_set(read_fd_set, write_fd_set, error_fd_set, max_fd, timeout);
+
+	require_noerr(ret, bail);
+
+	if (!ncp_state_is_detached_from_ncp(get_ncp_state())) {
+		nlpt_select_update_fd_set(&mDriverToNCPPumpPT, read_fd_set, write_fd_set, error_fd_set, max_fd);
+		nlpt_select_update_fd_set(&mNCPToDriverPumpPT, read_fd_set, write_fd_set, error_fd_set, max_fd);
+
+		ret = mPrimaryInterface->update_fd_set(read_fd_set, write_fd_set, error_fd_set, max_fd, timeout);
+		require_noerr(ret, bail);
+
+		if (is_legacy_interface_enabled()) {
+			ret = mLegacyInterface->update_fd_set(read_fd_set, write_fd_set, error_fd_set, max_fd, timeout);
+			require_noerr(ret, bail);
+		}
+
+		ret = mSerialAdapter->update_fd_set(read_fd_set, write_fd_set, error_fd_set, max_fd, timeout);
+		require_noerr(ret, bail);
+	}
+
+bail:
+	return ret;
+}
+
+void
+NCPInstanceBase::process(void)
+{
+	int ret = 0;
+
+	mRunawayResetBackoffManager.update();
+
+	mFirmwareUpgrade.process();
+
+	mPcapManager.process();
+
+	if (get_upgrade_status() != EINPROGRESS) {
+		refresh_global_addresses();
+
+		require_noerr(ret = mPrimaryInterface->process(), socket_failure);
+
+		if (is_legacy_interface_enabled()) {
+			mLegacyInterface->process();
+		}
+
+		require_noerr(ret = mSerialAdapter->process(), socket_failure);
+
+		ncp_to_driver_pump();
+	}
+
+	EventHandler::process_event(EVENT_IDLE);
+
+	if (get_upgrade_status() != EINPROGRESS) {
+		driver_to_ncp_pump();
+	}
+
+    update_busy_indication();
+
+	return;
+
+socket_failure:
+	signal_fatal_error(ret);
+	return;
+}
diff --git a/src/wpantund/NCPInstanceBase-NetInterface.cpp b/src/wpantund/NCPInstanceBase-NetInterface.cpp
new file mode 100644
index 0000000..b6ee944
--- /dev/null
+++ b/src/wpantund/NCPInstanceBase-NetInterface.cpp
@@ -0,0 +1,478 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include "NCPInstanceBase.h"
+#include "tunnel.h"
+#include <syslog.h>
+#include <errno.h>
+#include "nlpt.h"
+#include <algorithm>
+#include "socket-utils.h"
+#include "SuperSocket.h"
+
+using namespace nl;
+using namespace wpantund;
+
+
+int
+NCPInstanceBase::set_online(bool x)
+{
+	int ret;
+
+	ret = mPrimaryInterface->set_online(x);
+
+	restore_global_addresses();
+
+	if (IN6_IS_ADDR_LINKLOCAL(&mNCPLinkLocalAddress)) {
+		add_address(mNCPLinkLocalAddress);
+	}
+
+	if (buffer_is_nonzero(mNCPMeshLocalAddress.s6_addr, sizeof(mNCPMeshLocalAddress)))	{
+		add_address(mNCPMeshLocalAddress);
+	}
+
+	if ((ret == 0) && static_cast<bool>(mLegacyInterface)) {
+		if (x && mNodeTypeSupportsLegacy) {
+			ret = mLegacyInterface->set_online(true);
+
+			if (IN6_IS_ADDR_LINKLOCAL(&mNCPLinkLocalAddress)) {
+				mLegacyInterface->add_address(&mNCPLinkLocalAddress);
+			}
+		} else {
+			ret = mLegacyInterface->set_online(false);
+		}
+	}
+
+	return ret;
+}
+
+void
+NCPInstanceBase::set_mac_address(const uint8_t x[8])
+{
+	if (0 != memcmp(x, mMACAddress, sizeof(mMACAddress))) {
+		memcpy(mMACAddress, x, sizeof(mMACAddress));
+
+		syslog(
+			LOG_INFO,
+			"NCP Status: MACAddr:           %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
+			mMACAddress[0],mMACAddress[1],mMACAddress[2],mMACAddress[3],
+			mMACAddress[4],mMACAddress[5],mMACAddress[6],mMACAddress[7]
+		);
+
+		if ((x[0] & 1) == 1) {
+			syslog(LOG_WARNING,"MAC ADDRESS IS INVALID, MULTICAST BIT IS SET!");
+		}
+
+		signal_property_changed(kWPANTUNDProperty_NCPMACAddress, Data(mMACAddress, sizeof(mMACAddress)));
+
+	}
+
+	if (!buffer_is_nonzero(mMACHardwareAddress, sizeof(mMACHardwareAddress))) {
+		set_mac_hardware_address(x);
+	}
+}
+
+void
+NCPInstanceBase::set_mac_hardware_address(const uint8_t x[8])
+{
+	if (0 != memcmp(x, mMACHardwareAddress, sizeof(mMACHardwareAddress))) {
+		memcpy(mMACHardwareAddress, x, sizeof(mMACHardwareAddress));
+
+		syslog(
+			LOG_INFO,
+			"NCP Status: MACHardwareAddr:   %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
+			mMACHardwareAddress[0],mMACHardwareAddress[1],mMACHardwareAddress[2],mMACHardwareAddress[3],
+			mMACHardwareAddress[4],mMACHardwareAddress[5],mMACHardwareAddress[6],mMACHardwareAddress[7]
+		);
+
+		if ((x[0] & 1) == 1) {
+			syslog(LOG_WARNING,"HARDWARE ADDRESS IS INVALID, MULTICAST BIT IS SET!");
+		}
+
+		signal_property_changed(kWPANTUNDProperty_NCPHardwareAddress, Data(mMACHardwareAddress, sizeof(mMACHardwareAddress)));
+
+	}
+}
+
+void
+NCPInstanceBase::reset_interface(void)
+{
+	syslog(LOG_NOTICE, "Resetting interface(s). . .");
+
+	mCurrentNetworkInstance.joinable = false;
+
+	set_commissioniner(0, 0, 0);
+
+	mPrimaryInterface->reset();
+
+	// The global address table must be cleared upon reset.
+	mGlobalAddresses.clear();
+
+	if (static_cast<bool>(mLegacyInterface)) {
+		mLegacyInterface->reset();
+	}
+}
+
+void
+NCPInstanceBase::enable_legacy_interface(void)
+{
+	if (!static_cast<bool>(mLegacyInterface)) {
+		mLegacyInterface = boost::shared_ptr<TunnelIPv6Interface>(new TunnelIPv6Interface(mPrimaryInterface->get_interface_name()+"-L"));
+	}
+}
+
+bool
+NCPInstanceBase::is_legacy_interface_enabled(void)
+{
+	if (mNodeTypeSupportsLegacy) {
+		return static_cast<bool>(mLegacyInterface);
+	}
+	return false;
+}
+
+
+
+int
+NCPInstanceBase::join_multicast_group(const std::string &group_name)
+{
+	int ret = -1;
+	struct ipv6_mreq imreq;
+	unsigned int value = 1;
+	struct hostent *tmp = gethostbyname2(group_name.c_str(), AF_INET6);
+	memset(&imreq, 0, sizeof(imreq));
+
+	if (mMCFD < 0) {
+		mMCFD = socket(AF_INET6, SOCK_DGRAM, 0);
+	}
+
+	require(mMCFD >= 0, skip_mcast);
+
+	require(!h_errno && tmp, skip_mcast);
+	require(tmp->h_length > 1, skip_mcast);
+
+	memcpy(&imreq.ipv6mr_multiaddr.s6_addr, tmp->h_addr_list[0], 16);
+
+	value = 1;
+	ret = setsockopt(
+		mMCFD,
+		IPPROTO_IPV6,
+		IPV6_MULTICAST_LOOP,
+		&value,
+		sizeof(value)
+	);
+	require_noerr(ret, skip_mcast);
+
+	imreq.ipv6mr_interface = if_nametoindex(mPrimaryInterface->get_interface_name().c_str());
+
+	ret = setsockopt(
+		mMCFD,
+		IPPROTO_IPV6,
+		IPV6_JOIN_GROUP,
+		&imreq,
+		sizeof(imreq)
+	);
+	require_noerr(ret, skip_mcast);
+
+skip_mcast:
+
+	if (ret) {
+		syslog(LOG_WARNING, "Failed to join multicast group \"%s\"", group_name.c_str());
+	}
+
+	return ret;
+}
+
+
+int
+NCPInstanceBase::set_commissioniner(
+    int seconds, uint8_t traffic_type, in_port_t traffic_port
+    )
+{
+	int ret = kWPANTUNDStatus_Ok;
+
+	mCommissioningRule.clear();
+
+	if ((seconds > 0) && (traffic_port == 0)) {
+		ret = kWPANTUNDStatus_InvalidArgument;
+		goto bail;
+	}
+
+	if (seconds > 0 && traffic_port) {
+		mCommissioningExpiration = time_get_monotonic() + seconds;
+
+		mCommissioningRule.type = traffic_type;
+		mCommissioningRule.local_port = traffic_port;
+		mCommissioningRule.local_port_match = true;
+		mCommissioningRule.local_address.s6_addr[0] = 0xFE;
+		mCommissioningRule.local_address.s6_addr[1] = 0x80;
+		mCommissioningRule.local_match_mask = 10;
+	} else {
+		mCommissioningExpiration = 0;
+		mInsecureFirewall.clear();
+	}
+
+bail:
+	return ret;
+}
+
+
+
+void
+NCPInstanceBase::handle_normal_ipv6_from_ncp(const uint8_t* ip_packet, size_t packet_length)
+{
+	ssize_t ret = mPrimaryInterface->write(ip_packet, packet_length);
+
+	if (ret != packet_length) {
+		syslog(LOG_INFO, "[NCP->] IPv6 packet refused by host stack! (ret = %ld)", (long)ret);
+	}
+}
+
+void
+NCPInstanceBase::handle_alt_ipv6_from_ncp(const uint8_t* ip_packet, size_t packet_length)
+{
+	ssize_t ret = mLegacyInterface->write(ip_packet, packet_length);
+
+	if (ret != packet_length) {
+		syslog(LOG_INFO, "[NCP->] IPv6 packet refused by host stack! (ret = %ld)", (long)ret);
+	}
+}
+
+#define FRAME_TYPE_TO_CSTR(x) \
+			       (((x) == FRAME_TYPE_INSECURE_DATA) \
+					? "INSECURE" \
+					: ((x) == FRAME_TYPE_LEGACY_DATA) \
+						? "LEGACY" \
+						: "SECURE")
+
+// This function does a little more than it's name might imply.
+// It will also mutate the NCP frame to reflect the appropriate
+// interface if the firewall rules indicate that it should be
+// handled differently (i.e., a insecure packet that matches
+// the appropriate firewall rules will be re-tagged as a normal
+// packet, etc.)
+bool
+NCPInstanceBase::should_forward_hostbound_frame(uint8_t* type, const uint8_t* ip_packet, size_t packet_length)
+{
+	bool packet_should_be_dropped = false;
+	IPv6PacketMatcherRule rule;
+
+	rule.update_from_inbound_packet(ip_packet);
+
+	// Handle special considerations for packets received
+	// from the insecure data channel.
+	if (*type == FRAME_TYPE_INSECURE_DATA) {
+		// If the packet is from the insecure channel, we
+		// mark the packed as "to be dropped" by default.
+		// We perform some additional checks below which
+		// may switch this back to `false`.
+		packet_should_be_dropped = true;
+
+		if (ncp_state_is_joining(get_ncp_state())) {
+			// Don't drop data from insecure channel if we
+			// aren't joined yet.
+			packet_should_be_dropped = false;
+
+		} else if (mCommissioningExpiration != 0) {
+			if (mCommissioningExpiration > time_get_monotonic()) {
+				// We are in the middle of commissioning and we
+				// haven't expired yet.
+
+				if (mInsecureFirewall.count(rule)) {
+					syslog(LOG_INFO,
+						   "[NCP->] Routing insecure commissioning traffic.");
+					packet_should_be_dropped = false;
+				} else if (mCommissioningRule.match_inbound(ip_packet)) {
+					rule.subtype = IPv6PacketMatcherRule::SUBTYPE_ALL;
+					mInsecureFirewall.insert(rule);
+					packet_should_be_dropped = false;
+					syslog(LOG_INFO,
+						   "[NCP->] Tracking *NEW* insecure commissioning connection.");
+				} else if (rule.type == IPv6PacketMatcherRule::TYPE_ICMP) {
+					mInsecureFirewall.insert(rule);
+					packet_should_be_dropped = false;
+					syslog(LOG_INFO,
+						   "[NCP->] Tracking *NEW* ICMP ping during commissioning.");
+				} else {
+					syslog(LOG_INFO,
+						   "[NCP->] Non-matching insecure traffic while joinable, ignoring");
+				}
+			} else {
+				// Commissioning has ended. Clean up.
+				syslog(LOG_NOTICE, "Commissioning period has ended");
+				mCommissioningExpiration = 0;
+				mInsecureFirewall.clear();
+			}
+		}
+	} else if (
+		(   (*type == FRAME_TYPE_DATA)
+			|| (*type == FRAME_TYPE_LEGACY_DATA)
+		)
+		&&	(mInsecureFirewall.size()>0)
+	) {
+		// In this case we want to make sure that if we receive
+		// a packet on a secure channel that we were previously
+		// routing over the insecure channel that we remove the
+		// matching entry so that we don't route those packets
+		// over the insecure channel any more.
+
+		if (mInsecureFirewall.count(rule)) {
+			syslog(LOG_NOTICE, "Secure packet matched rule on insecure firewall, removing rule.");
+			mInsecureFirewall.erase(rule);
+
+			if (*type == FRAME_TYPE_LEGACY_DATA) {
+				// The first packet to match the rule on the insecure firewall
+				// was from the legacy interface. To ensure the continuity
+				// of the connection, we need to ensure that the packets
+				// for this session continue to come out of the non-legacy
+				// interface. We do that by adding them to this packet matcher.
+				mLegacyCommissioningMatcher.insert(rule);
+			}
+		}
+	}
+
+	// If our legacy interface isn't enabled, drop all legacy traffic.
+	if (*type == FRAME_TYPE_LEGACY_DATA) {
+		packet_should_be_dropped |= !is_legacy_interface_enabled();
+	}
+
+	// Debug logging.
+	dump_inbound_ipv6_packet(
+		ip_packet,
+		packet_length,
+		FRAME_TYPE_TO_CSTR(*type),
+		packet_should_be_dropped
+	);
+
+	// Make sure the interface is up.
+	if (!ncp_state_is_interface_up(get_ncp_state())) {
+		// The interface is down, so we don't send the packet.
+		packet_should_be_dropped = true;
+
+		// Check to see if the NCP is supposed to be asleep:
+		if (ncp_state_is_sleeping(get_ncp_state())) {
+			syslog(LOG_ERR, "Got IPv6 traffic when we should be asleep! (%s)",ncp_state_to_string(get_ncp_state()).c_str());
+			ncp_is_misbehaving();
+		} else {
+			syslog(LOG_WARNING, "Ignoring IPv6 traffic while in %s state.", ncp_state_to_string(get_ncp_state()).c_str());
+		}
+	}
+
+	if ((*type == FRAME_TYPE_LEGACY_DATA) && mLegacyCommissioningMatcher.count(rule)) {
+		// This is for ensuring that the commissioning TCP connection survives
+		// the transition to joining the network. In order for this to occur,
+		// we need to ensure that the packets for this particular connection
+		// continue to flow to and from the normal IPv6 data interface.
+		*type = FRAME_TYPE_DATA;
+	}
+
+	if (!packet_should_be_dropped) {
+		// Inform the statistic collector about the inbound IP packet
+		get_stat_collector().record_inbound_packet(ip_packet);
+	} else {
+		syslog(LOG_DEBUG, "Dropping host-bound IPv6 packet.");
+	}
+
+	return !packet_should_be_dropped;
+}
+
+bool
+NCPInstanceBase::should_forward_ncpbound_frame(uint8_t* type, const uint8_t* ip_packet, size_t packet_length)
+{
+	bool should_forward = true;
+	IPv6PacketMatcherRule rule;
+
+	if (!ncp_state_is_interface_up(get_ncp_state())) {
+		syslog(LOG_DEBUG, "Dropping IPv6 packet, NCP not ready yet!");
+		should_forward = false;
+		goto bail;
+	}
+
+	// Skip non-IPv6 packets
+	if (!is_valid_ipv6_packet(ip_packet, packet_length)) {
+		syslog(LOG_DEBUG,
+			   "Dropping non-IPv6 outbound packet (first byte was 0x%02X)",
+			   ip_packet[0]);
+		should_forward = false;
+		goto bail;
+	}
+
+	rule.update_from_outbound_packet(ip_packet);
+
+	if (mDropFirewall.match_outbound(ip_packet) != mDropFirewall.end()) {
+		syslog(LOG_INFO, "[->NCP] Dropping matched packet.");
+		should_forward = false;
+		goto bail;
+	}
+
+	if (mLegacyCommissioningMatcher.count(rule)) {
+		if (*type == FRAME_TYPE_LEGACY_DATA) {
+			// This is for ensuring that the commissioning TCP connection survives
+			// the transition to joining the network. In order for this to occur,
+			// we need to ensure that the packets for this particular connection
+			// continue to flow to and from the normal IPv6 data interface.
+			*type = FRAME_TYPE_DATA;
+		} else {
+			mLegacyCommissioningMatcher.erase(rule);
+		}
+	}
+
+	rule.subtype = IPv6PacketMatcherRule::SUBTYPE_ALL;
+
+	if (mInsecureFirewall.count(rule)) {
+		// We use `count` instead of `match_outbound` in the
+		// check above because exact matches are faster.
+		syslog(LOG_INFO, "[->NCP] Routing insecure commissioning traffic.");
+		*type = FRAME_TYPE_INSECURE_DATA;
+	}
+
+	if (ncp_state_is_joining(get_ncp_state())) {
+		// When we are joining, all outbound traffic is insecure.
+		*type = FRAME_TYPE_INSECURE_DATA;
+
+	} else if ((mCommissioningExpiration != 0)
+		&& (mCommissioningExpiration < time_get_monotonic())
+	) {
+		syslog(LOG_NOTICE, "Commissioning period has ended");
+		mCommissioningExpiration = 0;
+		mInsecureFirewall.clear();
+	}
+
+	// Inform the statistics collector about the outbound IPv6 packet
+	if (should_forward) {
+		get_stat_collector().record_outbound_packet(ip_packet);
+	} else {
+		syslog(LOG_DEBUG, "Dropping NCP-bound IPv6 packet.");
+	}
+
+	// Debug logging
+	dump_outbound_ipv6_packet(
+		ip_packet,
+		packet_length,
+		FRAME_TYPE_TO_CSTR(*type)
+	);
+
+bail:
+
+	return should_forward;
+}
diff --git a/src/wpantund/NCPInstanceBase.cpp b/src/wpantund/NCPInstanceBase.cpp
new file mode 100644
index 0000000..0e20131
--- /dev/null
+++ b/src/wpantund/NCPInstanceBase.cpp
@@ -0,0 +1,940 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include "NCPInstanceBase.h"
+#include "tunnel.h"
+#include <syslog.h>
+#include <errno.h>
+#include "nlpt.h"
+#include <algorithm>
+#include "socket-utils.h"
+#include "SuperSocket.h"
+#include "wpantund.h"
+#include "any-to.h"
+
+using namespace nl;
+using namespace wpantund;
+
+
+
+// ----------------------------------------------------------------------------
+// MARK: -
+// MARK: Constructors/Destructors
+
+NCPInstanceBase::NCPInstanceBase(const Settings& settings):
+	mCommissioningRule(),
+	mCommissioningExpiration(0)
+{
+	std::string wpan_interface_name = "wpan0";
+
+	mResetFD = -1;
+	mResetFD_BeginReset = '0';
+	mResetFD_EndReset = '1';
+
+	mPowerFD = -1;
+	mPowerFD_PowerOff = '0';
+	mPowerFD_PowerOn = '1';
+
+	mMCFD = -1;
+
+	NLPT_INIT(&mNCPToDriverPumpPT);
+	NLPT_INIT(&mDriverToNCPPumpPT);
+
+	mCommissioningExpiration = 0;
+	mEnabled = true;
+	mTerminateOnFault = false;
+	mAutoUpdateFirmware = false;
+	mAutoResume = true;
+	mAutoDeepSleep = false;
+	mIsInitializingNCP = false;
+	mNCPState = UNINITIALIZED;
+	mNodeType = UNKNOWN;
+	mFailureCount = 0;
+	mFailureThreshold = 3;
+	mAutoDeepSleepTimeout = 10;
+	mCommissionerPort = 5684;
+
+	memset(mNCPMeshLocalAddress.s6_addr, 0, sizeof(mNCPMeshLocalAddress));
+	memset(mNCPLinkLocalAddress.s6_addr, 0, sizeof(mNCPLinkLocalAddress));
+	memset(mNCPV6LegacyPrefix, 0, sizeof(mNCPV6LegacyPrefix));
+	memset(mMACAddress, 0, sizeof(mMACAddress));
+	memset(mMACHardwareAddress, 0, sizeof(mMACHardwareAddress));
+
+	if (!settings.empty()) {
+		Settings::const_iterator iter;
+
+		for(iter = settings.begin(); iter != settings.end(); iter++) {
+			if (strcaseequal(iter->first.c_str(), kWPANTUNDProperty_ConfigNCPHardResetPath)) {
+				mResetFD = open_super_socket(iter->second.c_str());
+
+			} else if (strcaseequal(iter->first.c_str(), kWPANTUNDProperty_ConfigNCPPowerPath)) {
+				mPowerFD = open_super_socket(iter->second.c_str());
+
+			} else if (strcaseequal(iter->first.c_str(), kWPANTUNDProperty_ConfigNCPSocketPath)) {
+				mRawSerialAdapter = SuperSocket::create(iter->second);
+
+			} else if (strcaseequal(iter->first.c_str(), kWPANTUNDProperty_ConfigTUNInterfaceName)) {
+				wpan_interface_name = iter->second;
+
+			} else if (strcaseequal(iter->first.c_str(), kWPANTUNDProperty_ConfigNCPFirmwareCheckCommand)) {
+				mFirmwareUpgrade.set_firmware_check_command(iter->second);
+
+			} else if (strcaseequal(iter->first.c_str(), kWPANTUNDProperty_ConfigNCPFirmwareUpgradeCommand)) {
+				mFirmwareUpgrade.set_firmware_upgrade_command(iter->second);
+
+			} else if (strcaseequal(iter->first.c_str(), kWPANTUNDProperty_DaemonAutoFirmwareUpdate)) {
+				mAutoUpdateFirmware = any_to_bool(boost::any(iter->second));
+
+			} else if (strcaseequal(iter->first.c_str(), kWPANTUNDProperty_ConfigDaemonNetworkRetainCommand)) {
+				mNetworkRetain.set_network_retain_command(iter->second);
+			}
+		}
+	}
+
+	if (!mRawSerialAdapter) {
+		syslog(LOG_WARNING, kWPANTUNDProperty_ConfigNCPSocketPath" was not specified. Using \"/dev/null\" instead.");
+		mRawSerialAdapter = SuperSocket::create("/dev/null");
+	}
+
+	if (mRawSerialAdapter) {
+		mRawSerialAdapter->set_log_level(LOG_DEBUG);
+	}
+
+	mSerialAdapter = mRawSerialAdapter;
+
+	mPrimaryInterface = boost::shared_ptr<TunnelIPv6Interface>(new TunnelIPv6Interface(wpan_interface_name));
+	mPrimaryInterface->mAddressWasAdded.connect(boost::bind(&NCPInstanceBase::address_was_added, this, _1, _2));
+	mPrimaryInterface->mAddressWasRemoved.connect(boost::bind(&NCPInstanceBase::address_was_removed, this, _1, _2));
+
+	set_ncp_power(true);
+
+	// Go ahead and start listening on ff03::1
+	join_multicast_group("ff03::1");
+
+
+	{
+		IPv6PacketMatcherRule rule;
+
+		// --------------------------------------------------------------------
+		// Packet Drop rules
+
+		rule.clear();
+		// OS X seems to generate these packets when bringing up the interface.
+		// Honey badger don't care.
+		rule.type = IPv6PacketMatcherRule::TYPE_HOP_BY_HOP;
+		rule.remote_address.s6_addr[0x0] = 0xFF;
+		rule.remote_address.s6_addr[0x1] = 0x02;
+		rule.remote_address.s6_addr[0xF] = 0x16;
+		rule.remote_match_mask = 128;
+		mDropFirewall.insert(rule);
+
+		rule.clear();
+		// Don't forward router advertisement or router solicitation
+		// traffic.
+		rule.type = IPv6PacketMatcherRule::TYPE_ICMP;
+		rule.remote_address.s6_addr[0x0] = 0xFF;
+		rule.remote_address.s6_addr[0x1] = 0x02;
+		rule.remote_address.s6_addr[0xF] = 0x02;
+		rule.remote_match_mask = 128;
+		rule.subtype = IPv6PacketMatcherRule::SUBTYPE_ICMP_ROUTER_ADV;
+		mDropFirewall.insert(rule);
+		rule.subtype = IPv6PacketMatcherRule::SUBTYPE_ICMP_ROUTER_SOL;
+		mDropFirewall.insert(rule);
+
+		rule.clear();
+		// Don't forward neighbor advertisement or neighbor solicitation
+		// traffic.
+		rule.type = IPv6PacketMatcherRule::TYPE_ICMP;
+		rule.subtype = IPv6PacketMatcherRule::SUBTYPE_ICMP_NEIGHBOR_ADV;
+		mDropFirewall.insert(rule);
+		rule.subtype = IPv6PacketMatcherRule::SUBTYPE_ICMP_NEIGHBOR_SOL;
+		mDropFirewall.insert(rule);
+	}
+}
+
+bool
+NCPInstanceBase::setup_property_supported_by_class(const std::string& prop_name)
+{
+	return strcaseequal(prop_name.c_str(), kWPANTUNDProperty_ConfigNCPHardResetPath)
+		|| strcaseequal(prop_name.c_str(), kWPANTUNDProperty_ConfigNCPPowerPath)
+		|| strcaseequal(prop_name.c_str(), kWPANTUNDProperty_ConfigNCPSocketPath)
+		|| strcaseequal(prop_name.c_str(), kWPANTUNDProperty_ConfigTUNInterfaceName)
+		|| strcaseequal(prop_name.c_str(), kWPANTUNDProperty_ConfigNCPDriverName)
+		|| strcaseequal(prop_name.c_str(), kWPANTUNDProperty_ConfigNCPFirmwareCheckCommand)
+		|| strcaseequal(prop_name.c_str(), kWPANTUNDProperty_DaemonAutoFirmwareUpdate)
+		|| strcaseequal(prop_name.c_str(), kWPANTUNDProperty_ConfigNCPFirmwareUpgradeCommand)
+		|| strcaseequal(prop_name.c_str(), kWPANTUNDProperty_ConfigDaemonNetworkRetainCommand);
+}
+
+NCPInstanceBase::~NCPInstanceBase()
+{
+	close(mMCFD);
+	close(mPowerFD);
+	close(mResetFD);
+}
+
+
+
+const std::string &
+NCPInstanceBase::get_name()
+{
+	return mPrimaryInterface->get_interface_name();
+}
+
+const WPAN::NetworkInstance&
+NCPInstanceBase::get_current_network_instance(void)const
+{
+	return mCurrentNetworkInstance;
+}
+
+// Helpful for use with callbacks.
+int
+NCPInstanceBase::process_event_helper(int event)
+{
+	return EventHandler::process_event(event);
+}
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+wpantund_status_t
+NCPInstanceBase::set_ncp_version_string(const std::string& version_string)
+{
+	wpantund_status_t status = kWPANTUNDStatus_Ok;
+
+	if (version_string != mNCPVersionString) {
+		if (!mNCPVersionString.empty()) {
+			// The previous version string isn't empty!
+			syslog(LOG_ERR, "Illegal NCP version change! (Previously \"%s\")", mNCPVersionString.c_str());
+			ncp_is_misbehaving();
+			status = kWPANTUNDStatus_InvalidArgument;
+		} else {
+			mNCPVersionString = version_string;
+
+			syslog(LOG_NOTICE, "NCP is running \"%s\"", mNCPVersionString.c_str());
+			syslog(LOG_NOTICE, "Driver is running \"%s\"", nl::wpantund::get_wpantund_version_string().c_str());
+
+			if (mAutoUpdateFirmware && is_firmware_upgrade_required(version_string)) {
+				syslog(LOG_NOTICE, "NCP FIRMWARE UPGRADE IS REQUIRED");
+				upgrade_firmware();
+			}
+		}
+	}
+	return status;
+}
+
+std::set<std::string>
+NCPInstanceBase::get_supported_property_keys() const
+{
+	std::set<std::string> properties;
+
+	properties.insert(kWPANTUNDProperty_NetworkName);
+	properties.insert(kWPANTUNDProperty_NetworkPANID);
+	properties.insert(kWPANTUNDProperty_NetworkXPANID);
+	properties.insert(kWPANTUNDProperty_NetworkKey);
+	properties.insert(kWPANTUNDProperty_NetworkKeyIndex);
+	properties.insert(kWPANTUNDProperty_NetworkNodeType);
+
+	properties.insert(kWPANTUNDProperty_NCPState);
+
+	properties.insert(kWPANTUNDProperty_IPv6MeshLocalPrefix);
+	properties.insert(kWPANTUNDProperty_IPv6MeshLocalAddress);
+	properties.insert(kWPANTUNDProperty_IPv6LinkLocalAddress);
+	properties.insert(kWPANTUNDProperty_IPv6AllAddresses);
+
+	properties.insert(kWPANTUNDProperty_DaemonAutoAssociateAfterReset);
+	properties.insert(kWPANTUNDProperty_DaemonAutoDeepSleep);
+	properties.insert(kWPANTUNDProperty_DaemonEnabled);
+	properties.insert(kWPANTUNDProperty_DaemonReadyForHostSleep);
+	properties.insert(kWPANTUNDProperty_DaemonTerminateOnFault);
+
+	properties.insert(kWPANTUNDProperty_NestLabs_NetworkAllowingJoin);
+
+	properties.insert(kWPANTUNDProperty_DaemonVersion);
+	properties.insert(kWPANTUNDProperty_DaemonTerminateOnFault);
+
+	properties.insert(kWPANTUNDProperty_NCPChannel);
+	properties.insert(kWPANTUNDProperty_NCPVersion);
+	properties.insert(kWPANTUNDProperty_NCPHardwareAddress);
+	properties.insert(kWPANTUNDProperty_NCPCCAThreshold);
+	properties.insert(kWPANTUNDProperty_NCPTXPower);
+
+	properties.insert(kWPANTUNDProperty_NCPMACAddress);
+
+	properties.insert(kWPANTUNDProperty_NetworkIsCommissioned);
+
+	properties.insert(kWPANTUNDProperty_ConfigTUNInterfaceName);
+
+	if (mLegacyInterfaceEnabled || mNodeTypeSupportsLegacy || buffer_is_nonzero(mNCPV6LegacyPrefix, sizeof(mNCPV6LegacyPrefix))) {
+		properties.insert(kWPANTUNDProperty_NestLabs_LegacyMeshLocalAddress);
+		properties.insert(kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix);
+	}
+
+	properties.insert(kWPANTUNDProperty_NestLabs_NetworkPassthruPort);
+
+	return properties;
+}
+
+void
+NCPInstanceBase::get_property(
+	const std::string& in_key,
+	CallbackWithStatusArg1 cb
+) {
+	std::string key = in_key;
+
+
+	if (key.empty()) {
+		/* This key is used to get the list of available properties */
+		cb(0, get_supported_property_keys());
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ConfigTUNInterfaceName)) {
+		cb(0, get_name());
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonEnabled)) {
+		cb(0, boost::any(mEnabled));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonReadyForHostSleep)) {
+		cb(0, boost::any(!is_busy()));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_ConfigTUNInterfaceName)) {
+		cb(0, get_name());
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NCPVersion)) {
+		cb(0, boost::any(mNCPVersionString));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NetworkName)) {
+		cb(0, boost::any(get_current_network_instance().name));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NetworkIsCommissioned)) {
+		NCPState ncp_state = get_ncp_state();
+		if (ncp_state_is_commissioned(ncp_state)) {
+			cb(0, boost::any(true));
+		} else  if (ncp_state == OFFLINE || ncp_state == DEEP_SLEEP) {
+			cb(0, boost::any(false));
+		} else {
+			cb(kWPANTUNDStatus_TryAgainLater, boost::any(std::string("Unable to determine association state at this time")));
+		}
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NestLabs_LegacyEnabled)) {
+		cb(0, boost::any(mLegacyInterfaceEnabled));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NestLabs_NetworkAllowingJoin)) {
+		cb(0, boost::any(get_current_network_instance().joinable));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NetworkPANID)) {
+		cb(0, boost::any(get_current_network_instance().panid));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NetworkXPANID)) {
+		cb(0, boost::any(get_current_network_instance().get_xpanid_as_uint64()));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NCPChannel)) {
+		cb(0, boost::any((int)get_current_network_instance().channel));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonVersion)) {
+		cb(0, boost::any(nl::wpantund::get_wpantund_version_string()));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonAutoAssociateAfterReset)) {
+		cb(0, boost::any(static_cast<bool>(mAutoResume)));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonAutoDeepSleep)) {
+		cb(0, boost::any(mAutoDeepSleep));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonAutoFirmwareUpdate)) {
+		cb(0, boost::any(mAutoUpdateFirmware));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonTerminateOnFault)) {
+		cb(0, boost::any(mTerminateOnFault));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NestLabs_NetworkPassthruPort)) {
+		cb(0, boost::any(mCommissionerPort));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NCPMACAddress)) {
+		cb(0, boost::any(nl::Data(mMACAddress, sizeof(mMACAddress))));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NCPHardwareAddress)) {
+		cb(0, boost::any(nl::Data(mMACHardwareAddress, sizeof(mMACHardwareAddress))));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_IPv6MeshLocalPrefix)) {
+		if (buffer_is_nonzero(mNCPV6Prefix, sizeof(mNCPV6Prefix))) {
+			struct in6_addr addr (mNCPMeshLocalAddress);
+			// Zero out the lower 64 bits.
+			memset(addr.s6_addr+8, 0, 8);
+			cb(0, boost::any(in6_addr_to_string(addr)+"/64"));
+		} else {
+			cb(kWPANTUNDStatus_FeatureNotSupported, std::string("Property is unavailable"));
+		}
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_IPv6MeshLocalAddress)) {
+		if (buffer_is_nonzero(mNCPMeshLocalAddress.s6_addr, sizeof(mNCPMeshLocalAddress))) {
+			cb(0, boost::any(in6_addr_to_string(mNCPMeshLocalAddress)));
+		} else {
+			cb(kWPANTUNDStatus_FeatureNotSupported, std::string("Property is unavailable"));
+		}
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_IPv6LinkLocalAddress)) {
+		if (buffer_is_nonzero(mNCPLinkLocalAddress.s6_addr, sizeof(mNCPLinkLocalAddress))) {
+			cb(0, boost::any(in6_addr_to_string(mNCPLinkLocalAddress)));
+		} else {
+			cb(kWPANTUNDStatus_FeatureNotSupported, std::string("Property is unavailable"));
+		}
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix)) {
+		if (mLegacyInterfaceEnabled || mNodeTypeSupportsLegacy || buffer_is_nonzero(mNCPV6LegacyPrefix, sizeof(mNCPV6LegacyPrefix))) {
+			cb(0, boost::any(nl::Data(mNCPV6LegacyPrefix, sizeof(mNCPV6LegacyPrefix))));
+		} else {
+			cb(kWPANTUNDStatus_FeatureNotSupported, std::string("Property is unavailable"));
+		}
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NestLabs_LegacyMeshLocalAddress)) {
+		struct in6_addr legacy_addr;
+
+		if ( (mLegacyInterfaceEnabled || mNodeTypeSupportsLegacy)
+		  && buffer_is_nonzero(mNCPV6LegacyPrefix, sizeof(mNCPV6LegacyPrefix))
+		) {
+			legacy_addr = make_slaac_addr_from_eui64(mNCPV6LegacyPrefix, mMACAddress);
+			cb(0, boost::any(in6_addr_to_string(legacy_addr)));
+		} else {
+			cb(kWPANTUNDStatus_FeatureNotSupported, std::string("Property is unavailable"));
+		}
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NCPState)) {
+		if ( is_initializing_ncp()
+		  && !ncp_state_is_detached_from_ncp(get_ncp_state())
+		) {
+			cb(0, boost::any(std::string(kWPANTUNDStateUninitialized)));
+		} else {
+			cb(0, boost::any(ncp_state_to_string(get_ncp_state())));
+		}
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NetworkNodeType)) {
+		cb(0, boost::any(node_type_to_string(mNodeType)));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_IPv6AllAddresses) || strcaseequal(key.c_str(), kWPANTUNDProperty_DebugIPv6GlobalIPAddressList))  {
+		std::list<std::string> result;
+		std::map<struct in6_addr, GlobalAddressEntry>::const_iterator it;
+		char address_string[INET6_ADDRSTRLEN];
+		for ( it = mGlobalAddresses.begin();
+			  it != mGlobalAddresses.end();
+			  it++ ) {
+			inet_ntop(AF_INET6,	&it->first,	address_string, sizeof(address_string));
+			result.push_back(std::string(address_string)+ "  " + it->second.get_description());
+		}
+		cb(0, boost::any(result));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonSyslogMask)) {
+		std::string mask_string;
+		int logmask;
+
+		setlogmask(logmask = setlogmask(0));
+
+		if (LOG_FAC(logmask) == LOG_DAEMON) {
+			mask_string += "daemon ";
+		}
+		if (LOG_FAC(logmask) == LOG_USER) {
+			mask_string += "user ";
+		}
+		if (logmask & LOG_MASK(LOG_EMERG)) {
+			mask_string += "emerg ";
+		}
+		if (logmask & LOG_MASK(LOG_ALERT)) {
+			mask_string += "alert ";
+		}
+		if (logmask & LOG_MASK(LOG_CRIT)) {
+			mask_string += "crit ";
+		}
+		if (logmask & LOG_MASK(LOG_ERR)) {
+			mask_string += "err ";
+		}
+		if (logmask & LOG_MASK(LOG_WARNING)) {
+			mask_string += "warning ";
+		}
+		if (logmask & LOG_MASK(LOG_NOTICE)) {
+			mask_string += "notice ";
+		}
+		if (logmask & LOG_MASK(LOG_INFO)) {
+			mask_string += "info ";
+		}
+		if (logmask & LOG_MASK(LOG_DEBUG)) {
+			mask_string += "debug ";
+		}
+
+		cb(0, mask_string);
+
+	} else if (StatCollector::is_a_stat_property(key)) {
+		get_stat_collector().get_property(key, cb);
+
+	} else {
+		cb(kWPANTUNDStatus_PropertyNotFound, boost::any(std::string("Property Not Found")));
+	}
+}
+
+void
+NCPInstanceBase::set_property(
+	const std::string& key,
+	const boost::any& value,
+	CallbackWithStatus cb
+) {
+	// If we are disabled, then the only property we
+	// are allowed to set is kWPANTUNDProperty_DaemonEnabled.
+	if (!mEnabled && !strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonEnabled)) {
+		cb(kWPANTUNDStatus_InvalidWhenDisabled);
+		return;
+	}
+
+	try {
+		if (strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonEnabled)) {
+			mEnabled = any_to_bool(value);
+			cb(0);
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonAutoAssociateAfterReset)) {
+			mAutoResume = any_to_bool(value);
+			cb(0);
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_NestLabs_NetworkPassthruPort)) {
+			mCommissionerPort = static_cast<uint16_t>(any_to_int(value));
+			cb(0);
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonAutoFirmwareUpdate)) {
+			bool value_bool = any_to_bool(value);
+
+			if (value_bool && !mAutoUpdateFirmware) {
+				if (get_ncp_state() == FAULT) {
+					syslog(LOG_ALERT, "The NCP is misbehaving: Attempting a firmware update");
+					upgrade_firmware();
+				} else if (get_ncp_state() != UNINITIALIZED) {
+					if (is_firmware_upgrade_required(mNCPVersionString)) {
+						syslog(LOG_NOTICE, "NCP FIRMWARE UPGRADE IS REQUIRED");
+						upgrade_firmware();
+					}
+				}
+			}
+
+			mAutoUpdateFirmware = value_bool;
+
+			cb(0);
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonTerminateOnFault)) {
+			mTerminateOnFault = any_to_bool(value);
+			cb(0);
+			if (mTerminateOnFault && (get_ncp_state() == FAULT)) {
+				reinitialize_ncp();
+			}
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_IPv6MeshLocalPrefix) || strcaseequal(key.c_str(), kWPANTUNDProperty_IPv6MeshLocalAddress)) {
+			if (get_ncp_state() <= OFFLINE) {
+				nl::Data prefix;
+
+				if (value.type() == typeid(std::string)) {
+					uint8_t ula_bytes[16] = {};
+					const std::string ip_string(any_to_string(value));
+
+					// Address-style
+					int bits = inet_pton(AF_INET6,ip_string.c_str(),ula_bytes);
+					if (bits <= 0) {
+						// Prefix is the wrong length.
+						cb(kWPANTUNDStatus_InvalidArgument);
+						return;
+					}
+
+					prefix = nl::Data(ula_bytes, 8);
+				} else {
+					prefix = any_to_data(value);
+				}
+
+				if (prefix.size() < sizeof(mNCPV6Prefix)) {
+					// Prefix is the wrong length.
+					cb(kWPANTUNDStatus_InvalidArgument);
+				}
+				memcpy(mNCPV6Prefix, prefix.data(), sizeof(mNCPV6Prefix));
+				cb(0);
+			} else {
+				cb(kWPANTUNDStatus_InvalidForCurrentState);
+			}
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonAutoDeepSleep)) {
+			mAutoDeepSleep = any_to_bool(value);
+
+			if (mAutoDeepSleep == false
+			    && mNCPState == DEEP_SLEEP
+				&& mEnabled
+			) {
+				// Wake us up if we are asleep and deep sleep was turned off.
+				get_control_interface().refresh_state(boost::bind(cb,0));
+			} else {
+				cb(0);
+			}
+
+		} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonSyslogMask)) {
+			setlogmask(strtologmask(any_to_string(value).c_str(), setlogmask(0)));
+			cb(0);
+
+		} else if (StatCollector::is_a_stat_property(key)) {
+			get_stat_collector().set_property(key, value, cb);
+
+		} else {
+			syslog(LOG_ERR,"set_property: Unsupported property \"%s\"", key.c_str());
+			cb(kWPANTUNDStatus_PropertyNotFound);
+		}
+
+	} catch (const boost::bad_any_cast &x) {
+		// We will get a bad_any_cast exception if the property is of
+		// the wrong type.
+		syslog(LOG_ERR,"set_property: Bad type for property \"%s\" (%s)", key.c_str(), x.what());
+		cb(kWPANTUNDStatus_InvalidArgument);
+
+	} catch (const std::invalid_argument &x) {
+		// We will get a bad_any_cast exception if the property is of
+		// the wrong type.
+		syslog(LOG_ERR,"set_property: Invalid argument for property \"%s\" (%s)", key.c_str(), x.what());
+		cb(kWPANTUNDStatus_InvalidArgument);
+	}
+}
+
+void
+NCPInstanceBase::signal_property_changed(
+	const std::string& key,
+	const boost::any& value
+) {
+	get_control_interface().mOnPropertyChanged(key, value);
+}
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+void
+NCPInstanceBase::set_initializing_ncp(bool x)
+{
+	if (mIsInitializingNCP != x) {
+		mIsInitializingNCP = x;
+
+		if (mIsInitializingNCP) {
+			change_ncp_state(UNINITIALIZED);
+			set_ncp_power(true);
+		} else if ( (get_ncp_state() != UNINITIALIZED)
+		         && (get_ncp_state() != FAULT)
+		         && (get_ncp_state() != UPGRADING)
+		) {
+			handle_ncp_state_change(get_ncp_state(), UNINITIALIZED);
+		}
+	}
+}
+
+bool
+NCPInstanceBase::is_initializing_ncp() const
+{
+	return mIsInitializingNCP;
+}
+
+NCPState
+NCPInstanceBase::get_ncp_state()const
+{
+	return mNCPState;
+}
+
+bool
+NCPInstanceBase::is_state_change_valid(NCPState new_ncp_state)const
+{
+	// Add any invalid state transitions here so that
+	// bugs can be more quickly identified and corrected.
+
+	if (ncp_state_is_detached_from_ncp(get_ncp_state())) {
+		return new_ncp_state == UNINITIALIZED;
+	}
+
+	return true;
+}
+
+void
+NCPInstanceBase::change_ncp_state(NCPState new_ncp_state)
+{
+	NCPState old_ncp_state = mNCPState;
+
+	if (old_ncp_state != new_ncp_state) {
+		if (!is_state_change_valid(new_ncp_state)) {
+			syslog(
+				LOG_WARNING,
+				"BUG: Invalid state change: \"%s\" -> \"%s\"",
+				ncp_state_to_string(old_ncp_state).c_str(),
+				ncp_state_to_string(new_ncp_state).c_str()
+			);
+
+			if (ncp_state_is_detached_from_ncp(get_ncp_state())) {
+				// If the state was detached, do not allow the
+				// state change to continue.
+				return;
+			}
+		} else {
+			syslog(
+				LOG_NOTICE,
+				"State change: \"%s\" -> \"%s\"",
+				ncp_state_to_string(old_ncp_state).c_str(),
+				ncp_state_to_string(new_ncp_state).c_str()
+			);
+		}
+
+		mNCPState = new_ncp_state;
+
+		if ( !mIsInitializingNCP
+		  || (new_ncp_state == UNINITIALIZED)
+		  || (new_ncp_state == FAULT)
+		  || (new_ncp_state == UPGRADING)
+		) {
+			handle_ncp_state_change(new_ncp_state, old_ncp_state);
+		}
+	}
+}
+
+void
+NCPInstanceBase::handle_ncp_state_change(NCPState new_ncp_state, NCPState old_ncp_state)
+{
+	// Detached NCP -> Online NCP
+	if (ncp_state_is_detached_from_ncp(old_ncp_state)
+	 && !ncp_state_is_detached_from_ncp(new_ncp_state)
+	) {
+		__ASSERT_MACROS_check(new_ncp_state == UNINITIALIZED);
+
+		// We are transitioning out of a state where we are disconnected
+		// from the NCP. This requires a hard reset.
+		set_ncp_power(true);
+
+		if (mResetFD >= 0) {
+			// If we have a way to hard reset the NCP,
+			// then do it. We do the check above to make
+			// sure that we don't end up calling mSerialAdapter->reset()
+			// twice.
+			hard_reset_ncp();
+		}
+
+		mSerialAdapter->reset();
+
+		PT_INIT(&mControlPT);
+	}
+
+	// Online NCP -> Detached NCP
+	else if (!ncp_state_is_detached_from_ncp(old_ncp_state)
+	 && ncp_state_is_detached_from_ncp(new_ncp_state)
+	) {
+		// We are transitioning into a state where we need to be disconnected
+		// from the NCP. For this we use the hibernate command.
+		mSerialAdapter->hibernate();
+		PT_INIT(&mControlPT);
+		NLPT_INIT(&mDriverToNCPPumpPT);
+		NLPT_INIT(&mNCPToDriverPumpPT);
+		mFailureCount = 0;
+
+		if (new_ncp_state == FAULT) {
+			// When we enter the fault state, attempt to
+			// ensure that we are using as little power as
+			// possible by physically turning off the NCP
+			// (if a method of doing so has been specified
+			// in our configuration)
+			set_ncp_power(false);
+
+			if (mTerminateOnFault) {
+				signal_fatal_error(kWPANTUNDStatus_Failure);
+			}
+		}
+		return;
+	}
+
+	// Interface Down -> Interface Up
+	if (!ncp_state_is_interface_up(old_ncp_state)
+	 && ncp_state_is_interface_up(new_ncp_state)
+	) {
+		set_online(true);
+
+
+	// InterfaceUp -> COMMISSIONED
+	// (Special case of InterfaceUp -> InterfaceDown)
+	} else if (ncp_state_is_interface_up(old_ncp_state)
+				&& (new_ncp_state == COMMISSIONED)
+				&& mAutoResume
+	) {
+		// We don't bother going further if autoresume is on.
+		return;
+
+
+	// Commissioned -> InterfaceDown
+	// (Special case of InterfaceUp -> InterfaceDown)
+	} else if (ncp_state_is_commissioned(old_ncp_state)
+		&& !ncp_state_is_commissioned(new_ncp_state)
+		&& !ncp_state_is_sleeping(new_ncp_state)
+		&& (new_ncp_state != UNINITIALIZED)
+	) {
+		reset_interface();
+
+
+	// Uninitialized -> Offline
+	// If we are transitioning from uninitialized to offline,
+	// and we have global addresses, then need to clear them out.
+	} else if (old_ncp_state == UNINITIALIZED
+		&& new_ncp_state == OFFLINE
+		&& !mGlobalAddresses.empty()
+	) {
+		reset_interface();
+
+
+	// InterfaceUp -> InterfaceDown (General Case)
+	} else if (ncp_state_is_interface_up(old_ncp_state)
+		&& !ncp_state_is_interface_up(new_ncp_state)
+		&& new_ncp_state != NET_WAKE_WAKING
+	) {
+		// Take the interface offline.
+		syslog(LOG_NOTICE, "Taking interface(s) down. . .");
+
+		mCurrentNetworkInstance.joinable = false;
+		set_commissioniner(0, 0, 0);
+		set_online(false);
+	}
+
+	// We don't announce transitions to the "UNITIALIZED" state.
+	if (UNINITIALIZED != new_ncp_state) {
+		signal_property_changed(kWPANTUNDProperty_NCPState, ncp_state_to_string(new_ncp_state));
+	}
+
+	mNetworkRetain.handle_ncp_state_change(new_ncp_state, old_ncp_state);
+}
+
+void
+NCPInstanceBase::reinitialize_ncp(void)
+{
+	PT_INIT(&mControlPT);
+	change_ncp_state(UNINITIALIZED);
+}
+
+void
+NCPInstanceBase::reset_tasks(wpantund_status_t status)
+{
+}
+
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+
+bool
+NCPInstanceBase::is_busy(void)
+{
+	const NCPState ncp_state = get_ncp_state();
+	bool is_busy = ncp_state_is_busy(ncp_state);
+
+	if (is_initializing_ncp()) {
+		return true;
+	}
+
+	if (ncp_state == FAULT) {
+		return false;
+	}
+
+	if (get_upgrade_status() == EINPROGRESS) {
+		is_busy = true;
+	}
+
+	return is_busy;
+}
+
+StatCollector&
+NCPInstanceBase::get_stat_collector(void)
+{
+	return mStatCollector;
+}
+
+void
+NCPInstanceBase::update_busy_indication(void)
+{
+    cms_t current_time = time_ms();
+
+	if (mWasBusy != is_busy()) {
+		if (!mWasBusy
+			|| (mLastChangedBusy == 0)
+			|| (current_time - mLastChangedBusy >= BUSY_DEBOUNCE_TIME_IN_MS)
+			|| (current_time - mLastChangedBusy < 0)
+		) {
+			mWasBusy = !mWasBusy;
+			if(!mWasBusy) {
+				if (mLastChangedBusy == 0) {
+					syslog(LOG_INFO, "NCP is no longer busy, host sleep is permitted.");
+				} else {
+					syslog(LOG_INFO, "NCP is no longer busy, host sleep is permitted. (Was busy for %dms)",(int)(current_time - mLastChangedBusy));
+				}
+				signal_property_changed(kWPANTUNDProperty_DaemonReadyForHostSleep, true);
+			} else {
+				syslog(LOG_INFO, "NCP is now BUSY.");
+				signal_property_changed(kWPANTUNDProperty_DaemonReadyForHostSleep, false);
+			}
+			mLastChangedBusy = current_time;
+		}
+	} else if (mWasBusy
+		&& (mLastChangedBusy != 0)
+		&& (current_time - mLastChangedBusy > MAX_INSOMNIA_TIME_IN_MS)
+	) {
+		syslog(LOG_ERR, "Experiencing extended insomnia. Resetting internal state.");
+
+		mLastChangedBusy = current_time;
+
+		ncp_is_misbehaving();
+	}
+}
+
+void
+NCPInstanceBase::ncp_is_misbehaving()
+{
+	mFailureCount++;
+	hard_reset_ncp();
+	reset_tasks();
+	reinitialize_ncp();
+
+	if (mFailureCount >= mFailureThreshold) {
+		change_ncp_state(FAULT);
+	}
+}
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+bool
+NCPInstanceBase::is_firmware_upgrade_required(const std::string& version)
+{
+	return mFirmwareUpgrade.is_firmware_upgrade_required(version);
+}
+
+void
+NCPInstanceBase::upgrade_firmware(void)
+{
+	change_ncp_state(UPGRADING);
+
+	set_ncp_power(true);
+
+	return mFirmwareUpgrade.upgrade_firmware();
+}
+
+int
+NCPInstanceBase::get_upgrade_status(void)
+{
+	return mFirmwareUpgrade.get_upgrade_status();
+}
+
+bool
+NCPInstanceBase::can_upgrade_firmware(void)
+{
+	return mFirmwareUpgrade.can_upgrade_firmware();
+}
diff --git a/src/wpantund/NCPInstanceBase.h b/src/wpantund/NCPInstanceBase.h
new file mode 100644
index 0000000..b614c1c
--- /dev/null
+++ b/src/wpantund/NCPInstanceBase.h
@@ -0,0 +1,353 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__NCPInstanceBase__
+#define __wpantund__NCPInstanceBase__
+
+#include "NCPInstance.h"
+#include <set>
+#include <map>
+#include <string>
+#include "FirmwareUpgrade.h"
+#include "EventHandler.h"
+#include "NCPTypes.h"
+#include "StatCollector.h"
+#include "NetworkRetain.h"
+#include "RunawayResetBackoffManager.h"
+#include "Pcap.h"
+
+namespace nl {
+namespace wpantund {
+
+class NCPInstanceBase : public NCPInstance, public EventHandler{
+public:
+
+	enum {
+		FRAME_TYPE_DATA = 2,
+		FRAME_TYPE_INSECURE_DATA = 3,
+		FRAME_TYPE_LEGACY_DATA = 4
+	};
+
+protected:
+	NCPInstanceBase(const Settings& settings = Settings());
+
+public:
+	virtual ~NCPInstanceBase();
+
+	virtual const std::string &get_name();
+
+	virtual void set_socket_adapter(const boost::shared_ptr<SocketAdapter> &adapter);
+
+public:
+	// ========================================================================
+	// Static Functions
+
+	static bool setup_property_supported_by_class(const std::string& prop_name);
+
+
+public:
+	// ========================================================================
+	// MARK: ASync I/O
+
+	virtual cms_t get_ms_to_next_event(void);
+
+	virtual int update_fd_set(
+		fd_set *read_fd_set,
+		fd_set *write_fd_set,
+		fd_set *error_fd_set,
+		int *max_fd,
+		cms_t *timeout
+	);
+
+	virtual void process(void);
+
+	// Helpful for use with callbacks.
+	int process_event_helper(int event);
+
+	virtual StatCollector& get_stat_collector(void);
+
+protected:
+	virtual char ncp_to_driver_pump() = 0;
+	virtual char driver_to_ncp_pump() = 0;
+
+public:
+	// ========================================================================
+	// MARK: NCP Behavior
+
+	virtual void hard_reset_ncp(void);
+
+	virtual int set_ncp_power(bool power);
+
+	virtual bool can_set_ncp_power(void);
+
+public:
+	// ========================================================================
+	// MARK: Other
+
+	virtual void reinitialize_ncp(void);
+
+	virtual void reset_tasks(wpantund_status_t status = kWPANTUNDStatus_Canceled);
+
+	NCPState get_ncp_state()const;
+
+	bool is_state_change_valid(NCPState new_ncp_state)const;
+
+	//! Handles transitioning from state-to-state.
+	/*! This is the ONLY WAY to change mNCPState. */
+	void change_ncp_state(NCPState new_ncp_state);
+
+	virtual void handle_ncp_state_change(NCPState new_ncp_state, NCPState old_ncp_state);
+
+	virtual void ncp_is_misbehaving();
+
+	virtual void set_initializing_ncp(bool x);
+
+	virtual bool is_initializing_ncp()const;
+
+public:
+	// ========================================================================
+	// MARK: Network Interface Methods
+
+	int set_online(bool x);
+
+	void set_mac_address(const uint8_t addr[8]);
+
+	void set_mac_hardware_address(const uint8_t addr[8]);
+
+	void reset_interface(void);
+
+	const WPAN::NetworkInstance& get_current_network_instance(void)const;
+
+public:
+	// ========================================================================
+	// MARK: Global Address Management
+
+
+	void add_address(const struct in6_addr &address, uint8_t prefix = 64, uint32_t valid_lifetime = UINT32_MAX, uint32_t preferred_lifetime = UINT32_MAX);
+	void remove_address(const struct in6_addr &address);
+
+	void refresh_global_addresses();
+
+	//! Removes all nonpermanent global address entries
+	void clear_nonpermanent_global_addresses();
+
+	void restore_global_addresses();
+
+	bool is_address_known(const struct in6_addr &address);
+
+	bool lookup_address_for_prefix(struct in6_addr *address, const struct in6_addr &prefix, int prefix_len_in_bits = 64);
+
+	int join_multicast_group(const std::string &group_name);
+
+public:
+	// ========================================================================
+	// MARK: Subclass Hooks
+
+	virtual void address_was_added(const struct in6_addr& addr, int prefix_len);
+
+	virtual void address_was_removed(const struct in6_addr& addr, int prefix_len);
+
+public:
+	// ========================================================================
+	// MARK: Firmware Upgrade
+
+	virtual bool is_firmware_upgrade_required(const std::string& version);
+
+	virtual void upgrade_firmware(void);
+
+	virtual int get_upgrade_status(void);
+
+	virtual bool can_upgrade_firmware(void);
+
+public:
+	// ========================================================================
+	// MARK: Busy/OkToSleep
+
+	virtual bool is_busy(void);
+
+	virtual void update_busy_indication(void);
+
+public:
+	// ========================================================================
+	// MARK: IPv6 data path helpers
+
+	bool should_forward_hostbound_frame(uint8_t* type, const uint8_t* packet, size_t packet_length);
+
+	bool should_forward_ncpbound_frame(uint8_t* type, const uint8_t* packet, size_t packet_length);
+
+	void handle_normal_ipv6_from_ncp(const uint8_t* packet, size_t packet_length);
+
+	int set_commissioniner(int seconds, uint8_t traffic_type, in_port_t traffic_port);
+
+public:
+	// ========================================================================
+	// MARK: Legacy Interface Methods
+
+	void enable_legacy_interface(void);
+
+	bool is_legacy_interface_enabled(void);
+
+	void handle_alt_ipv6_from_ncp(const uint8_t* packet, size_t packet_length);
+
+public:
+
+	virtual std::set<std::string> get_supported_property_keys()const;
+
+	virtual void get_property(
+	    const std::string& key,
+	    CallbackWithStatusArg1 cb
+	);
+
+	virtual void set_property(
+	    const std::string& key,
+	    const boost::any& value,
+	    CallbackWithStatus cb
+	);
+
+	virtual void signal_property_changed(
+	    const std::string& key,
+	    const boost::any& value = boost::any()
+	);
+
+	wpantund_status_t set_ncp_version_string(const std::string& version_string);
+
+protected:
+	// ========================================================================
+	// MARK: Protected Data
+
+	boost::shared_ptr<TunnelIPv6Interface> mPrimaryInterface;
+
+	boost::shared_ptr<SocketWrapper> mRawSerialAdapter;
+	boost::shared_ptr<SocketWrapper> mSerialAdapter;
+
+	struct nlpt mNCPToDriverPumpPT;
+	struct nlpt mDriverToNCPPumpPT;
+
+	std::map<struct in6_addr, GlobalAddressEntry> mGlobalAddresses;
+
+	IPv6PacketMatcherRule mCommissioningRule;
+	IPv6PacketMatcher mInsecureFirewall;
+	IPv6PacketMatcher mDropFirewall;
+
+	time_t mCommissioningExpiration;
+
+	std::string mNCPVersionString;
+
+	bool mEnabled;
+	bool mTerminateOnFault;
+	bool mAutoUpdateFirmware;
+	bool mAutoResume;
+	bool mAutoDeepSleep;
+	int mAutoDeepSleepTimeout; // In seconds
+	uint16_t mCommissionerPort;
+
+private:
+	NCPState mNCPState;
+	bool mIsInitializingNCP;
+
+protected:
+	//! This is set to the currently used MAC address (EUI64).
+	uint8_t mMACAddress[8];
+
+	//! This is set to the manufacturer-assigned permanent EUI64 address.
+	uint8_t mMACHardwareAddress[8];
+	union {
+		uint8_t mNCPV6Prefix[8];
+		struct in6_addr mNCPMeshLocalAddress;
+	};
+	struct in6_addr mNCPLinkLocalAddress;
+
+	WPAN::NetworkInstance mCurrentNetworkInstance;
+
+	std::set<unsigned int> mSupprotedChannels;
+
+	NodeType mNodeType;
+
+	int mFailureCount;
+	int mFailureThreshold;
+
+	RunawayResetBackoffManager mRunawayResetBackoffManager;
+
+protected:
+	// ========================================================================
+	// MARK: Legacy Interface Support
+
+	boost::shared_ptr<TunnelIPv6Interface> mLegacyInterface;
+	IPv6PacketMatcher mLegacyCommissioningMatcher;
+	uint8_t mNCPV6LegacyPrefix[8];
+	bool mLegacyInterfaceEnabled;
+	bool mNodeTypeSupportsLegacy;
+
+	PcapManager mPcapManager;
+
+private:
+	// ========================================================================
+	// MARK: Private Data
+
+	int mResetFD; //!^ File descriptor for resetting NCP.
+	char mResetFD_BeginReset; //!^ Value for entering reset
+	char mResetFD_EndReset; //!^ Value for leaving reset
+
+	int mPowerFD; //!^ File descriptor for controlling NCP power.
+	char mPowerFD_PowerOn; //!^ Value for the power being on.
+	char mPowerFD_PowerOff; //!^ Value for the power being off.
+
+	int mMCFD; //!^ File descriptor for multicast stuff.
+
+	bool mWasBusy;
+	cms_t mLastChangedBusy;
+
+	FirmwareUpgrade mFirmwareUpgrade;
+
+	NetworkRetain mNetworkRetain;
+
+	StatCollector mStatCollector;  // Statistic collector
+}; // class NCPInstance
+
+}; // namespace wpantund
+
+}; // namespace nl
+
+// This callback is not sent from the NCP. It is a fake NCP
+// callback sent from the processing thread to indicate that
+// the NCP is in deep sleep.
+#define EVENT_NCP_DISABLED                 0x78C9
+
+#define EVENT_NCP_CONN_RESET               0x78CB
+
+// Extracts a pointer and length from argument list and
+// returns a `nl::Data` object.
+static inline nl::Data
+va_arg_as_Data(va_list args)
+{
+	const uint8_t* data = NULL;
+	size_t data_len = 0;
+
+	data = va_arg(args, const uint8_t*);
+	data_len = va_arg(args, size_t);
+
+	// Sanity check
+	assert(data_len < 1024*1024);
+
+	return nl::Data(data, data_len);
+}
+
+#define va_arg_small(args, type)		static_cast<type>(va_arg(args, int))
+
+#endif /* defined(__wpantund__NCPInstanceBase__) */
diff --git a/src/wpantund/NCPMfgInterface_v0.h b/src/wpantund/NCPMfgInterface_v0.h
new file mode 100644
index 0000000..6ba384c
--- /dev/null
+++ b/src/wpantund/NCPMfgInterface_v0.h
@@ -0,0 +1,50 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef wpantund_NCPMfgInterface_v0_h
+#define wpantund_NCPMfgInterface_v0_h
+
+#include "NCPControlInterface.h"
+
+namespace nl {
+namespace wpantund {
+
+class NCPMfgInterface_v0 {
+public:
+	virtual void mfg_start(CallbackWithStatus cb) { }
+
+
+	virtual void mfg_finish(CallbackWithStatusArg1 cb) = 0;
+	virtual void mfg_begin_test(uint8_t type, CallbackWithStatus cb) = 0;
+	virtual void mfg_end_test(uint8_t type, CallbackWithStatus cb) = 0;
+	virtual void mfg_tx_packet(const Data& packet, int16_t repeat, CallbackWithStatus cb) = 0;
+
+	virtual void mfg_clockmon(bool enable, uint32_t timerId, CallbackWithStatus cb) = 0;
+	virtual void mfg_gpio_set(uint8_t port_pin, uint8_t config, uint8_t value, CallbackWithStatus cb) = 0;
+	virtual void mfg_gpio_get(uint8_t port_pin, CallbackWithStatusArg1 cb) = 0;
+	virtual void mfg_channelcal(uint8_t channel, uint32_t duration,  CallbackWithStatus cb) = 0;
+	virtual void mfg_channelcal_get(uint8_t channel, CallbackWithStatusArg1 cb) = 0;
+
+	boost::signals2::signal<void(Data, uint8_t, int8_t)> mOnMfgRXPacket;
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+#endif
diff --git a/src/wpantund/NCPMfgInterface_v1.h b/src/wpantund/NCPMfgInterface_v1.h
new file mode 100644
index 0000000..fd7fd71
--- /dev/null
+++ b/src/wpantund/NCPMfgInterface_v1.h
@@ -0,0 +1,37 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef wpantund_NCPMfgInterface_v1_h
+#define wpantund_NCPMfgInterface_v1_h
+
+#include "NCPControlInterface.h"
+
+namespace nl {
+namespace wpantund {
+
+class NCPMfgInterface_v1 {
+public:
+	virtual void mfg(const std::string& mfg_command, CallbackWithStatusArg1 cb = NilReturn()) = 0;
+
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+#endif
diff --git a/src/wpantund/NCPTypes.cpp b/src/wpantund/NCPTypes.cpp
new file mode 100644
index 0000000..0d038fb
--- /dev/null
+++ b/src/wpantund/NCPTypes.cpp
@@ -0,0 +1,393 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "NCPTypes.h"
+#include "string-utils.h"
+#include <string>
+#include "wpan-properties.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+using namespace nl;
+using namespace wpantund;
+
+
+// ----------------------------------------------------------------------------
+// MARK: -
+// MARK: Static Methods
+
+bool
+nl::wpantund::ncp_state_is_sleeping(NCPState x)
+{
+	switch(x) {
+	case DEEP_SLEEP:
+	case NET_WAKE_ASLEEP:
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool
+nl::wpantund::ncp_state_has_joined(NCPState x)
+{
+	switch(x) {
+	case ASSOCIATED:
+	case ISOLATED:
+	case NET_WAKE_ASLEEP:
+	case NET_WAKE_WAKING:
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool
+nl::wpantund::ncp_state_is_joining(NCPState x)
+{
+	switch(x) {
+	case ASSOCIATING:
+	case CREDENTIALS_NEEDED:
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool
+nl::wpantund::ncp_state_is_interface_up(NCPState x)
+{
+	switch(x) {
+	case CREDENTIALS_NEEDED:
+	case ASSOCIATED:
+	case NET_WAKE_ASLEEP:
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool
+nl::wpantund::ncp_state_is_commissioned(NCPState x)
+{
+	switch(x) {
+	case COMMISSIONED:
+	case ASSOCIATED:
+	case NET_WAKE_ASLEEP:
+	case ISOLATED:
+	case NET_WAKE_WAKING:
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool
+nl::wpantund::ncp_state_is_initializing(NCPState x)
+{
+	switch(x) {
+	case UNINITIALIZED:
+	case UPGRADING:
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool
+nl::wpantund::ncp_state_is_joining_or_joined(NCPState x)
+{
+	switch(x) {
+	case CREDENTIALS_NEEDED:
+	case ASSOCIATING:
+	case ASSOCIATED:
+	case ISOLATED:
+	case NET_WAKE_WAKING:
+	case NET_WAKE_ASLEEP:
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool
+nl::wpantund::ncp_state_is_associated(NCPState x)
+{
+	switch(x) {
+	case ASSOCIATED:
+	case ISOLATED:
+	case NET_WAKE_WAKING:
+	case NET_WAKE_ASLEEP:
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool
+nl::wpantund::ncp_state_is_detached_from_ncp(NCPState x)
+{
+	switch(x) {
+	case FAULT:
+	case UPGRADING:
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool
+nl::wpantund::ncp_state_is_busy(NCPState x)
+{
+	switch(x) {
+	case DEEP_SLEEP:
+	case OFFLINE:
+	case NET_WAKE_ASLEEP:
+	case ISOLATED:
+	case ASSOCIATED:
+	case FAULT:
+		return false;
+	default:
+		return true;
+	}
+}
+
+std::string
+nl::wpantund::ncp_state_to_string(NCPState state)
+{
+	switch (state) {
+	case UNINITIALIZED:      return kWPANTUNDStateUninitialized;
+	case FAULT:              return kWPANTUNDStateFault;
+	case UPGRADING:          return kWPANTUNDStateUpgrading;
+	case DEEP_SLEEP:         return kWPANTUNDStateDeepSleep;
+	case OFFLINE:            return kWPANTUNDStateOffline;
+	case COMMISSIONED:       return kWPANTUNDStateCommissioned;
+	case ASSOCIATING:        return kWPANTUNDStateAssociating;
+	case CREDENTIALS_NEEDED: return kWPANTUNDStateCredentialsNeeded;
+	case ASSOCIATED:         return kWPANTUNDStateAssociated;
+	case ISOLATED:           return kWPANTUNDStateIsolated;
+	case NET_WAKE_ASLEEP:    return kWPANTUNDStateNetWake_Asleep;
+	case NET_WAKE_WAKING:    return kWPANTUNDStateNetWake_Waking;
+	}
+	return std::string("unknown-state");
+}
+
+std::string
+nl::wpantund::node_type_to_string(NodeType node_type)
+{
+	std::string ret;
+
+	switch (node_type) {
+	case UNKNOWN:
+		ret = kWPANTUNDNodeType_Unknown;
+		break;
+	case END_DEVICE:
+		ret = kWPANTUNDNodeType_EndDevice;
+		break;
+	case SLEEPY_END_DEVICE:
+		ret = kWPANTUNDNodeType_SleepyEndDevice;
+		break;
+	case ROUTER:
+		ret = kWPANTUNDNodeType_Router;
+		break;
+	case LURKER:
+		ret = kWPANTUNDNodeType_NestLurker;
+		break;
+	case LEADER:
+		ret = kWPANTUNDNodeType_Leader;
+		break;
+	case COMMISSIONER:
+		ret = kWPANTUNDNodeType_Commissioner;
+		break;
+	default:
+		{
+			char cstr[16];
+			snprintf(cstr, sizeof(cstr), "(node-type-%u)", (unsigned int)node_type);
+			ret = cstr;
+		}
+		break;
+	}
+
+	return ret;
+}
+
+nl::wpantund::NodeType
+nl::wpantund::string_to_node_type(const std::string& node_type_string)
+{
+	if (strcaseequal(node_type_string.c_str(), kWPANTUNDNodeType_EndDevice) ||
+	    strcaseequal(node_type_string.c_str(), "end") ||
+	    strcaseequal(node_type_string.c_str(), "e") ||
+	    (node_type_string == "3"))
+	{
+		return END_DEVICE;
+	}
+
+	if (strcaseequal(node_type_string.c_str(), kWPANTUNDNodeType_SleepyEndDevice) ||
+	    strcaseequal(node_type_string.c_str(), "sleepy") ||
+	    strcaseequal(node_type_string.c_str(), "sed") ||
+	    strcaseequal(node_type_string.c_str(), "s") ||
+	    (node_type_string == "4"))
+	{
+		return SLEEPY_END_DEVICE;
+	}
+
+	if (strcaseequal(node_type_string.c_str(), kWPANTUNDNodeType_Router) ||
+	    strcaseequal(node_type_string.c_str(), "r") ||
+	    (node_type_string == "2"))
+	{
+		return ROUTER;
+	}
+
+	if (strcaseequal(node_type_string.c_str(), kWPANTUNDNodeType_Leader))
+	{
+		return LEADER;
+	}
+
+	if (strcaseequal(node_type_string.c_str(), kWPANTUNDNodeType_NestLurker) ||
+	    strcaseequal(node_type_string.c_str(), "lurker") ||
+	    (node_type_string == "6"))
+	{
+		return LURKER;
+	}
+
+	return UNKNOWN;
+}
+
+std::string
+nl::wpantund::address_flags_to_string(uint8_t flags)
+{
+	std::string ret;
+	int i;
+	for (i = 7; i >=0 ; --i) {
+		uint8_t mask = (1<<i);
+		if (i == 3) {
+			ret += ' ';
+		}
+		if (!(mask & flags)) {
+			ret += '-';
+			continue;
+		}
+		switch (mask) {
+		case GA_AM_GATEWAY:			//0
+			ret += 'G';
+			break;
+		case GA_AM_DHCP_SERVER:		//1
+			ret += 'D';
+			break;
+		case GA_AM_SLAAC_SERVER:	//2
+			ret += 'S';
+			break;
+		case GA_DHCP:				// 3
+			ret += 'd';
+			break;
+		case GA_SLAAC:				// 4
+			ret += 's';
+			break;
+		case GA_CONFIGURED:			// 5
+			ret += 'C';
+			break;
+		case GA_REQUEST_SENT:		//6
+			ret += 'R';
+			break;
+		case GA_REQUEST_FAILED:		//7
+			ret += 'F';
+			break;
+		default:
+			ret += '0' + i;
+			break;
+		}
+	}
+	return ret;
+}
+
+std::string
+nl::wpantund::flags_to_string(uint8_t flags, const char flag_lookup[8])
+{
+	std::string ret;
+	int i;
+	if (flag_lookup == NULL) {
+		flag_lookup = "76543210";
+	}
+	for (i = 7; i >= 0 ; --i) {
+		uint8_t mask = (1<<i);
+		if (i == 3) {
+			ret += ' ';
+		}
+		if (!(mask & flags)) {
+			ret += '-';
+			continue;
+		}
+		ret += flag_lookup[7-i];
+	}
+	return ret;
+}
+
+NCPState
+nl::wpantund::string_to_ncp_state(const std::string& state_string)
+{
+	if (state_string == kWPANTUNDStateFault) {
+		return FAULT;
+	} else if (state_string == kWPANTUNDStateUpgrading) {
+		return UPGRADING;
+	} else if (state_string == kWPANTUNDStateDeepSleep) {
+		return DEEP_SLEEP;
+	} else if (state_string == kWPANTUNDStateCommissioned) {
+		return COMMISSIONED;
+	} else if (state_string == kWPANTUNDStateCredentialsNeeded) {
+		return CREDENTIALS_NEEDED;
+	} else if (state_string == kWPANTUNDStateIsolated) {
+		return ISOLATED;
+	} else if (state_string == kWPANTUNDStateNetWake_Asleep) {
+		return NET_WAKE_ASLEEP;
+	} else if (state_string == kWPANTUNDStateNetWake_Waking) {
+		return NET_WAKE_WAKING;
+	}
+
+	if (strnequal(state_string.c_str(), kWPANTUNDStateUninitialized, sizeof(kWPANTUNDStateUninitialized)-1)) {
+		return UNINITIALIZED;
+	} else if (strnequal(state_string.c_str(), kWPANTUNDStateOffline, sizeof(kWPANTUNDStateOffline)-1)) {
+		return OFFLINE;
+	} else if (strnequal(state_string.c_str(), kWPANTUNDStateAssociating, sizeof(kWPANTUNDStateAssociating)-1)) {
+		return ASSOCIATING;
+	} else if (strnequal(state_string.c_str(), kWPANTUNDStateAssociated, sizeof(kWPANTUNDStateAssociated)-1)) {
+		return ASSOCIATED;
+	}
+
+	// Unknown
+	return UNINITIALIZED;
+}
+
+std::string
+GlobalAddressEntry::get_description() const
+{
+	char c_string[200];
+
+	snprintf(c_string, sizeof(c_string), "valid: %u  preferred: %u  flags: %s (0x%02X)",
+				mValidLifetime,
+				mPreferredLifetime,
+				address_flags_to_string(mFlags).c_str(),
+				mFlags);
+
+	return std::string(c_string);
+}
diff --git a/src/wpantund/NCPTypes.h b/src/wpantund/NCPTypes.h
new file mode 100644
index 0000000..7e22959
--- /dev/null
+++ b/src/wpantund/NCPTypes.h
@@ -0,0 +1,118 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__NCPTypes__
+#define __wpantund__NCPTypes__
+
+#include <stdint.h>
+#include "time-utils.h"
+#include <string>
+
+namespace nl {
+namespace wpantund {
+
+enum NCPState {
+	UNINITIALIZED,
+	FAULT,
+	UPGRADING,
+	DEEP_SLEEP,
+	OFFLINE,
+	COMMISSIONED,
+	ASSOCIATING,
+	CREDENTIALS_NEEDED,
+	ASSOCIATED,
+	ISOLATED,
+	NET_WAKE_WAKING,
+	NET_WAKE_ASLEEP,
+};
+
+enum NodeType {
+	UNKNOWN,
+	ROUTER,
+	END_DEVICE,
+	SLEEPY_END_DEVICE,
+	COMMISSIONER,
+	LURKER,
+	LEADER,
+};
+
+enum GlobalAddressFlags {
+	GA_AM_GATEWAY      = 0x01,
+	GA_AM_DHCP_SERVER  = 0x02,
+	GA_AM_SLAAC_SERVER = 0x04,
+	GA_DHCP            = 0x08,
+	GA_SLAAC           = 0x10,
+	GA_CONFIGURED      = 0x20,
+	GA_REQUEST_SENT    = 0x40,
+	GA_REQUEST_FAILED  = 0x80,
+};
+
+struct GlobalAddressEntry {
+	uint32_t mValidLifetime;
+	time_t mValidLifetimeExpiration;
+	uint32_t mPreferredLifetime;
+	time_t mPreferredLifetimeExpiration;
+	uint8_t mFlags;
+	uint8_t mUserAdded:1;
+
+	std::string get_description() const;
+};
+
+struct EnergyScanResultEntry
+{
+	uint8_t mChannel;
+	int8_t 	mMaxRssi;
+};
+
+std::string address_flags_to_string(uint8_t flags);
+
+std::string flags_to_string(uint8_t flags, const char flag_lookup[8] = "76543210");
+
+bool ncp_state_is_sleeping(NCPState x);
+
+bool ncp_state_has_joined(NCPState x);
+
+bool ncp_state_is_joining(NCPState x);
+
+bool ncp_state_is_commissioned(NCPState x);
+
+bool ncp_state_is_busy(NCPState x);
+
+bool ncp_state_is_joining_or_joined(NCPState x);
+
+bool ncp_state_is_interface_up(NCPState x);
+
+bool ncp_state_is_detached_from_ncp(NCPState x);
+
+bool ncp_state_is_initializing(NCPState x);
+
+bool ncp_state_is_associated(NCPState x);
+
+std::string ncp_state_to_string(NCPState state);
+
+NCPState string_to_ncp_state(const std::string& state_string);
+
+std::string node_type_to_string(NodeType node_type);
+
+NodeType string_to_node_type(const std::string& node_type_string);
+
+}; // namespace wpantund
+}; // namespace nl
+
+#endif  // defined(__wpantund__NCPTypes__)
diff --git a/src/wpantund/NetworkInstance.h b/src/wpantund/NetworkInstance.h
new file mode 100644
index 0000000..109d242
--- /dev/null
+++ b/src/wpantund/NetworkInstance.h
@@ -0,0 +1,172 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef wpantund_NetworkInstance_h
+#define wpantund_NetworkInstance_h
+
+#include <stdint.h>
+#include <string>
+#include <cstring>
+#include "string-utils.h"
+
+namespace nl {
+
+
+namespace wpantund {
+namespace WPAN {
+struct NetworkId {
+	std::string name;
+	uint8_t xpanid[8];
+
+	uint64_t
+	get_xpanid_as_uint64() const
+	{
+		union {
+			uint64_t val;
+			uint8_t data[8];
+		} x;
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+		memcpyrev(x.data, xpanid, 8);
+#else
+		memcpy(x.data, xpanid, 8);
+#endif
+		return x.val;
+	}
+
+	void
+	set_xpanid_as_uint64(const uint64_t &_xpanid)
+	{
+		union {
+			uint64_t val;
+			uint8_t data[8];
+		} x;
+		x.val = _xpanid;
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+		memcpyrev(xpanid, x.data, 8);
+#else
+		memcpy(xpanid, x.data, 8);
+#endif
+	}
+
+	NetworkId(const std::string& _name = "")
+		: name(_name)
+	{
+	}
+
+	NetworkId(
+	    const std::string& _name, const uint8_t _xpanid[8]
+	    )
+		: name(_name)
+	{
+		if (_xpanid) {
+			memcpy(xpanid, _xpanid, sizeof(xpanid));
+		} else {
+			memset(xpanid, 0, sizeof(xpanid));
+		}
+	}
+
+	NetworkId(
+	    const std::string& _name, const uint64_t &_xpanid
+	    )
+		: name(_name)
+	{
+		set_xpanid_as_uint64(_xpanid);
+	}
+
+	bool operator==(const NetworkId& rhs) const
+	{
+		return (name == rhs.name) &&
+		       (0 == memcmp(xpanid, rhs.xpanid, sizeof(xpanid)));
+	}
+};
+
+struct NetworkInstance : public NetworkId {
+	uint16_t panid;
+	uint8_t channel;
+	bool joinable;
+	int8_t rssi;
+	uint8_t lqi;
+	uint8_t type;
+	uint8_t hwaddr[8];
+	uint16_t saddr;
+	uint8_t version;
+
+public:
+	NetworkInstance(
+	    const std::string& _name = "",
+	    const uint8_t _xpanid[8] = NULL,
+	    uint16_t _panid = 0xFFFF, int _channel = 0,
+	    bool _joinable = false
+	    ) :
+		NetworkId(_name, _xpanid),
+		panid(_panid),
+		channel(_channel),
+		joinable(_joinable),
+		rssi(-128),
+		type(0),
+		hwaddr(),
+		version(0)
+	{
+	}
+	NetworkInstance(
+	    const std::string& _name,
+	    const uint64_t _xpanid,
+	    uint16_t _panid = 0xFFFF, int _channel = 0,
+	    bool _joinable = false
+	    ) :
+		NetworkId(_name, _xpanid),
+		panid(_panid),
+		channel(_channel),
+		joinable(_joinable),
+		rssi(-128),
+		type(0),
+		hwaddr(),
+		version(0)
+	{
+	}
+
+	bool operator==(const NetworkInstance& rhs) const
+	{
+		return NetworkId::operator==(rhs)
+		       && (panid == rhs.panid)
+		       && (channel == rhs.channel)
+		       && (type == rhs.type)
+		       && (0 == memcmp(hwaddr, rhs.hwaddr, 8));
+	}
+
+	bool operator!=(const NetworkInstance& rhs) const
+	{
+		return !(*this == rhs);
+	}
+
+	uint64_t get_hwaddr_as_uint64() const
+	{
+		union {
+			uint64_t ret;
+			uint8_t data[8];
+		};
+		memcpyrev(data, hwaddr, 8);
+		return ret;
+	}
+};
+}; // namespace WPAN
+}; // namespace wpantund
+}; // namespace nl
+
+#endif
diff --git a/src/wpantund/NetworkRetain.cpp b/src/wpantund/NetworkRetain.cpp
new file mode 100644
index 0000000..5716ca2
--- /dev/null
+++ b/src/wpantund/NetworkRetain.cpp
@@ -0,0 +1,215 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      NetworkRetain class implementation.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+#include "wpan-properties.h"
+#include "NetworkRetain.h"
+#include "socket-utils.h"
+
+#include <syslog.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+
+#if HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+using namespace nl;
+using namespace wpantund;
+
+NetworkRetain::NetworkRetain(void) :
+	mNetworkRetainFD(-1)
+{
+}
+
+NetworkRetain::~NetworkRetain()
+{
+	close_network_retain_fd();
+}
+
+void
+NetworkRetain::handle_ncp_state_change(NCPState new_ncp_state, NCPState old_ncp_state)
+{
+	require_quiet(mNetworkRetainFD >= 0, bail);
+
+	// Not-joined --> joined
+	if (!ncp_state_has_joined(old_ncp_state) && ncp_state_has_joined(new_ncp_state)) {
+		save_network_info();
+	}
+
+	// Initializing --> Offline
+	else if (ncp_state_is_initializing(old_ncp_state) && (new_ncp_state == OFFLINE)) {
+		recall_network_info();
+	}
+
+	// Joined --> Offline
+	else if (ncp_state_has_joined(old_ncp_state) && (new_ncp_state == OFFLINE)) {
+		erase_network_info();
+	}
+
+bail:
+	return;
+}
+
+void
+NetworkRetain::close_network_retain_fd(void)
+{
+	if (mNetworkRetainFD >= 0)
+	{
+		IGNORE_RETURN_VALUE(write(mNetworkRetainFD, "X", 1));
+		close(mNetworkRetainFD);
+		mNetworkRetainFD = -1;
+	}
+}
+
+void
+NetworkRetain::set_network_retain_command(const std::string& command)
+{
+	int status = -1;
+	pid_t pid = -1;
+
+	if (mNetworkRetainFD >= 0) {
+		close_network_retain_fd();
+	}
+
+	pid = fork_unixdomain_socket(&mNetworkRetainFD);
+
+	if (pid < 0) {
+		return;
+	}
+
+	if (pid == 0) {
+		int stdout_fd_copy = dup(STDOUT_FILENO);
+		int stdin_fd_copy = dup(STDIN_FILENO);
+		FILE* stdin_copy = NULL;
+		FILE* stdout_copy = NULL;
+
+		dup2(STDERR_FILENO,STDOUT_FILENO);
+
+		if (stdin_fd_copy >= 0) {
+			close(STDIN_FILENO);
+			stdin_copy = fdopen(stdin_fd_copy, "r");
+		}
+
+		if (stdout_fd_copy >= 0) {
+			stdout_copy = fdopen(stdout_fd_copy, "w");
+		}
+
+		// Double fork to avoid leaking zombie processes.
+		pid = fork();
+		if (pid < 0) {
+			syslog(LOG_ERR, "Call to fork() failed: %s (%d)", strerror(errno), errno);
+
+			_exit(errno);
+		}
+
+		if (0 == pid)  // In child process.
+		{
+			// Set the shell environment variable if it isn't set already.
+			setenv("SHELL",SOCKET_UTILS_DEFAULT_SHELL,0);
+
+			while ((ferror(stdin_copy) == 0) && (feof(stdin_copy) == 0)) {
+				int c;
+				std::string args;
+
+				c = fgetc(stdin_copy);
+
+				switch (c) {
+				case 'R':
+				case 'E':
+				case 'S':
+					args = " ";
+					args += c;
+
+					// Execute the requested command.
+					IGNORE_RETURN_VALUE(system((command + args).c_str()));
+					break;
+
+				case 'X':
+					_exit(EXIT_SUCCESS);
+					break;
+
+				default:
+					syslog(LOG_WARNING, "Got unrecognized char 0x%x in NetworkRetain child process.", (int)c);
+					break;
+				}
+			}
+
+			_exit(EXIT_FAILURE);
+		}
+
+		_exit(EXIT_SUCCESS);
+	}
+
+	// Wait for the first fork to return, and place the return value in errno
+	if (waitpid(pid, &status, 0) < 0) {
+		syslog(LOG_ERR, "Call to waitpid() failed: %s (%d)", strerror(errno), errno);
+	}
+
+	if (0 != WEXITSTATUS(status)) {
+		// If this has happened then the double fork failed. Clean up
+		// and pass this status along to the caller as errno.
+
+		syslog(LOG_ERR, "Child process failed: %s (%d)", strerror(WEXITSTATUS(status)), WEXITSTATUS(status));
+
+		close(mNetworkRetainFD);
+		mNetworkRetainFD = -1;
+
+		errno = WEXITSTATUS(status);
+	}
+}
+
+void
+NetworkRetain::save_network_info(void)
+{
+	syslog(LOG_NOTICE, "NetworkRetain - Saving network info...");
+	require_string(write(mNetworkRetainFD, "S", 1) == 1, bail, strerror(errno));
+bail:
+	return;
+}
+
+void
+NetworkRetain::recall_network_info(void)
+{
+	syslog(LOG_NOTICE, "NetworkRetain - Recalling/restoring network info...");
+	require_string(write(mNetworkRetainFD, "R", 1) == 1, bail, strerror(errno));
+bail:
+	return;
+}
+
+void
+NetworkRetain::erase_network_info(void)
+{
+	syslog(LOG_NOTICE, "NetworkRetaine - Erasing network info...");
+	require_string(write(mNetworkRetainFD, "E", 1) == 1, bail, strerror(errno));
+bail:
+	return;
+}
+
diff --git a/src/wpantund/NetworkRetain.h b/src/wpantund/NetworkRetain.h
new file mode 100644
index 0000000..a6ae6da
--- /dev/null
+++ b/src/wpantund/NetworkRetain.h
@@ -0,0 +1,53 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Declaration of NetworkRetain class (Hooks for saving/restoring network info)
+ *
+ */
+
+#ifndef __wpantund__NetworkRetain__
+#define __wpantund__NetworkRetain__
+
+#include <string>
+#include "NCPTypes.h"
+
+namespace nl {
+namespace wpantund {
+
+class NetworkRetain
+{
+public:
+	NetworkRetain();
+	~NetworkRetain();
+	void set_network_retain_command(const std::string& command);
+	void handle_ncp_state_change(NCPState new_ncp_state, NCPState old_ncp_state);
+
+private:
+	void save_network_info(void);
+	void recall_network_info(void);
+	void erase_network_info(void);
+	void close_network_retain_fd(void);
+
+private:
+	int mNetworkRetainFD;
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+#endif /* defined(__wpantund__NetworkRetain__) */
diff --git a/src/wpantund/Pcap.cpp b/src/wpantund/Pcap.cpp
new file mode 100644
index 0000000..84b5985
--- /dev/null
+++ b/src/wpantund/Pcap.cpp
@@ -0,0 +1,378 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "assert-macros.h"
+
+#include <string.h>
+#include <syslog.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "Pcap.h"
+
+using namespace nl;
+using namespace wpantund;
+
+
+PcapPacket::PcapPacket()
+	: mLen(sizeof(PcapFrameHeader)), mStatus(kWPANTUNDStatus_Ok)
+{
+	mHeader.mSeconds = 0;
+	mHeader.mMicroSeconds = 0;
+	mHeader.mRecordedPayloadSize = sizeof(PcapPpiHeader);
+	mHeader.mActualPayloadSize = sizeof(PcapPpiHeader);
+	mHeader.mPpiHeader.mVersion = 0;
+	mHeader.mPpiHeader.mFlags = 0;
+	mHeader.mPpiHeader.mSize = sizeof(PcapPpiHeader);
+	mHeader.mPpiHeader.mDLT = 0;
+}
+
+wpantund_status_t
+PcapPacket::get_status(void)const
+{
+	return mStatus;
+}
+
+const uint8_t*
+PcapPacket::get_data_ptr(void)const
+{
+	return mData;
+}
+
+int
+PcapPacket::get_data_len(void)const
+{
+	return mLen;
+}
+
+PcapPacket&
+PcapPacket::set_timestamp(struct timeval* tv)
+{
+	if (tv == NULL) {
+		struct timeval x;
+		gettimeofday(&x, NULL);
+
+		mHeader.mSeconds = static_cast<uint32_t>(x.tv_sec);
+		mHeader.mMicroSeconds = x.tv_usec;
+
+	} else {
+		mHeader.mSeconds = static_cast<uint32_t>(tv->tv_sec);
+		mHeader.mMicroSeconds = tv->tv_usec;
+	}
+
+	return *this;
+}
+
+PcapPacket&
+PcapPacket::set_dlt(uint32_t i)
+{
+	mHeader.mPpiHeader.mDLT = i;
+	return *this;
+}
+
+PcapPacket&
+PcapPacket::append_ppi_field(uint16_t type, const uint8_t* field_ptr, int field_len)
+{
+	PcapPpiFieldHeader field_header;
+
+	assert(mLen <= sizeof(mData));
+
+	if (field_len < 0) {
+		mStatus = kWPANTUNDStatus_InvalidArgument;
+
+	} else if (mLen + field_len + sizeof(PcapPpiFieldHeader) > sizeof(mData)) {
+		mStatus = kWPANTUNDStatus_InvalidArgument;
+
+	} else {
+		field_header.mType = type;
+		field_header.mSize = field_len;
+		memcpy(mData + mLen, &field_header, sizeof(PcapPpiFieldHeader));
+		memcpy(mData + mLen + sizeof(PcapPpiFieldHeader), field_ptr, field_len);
+		mLen += field_len + sizeof(PcapPpiFieldHeader);
+		mHeader.mRecordedPayloadSize += field_len + sizeof(PcapPpiFieldHeader);
+		mHeader.mPpiHeader.mSize += field_len + sizeof(PcapPpiFieldHeader);
+	}
+
+	mHeader.mActualPayloadSize += field_len + sizeof(PcapPpiFieldHeader);
+
+	return *this;
+}
+
+PcapPacket&
+PcapPacket::append_payload(const uint8_t* payload_ptr, int payload_len)
+{
+	assert(mLen <= sizeof(mData));
+
+	if (payload_len < 0) {
+		mStatus = kWPANTUNDStatus_InvalidArgument;
+
+	} else if (mLen + payload_len > sizeof(mData)) {
+		memcpy(mData + mLen, payload_ptr, sizeof(mData) - mLen);
+		mLen = sizeof(mData);
+		mHeader.mRecordedPayloadSize += sizeof(mData) - mLen;
+
+	} else {
+		memcpy(mData + mLen, payload_ptr, payload_len);
+		mLen += payload_len;
+		mHeader.mRecordedPayloadSize += payload_len;
+	}
+
+	mHeader.mActualPayloadSize += payload_len;
+
+	return *this;
+}
+
+
+PcapManager::PcapManager()
+{
+}
+
+PcapManager::~PcapManager()
+{
+}
+
+bool
+PcapManager::is_enabled(void)
+{
+	return !mFDSet.empty();
+}
+
+const std::set<int>&
+PcapManager::get_fd_set(void)
+{
+	return mFDSet;
+}
+
+int
+PcapManager::insert_fd(int fd)
+{
+	int ret = -1;
+	int save_errno;
+	int set = 1;
+	PcapGlobalHeader header;
+
+	// Prepare the PCAP header.
+	header.mMagic = PCAP_MAGIC;
+	header.mVerMaj = PCAP_VERSION_MAJOR;
+	header.mVerMin = PCAP_VERSION_MINOR;
+	header.mGMTOffset = 0;
+	header.mAccuracy = 0;
+	header.mSnapshotLengthField = PCAP_PACKET_MAX_SIZE;
+	header.mDLT = PCAP_DLT_PPI;
+
+#ifdef SO_NOSIGPIPE
+	setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
+#endif
+
+	// Send the PCAP header.
+	ret = static_cast<int>(write(fd, &header, sizeof(header)));
+
+	if (ret < 0) {
+		save_errno = errno;
+		syslog(LOG_ERR, "PcapManager::insert_fd: Call to send() on fd %d failed: %s (%d)", fd, strerror(errno), errno);
+		goto bail;
+	}
+
+	mFDSet.insert(fd);
+
+	ret = 0;
+
+bail:
+	if (ret < 0) {
+		errno = save_errno;
+	}
+
+	return ret;
+}
+
+int
+PcapManager::new_fd(void)
+{
+	int ret = -1;
+	int save_errno;
+	int fd[2] = { -1, -1 };
+
+	ret = socketpair(PF_UNIX, SOCK_DGRAM, 0, fd);
+
+	if (ret < 0) {
+		save_errno = errno;
+		syslog(LOG_ERR, "PcapManager::new_fd: Call to socketpair() failed: %s (%d)", strerror(errno), errno);
+		goto bail;
+	}
+
+	ret = insert_fd(fd[1]);
+
+	if (ret < 0) {
+		save_errno = errno;
+		goto bail;
+	}
+
+	ret = fd[0];
+
+bail:
+
+	if (ret < 0) {
+		close(fd[0]);
+		close(fd[1]);
+
+		errno = save_errno;
+	}
+
+	return ret;
+}
+
+void
+PcapManager::close_fd_set(const std::set<int>& x)
+{
+	if (&x == &mFDSet) {
+		// Special case where we are asked to close everything.
+		std::set<int> copy(x);
+
+		close_fd_set(copy);
+
+	} else if (!x.empty()) {
+		std::set<int>::const_iterator iter;
+
+		for ( iter  = x.begin()
+			; iter != x.end()
+			; ++iter
+		) {
+			const int fd = *iter;
+			syslog(LOG_INFO, "PcapManager::close_fd_set: Closing FD %d", fd);
+			close(fd);
+			mFDSet.erase(fd);
+		}
+		syslog(LOG_INFO, "PcapManager: %d pcap streams remaining", static_cast<int>(mFDSet.size()));
+	}
+}
+
+void
+PcapManager::push_packet(const PcapPacket& packet)
+{
+	std::set<int>::const_iterator iter;
+	std::set<int> remove_set;
+
+	require_noerr(packet.get_status(), bail);
+
+	for ( iter  = mFDSet.begin()
+	    ; iter != mFDSet.end()
+		; ++iter
+	) {
+		int ret;
+
+		// Send the PCAP frame.
+		ret = static_cast<int>(write(
+			*iter,
+			packet.get_data_ptr(),
+			packet.get_data_len()
+		));
+
+		__ASSERT_MACROS_check(ret >= 0);
+
+		if (ret < 0) {
+			// Since we can't remove this file descriptor
+			// from the set while we are iterating through it,
+			// we add it to the remove set for later removal.
+			remove_set.insert(*iter);
+		}
+	}
+
+	close_fd_set(remove_set);
+
+bail:
+	return;
+}
+
+int
+PcapManager::update_fd_set(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *error_fd_set, int *max_fd, cms_t *timeout)
+{
+	std::set<int>::const_iterator iter;
+
+	for ( iter  = mFDSet.begin()
+	    ; iter != mFDSet.end()
+		; ++iter
+	) {
+		const int fd = *iter;
+
+		if (read_fd_set) {
+			FD_SET(fd, read_fd_set);
+		}
+
+		if (error_fd_set) {
+			FD_SET(fd, error_fd_set);
+		}
+
+		if (max_fd && (*max_fd < fd)) {
+			*max_fd = fd;
+		}
+	}
+
+	return 0;
+}
+
+void
+PcapManager::process(void)
+{
+	if (is_enabled()) {
+		fd_set fds;
+		int max_fd(-1);
+		int fds_ready;
+		struct timeval timeout = {};
+
+		FD_ZERO(&fds);
+
+		update_fd_set(&fds, NULL, &fds, &max_fd, NULL);
+
+		fds_ready = select(
+			max_fd + 1,
+			&fds,
+			NULL,
+			&fds,
+			&timeout
+		);
+
+		if (fds_ready > 0) {
+			// Tear down bad file descriptors.
+			std::set<int> remove_set;
+			std::set<int>::const_iterator iter;
+
+			for ( iter  = mFDSet.begin()
+				; (fds_ready > 0) && (iter != mFDSet.end())
+				; ++iter
+			) {
+				int fd = *iter;
+				if (!FD_ISSET(fd, &fds)) {
+					continue;
+				}
+				fds_ready--;
+				remove_set.insert(fd);
+			}
+
+			close_fd_set(remove_set);
+		}
+	}
+}
diff --git a/src/wpantund/Pcap.h b/src/wpantund/Pcap.h
new file mode 100644
index 0000000..86c9860
--- /dev/null
+++ b/src/wpantund/Pcap.h
@@ -0,0 +1,144 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __wpantund__Pcap__
+#define __wpantund__Pcap__
+
+#include <set>
+#include "wpan-error.h"
+#include "time-utils.h"
+
+namespace nl {
+namespace wpantund {
+
+#define PCAP_PACKET_MAX_SIZE        512
+
+#define PCAP_DLT_PPI                192
+#define PCAP_DLT_IEEE802_15_4       195
+#define PCAP_DLT_IEEE802_15_4_NOFCS 230
+
+#define PCAP_MAGIC                  0xa1b2c3d4
+#define PCAP_VERSION_MAJOR          2
+#define PCAP_VERSION_MINOR          4
+
+#define PCAP_PPI_VERSION            0
+
+#define PCAP_PPI_TYPE_SPINEL        61616
+
+/* Additional reading:
+ *
+ * * DLT list: http://www.tcpdump.org/linktypes.html
+ * * Info on PPI: http://www.cacetech.com/documents/PPI%20Header%20format%201.0.7.pdf
+ */
+
+struct PcapGlobalHeader {
+	uint32_t mMagic;
+	uint16_t mVerMaj;
+	uint16_t mVerMin;
+	int32_t  mGMTOffset;
+	uint32_t mAccuracy;
+	uint32_t mSnapshotLengthField;
+	uint32_t mDLT;
+};
+
+struct PcapPpiHeader {
+	uint8_t mVersion;
+	uint8_t mFlags;
+	uint16_t mSize;
+	uint32_t mDLT;
+	uint8_t  mPayloadData[0];
+};
+
+struct PcapPpiFieldHeader {
+	uint16_t mType;
+	uint16_t mSize;
+	uint8_t  mData[0];
+};
+
+struct PcapFrameHeader {
+	uint32_t mSeconds;
+	uint32_t mMicroSeconds;
+	uint32_t mRecordedPayloadSize;
+	uint32_t mActualPayloadSize;
+	union {
+		struct PcapPpiHeader mPpiHeader;
+		uint8_t  mPayloadData[0];
+	};
+};
+
+class PcapPacket
+{
+public:
+	PcapPacket();
+
+	wpantund_status_t get_status(void)const;
+
+	const uint8_t* get_data_ptr(void)const;
+
+	int get_data_len(void)const;
+
+	PcapPacket& set_timestamp(struct timeval* tv = NULL);
+
+	PcapPacket& set_dlt(uint32_t i);
+
+	PcapPacket& append_ppi_field(uint16_t type, const uint8_t* field_ptr, int field_len);
+
+	PcapPacket& append_payload(const uint8_t* payload_ptr, int payload_len);
+
+	PcapPacket& finish(void);
+
+private:
+	union {
+		uint8_t         mData[PCAP_PACKET_MAX_SIZE];
+		PcapFrameHeader mHeader;
+	};
+	int               mLen;
+	wpantund_status_t mStatus;
+};
+
+class PcapManager
+{
+public:
+	PcapManager();
+	~PcapManager();
+
+	bool is_enabled(void);
+
+	const std::set<int>& get_fd_set(void);
+
+	int new_fd(void);
+
+	int insert_fd(int fd);
+
+	void push_packet(const PcapPacket& packet);
+
+	void process(void);
+
+	int update_fd_set(fd_set *read_fd_set, fd_set *write_fd_set, fd_set *error_fd_set, int *max_fd, cms_t *timeout);
+
+	void close_fd_set(const std::set<int>& x);
+
+private:
+	std::set<int> mFDSet;
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+#endif /* defined(__wpantund__NetworkRetain__) */
diff --git a/src/wpantund/RunawayResetBackoffManager.cpp b/src/wpantund/RunawayResetBackoffManager.cpp
new file mode 100644
index 0000000..27d0981
--- /dev/null
+++ b/src/wpantund/RunawayResetBackoffManager.cpp
@@ -0,0 +1,70 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "RunawayResetBackoffManager.h"
+
+#include <cstring>
+#include <syslog.h>
+#include <sys/time.h>
+
+using namespace nl;
+using namespace nl::wpantund;
+
+// -----------------------------
+
+const int RunawayResetBackoffManager::kDecayPeriod = 15;
+const int RunawayResetBackoffManager::kBackoffThreshold = 4;
+
+RunawayResetBackoffManager::RunawayResetBackoffManager():
+	mWindowedResetCount(0),
+	mDecrementAt(0)
+{
+}
+
+float
+RunawayResetBackoffManager::delay_for_unexpected_reset(void)
+{
+	float ret = 0;
+	if (mWindowedResetCount > kBackoffThreshold) {
+		int count = mWindowedResetCount - kBackoffThreshold;
+		ret = (count * count) / 2.0f;
+		syslog(LOG_ERR, "RunawayResetBackoffManager: mWindowedResetCount = %d, will delay for %f seconds", mWindowedResetCount, ret);
+	}
+	return ret;
+}
+
+void
+RunawayResetBackoffManager::count_unexpected_reset(void)
+{
+	mWindowedResetCount++;
+	mDecrementAt = time_get_monotonic() + kDecayPeriod;
+}
+
+void
+RunawayResetBackoffManager::update(void)
+{
+	if ((mWindowedResetCount > 0) && (mDecrementAt < time_get_monotonic())) {
+		mWindowedResetCount--;
+		mDecrementAt = time_get_monotonic() + kDecayPeriod;
+	}
+}
diff --git a/src/wpantund/RunawayResetBackoffManager.h b/src/wpantund/RunawayResetBackoffManager.h
new file mode 100644
index 0000000..cec5739
--- /dev/null
+++ b/src/wpantund/RunawayResetBackoffManager.h
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __WPANTUND_RUNAWAY_RESET_BACKOFF_MANAGER_H__
+#define __WPANTUND_RUNAWAY_RESET_BACKOFF_MANAGER_H__ 1
+
+#include "time-utils.h"
+
+namespace nl {
+namespace wpantund {
+
+class RunawayResetBackoffManager {
+public:
+	RunawayResetBackoffManager();
+
+	//! Returns the number of seconds that we should sleep after the next reset.
+	float delay_for_unexpected_reset(void);
+
+	//! Called when an unexpected reset occurs.
+	void count_unexpected_reset(void);
+
+	//! Called for every main loop to update the windowed reset count.
+	void update(void);
+
+private:
+	static const int kDecayPeriod;
+	static const int kBackoffThreshold;
+
+	int mWindowedResetCount;
+	time_t mDecrementAt;
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+#endif // __WPANTUND_RUNAWAY_RESET_BACKOFF_MANAGER_H__
diff --git a/src/wpantund/StatCollector.cpp b/src/wpantund/StatCollector.cpp
new file mode 100644
index 0000000..853e8c5
--- /dev/null
+++ b/src/wpantund/StatCollector.cpp
@@ -0,0 +1,1735 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Statistics collector module.
+ *
+ */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <syslog.h>
+#include <arpa/inet.h>
+#include <iterator>
+#include "StatCollector.h"
+#include "any-to.h"
+#include "wpan-error.h"
+
+using namespace nl;
+using namespace wpantund;
+
+// Enable additional debug logs only in this module
+#define ENABLE_MODULE_DEBUG  0
+#if ENABLE_MODULE_DEBUG
+#define DEBUG_LOG(msg, ...)  syslog(LOG_INFO, msg , ##__VA_ARGS__)
+#else
+#define DEBUG_LOG(msg, ...)  do { } while(false)
+#endif
+
+
+// Number of history items to show for short version of stat "Stat:Short"
+#define STAT_COLLECTOR_SHORT_HISTORY_COUNT        10
+
+// Number of history items to show for short version of stat "Stat:LinkQuality:Short"
+#define STAT_COLLECTOR_LINK_STAT_HISTORY_SIZE     8
+
+// Log level for adding logs to syslog when user/application requests it
+#define STAT_COLLECTOR_LOG_LEVEL_USER_REQUEST     LOG_INFO
+
+// Default log level for short auto logs (periodic logging)
+#define STAT_COLLECTOR_AUTO_LOG_DEFAULT_LOG_LEVEL LOG_INFO
+
+// Default period (in min) for automatically logging stat info
+#define STAT_COLLECTOR_AUTO_LOG_PERIOD_IN_MIN     30     // 30 min
+
+// Maximum allowed period for auto log (value is in min)
+#define STAT_COLLECTOR_AUTO_LOG_MAX_PERIOD		  (60 * 24 * 7 * 2) // Two weeks
+
+// Time stamp constants
+#define TIMESTAMP_ONE_SEC_IN_MS           ((int32_t)1000)
+#define TIMESTAMP_ONE_MIN_IN_MS           (TIMESTAMP_ONE_SEC_IN_MS * 60)
+#define TIMESTAMP_ONE_HOUR_IN_MS          (TIMESTAMP_ONE_MIN_IN_MS * 60)
+#define TIMESTAMP_ONE_DAY_IN_MS           (TIMESTAMP_ONE_HOUR_IN_MS * 24)
+#define TIMESTAMP_UNINITIALIZED_VALUE     0
+
+// IPv6 types
+#define IPV6_TYPE_UDP                     0x11
+#define IPV6_TYPE_TCP                     0x06
+#define IPV6_TYPE_ICMP                    0x3A
+#define IPV6_ICMP_TYPE_ECHO_REQUEST       128
+#define IPV6_ICMP_TYPE_ECHO_REPLY         129
+
+// IPv6 Header Offset
+#define IPV6_HEADER_VERSION_OFFSET        0
+#define IPV6_HEADER_PAYLOAD_LEN_OFFSET    4
+#define IPV6_HEADER_TYPE_OFFSET           6
+#define IPV6_HEADER_SRC_ADDRESS_OFFSET    8
+#define IPV6_HEADER_DST_ADDRESS_OFFSET    24
+#define IPV6_UDP_HEADER_SRC_PORT_OFFSET   40
+#define IPV6_UDP_HEADER_DST_PORT_OFFSET   42
+#define IPV6_ICMP_HEADER_CODE_OFFSET      40
+
+#define IPV6_GET_UINT16(pkt,idx)   ( (static_cast<uint16_t>(pkt[idx]) << 8) + static_cast<uint16_t>(pkt[idx + 1] << 0) )
+
+//===================================================================
+
+static std::string
+string_printf(const char *fmt, ...)
+{
+	va_list args;
+	char c_str_buf[512];
+	va_start(args, fmt);
+	vsnprintf(c_str_buf, sizeof(c_str_buf), fmt, args);
+	va_end(args);
+	return std::string(c_str_buf);
+}
+
+static std::string
+log_level_to_string(int log_level)
+{
+	switch(log_level) {
+		case LOG_EMERG:   return "emerg";
+		case LOG_ALERT:   return "alert";
+		case LOG_CRIT:    return "crit";
+		case LOG_ERR:     return "err";
+		case LOG_WARNING: return "warning";
+		case LOG_NOTICE:  return "notice";
+		case LOG_INFO:    return "info";
+		case LOG_DEBUG:   return "debug";
+	}
+	return string_printf("unknown(%d)", log_level);
+}
+
+// Converts a string to a log level, returns -1 if not a valid log level
+static int
+log_level_from_string(const char *log_string)
+{
+	int log_level = -1;
+
+	if (strcaseequal(log_string, "emerg")) {
+		log_level = LOG_EMERG;
+	} else 	if (strcaseequal(log_string, "alert")) {
+		log_level = LOG_ALERT;
+	} else 	if (strcaseequal(log_string, "crit")) {
+		log_level = LOG_CRIT;
+	} else 	if (strcaseequal(log_string, "err") || (strcaseequal(log_string, "error"))) {
+		log_level = LOG_ERR;
+	} else 	if (strcaseequal(log_string, "warning")) {
+		log_level = LOG_WARNING;
+	} else 	if (strcaseequal(log_string, "notice")) {
+		log_level = LOG_NOTICE;
+	} else 	if (strcaseequal(log_string, "info")) {
+		log_level = LOG_INFO;
+	} else 	if (strcaseequal(log_string, "debug")) {
+		log_level = LOG_DEBUG;
+	}
+
+	return log_level;
+}
+
+//-------------------------------------------------------------------
+// IPAddress
+
+void
+StatCollector::IPAddress::read_from(const uint8_t *arr)
+{
+	memcpy(static_cast<void *>(mAddressBuffer), arr, sizeof(mAddressBuffer));
+}
+
+std::string
+StatCollector::IPAddress::to_string(void) const
+{
+	char address_string[INET6_ADDRSTRLEN] = "::";
+	inet_ntop(AF_INET6, static_cast<const void *>(mAddressBuffer), address_string, sizeof(address_string));
+	return std::string(address_string);
+}
+
+bool
+StatCollector::IPAddress::operator==(const IPAddress& lhs) const
+{
+	// Since IPv6 addresses typically start with same prefix, we intentionally
+	// start the comparison from the end of address buffer
+	for(int indx = sizeof(mAddressBuffer)/sizeof(mAddressBuffer[0]) - 1; indx ; indx--) {
+		if (mAddressBuffer[indx] != lhs.mAddressBuffer[indx]) {
+			return false;
+		}
+	}
+
+	return true;
+}
+
+bool
+StatCollector::IPAddress::operator<(const IPAddress& lhs) const
+{
+	// Since IPv6 addresses typically start with same prefix, we intentionally
+	// start the comparison from the end of address buffer
+
+	for(int indx = sizeof(mAddressBuffer)/sizeof(mAddressBuffer[0]) - 1; indx ; indx--) {
+		if (mAddressBuffer[indx] < lhs.mAddressBuffer[indx]) {
+			return true;
+		}
+
+		if (mAddressBuffer[indx] > lhs.mAddressBuffer[indx]) {
+			return false;
+		}
+	}
+
+	// If all is equal, then return false.
+	return false;
+}
+
+//-------------------------------------------------------------------
+// EUI64Address
+
+void
+StatCollector::EUI64Address::read_from(const uint8_t *arr)
+{
+	mAddress[0] = arr[3] + (arr[2] << 8) + (arr[1] << 16) + (arr[0] << 24);
+	mAddress[1] = arr[7] + (arr[6] << 8) + (arr[5] << 16) + (arr[4] << 24);
+}
+
+std::string
+StatCollector::EUI64Address::to_string(void) const
+{
+	return string_printf("%08X%08X", mAddress[0], mAddress[1]);
+}
+
+bool
+StatCollector::EUI64Address::operator==(const EUI64Address& lhs) const
+{
+	return (mAddress[1] == lhs.mAddress[1]) && (mAddress[0] == lhs.mAddress[0]);
+}
+
+bool
+StatCollector::EUI64Address::operator<(const EUI64Address& lhs) const
+{
+	if (mAddress[1] < lhs.mAddress[1]) {
+		return true;
+	}
+
+	if (mAddress[1] > lhs.mAddress[1]) {
+		return false;
+	}
+
+	if (mAddress[0] < lhs.mAddress[0]) {
+		return true;
+	}
+
+	return false;
+}
+
+//-------------------------------------------------------------------
+// TimeStamp
+
+StatCollector::TimeStamp::TimeStamp()
+{
+	mTime = TIMESTAMP_UNINITIALIZED_VALUE;
+}
+
+void
+StatCollector::TimeStamp::set_to_now(void)
+{
+	mTime = time_ms();
+
+	if (mTime == TIMESTAMP_UNINITIALIZED_VALUE) {
+		mTime--;
+	}
+}
+
+void
+StatCollector::TimeStamp::clear(void)
+{
+	mTime = TIMESTAMP_UNINITIALIZED_VALUE;
+}
+
+cms_t
+StatCollector::TimeStamp::get_ms_till_now(void) const
+{
+	return CMS_SINCE(mTime);
+}
+
+bool
+StatCollector::TimeStamp::is_expired(void) const
+{
+	if (mTime == TIMESTAMP_UNINITIALIZED_VALUE) {
+		return true;
+	}
+
+	return (get_ms_till_now() < 0);
+}
+
+bool
+StatCollector::TimeStamp::is_uninitialized(void) const
+{
+	return (mTime == TIMESTAMP_UNINITIALIZED_VALUE);
+}
+
+bool
+StatCollector::TimeStamp::operator==(const TimeStamp &lhs)
+{
+	return mTime == lhs.mTime;
+}
+
+bool
+StatCollector::TimeStamp::operator<(const TimeStamp &lhs)
+{
+	return (mTime - lhs.mTime) < 0;
+}
+
+std::string
+StatCollector::TimeStamp::to_string(void) const
+{
+	int32_t days, hours, minutes, seconds, milliseconds;
+	cms_t ms_till_now = get_ms_till_now();
+
+	if (mTime == TIMESTAMP_UNINITIALIZED_VALUE)
+		return std::string("never");
+
+	if (ms_till_now < 0)
+		return std::string("long time (>24.86 days) ago");
+
+	days = ms_till_now / TIMESTAMP_ONE_DAY_IN_MS;
+	ms_till_now %= TIMESTAMP_ONE_DAY_IN_MS;
+	hours = ms_till_now / TIMESTAMP_ONE_HOUR_IN_MS;
+	ms_till_now %= TIMESTAMP_ONE_HOUR_IN_MS;
+	minutes = ms_till_now / TIMESTAMP_ONE_MIN_IN_MS;
+	ms_till_now %= TIMESTAMP_ONE_MIN_IN_MS;
+	seconds = ms_till_now / TIMESTAMP_ONE_SEC_IN_MS;
+	milliseconds = ms_till_now % TIMESTAMP_ONE_SEC_IN_MS;
+
+	if (days != 0) {
+		return string_printf("%2d day%s %02d:%02d:%02d.%03d ago", days, (days > 1)? "s" : "",
+		         hours, minutes, seconds, milliseconds);
+	}
+
+	return string_printf("%02d:%02d:%02d.%03d ago", hours, minutes, seconds, milliseconds);
+}
+
+int32_t
+StatCollector::TimeStamp::time_difference_in_ms(TimeStamp t1, TimeStamp t2)
+{
+	return (t2.mTime - t1.mTime);
+}
+
+//-------------------------------------------------------------------
+// BytesTotal
+
+StatCollector::BytesTotal::BytesTotal()
+{
+	clear();
+}
+
+void
+StatCollector::BytesTotal::clear()
+{
+	mBytes = 0;
+	mKiloBytes = 0;
+}
+
+void
+StatCollector::BytesTotal::add(uint16_t count)
+{
+	uint32_t num_bytes;
+
+	num_bytes = count;
+	num_bytes += mBytes;
+
+	mKiloBytes += (num_bytes >> 10);  // divide by 1024.
+	num_bytes &= 1023;                // reminder
+	mBytes = static_cast<uint16_t>(num_bytes);
+}
+
+std::string
+StatCollector::BytesTotal::to_string() const
+{
+	if (mKiloBytes == 0) {
+		return string_printf("%d bytes", mBytes);
+	}
+
+	if (mBytes == 0) {
+		return string_printf("%d Kbytes", mKiloBytes);
+	}
+
+	return string_printf("%d Kbytes & %d bytes", mKiloBytes, mBytes);
+}
+
+//-------------------------------------------------------------------
+// PacketInfo
+
+bool
+StatCollector::PacketInfo::update_from_packet(const uint8_t *packet)
+{
+	bool ret = false;
+
+	// Check the version in IPv6 header
+	if ((packet[IPV6_HEADER_VERSION_OFFSET] & 0xF0) == 0x60)  {
+
+		mTimeStamp.set_to_now();
+
+		mPayloadLen = IPV6_GET_UINT16(packet, IPV6_HEADER_PAYLOAD_LEN_OFFSET);
+
+		mType = packet[IPV6_HEADER_TYPE_OFFSET];
+
+		mSrcAddress.read_from(&packet[IPV6_HEADER_SRC_ADDRESS_OFFSET]);
+		mDstAddress.read_from(&packet[IPV6_HEADER_DST_ADDRESS_OFFSET]);
+
+		if (mType == IPV6_TYPE_ICMP) {
+			mSubtype = packet[IPV6_ICMP_HEADER_CODE_OFFSET];
+		} else {
+			mSubtype = 0;
+		}
+
+		if ((mType == IPV6_TYPE_UDP) || (mType == IPV6_TYPE_TCP)) {
+			mSrcPort = IPV6_GET_UINT16(packet, IPV6_UDP_HEADER_SRC_PORT_OFFSET);
+			mDstPort = IPV6_GET_UINT16(packet, IPV6_UDP_HEADER_DST_PORT_OFFSET);
+		} else {
+			mSrcPort = 0;
+			mDstPort = 0;
+		}
+
+		ret = true;
+	}
+
+	return ret;
+}
+
+std::string
+StatCollector::PacketInfo::to_string(void) const
+{
+	std::string type_str;
+	bool has_port;
+
+	has_port = false;
+	switch(mType) {
+		case IPV6_TYPE_TCP:
+			type_str = "TCP";
+			has_port = true;
+			break;
+
+		case IPV6_TYPE_UDP:
+			type_str = "UDP";
+			has_port = true;
+			break;
+
+		case IPV6_TYPE_ICMP:
+			switch(mSubtype) {
+				case IPV6_ICMP_TYPE_ECHO_REPLY:
+					type_str = "ICMP6(echo reply)";
+					break;
+				case IPV6_ICMP_TYPE_ECHO_REQUEST:
+					type_str = "ICMP6(echo request)";
+					break;
+				default:
+					type_str = string_printf("ICMP6(code:%d)", mSubtype);
+					break;
+			}
+			break;
+
+		default:
+			type_str = string_printf("0x%02x", mType);
+			break;
+	}
+
+	if (has_port) {
+		return string_printf(
+		        "%s -> type:%s len:%d from:[%s]:%d to:[%s]:%d",
+		        mTimeStamp.to_string().c_str(),
+		        type_str.c_str(),
+		        mPayloadLen,
+		        mSrcAddress.to_string().c_str(), mSrcPort,
+		        mDstAddress.to_string().c_str(), mDstPort
+		);
+	}
+
+	return string_printf(
+	        "%s -> type:%s len:%d from:[%s] to:[%s]",
+	        mTimeStamp.to_string().c_str(),
+	        type_str.c_str(),
+	        mPayloadLen,
+	        mSrcAddress.to_string().c_str(),
+	        mDstAddress.to_string().c_str()
+	);
+}
+
+//-------------------------------------------------------------------
+// NcpStateInfo
+
+void
+StatCollector::NcpStateInfo::update(NCPState new_state)
+{
+	mTimeStamp.set_to_now();
+	mNcpState = new_state;
+}
+
+std::string
+StatCollector::NcpStateInfo::to_string(void) const
+{
+	return
+		string_printf("%s -> %s",
+			mTimeStamp.to_string().c_str(),
+			ncp_state_to_string(mNcpState).c_str()
+		);
+}
+
+bool
+StatCollector::NcpStateInfo::is_expired(void) const
+{
+	return mTimeStamp.is_expired();
+}
+
+//------------------------------------------------------------------
+// ReadyForHostSleepState
+
+void
+StatCollector::ReadyForHostSleepState::update_with_blocking_sleep_time(TimeStamp blocking_sleep_time)
+{
+	mStartBlockingHostSleepTime = blocking_sleep_time;
+	mReadyForHostSleepTime.set_to_now();
+}
+
+std::string
+StatCollector::ReadyForHostSleepState::to_string(void) const
+{
+	if (mReadyForHostSleepTime.is_uninitialized() || mStartBlockingHostSleepTime.is_uninitialized()) {
+		return "Uninitialized";
+	}
+
+	return mStartBlockingHostSleepTime.to_string() + string_printf(" host sleep was blocked for %d ms",
+		TimeStamp::time_difference_in_ms(mStartBlockingHostSleepTime, mReadyForHostSleepTime));
+}
+
+//-------------------------------------------------------------------
+// Node Stat
+
+StatCollector::NodeStat::NodeStat():
+	mNodeInfoPool(), mNodeInfoMap()
+{
+	return;
+}
+
+void
+StatCollector::NodeStat::clear()
+{
+	mNodeInfoMap.clear();
+	mNodeInfoPool.free_all();
+}
+
+StatCollector::NodeStat::NodeInfo *
+StatCollector::NodeStat::find_node_info(const IPAddress& address)
+{
+	std::map<IPAddress, NodeInfo*>::iterator it = mNodeInfoMap.find(address);
+
+	if (it == mNodeInfoMap.end())
+		return NULL;
+
+	return it->second;
+}
+
+StatCollector::NodeStat::NodeInfo *
+StatCollector::NodeStat::create_new_node_info(const IPAddress& address)
+{
+	NodeInfo *node_info_ptr = NULL;
+
+	do {
+		node_info_ptr = mNodeInfoPool.alloc();
+
+		// If we can not allocate a new node info (all objects in the pool are used),
+		// we will remove oldest node info and try again.
+		if (!node_info_ptr) {
+			remove_oldest_node_info();
+		}
+	} while (!node_info_ptr);
+
+	node_info_ptr->clear();
+
+	mNodeInfoMap.insert(std::pair<IPAddress, NodeInfo*>(address, node_info_ptr));
+
+	return node_info_ptr;
+}
+
+void
+StatCollector::NodeStat::remove_oldest_node_info(void)
+{
+	std::map<IPAddress, NodeInfo*>::iterator cur_iter, oldest_iter;
+	TimeStamp ts, oldest_ts;
+
+	for (cur_iter = oldest_iter = mNodeInfoMap.begin(); cur_iter != mNodeInfoMap.end(); cur_iter++) {
+
+		ts = cur_iter->second->get_last_rx_or_tx_time();
+
+		if (oldest_ts.is_uninitialized()) {
+			oldest_ts = ts;
+			oldest_iter = cur_iter;
+		}
+
+		if (!ts.is_uninitialized()) {
+			if (ts < oldest_ts) {
+				oldest_ts = ts;
+				oldest_iter = cur_iter;
+			}
+		}
+	}
+
+	if (oldest_iter != mNodeInfoMap.end()) {
+		NodeInfo *node_info_ptr = oldest_iter->second;
+		mNodeInfoMap.erase(oldest_iter);
+		mNodeInfoPool.free(node_info_ptr);
+
+		syslog(LOG_INFO, "StatCollector: Out of NodeInfo objects --> Deleted the oldest NodeInfo");
+	}
+}
+
+void
+StatCollector::NodeStat::update_from_inbound_packet(const PacketInfo& packet_info)
+{
+	NodeInfo *node_info_ptr;
+
+	node_info_ptr = find_node_info(packet_info.mSrcAddress);
+	if (!node_info_ptr) {
+		node_info_ptr = create_new_node_info(packet_info.mSrcAddress);
+	}
+
+	if (node_info_ptr) {
+		node_info_ptr->mRxPacketsTotal++;
+		switch(packet_info.mType) {
+			case IPV6_TYPE_UDP: node_info_ptr->mRxPacketsUDP++; break;
+			case IPV6_TYPE_TCP: node_info_ptr->mRxPacketsTCP++; break;
+		}
+		node_info_ptr->mRxHistory.force_write(packet_info);
+	}
+}
+
+void
+StatCollector::NodeStat::update_from_outbound_packet(const PacketInfo& packet_info)
+{
+	NodeInfo *node_info_ptr;
+
+	node_info_ptr = find_node_info(packet_info.mDstAddress);
+	if (!node_info_ptr) {
+		node_info_ptr = create_new_node_info(packet_info.mDstAddress);
+	}
+
+	if (node_info_ptr) {
+		node_info_ptr->mTxPacketsTotal++;
+		switch(packet_info.mType) {
+			case IPV6_TYPE_UDP:  node_info_ptr->mTxPacketsUDP++;  break;
+			case IPV6_TYPE_TCP:  node_info_ptr->mTxPacketsTCP++;  break;
+		}
+		node_info_ptr->mTxHistory.force_write(packet_info);
+	}
+}
+
+void
+StatCollector::NodeStat::add_node_info_map_iter(StringList &output, const std::map<IPAddress, NodeInfo*>::const_iterator& it) const
+{
+	output.push_back("========================================================");
+	output.push_back("Address: " + it->first.to_string());
+	it->second->add_node_info(output);
+	output.push_back("");
+}
+
+void
+StatCollector::NodeStat::add_node_stat_history(StringList& output, std::string node_indicator) const
+{
+	std::map<IPAddress, NodeInfo*>::const_iterator it;
+
+	if (node_indicator.empty()) {
+		for (it = mNodeInfoMap.begin(); it != mNodeInfoMap.end(); it++) {
+			add_node_info_map_iter(output, it);
+		}
+	} else {
+		char c = node_indicator[0];
+		if (c == '@' || c == '[') { // Ip address mode
+			std::string ip_addr_str;
+			uint8_t ip_addr_buf[16];
+
+			if (c == '@') {
+				ip_addr_str = node_indicator.substr(1);
+			} else {
+				if (node_indicator[node_indicator.length() - 1] == ']') {
+					ip_addr_str = node_indicator.substr(1, node_indicator.length() - 2);
+				} else {
+					output.push_back(string_printf("Error : Missing \']\' in address format (\'%s\')", node_indicator.c_str()));
+					return;
+				}
+			}
+
+			if (inet_pton(AF_INET6, ip_addr_str.c_str(), ip_addr_buf) > 0) {
+				IPAddress ip_address;
+				ip_address.read_from(ip_addr_buf);
+				it = mNodeInfoMap.find(ip_address);
+				if (it != mNodeInfoMap.end()) {
+					add_node_info_map_iter(output, it);
+				} else {
+					output.push_back(string_printf("Error : Address does not exist (\'%s\')", node_indicator.c_str()));
+				}
+			} else {
+				output.push_back(string_printf("Error : Improper address format (\'%s\')", node_indicator.c_str()));
+			}
+		} else { // Index mode:
+			int index;
+			index = static_cast<int>(strtol(node_indicator.c_str(), NULL, 0));
+			if (index < mNodeInfoMap.size()) {
+				it = mNodeInfoMap.begin();
+				std::advance(it, index);
+				add_node_info_map_iter(output, it);
+			} else {
+				output.push_back(string_printf("Error: Out of bound index %d (\'%s\')", index, node_indicator.c_str()));
+			}
+		}
+	}
+}
+
+void
+StatCollector::NodeStat::add_node_stat(StringList& output) const
+{
+	std::map<IPAddress, NodeInfo*>::const_iterator it;
+
+	for (it = mNodeInfoMap.begin(); it != mNodeInfoMap.end(); it++) {
+		output.push_back("========================================================");
+		output.push_back("Address: " + it->first.to_string());
+		it->second->add_tx_stat(output);
+		it->second->add_rx_stat(output);
+		output.push_back("");
+	}
+}
+
+//-------------------------------------------------------------------
+// NodeStat::NodeInfo
+
+StatCollector::NodeStat::NodeInfo::NodeInfo()
+{
+	clear();
+}
+
+void
+StatCollector::NodeStat::NodeInfo::clear(void)
+{
+	mTxPacketsTotal = 0;
+	mTxPacketsUDP = 0;
+	mTxPacketsTCP = 0;
+
+	mRxPacketsTotal = 0;
+	mRxPacketsUDP = 0;
+	mRxPacketsTCP = 0;
+
+	mRxHistory.clear();
+	mTxHistory.clear();
+}
+
+StatCollector::TimeStamp
+StatCollector::NodeStat::NodeInfo::get_last_rx_time(void) const
+{
+	TimeStamp ts;
+	const PacketInfo *pkt_info_ptr;
+
+	pkt_info_ptr = mRxHistory.back();
+	if (pkt_info_ptr) {
+		ts = pkt_info_ptr->mTimeStamp;
+	}
+	return ts;
+}
+
+StatCollector::TimeStamp
+StatCollector::NodeStat::NodeInfo::get_last_tx_time(void) const
+{
+	TimeStamp ts;
+	const PacketInfo *pkt_info_ptr;
+
+	pkt_info_ptr = mTxHistory.back();
+	if (pkt_info_ptr) {
+		ts = pkt_info_ptr->mTimeStamp;
+	}
+	return ts;
+}
+
+StatCollector::TimeStamp
+StatCollector::NodeStat::NodeInfo::get_last_rx_or_tx_time(void) const
+{
+	TimeStamp rx_time = get_last_rx_time();
+	TimeStamp tx_time = get_last_tx_time();
+
+	// If either one is uninitialized, return the other one.
+	if (rx_time.is_uninitialized()) {
+		return tx_time;
+	}
+
+	if (tx_time.is_uninitialized()) {
+		return rx_time;
+	}
+
+	if (rx_time < tx_time) {
+		return tx_time;
+	}
+
+	return rx_time;
+}
+
+void
+StatCollector::NodeStat::NodeInfo::add_tx_stat(StringList& output, bool add_last_tx_time) const
+{
+	std::string str;
+
+	str = string_printf("%d packet%s (%d udp, %d tcp, %d other) %s sent to this address",
+		mTxPacketsTotal,
+		(mTxPacketsTotal == 1)? "" : "s",
+		mTxPacketsUDP,
+		mTxPacketsTCP,
+		mTxPacketsTotal - mTxPacketsUDP - mTxPacketsTCP,
+		(mTxPacketsTotal == 1)? "was" : "were"
+	);
+
+	if (add_last_tx_time) {
+		TimeStamp last_tx_time = get_last_tx_time();
+		if (!last_tx_time.is_uninitialized()) {
+			str += " - last tx happened " + last_tx_time.to_string();
+		}
+	}
+
+	output.push_back(str);
+}
+
+void
+StatCollector::NodeStat::NodeInfo::add_rx_stat(StringList& output, bool add_last_rx_time) const
+{
+	std::string str;
+
+	str = string_printf("%d packet%s (%d udp, %d tcp, %d other) %s received from this address",
+		mRxPacketsTotal,
+		(mRxPacketsTotal == 1)? "" : "s",
+		mRxPacketsUDP,
+		mRxPacketsTCP,
+		mRxPacketsTotal - mRxPacketsUDP - mRxPacketsTCP,
+		(mRxPacketsTotal == 1)? "was" : "were"
+	);
+
+	if (add_last_rx_time) {
+		TimeStamp last_rx_time = get_last_rx_time();
+		if (!last_rx_time.is_uninitialized()) {
+			str += " - last rx happened " + last_rx_time.to_string();
+		}
+	}
+
+	output.push_back(str);
+}
+
+void
+StatCollector::NodeStat::NodeInfo::add_node_info(StringList& output) const
+{
+	add_tx_stat(output, false);
+
+	if (!mTxHistory.empty()) {
+		RingBuffer<PacketInfo, STAT_COLLECTOR_PER_NODE_TX_HISTORY_SIZE>::ReverseIterator iter;
+
+		output.push_back(string_printf("\tLast %d tx packets", mTxHistory.size()));
+		for (iter = mTxHistory.rbegin(); iter != mTxHistory.rend(); ++iter) {
+			output.push_back("\t" + iter->to_string());
+		}
+	}
+	output.push_back("");
+
+	add_rx_stat(output, false);
+
+	if (!mRxHistory.empty()) {
+		RingBuffer<PacketInfo, STAT_COLLECTOR_PER_NODE_RX_HISTORY_SIZE>::ReverseIterator iter;
+
+		output.push_back(string_printf("\tLast %d rx packets", mRxHistory.size()));
+		for (iter = mRxHistory.rbegin(); iter != mRxHistory.rend(); ++iter) {
+			output.push_back("\t" + iter->to_string());
+		}
+	}
+}
+
+//-------------------------------------------------------------------
+// LinkStat:LinkQuality
+
+StatCollector::LinkStat::LinkQuality::LinkQuality()
+		: mTimeStamp()
+{
+	mRssi = 0;
+	mLinkQualityIncomingOutgoing = 0xff;
+}
+
+void
+StatCollector::LinkStat::LinkQuality::set(int8_t rssi, uint8_t incoming_link_quality, uint8_t outgoing_link_quality)
+{
+	mRssi = rssi;
+	mLinkQualityIncomingOutgoing = ((incoming_link_quality & 0x0f) << 4) + (outgoing_link_quality & 0x0f);
+	mTimeStamp.set_to_now();
+}
+
+StatCollector::TimeStamp
+StatCollector::LinkStat::LinkQuality::get_time_stamp(void) const
+{
+	return mTimeStamp;
+}
+
+uint8_t
+StatCollector::LinkStat::LinkQuality::get_incoming_link_quality(void) const
+{
+	return (mLinkQualityIncomingOutgoing >> 4);
+}
+
+uint8_t
+StatCollector::LinkStat::LinkQuality::get_outgoing_link_quality(void) const
+{
+	return (mLinkQualityIncomingOutgoing & 0x0f);
+}
+
+std::string
+StatCollector::LinkStat::LinkQuality::to_string(void) const
+{
+	if (mTimeStamp.is_uninitialized()) {
+		return "Uninitialized";
+	}
+
+	return mTimeStamp.to_string() + string_printf("-> RSSI: %-6d  LinkQuality(Incoming/Outgoing): %d/%d", mRssi,
+			get_incoming_link_quality(), get_outgoing_link_quality());
+}
+
+//-------------------------------------------------------------------
+// LinkStat::LinkInfo
+
+StatCollector::LinkStat::LinkInfo::LinkInfo() :
+		mNodeType(), mLinkQualityHistory()
+{
+	clear();
+}
+
+void
+StatCollector::LinkStat::LinkInfo::clear(void)
+{
+	mLinkQualityHistory.clear();
+}
+
+bool
+StatCollector::LinkStat::LinkInfo::empty(void) const
+{
+	return mLinkQualityHistory.empty();
+}
+
+void
+StatCollector::LinkStat::LinkInfo::add_link_info(StringList& output, int count) const
+{
+	RingBuffer<LinkQuality, STAT_COLLECTOR_LINK_QUALITY_HISTORY_SIZE>::ReverseIterator iter;
+
+	if (count == 0) {
+		count = mLinkQualityHistory.size();
+	}
+
+	for (iter = mLinkQualityHistory.rbegin(); (iter != mLinkQualityHistory.rend()) && (count != 0); ++iter, --count) {
+		output.push_back("\t" + iter->to_string());
+	}
+}
+
+StatCollector::TimeStamp
+StatCollector::LinkStat::LinkInfo::get_last_update_time(void) const
+{
+	TimeStamp ts;
+	const LinkQuality *link_quality_ptr;
+
+	link_quality_ptr = mLinkQualityHistory.back();
+	if (link_quality_ptr) {
+		ts = link_quality_ptr->get_time_stamp();
+	}
+	return ts;
+}
+
+//-------------------------------------------------------------------
+// LinkStat
+
+StatCollector::LinkStat::LinkStat()
+		: mLinkInfoPool(), mLinkInfoMap()
+{
+}
+
+void
+StatCollector::LinkStat::clear(void)
+{
+	mLinkInfoMap.clear();
+	mLinkInfoPool.free_all();
+}
+
+
+StatCollector::LinkStat::LinkInfo *
+StatCollector::LinkStat::find_link_info(const EUI64Address& address)
+{
+	std::map<EUI64Address, LinkInfo *>::iterator it = mLinkInfoMap.find(address);
+
+	if (it == mLinkInfoMap.end())
+		return NULL;
+
+	return it->second;
+}
+
+StatCollector::LinkStat::LinkInfo *
+StatCollector::LinkStat::create_new_link_info(const EUI64Address& address)
+{
+	LinkInfo *link_info_ptr = NULL;
+
+	do {
+		link_info_ptr = mLinkInfoPool.alloc();
+
+		// If we can not allocate a new link info (all objects in the pool are used),
+		// we will remove oldest one in the map and try again.
+		if (!link_info_ptr) {
+			remove_oldest_link_info();
+		}
+	} while (!link_info_ptr);
+
+	link_info_ptr->clear();
+
+	mLinkInfoMap.insert(std::pair<EUI64Address, LinkInfo*>(address, link_info_ptr));
+
+	return link_info_ptr;
+}
+
+void
+StatCollector::LinkStat::remove_oldest_link_info(void)
+{
+	std::map<EUI64Address, LinkInfo*>::iterator cur_iter, oldest_iter;
+	TimeStamp ts, oldest_ts;
+
+	for (cur_iter = oldest_iter = mLinkInfoMap.begin(); cur_iter != mLinkInfoMap.end(); cur_iter++) {
+
+		ts = cur_iter->second->get_last_update_time();
+
+		if (oldest_ts.is_uninitialized()) {
+			oldest_ts = ts;
+			oldest_iter = cur_iter;
+		}
+
+		if (!ts.is_uninitialized()) {
+			if (ts < oldest_ts) {
+				oldest_ts = ts;
+				oldest_iter = cur_iter;
+			}
+		}
+	}
+
+	if (oldest_iter != mLinkInfoMap.end()) {
+		LinkInfo *link_info_ptr = oldest_iter->second;
+		mLinkInfoMap.erase(oldest_iter);
+		mLinkInfoPool.free(link_info_ptr);
+
+		syslog(LOG_INFO, "StatCollector: Out of LinkInfo objects --> Deleted the oldest LinkInfo");
+	}
+}
+
+void
+StatCollector::LinkStat::update(const uint8_t *eui64_address_arr, int8_t rssi,
+		uint8_t incoming_link_quality, uint8_t outgoing_link_quality,
+		NodeType node_type)
+{
+	LinkQuality link_quality;
+	EUI64Address address;
+	LinkInfo *link_info_ptr;
+
+	if (eui64_address_arr) {
+
+		address.read_from(eui64_address_arr);
+
+		link_quality.set(rssi, incoming_link_quality, outgoing_link_quality);
+
+		link_info_ptr = find_link_info(address);
+		if (!link_info_ptr) {
+			link_info_ptr = create_new_link_info(address);
+		}
+
+		if (link_info_ptr) {
+			link_info_ptr->mLinkQualityHistory.force_write(link_quality);
+			link_info_ptr->mNodeType = node_type;
+		}
+	}
+}
+
+void
+StatCollector::LinkStat::add_link_stat(StringList& output, int count) const
+{
+	std::map<EUI64Address, LinkInfo*>::const_iterator it;
+
+	for (it = mLinkInfoMap.begin(); it != mLinkInfoMap.end(); ++it) {
+		output.push_back("========================================================");
+		output.push_back("EUI64 address: " + it->first.to_string() + " -  Node type: " +
+			node_type_to_string(it->second->mNodeType));
+		it->second->add_link_info(output, count);
+		output.push_back("");
+	}
+}
+
+//-------------------------------------------------------------------
+// StatCollector
+
+StatCollector::StatCollector() :
+		mTxBytesTotal(), mRxBytesTotal(),
+		mRxHistory(), mTxHistory(),
+		mLastBlockingHostSleepTime(),
+		mNodeStat(), mLinkStat(),
+		mAutoLogTimer(), mLinkStatTimer()
+{
+	mControlInterface = NULL;
+
+	mTxPacketsTotal = 0;
+	mRxPacketsTotal = 0;
+	mRxPacketsUDP = 0;
+	mRxPacketsTCP = 0;
+	mRxPacketsICMP = 0;
+	mTxPacketsUDP = 0;
+	mTxPacketsTCP = 0;
+	mTxPacketsICMP = 0;
+
+	mLastReadyForHostSleepState = true;
+
+	mUserRequestLogLevel = STAT_COLLECTOR_LOG_LEVEL_USER_REQUEST;
+	mAutoLogLevel = STAT_COLLECTOR_AUTO_LOG_DEFAULT_LOG_LEVEL;
+
+	mAutoLogState = kAutoLogShort;
+	mAutoLogPeriod = STAT_COLLECTOR_AUTO_LOG_PERIOD_IN_MIN * Timer::kOneMinute;
+	update_auto_log_timer();
+}
+
+StatCollector::~StatCollector()
+{
+	mAutoLogTimer.cancel();
+}
+
+void
+StatCollector::set_ncp_control_interface(NCPControlInterface *ncp_ctrl_interface)
+{
+	if (mControlInterface == ncp_ctrl_interface) {
+		return;
+	}
+
+	if (mControlInterface) {
+		mControlInterface->mOnPropertyChanged.disconnect(
+			boost::bind(&StatCollector::property_changed, this, _1, _2)
+		);
+
+		mControlInterface->mOnNetScanBeacon.disconnect(
+			boost::bind(&StatCollector::did_rx_net_scan_beacon, this, _1)
+		);
+	}
+
+	mControlInterface = ncp_ctrl_interface;
+
+	if (mControlInterface) {
+		mControlInterface->mOnPropertyChanged.connect(
+			boost::bind(&StatCollector::property_changed, this, _1, _2)
+		);
+
+		mControlInterface->mOnNetScanBeacon.connect(
+			boost::bind(&StatCollector::did_rx_net_scan_beacon, this, _1)
+		);
+	}
+}
+
+void
+StatCollector::record_inbound_packet(const uint8_t *packet)
+{
+	PacketInfo packet_info;
+
+	if (packet_info.update_from_packet(packet)) {
+		mRxPacketsTotal++;
+		switch (packet_info.mType) {
+			case IPV6_TYPE_UDP:  mRxPacketsUDP++;  break;
+			case IPV6_TYPE_TCP:  mRxPacketsTCP++;  break;
+			case IPV6_TYPE_ICMP: mRxPacketsICMP++; break;
+		}
+		mRxBytesTotal.add(packet_info.mPayloadLen);
+		mRxHistory.force_write(packet_info);
+
+		mNodeStat.update_from_inbound_packet(packet_info);
+	}
+}
+
+void
+StatCollector::record_outbound_packet(const uint8_t *packet)
+{
+	PacketInfo packet_info;
+
+	if (packet_info.update_from_packet(packet)) {
+		mTxPacketsTotal++;
+		switch (packet_info.mType) {
+			case IPV6_TYPE_UDP:  mTxPacketsUDP++;  break;
+			case IPV6_TYPE_TCP:  mTxPacketsTCP++;  break;
+			case IPV6_TYPE_ICMP: mTxPacketsICMP++; break;
+		}
+		mTxBytesTotal.add(packet_info.mPayloadLen);
+		mTxHistory.force_write(packet_info);
+
+		mNodeStat.update_from_outbound_packet(packet_info);
+	}
+}
+
+void
+StatCollector::record_ncp_state_change(NCPState new_ncp_state)
+{
+	NcpStateInfo ncp_state_info;
+	ncp_state_info.update(new_ncp_state);
+	mNCPStateHistory.force_write(ncp_state_info);
+}
+
+void
+StatCollector::record_ncp_ready_for_host_sleep_state(bool ready_for_sleep_state)
+{
+	ReadyForHostSleepState new_state;
+
+	if (mLastReadyForHostSleepState == ready_for_sleep_state) {
+		return;
+	}
+
+	if (ready_for_sleep_state) {
+		new_state.update_with_blocking_sleep_time(mLastBlockingHostSleepTime);
+
+		mReadyForSleepHistory.force_write(new_state);
+	} else {
+		mLastBlockingHostSleepTime.set_to_now();
+	}
+
+	mLastReadyForHostSleepState = ready_for_sleep_state;
+}
+
+void
+StatCollector::add_tx_history(StringList& output, int count) const
+{
+	if (count == 0) {
+		count = mTxHistory.size();
+	}
+
+	if (!mTxHistory.empty()) {
+		RingBuffer<PacketInfo, STAT_COLLECTOR_TX_HISTORY_SIZE>::ReverseIterator iter;
+
+		output.push_back("Tx History");
+		output.push_back("-------------------------");
+		for (iter = mTxHistory.rbegin(); (iter != mTxHistory.rend()) && (count != 0); ++iter, --count) {
+			output.push_back(iter->to_string());
+		}
+	} else  {
+		output.push_back("Tx history is empty");
+	}
+}
+
+void
+StatCollector::add_rx_history(StringList& output, int count) const
+{
+	if (count == 0) {
+		count = mRxHistory.size();
+	}
+
+	if (!mRxHistory.empty()) {
+		RingBuffer<PacketInfo, STAT_COLLECTOR_RX_HISTORY_SIZE>::ReverseIterator iter;
+
+		output.push_back("Rx History");
+		output.push_back("-------------------------");
+		for (iter = mRxHistory.rbegin(); (iter != mRxHistory.rend()) && (count != 0); ++iter, --count) {
+			output.push_back(iter->to_string());
+		}
+	} else  {
+		output.push_back("Rx history is empty");
+	}
+}
+
+void
+StatCollector::add_ncp_state_history(StringList& output, int count) const
+{
+	if (count == 0) {
+		count = mNCPStateHistory.size();
+	}
+
+	if(!mNCPStateHistory.empty()) {
+		RingBuffer<NcpStateInfo, STAT_COLLECTOR_NCP_STATE_HISTORY_SIZE>::ReverseIterator iter;
+
+		output.push_back("NCP State History");
+		output.push_back("-------------------------");
+		for (iter = mNCPStateHistory.rbegin(); (iter != mNCPStateHistory.rend()) && (count != 0); ++iter, --count) {
+			output.push_back(iter->to_string());
+		}
+	} else {
+		output.push_back("NCP state history is empty.");
+	}
+}
+
+void
+StatCollector::add_ncp_ready_for_host_sleep_state_history(StringList& output, int count) const
+{
+	if (count == 0) {
+		count = mReadyForSleepHistory.size();
+	}
+
+	if (!mReadyForSleepHistory.empty() || (mLastReadyForHostSleepState == false)) {
+		RingBuffer<ReadyForHostSleepState, STAT_COLLECTOR_NCP_READY_FOR_HOST_SLEEP_STATE_HISTORY_SIZE>::ReverseIterator iter;
+
+		output.push_back("\'NCP Ready For Host Sleep State\' History");
+		output.push_back("-------------------------");
+
+		if (mLastReadyForHostSleepState == false) {
+			output.push_back( mLastBlockingHostSleepTime.to_string() + " host sleep was blocked till now");
+		}
+
+		for (iter = mReadyForSleepHistory.rbegin(); (iter != mReadyForSleepHistory.rend()) && (count != 0); ++iter, --count) {
+			output.push_back(iter->to_string());
+		}
+	} else {
+		output.push_back("\'NCP Ready For Host Sleep State\' history is empty.");
+	}
+}
+
+void
+StatCollector::add_tx_stat(StringList& output) const
+{
+	output.push_back (
+		string_printf("Tx: %d packet%s (%d udp, %d tcp, %d icmp6) -- ",
+			mTxPacketsTotal, (mTxPacketsTotal == 1)? "" : "s",
+			mTxPacketsUDP,
+			mTxPacketsTCP,
+			mTxPacketsICMP
+		) +
+		mTxBytesTotal.to_string()
+	);
+}
+
+void
+StatCollector::add_rx_stat(StringList& output) const
+{
+	output.push_back (
+		string_printf("Rx: %d packet%s (%d udp, %d tcp, %d icmp6) -- ",
+			mRxPacketsTotal, (mRxPacketsTotal == 1)? "" : "s",
+			mRxPacketsUDP,
+			mRxPacketsTCP,
+			mRxPacketsICMP
+		) +
+		mRxBytesTotal.to_string()
+	);
+}
+
+void
+StatCollector::add_all_info(StringList& output, int count) const
+{
+	add_tx_stat(output);
+	add_tx_history(output, count);
+
+	output.push_back("");
+
+	add_rx_stat(output);
+	add_rx_history(output, count);
+
+	output.push_back("");
+
+	add_ncp_state_history(output, count);
+
+	output.push_back("");
+
+	if (count == 0) {
+		mNodeStat.add_node_stat_history(output);
+	} else {
+		mNodeStat.add_node_stat(output);
+	}
+
+	output.push_back("");
+	if (count == 0) {
+		mLinkStat.add_link_stat(output);
+	} else {
+		mLinkStat.add_link_stat(output, STAT_COLLECTOR_LINK_STAT_HISTORY_SIZE);
+	}
+}
+
+bool
+StatCollector::is_a_stat_property(const std::string& key)
+{
+	// Check for the prefix to match
+	return strncaseequal(key.c_str(), kWPANTUNDProperty_Stat_Prefix , sizeof(kWPANTUNDProperty_Stat_Prefix) - 1);
+}
+
+void
+StatCollector::add_help(StringList& output) const
+{
+	output.push_back("List of statistics properties");
+	output.push_back(string_printf("\t %-26s - RX statistics (all nodes)", kWPANTUNDProperty_StatRX));
+	output.push_back(string_printf("\t %-26s - TX statistics (all nodes)", kWPANTUNDProperty_StatTX));
+	output.push_back(string_printf("\t %-26s - RX packet info history (all nodes)", kWPANTUNDProperty_StatRXHistory));
+	output.push_back(string_printf("\t %-26s - TX packet info history (all nodes)", kWPANTUNDProperty_StatTXHistory));
+	output.push_back(string_printf("\t %-26s - Both RX & TX packet info history (all nodes)", kWPANTUNDProperty_StatHistory));
+	output.push_back(string_printf("\t %-26s - NCP state change history", kWPANTUNDProperty_StatNCP));
+	output.push_back(string_printf("\t %-26s - \'Blocking Host Sleep\' state change history", kWPANTUNDProperty_StatBlockingHostSleep));
+	output.push_back(string_printf("\t %-26s - List of nodes + RX/TX statistics per node", kWPANTUNDProperty_StatNode));
+	output.push_back(string_printf("\t %-26s - List of nodes + RX/TX statistics and packet history per node", kWPANTUNDProperty_StatNodeHistory));
+	output.push_back(string_printf("\t %-26s - List of nodes + RX/TX statistics and packet history for a specific node with given IP address", kWPANTUNDProperty_StatNodeHistoryID "[<ipv6>]"));
+	output.push_back(string_printf("\t %-26s - List of nodes + RX/TX statistics and packet history for a specific node with given index", kWPANTUNDProperty_StatNodeHistoryID "<index>"));
+	output.push_back(string_printf("\t %-26s - Peer link quality history - short version", kWPANTUNDProperty_StatLinkQualityShort));
+	output.push_back(string_printf("\t %-26s - Peer link quality history - long version", kWPANTUNDProperty_StatLinkQualityLong));
+	output.push_back(string_printf("\t %-26s - All info - short version", kWPANTUNDProperty_StatShort));
+	output.push_back(string_printf("\t %-26s - All info - long version", kWPANTUNDProperty_StatLong));
+	output.push_back(string_printf("\t "));
+	output.push_back(string_printf("\t %-26s - Peer link quality information - get only", kWPANTUNDProperty_StatLinkQuality));
+	output.push_back(string_printf("\t %-26s - Period interval (in seconds) for collecting peer link quality - get/set - zero to disable", kWPANTUNDProperty_StatLinkQualityPeriod));
+	output.push_back(string_printf("\t %-26s - AutoLog information - get only", kWPANTUNDProperty_StatAutoLog));
+	output.push_back(string_printf("\t %-26s - AutoLog state (\'disabled\',\'long\',\'short\'') - get/set", kWPANTUNDProperty_StatAutoLogState));
+	output.push_back(string_printf("\t %-26s - AutoLog period in minutes - get/set", kWPANTUNDProperty_StatAutoLogPeriod));
+	output.push_back(string_printf("\t %-26s - AutoLog log level - get/set", kWPANTUNDProperty_StatAutoLogLogLevel));
+	output.push_back(string_printf("\t %-26s - Log level for user requested logs - get/set", kWPANTUNDProperty_StatUserLogRequestLogLevel));
+    output.push_back(string_printf("\t %-26s : \'emerg\', \'alert\', \'crit\', \'err\', \'warning\', \'notice\', \'info\', \'debug\'","Valid log levels"));
+    output.push_back(string_printf("\t "));
+	output.push_back(string_printf("\t %-26s - Print this help", kWPANTUNDProperty_StatHelp));
+}
+
+int
+StatCollector::get_stat_property(const std::string& key, StringList& output) const
+{
+	int return_status = kWPANTUNDStatus_Ok;
+
+	if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatShort)) {
+		add_all_info(output, STAT_COLLECTOR_SHORT_HISTORY_COUNT);
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatLong)) {
+		add_all_info(output);
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatRX)) {
+		add_rx_stat(output);
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatTX)) {
+		add_tx_stat(output);
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatRXHistory)) {
+		add_rx_stat(output);
+		add_rx_history(output);
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatTXHistory)) {
+		add_tx_stat(output);
+		add_tx_history(output);
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatHistory)) {
+		add_rx_history(output);
+		output.push_back("");
+		add_tx_history(output);
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatNCP)) {
+		add_ncp_state_history(output);
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatBlockingHostSleep)) {
+		add_ncp_ready_for_host_sleep_state_history(output);
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatNode)) {
+		mNodeStat.add_node_stat(output);
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatNodeHistory)) {
+		mNodeStat.add_node_stat_history(output);
+	} else if (strncaseequal(key.c_str(), kWPANTUNDProperty_StatNodeHistoryID, sizeof(kWPANTUNDProperty_StatNodeHistoryID) - 1)) {
+		mNodeStat.add_node_stat_history(output, key.substr(sizeof(kWPANTUNDProperty_StatNodeHistoryID) - 1));
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatLinkQualityLong)) {
+		mLinkStat.add_link_stat(output);
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatLinkQualityShort)) {
+		mLinkStat.add_link_stat(output, STAT_COLLECTOR_LINK_STAT_HISTORY_SIZE);
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatHelp)) {
+		add_help(output);
+	} else {
+		output.push_back(std::string("Unknown/unsupported stat property. Please use \"get ") + kWPANTUNDProperty_StatHelp +
+			"\" to get list of supported properties by statistics collector." );
+		return_status = kWPANTUNDStatus_PropertyNotFound;
+	}
+
+	return return_status;
+}
+
+void
+StatCollector::get_property(const std::string& key, CallbackWithStatusArg1 cb)
+{
+	// First check for AutoLog properties.
+	if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatAutoLog)) {
+		std::string str;
+		switch(mAutoLogState) {
+			case kAutoLogDisabled:
+				str = "Auto stat log is disabled.";
+				break;
+
+			case kAutoLogLong:
+				str = string_printf("Auto stat log is enabled using long version every %d min at log level \'%s\'.",
+					mAutoLogPeriod / Timer::kOneMinute, log_level_to_string(mAutoLogLevel).c_str());
+				break;
+
+			case kAutoLogShort:
+				str = string_printf("Auto stat log is enabled using short version of stat every %d min at log level \'%s\'.",
+					mAutoLogPeriod / Timer::kOneMinute, log_level_to_string(mAutoLogLevel).c_str());
+				break;
+		}
+		cb(kWPANTUNDStatus_Ok, boost::any(str));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatAutoLogState)) {
+		std::string state;
+
+		switch (mAutoLogState) {
+			case kAutoLogDisabled:  state = kWPANTUNDStatAutoLogState_Disabled; break;
+			case kAutoLogShort:     state = kWPANTUNDStatAutoLogState_Short;    break;
+			case kAutoLogLong:      state = kWPANTUNDStatAutoLogState_Long;     break;
+		}
+		cb(kWPANTUNDStatus_Ok, boost::any(state));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatAutoLogPeriod)) {
+		int period_in_min = mAutoLogPeriod / Timer::kOneMinute;
+		cb(kWPANTUNDStatus_Ok, boost::any(period_in_min));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatAutoLogLogLevel)) {
+		cb(kWPANTUNDStatus_Ok, boost::any(log_level_to_string(mAutoLogLevel)));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatUserLogRequestLogLevel)) {
+		cb(kWPANTUNDStatus_Ok, boost::any(log_level_to_string(mUserRequestLogLevel)));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatLinkQuality)) {
+		int period_in_sec = static_cast<int>(mLinkStatTimer.get_interval() / Timer::kOneSecond);
+		std::string str;
+
+		if (period_in_sec == 0) {
+			str = "Periodic query of peer link quality is disabled";
+		} else {
+			str = string_printf("Peer link quality is collected every %d second%s",
+				period_in_sec, (period_in_sec == 1)? "" : "s");
+		}
+		cb(kWPANTUNDStatus_Ok, boost::any(str));
+
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatLinkQualityPeriod)) {
+		int period_in_sec = static_cast<int>(mLinkStatTimer.get_interval() / Timer::kOneSecond);
+		cb(kWPANTUNDStatus_Ok, boost::any(period_in_sec));
+
+	} else {
+		// If not an AutoLog property, check for the stat properties.
+		StringList output;
+		int status = get_stat_property(key, output);
+
+		if (status == kWPANTUNDStatus_Ok) {
+			cb(status, boost::any(output));
+		} else {
+			std::string err_str;
+			err_str = std::string("Unknown stat property. Please use \"get ") + kWPANTUNDProperty_StatHelp
+				+ "\" to get help about StatCollector.";
+			cb(status, boost::any(err_str));
+		}
+	}
+}
+
+void
+StatCollector::set_property(const std::string& key, const boost::any& value, CallbackWithStatus cb)
+{
+	int status = kWPANTUNDStatus_Ok;
+
+	// First check for AutoLog properties.
+	if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatAutoLogState)) {
+		std::string new_state_str = any_to_string(value);
+		AutoLogState new_state;
+
+		if (strcaseequal(new_state_str.c_str(), kWPANTUNDStatAutoLogState_Disabled) ||
+		    strcaseequal(new_state_str.c_str(), "off") ||
+		    strcaseequal(new_state_str.c_str(), "no") ||
+		    strcaseequal(new_state_str.c_str(), "0") )
+		{
+			new_state = kAutoLogDisabled;
+		} else if (
+		    strcaseequal(new_state_str.c_str(), kWPANTUNDStatAutoLogState_Short) ||
+		    strcaseequal(new_state_str.c_str(), "on") ||
+		    strcaseequal(new_state_str.c_str(), "yes") ||
+		    strcaseequal(new_state_str.c_str(), "1") )
+		{
+			new_state = kAutoLogShort;
+		} else if (strcaseequal(new_state_str.c_str(), kWPANTUNDStatAutoLogState_Long)) {
+			new_state = kAutoLogLong;
+		} else {
+			status = kWPANTUNDStatus_InvalidArgument;
+		}
+
+		if (status == kWPANTUNDStatus_Ok) {
+			if (new_state != mAutoLogState) {
+				mAutoLogState = new_state;
+				update_auto_log_timer();
+			}
+		}
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatAutoLogPeriod)) {
+		int period_in_min = any_to_int(value);
+		if ((period_in_min > 0) && (period_in_min <= STAT_COLLECTOR_AUTO_LOG_MAX_PERIOD)) {
+			mAutoLogPeriod = period_in_min * Timer::kOneMinute;
+			update_auto_log_timer();
+		} else {
+			status = kWPANTUNDStatus_InvalidArgument;
+		}
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatAutoLogLogLevel)) {
+		int log_level = log_level_from_string(any_to_string(value).c_str());
+		if (log_level >= 0) {
+			status = kWPANTUNDStatus_Ok;
+			mAutoLogLevel = log_level;
+		} else {
+			status = kWPANTUNDStatus_InvalidArgument;
+		}
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatUserLogRequestLogLevel)) {
+		int log_level = log_level_from_string(any_to_string(value).c_str());
+		if (log_level >= 0) {
+			status = kWPANTUNDStatus_Ok;
+			mUserRequestLogLevel = log_level;
+		} else {
+			status = kWPANTUNDStatus_InvalidArgument;
+		}
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_StatLinkQualityPeriod)) {
+		int period_in_sec = any_to_int(value);
+		if (period_in_sec >= 0) {
+			update_link_stat_timer(period_in_sec * Timer::kOneSecond);
+		}
+	} else {
+		StringList output;
+
+		status = get_stat_property(key, output);
+
+		if (status == kWPANTUNDStatus_Ok) {
+			for(StringList::iterator it = output.begin(); it != output.end(); ++it) {
+				syslog(mUserRequestLogLevel, "Stat: %s", it->c_str());
+			}
+		}
+	}
+
+	cb(status);
+}
+
+void
+StatCollector::update_auto_log_timer(void)
+{
+	if (mAutoLogState == kAutoLogDisabled) {
+		mAutoLogTimer.cancel();
+	} else {
+		mAutoLogTimer.schedule(
+			mAutoLogPeriod,
+			boost::bind(&StatCollector::auto_log_timer_did_fire, this),
+			Timer::kPeriodicFixedDelay
+		);
+
+		// Invoke the callback directly for the first iteration
+		auto_log_timer_did_fire();
+	}
+}
+
+void
+StatCollector::auto_log_timer_did_fire(void)
+{
+	StringList output;
+	int status = kWPANTUNDStatus_Canceled;
+
+	switch (mAutoLogState) {
+		case kAutoLogDisabled:
+			mAutoLogTimer.cancel();
+			break;
+
+		case kAutoLogLong:
+			status = get_stat_property(kWPANTUNDProperty_StatLong, output);
+			break;
+
+		case kAutoLogShort:
+			status = get_stat_property(kWPANTUNDProperty_StatShort, output);
+			break;
+	}
+
+	if (status == kWPANTUNDStatus_Ok) {
+		for(StringList::iterator it = output.begin(); it != output.end(); ++it) {
+			syslog(mAutoLogLevel, "Stat (autolog): %s", it->c_str());
+		}
+	}
+}
+
+void
+StatCollector::update_link_stat_timer(Timer::Interval interval)
+{
+	if (interval == 0) {
+		mLinkStatTimer.cancel();
+	} else {
+		mLinkStatTimer.schedule(
+			interval,
+			boost::bind(&StatCollector::link_stat_timer_did_fire, this),
+			Timer::kPeriodicFixedDelay
+		);
+
+		// Invoke the callback directly for the first iteration
+		link_stat_timer_did_fire();
+	}
+}
+
+void
+StatCollector::link_stat_timer_did_fire(void)
+{
+}
+
+void
+StatCollector::did_get_rip_entry_value_map(int status, const boost::any& value)
+{
+	if (status == kWPANTUNDStatus_Ok) {
+		if (value.type() == typeid(std::list<ValueMap>)) {
+			std::list<ValueMap> rip_entry_list;
+			std::list<ValueMap>::const_iterator it;
+
+			rip_entry_list = boost::any_cast< std::list<ValueMap> >(value);
+
+			for (it = rip_entry_list.begin(); it != rip_entry_list.end(); ++it) {
+				record_rip_entry(*it);
+			}
+		}
+	}
+}
+
+int
+StatCollector::record_rip_entry(const ValueMap& rip_entry)
+{
+	ValueMap::const_iterator it;
+	Data eui64;
+	int8_t rssi = 0;
+	uint8_t in_lqi = 0;
+	uint8_t out_lqi = 0;
+	NodeType node_type = UNKNOWN;
+
+
+	mLinkStat.update(eui64.data(), rssi, in_lqi, out_lqi, node_type);
+
+	return kWPANTUNDStatus_Ok;
+}
+
+void
+StatCollector::property_changed(const std::string& key, const boost::any& value)
+{
+	if (strcaseequal(key.c_str(), kWPANTUNDProperty_NCPState)) {
+		record_ncp_state_change(string_to_ncp_state(any_to_string(value)));
+	} else if (strcaseequal(key.c_str(), kWPANTUNDProperty_DaemonReadyForHostSleep)) {
+		record_ncp_ready_for_host_sleep_state(any_to_bool(value));
+	}
+}
+
+void
+StatCollector::did_rx_net_scan_beacon(const WPAN::NetworkInstance& network)
+{
+	// Log the scan result
+	syslog(LOG_NOTICE,
+	    "Scan -> "
+	    "Name:%-17s, "
+		"PanId:0x%04X, "
+		"Ch:%2d, "
+		"Joinable:%-3s, "
+		"XPanId:0x%02X%02X%02X%02X%02X%02X%02X%02X, "
+		"HwAddr:0x%02X%02X%02X%02X%02X%02X%02X%02X, "
+		"RSSI:%-4d, "
+		"LQI:%-3d, "
+		"ProtoId:%-3d, "
+		"Version:%2d, "
+		"ShortAddr:0x%04X ",
+
+		network.name.c_str(),
+		network.panid,
+		network.channel,
+		network.joinable? "YES" : "NO",
+		network.xpanid[0], network.xpanid[1], network.xpanid[2], network.xpanid[3],
+		network.xpanid[4], network.xpanid[5], network.xpanid[6], network.xpanid[7],
+		network.hwaddr[0], network.hwaddr[1], network.hwaddr[2], network.hwaddr[3],
+		network.hwaddr[4], network.hwaddr[5], network.hwaddr[6], network.xpanid[7],
+		network.rssi,
+		network.lqi,
+		network.type,
+		network.version,
+		network.saddr
+	);
+}
diff --git a/src/wpantund/StatCollector.h b/src/wpantund/StatCollector.h
new file mode 100644
index 0000000..ce5e4bb
--- /dev/null
+++ b/src/wpantund/StatCollector.h
@@ -0,0 +1,332 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      Declaration of Statistics collector module
+ *
+ */
+
+#ifndef wpantund_StatCollector_h
+#define wpantund_StatCollector_h
+
+#include <stdint.h>
+#include <string>
+#include <list>
+#include <map>
+#include "time-utils.h"
+#include "RingBuffer.h"
+#include "ObjectPool.h"
+#include "NCPControlInterface.h"
+#include "NCPTypes.h"
+#include "Timer.h"
+#include "ValueMap.h"
+
+namespace nl {
+namespace wpantund {
+
+// Size of the rx/tx history (for all nodes)
+#define STAT_COLLECTOR_RX_HISTORY_SIZE        64
+#define STAT_COLLECTOR_TX_HISTORY_SIZE        64
+
+// Size of the NCP state history
+#define STAT_COLLECTOR_NCP_STATE_HISTORY_SIZE 64
+
+// Size of the NCP "ReadyForHostSleep" state history
+#define STAT_COLLECTOR_NCP_READY_FOR_HOST_SLEEP_STATE_HISTORY_SIZE  64
+
+// Max number of nodes to track at the same time (nodes are tracked by IP address)
+#define STAT_COLLECTOR_MAX_NODES   64
+
+// Size of rx/tx history per node
+#define STAT_COLLECTOR_PER_NODE_RX_HISTORY_SIZE  5
+#define STAT_COLLECTOR_PER_NODE_TX_HISTORY_SIZE  5
+
+// Maximm number of peer nodes for which we store link quality
+#define STAT_COLLECTOR_MAX_LINKS   64
+
+// History length of link quality info per peer
+#define STAT_COLLECTOR_LINK_QUALITY_HISTORY_SIZE 40
+
+class StatCollector
+{
+public:
+	StatCollector();
+	virtual ~StatCollector();
+
+	void set_ncp_control_interface(NCPControlInterface *ncp_ctrl_interface);
+
+	// Static class methods
+
+	static bool is_a_stat_property(const std::string& key);   // returns true if the property key is associated with stat module
+
+	void get_property(const std::string& key, CallbackWithStatusArg1 cb);
+	void set_property(const std::string& key, const boost::any& value, CallbackWithStatus cb);
+
+	// Methods to inform StatCollector about received/sent packets and state changes
+	void record_inbound_packet(const uint8_t *ipv6_packet);
+	void record_outbound_packet(const uint8_t *ipv6_packet);
+
+private:
+	// Internal types and data structures
+
+	typedef std::list<std::string> StringList;
+
+	struct IPAddress
+	{
+		std::string to_string(void) const;
+		void read_from(const uint8_t *arr);
+		bool operator==(const IPAddress& lhs) const;
+		bool operator<(const IPAddress& lhs) const;
+	private:
+		uint32_t mAddressBuffer[4];
+	};
+
+	struct EUI64Address
+	{
+		std::string to_string(void) const;
+		void read_from(const uint8_t *arr);
+
+		bool operator==(const EUI64Address& lhs) const;
+		bool operator<(const EUI64Address& lhs) const;
+	private:
+		uint32_t mAddress[2];
+	};
+
+	struct TimeStamp
+	{
+		TimeStamp();
+		void set_to_now(void);
+		void clear(void);
+		cms_t get_ms_till_now(void) const;
+		bool is_expired(void) const;
+		bool is_uninitialized(void) const;
+		std::string to_string(void) const;
+		bool operator==(const TimeStamp& lhs);
+		bool operator<(const TimeStamp& lhs);
+
+		static int32_t time_difference_in_ms(TimeStamp t1, TimeStamp t2);
+
+	private:
+		cms_t mTime;
+	};
+
+	struct PacketInfo
+	{
+		TimeStamp  mTimeStamp;
+		uint16_t   mPayloadLen;
+		uint8_t    mType;
+		uint8_t    mSubtype;
+		uint16_t   mSrcPort;
+		uint16_t   mDstPort;
+		IPAddress  mSrcAddress;
+		IPAddress  mDstAddress;
+
+		bool update_from_packet(const uint8_t *ipv6_packet);
+		std::string to_string(void) const;
+	};
+
+	struct BytesTotal
+	{
+	public:
+		BytesTotal();
+		void add(uint16_t bytes);
+		void clear(void);
+		std::string to_string(void) const;
+	private:
+		uint16_t mBytes;      // Number of bytes remaining till next Kilo bytes (1024 bytes)
+		uint32_t mKiloBytes;  // Can go up to 2^32 KB which is 4.3 terabytes (> 4 years of continuous exchange at 250 kbps)
+	};
+
+	struct NcpStateInfo
+	{
+	public:
+		void update(NCPState new_state);
+		std::string to_string(void) const;
+		bool is_expired(void) const;
+	private:
+		NCPState mNcpState;
+		TimeStamp mTimeStamp;
+	};
+
+	struct ReadyForHostSleepState
+	{
+	public:
+		void update_with_blocking_sleep_time(TimeStamp blocking_sleep_time);
+		std::string to_string(void) const;
+	private:
+		TimeStamp mStartBlockingHostSleepTime;
+		TimeStamp mReadyForHostSleepTime;
+	};
+
+	class NodeStat
+	{
+	public:
+		struct NodeInfo
+		{
+		public:
+			uint32_t mTxPacketsTotal;
+			uint32_t mTxPacketsUDP;
+			uint32_t mTxPacketsTCP;
+
+			uint32_t mRxPacketsTotal;
+			uint32_t mRxPacketsUDP;
+			uint32_t mRxPacketsTCP;
+
+			RingBuffer<PacketInfo, STAT_COLLECTOR_PER_NODE_RX_HISTORY_SIZE> mRxHistory;
+			RingBuffer<PacketInfo, STAT_COLLECTOR_PER_NODE_TX_HISTORY_SIZE> mTxHistory;
+
+			NodeInfo();
+			void clear();
+			TimeStamp get_last_rx_time(void) const;
+			TimeStamp get_last_tx_time(void) const;
+			TimeStamp get_last_rx_or_tx_time(void) const;
+			void add_rx_stat(StringList& output, bool add_last_rx_time = true) const;
+			void add_tx_stat(StringList& output, bool add_last_tx_time = true) const;
+			void add_node_info(StringList& output) const;
+		};
+
+		NodeStat();
+		void clear(void);
+		void update_from_inbound_packet(const PacketInfo& packet_info);
+		void update_from_outbound_packet(const PacketInfo& packet_info);
+		void add_node_stat(StringList& output) const;
+		void add_node_stat_history(StringList& output, std::string node_indicator = "") const;
+
+	private:
+		NodeInfo *find_node_info(const IPAddress& address);
+		NodeInfo *create_new_node_info(const IPAddress& address);
+		void remove_oldest_node_info(void);
+		void add_node_info_map_iter(StringList &output, const std::map<IPAddress, NodeInfo*>::const_iterator& it) const;
+
+		ObjectPool<NodeInfo, STAT_COLLECTOR_MAX_NODES> mNodeInfoPool;
+		std::map<IPAddress, NodeInfo*> mNodeInfoMap;
+	};
+
+	class LinkStat
+	{
+	public:
+		struct LinkQuality
+		{
+			LinkQuality();
+			void set(int8_t rssi, uint8_t incoming_link_quality, uint8_t outgoing_link_quality);
+			std::string to_string(void) const;
+			TimeStamp get_time_stamp(void) const;
+		private:
+			uint8_t get_incoming_link_quality(void) const;
+			uint8_t get_outgoing_link_quality(void) const;
+
+			int8_t mRssi;
+			uint8_t mLinkQualityIncomingOutgoing;  // High 4 bits are for incoming, low 4 bits are for outgoing
+			TimeStamp mTimeStamp;
+		};
+
+		struct LinkInfo
+		{
+			NodeType mNodeType;
+			RingBuffer<LinkQuality, STAT_COLLECTOR_LINK_QUALITY_HISTORY_SIZE> mLinkQualityHistory;
+
+			LinkInfo();
+			void clear(void);
+			bool empty(void) const;
+			void add_link_info(StringList& output, int count = 0) const;
+			TimeStamp get_last_update_time(void) const;
+		};
+
+		LinkStat();
+		void clear();
+		void update(const uint8_t *eui64_address, int8_t rssi, uint8_t incoming_link_quality, uint8_t outgoing_link_quality,
+			NodeType node_type);
+		void add_link_stat(StringList& output, int count = 0) const;
+
+	private:
+		LinkInfo *find_link_info(const EUI64Address& address);
+		LinkInfo *create_new_link_info(const EUI64Address & address);
+		void remove_oldest_link_info(void);
+
+		ObjectPool<LinkInfo, STAT_COLLECTOR_MAX_LINKS> mLinkInfoPool;
+		std::map<EUI64Address, LinkInfo *> mLinkInfoMap;
+	};
+
+	enum AutoLogState
+	{
+		kAutoLogDisabled,
+		kAutoLogLong,
+		kAutoLogShort
+	};
+
+private:
+	void record_ncp_state_change(NCPState new_ncp_state);
+	void record_ncp_ready_for_host_sleep_state(bool ready_to_sleep);
+	void add_tx_stat(StringList& output) const;
+	void add_rx_stat(StringList& output) const;
+	void add_rx_history(StringList& output, int count = 0) const;
+	void add_tx_history(StringList& output, int count = 0) const;
+	void add_ncp_state_history(StringList& output, int count = 0) const;
+	void add_ncp_ready_for_host_sleep_state_history(StringList& output, int count = 0) const;
+	void add_help(StringList& output) const;
+	void add_all_info(StringList& output, int count = 0) const;
+	int  get_stat_property(const std::string& key, StringList& output) const;
+	void update_auto_log_timer(void);
+	void auto_log_timer_did_fire(void);
+	void update_link_stat_timer(Timer::Interval interval);
+	void link_stat_timer_did_fire(void);
+	void did_get_rip_entry_value_map(int status, const boost::any& value);
+	int  record_rip_entry(const ValueMap& rip_entry);
+	void property_changed(const std::string& key, const boost::any& value);
+	void did_rx_net_scan_beacon(const WPAN::NetworkInstance& network);
+
+private:
+	NCPControlInterface *mControlInterface;
+
+	uint32_t mTxPacketsTotal;
+	uint32_t mRxPacketsUDP;
+	uint32_t mRxPacketsTCP;
+	uint32_t mRxPacketsICMP;
+	BytesTotal mTxBytesTotal;
+
+	uint32_t mRxPacketsTotal;
+	uint32_t mTxPacketsUDP;
+	uint32_t mTxPacketsTCP;
+	uint32_t mTxPacketsICMP;
+	BytesTotal mRxBytesTotal;
+
+	RingBuffer<PacketInfo, STAT_COLLECTOR_RX_HISTORY_SIZE> mRxHistory;
+	RingBuffer<PacketInfo, STAT_COLLECTOR_TX_HISTORY_SIZE> mTxHistory;
+
+	RingBuffer<NcpStateInfo, STAT_COLLECTOR_NCP_STATE_HISTORY_SIZE> mNCPStateHistory;
+
+	RingBuffer<ReadyForHostSleepState, STAT_COLLECTOR_NCP_READY_FOR_HOST_SLEEP_STATE_HISTORY_SIZE> mReadyForSleepHistory;
+	bool mLastReadyForHostSleepState;
+	TimeStamp mLastBlockingHostSleepTime;
+
+	NodeStat mNodeStat;
+	LinkStat mLinkStat;
+
+	Timer mAutoLogTimer;
+	Timer mLinkStatTimer;
+
+	Timer::Interval mAutoLogPeriod;
+	enum AutoLogState mAutoLogState;
+
+	int mAutoLogLevel;
+	int mUserRequestLogLevel;
+};
+
+}; // namespace wpantund
+}; // namespace nl
+
+#endif  // defined(wpantund_StatCollector_h)
diff --git a/src/wpantund/wpan-error.h b/src/wpantund/wpan-error.h
new file mode 100644
index 0000000..922bc14
--- /dev/null
+++ b/src/wpantund/wpan-error.h
@@ -0,0 +1,78 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef wpantund_wpan_error_h
+#define wpantund_wpan_error_h
+#include <stddef.h>
+
+__BEGIN_DECLS
+
+typedef enum {
+	kWPANTUNDStatus_Ok                            = 0,
+	kWPANTUNDStatus_Failure                       = 1,
+
+	kWPANTUNDStatus_InvalidArgument               = 2,
+	kWPANTUNDStatus_InvalidWhenDisabled           = 3,
+	kWPANTUNDStatus_InvalidForCurrentState        = 4,
+	kWPANTUNDStatus_InvalidType                   = 5,
+	kWPANTUNDStatus_InvalidRange                  = 6,
+
+	kWPANTUNDStatus_Timeout                       = 7,
+	kWPANTUNDStatus_SocketReset                   = 8,
+	kWPANTUNDStatus_Busy                          = 9,
+
+	kWPANTUNDStatus_Already                       = 10,
+	kWPANTUNDStatus_Canceled                      = 11,
+	kWPANTUNDStatus_InProgress                    = 12,
+	kWPANTUNDStatus_TryAgainLater                 = 13,
+
+	kWPANTUNDStatus_FeatureNotSupported           = 14,
+	kWPANTUNDStatus_FeatureNotImplemented         = 15,
+
+	kWPANTUNDStatus_PropertyNotFound              = 16,
+	kWPANTUNDStatus_PropertyEmpty                 = 17,
+
+	kWPANTUNDStatus_JoinFailedUnknown             = 18,
+	kWPANTUNDStatus_JoinFailedAtScan              = 19,
+	kWPANTUNDStatus_JoinFailedAtAuthenticate      = 20,
+	kWPANTUNDStatus_FormFailedAtScan              = 21,
+
+	kWPANTUNDStatus_NCP_Crashed                   = 22,
+	kWPANTUNDStatus_NCP_Fatal                     = 23,
+	kWPANTUNDStatus_NCP_InvalidArgument           = 24,
+	kWPANTUNDStatus_NCP_InvalidRange              = 25,
+
+	kWPANTUNDStatus_MissingXPANID                 = 26,
+
+	kWPANTUNDStatus_NCP_Reset                     = 27,
+
+	kWPANTUNDStatus_InterfaceNotFound             = 28,
+
+	kWPANTUNDStatus_NCPError_First = 0xEA0000,
+	kWPANTUNDStatus_NCPError_Last = 0xEAFFFF,
+} wpantund_status_t;
+
+#define WPANTUND_NCPERROR_MASK		0xFFFF
+
+#define WPANTUND_STATUS_IS_NCPERROR(x)	((((int)x)&~WPANTUND_NCPERROR_MASK) == kWPANTUNDStatus_NCPError_First)
+#define WPANTUND_NCPERROR_TO_STATUS(x)	(wpantund_status_t)((((int)x)&WPANTUND_NCPERROR_MASK)|kWPANTUNDStatus_NCPError_First)
+#define WPANTUND_STATUS_TO_NCPERROR(x)	((x)&WPANTUND_NCPERROR_MASK)
+
+__END_DECLS
+
+#endif
diff --git a/src/wpantund/wpan-properties.h b/src/wpantund/wpan-properties.h
new file mode 100644
index 0000000..0086cee
--- /dev/null
+++ b/src/wpantund/wpan-properties.h
@@ -0,0 +1,201 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *      This file contains the enumeration of the properties that can be
+ *      gotten or set via the "get_prop()" and "set_prop()" methods.
+ *
+ */
+
+#ifndef wpantund_wpan_properties_h
+#define wpantund_wpan_properties_h
+
+
+#define kWPANTUNDProperty_ConfigNCPSocketPath              "Config:NCP:SocketPath"
+#define kWPANTUNDProperty_ConfigNCPSocketBaud              "Config:NCP:SocketBaud"
+#define kWPANTUNDProperty_ConfigNCPDriverName              "Config:NCP:DriverName"
+#define kWPANTUNDProperty_ConfigNCPHardResetPath           "Config:NCP:HardResetPath"
+#define kWPANTUNDProperty_ConfigNCPPowerPath               "Config:NCP:PowerPath"
+#define kWPANTUNDProperty_ConfigNCPReliabilityLayer        "Config:NCP:ReliabilityLayer"
+#define kWPANTUNDProperty_ConfigNCPFirmwareCheckCommand    "Config:NCP:FirmwareCheckCommand"
+#define kWPANTUNDProperty_ConfigNCPFirmwareUpgradeCommand  "Config:NCP:FirmwareUpgradeCommand"
+#define kWPANTUNDProperty_ConfigTUNInterfaceName           "Config:TUN:InterfaceName"
+#define kWPANTUNDProperty_ConfigDaemonPIDFile              "Config:Daemon:PIDFile"
+#define kWPANTUNDProperty_ConfigDaemonPrivDropToUser       "Config:Daemon:PrivDropToUser"
+#define kWPANTUNDProperty_ConfigDaemonChroot               "Config:Daemon:Chroot"
+#define kWPANTUNDProperty_ConfigDaemonNetworkRetainCommand "Config:Daemon:NetworkRetainCommand"
+
+#define kWPANTUNDProperty_DaemonVersion                   "Daemon:Version"
+#define kWPANTUNDProperty_DaemonEnabled                   "Daemon:Enabled"
+#define kWPANTUNDProperty_DaemonSyslogMask                "Daemon:SyslogMask"
+#define kWPANTUNDProperty_DaemonTerminateOnFault          "Daemon:TerminateOnFault"
+#define kWPANTUNDProperty_DaemonReadyForHostSleep         "Daemon:ReadyForHostSleep"
+#define kWPANTUNDProperty_DaemonAutoAssociateAfterReset   "Daemon:AutoAssociateAfterReset"
+#define kWPANTUNDProperty_DaemonAutoFirmwareUpdate        "Daemon:AutoFirmwareUpdate"
+#define kWPANTUNDProperty_DaemonAutoDeepSleep             "Daemon:AutoDeepSleep"
+#define kWPANTUNDProperty_DaemonFaultReason               "Daemon:FaultReason"
+
+#define kWPANTUNDProperty_NCPVersion             "NCP:Version"
+#define kWPANTUNDProperty_NCPState               "NCP:State"
+#define kWPANTUNDProperty_NCPHardwareAddress     "NCP:HardwareAddress"
+#define kWPANTUNDProperty_NCPExtendedAddress     "NCP:ExtendedAddress"
+#define kWPANTUNDProperty_NCPMACAddress          "NCP:MACAddress"
+#define kWPANTUNDProperty_NCPChannel             "NCP:Channel"
+#define kWPANTUNDProperty_NCPFrequency           "NCP:Frequency"
+#define kWPANTUNDProperty_NCPTXPower             "NCP:TXPower"
+#define kWPANTUNDProperty_NCPTXPowerLimit        "NCP:TXPowerLimit"
+#define kWPANTUNDProperty_NCPCCAThreshold        "NCP:CCAThreshold"
+#define kWPANTUNDProperty_NCPChannelMask         "NCP:ChannelMask"
+#define kWPANTUNDProperty_NCPSleepyPollInterval  "NCP:SleepyPollInterval"
+#define kWPANTUNDProperty_NCPRSSI                "NCP:RSSI"
+
+#define kWPANTUNDProperty_NetworkName            "Network:Name"
+#define kWPANTUNDProperty_NetworkXPANID          "Network:XPANID"
+#define kWPANTUNDProperty_NetworkPANID           "Network:PANID"
+#define kWPANTUNDProperty_NetworkNodeType        "Network:NodeType"
+#define kWPANTUNDProperty_NetworkKey             "Network:Key"
+#define kWPANTUNDProperty_NetworkKeyIndex        "Network:KeyIndex"
+#define kWPANTUNDProperty_NetworkIsCommissioned  "Network:IsCommissioned"
+
+#define kWPANTUNDProperty_IPv6LinkLocalAddress   "IPv6:LinkLocalAddress"
+#define kWPANTUNDProperty_IPv6MeshLocalAddress   "IPv6:MeshLocalAddress"
+#define kWPANTUNDProperty_IPv6MeshLocalPrefix    "IPv6:MeshLocalPrefix"
+#define kWPANTUNDProperty_IPv6AllAddresses       "IPv6:AllAddresses"
+
+#define kWPANTUNDProperty_ThreadRLOC16                   "Thread:RLOC16"
+#define kWPANTUNDProperty_ThreadRouterID                 "Thread:RouterID"
+#define kWPANTUNDProperty_ThreadLeaderAddress            "Thread:Leader:Address"
+#define kWPANTUNDProperty_ThreadLeaderRouterID           "Thread:Leader:RouterID"
+#define kWPANTUNDProperty_ThreadLeaderWeight             "Thread:Leader:Weight"
+#define kWPANTUNDProperty_ThreadLeaderLocalWeight        "Thread:Leader:LocalWeight"
+#define kWPANTUNDProperty_ThreadLeaderNetworkData        "Thread:Leader:NetworkData"
+#define kWPANTUNDProperty_ThreadStableLeaderNetworkData  "Thread:Leader:StableNetworkData"
+#define kWPANTUNDProperty_ThreadNetworkData              "Thread:NetworkData"
+#define kWPANTUNDProperty_ThreadChildTable               "Thread:ChildTable"
+#define kWPANTUNDProperty_ThreadChildTableAsValMap       "Thread:ChildTable:AsValMap"
+#define kWPANTUNDProperty_ThreadNeighborTable            "Thread:NeighborTable"
+#define kWPANTUNDProperty_ThreadNeighborTableAsValMap    "Thread:NeighborTable:AsValMap"
+#define kWPANTUNDProperty_ThreadNetworkDataVersion       "Thread:NetworkDataVersion"
+#define kWPANTUNDProperty_ThreadStableNetworkData        "Thread:StableNetworkData"
+#define kWPANTUNDProperty_ThreadStableNetworkDataVersion "Thread:StableNetworkDataVersion"
+#define kWPANTUNDProperty_ThreadPreferredRouterID        "Thread:PreferredRouterID"
+
+#define kWPANTUNDProperty_OpenThreadMsgBufferCounters          "OpenThread:MsgBufferCounters"
+#define kWPANTUNDProperty_OpenThreadMsgBufferCountersAsString  "OpenThread:MsgBufferCounters:AsString"
+
+#define kWPANTUNDProperty_DebugIPv6GlobalIPAddressList         "Debug:IPv6:GlobalIPAddressList"
+
+#define kWPANTUNDProperty_JamDetectionStatus                   "JamDetection:Status"
+#define kWPANTUNDProperty_JamDetectionEnable                   "JamDetection:Enable"
+#define kWPANTUNDProperty_JamDetectionRssiThreshold            "JamDetection:RssiThreshold"
+#define kWPANTUNDProperty_JamDetectionWindow                   "JamDetection:Window"
+#define kWPANTUNDProperty_JamDetectionBusyPeriod               "JamDetection:BusyPeriod"
+#define kWPANTUNDProperty_JamDetectionDebugHistoryBitmap       "JamDetection:Debug:HistoryBitmap"
+
+#define kWPANTUNDProperty_NestLabs_NetworkAllowingJoin         "com.nestlabs.internal:Network:AllowingJoin"
+#define kWPANTUNDProperty_NestLabs_NetworkPassthruPort         "com.nestlabs.internal:Network:PassthruPort"
+#define kWPANTUNDProperty_NestLabs_NCPTransmitHookActive       "com.nestlabs.internal:NCP:TransmitHookActive"
+#define kWPANTUNDProperty_NestLabs_LegacyPreferInterface       "com.nestlabs.internal:Legacy:PreferInterface"
+#define kWPANTUNDProperty_NestLabs_LegacyMeshLocalAddress      "com.nestlabs.internal:Legacy:MeshLocalAddress"
+#define kWPANTUNDProperty_NestLabs_LegacyMeshLocalPrefix       "com.nestlabs.internal:Legacy:MeshLocalPrefix"
+#define kWPANTUNDProperty_NestLabs_LegacyEnabled               "com.nestlabs.internal:Legacy:Enabled"
+#define kWPANTUNDProperty_NestLabs_NetworkWakeData             "com.nestlabs.internal:NetworkWake:Data"
+#define kWPANTUNDProperty_NestLabs_NetworkWakeRemaining        "com.nestlabs.internal:NetworkWake:Remaining"
+#define kWPANTUNDProperty_NestLabs_NetworkWakeBlacklist        "com.nestlabs.internal:NetworkWake:Blacklist"
+#define kWPANTUNDProperty_NestLabs_HackUseDeepSleepOnLowPower  "com.nestlabs.internal:Hack:UseDeepSleepOnLowPower"
+#define kWPANTUNDProperty_NestLabs_HackAlwaysResetToWake       "com.nestlabs.internal:Hack:AlwaysResetToWake"
+
+
+#define kWPANTUNDProperty_Stat_Prefix                "Stat:"
+#define kWPANTUNDProperty_StatRX                     "Stat:RX"
+#define kWPANTUNDProperty_StatTX                     "Stat:TX"
+#define kWPANTUNDProperty_StatRXHistory              "Stat:RX:History"
+#define kWPANTUNDProperty_StatTXHistory              "Stat:TX:History"
+#define kWPANTUNDProperty_StatHistory                "Stat:History"
+#define kWPANTUNDProperty_StatNCP                    "Stat:NCP"
+#define kWPANTUNDProperty_StatBlockingHostSleep      "Stat:BlockingHostSleep"
+#define kWPANTUNDProperty_StatNode                   "Stat:Node"
+#define kWPANTUNDProperty_StatNodeHistory            "Stat:Node:History"
+#define kWPANTUNDProperty_StatNodeHistoryID          "Stat:Node:History:"
+#define kWPANTUNDProperty_StatShort                  "Stat:Short"
+#define kWPANTUNDProperty_StatLong                   "Stat:Long"
+#define kWPANTUNDProperty_StatAutoLog                "Stat:AutoLog"
+#define kWPANTUNDProperty_StatAutoLogState           "Stat:AutoLog:State"
+#define kWPANTUNDProperty_StatAutoLogPeriod          "Stat:AutoLog:Period"
+#define kWPANTUNDProperty_StatAutoLogLogLevel        "Stat:AutoLog:LogLevel"
+#define kWPANTUNDProperty_StatUserLogRequestLogLevel "Stat:UserRequest:LogLevel"
+#define kWPANTUNDProperty_StatLinkQuality            "Stat:LinkQuality"
+#define kWPANTUNDProperty_StatLinkQualityLong        "Stat:LinkQuality:Long"
+#define kWPANTUNDProperty_StatLinkQualityShort       "Stat:LinkQuality:Short"
+#define kWPANTUNDProperty_StatLinkQualityPeriod      "Stat:LinkQuality:Period"
+#define kWPANTUNDProperty_StatHelp                   "Stat:Help"
+
+// ----------------------------------------------------------------------------
+
+#define kWPANTUNDNodeType_Unknown          "unknown"
+#define kWPANTUNDNodeType_Router           "router"
+#define kWPANTUNDNodeType_EndDevice        "end-device"
+#define kWPANTUNDNodeType_SleepyEndDevice  "sleepy-end-device"
+#define kWPANTUNDNodeType_NestLurker       "nl-lurker"
+#define kWPANTUNDNodeType_Commissioner     "commissioner"
+#define kWPANTUNDNodeType_Leader           "leader"
+
+// ----------------------------------------------------------------------------
+
+// When querying the value of the association state property,
+// the returned value will be a human-readable string. Compare
+// it with one of the constants below to get the exact meaning.
+#define kWPANTUNDStateUninitialized            "uninitialized"
+#define kWPANTUNDStateFault                    "uninitialized:fault"
+#define kWPANTUNDStateUpgrading                "uninitialized:upgrading"
+#define kWPANTUNDStateDeepSleep                "offline:deep-sleep"
+#define kWPANTUNDStateOffline                  "offline"
+#define kWPANTUNDStateCommissioned             "offline:commissioned"
+#define kWPANTUNDStateAssociating              "associating"
+#define kWPANTUNDStateCredentialsNeeded        "associating:credentials-needed"
+#define kWPANTUNDStateAssociated               "associated"
+#define kWPANTUNDStateIsolated                 "associated:no-parent"
+#define kWPANTUNDStateNetWake_Asleep           "associated:netwake-asleep"
+#define kWPANTUNDStateNetWake_Waking           "associated:netwake-waking"
+
+// ----------------------------------------------------------------------------
+
+// Values of  the property kWPANTUNDProperty_StatAutoLogState
+#define kWPANTUNDStatAutoLogState_Disabled          "disabled"
+#define kWPANTUNDStatAutoLogState_Long              "long"
+#define kWPANTUNDStatAutoLogState_Short             "short"
+
+
+// ----------------------------------------------------------------------------
+
+// Values for value map keys
+#define kWPANTUNDValueMapKey_NetworkTopology_ExtAddress           "ExtAddress"
+#define kWPANTUNDValueMapKey_NetworkTopology_RLOC16               "RLOC16"
+#define kWPANTUNDValueMapKey_NetworkTopology_LinkQualityIn        "LinkQualityIn"
+#define kWPANTUNDValueMapKey_NetworkTopology_AverageRssi          "AverageRssi"
+#define kWPANTUNDValueMapKey_NetworkTopology_Age                  "Age"
+#define kWPANTUNDValueMapKey_NetworkTopology_RxOnWhenIdle         "RxOnWhenIdle"
+#define kWPANTUNDValueMapKey_NetworkTopology_FullFunction         "FullFunction"
+#define kWPANTUNDValueMapKey_NetworkTopology_SecureDataRequest    "SecureDataRequest"
+#define kWPANTUNDValueMapKey_NetworkTopology_FullNetworkData      "FullNetworkData"
+#define kWPANTUNDValueMapKey_NetworkTopology_Timeout              "Timeout"
+#define kWPANTUNDValueMapKey_NetworkTopology_NetworkDataVersion   "NetworkDataVersion"
+#define kWPANTUNDValueMapKey_NetworkTopology_LinkFrameCounter     "LinkFrameCounter"
+#define kWPANTUNDValueMapKey_NetworkTopology_MleFrameCounter      "MleFrameCounter"
+#define kWPANTUNDValueMapKey_NetworkTopology_IsChild              "IsChild"
+
+#endif
diff --git a/src/wpantund/wpantund.conf b/src/wpantund/wpantund.conf
new file mode 100644
index 0000000..1d98db8
--- /dev/null
+++ b/src/wpantund/wpantund.conf
@@ -0,0 +1,154 @@
+# Example wpantund configuration file
+#
+
+# The desired name of the network interface (not supported on all platforms)
+# Default value is `wpan0`.
+#
+#Config:TUN:InterfaceName wpan0
+
+# Path to serial port used to communicate with the NCP.
+# Has special meaning when prefixed with `system:` or `serial:`.
+# If the path is an IPv4 address/port, it will use a TCP socket.
+#
+#Config:NCP:SocketPath "/dev/tty.usbmodem1234"
+#Config:NCP:SocketPath "127.0.0.1:4901"
+#Config:NCP:SocketPath "system:/usr/local/sbin/spi-server -p - -s /dev/spidev2.0"
+#Config:NCP:SocketPath "serial:/dev/ttyO1,raw,b115200,crtscts=1"
+
+# The desired NCP driver to use.
+# Default value is `spinel`.
+#
+#Config:NCP:DriverName spinel
+
+# Describes what type of serial reliability layer should be used, if any.
+# Generally this is set appropriately automatically, so you usually
+# don't need to bother setting this.
+#
+# Optional. Default value is automatic.
+#
+#Config:NCP:ReliabilityLayer libsoot
+
+# The default transmit power of the NCP, measured in dBm
+# (0 dBm is one milliwatt, can be negative)
+#
+# Optional. Default value is NCP-specific.
+#
+#NCP:TXPower 0
+
+# The CCA threshold value, measured in dBm
+#
+# Optional. Default value is NCP-specific.
+#
+#NCP:CCAThreshold -70
+
+# Path to reset pin. This socket is opened and values sent to it
+# based on the desired reset state. wpantund sends `0\n` to
+# assert the reset pin and sends `1\n` to deassert the reset pin.
+# Can be used with the same `system:` and `serial:` prefixes defined
+# above to handle special cases. On linux, you would generally
+# set this to the `value` file of the RESET GPIO.
+#
+# Optional. If not set, only software resets will be possible.
+#
+#Config:NCP:HardResetPath "/sys/class/gpio/gpio49/value"
+
+# Path to power pin. The semantics are similar to those for
+# `NCPHardResetPath` above, except that wpantund sends `0\n` to
+# indicate that the NCP power should be disabled and `1\n` to
+# indicate that the NCP power should be enabled.
+#
+# Optional. If not set, only software induced sleep will be used
+# for low-power states.
+#
+#Config:NCP:PowerPath "/sys/class/gpio/gpio11/value"
+
+# Syslog mask adjustment. This property is a set of
+# boolean masks for manipulating the bitmask used by `syslog()`.
+# The string can contain the following words that represent
+# the associated bit. The presence of the word in the string
+# indicates that that bit should be set. Prefixing the word with
+# a `-` (dash/minus) indicates that that bit should be cleared.
+# The following keywords are supported:
+#
+# * `all` (All log levels)
+# * `emerg`
+# * `alert`
+# * `crit`
+# * `err`
+# * `warn`
+# * `notice`
+# * `info`
+# * `debug`
+#
+# So, for example, to get all log messages except debugging
+# messages, you would use `all -debug`.
+#
+# Optional. The default value for non-debug builds is
+# `all -info -debug`.
+#
+#Daemon:SyslogMask "all -info -debug"
+
+# Drop root privileges to the given user (and that user's group)
+# after setting up all network interfaces and socket connections.
+# Doing this helps mitigate the implications of security exploits,
+# but may interfere with how hard resets are performed for certain
+# NCPs.
+#
+# Optional. Default value is empty, which means that privileges
+# are not dropped.
+#
+#Config:Daemon:PrivDropToUser "nobody"
+
+# Call `chroot()` to change the root directory to the directory
+# indicated, after setting up all network interfaces and socket
+# connections, but before privileges are dropped for `PrivDropToUser`
+# (if set). Doing this helps mitigate the implications of security
+# exploits, but may interfere with how hard resets are performed
+# for certain NCPs.
+#
+# Optional. Default value is empty, which means that `chroot` is
+# not called.
+#
+#Config:Daemon:Chroot "/var/empty"
+
+# Automatic firmware update enable/disable. This flag determines
+# if the automatic firmware update mechanism (which uses the
+# properties `FirmwareCheckCommand` and `FirmwareUpgradeCommand`,
+# described below) is enabled or disabled. This flag is used
+# when the driver determines that it doesn't know how to talk to
+# the version of the firmware that is running on the NCP.
+#
+# If set to true, the NCP association state will then be set to
+# `upgrading` and the firmware update process will begin. If set to
+# false, the NCP association state will change to `fault`.
+#
+# This property may be changed at runtime to more strictly
+# control when a firmware update is allowed to take place.
+#
+# Optional. The default value is false---which will prevent
+# automatic wpantund-driven firmware updates.
+#
+#Daemon:AutoFirmwareUpdate true
+
+# Firmware update check command. This command is executed with
+# the retrieved version string of the NCP appended as the last
+# argument. If the command returns `0`, a firmware update is
+# necessary. This configuration option is fairly useless without
+# the `FirmwareUpgradeCommand` option also being set, defined below.
+#
+# Optional. If left blank, wpantund-driven firmware updates will
+# be disabled.
+#
+#Config:NCP:FirmwareCheckCommand "test 'MyFunStack/1.0' !="
+#Config:NCP:FirmwareCheckCommand "/usr/local/sbin/zb-loader --is-update-required /usr/share/ncp-firmware/ip-modem-app.bin"
+
+# Firmware upgrade command. This is the command that is actually
+# executed that performs the firmware update. Before calling this
+# command, `wpantund` disconnects entirely from the NCP. While
+# this command is executing, the association state reported
+# for this interface will be `upgrading`.
+#
+# Optional. If left blank, wpantund-driven firmware updates will
+# be disabled.
+#
+#Config:NCP:FirmwareUpgradeCommand "/usr/local/sbin/zb-loader /dev/ttyO1 --app-easyload /usr/share/ncp-firmware/ip-modem-app.bin"
diff --git a/src/wpantund/wpantund.cpp b/src/wpantund/wpantund.cpp
new file mode 100644
index 0000000..a7a028b
--- /dev/null
+++ b/src/wpantund/wpantund.cpp
@@ -0,0 +1,926 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *    Description:
+ *		This file implements the main program entry point for the
+ *		WPAN Tunnel Driver, masterfuly named `wpantund`.
+ *
+ */
+
+#define DEBUG 1
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef ASSERT_MACROS_USE_SYSLOG
+#define ASSERT_MACROS_USE_SYSLOG 1
+#endif
+
+#ifndef ASSERT_MACROS_SQUELCH
+#define ASSERT_MACROS_SQUELCH 0
+#endif
+
+#include "assert-macros.h"
+
+#include "wpantund.h"
+
+#include "config-file.h"
+#include "args.h"
+#include "pt.h"
+#include "tunnel.h"
+#include "socket-utils.h"
+#include "string-utils.h"
+#include "version.h"
+#include "SuperSocket.h"
+#include "Timer.h"
+
+#include "DBUSIPCServer.h"
+#include "NCPControlInterface.h"
+#include "NCPInstance.h"
+
+#include "nlpt.h"
+
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <unistd.h>
+#include <signal.h>
+
+#include <poll.h>
+#include <sys/select.h>
+
+#include <syslog.h>
+#include <errno.h>
+#include <libgen.h>
+
+#include <exception>
+#include <algorithm>
+
+#include "any-to.h"
+#include "sec-random.h"
+
+#if HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#ifndef PREFIX
+#define PREFIX "/usr/local"
+#endif
+
+#ifndef SYSCONFDIR
+#define SYSCONFDIR PREFIX "/etc"
+#endif
+
+#ifndef DEFAULT_MAX_LOG_LEVEL
+#if DEBUG
+#define DEFAULT_MAX_LOG_LEVEL	LOG_INFO
+#else
+#define DEFAULT_MAX_LOG_LEVEL	LOG_NOTICE
+#endif
+#endif
+
+#ifndef WPANTUND_DEFAULT_PRIV_DROP_USER
+#define WPANTUND_DEFAULT_PRIV_DROP_USER     NULL
+#endif
+
+#ifndef WPANTUND_DEFAULT_CHROOT_PATH
+#define WPANTUND_DEFAULT_CHROOT_PATH        NULL
+#endif
+
+#ifndef WPANTUND_BACKTRACE
+#define WPANTUND_BACKTRACE	(HAVE_EXECINFO_H || __APPLE__)
+#endif
+
+#if WPANTUND_BACKTRACE
+#include <execinfo.h>
+#if HAVE_ASM_SIGCONTEXT
+#include <asm/sigcontext.h>
+#endif
+#ifndef FAULT_BACKTRACE_STACK_DEPTH
+#define FAULT_BACKTRACE_STACK_DEPTH		20
+#endif
+#endif
+
+#ifndef SOURCE_VERSION
+#define SOURCE_VERSION		PACKAGE_VERSION
+__BEGIN_DECLS
+#include "version.c.in"
+__END_DECLS
+#endif
+
+using namespace nl;
+using namespace wpantund;
+
+static arg_list_item_t option_list[] = {
+	{ 'h', "help",   NULL,	"Print Help"},
+	{ 'd', "debug",  "<level>", "Enable debugging mode"},
+	{ 'c', "config", "<filename>", "Config File"},
+	{ 'o', "option", "<option-string>", "Config option"},
+	{ 'I', "interface", "<iface>", "Network interface name"},
+	{ 's', "socket", "<socket>", "Socket file"},
+	{ 'b', "baudrate", "<integer>", "Baudrate"},
+	{ 'v', "version", NULL, "Print version" },
+#if HAVE_PWD_H
+	{ 'u', "user", NULL, "Username for dropping privileges" },
+#endif
+	{ 0 }
+};
+
+static int gRet;
+
+static const char* gProcessName = "wpantund";
+static const char* gPIDFilename = NULL;
+static const char* gChroot = WPANTUND_DEFAULT_CHROOT_PATH;
+
+#if HAVE_PWD_H
+static const char* gPrivDropToUser = WPANTUND_DEFAULT_PRIV_DROP_USER;
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* MARK: Signal Handlers */
+
+static sig_t gPreviousHandlerForSIGINT;
+static sig_t gPreviousHandlerForSIGTERM;
+
+static void
+signal_SIGINT(int sig)
+{
+	static const char message[] = "\nCaught SIGINT!\n";
+
+	gRet = ERRORCODE_INTERRUPT;
+
+	// Can't use syslog() because it isn't async signal safe.
+	// So we write to stderr
+	(void)write(STDERR_FILENO, message, sizeof(message)-1);
+
+	// Restore the previous handler so that if we end up getting
+	// this signal again we peform the system default action.
+	signal(SIGINT, gPreviousHandlerForSIGINT);
+	gPreviousHandlerForSIGINT = NULL;
+}
+
+static void
+signal_SIGTERM(int sig)
+{
+	static const char message[] = "\nCaught SIGTERM!\n";
+
+	gRet = ERRORCODE_QUIT;
+
+	// Can't use syslog() because it isn't async signal safe.
+	// So we write to stderr
+	IGNORE_RETURN_VALUE(write(STDERR_FILENO, message, sizeof(message)-1));
+
+	// Restore the previous handler so that if we end up getting
+	// this signal again we peform the system default action.
+	signal(SIGTERM, gPreviousHandlerForSIGTERM);
+	gPreviousHandlerForSIGTERM = NULL;
+}
+
+static void
+signal_SIGHUP(int sig)
+{
+	static const char message[] = "\nCaught SIGHUP!\n";
+
+	gRet = ERRORCODE_SIGHUP;
+
+	// Can't use syslog() because it isn't async signal safe.
+	// So we write to stderr
+	IGNORE_RETURN_VALUE(write(STDERR_FILENO, message, sizeof(message)-1));
+
+	// We don't restore the "previous handler"
+	// because we always want to let the main
+	// loop decide what to do for hangups.
+}
+
+static void
+signal_critical(int sig, siginfo_t * info, void * ucontext)
+{
+	// This is the last hurah for this process.
+	// We dump the stack, because that's all we can do.
+
+	// We call some functions here which aren't async-signal-safe,
+	// but this function isn't really useful without those calls.
+	// Since we are making a gamble (and we deadlock if we loose),
+	// we are going to set up a two-second watchdog to make sure
+	// we end up terminating like we should. The choice of a two
+	// second timeout is entirely arbitrary, and may be changed
+	// if needs warrant.
+	alarm(2);
+	signal(SIGALRM, SIG_DFL);
+
+#if WPANTUND_BACKTRACE
+	void *stack_mem[FAULT_BACKTRACE_STACK_DEPTH];
+	void **stack = stack_mem;
+	char **stack_symbols;
+	int stack_depth, i;
+	ucontext_t *uc = (ucontext_t*)ucontext;
+
+	// Shut up compiler warning.
+	(void)uc;
+
+#endif // WPANTUND_BACKTRACE
+
+	fprintf(stderr, " *** FATAL ERROR: Caught signal %d (%s):\n", sig, strsignal(sig));
+
+#if WPANTUND_BACKTRACE
+	stack_depth = backtrace(stack, FAULT_BACKTRACE_STACK_DEPTH);
+
+#if __APPLE__
+	// OS X adds an extra call onto the stack that
+	// we can leave out for clarity sake.
+	stack[1] = stack[0];
+	stack++;
+	stack_depth--;
+#endif
+
+	// Here are are trying to update the pointer in the backtrace
+	// to be the actual location of the fault.
+#if __linux__
+#if defined(__x86_64__)
+	stack[1] = (void *) uc->uc_mcontext.gregs[REG_RIP];
+#elif defined(__arm__)
+	stack[1] = (void *) uc->uc_mcontext.arm_ip;
+#else
+#warning TODO: Add this arch to signal_critical
+#endif
+
+#elif __APPLE__ // #if __linux__
+#if defined(__x86_64__)
+	stack[1] = (void *) uc->uc_mcontext->__ss.__rip;
+#endif
+
+#else //#elif __APPLE__
+#warning TODO: Add this OS to signal_critical
+#endif
+
+	// Now dump the symbols to stderr, in case syslog barfs.
+	backtrace_symbols_fd(stack, stack_depth, STDERR_FILENO);
+
+	// Load up the symbols individually, so we can output to syslog, too.
+	stack_symbols = backtrace_symbols(stack, stack_depth);
+#endif // WPANTUND_BACKTRACE
+
+	syslog(LOG_CRIT, " *** FATAL ERROR: Caught signal %d (%s):", sig, strsignal(sig));
+
+#if WPANTUND_BACKTRACE
+	for(i = 0; i != stack_depth; i++) {
+#if __APPLE__
+		syslog(LOG_CRIT, "[BT] %s", stack_symbols[i]);
+#else
+		syslog(LOG_CRIT, "[BT] %2d: %s", i, stack_symbols[i]);
+#endif
+	}
+
+	free(stack_symbols);
+#endif // WPANTUND_BACKTRACE
+
+	_exit(EXIT_FAILURE);
+}
+
+/* ------------------------------------------------------------------------- */
+/* MARK: Misc. */
+
+// TODO: Refactor and clean up.
+static int
+set_config_param(
+    void* ignored, const char* key, const char* value
+    )
+{
+	int ret = -1;
+
+	syslog(LOG_INFO, "set-config-param: \"%s\" = \"%s\"", key, value);
+
+	if (strcaseequal(key, kWPANTUNDProperty_ConfigNCPSocketBaud)) {
+		int baud = atoi(value);
+		ret = 0;
+		require(9600 <= baud, bail);
+		gSocketWrapperBaud = baud;
+#if HAVE_PWD_H
+	} else if (strcaseequal(key, kWPANTUNDProperty_ConfigDaemonPrivDropToUser)) {
+		if (value[0] == 0) {
+			gPrivDropToUser = NULL;
+		} else {
+			gPrivDropToUser = strdup(value);
+		}
+		ret = 0;
+#endif
+	} else if (strcaseequal(key, kWPANTUNDProperty_ConfigDaemonChroot)) {
+		if (value[0] == 0) {
+			gChroot = NULL;
+		} else {
+			gChroot = strdup(value);
+		}
+		ret = 0;
+	} else if (strcaseequal(key, kWPANTUNDProperty_DaemonSyslogMask)) {
+		setlogmask(strtologmask(value, setlogmask(0)));
+		ret = 0;
+	} else if (strcaseequal(key, kWPANTUNDProperty_ConfigDaemonPIDFile)) {
+		if (gPIDFilename)
+			goto bail;
+		gPIDFilename = strdup(value);
+		unlink(gPIDFilename);
+		FILE* pidfile = fopen(gPIDFilename, "w");
+		if (!pidfile) {
+			syslog(LOG_ERR, "Unable to open PID file \"%s\".", gPIDFilename);
+			goto bail;
+		}
+		fclose(pidfile);
+		ret = 0;
+	}
+
+bail:
+	if (ret == 0) {
+		syslog(LOG_INFO, "set-config-param: \"%s\" set succeded", key);
+	}
+	return ret;
+}
+
+// Used with `read_config()` to collect configuration settings into a map.
+static int
+add_to_map(
+    void* context,
+	const char* key,
+	const char* value
+) {
+	std::map<std::string, std::string> *map = static_cast<std::map<std::string, std::string>*>(context);
+	(*map)[key] = value;
+	return 0;
+}
+
+static void
+handle_error(int err)
+{
+	gRet = err;
+}
+
+std::string
+nl::wpantund::get_wpantund_version_string(void)
+{
+	std::string version = PACKAGE_VERSION;
+
+	if ((internal_build_source_version[0] == 0) || strequal(SOURCE_VERSION, internal_build_source_version)) {
+		// Ignore any coverty warnings about the following line being pointless.
+		// I assure you, it is not pointless.
+		if (strequal(PACKAGE_VERSION, SOURCE_VERSION)) {
+			version += " (";
+			version += internal_build_date;
+			version += ")";
+		} else {
+			version += " (";
+			version += SOURCE_VERSION;
+			version += "; ";
+			version += internal_build_date;
+			version += ")";
+		}
+	} else {
+		// Ignore any coverty warnings about the following line being pointless.
+		// I assure you, it is not pointless.
+		if (strequal(SOURCE_VERSION, PACKAGE_VERSION) || strequal(PACKAGE_VERSION, internal_build_source_version)) {
+			version += " (";
+			version += internal_build_source_version;
+			version += "; ";
+			version += internal_build_date;
+			version += ")";
+		} else {
+			version += " (";
+			version += SOURCE_VERSION;
+			version += "/";
+			version += internal_build_source_version;
+			version += "; ";
+			version += internal_build_date;
+			version += ")";
+		}
+	}
+	return version;
+}
+
+static void
+print_version()
+{
+	printf("wpantund %s\n", get_wpantund_version_string().c_str() );
+}
+
+/* ------------------------------------------------------------------------- */
+/* MARK: NLPT Hooks */
+
+static fd_set gReadableFDs;
+static fd_set gWritableFDs;
+static fd_set gErrorableFDs;
+
+bool
+nlpt_hook_check_read_fd_source(struct nlpt* nlpt, int fd)
+{
+
+	bool ret = false;
+	if (fd >= 0) {
+		ret = FD_ISSET(fd, &gReadableFDs) || FD_ISSET(fd, &gErrorableFDs);
+		FD_CLR(fd, &gReadableFDs);
+		FD_CLR(fd, &gErrorableFDs);
+	}
+	return ret;
+}
+
+bool
+nlpt_hook_check_write_fd_source(struct nlpt* nlpt, int fd)
+{
+	bool ret = false;
+	if (fd >= 0) {
+		ret = FD_ISSET(fd, &gWritableFDs) || FD_ISSET(fd, &gErrorableFDs);
+		FD_CLR(fd, &gWritableFDs);
+		FD_CLR(fd, &gErrorableFDs);
+	}
+	return ret;
+}
+
+static void
+syslog_dump_select_info(int loglevel, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *error_fd_set, int fd_count, cms_t timeout)
+{
+#define DUMP_FD_SET(l, x) do {\
+		int i; \
+		std::string buffer; \
+		for (i = 0; i < fd_count; i++) { \
+			if (!FD_ISSET(i, x)) { \
+				continue; \
+			} \
+			if (buffer.size() != 0) { \
+				buffer += ", "; \
+			} \
+			char str[10]; \
+			snprintf(str, sizeof(str), "%d", i); \
+			buffer += str; \
+		} \
+		syslog(l, "SELECT:     %s: %s", #x, buffer.c_str()); \
+	} while (0)
+
+	// Check the log level preemptively to avoid wasted CPU.
+	if((setlogmask(0)&LOG_MASK(loglevel))) {
+		syslog(loglevel, "SELECT: fd_count=%d cms_timeout=%d", fd_count, timeout);
+
+		DUMP_FD_SET(loglevel, read_fd_set);
+		DUMP_FD_SET(loglevel, write_fd_set);
+		//DUMP_FD_SET(loglevel, error_fd_set); // Commented out to reduce log volume
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+/* MARK: Main Function */
+
+int
+main(int argc, char * argv[])
+{
+	int c;
+	int fds_ready = 0;
+	bool interface_added = false;
+	int zero_cms_in_a_row_count = 0;
+	const char* config_file = SYSCONFDIR "/wpantund.conf";
+	const char* alt_config_file = SYSCONFDIR "/wpan-tunnel-driver.conf";
+	nl::wpantund::IPCServer *ipc_server = NULL;
+	nl::wpantund::NCPInstance *ncp_instance = NULL;
+	std::map<std::string, std::string> cmd_line_settings;
+
+	// ========================================================================
+	// INITIALIZATION and ARGUMENT PARSING
+
+	gPreviousHandlerForSIGINT = signal(SIGINT, &signal_SIGINT);
+	gPreviousHandlerForSIGTERM = signal(SIGTERM, &signal_SIGTERM);
+	signal(SIGHUP, &signal_SIGHUP);
+
+	// Always ignore SIGPIPE.
+	signal(SIGPIPE, SIG_IGN);
+
+	{
+		struct sigaction sigact = { };
+		sigact.sa_sigaction = &signal_critical;
+		sigact.sa_flags = SA_RESTART | SA_SIGINFO | SA_NOCLDWAIT;
+
+		sigaction(SIGSEGV, &sigact, (struct sigaction *)NULL);
+		sigaction(SIGBUS, &sigact, (struct sigaction *)NULL);
+		sigaction(SIGILL, &sigact, (struct sigaction *)NULL);
+		sigaction(SIGABRT, &sigact, (struct sigaction *)NULL);
+	}
+
+	openlog(basename(argv[0]), LOG_PERROR | LOG_PID | LOG_CONS, LOG_DAEMON);
+
+	// Temper the amount of logging.
+	setlogmask(setlogmask(0) & LOG_UPTO(DEFAULT_MAX_LOG_LEVEL));
+
+	gRet = ERRORCODE_UNKNOWN;
+
+	if (argc && argv[0][0]) {
+		gProcessName = basename(argv[0]);
+	}
+	optind = 0;
+	while(1) {
+		static struct option long_options[] =
+		{
+			{"help",	no_argument,		0,	'h'},
+			{"version",	no_argument,		0,	'v'},
+			{"debug",	no_argument,		0,	'd'},
+			{"config",	required_argument,	0,	'c'},
+			{"option",	required_argument,	0,	'o'},
+			{"interface",	required_argument,	0,	'I'},
+			{"socket",	required_argument,	0,	's'},
+			{"baudrate",	required_argument,	0,	'b'},
+			{"user",	required_argument,	0,	'u'},
+			{0,		0,			0,	0}
+		};
+
+		int option_index = 0;
+		c = getopt_long(argc, argv, "hvd:c:o:I:s:b:u:", long_options,
+			&option_index);
+
+		if (c == -1)
+			break;
+
+		switch(c) {
+		case 'h':
+			print_arg_list_help(option_list, argv[0], "[options]");
+			gRet = ERRORCODE_HELP;
+			goto bail;
+
+		case 'v':
+			print_version();
+			gRet = 0;
+			goto bail;
+
+		case 'd':
+			setlogmask(~0);
+			break;
+
+		case 'c':
+			config_file = optarg;
+			break;
+
+		case 'I':
+			cmd_line_settings[kWPANTUNDProperty_ConfigTUNInterfaceName] = optarg;
+			break;
+
+		case 's':
+			cmd_line_settings[kWPANTUNDProperty_ConfigNCPSocketPath] = optarg;
+			break;
+
+		case 'b':
+			cmd_line_settings[kWPANTUNDProperty_ConfigNCPSocketBaud] = optarg;
+			break;
+
+		case 'u':
+			cmd_line_settings[kWPANTUNDProperty_ConfigDaemonPrivDropToUser] = optarg;
+			break;
+
+		case 'o':
+			if ((optind >= argc) || (strncmp(argv[optind], "-", 1) == 0)) {
+				syslog(LOG_ERR, "Missing argument to '-o'.");
+				gRet = ERRORCODE_BADARG;
+				goto bail;
+			}
+			char *key = optarg;
+			char *value = argv[optind];
+			optind++;
+
+			// We handle this option after we try loading the configuration
+			// file, so that command-line specified settings can override
+			// settings read from the configuration file.
+			cmd_line_settings[key] = value;
+			break;
+		}
+	}
+
+	if (optind < argc) {
+		fprintf(stderr,
+		        "%s: error: Unexpected extra argument: \"%s\"\n",
+		        argv[0],
+		        argv[optind]);
+		gRet = ERRORCODE_BADARG;
+		goto bail;
+	}
+
+	// ========================================================================
+	// STARTUP
+
+	syslog(LOG_NOTICE, "Starting %s " PACKAGE_VERSION " (%s) . . .", gProcessName, internal_build_date);
+
+	if (("" SOURCE_VERSION)[0] != 0) {
+		syslog(LOG_NOTICE, "\tSOURCE_VERSION = " SOURCE_VERSION);
+	}
+
+	if (internal_build_source_version[0] != 0) {
+		syslog(LOG_NOTICE, "\tBUILD_VERSION = %s", internal_build_source_version);
+	}
+
+	if (getuid() != 0) {
+		// Warn people if we aren't root.
+		syslog(LOG_WARNING, "wpantund was not started as 'root'! If wpantund fails immediately, this is probably why.");
+	}
+
+	try {
+		std::map<std::string, std::string> settings;
+
+		// Read the configuration file into the settings map.
+		if (0 == read_config(config_file, &add_to_map, &settings)) {
+			syslog(LOG_NOTICE, "Configuration file \"%s\" read.", config_file);
+		} else if (0 == read_config(alt_config_file, &add_to_map, &settings)) {
+			syslog(LOG_NOTICE, "Configuration file \"%s\" read.", alt_config_file);
+		} else {
+			syslog(LOG_WARNING, "Configuration file \"%s\" not found, will use defaults.", config_file);
+		}
+
+		// Command line settings override configuration file settings.
+		// This is weird because the `insert()` method doesn't replace
+		// a key value pair if it already exists, so to get the desired
+		// behavior, we insert into `cmd_line_settings`, not `settings`.
+		cmd_line_settings.insert(settings.begin(), settings.end());
+
+		// Perform depricated property translation
+		{
+			std::map<std::string, std::string>::const_iterator iter;
+			settings.clear();
+
+			for (iter = cmd_line_settings.begin(); iter != cmd_line_settings.end(); iter++) {
+				std::string key(iter->first);
+				boost::any value(iter->second);
+				if (NCPControlInterface::translate_deprecated_property(key, value)) {
+					if (key.empty()) {
+						syslog(LOG_WARNING, "Configuration property \"%s\" is no longer supported. Please remove it from your configuration.", iter->first.c_str());
+					} else {
+						syslog(LOG_WARNING, "CONFIGURATION PROPERTY \"%s\" IS DEPRECATED. Please use \"%s\" instead.", iter->first.c_str(), key.c_str());
+					}
+				}
+				if (!key.empty()) {
+					settings[key] = any_to_string(value);
+				}
+			}
+		}
+
+		// Handle all of the options/settings.
+		if (!settings.empty()) {
+			std::map<std::string, std::string>::const_iterator iter;
+			std::map<std::string, std::string> settings_for_ncp_control_interface;
+
+			for(iter = settings.begin(); iter != settings.end(); iter++) {
+				if (set_config_param(NULL, iter->first.c_str(), iter->second.c_str())) {
+					// If set_config_param() doesn't like the argument,
+					// we hold onto it for now so we can try passing it as
+					// a property to the NCP instance.
+					settings_for_ncp_control_interface[iter->first] = iter->second;
+				}
+			}
+			settings = settings_for_ncp_control_interface;
+		}
+
+		//require_string(settings.count(kWPANTUNDProperty_ConfigNCPSocketPath) == 1, bail, "Missing "kWPANTUNDProperty_ConfigNCPSocketPath);
+
+		ipc_server = new DBUSIPCServer();
+
+		ncp_instance = NCPInstance::alloc(settings);
+
+		require_string(ncp_instance != NULL, bail, "Unable to create NCPInstance");
+
+		ncp_instance->mOnFatalError.connect(&handle_error);
+
+		ncp_instance->get_stat_collector().set_ncp_control_interface(&ncp_instance->get_control_interface());
+
+	} catch(std::runtime_error x) {
+		syslog(LOG_ERR, "Runtime error thrown while starting up, \"%s\"",x.what());
+		ncp_instance = NULL;
+		goto bail;
+
+	} catch(std::exception x) {
+		syslog(LOG_ERR, "Exception thrown while starting up, \"%s\"",x.what());
+		ncp_instance = NULL;
+		goto bail;
+	}
+
+	if (sec_random_init() < 0) {
+		syslog(LOG_ERR, "Call to sec_random_init() failed, errno=%d \"%s\"", errno, strerror(errno));
+		goto bail;
+	}
+
+	// ========================================================================
+	// Dropping Privileges
+
+	if (gChroot != NULL) {
+		if (getuid() == 0) {
+			if (chdir(gChroot) != 0) {
+				syslog(LOG_CRIT, "chdir: %s", strerror(errno));
+				gRet = ERRORCODE_ERRNO;
+				goto bail;
+			}
+
+			if (chroot(gChroot) != 0) {
+				syslog(LOG_CRIT, "chroot: %s", strerror(errno));
+				gRet = ERRORCODE_ERRNO;
+				goto bail;
+			} else {
+				if (chdir("/") != 0) {
+					syslog(LOG_INFO, "Failed to `chdir` after `chroot` to \"%s\"", gChroot);
+					gRet = ERRORCODE_ERRNO;
+					goto bail;
+				} else {
+					syslog(LOG_INFO, "Successfully changed root directory to \"%s\".", gChroot);
+				}
+			}
+		} else {
+			syslog(LOG_WARNING, "Not running as root, cannot chroot");
+		}
+	}
+
+#if HAVE_PWD_H
+	if (getuid() == 0) {
+		uid_t target_uid = 0;
+		gid_t target_gid = 0;
+
+		if (gPrivDropToUser != NULL) {
+			struct passwd *passwd = getpwnam(gPrivDropToUser);
+
+			if (passwd == NULL) {
+				syslog(LOG_CRIT, "getpwnam: Unable to lookup user \"%s\", cannot drop privileges.", gPrivDropToUser);
+				gRet = ERRORCODE_ERRNO;
+				goto bail;
+			}
+
+			target_uid = passwd->pw_uid;
+			target_gid = passwd->pw_gid;
+		}
+
+		if (target_gid != 0) {
+			if (setgid(target_gid) != 0) {
+				syslog(LOG_CRIT, "setgid: Unable to drop group privileges: %s", strerror(errno));
+				gRet = ERRORCODE_ERRNO;
+				goto bail;
+			} else {
+				syslog(LOG_INFO, "Group privileges dropped to GID:%d", (int)target_gid);
+			}
+		}
+
+		if (target_uid != 0) {
+			if (setuid(target_uid) != 0) {
+				syslog(LOG_CRIT, "setuid: Unable to drop user privileges: %s", strerror(errno));
+				gRet = ERRORCODE_ERRNO;
+				goto bail;
+			} else {
+				syslog(LOG_INFO, "User privileges dropped to UID:%d", (int)target_uid);
+			}
+		}
+
+		if ((target_gid == 0) || (target_uid == 0)) {
+			syslog(LOG_NOTICE, "Running as root without dropping privileges!");
+		}
+	} else if (gPrivDropToUser != NULL) {
+		syslog(LOG_NOTICE, "Not running as root, skipping dropping privileges");
+	}
+#endif // #if HAVE_PWD_H
+
+	// ========================================================================
+	// MAIN LOOP
+
+	gRet = 0;
+
+	while (!gRet) {
+		const cms_t max_main_loop_timeout(CMS_DISTANT_FUTURE);
+		cms_t cms_timeout(max_main_loop_timeout);
+		int max_fd(-1);
+		struct timeval timeout;
+
+		FD_ZERO(&gReadableFDs);
+		FD_ZERO(&gWritableFDs);
+		FD_ZERO(&gErrorableFDs);
+
+		// Update the FD masks and timeouts
+		ncp_instance->update_fd_set(&gReadableFDs, &gWritableFDs, &gErrorableFDs, &max_fd, &cms_timeout);
+		ipc_server->update_fd_set(&gReadableFDs, &gWritableFDs, &gErrorableFDs, &max_fd, &cms_timeout);
+		Timer::update_timeout(&cms_timeout);
+
+		require_string(max_fd < FD_SETSIZE, bail, "Too many file descriptors");
+
+		// Negative CMS timeout values are not valid.
+		if (cms_timeout < 0) {
+			syslog(LOG_DEBUG, "Negative CMS value: %d", cms_timeout);
+			cms_timeout = 0;
+		}
+
+		// Identify conditions where we are burning too much CPU.
+		if (cms_timeout == 0) {
+			double loadavg[3] = {-1.0, -1.0, -1.0};
+
+#if HAVE_GETLOADAVG
+			getloadavg(loadavg, 3);
+#endif
+
+			switch (++zero_cms_in_a_row_count) {
+			case 20:
+				syslog(LOG_INFO, "BUG: Main loop is thrashing! (%f %f %f)", loadavg[0], loadavg[1], loadavg[2]);
+				break;
+
+			case 200:
+				syslog(LOG_WARNING, "BUG: Main loop is still thrashing! Slowing things down. (%f %f %f)", loadavg[0], loadavg[1], loadavg[2]);
+				break;
+
+			case 1000:
+				syslog(LOG_CRIT, "BUG: Main loop had over 1000 iterations in a row with a zero timeout! Terminating. (%f %f %f)", loadavg[0], loadavg[1], loadavg[2]);
+				gRet = ERRORCODE_UNKNOWN;
+				break;
+			}
+			if (zero_cms_in_a_row_count > 200) {
+				// If the past 200 iterations have had a zero timeout,
+				// start using a minimum timeout of 10ms, so that we
+				// don't bring the rest of the system to a grinding halt.
+				cms_timeout = 10;
+			}
+		} else {
+			zero_cms_in_a_row_count = 0;
+		}
+
+		// Convert our `cms` value into timeval compatible with select().
+		timeout.tv_sec = cms_timeout / MSEC_PER_SEC;
+		timeout.tv_usec = (cms_timeout % MSEC_PER_SEC) * USEC_PER_MSEC;
+
+#if DEBUG
+		syslog_dump_select_info(
+			LOG_DEBUG,
+			&gReadableFDs,
+			&gWritableFDs,
+			&gErrorableFDs,
+			max_fd + 1,
+			cms_timeout
+		);
+#endif
+
+		// Block until we timeout or there is FD activity.
+		fds_ready = select(
+			max_fd + 1,
+			&gReadableFDs,
+			&gWritableFDs,
+			&gErrorableFDs,
+			&timeout
+		);
+
+		if (fds_ready < 0) {
+			syslog(LOG_ERR, "select() errno=\"%s\" (%d)", strerror(errno),
+			       errno);
+
+			if (errno == EINTR) {
+				// EINTR isn't necessarily bad. If it was something bad,
+				// we would either already be terminated or gRet will be
+				// set and we will break out of the main loop in a moment.
+				continue;
+			}
+			gRet = ERRORCODE_ERRNO;
+			break;
+		}
+
+		// Process callback timers.
+		Timer::process();
+
+		// Process any necessary IPC actions.
+		ipc_server->process();
+
+		// Process the NCP instance.
+		ncp_instance->process();
+
+		// We only expose the interface via IPC after it is
+		// successfully initialized for the first time.
+		if (!interface_added) {
+			const boost::any value = ncp_instance->get_control_interface().get_property(kWPANTUNDProperty_NCPState);
+			if ((value.type() == boost::any(std::string()).type())
+			 && (boost::any_cast<std::string>(value) != kWPANTUNDStateUninitialized)
+			) {
+				ipc_server->add_interface(&ncp_instance->get_control_interface());
+				interface_added = true;
+			}
+		}
+	} // while (!gRet)
+
+bail:
+	syslog(LOG_NOTICE, "Cleaning up. (gRet = %d)", gRet);
+
+	if (gRet == ERRORCODE_QUIT) {
+		gRet = 0;
+	}
+
+	if (gPIDFilename) {
+		unlink(gPIDFilename);
+	}
+
+	syslog(LOG_NOTICE, "Stopped.");
+	return gRet;
+}
diff --git a/src/wpantund/wpantund.h b/src/wpantund/wpantund.h
new file mode 100644
index 0000000..192bd28
--- /dev/null
+++ b/src/wpantund/wpantund.h
@@ -0,0 +1,33 @@
+/*
+ *
+ * Copyright (c) 2016 Nest Labs, Inc.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef wpantund_h
+#define wpantund_h
+
+#include <string>
+
+namespace nl {
+namespace wpantund {
+
+std::string get_wpantund_version_string(void);
+
+};
+};
+
+#endif
diff --git a/third_party/Makefile.am b/third_party/Makefile.am
new file mode 100644
index 0000000..ca170a4
--- /dev/null
+++ b/third_party/Makefile.am
@@ -0,0 +1,761 @@
+#
+# Copyright (c) 2016 Nest Labs, 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.
+#
+
+DISTCLEANFILES = \
+	.deps \
+	Makefile \
+	$(NULL)
+
+# This line is needed for the lines below to work.
+EXTRA_DIST = $(NULL)
+
+# Protothreads
+EXTRA_DIST += \
+	pt/LICENSE \
+	pt/Makefile \
+	pt/README \
+	pt/README-VISUAL-C++.txt \
+	pt/README.google \
+	pt/doc/Doxyfile \
+	pt/doc/Makefile \
+	pt/doc/header.tex \
+	pt/doc/pt-doc.txt \
+	pt/doc/pt-mainpage.txt \
+	pt/doc/sicslogo.pdf \
+	pt/example-buffer.c \
+	pt/example-codelock.c \
+	pt/example-small.c \
+	pt/lc-addrlabels.h \
+	pt/lc-switch.h \
+	pt/lc.h \
+	pt/pt-sem.h \
+	pt/pt.h \
+	$(NULL)
+
+# Assert Macros
+EXTRA_DIST += \
+	assert-macros/LICENSE \
+	assert-macros/README.google \
+	assert-macros/assert-macros.h \
+	$(NULL)
+
+# fgetln
+EXTRA_DIST += \
+	fgetln/LICENSE \
+	fgetln/README.google \
+	fgetln/fgetln.h \
+	$(NULL)
+
+# Boost
+EXTRA_DIST += \
+	boost/LICENSE \
+	boost/README.google \
+	boost/boost/aligned_storage.hpp \
+	boost/boost/any.hpp \
+	boost/boost/assert.hpp \
+	boost/boost/bind/arg.hpp \
+	boost/boost/bind/bind.hpp \
+	boost/boost/bind/bind_cc.hpp \
+	boost/boost/bind/bind_mf2_cc.hpp \
+	boost/boost/bind/bind_mf_cc.hpp \
+	boost/boost/bind/bind_template.hpp \
+	boost/boost/bind/mem_fn.hpp \
+	boost/boost/bind/mem_fn_cc.hpp \
+	boost/boost/bind/mem_fn_template.hpp \
+	boost/boost/bind/placeholders.hpp \
+	boost/boost/bind/storage.hpp \
+	boost/boost/bind.hpp \
+	boost/boost/blank.hpp \
+	boost/boost/blank_fwd.hpp \
+	boost/boost/call_traits.hpp \
+	boost/boost/checked_delete.hpp \
+	boost/boost/config/compiler/clang.hpp \
+	boost/boost/config/compiler/gcc.hpp \
+	boost/boost/config/no_tr1/functional.hpp \
+	boost/boost/config/no_tr1/memory.hpp \
+	boost/boost/config/platform/linux.hpp \
+	boost/boost/config/platform/macos.hpp \
+	boost/boost/config/posix_features.hpp \
+	boost/boost/config/select_compiler_config.hpp \
+	boost/boost/config/select_platform_config.hpp \
+	boost/boost/config/select_stdlib_config.hpp \
+	boost/boost/config/stdlib/libcpp.hpp \
+	boost/boost/config/stdlib/libstdcpp3.hpp \
+	boost/boost/config/suffix.hpp \
+	boost/boost/config/user.hpp \
+	boost/boost/config.hpp \
+	boost/boost/core/addressof.hpp \
+	boost/boost/core/checked_delete.hpp \
+	boost/boost/core/demangle.hpp \
+	boost/boost/core/enable_if.hpp \
+	boost/boost/core/explicit_operator_bool.hpp \
+	boost/boost/core/is_same.hpp \
+	boost/boost/core/no_exceptions_support.hpp \
+	boost/boost/core/noncopyable.hpp \
+	boost/boost/core/ref.hpp \
+	boost/boost/core/swap.hpp \
+	boost/boost/core/typeinfo.hpp \
+	boost/boost/cstdint.hpp \
+	boost/boost/current_function.hpp \
+	boost/boost/detail/call_traits.hpp \
+	boost/boost/detail/indirect_traits.hpp \
+	boost/boost/detail/iterator.hpp \
+	boost/boost/detail/no_exceptions_support.hpp \
+	boost/boost/detail/reference_content.hpp \
+	boost/boost/detail/sp_typeinfo.hpp \
+	boost/boost/detail/templated_streams.hpp \
+	boost/boost/detail/workaround.hpp \
+	boost/boost/enable_shared_from_this.hpp \
+	boost/boost/exception/exception.hpp \
+	boost/boost/function/detail/function_iterate.hpp \
+	boost/boost/function/detail/maybe_include.hpp \
+	boost/boost/function/detail/prologue.hpp \
+	boost/boost/function/function_base.hpp \
+	boost/boost/function/function_fwd.hpp \
+	boost/boost/function/function_template.hpp \
+	boost/boost/function.hpp \
+	boost/boost/function_equal.hpp \
+	boost/boost/function_output_iterator.hpp \
+	boost/boost/functional/hash/hash_fwd.hpp \
+	boost/boost/functional/hash_fwd.hpp \
+	boost/boost/get_pointer.hpp \
+	boost/boost/integer.hpp \
+	boost/boost/integer_fwd.hpp \
+	boost/boost/integer_traits.hpp \
+	boost/boost/is_placeholder.hpp \
+	boost/boost/iterator/detail/config_def.hpp \
+	boost/boost/iterator/detail/config_undef.hpp \
+	boost/boost/iterator/detail/enable_if.hpp \
+	boost/boost/iterator/detail/facade_iterator_category.hpp \
+	boost/boost/iterator/interoperable.hpp \
+	boost/boost/iterator/iterator_adaptor.hpp \
+	boost/boost/iterator/iterator_categories.hpp \
+	boost/boost/iterator/iterator_facade.hpp \
+	boost/boost/iterator/iterator_traits.hpp \
+	boost/boost/iterator/reverse_iterator.hpp \
+	boost/boost/iterator.hpp \
+	boost/boost/limits.hpp \
+	boost/boost/math/common_factor_ct.hpp \
+	boost/boost/math_fwd.hpp \
+	boost/boost/mem_fn.hpp \
+	boost/boost/move/adl_move_swap.hpp \
+	boost/boost/move/algorithm.hpp \
+	boost/boost/move/core.hpp \
+	boost/boost/move/detail/config_begin.hpp \
+	boost/boost/move/detail/config_end.hpp \
+	boost/boost/move/detail/iterator_traits.hpp \
+	boost/boost/move/detail/meta_utils.hpp \
+	boost/boost/move/detail/meta_utils_core.hpp \
+	boost/boost/move/detail/std_ns_begin.hpp \
+	boost/boost/move/detail/std_ns_end.hpp \
+	boost/boost/move/detail/type_traits.hpp \
+	boost/boost/move/detail/workaround.hpp \
+	boost/boost/move/iterator.hpp \
+	boost/boost/move/move.hpp \
+	boost/boost/move/traits.hpp \
+	boost/boost/move/utility.hpp \
+	boost/boost/move/utility_core.hpp \
+	boost/boost/mpl/O1_size.hpp \
+	boost/boost/mpl/O1_size_fwd.hpp \
+	boost/boost/mpl/advance.hpp \
+	boost/boost/mpl/advance_fwd.hpp \
+	boost/boost/mpl/always.hpp \
+	boost/boost/mpl/and.hpp \
+	boost/boost/mpl/apply.hpp \
+	boost/boost/mpl/apply_fwd.hpp \
+	boost/boost/mpl/apply_wrap.hpp \
+	boost/boost/mpl/arg.hpp \
+	boost/boost/mpl/arg_fwd.hpp \
+	boost/boost/mpl/assert.hpp \
+	boost/boost/mpl/aux_/O1_size_impl.hpp \
+	boost/boost/mpl/aux_/adl_barrier.hpp \
+	boost/boost/mpl/aux_/advance_backward.hpp \
+	boost/boost/mpl/aux_/advance_forward.hpp \
+	boost/boost/mpl/aux_/arg_typedef.hpp \
+	boost/boost/mpl/aux_/arity.hpp \
+	boost/boost/mpl/aux_/arity_spec.hpp \
+	boost/boost/mpl/aux_/begin_end_impl.hpp \
+	boost/boost/mpl/aux_/clear_impl.hpp \
+	boost/boost/mpl/aux_/common_name_wknd.hpp \
+	boost/boost/mpl/aux_/comparison_op.hpp \
+	boost/boost/mpl/aux_/config/adl.hpp \
+	boost/boost/mpl/aux_/config/arrays.hpp \
+	boost/boost/mpl/aux_/config/bcc.hpp \
+	boost/boost/mpl/aux_/config/bind.hpp \
+	boost/boost/mpl/aux_/config/compiler.hpp \
+	boost/boost/mpl/aux_/config/ctps.hpp \
+	boost/boost/mpl/aux_/config/dtp.hpp \
+	boost/boost/mpl/aux_/config/eti.hpp \
+	boost/boost/mpl/aux_/config/forwarding.hpp \
+	boost/boost/mpl/aux_/config/gcc.hpp \
+	boost/boost/mpl/aux_/config/gpu.hpp \
+	boost/boost/mpl/aux_/config/has_apply.hpp \
+	boost/boost/mpl/aux_/config/has_xxx.hpp \
+	boost/boost/mpl/aux_/config/integral.hpp \
+	boost/boost/mpl/aux_/config/intel.hpp \
+	boost/boost/mpl/aux_/config/lambda.hpp \
+	boost/boost/mpl/aux_/config/msvc.hpp \
+	boost/boost/mpl/aux_/config/msvc_typename.hpp \
+	boost/boost/mpl/aux_/config/nttp.hpp \
+	boost/boost/mpl/aux_/config/overload_resolution.hpp \
+	boost/boost/mpl/aux_/config/pp_counter.hpp \
+	boost/boost/mpl/aux_/config/preprocessor.hpp \
+	boost/boost/mpl/aux_/config/static_constant.hpp \
+	boost/boost/mpl/aux_/config/ttp.hpp \
+	boost/boost/mpl/aux_/config/use_preprocessed.hpp \
+	boost/boost/mpl/aux_/config/workaround.hpp \
+	boost/boost/mpl/aux_/empty_impl.hpp \
+	boost/boost/mpl/aux_/find_if_pred.hpp \
+	boost/boost/mpl/aux_/fold_impl.hpp \
+	boost/boost/mpl/aux_/front_impl.hpp \
+	boost/boost/mpl/aux_/full_lambda.hpp \
+	boost/boost/mpl/aux_/has_apply.hpp \
+	boost/boost/mpl/aux_/has_begin.hpp \
+	boost/boost/mpl/aux_/has_size.hpp \
+	boost/boost/mpl/aux_/has_tag.hpp \
+	boost/boost/mpl/aux_/has_type.hpp \
+	boost/boost/mpl/aux_/include_preprocessed.hpp \
+	boost/boost/mpl/aux_/inserter_algorithm.hpp \
+	boost/boost/mpl/aux_/integral_wrapper.hpp \
+	boost/boost/mpl/aux_/is_msvc_eti_arg.hpp \
+	boost/boost/mpl/aux_/iter_apply.hpp \
+	boost/boost/mpl/aux_/iter_fold_if_impl.hpp \
+	boost/boost/mpl/aux_/iter_fold_impl.hpp \
+	boost/boost/mpl/aux_/lambda_arity_param.hpp \
+	boost/boost/mpl/aux_/lambda_spec.hpp \
+	boost/boost/mpl/aux_/lambda_support.hpp \
+	boost/boost/mpl/aux_/msvc_eti_base.hpp \
+	boost/boost/mpl/aux_/msvc_never_true.hpp \
+	boost/boost/mpl/aux_/msvc_type.hpp \
+	boost/boost/mpl/aux_/na.hpp \
+	boost/boost/mpl/aux_/na_assert.hpp \
+	boost/boost/mpl/aux_/na_fwd.hpp \
+	boost/boost/mpl/aux_/na_spec.hpp \
+	boost/boost/mpl/aux_/nested_type_wknd.hpp \
+	boost/boost/mpl/aux_/nttp_decl.hpp \
+	boost/boost/mpl/aux_/numeric_cast_utils.hpp \
+	boost/boost/mpl/aux_/numeric_op.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/and.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/apply.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/apply_fwd.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/arg.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/bind.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/bind_fwd.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/full_lambda.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/less.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/list.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/or.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/placeholders.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/quote.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp \
+	boost/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp \
+	boost/boost/mpl/aux_/preprocessor/def_params_tail.hpp \
+	boost/boost/mpl/aux_/preprocessor/default_params.hpp \
+	boost/boost/mpl/aux_/preprocessor/enum.hpp \
+	boost/boost/mpl/aux_/preprocessor/params.hpp \
+	boost/boost/mpl/aux_/push_back_impl.hpp \
+	boost/boost/mpl/aux_/push_front_impl.hpp \
+	boost/boost/mpl/aux_/reverse_fold_impl.hpp \
+	boost/boost/mpl/aux_/static_cast.hpp \
+	boost/boost/mpl/aux_/template_arity.hpp \
+	boost/boost/mpl/aux_/template_arity_fwd.hpp \
+	boost/boost/mpl/aux_/traits_lambda_spec.hpp \
+	boost/boost/mpl/aux_/type_wrapper.hpp \
+	boost/boost/mpl/aux_/value_wknd.hpp \
+	boost/boost/mpl/aux_/yes_no.hpp \
+	boost/boost/mpl/back_inserter.hpp \
+	boost/boost/mpl/begin_end.hpp \
+	boost/boost/mpl/begin_end_fwd.hpp \
+	boost/boost/mpl/bind.hpp \
+	boost/boost/mpl/bind_fwd.hpp \
+	boost/boost/mpl/bool.hpp \
+	boost/boost/mpl/bool_fwd.hpp \
+	boost/boost/mpl/clear.hpp \
+	boost/boost/mpl/clear_fwd.hpp \
+	boost/boost/mpl/deref.hpp \
+	boost/boost/mpl/distance.hpp \
+	boost/boost/mpl/distance_fwd.hpp \
+	boost/boost/mpl/empty.hpp \
+	boost/boost/mpl/empty_fwd.hpp \
+	boost/boost/mpl/eval_if.hpp \
+	boost/boost/mpl/find_if.hpp \
+	boost/boost/mpl/fold.hpp \
+	boost/boost/mpl/front.hpp \
+	boost/boost/mpl/front_fwd.hpp \
+	boost/boost/mpl/front_inserter.hpp \
+	boost/boost/mpl/has_xxx.hpp \
+	boost/boost/mpl/identity.hpp \
+	boost/boost/mpl/if.hpp \
+	boost/boost/mpl/inserter.hpp \
+	boost/boost/mpl/int.hpp \
+	boost/boost/mpl/int_fwd.hpp \
+	boost/boost/mpl/integral_c.hpp \
+	boost/boost/mpl/integral_c_fwd.hpp \
+	boost/boost/mpl/integral_c_tag.hpp \
+	boost/boost/mpl/is_sequence.hpp \
+	boost/boost/mpl/iter_fold.hpp \
+	boost/boost/mpl/iter_fold_if.hpp \
+	boost/boost/mpl/iterator_category.hpp \
+	boost/boost/mpl/iterator_range.hpp \
+	boost/boost/mpl/iterator_tags.hpp \
+	boost/boost/mpl/lambda.hpp \
+	boost/boost/mpl/lambda_fwd.hpp \
+	boost/boost/mpl/less.hpp \
+	boost/boost/mpl/limits/arity.hpp \
+	boost/boost/mpl/limits/list.hpp \
+	boost/boost/mpl/list/aux_/O1_size.hpp \
+	boost/boost/mpl/list/aux_/begin_end.hpp \
+	boost/boost/mpl/list/aux_/clear.hpp \
+	boost/boost/mpl/list/aux_/empty.hpp \
+	boost/boost/mpl/list/aux_/front.hpp \
+	boost/boost/mpl/list/aux_/include_preprocessed.hpp \
+	boost/boost/mpl/list/aux_/item.hpp \
+	boost/boost/mpl/list/aux_/iterator.hpp \
+	boost/boost/mpl/list/aux_/pop_front.hpp \
+	boost/boost/mpl/list/aux_/preprocessed/plain/list10.hpp \
+	boost/boost/mpl/list/aux_/preprocessed/plain/list20.hpp \
+	boost/boost/mpl/list/aux_/push_back.hpp \
+	boost/boost/mpl/list/aux_/push_front.hpp \
+	boost/boost/mpl/list/aux_/size.hpp \
+	boost/boost/mpl/list/aux_/tag.hpp \
+	boost/boost/mpl/list/list0.hpp \
+	boost/boost/mpl/list/list10.hpp \
+	boost/boost/mpl/list/list20.hpp \
+	boost/boost/mpl/list.hpp \
+	boost/boost/mpl/logical.hpp \
+	boost/boost/mpl/long.hpp \
+	boost/boost/mpl/long_fwd.hpp \
+	boost/boost/mpl/max_element.hpp \
+	boost/boost/mpl/min_max.hpp \
+	boost/boost/mpl/negate.hpp \
+	boost/boost/mpl/next.hpp \
+	boost/boost/mpl/next_prior.hpp \
+	boost/boost/mpl/not.hpp \
+	boost/boost/mpl/numeric_cast.hpp \
+	boost/boost/mpl/or.hpp \
+	boost/boost/mpl/pair.hpp \
+	boost/boost/mpl/pair_view.hpp \
+	boost/boost/mpl/placeholders.hpp \
+	boost/boost/mpl/pop_front_fwd.hpp \
+	boost/boost/mpl/prior.hpp \
+	boost/boost/mpl/protect.hpp \
+	boost/boost/mpl/push_back.hpp \
+	boost/boost/mpl/push_back_fwd.hpp \
+	boost/boost/mpl/push_front.hpp \
+	boost/boost/mpl/push_front_fwd.hpp \
+	boost/boost/mpl/quote.hpp \
+	boost/boost/mpl/reverse_fold.hpp \
+	boost/boost/mpl/same_as.hpp \
+	boost/boost/mpl/sequence_tag.hpp \
+	boost/boost/mpl/sequence_tag_fwd.hpp \
+	boost/boost/mpl/size_fwd.hpp \
+	boost/boost/mpl/size_t.hpp \
+	boost/boost/mpl/size_t_fwd.hpp \
+	boost/boost/mpl/sizeof.hpp \
+	boost/boost/mpl/tag.hpp \
+	boost/boost/mpl/transform.hpp \
+	boost/boost/mpl/void.hpp \
+	boost/boost/mpl/void_fwd.hpp \
+	boost/boost/multi_index/detail/scope_guard.hpp \
+	boost/boost/next_prior.hpp \
+	boost/boost/noncopyable.hpp \
+	boost/boost/none.hpp \
+	boost/boost/none_t.hpp \
+	boost/boost/optional/bad_optional_access.hpp \
+	boost/boost/optional/optional.hpp \
+	boost/boost/optional/optional_fwd.hpp \
+	boost/boost/optional.hpp \
+	boost/boost/predef/architecture/alpha.h \
+	boost/boost/predef/architecture/arm.h \
+	boost/boost/predef/architecture/blackfin.h \
+	boost/boost/predef/architecture/convex.h \
+	boost/boost/predef/architecture/ia64.h \
+	boost/boost/predef/architecture/m68k.h \
+	boost/boost/predef/architecture/mips.h \
+	boost/boost/predef/architecture/parisc.h \
+	boost/boost/predef/architecture/ppc.h \
+	boost/boost/predef/architecture/pyramid.h \
+	boost/boost/predef/architecture/rs6k.h \
+	boost/boost/predef/architecture/sparc.h \
+	boost/boost/predef/architecture/superh.h \
+	boost/boost/predef/architecture/sys370.h \
+	boost/boost/predef/architecture/sys390.h \
+	boost/boost/predef/architecture/x86/32.h \
+	boost/boost/predef/architecture/x86/64.h \
+	boost/boost/predef/architecture/x86.h \
+	boost/boost/predef/architecture/z.h \
+	boost/boost/predef/architecture.h \
+	boost/boost/predef/compiler/borland.h \
+	boost/boost/predef/compiler/clang.h \
+	boost/boost/predef/compiler/comeau.h \
+	boost/boost/predef/compiler/compaq.h \
+	boost/boost/predef/compiler/diab.h \
+	boost/boost/predef/compiler/digitalmars.h \
+	boost/boost/predef/compiler/dignus.h \
+	boost/boost/predef/compiler/edg.h \
+	boost/boost/predef/compiler/ekopath.h \
+	boost/boost/predef/compiler/gcc.h \
+	boost/boost/predef/compiler/gcc_xml.h \
+	boost/boost/predef/compiler/greenhills.h \
+	boost/boost/predef/compiler/hp_acc.h \
+	boost/boost/predef/compiler/iar.h \
+	boost/boost/predef/compiler/ibm.h \
+	boost/boost/predef/compiler/intel.h \
+	boost/boost/predef/compiler/kai.h \
+	boost/boost/predef/compiler/llvm.h \
+	boost/boost/predef/compiler/metaware.h \
+	boost/boost/predef/compiler/metrowerks.h \
+	boost/boost/predef/compiler/microtec.h \
+	boost/boost/predef/compiler/mpw.h \
+	boost/boost/predef/compiler/palm.h \
+	boost/boost/predef/compiler/pgi.h \
+	boost/boost/predef/compiler/sgi_mipspro.h \
+	boost/boost/predef/compiler/sunpro.h \
+	boost/boost/predef/compiler/tendra.h \
+	boost/boost/predef/compiler/visualc.h \
+	boost/boost/predef/compiler/watcom.h \
+	boost/boost/predef/compiler.h \
+	boost/boost/predef/detail/_cassert.h \
+	boost/boost/predef/detail/_exception.h \
+	boost/boost/predef/detail/comp_detected.h \
+	boost/boost/predef/detail/os_detected.h \
+	boost/boost/predef/detail/test.h \
+	boost/boost/predef/hardware/simd/arm/versions.h \
+	boost/boost/predef/hardware/simd/arm.h \
+	boost/boost/predef/hardware/simd/ppc/versions.h \
+	boost/boost/predef/hardware/simd/ppc.h \
+	boost/boost/predef/hardware/simd/x86/versions.h \
+	boost/boost/predef/hardware/simd/x86.h \
+	boost/boost/predef/hardware/simd/x86_amd/versions.h \
+	boost/boost/predef/hardware/simd/x86_amd.h \
+	boost/boost/predef/hardware/simd.h \
+	boost/boost/predef/hardware.h \
+	boost/boost/predef/language/objc.h \
+	boost/boost/predef/language/stdc.h \
+	boost/boost/predef/language/stdcpp.h \
+	boost/boost/predef/language.h \
+	boost/boost/predef/library/c/_prefix.h \
+	boost/boost/predef/library/c/gnu.h \
+	boost/boost/predef/library/c/uc.h \
+	boost/boost/predef/library/c/vms.h \
+	boost/boost/predef/library/c/zos.h \
+	boost/boost/predef/library/c.h \
+	boost/boost/predef/library/std/_prefix.h \
+	boost/boost/predef/library/std/cxx.h \
+	boost/boost/predef/library/std/dinkumware.h \
+	boost/boost/predef/library/std/libcomo.h \
+	boost/boost/predef/library/std/modena.h \
+	boost/boost/predef/library/std/msl.h \
+	boost/boost/predef/library/std/roguewave.h \
+	boost/boost/predef/library/std/sgi.h \
+	boost/boost/predef/library/std/stdcpp3.h \
+	boost/boost/predef/library/std/stlport.h \
+	boost/boost/predef/library/std/vacpp.h \
+	boost/boost/predef/library/std.h \
+	boost/boost/predef/library.h \
+	boost/boost/predef/make.h \
+	boost/boost/predef/os/aix.h \
+	boost/boost/predef/os/amigaos.h \
+	boost/boost/predef/os/android.h \
+	boost/boost/predef/os/beos.h \
+	boost/boost/predef/os/bsd/bsdi.h \
+	boost/boost/predef/os/bsd/dragonfly.h \
+	boost/boost/predef/os/bsd/free.h \
+	boost/boost/predef/os/bsd/net.h \
+	boost/boost/predef/os/bsd/open.h \
+	boost/boost/predef/os/bsd.h \
+	boost/boost/predef/os/cygwin.h \
+	boost/boost/predef/os/haiku.h \
+	boost/boost/predef/os/hpux.h \
+	boost/boost/predef/os/ios.h \
+	boost/boost/predef/os/irix.h \
+	boost/boost/predef/os/linux.h \
+	boost/boost/predef/os/macos.h \
+	boost/boost/predef/os/os400.h \
+	boost/boost/predef/os/qnxnto.h \
+	boost/boost/predef/os/solaris.h \
+	boost/boost/predef/os/unix.h \
+	boost/boost/predef/os/vms.h \
+	boost/boost/predef/os/windows.h \
+	boost/boost/predef/os.h \
+	boost/boost/predef/other/endian.h \
+	boost/boost/predef/other.h \
+	boost/boost/predef/platform/mingw.h \
+	boost/boost/predef/platform/windows_desktop.h \
+	boost/boost/predef/platform/windows_phone.h \
+	boost/boost/predef/platform/windows_runtime.h \
+	boost/boost/predef/platform/windows_store.h \
+	boost/boost/predef/platform.h \
+	boost/boost/predef/version.h \
+	boost/boost/predef/version_number.h \
+	boost/boost/predef.h \
+	boost/boost/preprocessor/arithmetic/add.hpp \
+	boost/boost/preprocessor/arithmetic/dec.hpp \
+	boost/boost/preprocessor/arithmetic/detail/div_base.hpp \
+	boost/boost/preprocessor/arithmetic/div.hpp \
+	boost/boost/preprocessor/arithmetic/inc.hpp \
+	boost/boost/preprocessor/arithmetic/mod.hpp \
+	boost/boost/preprocessor/arithmetic/mul.hpp \
+	boost/boost/preprocessor/arithmetic/sub.hpp \
+	boost/boost/preprocessor/arithmetic.hpp \
+	boost/boost/preprocessor/array/data.hpp \
+	boost/boost/preprocessor/array/elem.hpp \
+	boost/boost/preprocessor/array/size.hpp \
+	boost/boost/preprocessor/cat.hpp \
+	boost/boost/preprocessor/comma_if.hpp \
+	boost/boost/preprocessor/comparison/less_equal.hpp \
+	boost/boost/preprocessor/config/config.hpp \
+	boost/boost/preprocessor/control/detail/while.hpp \
+	boost/boost/preprocessor/control/expr_if.hpp \
+	boost/boost/preprocessor/control/expr_iif.hpp \
+	boost/boost/preprocessor/control/if.hpp \
+	boost/boost/preprocessor/control/iif.hpp \
+	boost/boost/preprocessor/control/while.hpp \
+	boost/boost/preprocessor/debug/error.hpp \
+	boost/boost/preprocessor/detail/auto_rec.hpp \
+	boost/boost/preprocessor/detail/check.hpp \
+	boost/boost/preprocessor/detail/is_binary.hpp \
+	boost/boost/preprocessor/empty.hpp \
+	boost/boost/preprocessor/enum.hpp \
+	boost/boost/preprocessor/enum_params.hpp \
+	boost/boost/preprocessor/enum_shifted_params.hpp \
+	boost/boost/preprocessor/facilities/empty.hpp \
+	boost/boost/preprocessor/facilities/expand.hpp \
+	boost/boost/preprocessor/facilities/identity.hpp \
+	boost/boost/preprocessor/facilities/intercept.hpp \
+	boost/boost/preprocessor/facilities/overload.hpp \
+	boost/boost/preprocessor/identity.hpp \
+	boost/boost/preprocessor/inc.hpp \
+	boost/boost/preprocessor/iterate.hpp \
+	boost/boost/preprocessor/iteration/detail/bounds/lower1.hpp \
+	boost/boost/preprocessor/iteration/detail/bounds/upper1.hpp \
+	boost/boost/preprocessor/iteration/detail/iter/forward1.hpp \
+	boost/boost/preprocessor/iteration/iterate.hpp \
+	boost/boost/preprocessor/iteration/local.hpp \
+	boost/boost/preprocessor/iteration/self.hpp \
+	boost/boost/preprocessor/iteration.hpp \
+	boost/boost/preprocessor/list/adt.hpp \
+	boost/boost/preprocessor/list/detail/fold_left.hpp \
+	boost/boost/preprocessor/list/detail/fold_right.hpp \
+	boost/boost/preprocessor/list/fold_left.hpp \
+	boost/boost/preprocessor/list/fold_right.hpp \
+	boost/boost/preprocessor/list/reverse.hpp \
+	boost/boost/preprocessor/logical/and.hpp \
+	boost/boost/preprocessor/logical/bitand.hpp \
+	boost/boost/preprocessor/logical/bool.hpp \
+	boost/boost/preprocessor/logical/compl.hpp \
+	boost/boost/preprocessor/logical/not.hpp \
+	boost/boost/preprocessor/punctuation/comma.hpp \
+	boost/boost/preprocessor/punctuation/comma_if.hpp \
+	boost/boost/preprocessor/repeat.hpp \
+	boost/boost/preprocessor/repetition/deduce_r.hpp \
+	boost/boost/preprocessor/repetition/deduce_z.hpp \
+	boost/boost/preprocessor/repetition/detail/for.hpp \
+	boost/boost/preprocessor/repetition/enum.hpp \
+	boost/boost/preprocessor/repetition/enum_binary_params.hpp \
+	boost/boost/preprocessor/repetition/enum_params.hpp \
+	boost/boost/preprocessor/repetition/enum_params_with_a_default.hpp \
+	boost/boost/preprocessor/repetition/enum_params_with_defaults.hpp \
+	boost/boost/preprocessor/repetition/enum_shifted.hpp \
+	boost/boost/preprocessor/repetition/enum_shifted_binary_params.hpp \
+	boost/boost/preprocessor/repetition/enum_shifted_params.hpp \
+	boost/boost/preprocessor/repetition/enum_trailing.hpp \
+	boost/boost/preprocessor/repetition/enum_trailing_binary_params.hpp \
+	boost/boost/preprocessor/repetition/enum_trailing_params.hpp \
+	boost/boost/preprocessor/repetition/for.hpp \
+	boost/boost/preprocessor/repetition/repeat.hpp \
+	boost/boost/preprocessor/repetition/repeat_from_to.hpp \
+	boost/boost/preprocessor/repetition.hpp \
+	boost/boost/preprocessor/slot/detail/def.hpp \
+	boost/boost/preprocessor/slot/detail/shared.hpp \
+	boost/boost/preprocessor/slot/slot.hpp \
+	boost/boost/preprocessor/stringize.hpp \
+	boost/boost/preprocessor/tuple/detail/is_single_return.hpp \
+	boost/boost/preprocessor/tuple/eat.hpp \
+	boost/boost/preprocessor/tuple/elem.hpp \
+	boost/boost/preprocessor/tuple/rem.hpp \
+	boost/boost/preprocessor/variadic/elem.hpp \
+	boost/boost/preprocessor/variadic/size.hpp \
+	boost/boost/ref.hpp \
+	boost/boost/scoped_ptr.hpp \
+	boost/boost/shared_ptr.hpp \
+	boost/boost/signals2/connection.hpp \
+	boost/boost/signals2/detail/auto_buffer.hpp \
+	boost/boost/signals2/detail/foreign_ptr.hpp \
+	boost/boost/signals2/detail/lwm_pthreads.hpp \
+	boost/boost/signals2/detail/null_output_iterator.hpp \
+	boost/boost/signals2/detail/preprocessed_arg_type.hpp \
+	boost/boost/signals2/detail/preprocessed_arg_type_template.hpp \
+	boost/boost/signals2/detail/replace_slot_function.hpp \
+	boost/boost/signals2/detail/result_type_wrapper.hpp \
+	boost/boost/signals2/detail/signal_template.hpp \
+	boost/boost/signals2/detail/signals_common.hpp \
+	boost/boost/signals2/detail/signals_common_macros.hpp \
+	boost/boost/signals2/detail/slot_call_iterator.hpp \
+	boost/boost/signals2/detail/slot_groups.hpp \
+	boost/boost/signals2/detail/slot_template.hpp \
+	boost/boost/signals2/detail/tracked_objects_visitor.hpp \
+	boost/boost/signals2/detail/unique_lock.hpp \
+	boost/boost/signals2/expired_slot.hpp \
+	boost/boost/signals2/mutex.hpp \
+	boost/boost/signals2/optional_last_value.hpp \
+	boost/boost/signals2/preprocessed_signal.hpp \
+	boost/boost/signals2/preprocessed_slot.hpp \
+	boost/boost/signals2/signal.hpp \
+	boost/boost/signals2/signal_base.hpp \
+	boost/boost/signals2/slot.hpp \
+	boost/boost/signals2/slot_base.hpp \
+	boost/boost/signals2/trackable.hpp \
+	boost/boost/smart_ptr/bad_weak_ptr.hpp \
+	boost/boost/smart_ptr/detail/operator_bool.hpp \
+	boost/boost/smart_ptr/detail/shared_count.hpp \
+	boost/boost/smart_ptr/detail/sp_convertible.hpp \
+	boost/boost/smart_ptr/detail/sp_counted_base.hpp \
+	boost/boost/smart_ptr/detail/sp_counted_base_clang.hpp \
+	boost/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp \
+	boost/boost/smart_ptr/detail/sp_counted_impl.hpp \
+	boost/boost/smart_ptr/detail/sp_disable_deprecated.hpp \
+	boost/boost/smart_ptr/detail/sp_has_sync.hpp \
+	boost/boost/smart_ptr/detail/sp_nullptr_t.hpp \
+	boost/boost/smart_ptr/detail/spinlock.hpp \
+	boost/boost/smart_ptr/detail/spinlock_pool.hpp \
+	boost/boost/smart_ptr/detail/spinlock_sync.hpp \
+	boost/boost/smart_ptr/detail/yield_k.hpp \
+	boost/boost/smart_ptr/enable_shared_from_this.hpp \
+	boost/boost/smart_ptr/scoped_ptr.hpp \
+	boost/boost/smart_ptr/shared_ptr.hpp \
+	boost/boost/smart_ptr/weak_ptr.hpp \
+	boost/boost/static_assert.hpp \
+	boost/boost/swap.hpp \
+	boost/boost/throw_exception.hpp \
+	boost/boost/type.hpp \
+	boost/boost/type_index/ctti_type_index.hpp \
+	boost/boost/type_index/detail/compile_time_type_info.hpp \
+	boost/boost/type_index/detail/ctti_register_class.hpp \
+	boost/boost/type_index/stl_type_index.hpp \
+	boost/boost/type_index/type_index_facade.hpp \
+	boost/boost/type_index.hpp \
+	boost/boost/type_traits/add_const.hpp \
+	boost/boost/type_traits/add_lvalue_reference.hpp \
+	boost/boost/type_traits/add_pointer.hpp \
+	boost/boost/type_traits/add_reference.hpp \
+	boost/boost/type_traits/add_rvalue_reference.hpp \
+	boost/boost/type_traits/add_volatile.hpp \
+	boost/boost/type_traits/aligned_storage.hpp \
+	boost/boost/type_traits/alignment_of.hpp \
+	boost/boost/type_traits/composite_traits.hpp \
+	boost/boost/type_traits/conditional.hpp \
+	boost/boost/type_traits/decay.hpp \
+	boost/boost/type_traits/declval.hpp \
+	boost/boost/type_traits/detail/config.hpp \
+	boost/boost/type_traits/detail/has_binary_operator.hpp \
+	boost/boost/type_traits/detail/is_function_ptr_helper.hpp \
+	boost/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp \
+	boost/boost/type_traits/detail/yes_no_type.hpp \
+	boost/boost/type_traits/function_traits.hpp \
+	boost/boost/type_traits/has_minus.hpp \
+	boost/boost/type_traits/has_minus_assign.hpp \
+	boost/boost/type_traits/has_nothrow_assign.hpp \
+	boost/boost/type_traits/has_nothrow_constructor.hpp \
+	boost/boost/type_traits/has_nothrow_copy.hpp \
+	boost/boost/type_traits/has_plus.hpp \
+	boost/boost/type_traits/has_plus_assign.hpp \
+	boost/boost/type_traits/has_trivial_assign.hpp \
+	boost/boost/type_traits/has_trivial_constructor.hpp \
+	boost/boost/type_traits/has_trivial_copy.hpp \
+	boost/boost/type_traits/has_trivial_destructor.hpp \
+	boost/boost/type_traits/has_trivial_move_assign.hpp \
+	boost/boost/type_traits/has_trivial_move_constructor.hpp \
+	boost/boost/type_traits/integral_constant.hpp \
+	boost/boost/type_traits/integral_promotion.hpp \
+	boost/boost/type_traits/intrinsics.hpp \
+	boost/boost/type_traits/is_abstract.hpp \
+	boost/boost/type_traits/is_arithmetic.hpp \
+	boost/boost/type_traits/is_array.hpp \
+	boost/boost/type_traits/is_assignable.hpp \
+	boost/boost/type_traits/is_base_and_derived.hpp \
+	boost/boost/type_traits/is_base_of.hpp \
+	boost/boost/type_traits/is_class.hpp \
+	boost/boost/type_traits/is_const.hpp \
+	boost/boost/type_traits/is_convertible.hpp \
+	boost/boost/type_traits/is_copy_constructible.hpp \
+	boost/boost/type_traits/is_default_constructible.hpp \
+	boost/boost/type_traits/is_destructible.hpp \
+	boost/boost/type_traits/is_empty.hpp \
+	boost/boost/type_traits/is_enum.hpp \
+	boost/boost/type_traits/is_floating_point.hpp \
+	boost/boost/type_traits/is_function.hpp \
+	boost/boost/type_traits/is_fundamental.hpp \
+	boost/boost/type_traits/is_integral.hpp \
+	boost/boost/type_traits/is_lvalue_reference.hpp \
+	boost/boost/type_traits/is_member_function_pointer.hpp \
+	boost/boost/type_traits/is_member_pointer.hpp \
+	boost/boost/type_traits/is_nothrow_move_assignable.hpp \
+	boost/boost/type_traits/is_nothrow_move_constructible.hpp \
+	boost/boost/type_traits/is_pod.hpp \
+	boost/boost/type_traits/is_pointer.hpp \
+	boost/boost/type_traits/is_reference.hpp \
+	boost/boost/type_traits/is_rvalue_reference.hpp \
+	boost/boost/type_traits/is_same.hpp \
+	boost/boost/type_traits/is_scalar.hpp \
+	boost/boost/type_traits/is_signed.hpp \
+	boost/boost/type_traits/is_stateless.hpp \
+	boost/boost/type_traits/is_union.hpp \
+	boost/boost/type_traits/is_unsigned.hpp \
+	boost/boost/type_traits/is_void.hpp \
+	boost/boost/type_traits/is_volatile.hpp \
+	boost/boost/type_traits/make_signed.hpp \
+	boost/boost/type_traits/remove_bounds.hpp \
+	boost/boost/type_traits/remove_const.hpp \
+	boost/boost/type_traits/remove_cv.hpp \
+	boost/boost/type_traits/remove_extent.hpp \
+	boost/boost/type_traits/remove_pointer.hpp \
+	boost/boost/type_traits/remove_reference.hpp \
+	boost/boost/type_traits/type_with_alignment.hpp \
+	boost/boost/utility/addressof.hpp \
+	boost/boost/utility/compare_pointees.hpp \
+	boost/boost/utility/declval.hpp \
+	boost/boost/utility/enable_if.hpp \
+	boost/boost/utility/swap.hpp \
+	boost/boost/variant/apply_visitor.hpp \
+	boost/boost/variant/detail/apply_visitor_binary.hpp \
+	boost/boost/variant/detail/apply_visitor_delayed.hpp \
+	boost/boost/variant/detail/apply_visitor_unary.hpp \
+	boost/boost/variant/detail/backup_holder.hpp \
+	boost/boost/variant/detail/cast_storage.hpp \
+	boost/boost/variant/detail/config.hpp \
+	boost/boost/variant/detail/enable_recursive_fwd.hpp \
+	boost/boost/variant/detail/forced_return.hpp \
+	boost/boost/variant/detail/generic_result_type.hpp \
+	boost/boost/variant/detail/has_result_type.hpp \
+	boost/boost/variant/detail/hash_variant.hpp \
+	boost/boost/variant/detail/initializer.hpp \
+	boost/boost/variant/detail/make_variant_list.hpp \
+	boost/boost/variant/detail/move.hpp \
+	boost/boost/variant/detail/over_sequence.hpp \
+	boost/boost/variant/detail/substitute_fwd.hpp \
+	boost/boost/variant/detail/variant_io.hpp \
+	boost/boost/variant/detail/visitation_impl.hpp \
+	boost/boost/variant/recursive_wrapper_fwd.hpp \
+	boost/boost/variant/static_visitor.hpp \
+	boost/boost/variant/variant.hpp \
+	boost/boost/variant/variant_fwd.hpp \
+	boost/boost/version.hpp \
+	boost/boost/visit_each.hpp \
+	boost/boost/weak_ptr.hpp \
+	$(NULL)
diff --git a/third_party/assert-macros/LICENSE b/third_party/assert-macros/LICENSE
new file mode 100644
index 0000000..a25d13c
--- /dev/null
+++ b/third_party/assert-macros/LICENSE
@@ -0,0 +1,26 @@
+MIT License
+===========
+
+Copyright (C) 2013 Robert Quattlebaum
+
+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/third_party/assert-macros/README.google b/third_party/assert-macros/README.google
new file mode 100644
index 0000000..c5e47f8
--- /dev/null
+++ b/third_party/assert-macros/README.google
@@ -0,0 +1,12 @@
+URL: https://raw.githubusercontent.com/darconeous/smcp/c3b3d11fbbe0f63aa664320d296694d24ca09b37/src/smcp/assert-macros.h
+Version: c3b3d11fbbe0f63aa664320d296694d24ca09b37
+License: MIT
+License File: LICENSE
+
+Description:
+Introduces an expanded collection of assert macros, including `check()`,
+`require()`, etc.
+
+Local Modifications:
+Minor modifications and improvements. LICENSE file has been created for
+compliance purposes. Not included in original distribution.
diff --git a/third_party/assert-macros/assert-macros.h b/third_party/assert-macros/assert-macros.h
new file mode 100644
index 0000000..f9e838b
--- /dev/null
+++ b/third_party/assert-macros/assert-macros.h
@@ -0,0 +1,164 @@
+/*!	@file assert-macros.h
+**	@author Robert Quattlebaum <darco@deepdarc.com>
+**	@brief "Assert" and "Require" macros
+**
+**  MIT-Licensed Version
+**
+**	Copyright (C) 2013 Robert Quattlebaum
+**
+**	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.
+**
+**	See <http://www.deepdarc.com/> for other cool stuff.
+**
+**	-------------------------------------------------------------------
+**
+**	See <http://www.mactech.com/articles/develop/issue_11/Parent_final.html>
+**	for an explanation about how to use these macros and justification
+**	for using this pattern in general.
+*/
+
+#ifndef __DARC_ASSERT_MACROS__
+#define __DARC_ASSERT_MACROS__
+
+#ifndef assert_error_stream
+#if CONTIKI
+#define assert_error_stream     stdout
+#else
+#define assert_error_stream     stderr
+#endif
+#endif
+
+#if !DEBUG && !defined(NDEBUG)
+#define NDEBUG 1
+#endif
+
+#if ASSERT_MACROS_USE_SYSLOG
+#include <syslog.h>
+#endif
+
+#ifndef ASSERT_MACROS_SQUELCH
+#define ASSERT_MACROS_SQUELCH !DEBUG
+#endif
+
+#ifndef ASSERT_MACROS_SYSLOG_LEVEL
+#define ASSERT_MACROS_SYSLOG_LEVEL LOG_WARNING
+#endif
+
+#ifndef ASSERT_REQUIRE_FAILURE_HOOK
+#define ASSERT_REQUIRE_FAILURE_HOOK       do { } while (false)
+#endif
+
+#if HAVE_ASSERTMACROS_H
+ #include <AssertMacros.h>
+#else
+#include <stdio.h>
+#include <assert.h>
+#if ASSERT_MACROS_SQUELCH
+ #define assert_printf(fmt, ...) do { } while (0)
+ #define check_string(c, s)   do { } while (0)
+ #define check_noerr(c)   do { } while (0)
+ #define require_action_string(c, l, a, s) \
+	do { if (!(c)) { \
+		ASSERT_REQUIRE_FAILURE_HOOK; \
+		a; \
+		goto l; \
+	} } while (0)
+#else
+ #if __AVR__
+  #define assert_printf(fmt, ...) \
+	fprintf_P(assert_error_stream, \
+			  PSTR(__FILE__ ":%d: " fmt "\n"), \
+			  __LINE__, \
+			  __VA_ARGS__)
+ #else
+  #if ASSERT_MACROS_USE_SYSLOG
+   #define assert_printf(fmt, ...) \
+	syslog(ASSERT_MACROS_SYSLOG_LEVEL, \
+		   __FILE__ ":%d: " fmt, \
+		   __LINE__, \
+		   __VA_ARGS__)
+  #elif ASSERT_MACROS_USE_VANILLA_PRINTF
+   #define assert_printf(fmt, ...) \
+	printf(__FILE__ ":%d: " fmt "\n", \
+		   __LINE__, \
+		   __VA_ARGS__)
+  #else
+   #define assert_printf(fmt, ...) \
+	fprintf(assert_error_stream, \
+			__FILE__ ":%d: " fmt "\n", \
+			__LINE__, \
+			__VA_ARGS__)
+  #endif
+ #endif
+ #define check_string(c, s) \
+	do { if (!(c)) { \
+		assert_printf("Check Failed (%s)", s); \
+		ASSERT_REQUIRE_FAILURE_HOOK; \
+	} } while (0)
+ #define check_noerr(c) \
+	do { \
+		int ASSERT_MACROS_c = (int)c; \
+		if (ASSERT_MACROS_c != 0) { \
+		assert_printf("Check Failed (error %d)", ASSERT_MACROS_c); \
+		ASSERT_REQUIRE_FAILURE_HOOK; \
+	} } while (0)
+ #define require_action_string(c, l, a, s) \
+	do { if (!(c)) { \
+		assert_printf("Requirement Failed (%s)", s); \
+		ASSERT_REQUIRE_FAILURE_HOOK; \
+		a; \
+		goto l; \
+	} } while (0)
+#endif
+
+ #define __ASSERT_MACROS_check(c)   check_string(c, # c)
+#if !defined(__cplusplus)
+ #define check(c)   __ASSERT_MACROS_check(c)
+#endif
+ #define require_quiet(c, l)   do { if (!(c)) goto l; } while (0)
+ #define require(c, l)   require_action_string(c, l, {}, # c)
+
+ #define require_noerr(c, l)   require((c) == 0, l)
+ #define require_action(c, l, a)   require_action_string(c, l, a, # c)
+ #define require_noerr_action(c, l, a)   require_action((c) == 0, l, a)
+ #define require_string(c, l, s) \
+	require_action_string(c, l, \
+						  do {} while (0), s)
+#endif
+
+#if OVERRIDE_ASSERT_H
+#undef assert
+#undef __assert
+#define assert(e)  \
+	((void)((e) ? 0 : __assert(#e, __FILE__, __LINE__)))
+#define __assert(e, file, line) \
+	do { \
+		assert_printf("failed assertion `%s'", e) ; \
+		abort(); \
+	} while (0)
+#endif // OVERRIDE_ASSERT_H
+
+// Ignores return value from function 's'
+#define IGNORE_RETURN_VALUE(s)  do { if (s){} } while (0)
+
+#endif // __DARC_ASSERT_MACROS__
diff --git a/third_party/boost/LICENSE b/third_party/boost/LICENSE
new file mode 100644
index 0000000..36b7cd9
--- /dev/null
+++ b/third_party/boost/LICENSE
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN 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/third_party/boost/README.google b/third_party/boost/README.google
new file mode 100644
index 0000000..bdd133d
--- /dev/null
+++ b/third_party/boost/README.google
@@ -0,0 +1,15 @@
+URL: https://sourceforge.net/projects/boost/files/boost/1.60.0/boost_1_60_0.tar.bz2
+Version: 1.60.0
+License: Boost Software License
+License File: LICENSE
+
+Description:
+Boost is a set of libraries for the C++ programming language that
+provide support for tasks and structures such as linear algebra,
+pseudorandom number generation, multithreading, image processing,
+regular expressions, and unit testing. It contains over eighty
+individual libraries. (Not all of which are included here)
+
+Local Modifications:
+Stripped all unused files.
+
diff --git a/third_party/boost/boost/aligned_storage.hpp b/third_party/boost/boost/aligned_storage.hpp
new file mode 100644
index 0000000..f400fa9
--- /dev/null
+++ b/third_party/boost/boost/aligned_storage.hpp
@@ -0,0 +1,18 @@
+//-----------------------------------------------------------------------------
+// boost aligned_storage.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2002-2003
+// Eric Friedman, Itay Maman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_ALIGNED_STORAGE_HPP
+#define BOOST_ALIGNED_STORAGE_HPP
+
+#include <boost/type_traits/aligned_storage.hpp>
+
+#endif // BOOST_ALIGNED_STORAGE_HPP
diff --git a/third_party/boost/boost/any.hpp b/third_party/boost/boost/any.hpp
new file mode 100644
index 0000000..8a15e37
--- /dev/null
+++ b/third_party/boost/boost/any.hpp
@@ -0,0 +1,325 @@
+// See http://www.boost.org/libs/any for Documentation.
+
+#ifndef BOOST_ANY_INCLUDED
+#define BOOST_ANY_INCLUDED
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+// what:  variant type boost::any
+// who:   contributed by Kevlin Henney,
+//        with features contributed and bugs found by
+//        Antony Polukhin, Ed Brey, Mark Rodgers,
+//        Peter Dimov, and James Curran
+// when:  July 2001, April 2013 - May 2013
+
+#include <algorithm>
+
+#include "boost/config.hpp"
+#include <boost/type_index.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/decay.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/mpl/if.hpp>
+
+namespace boost
+{
+    class any
+    {
+    public: // structors
+
+        any() BOOST_NOEXCEPT
+          : content(0)
+        {
+        }
+
+        template<typename ValueType>
+        any(const ValueType & value)
+          : content(new holder<
+                BOOST_DEDUCED_TYPENAME remove_cv<BOOST_DEDUCED_TYPENAME decay<const ValueType>::type>::type
+            >(value))
+        {
+        }
+
+        any(const any & other)
+          : content(other.content ? other.content->clone() : 0)
+        {
+        }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+        // Move constructor
+        any(any&& other) BOOST_NOEXCEPT
+          : content(other.content)
+        {
+            other.content = 0;
+        }
+
+        // Perfect forwarding of ValueType
+        template<typename ValueType>
+        any(ValueType&& value
+            , typename boost::disable_if<boost::is_same<any&, ValueType> >::type* = 0 // disable if value has type `any&`
+            , typename boost::disable_if<boost::is_const<ValueType> >::type* = 0) // disable if value has type `const ValueType&&`
+          : content(new holder< typename decay<ValueType>::type >(static_cast<ValueType&&>(value)))
+        {
+        }
+#endif
+
+        ~any() BOOST_NOEXCEPT
+        {
+            delete content;
+        }
+
+    public: // modifiers
+
+        any & swap(any & rhs) BOOST_NOEXCEPT
+        {
+            std::swap(content, rhs.content);
+            return *this;
+        }
+
+
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+        template<typename ValueType>
+        any & operator=(const ValueType & rhs)
+        {
+            any(rhs).swap(*this);
+            return *this;
+        }
+
+        any & operator=(any rhs)
+        {
+            any(rhs).swap(*this);
+            return *this;
+        }
+
+#else
+        any & operator=(const any& rhs)
+        {
+            any(rhs).swap(*this);
+            return *this;
+        }
+
+        // move assignement
+        any & operator=(any&& rhs) BOOST_NOEXCEPT
+        {
+            rhs.swap(*this);
+            any().swap(rhs);
+            return *this;
+        }
+
+        // Perfect forwarding of ValueType
+        template <class ValueType>
+        any & operator=(ValueType&& rhs)
+        {
+            any(static_cast<ValueType&&>(rhs)).swap(*this);
+            return *this;
+        }
+#endif
+
+    public: // queries
+
+        bool empty() const BOOST_NOEXCEPT
+        {
+            return !content;
+        }
+
+        void clear() BOOST_NOEXCEPT
+        {
+            any().swap(*this);
+        }
+
+        const boost::typeindex::type_info& type() const BOOST_NOEXCEPT
+        {
+            return content ? content->type() : boost::typeindex::type_id<void>().type_info();
+        }
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+    private: // types
+#else
+    public: // types (public so any_cast can be non-friend)
+#endif
+
+        class placeholder
+        {
+        public: // structors
+
+            virtual ~placeholder()
+            {
+            }
+
+        public: // queries
+
+            virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT = 0;
+
+            virtual placeholder * clone() const = 0;
+
+        };
+
+        template<typename ValueType>
+        class holder : public placeholder
+        {
+        public: // structors
+
+            holder(const ValueType & value)
+              : held(value)
+            {
+            }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+            holder(ValueType&& value)
+              : held(static_cast< ValueType&& >(value))
+            {
+            }
+#endif
+        public: // queries
+
+            virtual const boost::typeindex::type_info& type() const BOOST_NOEXCEPT
+            {
+                return boost::typeindex::type_id<ValueType>().type_info();
+            }
+
+            virtual placeholder * clone() const
+            {
+                return new holder(held);
+            }
+
+        public: // representation
+
+            ValueType held;
+
+        private: // intentionally left unimplemented
+            holder & operator=(const holder &);
+        };
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+
+    private: // representation
+
+        template<typename ValueType>
+        friend ValueType * any_cast(any *) BOOST_NOEXCEPT;
+
+        template<typename ValueType>
+        friend ValueType * unsafe_any_cast(any *) BOOST_NOEXCEPT;
+
+#else
+
+    public: // representation (public so any_cast can be non-friend)
+
+#endif
+
+        placeholder * content;
+
+    };
+
+    inline void swap(any & lhs, any & rhs) BOOST_NOEXCEPT
+    {
+        lhs.swap(rhs);
+    }
+
+    class BOOST_SYMBOL_VISIBLE bad_any_cast :
+#ifndef BOOST_NO_RTTI
+        public std::bad_cast
+#else
+        public std::exception
+#endif
+    {
+    public:
+        virtual const char * what() const BOOST_NOEXCEPT_OR_NOTHROW
+        {
+            return "boost::bad_any_cast: "
+                   "failed conversion using boost::any_cast";
+        }
+    };
+
+    template<typename ValueType>
+    ValueType * any_cast(any * operand) BOOST_NOEXCEPT
+    {
+        return operand && operand->type() == boost::typeindex::type_id<ValueType>()
+            ? &static_cast<any::holder<BOOST_DEDUCED_TYPENAME remove_cv<ValueType>::type> *>(operand->content)->held
+            : 0;
+    }
+
+    template<typename ValueType>
+    inline const ValueType * any_cast(const any * operand) BOOST_NOEXCEPT
+    {
+        return any_cast<ValueType>(const_cast<any *>(operand));
+    }
+
+    template<typename ValueType>
+    ValueType any_cast(any & operand)
+    {
+        typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
+
+
+        nonref * result = any_cast<nonref>(&operand);
+        if(!result)
+            boost::throw_exception(bad_any_cast());
+
+        // Attempt to avoid construction of a temporary object in cases when
+        // `ValueType` is not a reference. Example:
+        // `static_cast<std::string>(*result);`
+        // which is equal to `std::string(*result);`
+        typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
+            boost::is_reference<ValueType>,
+            ValueType,
+            BOOST_DEDUCED_TYPENAME boost::add_reference<ValueType>::type
+        >::type ref_type;
+
+        return static_cast<ref_type>(*result);
+    }
+
+    template<typename ValueType>
+    inline ValueType any_cast(const any & operand)
+    {
+        typedef BOOST_DEDUCED_TYPENAME remove_reference<ValueType>::type nonref;
+        return any_cast<const nonref &>(const_cast<any &>(operand));
+    }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    template<typename ValueType>
+    inline ValueType any_cast(any&& operand)
+    {
+        BOOST_STATIC_ASSERT_MSG(
+            boost::is_rvalue_reference<ValueType&&>::value /*true if ValueType is rvalue or just a value*/
+            || boost::is_const< typename boost::remove_reference<ValueType>::type >::value,
+            "boost::any_cast shall not be used for getting nonconst references to temporary objects"
+        );
+        return any_cast<ValueType>(operand);
+    }
+#endif
+
+
+    // Note: The "unsafe" versions of any_cast are not part of the
+    // public interface and may be removed at any time. They are
+    // required where we know what type is stored in the any and can't
+    // use typeid() comparison, e.g., when our types may travel across
+    // different shared libraries.
+    template<typename ValueType>
+    inline ValueType * unsafe_any_cast(any * operand) BOOST_NOEXCEPT
+    {
+        return &static_cast<any::holder<ValueType> *>(operand->content)->held;
+    }
+
+    template<typename ValueType>
+    inline const ValueType * unsafe_any_cast(const any * operand) BOOST_NOEXCEPT
+    {
+        return unsafe_any_cast<ValueType>(const_cast<any *>(operand));
+    }
+}
+
+// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#endif
diff --git a/third_party/boost/boost/assert.hpp b/third_party/boost/boost/assert.hpp
new file mode 100644
index 0000000..9650d7a
--- /dev/null
+++ b/third_party/boost/boost/assert.hpp
@@ -0,0 +1,85 @@
+//
+//  boost/assert.hpp - BOOST_ASSERT(expr)
+//                     BOOST_ASSERT_MSG(expr, msg)
+//                     BOOST_VERIFY(expr)
+//                     BOOST_VERIFY_MSG(expr, msg)
+//                     BOOST_ASSERT_IS_VOID
+//
+//  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
+//  Copyright (c) 2007, 2014 Peter Dimov
+//  Copyright (c) Beman Dawes 2011
+//  Copyright (c) 2015 Ion Gaztanaga
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+//
+//  Note: There are no include guards. This is intentional.
+//
+//  See http://www.boost.org/libs/assert/assert.html for documentation.
+//
+
+//
+// Stop inspect complaining about use of 'assert':
+//
+// boostinspect:naassert_macro
+//
+
+//
+// BOOST_ASSERT, BOOST_ASSERT_MSG, BOOST_ASSERT_IS_VOID
+//
+
+#undef BOOST_ASSERT
+#undef BOOST_ASSERT_MSG
+#undef BOOST_ASSERT_IS_VOID
+
+#if defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) )
+
+# define BOOST_ASSERT(expr) ((void)0)
+# define BOOST_ASSERT_MSG(expr, msg) ((void)0)
+# define BOOST_ASSERT_IS_VOID
+
+#elif defined(BOOST_ENABLE_ASSERT_HANDLER) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && !defined(NDEBUG) )
+
+#include <boost/config.hpp> // for BOOST_LIKELY
+#include <boost/current_function.hpp>
+
+namespace boost
+{
+    void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined
+    void assertion_failed_msg(char const * expr, char const * msg, char const * function, char const * file, long line); // user defined
+} // namespace boost
+
+#define BOOST_ASSERT(expr) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
+#define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
+
+#else
+
+# include <assert.h> // .h to support old libraries w/o <cassert> - effect is the same
+
+# define BOOST_ASSERT(expr) assert(expr)
+# define BOOST_ASSERT_MSG(expr, msg) assert((expr)&&(msg))
+#if defined(NDEBUG)
+# define BOOST_ASSERT_IS_VOID
+#endif
+
+#endif
+
+//
+// BOOST_VERIFY, BOOST_VERIFY_MSG
+//
+
+#undef BOOST_VERIFY
+#undef BOOST_VERIFY_MSG
+
+#if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) )
+
+# define BOOST_VERIFY(expr) ((void)(expr))
+# define BOOST_VERIFY_MSG(expr, msg) ((void)(expr))
+
+#else
+
+# define BOOST_VERIFY(expr) BOOST_ASSERT(expr)
+# define BOOST_VERIFY_MSG(expr, msg) BOOST_ASSERT_MSG(expr,msg)
+
+#endif
diff --git a/third_party/boost/boost/bind.hpp b/third_party/boost/boost/bind.hpp
new file mode 100644
index 0000000..450120c
--- /dev/null
+++ b/third_party/boost/boost/bind.hpp
@@ -0,0 +1,41 @@
+#ifndef BOOST_BIND_HPP_INCLUDED
+#define BOOST_BIND_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  bind.hpp - binds function objects to arguments
+//
+//  Copyright (c) 2009, 2015 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+//
+//  See http://www.boost.org/libs/bind/bind.html for documentation.
+//
+
+#include <boost/bind/bind.hpp>
+
+#ifndef BOOST_BIND_NO_PLACEHOLDERS
+
+#if defined(BOOST_CLANG)
+# pragma clang diagnostic push
+# if  __has_warning("-Wheader-hygiene")
+#  pragma clang diagnostic ignored "-Wheader-hygiene"
+# endif
+#endif
+
+using namespace boost::placeholders;
+
+#if defined(BOOST_CLANG)
+# pragma clang diagnostic pop
+#endif
+
+#endif // #ifndef BOOST_BIND_NO_PLACEHOLDERS
+
+#endif // #ifndef BOOST_BIND_HPP_INCLUDED
diff --git a/third_party/boost/boost/bind/arg.hpp b/third_party/boost/boost/bind/arg.hpp
new file mode 100644
index 0000000..a74b829
--- /dev/null
+++ b/third_party/boost/boost/bind/arg.hpp
@@ -0,0 +1,62 @@
+#ifndef BOOST_BIND_ARG_HPP_INCLUDED
+#define BOOST_BIND_ARG_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  bind/arg.hpp
+//
+//  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//  See http://www.boost.org/libs/bind/bind.html for documentation.
+//
+
+#include <boost/config.hpp>
+#include <boost/is_placeholder.hpp>
+#include <boost/static_assert.hpp>
+
+namespace boost
+{
+
+template< int I > struct arg
+{
+    BOOST_CONSTEXPR arg()
+    {
+    }
+
+    template< class T > BOOST_CONSTEXPR arg( T const & /* t */ )
+    {
+        BOOST_STATIC_ASSERT( I == is_placeholder<T>::value );
+    }
+};
+
+template< int I > BOOST_CONSTEXPR bool operator==( arg<I> const &, arg<I> const & )
+{
+    return true;
+}
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template< int I > struct is_placeholder< arg<I> >
+{
+    enum _vt { value = I };
+};
+
+template< int I > struct is_placeholder< arg<I> (*) () >
+{
+    enum _vt { value = I };
+};
+
+#endif
+
+} // namespace boost
+
+#endif // #ifndef BOOST_BIND_ARG_HPP_INCLUDED
diff --git a/third_party/boost/boost/bind/bind.hpp b/third_party/boost/boost/bind/bind.hpp
new file mode 100644
index 0000000..5a70fcb
--- /dev/null
+++ b/third_party/boost/boost/bind/bind.hpp
@@ -0,0 +1,2256 @@
+#ifndef BOOST_BIND_BIND_HPP_INCLUDED
+#define BOOST_BIND_BIND_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  bind.hpp - binds function objects to arguments
+//
+//  Copyright (c) 2001-2004 Peter Dimov and Multi Media Ltd.
+//  Copyright (c) 2001 David Abrahams
+//  Copyright (c) 2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//  See http://www.boost.org/libs/bind/bind.html for documentation.
+//
+
+#include <boost/config.hpp>
+#include <boost/ref.hpp>
+#include <boost/mem_fn.hpp>
+#include <boost/type.hpp>
+#include <boost/is_placeholder.hpp>
+#include <boost/bind/arg.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/visit_each.hpp>
+#include <boost/core/enable_if.hpp>
+#include <boost/core/is_same.hpp>
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+#include <utility> // std::forward
+#endif
+
+// Borland-specific bug, visit_each() silently fails to produce code
+
+#if defined(__BORLANDC__)
+#  define BOOST_BIND_VISIT_EACH boost::visit_each
+#else
+#  define BOOST_BIND_VISIT_EACH visit_each
+#endif
+
+#include <boost/bind/storage.hpp>
+
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable: 4512) // assignment operator could not be generated
+#endif
+
+namespace boost
+{
+
+template<class T> class weak_ptr;
+
+namespace _bi // implementation details
+{
+
+// result_traits
+
+template<class R, class F> struct result_traits
+{
+    typedef R type;
+};
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+
+struct unspecified {};
+
+template<class F> struct result_traits<unspecified, F>
+{
+    typedef typename F::result_type type;
+};
+
+template<class F> struct result_traits< unspecified, reference_wrapper<F> >
+{
+    typedef typename F::result_type type;
+};
+
+#endif
+
+// ref_compare
+
+template<class T> bool ref_compare( T const & a, T const & b, long )
+{
+    return a == b;
+}
+
+template<int I> bool ref_compare( arg<I> const &, arg<I> const &, int )
+{
+    return true;
+}
+
+template<int I> bool ref_compare( arg<I> (*) (), arg<I> (*) (), int )
+{
+    return true;
+}
+
+template<class T> bool ref_compare( reference_wrapper<T> const & a, reference_wrapper<T> const & b, int )
+{
+    return a.get_pointer() == b.get_pointer();
+}
+
+// bind_t forward declaration for listN
+
+template<class R, class F, class L> class bind_t;
+
+template<class R, class F, class L> bool ref_compare( bind_t<R, F, L> const & a, bind_t<R, F, L> const & b, int )
+{
+    return a.compare( b );
+}
+
+// value
+
+template<class T> class value
+{
+public:
+
+    value(T const & t): t_(t) {}
+
+    T & get() { return t_; }
+    T const & get() const { return t_; }
+
+    bool operator==(value const & rhs) const
+    {
+        return t_ == rhs.t_;
+    }
+
+private:
+
+    T t_;
+};
+
+// ref_compare for weak_ptr
+
+template<class T> bool ref_compare( value< weak_ptr<T> > const & a, value< weak_ptr<T> > const & b, int )
+{
+    return !(a.get() < b.get()) && !(b.get() < a.get());
+}
+
+// type
+
+template<class T> class type {};
+
+// unwrap
+
+template<class F> struct unwrapper
+{
+    static inline F & unwrap( F & f, long )
+    {
+        return f;
+    }
+
+    template<class F2> static inline F2 & unwrap( reference_wrapper<F2> rf, int )
+    {
+        return rf.get();
+    }
+
+    template<class R, class T> static inline _mfi::dm<R, T> unwrap( R T::* pm, int )
+    {
+        return _mfi::dm<R, T>( pm );
+    }
+};
+
+// listN
+
+class list0
+{
+public:
+
+    list0() {}
+
+    template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); }
+
+    template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+
+    template<class R, class F, class A> R operator()(type<R>, F & f, A &, long)
+    {
+        return unwrapper<F>::unwrap(f, 0)();
+    }
+
+    template<class R, class F, class A> R operator()(type<R>, F const & f, A &, long) const
+    {
+        return unwrapper<F const>::unwrap(f, 0)();
+    }
+
+    template<class F, class A> void operator()(type<void>, F & f, A &, int)
+    {
+        unwrapper<F>::unwrap(f, 0)();
+    }
+
+    template<class F, class A> void operator()(type<void>, F const & f, A &, int) const
+    {
+        unwrapper<F const>::unwrap(f, 0)();
+    }
+
+    template<class V> void accept(V &) const
+    {
+    }
+
+    bool operator==(list0 const &) const
+    {
+        return true;
+    }
+};
+
+#ifdef BOOST_MSVC
+// MSVC is bright enough to realise that the parameter rhs
+// in operator==may be unused for some template argument types:
+#pragma warning(push)
+#pragma warning(disable:4100)
+#endif
+
+template< class A1 > class list1: private storage1< A1 >
+{
+private:
+
+    typedef storage1< A1 > base_type;
+
+public:
+
+    explicit list1( A1 a1 ): base_type( a1 ) {}
+
+    A1 operator[] (boost::arg<1>) const { return base_type::a1_; }
+
+    A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; }
+
+    template<class T> T & operator[] ( _bi::value<T> & v ) const { return v.get(); }
+
+    template<class T> T const & operator[] ( _bi::value<T> const & v ) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+
+    template<class R, class F, class A> R operator()(type<R>, F & f, A & a, long)
+    {
+        return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_]);
+    }
+
+    template<class R, class F, class A> R operator()(type<R>, F const & f, A & a, long) const
+    {
+        return unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F & f, A & a, int)
+    {
+        unwrapper<F>::unwrap(f, 0)(a[base_type::a1_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F const & f, A & a, int) const
+    {
+        unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_]);
+    }
+
+    template<class V> void accept(V & v) const
+    {
+        base_type::accept(v);
+    }
+
+    bool operator==(list1 const & rhs) const
+    {
+        return ref_compare(base_type::a1_, rhs.a1_, 0);
+    }
+};
+
+struct logical_and;
+struct logical_or;
+
+template< class A1, class A2 > class list2: private storage2< A1, A2 >
+{
+private:
+
+    typedef storage2< A1, A2 > base_type;
+
+public:
+
+    list2( A1 a1, A2 a2 ): base_type( a1, a2 ) {}
+
+    A1 operator[] (boost::arg<1>) const { return base_type::a1_; }
+    A2 operator[] (boost::arg<2>) const { return base_type::a2_; }
+
+    A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; }
+    A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; }
+
+    template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); }
+
+    template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+
+    template<class R, class F, class A> R operator()(type<R>, F & f, A & a, long)
+    {
+        return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);
+    }
+
+    template<class R, class F, class A> R operator()(type<R>, F const & f, A & a, long) const
+    {
+        return unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F & f, A & a, int)
+    {
+        unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F const & f, A & a, int) const
+    {
+        unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);
+    }
+
+    template<class A> bool operator()( type<bool>, logical_and & /*f*/, A & a, int )
+    {
+        return a[ base_type::a1_ ] && a[ base_type::a2_ ];
+    }
+
+    template<class A> bool operator()( type<bool>, logical_and const & /*f*/, A & a, int ) const
+    {
+        return a[ base_type::a1_ ] && a[ base_type::a2_ ];
+    }
+
+    template<class A> bool operator()( type<bool>, logical_or & /*f*/, A & a, int )
+    {
+        return a[ base_type::a1_ ] || a[ base_type::a2_ ];
+    }
+
+    template<class A> bool operator()( type<bool>, logical_or const & /*f*/, A & a, int ) const
+    {
+        return a[ base_type::a1_ ] || a[ base_type::a2_ ];
+    }
+
+    template<class V> void accept(V & v) const
+    {
+        base_type::accept(v);
+    }
+
+    bool operator==(list2 const & rhs) const
+    {
+        return ref_compare(base_type::a1_, rhs.a1_, 0) && ref_compare(base_type::a2_, rhs.a2_, 0);
+    }
+};
+
+template< class A1, class A2, class A3 > class list3: private storage3< A1, A2, A3 >
+{
+private:
+
+    typedef storage3< A1, A2, A3 > base_type;
+
+public:
+
+    list3( A1 a1, A2 a2, A3 a3 ): base_type( a1, a2, a3 ) {}
+
+    A1 operator[] (boost::arg<1>) const { return base_type::a1_; }
+    A2 operator[] (boost::arg<2>) const { return base_type::a2_; }
+    A3 operator[] (boost::arg<3>) const { return base_type::a3_; }
+
+    A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; }
+    A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; }
+    A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; }
+
+    template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); }
+
+    template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+
+    template<class R, class F, class A> R operator()(type<R>, F & f, A & a, long)
+    {
+        return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]);
+    }
+
+    template<class R, class F, class A> R operator()(type<R>, F const & f, A & a, long) const
+    {
+        return unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F & f, A & a, int)
+    {
+        unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F const & f, A & a, int) const
+    {
+        unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]);
+    }
+
+    template<class V> void accept(V & v) const
+    {
+        base_type::accept(v);
+    }
+
+    bool operator==(list3 const & rhs) const
+    {
+        return
+
+            ref_compare( base_type::a1_, rhs.a1_, 0 ) &&
+            ref_compare( base_type::a2_, rhs.a2_, 0 ) &&
+            ref_compare( base_type::a3_, rhs.a3_, 0 );
+    }
+};
+
+template< class A1, class A2, class A3, class A4 > class list4: private storage4< A1, A2, A3, A4 >
+{
+private:
+
+    typedef storage4< A1, A2, A3, A4 > base_type;
+
+public:
+
+    list4( A1 a1, A2 a2, A3 a3, A4 a4 ): base_type( a1, a2, a3, a4 ) {}
+
+    A1 operator[] (boost::arg<1>) const { return base_type::a1_; }
+    A2 operator[] (boost::arg<2>) const { return base_type::a2_; }
+    A3 operator[] (boost::arg<3>) const { return base_type::a3_; }
+    A4 operator[] (boost::arg<4>) const { return base_type::a4_; }
+
+    A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; }
+    A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; }
+    A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; }
+    A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; }
+
+    template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); }
+
+    template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+
+    template<class R, class F, class A> R operator()(type<R>, F & f, A & a, long)
+    {
+        return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]);
+    }
+
+    template<class R, class F, class A> R operator()(type<R>, F const & f, A & a, long) const
+    {
+        return unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F & f, A & a, int)
+    {
+        unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F const & f, A & a, int) const
+    {
+        unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]);
+    }
+
+    template<class V> void accept(V & v) const
+    {
+        base_type::accept(v);
+    }
+
+    bool operator==(list4 const & rhs) const
+    {
+        return
+
+            ref_compare( base_type::a1_, rhs.a1_, 0 ) &&
+            ref_compare( base_type::a2_, rhs.a2_, 0 ) &&
+            ref_compare( base_type::a3_, rhs.a3_, 0 ) &&
+            ref_compare( base_type::a4_, rhs.a4_, 0 );
+    }
+};
+
+template< class A1, class A2, class A3, class A4, class A5 > class list5: private storage5< A1, A2, A3, A4, A5 >
+{
+private:
+
+    typedef storage5< A1, A2, A3, A4, A5 > base_type;
+
+public:
+
+    list5( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 ): base_type( a1, a2, a3, a4, a5 ) {}
+
+    A1 operator[] (boost::arg<1>) const { return base_type::a1_; }
+    A2 operator[] (boost::arg<2>) const { return base_type::a2_; }
+    A3 operator[] (boost::arg<3>) const { return base_type::a3_; }
+    A4 operator[] (boost::arg<4>) const { return base_type::a4_; }
+    A5 operator[] (boost::arg<5>) const { return base_type::a5_; }
+
+    A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; }
+    A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; }
+    A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; }
+    A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; }
+    A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; }
+
+    template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); }
+
+    template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+
+    template<class R, class F, class A> R operator()(type<R>, F & f, A & a, long)
+    {
+        return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_]);
+    }
+
+    template<class R, class F, class A> R operator()(type<R>, F const & f, A & a, long) const
+    {
+        return unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F & f, A & a, int)
+    {
+        unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F const & f, A & a, int) const
+    {
+        unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_]);
+    }
+
+    template<class V> void accept(V & v) const
+    {
+        base_type::accept(v);
+    }
+
+    bool operator==(list5 const & rhs) const
+    {
+        return
+
+            ref_compare( base_type::a1_, rhs.a1_, 0 ) &&
+            ref_compare( base_type::a2_, rhs.a2_, 0 ) &&
+            ref_compare( base_type::a3_, rhs.a3_, 0 ) &&
+            ref_compare( base_type::a4_, rhs.a4_, 0 ) &&
+            ref_compare( base_type::a5_, rhs.a5_, 0 );
+    }
+};
+
+template<class A1, class A2, class A3, class A4, class A5, class A6> class list6: private storage6< A1, A2, A3, A4, A5, A6 >
+{
+private:
+
+    typedef storage6< A1, A2, A3, A4, A5, A6 > base_type;
+
+public:
+
+    list6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6 ): base_type( a1, a2, a3, a4, a5, a6 ) {}
+
+    A1 operator[] (boost::arg<1>) const { return base_type::a1_; }
+    A2 operator[] (boost::arg<2>) const { return base_type::a2_; }
+    A3 operator[] (boost::arg<3>) const { return base_type::a3_; }
+    A4 operator[] (boost::arg<4>) const { return base_type::a4_; }
+    A5 operator[] (boost::arg<5>) const { return base_type::a5_; }
+    A6 operator[] (boost::arg<6>) const { return base_type::a6_; }
+
+    A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; }
+    A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; }
+    A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; }
+    A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; }
+    A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; }
+    A6 operator[] (boost::arg<6> (*) ()) const { return base_type::a6_; }
+
+    template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); }
+
+    template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+
+    template<class R, class F, class A> R operator()(type<R>, F & f, A & a, long)
+    {
+        return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_]);
+    }
+
+    template<class R, class F, class A> R operator()(type<R>, F const & f, A & a, long) const
+    {
+        return unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F & f, A & a, int)
+    {
+        unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F const & f, A & a, int) const
+    {
+        unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_]);
+    }
+
+    template<class V> void accept(V & v) const
+    {
+        base_type::accept(v);
+    }
+
+    bool operator==(list6 const & rhs) const
+    {
+        return
+
+            ref_compare( base_type::a1_, rhs.a1_, 0 ) &&
+            ref_compare( base_type::a2_, rhs.a2_, 0 ) &&
+            ref_compare( base_type::a3_, rhs.a3_, 0 ) &&
+            ref_compare( base_type::a4_, rhs.a4_, 0 ) &&
+            ref_compare( base_type::a5_, rhs.a5_, 0 ) &&
+            ref_compare( base_type::a6_, rhs.a6_, 0 );
+    }
+};
+
+template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> class list7: private storage7< A1, A2, A3, A4, A5, A6, A7 >
+{
+private:
+
+    typedef storage7< A1, A2, A3, A4, A5, A6, A7 > base_type;
+
+public:
+
+    list7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7 ): base_type( a1, a2, a3, a4, a5, a6, a7 ) {}
+
+    A1 operator[] (boost::arg<1>) const { return base_type::a1_; }
+    A2 operator[] (boost::arg<2>) const { return base_type::a2_; }
+    A3 operator[] (boost::arg<3>) const { return base_type::a3_; }
+    A4 operator[] (boost::arg<4>) const { return base_type::a4_; }
+    A5 operator[] (boost::arg<5>) const { return base_type::a5_; }
+    A6 operator[] (boost::arg<6>) const { return base_type::a6_; }
+    A7 operator[] (boost::arg<7>) const { return base_type::a7_; }
+
+    A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; }
+    A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; }
+    A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; }
+    A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; }
+    A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; }
+    A6 operator[] (boost::arg<6> (*) ()) const { return base_type::a6_; }
+    A7 operator[] (boost::arg<7> (*) ()) const { return base_type::a7_; }
+
+    template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); }
+
+    template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+
+    template<class R, class F, class A> R operator()(type<R>, F & f, A & a, long)
+    {
+        return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_]);
+    }
+
+    template<class R, class F, class A> R operator()(type<R>, F const & f, A & a, long) const
+    {
+        return unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F & f, A & a, int)
+    {
+        unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F const & f, A & a, int) const
+    {
+        unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_]);
+    }
+
+    template<class V> void accept(V & v) const
+    {
+        base_type::accept(v);
+    }
+
+    bool operator==(list7 const & rhs) const
+    {
+        return
+
+            ref_compare( base_type::a1_, rhs.a1_, 0 ) &&
+            ref_compare( base_type::a2_, rhs.a2_, 0 ) &&
+            ref_compare( base_type::a3_, rhs.a3_, 0 ) &&
+            ref_compare( base_type::a4_, rhs.a4_, 0 ) &&
+            ref_compare( base_type::a5_, rhs.a5_, 0 ) &&
+            ref_compare( base_type::a6_, rhs.a6_, 0 ) &&
+            ref_compare( base_type::a7_, rhs.a7_, 0 );
+    }
+};
+
+template< class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > class list8: private storage8< A1, A2, A3, A4, A5, A6, A7, A8 >
+{
+private:
+
+    typedef storage8< A1, A2, A3, A4, A5, A6, A7, A8 > base_type;
+
+public:
+
+    list8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8 ): base_type( a1, a2, a3, a4, a5, a6, a7, a8 ) {}
+
+    A1 operator[] (boost::arg<1>) const { return base_type::a1_; }
+    A2 operator[] (boost::arg<2>) const { return base_type::a2_; }
+    A3 operator[] (boost::arg<3>) const { return base_type::a3_; }
+    A4 operator[] (boost::arg<4>) const { return base_type::a4_; }
+    A5 operator[] (boost::arg<5>) const { return base_type::a5_; }
+    A6 operator[] (boost::arg<6>) const { return base_type::a6_; }
+    A7 operator[] (boost::arg<7>) const { return base_type::a7_; }
+    A8 operator[] (boost::arg<8>) const { return base_type::a8_; }
+
+    A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; }
+    A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; }
+    A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; }
+    A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; }
+    A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; }
+    A6 operator[] (boost::arg<6> (*) ()) const { return base_type::a6_; }
+    A7 operator[] (boost::arg<7> (*) ()) const { return base_type::a7_; }
+    A8 operator[] (boost::arg<8> (*) ()) const { return base_type::a8_; }
+
+    template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); }
+
+    template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+
+    template<class R, class F, class A> R operator()(type<R>, F & f, A & a, long)
+    {
+        return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_]);
+    }
+
+    template<class R, class F, class A> R operator()(type<R>, F const & f, A & a, long) const
+    {
+        return unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F & f, A & a, int)
+    {
+        unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F const & f, A & a, int) const
+    {
+        unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_]);
+    }
+
+    template<class V> void accept(V & v) const
+    {
+        base_type::accept(v);
+    }
+
+    bool operator==(list8 const & rhs) const
+    {
+        return
+
+            ref_compare( base_type::a1_, rhs.a1_, 0 ) &&
+            ref_compare( base_type::a2_, rhs.a2_, 0 ) &&
+            ref_compare( base_type::a3_, rhs.a3_, 0 ) &&
+            ref_compare( base_type::a4_, rhs.a4_, 0 ) &&
+            ref_compare( base_type::a5_, rhs.a5_, 0 ) &&
+            ref_compare( base_type::a6_, rhs.a6_, 0 ) &&
+            ref_compare( base_type::a7_, rhs.a7_, 0 ) &&
+            ref_compare( base_type::a8_, rhs.a8_, 0 );
+    }
+};
+
+template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> class list9: private storage9< A1, A2, A3, A4, A5, A6, A7, A8, A9 >
+{
+private:
+
+    typedef storage9< A1, A2, A3, A4, A5, A6, A7, A8, A9 > base_type;
+
+public:
+
+    list9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9 ): base_type( a1, a2, a3, a4, a5, a6, a7, a8, a9 ) {}
+
+    A1 operator[] (boost::arg<1>) const { return base_type::a1_; }
+    A2 operator[] (boost::arg<2>) const { return base_type::a2_; }
+    A3 operator[] (boost::arg<3>) const { return base_type::a3_; }
+    A4 operator[] (boost::arg<4>) const { return base_type::a4_; }
+    A5 operator[] (boost::arg<5>) const { return base_type::a5_; }
+    A6 operator[] (boost::arg<6>) const { return base_type::a6_; }
+    A7 operator[] (boost::arg<7>) const { return base_type::a7_; }
+    A8 operator[] (boost::arg<8>) const { return base_type::a8_; }
+    A9 operator[] (boost::arg<9>) const { return base_type::a9_; }
+
+    A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; }
+    A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; }
+    A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; }
+    A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; }
+    A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; }
+    A6 operator[] (boost::arg<6> (*) ()) const { return base_type::a6_; }
+    A7 operator[] (boost::arg<7> (*) ()) const { return base_type::a7_; }
+    A8 operator[] (boost::arg<8> (*) ()) const { return base_type::a8_; }
+    A9 operator[] (boost::arg<9> (*) ()) const { return base_type::a9_; }
+
+    template<class T> T & operator[] (_bi::value<T> & v) const { return v.get(); }
+
+    template<class T> T const & operator[] (_bi::value<T> const & v) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+
+    template<class R, class F, class A> R operator()(type<R>, F & f, A & a, long)
+    {
+        return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_], a[base_type::a9_]);
+    }
+
+    template<class R, class F, class A> R operator()(type<R>, F const & f, A & a, long) const
+    {
+        return unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_], a[base_type::a9_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F & f, A & a, int)
+    {
+        unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_], a[base_type::a9_]);
+    }
+
+    template<class F, class A> void operator()(type<void>, F const & f, A & a, int) const
+    {
+        unwrapper<F const>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_], a[base_type::a9_]);
+    }
+
+    template<class V> void accept(V & v) const
+    {
+        base_type::accept(v);
+    }
+
+    bool operator==(list9 const & rhs) const
+    {
+        return
+
+            ref_compare( base_type::a1_, rhs.a1_, 0 ) &&
+            ref_compare( base_type::a2_, rhs.a2_, 0 ) &&
+            ref_compare( base_type::a3_, rhs.a3_, 0 ) &&
+            ref_compare( base_type::a4_, rhs.a4_, 0 ) &&
+            ref_compare( base_type::a5_, rhs.a5_, 0 ) &&
+            ref_compare( base_type::a6_, rhs.a6_, 0 ) &&
+            ref_compare( base_type::a7_, rhs.a7_, 0 ) &&
+            ref_compare( base_type::a8_, rhs.a8_, 0 ) &&
+            ref_compare( base_type::a9_, rhs.a9_, 0 );
+    }
+};
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+// bind_t
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+template< class A1 > class rrlist1
+{
+private:
+
+    A1 & a1_; // not A1&& because of msvc-10.0
+
+public:
+
+    explicit rrlist1( A1 & a1 ): a1_( a1 ) {}
+
+    A1 && operator[] (boost::arg<1>) const { return std::forward<A1>( a1_ ); } // not static_cast because of g++ 4.9
+
+    A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward<A1>( a1_ ); }
+
+    template<class T> T & operator[] ( _bi::value<T> & v ) const { return v.get(); }
+
+    template<class T> T const & operator[] ( _bi::value<T> const & v ) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+};
+
+template< class A1, class A2 > class rrlist2
+{
+private:
+
+    A1 & a1_;
+    A2 & a2_;
+
+public:
+
+    rrlist2( A1 & a1, A2 & a2 ): a1_( a1 ), a2_( a2 ) {}
+
+    A1 && operator[] (boost::arg<1>) const { return std::forward<A1>( a1_ ); }
+    A2 && operator[] (boost::arg<2>) const { return std::forward<A2>( a2_ ); }
+
+    A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward<A1>( a1_ ); }
+    A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward<A2>( a2_ ); }
+
+    template<class T> T & operator[] ( _bi::value<T> & v ) const { return v.get(); }
+
+    template<class T> T const & operator[] ( _bi::value<T> const & v ) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+};
+
+template< class A1, class A2, class A3 > class rrlist3
+{
+private:
+
+    A1 & a1_;
+    A2 & a2_;
+    A3 & a3_;
+
+public:
+
+    rrlist3( A1 & a1, A2 & a2, A3 & a3 ): a1_( a1 ), a2_( a2 ), a3_( a3 ) {}
+
+    A1 && operator[] (boost::arg<1>) const { return std::forward<A1>( a1_ ); }
+    A2 && operator[] (boost::arg<2>) const { return std::forward<A2>( a2_ ); }
+    A3 && operator[] (boost::arg<3>) const { return std::forward<A3>( a3_ ); }
+
+    A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward<A1>( a1_ ); }
+    A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward<A2>( a2_ ); }
+    A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward<A3>( a3_ ); }
+
+    template<class T> T & operator[] ( _bi::value<T> & v ) const { return v.get(); }
+
+    template<class T> T const & operator[] ( _bi::value<T> const & v ) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+};
+
+template< class A1, class A2, class A3, class A4 > class rrlist4
+{
+private:
+
+    A1 & a1_;
+    A2 & a2_;
+    A3 & a3_;
+    A4 & a4_;
+
+public:
+
+    rrlist4( A1 & a1, A2 & a2, A3 & a3, A4 & a4 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ) {}
+
+    A1 && operator[] (boost::arg<1>) const { return std::forward<A1>( a1_ ); }
+    A2 && operator[] (boost::arg<2>) const { return std::forward<A2>( a2_ ); }
+    A3 && operator[] (boost::arg<3>) const { return std::forward<A3>( a3_ ); }
+    A4 && operator[] (boost::arg<4>) const { return std::forward<A4>( a4_ ); }
+
+    A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward<A1>( a1_ ); }
+    A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward<A2>( a2_ ); }
+    A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward<A3>( a3_ ); }
+    A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward<A4>( a4_ ); }
+
+    template<class T> T & operator[] ( _bi::value<T> & v ) const { return v.get(); }
+
+    template<class T> T const & operator[] ( _bi::value<T> const & v ) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+};
+
+template< class A1, class A2, class A3, class A4, class A5 > class rrlist5
+{
+private:
+
+    A1 & a1_;
+    A2 & a2_;
+    A3 & a3_;
+    A4 & a4_;
+    A5 & a5_;
+
+public:
+
+    rrlist5( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ) {}
+
+    A1 && operator[] (boost::arg<1>) const { return std::forward<A1>( a1_ ); }
+    A2 && operator[] (boost::arg<2>) const { return std::forward<A2>( a2_ ); }
+    A3 && operator[] (boost::arg<3>) const { return std::forward<A3>( a3_ ); }
+    A4 && operator[] (boost::arg<4>) const { return std::forward<A4>( a4_ ); }
+    A5 && operator[] (boost::arg<5>) const { return std::forward<A5>( a5_ ); }
+
+    A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward<A1>( a1_ ); }
+    A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward<A2>( a2_ ); }
+    A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward<A3>( a3_ ); }
+    A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward<A4>( a4_ ); }
+    A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward<A5>( a5_ ); }
+
+    template<class T> T & operator[] ( _bi::value<T> & v ) const { return v.get(); }
+
+    template<class T> T const & operator[] ( _bi::value<T> const & v ) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+};
+
+template< class A1, class A2, class A3, class A4, class A5, class A6 > class rrlist6
+{
+private:
+
+    A1 & a1_;
+    A2 & a2_;
+    A3 & a3_;
+    A4 & a4_;
+    A5 & a5_;
+    A6 & a6_;
+
+public:
+
+    rrlist6( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ), a6_( a6 ) {}
+
+    A1 && operator[] (boost::arg<1>) const { return std::forward<A1>( a1_ ); }
+    A2 && operator[] (boost::arg<2>) const { return std::forward<A2>( a2_ ); }
+    A3 && operator[] (boost::arg<3>) const { return std::forward<A3>( a3_ ); }
+    A4 && operator[] (boost::arg<4>) const { return std::forward<A4>( a4_ ); }
+    A5 && operator[] (boost::arg<5>) const { return std::forward<A5>( a5_ ); }
+    A6 && operator[] (boost::arg<6>) const { return std::forward<A6>( a6_ ); }
+
+    A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward<A1>( a1_ ); }
+    A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward<A2>( a2_ ); }
+    A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward<A3>( a3_ ); }
+    A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward<A4>( a4_ ); }
+    A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward<A5>( a5_ ); }
+    A6 && operator[] (boost::arg<6> (*) ()) const { return std::forward<A6>( a6_ ); }
+
+    template<class T> T & operator[] ( _bi::value<T> & v ) const { return v.get(); }
+
+    template<class T> T const & operator[] ( _bi::value<T> const & v ) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+};
+
+template< class A1, class A2, class A3, class A4, class A5, class A6, class A7 > class rrlist7
+{
+private:
+
+    A1 & a1_;
+    A2 & a2_;
+    A3 & a3_;
+    A4 & a4_;
+    A5 & a5_;
+    A6 & a6_;
+    A7 & a7_;
+
+public:
+
+    rrlist7( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ), a6_( a6 ), a7_( a7 ) {}
+
+    A1 && operator[] (boost::arg<1>) const { return std::forward<A1>( a1_ ); }
+    A2 && operator[] (boost::arg<2>) const { return std::forward<A2>( a2_ ); }
+    A3 && operator[] (boost::arg<3>) const { return std::forward<A3>( a3_ ); }
+    A4 && operator[] (boost::arg<4>) const { return std::forward<A4>( a4_ ); }
+    A5 && operator[] (boost::arg<5>) const { return std::forward<A5>( a5_ ); }
+    A6 && operator[] (boost::arg<6>) const { return std::forward<A6>( a6_ ); }
+    A7 && operator[] (boost::arg<7>) const { return std::forward<A7>( a7_ ); }
+
+    A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward<A1>( a1_ ); }
+    A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward<A2>( a2_ ); }
+    A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward<A3>( a3_ ); }
+    A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward<A4>( a4_ ); }
+    A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward<A5>( a5_ ); }
+    A6 && operator[] (boost::arg<6> (*) ()) const { return std::forward<A6>( a6_ ); }
+    A7 && operator[] (boost::arg<7> (*) ()) const { return std::forward<A7>( a7_ ); }
+
+    template<class T> T & operator[] ( _bi::value<T> & v ) const { return v.get(); }
+
+    template<class T> T const & operator[] ( _bi::value<T> const & v ) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+};
+
+template< class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > class rrlist8
+{
+private:
+
+    A1 & a1_;
+    A2 & a2_;
+    A3 & a3_;
+    A4 & a4_;
+    A5 & a5_;
+    A6 & a6_;
+    A7 & a7_;
+    A8 & a8_;
+
+public:
+
+    rrlist8( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ), a6_( a6 ), a7_( a7 ), a8_( a8 ) {}
+
+    A1 && operator[] (boost::arg<1>) const { return std::forward<A1>( a1_ ); }
+    A2 && operator[] (boost::arg<2>) const { return std::forward<A2>( a2_ ); }
+    A3 && operator[] (boost::arg<3>) const { return std::forward<A3>( a3_ ); }
+    A4 && operator[] (boost::arg<4>) const { return std::forward<A4>( a4_ ); }
+    A5 && operator[] (boost::arg<5>) const { return std::forward<A5>( a5_ ); }
+    A6 && operator[] (boost::arg<6>) const { return std::forward<A6>( a6_ ); }
+    A7 && operator[] (boost::arg<7>) const { return std::forward<A7>( a7_ ); }
+    A8 && operator[] (boost::arg<8>) const { return std::forward<A8>( a8_ ); }
+
+    A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward<A1>( a1_ ); }
+    A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward<A2>( a2_ ); }
+    A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward<A3>( a3_ ); }
+    A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward<A4>( a4_ ); }
+    A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward<A5>( a5_ ); }
+    A6 && operator[] (boost::arg<6> (*) ()) const { return std::forward<A6>( a6_ ); }
+    A7 && operator[] (boost::arg<7> (*) ()) const { return std::forward<A7>( a7_ ); }
+    A8 && operator[] (boost::arg<8> (*) ()) const { return std::forward<A8>( a8_ ); }
+
+    template<class T> T & operator[] ( _bi::value<T> & v ) const { return v.get(); }
+
+    template<class T> T const & operator[] ( _bi::value<T> const & v ) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+};
+
+template< class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > class rrlist9
+{
+private:
+
+    A1 & a1_;
+    A2 & a2_;
+    A3 & a3_;
+    A4 & a4_;
+    A5 & a5_;
+    A6 & a6_;
+    A7 & a7_;
+    A8 & a8_;
+    A9 & a9_;
+
+public:
+
+    rrlist9( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8, A9 & a9 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ), a6_( a6 ), a7_( a7 ), a8_( a8 ), a9_( a9 ) {}
+
+    A1 && operator[] (boost::arg<1>) const { return std::forward<A1>( a1_ ); }
+    A2 && operator[] (boost::arg<2>) const { return std::forward<A2>( a2_ ); }
+    A3 && operator[] (boost::arg<3>) const { return std::forward<A3>( a3_ ); }
+    A4 && operator[] (boost::arg<4>) const { return std::forward<A4>( a4_ ); }
+    A5 && operator[] (boost::arg<5>) const { return std::forward<A5>( a5_ ); }
+    A6 && operator[] (boost::arg<6>) const { return std::forward<A6>( a6_ ); }
+    A7 && operator[] (boost::arg<7>) const { return std::forward<A7>( a7_ ); }
+    A8 && operator[] (boost::arg<8>) const { return std::forward<A8>( a8_ ); }
+    A9 && operator[] (boost::arg<9>) const { return std::forward<A9>( a9_ ); }
+
+    A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward<A1>( a1_ ); }
+    A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward<A2>( a2_ ); }
+    A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward<A3>( a3_ ); }
+    A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward<A4>( a4_ ); }
+    A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward<A5>( a5_ ); }
+    A6 && operator[] (boost::arg<6> (*) ()) const { return std::forward<A6>( a6_ ); }
+    A7 && operator[] (boost::arg<7> (*) ()) const { return std::forward<A7>( a7_ ); }
+    A8 && operator[] (boost::arg<8> (*) ()) const { return std::forward<A8>( a8_ ); }
+    A9 && operator[] (boost::arg<9> (*) ()) const { return std::forward<A9>( a9_ ); }
+
+    template<class T> T & operator[] ( _bi::value<T> & v ) const { return v.get(); }
+
+    template<class T> T const & operator[] ( _bi::value<T> const & v ) const { return v.get(); }
+
+    template<class T> T & operator[] (reference_wrapper<T> const & v) const { return v.get(); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> & b) const { return b.eval(*this); }
+
+    template<class R, class F, class L> typename result_traits<R, F>::type operator[] (bind_t<R, F, L> const & b) const { return b.eval(*this); }
+};
+
+template<class R, class F, class L> class bind_t
+{
+private:
+
+    F f_;
+    L l_;
+
+public:
+
+    typedef typename result_traits<R, F>::type result_type;
+    typedef bind_t this_type;
+
+    bind_t( F f, L const & l ): f_( f ), l_( l ) {}
+
+    //
+
+    result_type operator()()
+    {
+        list0 a;
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    result_type operator()() const
+    {
+        list0 a;
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1> result_type operator()( A1 && a1 )
+    {
+        rrlist1< A1 > a( a1 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1> result_type operator()( A1 && a1 ) const
+    {
+        rrlist1< A1 > a( a1 );
+        return l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2> result_type operator()( A1 && a1, A2 && a2 )
+    {
+        rrlist2< A1, A2 > a( a1, a2 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1, class A2> result_type operator()( A1 && a1, A2 && a2 ) const
+    {
+        rrlist2< A1, A2 > a( a1, a2 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1, class A2, class A3> result_type operator()( A1 && a1, A2 && a2, A3 && a3 )
+    {
+        rrlist3< A1, A2, A3 > a( a1, a2, a3 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1, class A2, class A3> result_type operator()( A1 && a1, A2 && a2, A3 && a3 ) const
+    {
+        rrlist3< A1, A2, A3 > a( a1, a2, a3 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1, class A2, class A3, class A4> result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4 )
+    {
+        rrlist4< A1, A2, A3, A4 > a( a1, a2, a3, a4 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1, class A2, class A3, class A4> result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4 ) const
+    {
+        rrlist4< A1, A2, A3, A4 > a( a1, a2, a3, a4 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5> result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 )
+    {
+        rrlist5< A1, A2, A3, A4, A5 > a( a1, a2, a3, a4, a5 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5> result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 ) const
+    {
+        rrlist5< A1, A2, A3, A4, A5 > a( a1, a2, a3, a4, a5 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6> result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 )
+    {
+        rrlist6< A1, A2, A3, A4, A5, A6 > a( a1, a2, a3, a4, a5, a6 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6> result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 ) const
+    {
+        rrlist6< A1, A2, A3, A4, A5, A6 > a( a1, a2, a3, a4, a5, a6 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 )
+    {
+        rrlist7< A1, A2, A3, A4, A5, A6, A7 > a( a1, a2, a3, a4, a5, a6, a7 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 ) const
+    {
+        rrlist7< A1, A2, A3, A4, A5, A6, A7 > a( a1, a2, a3, a4, a5, a6, a7 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 )
+    {
+        rrlist8< A1, A2, A3, A4, A5, A6, A7, A8 > a( a1, a2, a3, a4, a5, a6, a7, a8 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 ) const
+    {
+        rrlist8< A1, A2, A3, A4, A5, A6, A7, A8 > a( a1, a2, a3, a4, a5, a6, a7, a8 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 )
+    {
+        rrlist9< A1, A2, A3, A4, A5, A6, A7, A8, A9 > a( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 ) const
+    {
+        rrlist9< A1, A2, A3, A4, A5, A6, A7, A8, A9 > a( a1, a2, a3, a4, a5, a6, a7, a8, a9 );
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    //
+
+    template<class A> result_type eval( A & a )
+    {
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class A> result_type eval( A & a ) const
+    {
+        return l_( type<result_type>(), f_, a, 0 );
+    }
+
+    template<class V> void accept( V & v ) const
+    {
+#if !defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) && !defined( __BORLANDC__ )
+        using boost::visit_each;
+#endif
+
+        BOOST_BIND_VISIT_EACH( v, f_, 0 );
+        l_.accept( v );
+    }
+
+    bool compare( this_type const & rhs ) const
+    {
+        return ref_compare( f_, rhs.f_, 0 ) && l_ == rhs.l_;
+    }
+};
+
+#elif !defined( BOOST_NO_VOID_RETURNS )
+
+template<class R, class F, class L> class bind_t
+{
+public:
+
+    typedef bind_t this_type;
+
+    bind_t(F f, L const & l): f_(f), l_(l) {}
+
+#define BOOST_BIND_RETURN return
+#include <boost/bind/bind_template.hpp>
+#undef BOOST_BIND_RETURN
+
+};
+
+#else // no void returns
+
+template<class R> struct bind_t_generator
+{
+
+template<class F, class L> class implementation
+{
+public:
+
+    typedef implementation this_type;
+
+    implementation(F f, L const & l): f_(f), l_(l) {}
+
+#define BOOST_BIND_RETURN return
+#include <boost/bind/bind_template.hpp>
+#undef BOOST_BIND_RETURN
+
+};
+
+};
+
+template<> struct bind_t_generator<void>
+{
+
+template<class F, class L> class implementation
+{
+private:
+
+    typedef void R;
+
+public:
+
+    typedef implementation this_type;
+
+    implementation(F f, L const & l): f_(f), l_(l) {}
+
+#define BOOST_BIND_RETURN
+#include <boost/bind/bind_template.hpp>
+#undef BOOST_BIND_RETURN
+
+};
+
+};
+
+template<class R2, class F, class L> class bind_t: public bind_t_generator<R2>::BOOST_NESTED_TEMPLATE implementation<F, L>
+{
+public:
+
+    bind_t(F f, L const & l): bind_t_generator<R2>::BOOST_NESTED_TEMPLATE implementation<F, L>(f, l) {}
+
+};
+
+#endif
+
+// function_equal
+
+#ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
+
+// put overloads in _bi, rely on ADL
+
+# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+template<class R, class F, class L> bool function_equal( bind_t<R, F, L> const & a, bind_t<R, F, L> const & b )
+{
+    return a.compare(b);
+}
+
+# else
+
+template<class R, class F, class L> bool function_equal_impl( bind_t<R, F, L> const & a, bind_t<R, F, L> const & b, int )
+{
+    return a.compare(b);
+}
+
+# endif // #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+#else // BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
+
+// put overloads in boost
+
+} // namespace _bi
+
+# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+template<class R, class F, class L> bool function_equal( _bi::bind_t<R, F, L> const & a, _bi::bind_t<R, F, L> const & b )
+{
+    return a.compare(b);
+}
+
+# else
+
+template<class R, class F, class L> bool function_equal_impl( _bi::bind_t<R, F, L> const & a, _bi::bind_t<R, F, L> const & b, int )
+{
+    return a.compare(b);
+}
+
+# endif // #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+
+namespace _bi
+{
+
+#endif // BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
+
+// add_value
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || (__SUNPRO_CC >= 0x530)
+
+#if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x582) )
+
+template<class T> struct add_value
+{
+    typedef _bi::value<T> type;
+};
+
+#else
+
+template< class T, int I > struct add_value_2
+{
+    typedef boost::arg<I> type;
+};
+
+template< class T > struct add_value_2< T, 0 >
+{
+    typedef _bi::value< T > type;
+};
+
+template<class T> struct add_value
+{
+    typedef typename add_value_2< T, boost::is_placeholder< T >::value >::type type;
+};
+
+#endif
+
+template<class T> struct add_value< value<T> >
+{
+    typedef _bi::value<T> type;
+};
+
+template<class T> struct add_value< reference_wrapper<T> >
+{
+    typedef reference_wrapper<T> type;
+};
+
+template<int I> struct add_value< arg<I> >
+{
+    typedef boost::arg<I> type;
+};
+
+template<int I> struct add_value< arg<I> (*) () >
+{
+    typedef boost::arg<I> (*type) ();
+};
+
+template<class R, class F, class L> struct add_value< bind_t<R, F, L> >
+{
+    typedef bind_t<R, F, L> type;
+};
+
+#else
+
+template<int I> struct _avt_0;
+
+template<> struct _avt_0<1>
+{
+    template<class T> struct inner
+    {
+        typedef T type;
+    };
+};
+
+template<> struct _avt_0<2>
+{
+    template<class T> struct inner
+    {
+        typedef value<T> type;
+    };
+};
+
+typedef char (&_avt_r1) [1];
+typedef char (&_avt_r2) [2];
+
+template<class T> _avt_r1 _avt_f(value<T>);
+template<class T> _avt_r1 _avt_f(reference_wrapper<T>);
+template<int I> _avt_r1 _avt_f(arg<I>);
+template<int I> _avt_r1 _avt_f(arg<I> (*) ());
+template<class R, class F, class L> _avt_r1 _avt_f(bind_t<R, F, L>);
+
+_avt_r2 _avt_f(...);
+
+template<class T> struct add_value
+{
+    static T t();
+    typedef typename _avt_0<sizeof(_avt_f(t()))>::template inner<T>::type type;
+};
+
+#endif
+
+// list_av_N
+
+template<class A1> struct list_av_1
+{
+    typedef typename add_value<A1>::type B1;
+    typedef list1<B1> type;
+};
+
+template<class A1, class A2> struct list_av_2
+{
+    typedef typename add_value<A1>::type B1;
+    typedef typename add_value<A2>::type B2;
+    typedef list2<B1, B2> type;
+};
+
+template<class A1, class A2, class A3> struct list_av_3
+{
+    typedef typename add_value<A1>::type B1;
+    typedef typename add_value<A2>::type B2;
+    typedef typename add_value<A3>::type B3;
+    typedef list3<B1, B2, B3> type;
+};
+
+template<class A1, class A2, class A3, class A4> struct list_av_4
+{
+    typedef typename add_value<A1>::type B1;
+    typedef typename add_value<A2>::type B2;
+    typedef typename add_value<A3>::type B3;
+    typedef typename add_value<A4>::type B4;
+    typedef list4<B1, B2, B3, B4> type;
+};
+
+template<class A1, class A2, class A3, class A4, class A5> struct list_av_5
+{
+    typedef typename add_value<A1>::type B1;
+    typedef typename add_value<A2>::type B2;
+    typedef typename add_value<A3>::type B3;
+    typedef typename add_value<A4>::type B4;
+    typedef typename add_value<A5>::type B5;
+    typedef list5<B1, B2, B3, B4, B5> type;
+};
+
+template<class A1, class A2, class A3, class A4, class A5, class A6> struct list_av_6
+{
+    typedef typename add_value<A1>::type B1;
+    typedef typename add_value<A2>::type B2;
+    typedef typename add_value<A3>::type B3;
+    typedef typename add_value<A4>::type B4;
+    typedef typename add_value<A5>::type B5;
+    typedef typename add_value<A6>::type B6;
+    typedef list6<B1, B2, B3, B4, B5, B6> type;
+};
+
+template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> struct list_av_7
+{
+    typedef typename add_value<A1>::type B1;
+    typedef typename add_value<A2>::type B2;
+    typedef typename add_value<A3>::type B3;
+    typedef typename add_value<A4>::type B4;
+    typedef typename add_value<A5>::type B5;
+    typedef typename add_value<A6>::type B6;
+    typedef typename add_value<A7>::type B7;
+    typedef list7<B1, B2, B3, B4, B5, B6, B7> type;
+};
+
+template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> struct list_av_8
+{
+    typedef typename add_value<A1>::type B1;
+    typedef typename add_value<A2>::type B2;
+    typedef typename add_value<A3>::type B3;
+    typedef typename add_value<A4>::type B4;
+    typedef typename add_value<A5>::type B5;
+    typedef typename add_value<A6>::type B6;
+    typedef typename add_value<A7>::type B7;
+    typedef typename add_value<A8>::type B8;
+    typedef list8<B1, B2, B3, B4, B5, B6, B7, B8> type;
+};
+
+template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> struct list_av_9
+{
+    typedef typename add_value<A1>::type B1;
+    typedef typename add_value<A2>::type B2;
+    typedef typename add_value<A3>::type B3;
+    typedef typename add_value<A4>::type B4;
+    typedef typename add_value<A5>::type B5;
+    typedef typename add_value<A6>::type B6;
+    typedef typename add_value<A7>::type B7;
+    typedef typename add_value<A8>::type B8;
+    typedef typename add_value<A9>::type B9;
+    typedef list9<B1, B2, B3, B4, B5, B6, B7, B8, B9> type;
+};
+
+// operator!
+
+struct logical_not
+{
+    template<class V> bool operator()(V const & v) const { return !v; }
+};
+
+template<class R, class F, class L>
+    bind_t< bool, logical_not, list1< bind_t<R, F, L> > >
+    operator! (bind_t<R, F, L> const & f)
+{
+    typedef list1< bind_t<R, F, L> > list_type;
+    return bind_t<bool, logical_not, list_type> ( logical_not(), list_type(f) );
+}
+
+// relational operators
+
+#define BOOST_BIND_OPERATOR( op, name ) \
+\
+struct name \
+{ \
+    template<class V, class W> bool operator()(V const & v, W const & w) const { return v op w; } \
+}; \
+ \
+template<class R, class F, class L, class A2> \
+    bind_t< bool, name, list2< bind_t<R, F, L>, typename add_value<A2>::type > > \
+    operator op (bind_t<R, F, L> const & f, A2 a2) \
+{ \
+    typedef typename add_value<A2>::type B2; \
+    typedef list2< bind_t<R, F, L>, B2> list_type; \
+    return bind_t<bool, name, list_type> ( name(), list_type(f, a2) ); \
+}
+
+BOOST_BIND_OPERATOR( ==, equal )
+BOOST_BIND_OPERATOR( !=, not_equal )
+
+BOOST_BIND_OPERATOR( <, less )
+BOOST_BIND_OPERATOR( <=, less_equal )
+
+BOOST_BIND_OPERATOR( >, greater )
+BOOST_BIND_OPERATOR( >=, greater_equal )
+
+BOOST_BIND_OPERATOR( &&, logical_and )
+BOOST_BIND_OPERATOR( ||, logical_or )
+
+#undef BOOST_BIND_OPERATOR
+
+#if defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3)
+
+// resolve ambiguity with rel_ops
+
+#define BOOST_BIND_OPERATOR( op, name ) \
+\
+template<class R, class F, class L> \
+    bind_t< bool, name, list2< bind_t<R, F, L>, bind_t<R, F, L> > > \
+    operator op (bind_t<R, F, L> const & f, bind_t<R, F, L> const & g) \
+{ \
+    typedef list2< bind_t<R, F, L>, bind_t<R, F, L> > list_type; \
+    return bind_t<bool, name, list_type> ( name(), list_type(f, g) ); \
+}
+
+BOOST_BIND_OPERATOR( !=, not_equal )
+BOOST_BIND_OPERATOR( <=, less_equal )
+BOOST_BIND_OPERATOR( >, greater )
+BOOST_BIND_OPERATOR( >=, greater_equal )
+
+#endif
+
+// visit_each, ADL
+
+#if !defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) && !defined( __BORLANDC__ ) \
+   && !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
+
+template<class V, class T> void visit_each( V & v, value<T> const & t, int )
+{
+    using boost::visit_each;
+    BOOST_BIND_VISIT_EACH( v, t.get(), 0 );
+}
+
+template<class V, class R, class F, class L> void visit_each( V & v, bind_t<R, F, L> const & t, int )
+{
+    t.accept( v );
+}
+
+#endif
+
+} // namespace _bi
+
+// visit_each, no ADL
+
+#if defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) || defined( __BORLANDC__ ) \
+  || (defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
+
+template<class V, class T> void visit_each( V & v, _bi::value<T> const & t, int )
+{
+    BOOST_BIND_VISIT_EACH( v, t.get(), 0 );
+}
+
+template<class V, class R, class F, class L> void visit_each( V & v, _bi::bind_t<R, F, L> const & t, int )
+{
+    t.accept( v );
+}
+
+#endif
+
+// is_bind_expression
+
+template< class T > struct is_bind_expression
+{
+    enum _vt { value = 0 };
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template< class R, class F, class L > struct is_bind_expression< _bi::bind_t< R, F, L > >
+{
+    enum _vt { value = 1 };
+};
+
+#endif
+
+// bind
+
+#ifndef BOOST_BIND
+#define BOOST_BIND bind
+#endif
+
+// generic function objects
+
+template<class R, class F>
+    _bi::bind_t<R, F, _bi::list0>
+    BOOST_BIND(F f)
+{
+    typedef _bi::list0 list_type;
+    return _bi::bind_t<R, F, list_type> (f, list_type());
+}
+
+template<class R, class F, class A1>
+    _bi::bind_t<R, F, typename _bi::list_av_1<A1>::type>
+    BOOST_BIND(F f, A1 a1)
+{
+    typedef typename _bi::list_av_1<A1>::type list_type;
+    return _bi::bind_t<R, F, list_type> (f, list_type(a1));
+}
+
+template<class R, class F, class A1, class A2>
+    _bi::bind_t<R, F, typename _bi::list_av_2<A1, A2>::type>
+    BOOST_BIND(F f, A1 a1, A2 a2)
+{
+    typedef typename _bi::list_av_2<A1, A2>::type list_type;
+    return _bi::bind_t<R, F, list_type> (f, list_type(a1, a2));
+}
+
+template<class R, class F, class A1, class A2, class A3>
+    _bi::bind_t<R, F, typename _bi::list_av_3<A1, A2, A3>::type>
+    BOOST_BIND(F f, A1 a1, A2 a2, A3 a3)
+{
+    typedef typename _bi::list_av_3<A1, A2, A3>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3));
+}
+
+template<class R, class F, class A1, class A2, class A3, class A4>
+    _bi::bind_t<R, F, typename _bi::list_av_4<A1, A2, A3, A4>::type>
+    BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4)
+{
+    typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4));
+}
+
+template<class R, class F, class A1, class A2, class A3, class A4, class A5>
+    _bi::bind_t<R, F, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
+    BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+    typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5));
+}
+
+template<class R, class F, class A1, class A2, class A3, class A4, class A5, class A6>
+    _bi::bind_t<R, F, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
+    BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+{
+    typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6));
+}
+
+template<class R, class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+    _bi::bind_t<R, F, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
+    BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+{
+    typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7));
+}
+
+template<class R, class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
+    _bi::bind_t<R, F, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
+    BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+{
+    typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8));
+}
+
+template<class R, class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
+    _bi::bind_t<R, F, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
+    BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+{
+    typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9));
+}
+
+// generic function objects, alternative syntax
+
+template<class R, class F>
+    _bi::bind_t<R, F, _bi::list0>
+    BOOST_BIND(boost::type<R>, F f)
+{
+    typedef _bi::list0 list_type;
+    return _bi::bind_t<R, F, list_type> (f, list_type());
+}
+
+template<class R, class F, class A1>
+    _bi::bind_t<R, F, typename _bi::list_av_1<A1>::type>
+    BOOST_BIND(boost::type<R>, F f, A1 a1)
+{
+    typedef typename _bi::list_av_1<A1>::type list_type;
+    return _bi::bind_t<R, F, list_type> (f, list_type(a1));
+}
+
+template<class R, class F, class A1, class A2>
+    _bi::bind_t<R, F, typename _bi::list_av_2<A1, A2>::type>
+    BOOST_BIND(boost::type<R>, F f, A1 a1, A2 a2)
+{
+    typedef typename _bi::list_av_2<A1, A2>::type list_type;
+    return _bi::bind_t<R, F, list_type> (f, list_type(a1, a2));
+}
+
+template<class R, class F, class A1, class A2, class A3>
+    _bi::bind_t<R, F, typename _bi::list_av_3<A1, A2, A3>::type>
+    BOOST_BIND(boost::type<R>, F f, A1 a1, A2 a2, A3 a3)
+{
+    typedef typename _bi::list_av_3<A1, A2, A3>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3));
+}
+
+template<class R, class F, class A1, class A2, class A3, class A4>
+    _bi::bind_t<R, F, typename _bi::list_av_4<A1, A2, A3, A4>::type>
+    BOOST_BIND(boost::type<R>, F f, A1 a1, A2 a2, A3 a3, A4 a4)
+{
+    typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4));
+}
+
+template<class R, class F, class A1, class A2, class A3, class A4, class A5>
+    _bi::bind_t<R, F, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
+    BOOST_BIND(boost::type<R>, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+    typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5));
+}
+
+template<class R, class F, class A1, class A2, class A3, class A4, class A5, class A6>
+    _bi::bind_t<R, F, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
+    BOOST_BIND(boost::type<R>, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+{
+    typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6));
+}
+
+template<class R, class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+    _bi::bind_t<R, F, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
+    BOOST_BIND(boost::type<R>, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+{
+    typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7));
+}
+
+template<class R, class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
+    _bi::bind_t<R, F, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
+    BOOST_BIND(boost::type<R>, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+{
+    typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8));
+}
+
+template<class R, class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
+    _bi::bind_t<R, F, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
+    BOOST_BIND(boost::type<R>, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+{
+    typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9));
+}
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+
+// adaptable function objects
+
+template<class F>
+    _bi::bind_t<_bi::unspecified, F, _bi::list0>
+    BOOST_BIND(F f)
+{
+    typedef _bi::list0 list_type;
+    return _bi::bind_t<_bi::unspecified, F, list_type> (f, list_type());
+}
+
+template<class F, class A1>
+    _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_1<A1>::type>
+    BOOST_BIND(F f, A1 a1)
+{
+    typedef typename _bi::list_av_1<A1>::type list_type;
+    return _bi::bind_t<_bi::unspecified, F, list_type> (f, list_type(a1));
+}
+
+template<class F, class A1, class A2>
+    _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_2<A1, A2>::type>
+    BOOST_BIND(F f, A1 a1, A2 a2)
+{
+    typedef typename _bi::list_av_2<A1, A2>::type list_type;
+    return _bi::bind_t<_bi::unspecified, F, list_type> (f, list_type(a1, a2));
+}
+
+template<class F, class A1, class A2, class A3>
+    _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_3<A1, A2, A3>::type>
+    BOOST_BIND(F f, A1 a1, A2 a2, A3 a3)
+{
+    typedef typename _bi::list_av_3<A1, A2, A3>::type list_type;
+    return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3));
+}
+
+template<class F, class A1, class A2, class A3, class A4>
+    _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_4<A1, A2, A3, A4>::type>
+    BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4)
+{
+    typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type;
+    return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4));
+}
+
+template<class F, class A1, class A2, class A3, class A4, class A5>
+    _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
+    BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+    typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type;
+    return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5));
+}
+
+template<class F, class A1, class A2, class A3, class A4, class A5, class A6>
+    _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
+    BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+{
+    typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type;
+    return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6));
+}
+
+template<class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+    _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
+    BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+{
+    typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type;
+    return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7));
+}
+
+template<class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
+    _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
+    BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+{
+    typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
+    return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8));
+}
+
+template<class F, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
+    _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
+    BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+{
+    typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
+    return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9));
+}
+
+#endif // !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+
+// function pointers
+
+#define BOOST_BIND_CC
+#define BOOST_BIND_ST
+
+#include <boost/bind/bind_cc.hpp>
+
+#undef BOOST_BIND_CC
+#undef BOOST_BIND_ST
+
+#ifdef BOOST_BIND_ENABLE_STDCALL
+
+#define BOOST_BIND_CC __stdcall
+#define BOOST_BIND_ST
+
+#include <boost/bind/bind_cc.hpp>
+
+#undef BOOST_BIND_CC
+#undef BOOST_BIND_ST
+
+#endif
+
+#ifdef BOOST_BIND_ENABLE_FASTCALL
+
+#define BOOST_BIND_CC __fastcall
+#define BOOST_BIND_ST
+
+#include <boost/bind/bind_cc.hpp>
+
+#undef BOOST_BIND_CC
+#undef BOOST_BIND_ST
+
+#endif
+
+#ifdef BOOST_BIND_ENABLE_PASCAL
+
+#define BOOST_BIND_ST pascal
+#define BOOST_BIND_CC
+
+#include <boost/bind/bind_cc.hpp>
+
+#undef BOOST_BIND_ST
+#undef BOOST_BIND_CC
+
+#endif
+
+// member function pointers
+
+#define BOOST_BIND_MF_NAME(X) X
+#define BOOST_BIND_MF_CC
+
+#include <boost/bind/bind_mf_cc.hpp>
+#include <boost/bind/bind_mf2_cc.hpp>
+
+#undef BOOST_BIND_MF_NAME
+#undef BOOST_BIND_MF_CC
+
+#ifdef BOOST_MEM_FN_ENABLE_CDECL
+
+#define BOOST_BIND_MF_NAME(X) X##_cdecl
+#define BOOST_BIND_MF_CC __cdecl
+
+#include <boost/bind/bind_mf_cc.hpp>
+#include <boost/bind/bind_mf2_cc.hpp>
+
+#undef BOOST_BIND_MF_NAME
+#undef BOOST_BIND_MF_CC
+
+#endif
+
+#ifdef BOOST_MEM_FN_ENABLE_STDCALL
+
+#define BOOST_BIND_MF_NAME(X) X##_stdcall
+#define BOOST_BIND_MF_CC __stdcall
+
+#include <boost/bind/bind_mf_cc.hpp>
+#include <boost/bind/bind_mf2_cc.hpp>
+
+#undef BOOST_BIND_MF_NAME
+#undef BOOST_BIND_MF_CC
+
+#endif
+
+#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
+
+#define BOOST_BIND_MF_NAME(X) X##_fastcall
+#define BOOST_BIND_MF_CC __fastcall
+
+#include <boost/bind/bind_mf_cc.hpp>
+#include <boost/bind/bind_mf2_cc.hpp>
+
+#undef BOOST_BIND_MF_NAME
+#undef BOOST_BIND_MF_CC
+
+#endif
+
+// data member pointers
+
+#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
+    || ( defined(__BORLANDC__) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x620 ) ) )
+
+template<class R, class T, class A1>
+_bi::bind_t< R, _mfi::dm<R, T>, typename _bi::list_av_1<A1>::type >
+    BOOST_BIND(R T::*f, A1 a1)
+{
+    typedef _mfi::dm<R, T> F;
+    typedef typename _bi::list_av_1<A1>::type list_type;
+    return _bi::bind_t<R, F, list_type>( F(f), list_type(a1) );
+}
+
+#else
+
+namespace _bi
+{
+
+template< class Pm, int I > struct add_cref;
+
+template< class M, class T > struct add_cref< M T::*, 0 >
+{
+    typedef M type;
+};
+
+template< class M, class T > struct add_cref< M T::*, 1 >
+{
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4180)
+#endif
+    typedef M const & type;
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+};
+
+template< class R, class T > struct add_cref< R (T::*) (), 1 >
+{
+    typedef void type;
+};
+
+#if !defined(__IBMCPP__) || __IBMCPP_FUNC_CV_TMPL_ARG_DEDUCTION
+
+template< class R, class T > struct add_cref< R (T::*) () const, 1 >
+{
+    typedef void type;
+};
+
+#endif // __IBMCPP__
+
+template<class R> struct isref
+{
+    enum value_type { value = 0 };
+};
+
+template<class R> struct isref< R& >
+{
+    enum value_type { value = 1 };
+};
+
+template<class R> struct isref< R* >
+{
+    enum value_type { value = 1 };
+};
+
+template<class Pm, class A1> struct dm_result
+{
+    typedef typename add_cref< Pm, 1 >::type type;
+};
+
+template<class Pm, class R, class F, class L> struct dm_result< Pm, bind_t<R, F, L> >
+{
+    typedef typename bind_t<R, F, L>::result_type result_type;
+    typedef typename add_cref< Pm, isref< result_type >::value >::type type;
+};
+
+} // namespace _bi
+
+template< class A1, class M, class T >
+
+_bi::bind_t<
+    typename _bi::dm_result< M T::*, A1 >::type,
+    _mfi::dm<M, T>,
+    typename _bi::list_av_1<A1>::type
+>
+
+BOOST_BIND( M T::*f, A1 a1 )
+{
+    typedef typename _bi::dm_result< M T::*, A1 >::type result_type;
+    typedef _mfi::dm<M, T> F;
+    typedef typename _bi::list_av_1<A1>::type list_type;
+    return _bi::bind_t< result_type, F, list_type >( F( f ), list_type( a1 ) );
+}
+
+#endif
+
+} // namespace boost
+
+#ifndef BOOST_BIND_NO_PLACEHOLDERS
+
+# include <boost/bind/placeholders.hpp>
+
+#endif
+
+#ifdef BOOST_MSVC
+# pragma warning(default: 4512) // assignment operator could not be generated
+# pragma warning(pop)
+#endif
+
+#endif // #ifndef BOOST_BIND_BIND_HPP_INCLUDED
diff --git a/third_party/boost/boost/bind/bind_cc.hpp b/third_party/boost/boost/bind/bind_cc.hpp
new file mode 100644
index 0000000..35f8ece
--- /dev/null
+++ b/third_party/boost/boost/bind/bind_cc.hpp
@@ -0,0 +1,117 @@
+//
+//  bind/bind_cc.hpp - support for different calling conventions
+//
+//  Do not include this header directly.
+//
+//  Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//  See http://www.boost.org/libs/bind/bind.html for documentation.
+//
+
+template<class R>
+    _bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (), _bi::list0>
+    BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) ())
+{
+    typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) ();
+    typedef _bi::list0 list_type;
+    return _bi::bind_t<R, F, list_type> (f, list_type());
+}
+
+template<class R, class B1, class A1>
+    _bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1), typename _bi::list_av_1<A1>::type>
+    BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1), A1 a1)
+{
+    typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1);
+    typedef typename _bi::list_av_1<A1>::type list_type;
+    return _bi::bind_t<R, F, list_type> (f, list_type(a1));
+}
+
+template<class R, class B1, class B2, class A1, class A2>
+    _bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2), typename _bi::list_av_2<A1, A2>::type>
+    BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2), A1 a1, A2 a2)
+{
+    typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2);
+    typedef typename _bi::list_av_2<A1, A2>::type list_type;
+    return _bi::bind_t<R, F, list_type> (f, list_type(a1, a2));
+}
+
+template<class R,
+    class B1, class B2, class B3,
+    class A1, class A2, class A3>
+    _bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2, B3), typename _bi::list_av_3<A1, A2, A3>::type>
+    BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3), A1 a1, A2 a2, A3 a3)
+{
+    typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3);
+    typedef typename _bi::list_av_3<A1, A2, A3>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3));
+}
+
+template<class R,
+    class B1, class B2, class B3, class B4,
+    class A1, class A2, class A3, class A4>
+    _bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2, B3, B4), typename _bi::list_av_4<A1, A2, A3, A4>::type>
+    BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4), A1 a1, A2 a2, A3 a3, A4 a4)
+{
+    typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4);
+    typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4));
+}
+
+template<class R,
+    class B1, class B2, class B3, class B4, class B5,
+    class A1, class A2, class A3, class A4, class A5>
+    _bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2, B3, B4, B5), typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
+    BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+    typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5);
+    typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5));
+}
+
+template<class R,
+    class B1, class B2, class B3, class B4, class B5, class B6,
+    class A1, class A2, class A3, class A4, class A5, class A6>
+    _bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2, B3, B4, B5, B6), typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
+    BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+{
+    typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6);
+    typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6));
+}
+
+template<class R,
+    class B1, class B2, class B3, class B4, class B5, class B6, class B7,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+    _bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2, B3, B4, B5, B6, B7), typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
+    BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6, B7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+{
+    typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6, B7);
+    typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7));
+}
+
+template<class R,
+    class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
+    _bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2, B3, B4, B5, B6, B7, B8), typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
+    BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6, B7, B8), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+{
+    typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6, B7, B8);
+    typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8));
+}
+
+template<class R,
+    class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8, class B9,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
+    _bi::bind_t<R, BOOST_BIND_ST R (BOOST_BIND_CC *) (B1, B2, B3, B4, B5, B6, B7, B8, B9), typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
+    BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6, B7, B8, B9), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+{
+    typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6, B7, B8, B9);
+    typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
+    return _bi::bind_t<R, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9));
+}
diff --git a/third_party/boost/boost/bind/bind_mf2_cc.hpp b/third_party/boost/boost/bind/bind_mf2_cc.hpp
new file mode 100644
index 0000000..66476bc
--- /dev/null
+++ b/third_party/boost/boost/bind/bind_mf2_cc.hpp
@@ -0,0 +1,228 @@
+//
+//  bind/bind_mf2_cc.hpp - member functions, type<> syntax
+//
+//  Do not include this header directly.
+//
+//  Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
+//  Copyright (c) 2008 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+//
+//  See http://www.boost.org/libs/bind/bind.html for documentation.
+//
+
+// 0
+
+template<class Rt2, class R, class T,
+    class A1>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf0)<R, T>, typename _bi::list_av_1<A1>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (), A1 a1)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf0)<R, T> F;
+    typedef typename _bi::list_av_1<A1>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1));
+}
+
+template<class Rt2, class R, class T,
+    class A1>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T>, typename _bi::list_av_1<A1>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) () const, A1 a1)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T> F;
+    typedef typename _bi::list_av_1<A1>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1));
+}
+
+// 1
+
+template<class Rt2, class R, class T,
+    class B1,
+    class A1, class A2>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1), A1 a1, A2 a2)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1> F;
+    typedef typename _bi::list_av_2<A1, A2>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2));
+}
+
+template<class Rt2, class R, class T,
+    class B1,
+    class A1, class A2>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1) const, A1 a1, A2 a2)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1> F;
+    typedef typename _bi::list_av_2<A1, A2>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2));
+}
+
+// 2
+
+template<class Rt2, class R, class T,
+    class B1, class B2,
+    class A1, class A2, class A3>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2), A1 a1, A2 a2, A3 a3)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2> F;
+    typedef typename _bi::list_av_3<A1, A2, A3>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2,
+    class A1, class A2, class A3>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2) const, A1 a1, A2 a2, A3 a3)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2> F;
+    typedef typename _bi::list_av_3<A1, A2, A3>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3));
+}
+
+// 3
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3,
+    class A1, class A2, class A3, class A4>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3), A1 a1, A2 a2, A3 a3, A4 a4)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3> F;
+    typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3,
+    class A1, class A2, class A3, class A4>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const, A1 a1, A2 a2, A3 a3, A4 a4)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3> F;
+    typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4));
+}
+
+// 4
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4,
+    class A1, class A2, class A3, class A4, class A5>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4> F;
+    typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4,
+    class A1, class A2, class A3, class A4, class A5>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4> F;
+    typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5));
+}
+
+// 5
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4, class B5,
+    class A1, class A2, class A3, class A4, class A5, class A6>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5> F;
+    typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4, class B5,
+    class A1, class A2, class A3, class A4, class A5, class A6>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5> F;
+    typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6));
+}
+
+// 6
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6> F;
+    typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6> F;
+    typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7));
+}
+
+// 7
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6, class B7,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7> F;
+    typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6, class B7,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7> F;
+    typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8));
+}
+
+// 8
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F;
+    typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
+    BOOST_BIND(boost::type<Rt2>, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F;
+    typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9));
+}
diff --git a/third_party/boost/boost/bind/bind_mf_cc.hpp b/third_party/boost/boost/bind/bind_mf_cc.hpp
new file mode 100644
index 0000000..e149384
--- /dev/null
+++ b/third_party/boost/boost/bind/bind_mf_cc.hpp
@@ -0,0 +1,441 @@
+//
+//  bind/bind_mf_cc.hpp - support for different calling conventions
+//
+//  Do not include this header directly.
+//
+//  Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//  See http://www.boost.org/libs/bind/bind.html for documentation.
+//
+
+// 0
+
+template<class R, class T,
+    class A1>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf0)<R, T>, typename _bi::list_av_1<A1>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (), A1 a1)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf0)<R, T> F;
+    typedef typename _bi::list_av_1<A1>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1));
+}
+
+template<class R, class T,
+    class A1>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T>, typename _bi::list_av_1<A1>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () const, A1 a1)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T> F;
+    typedef typename _bi::list_av_1<A1>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1));
+}
+
+template<class Rt2, class R, class T,
+    class A1>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf0)<R, T>, typename _bi::list_av_1<A1>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (), A1 a1)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf0)<R, T> F;
+    typedef typename _bi::list_av_1<A1>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1));
+}
+
+template<class Rt2, class R, class T,
+    class A1>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T>, typename _bi::list_av_1<A1>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () const, A1 a1)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf0)<R, T> F;
+    typedef typename _bi::list_av_1<A1>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1));
+}
+
+// 1
+
+template<class R, class T,
+    class B1,
+    class A1, class A2>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1), A1 a1, A2 a2)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1> F;
+    typedef typename _bi::list_av_2<A1, A2>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2));
+}
+
+template<class R, class T,
+    class B1,
+    class A1, class A2>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) const, A1 a1, A2 a2)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1> F;
+    typedef typename _bi::list_av_2<A1, A2>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2));
+}
+
+template<class Rt2, class R, class T,
+    class B1,
+    class A1, class A2>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1), A1 a1, A2 a2)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf1)<R, T, B1> F;
+    typedef typename _bi::list_av_2<A1, A2>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2));
+}
+
+template<class Rt2, class R, class T,
+    class B1,
+    class A1, class A2>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1>, typename _bi::list_av_2<A1, A2>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) const, A1 a1, A2 a2)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf1)<R, T, B1> F;
+    typedef typename _bi::list_av_2<A1, A2>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2));
+}
+
+// 2
+
+template<class R, class T,
+    class B1, class B2,
+    class A1, class A2, class A3>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2), A1 a1, A2 a2, A3 a3)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2> F;
+    typedef typename _bi::list_av_3<A1, A2, A3>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3));
+}
+
+template<class R, class T,
+    class B1, class B2,
+    class A1, class A2, class A3>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) const, A1 a1, A2 a2, A3 a3)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2> F;
+    typedef typename _bi::list_av_3<A1, A2, A3>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2,
+    class A1, class A2, class A3>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2), A1 a1, A2 a2, A3 a3)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf2)<R, T, B1, B2> F;
+    typedef typename _bi::list_av_3<A1, A2, A3>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2,
+    class A1, class A2, class A3>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2>, typename _bi::list_av_3<A1, A2, A3>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) const, A1 a1, A2 a2, A3 a3)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf2)<R, T, B1, B2> F;
+    typedef typename _bi::list_av_3<A1, A2, A3>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3));
+}
+
+// 3
+
+template<class R, class T,
+    class B1, class B2, class B3,
+    class A1, class A2, class A3, class A4>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3), A1 a1, A2 a2, A3 a3, A4 a4)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3> F;
+    typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4));
+}
+
+template<class R, class T,
+    class B1, class B2, class B3,
+    class A1, class A2, class A3, class A4>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const, A1 a1, A2 a2, A3 a3, A4 a4)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3> F;
+    typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3,
+    class A1, class A2, class A3, class A4>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3), A1 a1, A2 a2, A3 a3, A4 a4)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf3)<R, T, B1, B2, B3> F;
+    typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3,
+    class A1, class A2, class A3, class A4>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3>, typename _bi::list_av_4<A1, A2, A3, A4>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const, A1 a1, A2 a2, A3 a3, A4 a4)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf3)<R, T, B1, B2, B3> F;
+    typedef typename _bi::list_av_4<A1, A2, A3, A4>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4));
+}
+
+// 4
+
+template<class R, class T,
+    class B1, class B2, class B3, class B4,
+    class A1, class A2, class A3, class A4, class A5>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4> F;
+    typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5));
+}
+
+template<class R, class T,
+    class B1, class B2, class B3, class B4,
+    class A1, class A2, class A3, class A4, class A5>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4> F;
+    typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4,
+    class A1, class A2, class A3, class A4, class A5>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf4)<R, T, B1, B2, B3, B4> F;
+    typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4,
+    class A1, class A2, class A3, class A4, class A5>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4>, typename _bi::list_av_5<A1, A2, A3, A4, A5>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf4)<R, T, B1, B2, B3, B4> F;
+    typedef typename _bi::list_av_5<A1, A2, A3, A4, A5>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5));
+}
+
+// 5
+
+template<class R, class T,
+    class B1, class B2, class B3, class B4, class B5,
+    class A1, class A2, class A3, class A4, class A5, class A6>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5> F;
+    typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6));
+}
+
+template<class R, class T,
+    class B1, class B2, class B3, class B4, class B5,
+    class A1, class A2, class A3, class A4, class A5, class A6>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5> F;
+    typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4, class B5,
+    class A1, class A2, class A3, class A4, class A5, class A6>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf5)<R, T, B1, B2, B3, B4, B5> F;
+    typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4, class B5,
+    class A1, class A2, class A3, class A4, class A5, class A6>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5>, typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf5)<R, T, B1, B2, B3, B4, B5> F;
+    typedef typename _bi::list_av_6<A1, A2, A3, A4, A5, A6>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6));
+}
+
+// 6
+
+template<class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6> F;
+    typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7));
+}
+
+template<class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6> F;
+    typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf6)<R, T, B1, B2, B3, B4, B5, B6> F;
+    typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6>, typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf6)<R, T, B1, B2, B3, B4, B5, B6> F;
+    typedef typename _bi::list_av_7<A1, A2, A3, A4, A5, A6, A7>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7));
+}
+
+// 7
+
+template<class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6, class B7,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7> F;
+    typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8));
+}
+
+template<class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6, class B7,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7> F;
+    typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6, class B7,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf7)<R, T, B1, B2, B3, B4, B5, B6, B7> F;
+    typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6, class B7,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7>, typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf7)<R, T, B1, B2, B3, B4, B5, B6, B7> F;
+    typedef typename _bi::list_av_8<A1, A2, A3, A4, A5, A6, A7, A8>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8));
+}
+
+// 8
+
+template<class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F;
+    typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9));
+}
+
+template<class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
+    _bi::bind_t<R, _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
+    BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F;
+    typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
+    return _bi::bind_t<R, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(mf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F;
+    typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9));
+}
+
+template<class Rt2, class R, class T,
+    class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8,
+    class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
+    typename boost::enable_if_c<!boost::core::is_same<Rt2, R>::value,
+    _bi::bind_t<Rt2, _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8>, typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type>
+    >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) const, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+{
+    typedef _mfi::BOOST_BIND_MF_NAME(cmf8)<R, T, B1, B2, B3, B4, B5, B6, B7, B8> F;
+    typedef typename _bi::list_av_9<A1, A2, A3, A4, A5, A6, A7, A8, A9>::type list_type;
+    return _bi::bind_t<Rt2, F, list_type>(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9));
+}
diff --git a/third_party/boost/boost/bind/bind_template.hpp b/third_party/boost/boost/bind/bind_template.hpp
new file mode 100644
index 0000000..411d20c
--- /dev/null
+++ b/third_party/boost/boost/bind/bind_template.hpp
@@ -0,0 +1,345 @@
+//
+//  bind/bind_template.hpp
+//
+//  Do not include this header directly.
+//
+//  Copyright (c) 2001-2004 Peter Dimov and Multi Media Ltd.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//  See http://www.boost.org/libs/bind/bind.html for documentation.
+//
+
+    typedef typename result_traits<R, F>::type result_type;
+
+    result_type operator()()
+    {
+        list0 a;
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    result_type operator()() const
+    {
+        list0 a;
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1> result_type operator()(A1 & a1)
+    {
+        list1<A1 &> a(a1);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1> result_type operator()(A1 & a1) const
+    {
+        list1<A1 &> a(a1);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
+ && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
+
+    template<class A1> result_type operator()(A1 const & a1)
+    {
+        list1<A1 const &> a(a1);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1> result_type operator()(A1 const & a1) const
+    {
+        list1<A1 const &> a(a1);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#endif
+
+    template<class A1, class A2> result_type operator()(A1 & a1, A2 & a2)
+    {
+        list2<A1 &, A2 &> a(a1, a2);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2> result_type operator()(A1 & a1, A2 & a2) const
+    {
+        list2<A1 &, A2 &> a(a1, a2);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
+ && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
+
+    template<class A1, class A2> result_type operator()(A1 const & a1, A2 & a2)
+    {
+        list2<A1 const &, A2 &> a(a1, a2);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2> result_type operator()(A1 const & a1, A2 & a2) const
+    {
+        list2<A1 const &, A2 &> a(a1, a2);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+
+    template<class A1, class A2> result_type operator()(A1 & a1, A2 const & a2)
+    {
+        list2<A1 &, A2 const &> a(a1, a2);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2> result_type operator()(A1 & a1, A2 const & a2) const
+    {
+        list2<A1 &, A2 const &> a(a1, a2);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+
+    template<class A1, class A2> result_type operator()(A1 const & a1, A2 const & a2)
+    {
+        list2<A1 const &, A2 const &> a(a1, a2);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2> result_type operator()(A1 const & a1, A2 const & a2) const
+    {
+        list2<A1 const &, A2 const &> a(a1, a2);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#endif
+
+    template<class A1, class A2, class A3> result_type operator()(A1 & a1, A2 & a2, A3 & a3)
+    {
+        list3<A1 &, A2 &, A3 &> a(a1, a2, a3);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2, class A3> result_type operator()(A1 & a1, A2 & a2, A3 & a3) const
+    {
+        list3<A1 &, A2 &, A3 &> a(a1, a2, a3);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
+ && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
+
+    template<class A1, class A2, class A3> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3)
+    {
+        list3<A1 const &, A2 const &, A3 const &> a(a1, a2, a3);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2, class A3> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3) const
+    {
+        list3<A1 const &, A2 const &, A3 const &> a(a1, a2, a3);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#endif
+
+    template<class A1, class A2, class A3, class A4> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4)
+    {
+        list4<A1 &, A2 &, A3 &, A4 &> a(a1, a2, a3, a4);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2, class A3, class A4> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4) const
+    {
+        list4<A1 &, A2 &, A3 &, A4 &> a(a1, a2, a3, a4);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
+ && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
+
+    template<class A1, class A2, class A3, class A4> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4)
+    {
+        list4<A1 const &, A2 const &, A3 const &, A4 const &> a(a1, a2, a3, a4);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2, class A3, class A4> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4) const
+    {
+        list4<A1 const &, A2 const &, A3 const &, A4 const &> a(a1, a2, a3, a4);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#endif
+
+    template<class A1, class A2, class A3, class A4, class A5> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5)
+    {
+        list5<A1 &, A2 &, A3 &, A4 &, A5 &> a(a1, a2, a3, a4, a5);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5) const
+    {
+        list5<A1 &, A2 &, A3 &, A4 &, A5 &> a(a1, a2, a3, a4, a5);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
+ && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
+
+    template<class A1, class A2, class A3, class A4, class A5> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5)
+    {
+        list5<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &> a(a1, a2, a3, a4, a5);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5) const
+    {
+        list5<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &> a(a1, a2, a3, a4, a5);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#endif
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6)
+    {
+        list6<A1 &, A2 &, A3 &, A4 &, A5 &, A6 &> a(a1, a2, a3, a4, a5, a6);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6) const
+    {
+        list6<A1 &, A2 &, A3 &, A4 &, A5 &, A6 &> a(a1, a2, a3, a4, a5, a6);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
+ && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6)
+    {
+        list6<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &, A6 const &> a(a1, a2, a3, a4, a5, a6);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6) const
+    {
+        list6<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &, A6 const &> a(a1, a2, a3, a4, a5, a6);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#endif
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7)
+    {
+        list7<A1 &, A2 &, A3 &, A4 &, A5 &, A6 &, A7 &> a(a1, a2, a3, a4, a5, a6, a7);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7) const
+    {
+        list7<A1 &, A2 &, A3 &, A4 &, A5 &, A6 &, A7 &> a(a1, a2, a3, a4, a5, a6, a7);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
+ && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7)
+    {
+        list7<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &, A6 const &, A7 const &> a(a1, a2, a3, a4, a5, a6, a7);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7) const
+    {
+        list7<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &, A6 const &, A7 const &> a(a1, a2, a3, a4, a5, a6, a7);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#endif
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8)
+    {
+        list8<A1 &, A2 &, A3 &, A4 &, A5 &, A6 &, A7 &, A8 &> a(a1, a2, a3, a4, a5, a6, a7, a8);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8) const
+    {
+        list8<A1 &, A2 &, A3 &, A4 &, A5 &, A6 &, A7 &, A8 &> a(a1, a2, a3, a4, a5, a6, a7, a8);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
+ && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8)
+    {
+        list8<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &, A6 const &, A7 const &, A8 const &> a(a1, a2, a3, a4, a5, a6, a7, a8);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8) const
+    {
+        list8<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &, A6 const &, A7 const &, A8 const &> a(a1, a2, a3, a4, a5, a6, a7, a8);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#endif
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8, A9 & a9)
+    {
+        list9<A1 &, A2 &, A3 &, A4 &, A5 &, A6 &, A7 &, A8 &, A9 &> a(a1, a2, a3, a4, a5, a6, a7, a8, a9);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> result_type operator()(A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8, A9 & a9) const
+    {
+        list9<A1 &, A2 &, A3 &, A4 &, A5 &, A6 &, A7 &, A8 &, A9 &> a(a1, a2, a3, a4, a5, a6, a7, a8, a9);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \
+ && !BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9)
+    {
+        list9<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &, A6 const &, A7 const &, A8 const &, A9 const &> a(a1, a2, a3, a4, a5, a6, a7, a8, a9);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> result_type operator()(A1 const & a1, A2 const & a2, A3 const & a3, A4 const & a4, A5 const & a5, A6 const & a6, A7 const & a7, A8 const & a8, A9 const & a9) const
+    {
+        list9<A1 const &, A2 const &, A3 const &, A4 const &, A5 const &, A6 const &, A7 const &, A8 const &, A9 const &> a(a1, a2, a3, a4, a5, a6, a7, a8, a9);
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+#endif
+
+    template<class A> result_type eval(A & a)
+    {
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class A> result_type eval(A & a) const
+    {
+        BOOST_BIND_RETURN l_(type<result_type>(), f_, a, 0);
+    }
+
+    template<class V> void accept(V & v) const
+    {
+#if !defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) && !defined( __BORLANDC__ )
+
+        using boost::visit_each;
+
+#endif
+        BOOST_BIND_VISIT_EACH(v, f_, 0);
+        l_.accept(v);
+    }
+
+    bool compare(this_type const & rhs) const
+    {
+        return ref_compare(f_, rhs.f_, 0) && l_ == rhs.l_;
+    }
+
+private:
+
+    F f_;
+    L l_;
diff --git a/third_party/boost/boost/bind/mem_fn.hpp b/third_party/boost/boost/bind/mem_fn.hpp
new file mode 100644
index 0000000..e3154e3
--- /dev/null
+++ b/third_party/boost/boost/bind/mem_fn.hpp
@@ -0,0 +1,389 @@
+#ifndef BOOST_BIND_MEM_FN_HPP_INCLUDED
+#define BOOST_BIND_MEM_FN_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  mem_fn.hpp - a generalization of std::mem_fun[_ref]
+//
+//  Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
+//  Copyright (c) 2001 David Abrahams
+//  Copyright (c) 2003-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//  See http://www.boost.org/libs/bind/mem_fn.html for documentation.
+//
+
+#include <boost/config.hpp>
+#include <boost/get_pointer.hpp>
+#include <boost/detail/workaround.hpp>
+
+namespace boost
+{
+
+#if defined(BOOST_NO_VOID_RETURNS)
+
+#define BOOST_MEM_FN_CLASS_F , class F
+#define BOOST_MEM_FN_TYPEDEF(X)
+
+namespace _mfi // mem_fun_impl
+{
+
+template<class V> struct mf
+{
+
+#define BOOST_MEM_FN_RETURN return
+
+#define BOOST_MEM_FN_NAME(X) inner_##X
+#define BOOST_MEM_FN_CC
+
+#include <boost/bind/mem_fn_template.hpp>
+
+#undef BOOST_MEM_FN_CC
+#undef BOOST_MEM_FN_NAME
+
+#ifdef BOOST_MEM_FN_ENABLE_CDECL
+
+#define BOOST_MEM_FN_NAME(X) inner_##X##_cdecl
+#define BOOST_MEM_FN_CC __cdecl
+
+#include <boost/bind/mem_fn_template.hpp>
+
+#undef BOOST_MEM_FN_CC
+#undef BOOST_MEM_FN_NAME
+
+#endif
+
+#ifdef BOOST_MEM_FN_ENABLE_STDCALL
+
+#define BOOST_MEM_FN_NAME(X) inner_##X##_stdcall
+#define BOOST_MEM_FN_CC __stdcall
+
+#include <boost/bind/mem_fn_template.hpp>
+
+#undef BOOST_MEM_FN_CC
+#undef BOOST_MEM_FN_NAME
+
+#endif
+
+#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
+
+#define BOOST_MEM_FN_NAME(X) inner_##X##_fastcall
+#define BOOST_MEM_FN_CC __fastcall
+
+#include <boost/bind/mem_fn_template.hpp>
+
+#undef BOOST_MEM_FN_CC
+#undef BOOST_MEM_FN_NAME
+
+#endif
+
+#undef BOOST_MEM_FN_RETURN
+
+}; // struct mf<V>
+
+template<> struct mf<void>
+{
+
+#define BOOST_MEM_FN_RETURN
+
+#define BOOST_MEM_FN_NAME(X) inner_##X
+#define BOOST_MEM_FN_CC
+
+#include <boost/bind/mem_fn_template.hpp>
+
+#undef BOOST_MEM_FN_CC
+#undef BOOST_MEM_FN_NAME
+
+#ifdef BOOST_MEM_FN_ENABLE_CDECL
+
+#define BOOST_MEM_FN_NAME(X) inner_##X##_cdecl
+#define BOOST_MEM_FN_CC __cdecl
+
+#include <boost/bind/mem_fn_template.hpp>
+
+#undef BOOST_MEM_FN_CC
+#undef BOOST_MEM_FN_NAME
+
+#endif
+
+#ifdef BOOST_MEM_FN_ENABLE_STDCALL
+
+#define BOOST_MEM_FN_NAME(X) inner_##X##_stdcall
+#define BOOST_MEM_FN_CC __stdcall
+
+#include <boost/bind/mem_fn_template.hpp>
+
+#undef BOOST_MEM_FN_CC
+#undef BOOST_MEM_FN_NAME
+
+#endif
+
+#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
+
+#define BOOST_MEM_FN_NAME(X) inner_##X##_fastcall
+#define BOOST_MEM_FN_CC __fastcall
+
+#include <boost/bind/mem_fn_template.hpp>
+
+#undef BOOST_MEM_FN_CC
+#undef BOOST_MEM_FN_NAME
+
+#endif
+
+#undef BOOST_MEM_FN_RETURN
+
+}; // struct mf<void>
+
+#undef BOOST_MEM_FN_CLASS_F
+#undef BOOST_MEM_FN_TYPEDEF_F
+
+#define BOOST_MEM_FN_NAME(X) X
+#define BOOST_MEM_FN_NAME2(X) inner_##X
+#define BOOST_MEM_FN_CC
+
+#include <boost/bind/mem_fn_vw.hpp>
+
+#undef BOOST_MEM_FN_NAME
+#undef BOOST_MEM_FN_NAME2
+#undef BOOST_MEM_FN_CC
+
+#ifdef BOOST_MEM_FN_ENABLE_CDECL
+
+#define BOOST_MEM_FN_NAME(X) X##_cdecl
+#define BOOST_MEM_FN_NAME2(X) inner_##X##_cdecl
+#define BOOST_MEM_FN_CC __cdecl
+
+#include <boost/bind/mem_fn_vw.hpp>
+
+#undef BOOST_MEM_FN_NAME
+#undef BOOST_MEM_FN_NAME2
+#undef BOOST_MEM_FN_CC
+
+#endif
+
+#ifdef BOOST_MEM_FN_ENABLE_STDCALL
+
+#define BOOST_MEM_FN_NAME(X) X##_stdcall
+#define BOOST_MEM_FN_NAME2(X) inner_##X##_stdcall
+#define BOOST_MEM_FN_CC __stdcall
+
+#include <boost/bind/mem_fn_vw.hpp>
+
+#undef BOOST_MEM_FN_NAME
+#undef BOOST_MEM_FN_NAME2
+#undef BOOST_MEM_FN_CC
+
+#endif
+
+#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
+
+#define BOOST_MEM_FN_NAME(X) X##_fastcall
+#define BOOST_MEM_FN_NAME2(X) inner_##X##_fastcall
+#define BOOST_MEM_FN_CC __fastcall
+
+#include <boost/bind/mem_fn_vw.hpp>
+
+#undef BOOST_MEM_FN_NAME
+#undef BOOST_MEM_FN_NAME2
+#undef BOOST_MEM_FN_CC
+
+#endif
+
+} // namespace _mfi
+
+#else // #ifdef BOOST_NO_VOID_RETURNS
+
+#define BOOST_MEM_FN_CLASS_F
+#define BOOST_MEM_FN_TYPEDEF(X) typedef X;
+
+namespace _mfi
+{
+
+#define BOOST_MEM_FN_RETURN return
+
+#define BOOST_MEM_FN_NAME(X) X
+#define BOOST_MEM_FN_CC
+
+#include <boost/bind/mem_fn_template.hpp>
+
+#undef BOOST_MEM_FN_CC
+#undef BOOST_MEM_FN_NAME
+
+#ifdef BOOST_MEM_FN_ENABLE_CDECL
+
+#define BOOST_MEM_FN_NAME(X) X##_cdecl
+#define BOOST_MEM_FN_CC __cdecl
+
+#include <boost/bind/mem_fn_template.hpp>
+
+#undef BOOST_MEM_FN_CC
+#undef BOOST_MEM_FN_NAME
+
+#endif
+
+#ifdef BOOST_MEM_FN_ENABLE_STDCALL
+
+#define BOOST_MEM_FN_NAME(X) X##_stdcall
+#define BOOST_MEM_FN_CC __stdcall
+
+#include <boost/bind/mem_fn_template.hpp>
+
+#undef BOOST_MEM_FN_CC
+#undef BOOST_MEM_FN_NAME
+
+#endif
+
+#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
+
+#define BOOST_MEM_FN_NAME(X) X##_fastcall
+#define BOOST_MEM_FN_CC __fastcall
+
+#include <boost/bind/mem_fn_template.hpp>
+
+#undef BOOST_MEM_FN_CC
+#undef BOOST_MEM_FN_NAME
+
+#endif
+
+#undef BOOST_MEM_FN_RETURN
+
+} // namespace _mfi
+
+#undef BOOST_MEM_FN_CLASS_F
+#undef BOOST_MEM_FN_TYPEDEF
+
+#endif // #ifdef BOOST_NO_VOID_RETURNS
+
+#define BOOST_MEM_FN_NAME(X) X
+#define BOOST_MEM_FN_CC
+
+#include <boost/bind/mem_fn_cc.hpp>
+
+#undef BOOST_MEM_FN_NAME
+#undef BOOST_MEM_FN_CC
+
+#ifdef BOOST_MEM_FN_ENABLE_CDECL
+
+#define BOOST_MEM_FN_NAME(X) X##_cdecl
+#define BOOST_MEM_FN_CC __cdecl
+
+#include <boost/bind/mem_fn_cc.hpp>
+
+#undef BOOST_MEM_FN_NAME
+#undef BOOST_MEM_FN_CC
+
+#endif
+
+#ifdef BOOST_MEM_FN_ENABLE_STDCALL
+
+#define BOOST_MEM_FN_NAME(X) X##_stdcall
+#define BOOST_MEM_FN_CC __stdcall
+
+#include <boost/bind/mem_fn_cc.hpp>
+
+#undef BOOST_MEM_FN_NAME
+#undef BOOST_MEM_FN_CC
+
+#endif
+
+#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
+
+#define BOOST_MEM_FN_NAME(X) X##_fastcall
+#define BOOST_MEM_FN_CC __fastcall
+
+#include <boost/bind/mem_fn_cc.hpp>
+
+#undef BOOST_MEM_FN_NAME
+#undef BOOST_MEM_FN_CC
+
+#endif
+
+// data member support
+
+namespace _mfi
+{
+
+template<class R, class T> class dm
+{
+public:
+
+    typedef R const & result_type;
+    typedef T const * argument_type;
+
+private:
+
+    typedef R (T::*F);
+    F f_;
+
+    template<class U> R const & call(U & u, T const *) const
+    {
+        return (u.*f_);
+    }
+
+    template<class U> R const & call(U & u, void const *) const
+    {
+        return (get_pointer(u)->*f_);
+    }
+
+public:
+
+    explicit dm(F f): f_(f) {}
+
+    R & operator()(T * p) const
+    {
+        return (p->*f_);
+    }
+
+    R const & operator()(T const * p) const
+    {
+        return (p->*f_);
+    }
+
+    template<class U> R const & operator()(U const & u) const
+    {
+        return call(u, &u);
+    }
+
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && !BOOST_WORKAROUND(__MWERKS__, < 0x3200)
+
+    R & operator()(T & t) const
+    {
+        return (t.*f_);
+    }
+
+    R const & operator()(T const & t) const
+    {
+        return (t.*f_);
+    }
+
+#endif
+
+    bool operator==(dm const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(dm const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+} // namespace _mfi
+
+template<class R, class T> _mfi::dm<R, T> mem_fn(R T::*f)
+{
+    return _mfi::dm<R, T>(f);
+}
+
+} // namespace boost
+
+#endif // #ifndef BOOST_BIND_MEM_FN_HPP_INCLUDED
diff --git a/third_party/boost/boost/bind/mem_fn_cc.hpp b/third_party/boost/boost/bind/mem_fn_cc.hpp
new file mode 100644
index 0000000..8b6ea0b
--- /dev/null
+++ b/third_party/boost/boost/bind/mem_fn_cc.hpp
@@ -0,0 +1,103 @@
+//
+//  bind/mem_fn_cc.hpp - support for different calling conventions
+//
+//  Do not include this header directly.
+//
+//  Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//  See http://www.boost.org/libs/bind/mem_fn.html for documentation.
+//
+
+template<class R, class T> _mfi::BOOST_MEM_FN_NAME(mf0)<R, T> mem_fn(R (BOOST_MEM_FN_CC T::*f) ())
+{
+    return _mfi::BOOST_MEM_FN_NAME(mf0)<R, T>(f);
+}
+
+template<class R, class T> _mfi::BOOST_MEM_FN_NAME(cmf0)<R, T> mem_fn(R (BOOST_MEM_FN_CC T::*f) () const)
+{
+    return _mfi::BOOST_MEM_FN_NAME(cmf0)<R, T>(f);
+}
+
+template<class R, class T, class A1> _mfi::BOOST_MEM_FN_NAME(mf1)<R, T, A1> mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1))
+{
+    return _mfi::BOOST_MEM_FN_NAME(mf1)<R, T, A1>(f);
+}
+
+template<class R, class T, class A1> _mfi::BOOST_MEM_FN_NAME(cmf1)<R, T, A1> mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1) const)
+{
+    return _mfi::BOOST_MEM_FN_NAME(cmf1)<R, T, A1>(f);
+}
+
+template<class R, class T, class A1, class A2> _mfi::BOOST_MEM_FN_NAME(mf2)<R, T, A1, A2> mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2))
+{
+    return _mfi::BOOST_MEM_FN_NAME(mf2)<R, T, A1, A2>(f);
+}
+
+template<class R, class T, class A1, class A2> _mfi::BOOST_MEM_FN_NAME(cmf2)<R, T, A1, A2> mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2) const)
+{
+    return _mfi::BOOST_MEM_FN_NAME(cmf2)<R, T, A1, A2>(f);
+}
+
+template<class R, class T, class A1, class A2, class A3> _mfi::BOOST_MEM_FN_NAME(mf3)<R, T, A1, A2, A3> mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3))
+{
+    return _mfi::BOOST_MEM_FN_NAME(mf3)<R, T, A1, A2, A3>(f);
+}
+
+template<class R, class T, class A1, class A2, class A3> _mfi::BOOST_MEM_FN_NAME(cmf3)<R, T, A1, A2, A3> mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3) const)
+{
+    return _mfi::BOOST_MEM_FN_NAME(cmf3)<R, T, A1, A2, A3>(f);
+}
+
+template<class R, class T, class A1, class A2, class A3, class A4> _mfi::BOOST_MEM_FN_NAME(mf4)<R, T, A1, A2, A3, A4> mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4))
+{
+    return _mfi::BOOST_MEM_FN_NAME(mf4)<R, T, A1, A2, A3, A4>(f);
+}
+
+template<class R, class T, class A1, class A2, class A3, class A4> _mfi::BOOST_MEM_FN_NAME(cmf4)<R, T, A1, A2, A3, A4> mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4) const)
+{
+    return _mfi::BOOST_MEM_FN_NAME(cmf4)<R, T, A1, A2, A3, A4>(f);
+}
+
+template<class R, class T, class A1, class A2, class A3, class A4, class A5> _mfi::BOOST_MEM_FN_NAME(mf5)<R, T, A1, A2, A3, A4, A5> mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5))
+{
+    return _mfi::BOOST_MEM_FN_NAME(mf5)<R, T, A1, A2, A3, A4, A5>(f);
+}
+
+template<class R, class T, class A1, class A2, class A3, class A4, class A5> _mfi::BOOST_MEM_FN_NAME(cmf5)<R, T, A1, A2, A3, A4, A5> mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5) const)
+{
+    return _mfi::BOOST_MEM_FN_NAME(cmf5)<R, T, A1, A2, A3, A4, A5>(f);
+}
+
+template<class R, class T, class A1, class A2, class A3, class A4, class A5, class A6> _mfi::BOOST_MEM_FN_NAME(mf6)<R, T, A1, A2, A3, A4, A5, A6> mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6))
+{
+    return _mfi::BOOST_MEM_FN_NAME(mf6)<R, T, A1, A2, A3, A4, A5, A6>(f);
+}
+
+template<class R, class T, class A1, class A2, class A3, class A4, class A5, class A6> _mfi::BOOST_MEM_FN_NAME(cmf6)<R, T, A1, A2, A3, A4, A5, A6> mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6) const)
+{
+    return _mfi::BOOST_MEM_FN_NAME(cmf6)<R, T, A1, A2, A3, A4, A5, A6>(f);
+}
+
+template<class R, class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7> _mfi::BOOST_MEM_FN_NAME(mf7)<R, T, A1, A2, A3, A4, A5, A6, A7> mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6, A7))
+{
+    return _mfi::BOOST_MEM_FN_NAME(mf7)<R, T, A1, A2, A3, A4, A5, A6, A7>(f);
+}
+
+template<class R, class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7> _mfi::BOOST_MEM_FN_NAME(cmf7)<R, T, A1, A2, A3, A4, A5, A6, A7> mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6, A7) const)
+{
+    return _mfi::BOOST_MEM_FN_NAME(cmf7)<R, T, A1, A2, A3, A4, A5, A6, A7>(f);
+}
+
+template<class R, class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> _mfi::BOOST_MEM_FN_NAME(mf8)<R, T, A1, A2, A3, A4, A5, A6, A7, A8> mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6, A7, A8))
+{
+    return _mfi::BOOST_MEM_FN_NAME(mf8)<R, T, A1, A2, A3, A4, A5, A6, A7, A8>(f);
+}
+
+template<class R, class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> _mfi::BOOST_MEM_FN_NAME(cmf8)<R, T, A1, A2, A3, A4, A5, A6, A7, A8> mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6, A7, A8) const)
+{
+    return _mfi::BOOST_MEM_FN_NAME(cmf8)<R, T, A1, A2, A3, A4, A5, A6, A7, A8>(f);
+}
diff --git a/third_party/boost/boost/bind/mem_fn_template.hpp b/third_party/boost/boost/bind/mem_fn_template.hpp
new file mode 100644
index 0000000..ff65b4b
--- /dev/null
+++ b/third_party/boost/boost/bind/mem_fn_template.hpp
@@ -0,0 +1,1047 @@
+//
+//  bind/mem_fn_template.hpp
+//
+//  Do not include this header directly
+//
+//  Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//  See http://www.boost.org/libs/bind/mem_fn.html for documentation.
+//
+
+#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
+# define BOOST_MEM_FN_ENABLE_CONST_OVERLOADS
+#endif
+
+// mf0
+
+template<class R, class T BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(mf0)
+{
+public:
+
+    typedef R result_type;
+    typedef T * argument_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) ())
+    F f_;
+
+    template<class U> R call(U & u, T const *) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)();
+    }
+
+    template<class U> R call(U & u, void const *) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)();
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(mf0)(F f): f_(f) {}
+
+    R operator()(T * p) const
+    {
+        BOOST_MEM_FN_RETURN (p->*f_)();
+    }
+
+    template<class U> R operator()(U & u) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p);
+    }
+
+#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS
+
+    template<class U> R operator()(U const & u) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p);
+    }
+
+#endif
+
+    R operator()(T & t) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)();
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(mf0) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(mf0) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// cmf0
+
+template<class R, class T BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(cmf0)
+{
+public:
+
+    typedef R result_type;
+    typedef T const * argument_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) () const)
+    F f_;
+
+    template<class U> R call(U & u, T const *) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)();
+    }
+
+    template<class U> R call(U & u, void const *) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)();
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(cmf0)(F f): f_(f) {}
+
+    template<class U> R operator()(U const & u) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p);
+    }
+
+    R operator()(T const & t) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)();
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(cmf0) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(cmf0) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// mf1
+
+template<class R, class T, class A1 BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(mf1)
+{
+public:
+
+    typedef R result_type;
+    typedef T * first_argument_type;
+    typedef A1 second_argument_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1))
+    F f_;
+
+    template<class U, class B1> R call(U & u, T const *, B1 & b1) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)(b1);
+    }
+
+    template<class U, class B1> R call(U & u, void const *, B1 & b1) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1);
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(mf1)(F f): f_(f) {}
+
+    R operator()(T * p, A1 a1) const
+    {
+        BOOST_MEM_FN_RETURN (p->*f_)(a1);
+    }
+
+    template<class U> R operator()(U & u, A1 a1) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1);
+    }
+
+#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS
+
+    template<class U> R operator()(U const & u, A1 a1) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1);
+    }
+
+#endif
+
+    R operator()(T & t, A1 a1) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)(a1);
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(mf1) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(mf1) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// cmf1
+
+template<class R, class T, class A1 BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(cmf1)
+{
+public:
+
+    typedef R result_type;
+    typedef T const * first_argument_type;
+    typedef A1 second_argument_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1) const)
+    F f_;
+
+    template<class U, class B1> R call(U & u, T const *, B1 & b1) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)(b1);
+    }
+
+    template<class U, class B1> R call(U & u, void const *, B1 & b1) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1);
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(cmf1)(F f): f_(f) {}
+
+    template<class U> R operator()(U const & u, A1 a1) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1);
+    }
+
+    R operator()(T const & t, A1 a1) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)(a1);
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(cmf1) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(cmf1) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// mf2
+
+template<class R, class T, class A1, class A2 BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(mf2)
+{
+public:
+
+    typedef R result_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2))
+    F f_;
+
+    template<class U, class B1, class B2> R call(U & u, T const *, B1 & b1, B2 & b2) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)(b1, b2);
+    }
+
+    template<class U, class B1, class B2> R call(U & u, void const *, B1 & b1, B2 & b2) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2);
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(mf2)(F f): f_(f) {}
+
+    R operator()(T * p, A1 a1, A2 a2) const
+    {
+        BOOST_MEM_FN_RETURN (p->*f_)(a1, a2);
+    }
+
+    template<class U> R operator()(U & u, A1 a1, A2 a2) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2);
+    }
+
+#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS
+
+    template<class U> R operator()(U const & u, A1 a1, A2 a2) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2);
+    }
+
+#endif
+
+    R operator()(T & t, A1 a1, A2 a2) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)(a1, a2);
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(mf2) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(mf2) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// cmf2
+
+template<class R, class T, class A1, class A2 BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(cmf2)
+{
+public:
+
+    typedef R result_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2) const)
+    F f_;
+
+    template<class U, class B1, class B2> R call(U & u, T const *, B1 & b1, B2 & b2) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)(b1, b2);
+    }
+
+    template<class U, class B1, class B2> R call(U & u, void const *, B1 & b1, B2 & b2) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2);
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(cmf2)(F f): f_(f) {}
+
+    template<class U> R operator()(U const & u, A1 a1, A2 a2) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2);
+    }
+
+    R operator()(T const & t, A1 a1, A2 a2) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)(a1, a2);
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(cmf2) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(cmf2) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// mf3
+
+template<class R, class T, class A1, class A2, class A3 BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(mf3)
+{
+public:
+
+    typedef R result_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3))
+    F f_;
+
+    template<class U, class B1, class B2, class B3> R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3);
+    }
+
+    template<class U, class B1, class B2, class B3> R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3);
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(mf3)(F f): f_(f) {}
+
+    R operator()(T * p, A1 a1, A2 a2, A3 a3) const
+    {
+        BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3);
+    }
+
+    template<class U> R operator()(U & u, A1 a1, A2 a2, A3 a3) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3);
+    }
+
+#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS
+
+    template<class U> R operator()(U const & u, A1 a1, A2 a2, A3 a3) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3);
+    }
+
+#endif
+
+    R operator()(T & t, A1 a1, A2 a2, A3 a3) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3);
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(mf3) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(mf3) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// cmf3
+
+template<class R, class T, class A1, class A2, class A3 BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(cmf3)
+{
+public:
+
+    typedef R result_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3) const)
+    F f_;
+
+    template<class U, class B1, class B2, class B3> R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3);
+    }
+
+    template<class U, class B1, class B2, class B3> R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3);
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(cmf3)(F f): f_(f) {}
+
+    template<class U> R operator()(U const & u, A1 a1, A2 a2, A3 a3) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3);
+    }
+
+    R operator()(T const & t, A1 a1, A2 a2, A3 a3) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3);
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(cmf3) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(cmf3) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// mf4
+
+template<class R, class T, class A1, class A2, class A3, class A4 BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(mf4)
+{
+public:
+
+    typedef R result_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4))
+    F f_;
+
+    template<class U, class B1, class B2, class B3, class B4> R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4);
+    }
+
+    template<class U, class B1, class B2, class B3, class B4> R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4);
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(mf4)(F f): f_(f) {}
+
+    R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4) const
+    {
+        BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4);
+    }
+
+    template<class U> R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4);
+    }
+
+#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS
+
+    template<class U> R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4);
+    }
+
+#endif
+
+    R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4);
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(mf4) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(mf4) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// cmf4
+
+template<class R, class T, class A1, class A2, class A3, class A4 BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(cmf4)
+{
+public:
+
+    typedef R result_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4) const)
+    F f_;
+
+    template<class U, class B1, class B2, class B3, class B4> R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4);
+    }
+
+    template<class U, class B1, class B2, class B3, class B4> R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4);
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(cmf4)(F f): f_(f) {}
+
+    template<class U> R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4);
+    }
+
+    R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4);
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(cmf4) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(cmf4) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// mf5
+
+template<class R, class T, class A1, class A2, class A3, class A4, class A5 BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(mf5)
+{
+public:
+
+    typedef R result_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5))
+    F f_;
+
+    template<class U, class B1, class B2, class B3, class B4, class B5> R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5);
+    }
+
+    template<class U, class B1, class B2, class B3, class B4, class B5> R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5);
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(mf5)(F f): f_(f) {}
+
+    R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
+    {
+        BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5);
+    }
+
+    template<class U> R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5);
+    }
+
+#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS
+
+    template<class U> R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5);
+    }
+
+#endif
+
+    R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5);
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(mf5) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(mf5) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// cmf5
+
+template<class R, class T, class A1, class A2, class A3, class A4, class A5 BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(cmf5)
+{
+public:
+
+    typedef R result_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5) const)
+    F f_;
+
+    template<class U, class B1, class B2, class B3, class B4, class B5> R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5);
+    }
+
+    template<class U, class B1, class B2, class B3, class B4, class B5> R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5);
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(cmf5)(F f): f_(f) {}
+
+    template<class U> R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5);
+    }
+
+    R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5);
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(cmf5) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(cmf5) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// mf6
+
+template<class R, class T, class A1, class A2, class A3, class A4, class A5, class A6 BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(mf6)
+{
+public:
+
+    typedef R result_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6))
+    F f_;
+
+    template<class U, class B1, class B2, class B3, class B4, class B5, class B6> R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6);
+    }
+
+    template<class U, class B1, class B2, class B3, class B4, class B5, class B6> R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6);
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(mf6)(F f): f_(f) {}
+
+    R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
+    {
+        BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5, a6);
+    }
+
+    template<class U> R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6);
+    }
+
+#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS
+
+    template<class U> R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6);
+    }
+
+#endif
+
+    R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6);
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(mf6) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(mf6) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// cmf6
+
+template<class R, class T, class A1, class A2, class A3, class A4, class A5, class A6 BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(cmf6)
+{
+public:
+
+    typedef R result_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6) const)
+    F f_;
+
+    template<class U, class B1, class B2, class B3, class B4, class B5, class B6> R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6);
+    }
+
+    template<class U, class B1, class B2, class B3, class B4, class B5, class B6> R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6);
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(cmf6)(F f): f_(f) {}
+
+    template<class U> R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6);
+    }
+
+    R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6);
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(cmf6) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(cmf6) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// mf7
+
+template<class R, class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(mf7)
+{
+public:
+
+    typedef R result_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7))
+    F f_;
+
+    template<class U, class B1, class B2, class B3, class B4, class B5, class B6, class B7> R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6, b7);
+    }
+
+    template<class U, class B1, class B2, class B3, class B4, class B5, class B6, class B7> R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6, b7);
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(mf7)(F f): f_(f) {}
+
+    R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
+    {
+        BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5, a6, a7);
+    }
+
+    template<class U> R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7);
+    }
+
+#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS
+
+    template<class U> R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7);
+    }
+
+#endif
+
+    R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7);
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(mf7) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(mf7) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// cmf7
+
+template<class R, class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7 BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(cmf7)
+{
+public:
+
+    typedef R result_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7) const)
+    F f_;
+
+    template<class U, class B1, class B2, class B3, class B4, class B5, class B6, class B7> R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6, b7);
+    }
+
+    template<class U, class B1, class B2, class B3, class B4, class B5, class B6, class B7> R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6, b7);
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(cmf7)(F f): f_(f) {}
+
+    template<class U> R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7);
+    }
+
+    R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7);
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(cmf7) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(cmf7) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// mf8
+
+template<class R, class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(mf8)
+{
+public:
+
+    typedef R result_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7, A8))
+    F f_;
+
+    template<class U, class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8> R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7, B8 & b8) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6, b7, b8);
+    }
+
+    template<class U, class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8> R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7, B8 & b8) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6, b7, b8);
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(mf8)(F f): f_(f) {}
+
+    R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
+    {
+        BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5, a6, a7, a8);
+    }
+
+    template<class U> R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7, a8);
+    }
+
+#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS
+
+    template<class U> R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7, a8);
+    }
+
+#endif
+
+    R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7, a8);
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(mf8) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(mf8) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+// cmf8
+
+template<class R, class T, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 BOOST_MEM_FN_CLASS_F> class BOOST_MEM_FN_NAME(cmf8)
+{
+public:
+
+    typedef R result_type;
+
+private:
+
+    BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7, A8) const)
+    F f_;
+
+    template<class U, class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8> R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7, B8 & b8) const
+    {
+        BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6, b7, b8);
+    }
+
+    template<class U, class B1, class B2, class B3, class B4, class B5, class B6, class B7, class B8> R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7, B8 & b8) const
+    {
+        BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6, b7, b8);
+    }
+
+public:
+
+    explicit BOOST_MEM_FN_NAME(cmf8)(F f): f_(f) {}
+
+    R operator()(T const * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
+    {
+        BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5, a6, a7, a8);
+    }
+
+    template<class U> R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
+    {
+        U const * p = 0;
+        BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7, a8);
+    }
+
+    R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
+    {
+        BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7, a8);
+    }
+
+    bool operator==(BOOST_MEM_FN_NAME(cmf8) const & rhs) const
+    {
+        return f_ == rhs.f_;
+    }
+
+    bool operator!=(BOOST_MEM_FN_NAME(cmf8) const & rhs) const
+    {
+        return f_ != rhs.f_;
+    }
+};
+
+#undef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS
diff --git a/third_party/boost/boost/bind/placeholders.hpp b/third_party/boost/boost/bind/placeholders.hpp
new file mode 100644
index 0000000..b819ef4
--- /dev/null
+++ b/third_party/boost/boost/bind/placeholders.hpp
@@ -0,0 +1,62 @@
+#ifndef BOOST_BIND_PLACEHOLDERS_HPP_INCLUDED
+#define BOOST_BIND_PLACEHOLDERS_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  bind/placeholders.hpp - _N definitions
+//
+//  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
+//  Copyright 2015 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+//
+//  See http://www.boost.org/libs/bind/bind.html for documentation.
+//
+
+#include <boost/bind/arg.hpp>
+#include <boost/config.hpp>
+
+namespace boost
+{
+
+namespace placeholders
+{
+
+#if defined(__BORLANDC__) || defined(__GNUC__) && (__GNUC__ < 4)
+
+inline boost::arg<1> _1() { return boost::arg<1>(); }
+inline boost::arg<2> _2() { return boost::arg<2>(); }
+inline boost::arg<3> _3() { return boost::arg<3>(); }
+inline boost::arg<4> _4() { return boost::arg<4>(); }
+inline boost::arg<5> _5() { return boost::arg<5>(); }
+inline boost::arg<6> _6() { return boost::arg<6>(); }
+inline boost::arg<7> _7() { return boost::arg<7>(); }
+inline boost::arg<8> _8() { return boost::arg<8>(); }
+inline boost::arg<9> _9() { return boost::arg<9>(); }
+
+#else
+
+BOOST_STATIC_CONSTEXPR boost::arg<1> _1;
+BOOST_STATIC_CONSTEXPR boost::arg<2> _2;
+BOOST_STATIC_CONSTEXPR boost::arg<3> _3;
+BOOST_STATIC_CONSTEXPR boost::arg<4> _4;
+BOOST_STATIC_CONSTEXPR boost::arg<5> _5;
+BOOST_STATIC_CONSTEXPR boost::arg<6> _6;
+BOOST_STATIC_CONSTEXPR boost::arg<7> _7;
+BOOST_STATIC_CONSTEXPR boost::arg<8> _8;
+BOOST_STATIC_CONSTEXPR boost::arg<9> _9;
+
+#endif
+
+} // namespace placeholders
+
+} // namespace boost
+
+#endif // #ifndef BOOST_BIND_PLACEHOLDERS_HPP_INCLUDED
diff --git a/third_party/boost/boost/bind/storage.hpp b/third_party/boost/boost/bind/storage.hpp
new file mode 100644
index 0000000..be490b0
--- /dev/null
+++ b/third_party/boost/boost/bind/storage.hpp
@@ -0,0 +1,475 @@
+#ifndef BOOST_BIND_STORAGE_HPP_INCLUDED
+#define BOOST_BIND_STORAGE_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  bind/storage.hpp
+//
+//  boost/bind.hpp support header, optimized storage
+//
+//  Copyright (c) 2006 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+//
+//  See http://www.boost.org/libs/bind/bind.html for documentation.
+//
+
+#include <boost/config.hpp>
+#include <boost/bind/arg.hpp>
+
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable: 4512) // assignment operator could not be generated
+#endif
+
+namespace boost
+{
+
+namespace _bi
+{
+
+// 1
+
+template<class A1> struct storage1
+{
+    explicit storage1( A1 a1 ): a1_( a1 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        BOOST_BIND_VISIT_EACH(v, a1_, 0);
+    }
+
+    A1 a1_;
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( __BORLANDC__ )
+
+template<int I> struct storage1< boost::arg<I> >
+{
+    explicit storage1( boost::arg<I> ) {}
+
+    template<class V> void accept(V &) const { }
+
+    static boost::arg<I> a1_() { return boost::arg<I>(); }
+};
+
+template<int I> struct storage1< boost::arg<I> (*) () >
+{
+    explicit storage1( boost::arg<I> (*) () ) {}
+
+    template<class V> void accept(V &) const { }
+
+    static boost::arg<I> a1_() { return boost::arg<I>(); }
+};
+
+#endif
+
+// 2
+
+template<class A1, class A2> struct storage2: public storage1<A1>
+{
+    typedef storage1<A1> inherited;
+
+    storage2( A1 a1, A2 a2 ): storage1<A1>( a1 ), a2_( a2 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+        BOOST_BIND_VISIT_EACH(v, a2_, 0);
+    }
+
+    A2 a2_;
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template<class A1, int I> struct storage2< A1, boost::arg<I> >: public storage1<A1>
+{
+    typedef storage1<A1> inherited;
+
+    storage2( A1 a1, boost::arg<I> ): storage1<A1>( a1 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+    }
+
+    static boost::arg<I> a2_() { return boost::arg<I>(); }
+};
+
+template<class A1, int I> struct storage2< A1, boost::arg<I> (*) () >: public storage1<A1>
+{
+    typedef storage1<A1> inherited;
+
+    storage2( A1 a1, boost::arg<I> (*) () ): storage1<A1>( a1 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+    }
+
+    static boost::arg<I> a2_() { return boost::arg<I>(); }
+};
+
+#endif
+
+// 3
+
+template<class A1, class A2, class A3> struct storage3: public storage2< A1, A2 >
+{
+    typedef storage2<A1, A2> inherited;
+
+    storage3( A1 a1, A2 a2, A3 a3 ): storage2<A1, A2>( a1, a2 ), a3_( a3 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+        BOOST_BIND_VISIT_EACH(v, a3_, 0);
+    }
+
+    A3 a3_;
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template<class A1, class A2, int I> struct storage3< A1, A2, boost::arg<I> >: public storage2< A1, A2 >
+{
+    typedef storage2<A1, A2> inherited;
+
+    storage3( A1 a1, A2 a2, boost::arg<I> ): storage2<A1, A2>( a1, a2 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+    }
+
+    static boost::arg<I> a3_() { return boost::arg<I>(); }
+};
+
+template<class A1, class A2, int I> struct storage3< A1, A2, boost::arg<I> (*) () >: public storage2< A1, A2 >
+{
+    typedef storage2<A1, A2> inherited;
+
+    storage3( A1 a1, A2 a2, boost::arg<I> (*) () ): storage2<A1, A2>( a1, a2 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+    }
+
+    static boost::arg<I> a3_() { return boost::arg<I>(); }
+};
+
+#endif
+
+// 4
+
+template<class A1, class A2, class A3, class A4> struct storage4: public storage3< A1, A2, A3 >
+{
+    typedef storage3<A1, A2, A3> inherited;
+
+    storage4( A1 a1, A2 a2, A3 a3, A4 a4 ): storage3<A1, A2, A3>( a1, a2, a3 ), a4_( a4 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+        BOOST_BIND_VISIT_EACH(v, a4_, 0);
+    }
+
+    A4 a4_;
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template<class A1, class A2, class A3, int I> struct storage4< A1, A2, A3, boost::arg<I> >: public storage3< A1, A2, A3 >
+{
+    typedef storage3<A1, A2, A3> inherited;
+
+    storage4( A1 a1, A2 a2, A3 a3, boost::arg<I> ): storage3<A1, A2, A3>( a1, a2, a3 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+    }
+
+    static boost::arg<I> a4_() { return boost::arg<I>(); }
+};
+
+template<class A1, class A2, class A3, int I> struct storage4< A1, A2, A3, boost::arg<I> (*) () >: public storage3< A1, A2, A3 >
+{
+    typedef storage3<A1, A2, A3> inherited;
+
+    storage4( A1 a1, A2 a2, A3 a3, boost::arg<I> (*) () ): storage3<A1, A2, A3>( a1, a2, a3 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+    }
+
+    static boost::arg<I> a4_() { return boost::arg<I>(); }
+};
+
+#endif
+
+// 5
+
+template<class A1, class A2, class A3, class A4, class A5> struct storage5: public storage4< A1, A2, A3, A4 >
+{
+    typedef storage4<A1, A2, A3, A4> inherited;
+
+    storage5( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 ): storage4<A1, A2, A3, A4>( a1, a2, a3, a4 ), a5_( a5 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+        BOOST_BIND_VISIT_EACH(v, a5_, 0);
+    }
+
+    A5 a5_;
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template<class A1, class A2, class A3, class A4, int I> struct storage5< A1, A2, A3, A4, boost::arg<I> >: public storage4< A1, A2, A3, A4 >
+{
+    typedef storage4<A1, A2, A3, A4> inherited;
+
+    storage5( A1 a1, A2 a2, A3 a3, A4 a4, boost::arg<I> ): storage4<A1, A2, A3, A4>( a1, a2, a3, a4 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+    }
+
+    static boost::arg<I> a5_() { return boost::arg<I>(); }
+};
+
+template<class A1, class A2, class A3, class A4, int I> struct storage5< A1, A2, A3, A4, boost::arg<I> (*) () >: public storage4< A1, A2, A3, A4 >
+{
+    typedef storage4<A1, A2, A3, A4> inherited;
+
+    storage5( A1 a1, A2 a2, A3 a3, A4 a4, boost::arg<I> (*) () ): storage4<A1, A2, A3, A4>( a1, a2, a3, a4 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+    }
+
+    static boost::arg<I> a5_() { return boost::arg<I>(); }
+};
+
+#endif
+
+// 6
+
+template<class A1, class A2, class A3, class A4, class A5, class A6> struct storage6: public storage5< A1, A2, A3, A4, A5 >
+{
+    typedef storage5<A1, A2, A3, A4, A5> inherited;
+
+    storage6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6 ): storage5<A1, A2, A3, A4, A5>( a1, a2, a3, a4, a5 ), a6_( a6 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+        BOOST_BIND_VISIT_EACH(v, a6_, 0);
+    }
+
+    A6 a6_;
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template<class A1, class A2, class A3, class A4, class A5, int I> struct storage6< A1, A2, A3, A4, A5, boost::arg<I> >: public storage5< A1, A2, A3, A4, A5 >
+{
+    typedef storage5<A1, A2, A3, A4, A5> inherited;
+
+    storage6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, boost::arg<I> ): storage5<A1, A2, A3, A4, A5>( a1, a2, a3, a4, a5 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+    }
+
+    static boost::arg<I> a6_() { return boost::arg<I>(); }
+};
+
+template<class A1, class A2, class A3, class A4, class A5, int I> struct storage6< A1, A2, A3, A4, A5, boost::arg<I> (*) () >: public storage5< A1, A2, A3, A4, A5 >
+{
+    typedef storage5<A1, A2, A3, A4, A5> inherited;
+
+    storage6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, boost::arg<I> (*) () ): storage5<A1, A2, A3, A4, A5>( a1, a2, a3, a4, a5 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+    }
+
+    static boost::arg<I> a6_() { return boost::arg<I>(); }
+};
+
+#endif
+
+// 7
+
+template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> struct storage7: public storage6< A1, A2, A3, A4, A5, A6 >
+{
+    typedef storage6<A1, A2, A3, A4, A5, A6> inherited;
+
+    storage7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7 ): storage6<A1, A2, A3, A4, A5, A6>( a1, a2, a3, a4, a5, a6 ), a7_( a7 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+        BOOST_BIND_VISIT_EACH(v, a7_, 0);
+    }
+
+    A7 a7_;
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template<class A1, class A2, class A3, class A4, class A5, class A6, int I> struct storage7< A1, A2, A3, A4, A5, A6, boost::arg<I> >: public storage6< A1, A2, A3, A4, A5, A6 >
+{
+    typedef storage6<A1, A2, A3, A4, A5, A6> inherited;
+
+    storage7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, boost::arg<I> ): storage6<A1, A2, A3, A4, A5, A6>( a1, a2, a3, a4, a5, a6 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+    }
+
+    static boost::arg<I> a7_() { return boost::arg<I>(); }
+};
+
+template<class A1, class A2, class A3, class A4, class A5, class A6, int I> struct storage7< A1, A2, A3, A4, A5, A6, boost::arg<I> (*) () >: public storage6< A1, A2, A3, A4, A5, A6 >
+{
+    typedef storage6<A1, A2, A3, A4, A5, A6> inherited;
+
+    storage7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, boost::arg<I> (*) () ): storage6<A1, A2, A3, A4, A5, A6>( a1, a2, a3, a4, a5, a6 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+    }
+
+    static boost::arg<I> a7_() { return boost::arg<I>(); }
+};
+
+#endif
+
+// 8
+
+template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> struct storage8: public storage7< A1, A2, A3, A4, A5, A6, A7 >
+{
+    typedef storage7<A1, A2, A3, A4, A5, A6, A7> inherited;
+
+    storage8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8 ): storage7<A1, A2, A3, A4, A5, A6, A7>( a1, a2, a3, a4, a5, a6, a7 ), a8_( a8 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+        BOOST_BIND_VISIT_EACH(v, a8_, 0);
+    }
+
+    A8 a8_;
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, int I> struct storage8< A1, A2, A3, A4, A5, A6, A7, boost::arg<I> >: public storage7< A1, A2, A3, A4, A5, A6, A7 >
+{
+    typedef storage7<A1, A2, A3, A4, A5, A6, A7> inherited;
+
+    storage8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, boost::arg<I> ): storage7<A1, A2, A3, A4, A5, A6, A7>( a1, a2, a3, a4, a5, a6, a7 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+    }
+
+    static boost::arg<I> a8_() { return boost::arg<I>(); }
+};
+
+template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, int I> struct storage8< A1, A2, A3, A4, A5, A6, A7, boost::arg<I> (*) () >: public storage7< A1, A2, A3, A4, A5, A6, A7 >
+{
+    typedef storage7<A1, A2, A3, A4, A5, A6, A7> inherited;
+
+    storage8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, boost::arg<I> (*) () ): storage7<A1, A2, A3, A4, A5, A6, A7>( a1, a2, a3, a4, a5, a6, a7 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+    }
+
+    static boost::arg<I> a8_() { return boost::arg<I>(); }
+};
+
+#endif
+
+// 9
+
+template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> struct storage9: public storage8< A1, A2, A3, A4, A5, A6, A7, A8 >
+{
+    typedef storage8<A1, A2, A3, A4, A5, A6, A7, A8> inherited;
+
+    storage9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9 ): storage8<A1, A2, A3, A4, A5, A6, A7, A8>( a1, a2, a3, a4, a5, a6, a7, a8 ), a9_( a9 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+        BOOST_BIND_VISIT_EACH(v, a9_, 0);
+    }
+
+    A9 a9_;
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, int I> struct storage9< A1, A2, A3, A4, A5, A6, A7, A8, boost::arg<I> >: public storage8< A1, A2, A3, A4, A5, A6, A7, A8 >
+{
+    typedef storage8<A1, A2, A3, A4, A5, A6, A7, A8> inherited;
+
+    storage9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, boost::arg<I> ): storage8<A1, A2, A3, A4, A5, A6, A7, A8>( a1, a2, a3, a4, a5, a6, a7, a8 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+    }
+
+    static boost::arg<I> a9_() { return boost::arg<I>(); }
+};
+
+template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, int I> struct storage9< A1, A2, A3, A4, A5, A6, A7, A8, boost::arg<I> (*) () >: public storage8< A1, A2, A3, A4, A5, A6, A7, A8 >
+{
+    typedef storage8<A1, A2, A3, A4, A5, A6, A7, A8> inherited;
+
+    storage9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, boost::arg<I> (*) () ): storage8<A1, A2, A3, A4, A5, A6, A7, A8>( a1, a2, a3, a4, a5, a6, a7, a8 ) {}
+
+    template<class V> void accept(V & v) const
+    {
+        inherited::accept(v);
+    }
+
+    static boost::arg<I> a9_() { return boost::arg<I>(); }
+};
+
+#endif
+
+} // namespace _bi
+
+} // namespace boost
+
+#ifdef BOOST_MSVC
+# pragma warning(default: 4512) // assignment operator could not be generated
+# pragma warning(pop)
+#endif
+
+#endif // #ifndef BOOST_BIND_STORAGE_HPP_INCLUDED
diff --git a/third_party/boost/boost/blank.hpp b/third_party/boost/boost/blank.hpp
new file mode 100644
index 0000000..d0fe5ab
--- /dev/null
+++ b/third_party/boost/boost/blank.hpp
@@ -0,0 +1,106 @@
+//-----------------------------------------------------------------------------
+// boost blank.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_BLANK_HPP
+#define BOOST_BLANK_HPP
+
+#include "boost/blank_fwd.hpp"
+
+#if !defined(BOOST_NO_IOSTREAM)
+#include <iosfwd> // for std::basic_ostream forward declare
+#include "boost/detail/templated_streams.hpp"
+#endif // BOOST_NO_IOSTREAM
+
+#include "boost/mpl/bool.hpp"
+#include "boost/type_traits/is_empty.hpp"
+#include "boost/type_traits/is_pod.hpp"
+#include "boost/type_traits/is_stateless.hpp"
+
+namespace boost {
+
+struct blank
+{
+};
+
+// type traits specializations
+//
+
+template <>
+struct is_pod< blank >
+    : mpl::true_
+{
+};
+
+template <>
+struct is_empty< blank >
+    : mpl::true_
+{
+};
+
+template <>
+struct is_stateless< blank >
+    : mpl::true_
+{
+};
+
+// relational operators
+//
+
+inline bool operator==(const blank&, const blank&)
+{
+    return true;
+}
+
+inline bool operator<=(const blank&, const blank&)
+{
+    return true;
+}
+
+inline bool operator>=(const blank&, const blank&)
+{
+    return true;
+}
+
+inline bool operator!=(const blank&, const blank&)
+{
+    return false;
+}
+
+inline bool operator<(const blank&, const blank&)
+{
+    return false;
+}
+
+inline bool operator>(const blank&, const blank&)
+{
+    return false;
+}
+
+// streaming support
+//
+#if !defined(BOOST_NO_IOSTREAM)
+
+BOOST_TEMPLATED_STREAM_TEMPLATE(E,T)
+inline BOOST_TEMPLATED_STREAM(ostream, E,T)& operator<<(
+      BOOST_TEMPLATED_STREAM(ostream, E,T)& out
+    , const blank&
+    )
+{
+    // (output nothing)
+    return out;
+}
+
+#endif // BOOST_NO_IOSTREAM
+
+} // namespace boost
+
+#endif // BOOST_BLANK_HPP
diff --git a/third_party/boost/boost/blank_fwd.hpp b/third_party/boost/boost/blank_fwd.hpp
new file mode 100644
index 0000000..8bfe97c
--- /dev/null
+++ b/third_party/boost/boost/blank_fwd.hpp
@@ -0,0 +1,22 @@
+//-----------------------------------------------------------------------------
+// boost blank_fwd.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_BLANK_FWD_HPP
+#define BOOST_BLANK_FWD_HPP
+
+namespace boost {
+
+struct blank;
+
+} // namespace boost
+
+#endif // BOOST_BLANK_FWD_HPP
diff --git a/third_party/boost/boost/call_traits.hpp b/third_party/boost/boost/call_traits.hpp
new file mode 100644
index 0000000..2c1328e
--- /dev/null
+++ b/third_party/boost/boost/call_traits.hpp
@@ -0,0 +1,20 @@
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/utility for most recent version including documentation.
+
+//  See boost/detail/call_traits.hpp
+//  for full copyright notices.
+
+#ifndef BOOST_CALL_TRAITS_HPP
+#define BOOST_CALL_TRAITS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#include <boost/config.hpp>
+#endif
+
+#include <boost/detail/call_traits.hpp>
+
+#endif // BOOST_CALL_TRAITS_HPP
diff --git a/third_party/boost/boost/checked_delete.hpp b/third_party/boost/boost/checked_delete.hpp
new file mode 100644
index 0000000..fb71c78
--- /dev/null
+++ b/third_party/boost/boost/checked_delete.hpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2014 Glen Fernandes
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef BOOST_CHECKED_DELETE_HPP
+#define BOOST_CHECKED_DELETE_HPP
+
+// The header file at this path is deprecated;
+// use boost/core/checked_delete.hpp instead.
+
+#include <boost/core/checked_delete.hpp>
+
+#endif
diff --git a/third_party/boost/boost/config.hpp b/third_party/boost/boost/config.hpp
new file mode 100644
index 0000000..a73f7e1
--- /dev/null
+++ b/third_party/boost/boost/config.hpp
@@ -0,0 +1,67 @@
+//  Boost config.hpp configuration header file  ------------------------------//
+
+//  (C) Copyright John Maddock 2002.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org/libs/config for most recent version.
+
+//  Boost config.hpp policy and rationale documentation has been moved to
+//  http://www.boost.org/libs/config
+//
+//  CAUTION: This file is intended to be completely stable -
+//           DO NOT MODIFY THIS FILE!
+//
+
+#ifndef BOOST_CONFIG_HPP
+#define BOOST_CONFIG_HPP
+
+// if we don't have a user config, then use the default location:
+#if !defined(BOOST_USER_CONFIG) && !defined(BOOST_NO_USER_CONFIG)
+#  define BOOST_USER_CONFIG <boost/config/user.hpp>
+#if 0
+// For dependency trackers:
+#  include <boost/config/user.hpp>
+#endif
+#endif
+// include it first:
+#ifdef BOOST_USER_CONFIG
+#  include BOOST_USER_CONFIG
+#endif
+
+// if we don't have a compiler config set, try and find one:
+#if !defined(BOOST_COMPILER_CONFIG) && !defined(BOOST_NO_COMPILER_CONFIG) && !defined(BOOST_NO_CONFIG)
+#  include <boost/config/select_compiler_config.hpp>
+#endif
+// if we have a compiler config, include it now:
+#ifdef BOOST_COMPILER_CONFIG
+#  include BOOST_COMPILER_CONFIG
+#endif
+
+// if we don't have a std library config set, try and find one:
+#if !defined(BOOST_STDLIB_CONFIG) && !defined(BOOST_NO_STDLIB_CONFIG) && !defined(BOOST_NO_CONFIG) && defined(__cplusplus)
+#  include <boost/config/select_stdlib_config.hpp>
+#endif
+// if we have a std library config, include it now:
+#ifdef BOOST_STDLIB_CONFIG
+#  include BOOST_STDLIB_CONFIG
+#endif
+
+// if we don't have a platform config set, try and find one:
+#if !defined(BOOST_PLATFORM_CONFIG) && !defined(BOOST_NO_PLATFORM_CONFIG) && !defined(BOOST_NO_CONFIG)
+#  include <boost/config/select_platform_config.hpp>
+#endif
+// if we have a platform config, include it now:
+#ifdef BOOST_PLATFORM_CONFIG
+#  include BOOST_PLATFORM_CONFIG
+#endif
+
+// get config suffix code:
+#include <boost/config/suffix.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#endif  // BOOST_CONFIG_HPP
diff --git a/third_party/boost/boost/config/compiler/clang.hpp b/third_party/boost/boost/config/compiler/clang.hpp
new file mode 100644
index 0000000..329a196
--- /dev/null
+++ b/third_party/boost/boost/config/compiler/clang.hpp
@@ -0,0 +1,278 @@
+// (C) Copyright Douglas Gregor 2010
+//
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org for most recent version.
+
+// Clang compiler setup.
+
+#define BOOST_HAS_PRAGMA_ONCE
+
+// Detecting `-fms-extension` compiler flag assuming that _MSC_VER defined when that flag is used.
+#if defined (_MSC_VER) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 4))
+#   define BOOST_HAS_PRAGMA_DETECT_MISMATCH
+#endif
+
+// When compiling with clang before __has_extension was defined,
+// even if one writes 'defined(__has_extension) && __has_extension(xxx)',
+// clang reports a compiler error. So the only workaround found is:
+
+#ifndef __has_extension
+#define __has_extension __has_feature
+#endif
+
+#ifndef __has_attribute
+#define __has_attribute(x) 0
+#endif
+
+#if !__has_feature(cxx_exceptions) && !defined(BOOST_NO_EXCEPTIONS)
+#  define BOOST_NO_EXCEPTIONS
+#endif
+
+#if !__has_feature(cxx_rtti) && !defined(BOOST_NO_RTTI)
+#  define BOOST_NO_RTTI
+#endif
+
+#if !__has_feature(cxx_rtti) && !defined(BOOST_NO_TYPEID)
+#  define BOOST_NO_TYPEID
+#endif
+
+#if defined(__int64) && !defined(__GNUC__)
+#  define BOOST_HAS_MS_INT64
+#endif
+
+#define BOOST_HAS_NRVO
+
+// Branch prediction hints
+#if defined(__has_builtin)
+#if __has_builtin(__builtin_expect)
+#define BOOST_LIKELY(x) __builtin_expect(x, 1)
+#define BOOST_UNLIKELY(x) __builtin_expect(x, 0)
+#endif
+#endif
+
+// Clang supports "long long" in all compilation modes.
+#define BOOST_HAS_LONG_LONG
+
+//
+// We disable this if the compiler is really nvcc as it
+// doesn't actually support __int128 as of CUDA_VERSION=5000
+// even though it defines __SIZEOF_INT128__.
+// See https://svn.boost.org/trac/boost/ticket/10418
+// Only re-enable this for nvcc if you're absolutely sure
+// of the circumstances under which it's supported.
+// Similarly __SIZEOF_INT128__ is defined when targetting msvc
+// compatibility even though the required support functions are absent.
+//
+#if defined(__SIZEOF_INT128__) && !defined(__CUDACC__) && !defined(_MSC_VER)
+#  define BOOST_HAS_INT128
+#endif
+
+
+//
+// Dynamic shared object (DSO) and dynamic-link library (DLL) support
+//
+#if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32)
+#  define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default")))
+#  define BOOST_SYMBOL_IMPORT
+#  define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default")))
+#endif
+
+//
+// The BOOST_FALLTHROUGH macro can be used to annotate implicit fall-through
+// between switch labels.
+//
+#if __cplusplus >= 201103L && defined(__has_warning)
+#  if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
+#    define BOOST_FALLTHROUGH [[clang::fallthrough]]
+#  endif
+#endif
+
+#if !__has_feature(cxx_auto_type)
+#  define BOOST_NO_CXX11_AUTO_DECLARATIONS
+#  define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS
+#endif
+
+//
+// Currently clang on Windows using VC++ RTL does not support C++11's char16_t or char32_t
+//
+#if defined(_MSC_VER) || !(defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L)
+#  define BOOST_NO_CXX11_CHAR16_T
+#  define BOOST_NO_CXX11_CHAR32_T
+#endif
+
+#if !__has_feature(cxx_constexpr)
+#  define BOOST_NO_CXX11_CONSTEXPR
+#endif
+
+#if !__has_feature(cxx_decltype)
+#  define BOOST_NO_CXX11_DECLTYPE
+#endif
+
+#if !__has_feature(cxx_decltype_incomplete_return_types)
+#  define BOOST_NO_CXX11_DECLTYPE_N3276
+#endif
+
+#if !__has_feature(cxx_defaulted_functions)
+#  define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
+#endif
+
+#if !__has_feature(cxx_deleted_functions)
+#  define BOOST_NO_CXX11_DELETED_FUNCTIONS
+#endif
+
+#if !__has_feature(cxx_explicit_conversions)
+#  define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
+#endif
+
+#if !__has_feature(cxx_default_function_template_args)
+#  define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
+#endif
+
+#if !__has_feature(cxx_generalized_initializers)
+#  define BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+#endif
+
+#if !__has_feature(cxx_lambdas)
+#  define BOOST_NO_CXX11_LAMBDAS
+#endif
+
+#if !__has_feature(cxx_local_type_template_args)
+#  define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS
+#endif
+
+#if !__has_feature(cxx_noexcept)
+#  define BOOST_NO_CXX11_NOEXCEPT
+#endif
+
+#if !__has_feature(cxx_nullptr)
+#  define BOOST_NO_CXX11_NULLPTR
+#endif
+
+#if !__has_feature(cxx_range_for)
+#  define BOOST_NO_CXX11_RANGE_BASED_FOR
+#endif
+
+#if !__has_feature(cxx_raw_string_literals)
+#  define BOOST_NO_CXX11_RAW_LITERALS
+#endif
+
+#if !__has_feature(cxx_reference_qualified_functions)
+#  define BOOST_NO_CXX11_REF_QUALIFIERS
+#endif
+
+#if !__has_feature(cxx_generalized_initializers)
+#  define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
+#endif
+
+#if !__has_feature(cxx_rvalue_references)
+#  define BOOST_NO_CXX11_RVALUE_REFERENCES
+#endif
+
+#if !__has_feature(cxx_strong_enums)
+#  define BOOST_NO_CXX11_SCOPED_ENUMS
+#endif
+
+#if !__has_feature(cxx_static_assert)
+#  define BOOST_NO_CXX11_STATIC_ASSERT
+#endif
+
+#if !__has_feature(cxx_alias_templates)
+#  define BOOST_NO_CXX11_TEMPLATE_ALIASES
+#endif
+
+#if !__has_feature(cxx_unicode_literals)
+#  define BOOST_NO_CXX11_UNICODE_LITERALS
+#endif
+
+#if !__has_feature(cxx_variadic_templates)
+#  define BOOST_NO_CXX11_VARIADIC_TEMPLATES
+#endif
+
+#if !__has_feature(cxx_user_literals)
+#  define BOOST_NO_CXX11_USER_DEFINED_LITERALS
+#endif
+
+#if !__has_feature(cxx_alignas)
+#  define BOOST_NO_CXX11_ALIGNAS
+#endif
+
+#if !__has_feature(cxx_trailing_return)
+#  define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
+#endif
+
+#if !__has_feature(cxx_inline_namespaces)
+#  define BOOST_NO_CXX11_INLINE_NAMESPACES
+#endif
+
+#if !__has_feature(cxx_override_control)
+#  define BOOST_NO_CXX11_FINAL
+#endif
+
+#if !(__has_feature(__cxx_binary_literals__) || __has_extension(__cxx_binary_literals__))
+#  define BOOST_NO_CXX14_BINARY_LITERALS
+#endif
+
+#if !__has_feature(__cxx_decltype_auto__)
+#  define BOOST_NO_CXX14_DECLTYPE_AUTO
+#endif
+
+#if !__has_feature(__cxx_aggregate_nsdmi__)
+#  define BOOST_NO_CXX14_AGGREGATE_NSDMI
+#endif
+
+#if !__has_feature(__cxx_init_captures__)
+#  define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES
+#endif
+
+#if !__has_feature(__cxx_generic_lambdas__)
+#  define BOOST_NO_CXX14_GENERIC_LAMBDAS
+#endif
+
+// clang < 3.5 has a defect with dependent type, like following.
+//
+//  template <class T>
+//  constexpr typename enable_if<pred<T> >::type foo(T &)
+//  { } // error: no return statement in constexpr function
+//
+// This issue also affects C++11 mode, but C++11 constexpr requires return stmt.
+// Therefore we don't care such case.
+//
+// Note that we can't check Clang version directly as the numbering system changes depending who's
+// creating the Clang release (see https://github.com/boostorg/config/pull/39#issuecomment-59927873)
+// so instead verify that we have a feature that was introduced at the same time as working C++14
+// constexpr (generic lambda's in this case):
+//
+#if !__has_feature(__cxx_generic_lambdas__) || !__has_feature(__cxx_relaxed_constexpr__)
+#  define BOOST_NO_CXX14_CONSTEXPR
+#endif
+
+#if !__has_feature(__cxx_return_type_deduction__)
+#  define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION
+#endif
+
+#if !__has_feature(__cxx_variable_templates__)
+#  define BOOST_NO_CXX14_VARIABLE_TEMPLATES
+#endif
+
+#if __cplusplus < 201400
+// All versions with __cplusplus above this value seem to support this:
+#  define BOOST_NO_CXX14_DIGIT_SEPARATORS
+#endif
+//
+// __builtin_unreachable:
+#if defined(__has_builtin) && __has_builtin(__builtin_unreachable)
+#define BOOST_UNREACHABLE_RETURN(x) __builtin_unreachable();
+#endif
+
+// Clang has supported the 'unused' attribute since the first release.
+#define BOOST_ATTRIBUTE_UNUSED __attribute__((__unused__))
+
+#ifndef BOOST_COMPILER
+#  define BOOST_COMPILER "Clang version " __clang_version__
+#endif
+
+// Macro used to identify the Clang compiler.
+#define BOOST_CLANG 1
diff --git a/third_party/boost/boost/config/compiler/gcc.hpp b/third_party/boost/boost/config/compiler/gcc.hpp
new file mode 100644
index 0000000..735c231
--- /dev/null
+++ b/third_party/boost/boost/config/compiler/gcc.hpp
@@ -0,0 +1,313 @@
+//  (C) Copyright John Maddock 2001 - 2003.
+//  (C) Copyright Darin Adler 2001 - 2002.
+//  (C) Copyright Jens Maurer 2001 - 2002.
+//  (C) Copyright Beman Dawes 2001 - 2003.
+//  (C) Copyright Douglas Gregor 2002.
+//  (C) Copyright David Abrahams 2002 - 2003.
+//  (C) Copyright Synge Todo 2003.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org for most recent version.
+
+//  GNU C++ compiler setup.
+
+//
+// Define BOOST_GCC so we know this is "real" GCC and not some pretender:
+//
+#define BOOST_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#if !defined(__CUDACC__)
+#define BOOST_GCC BOOST_GCC_VERSION
+#endif
+
+#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
+#  define BOOST_GCC_CXX11
+#endif
+
+#if __GNUC__ == 3
+#  if defined (__PATHSCALE__)
+#     define BOOST_NO_TWO_PHASE_NAME_LOOKUP
+#     define BOOST_NO_IS_ABSTRACT
+#  endif
+
+#  if __GNUC_MINOR__ < 4
+#     define BOOST_NO_IS_ABSTRACT
+#  endif
+#  define BOOST_NO_CXX11_EXTERN_TEMPLATE
+#endif
+#if __GNUC__ < 4
+//
+// All problems to gcc-3.x and earlier here:
+//
+#define BOOST_NO_TWO_PHASE_NAME_LOOKUP
+#  ifdef __OPEN64__
+#     define BOOST_NO_IS_ABSTRACT
+#  endif
+#endif
+
+// GCC prior to 3.4 had #pragma once too but it didn't work well with filesystem links
+#if BOOST_GCC_VERSION >= 30400
+#define BOOST_HAS_PRAGMA_ONCE
+#endif
+
+#if BOOST_GCC_VERSION < 40400
+// Previous versions of GCC did not completely implement value-initialization:
+// GCC Bug 30111, "Value-initialization of POD base class doesn't initialize
+// members", reported by Jonathan Wakely in 2006,
+// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111 (fixed for GCC 4.4)
+// GCC Bug 33916, "Default constructor fails to initialize array members",
+// reported by Michael Elizabeth Chastain in 2007,
+// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 (fixed for GCC 4.2.4)
+// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues
+#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION
+#endif
+
+#if !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS)
+# define BOOST_NO_EXCEPTIONS
+#endif
+
+
+//
+// Threading support: Turn this on unconditionally here (except for
+// those platforms where we can know for sure). It will get turned off again
+// later if no threading API is detected.
+//
+#if !defined(__MINGW32__) && !defined(linux) && !defined(__linux) && !defined(__linux__)
+# define BOOST_HAS_THREADS
+#endif
+
+//
+// gcc has "long long"
+// Except on Darwin with standard compliance enabled (-pedantic)
+// Apple gcc helpfully defines this macro we can query
+//
+#if !defined(__DARWIN_NO_LONG_LONG)
+# define BOOST_HAS_LONG_LONG
+#endif
+
+//
+// gcc implements the named return value optimization since version 3.1
+//
+#define BOOST_HAS_NRVO
+
+// Branch prediction hints
+#define BOOST_LIKELY(x) __builtin_expect(x, 1)
+#define BOOST_UNLIKELY(x) __builtin_expect(x, 0)
+
+//
+// Dynamic shared object (DSO) and dynamic-link library (DLL) support
+//
+#if __GNUC__ >= 4
+#  if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && !defined(__CYGWIN__)
+     // All Win32 development environments, including 64-bit Windows and MinGW, define
+     // _WIN32 or one of its variant spellings. Note that Cygwin is a POSIX environment,
+     // so does not define _WIN32 or its variants.
+#    define BOOST_HAS_DECLSPEC
+#    define BOOST_SYMBOL_EXPORT __attribute__((__dllexport__))
+#    define BOOST_SYMBOL_IMPORT __attribute__((__dllimport__))
+#  else
+#    define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default")))
+#    define BOOST_SYMBOL_IMPORT
+#  endif
+#  define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default")))
+#else
+// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined
+#  define BOOST_SYMBOL_EXPORT
+#endif
+
+//
+// RTTI and typeinfo detection is possible post gcc-4.3:
+//
+#if BOOST_GCC_VERSION > 40300
+#  ifndef __GXX_RTTI
+#     ifndef BOOST_NO_TYPEID
+#        define BOOST_NO_TYPEID
+#     endif
+#     ifndef BOOST_NO_RTTI
+#        define BOOST_NO_RTTI
+#     endif
+#  endif
+#endif
+
+//
+// Recent GCC versions have __int128 when in 64-bit mode.
+//
+// We disable this if the compiler is really nvcc as it
+// doesn't actually support __int128 as of CUDA_VERSION=5000
+// even though it defines __SIZEOF_INT128__.
+// See https://svn.boost.org/trac/boost/ticket/8048
+// Only re-enable this for nvcc if you're absolutely sure
+// of the circumstances under which it's supported:
+//
+#if defined(__SIZEOF_INT128__) && !defined(__CUDACC__)
+#  define BOOST_HAS_INT128
+#endif
+//
+// Recent GCC versions have a __float128 native type, we need to
+// include a std lib header to detect this - not ideal, but we'll
+// be including <cstddef> later anyway when we select the std lib.
+//
+#ifdef __cplusplus
+#include <cstddef>
+#else
+#include <stddef.h>
+#endif
+#if defined(_GLIBCXX_USE_FLOAT128) && !defined(__STRICT_ANSI__)
+# define BOOST_HAS_FLOAT128
+#endif
+
+// C++0x features in 4.3.n and later
+//
+#if (BOOST_GCC_VERSION >= 40300) && defined(BOOST_GCC_CXX11)
+// C++0x features are only enabled when -std=c++0x or -std=gnu++0x are
+// passed on the command line, which in turn defines
+// __GXX_EXPERIMENTAL_CXX0X__.
+#  define BOOST_HAS_DECLTYPE
+#  define BOOST_HAS_RVALUE_REFS
+#  define BOOST_HAS_STATIC_ASSERT
+#  define BOOST_HAS_VARIADIC_TMPL
+#else
+#  define BOOST_NO_CXX11_DECLTYPE
+#  define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
+#  define BOOST_NO_CXX11_RVALUE_REFERENCES
+#  define BOOST_NO_CXX11_STATIC_ASSERT
+#endif
+
+// C++0x features in 4.4.n and later
+//
+#if (BOOST_GCC_VERSION < 40400) || !defined(BOOST_GCC_CXX11)
+#  define BOOST_NO_CXX11_AUTO_DECLARATIONS
+#  define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS
+#  define BOOST_NO_CXX11_CHAR16_T
+#  define BOOST_NO_CXX11_CHAR32_T
+#  define BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+#  define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
+#  define BOOST_NO_CXX11_DELETED_FUNCTIONS
+#  define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
+#  define BOOST_NO_CXX11_INLINE_NAMESPACES
+#  define BOOST_NO_CXX11_VARIADIC_TEMPLATES
+#endif
+
+#if BOOST_GCC_VERSION < 40500
+#  define BOOST_NO_SFINAE_EXPR
+#endif
+
+// GCC 4.5 forbids declaration of defaulted functions in private or protected sections
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 5) || !defined(BOOST_GCC_CXX11)
+#  define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS
+#endif
+
+// C++0x features in 4.5.0 and later
+//
+#if (BOOST_GCC_VERSION < 40500) || !defined(BOOST_GCC_CXX11)
+#  define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
+#  define BOOST_NO_CXX11_LAMBDAS
+#  define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS
+#  define BOOST_NO_CXX11_RAW_LITERALS
+#  define BOOST_NO_CXX11_UNICODE_LITERALS
+#endif
+
+// C++0x features in 4.5.1 and later
+//
+#if (BOOST_GCC_VERSION < 40501) || !defined(BOOST_GCC_CXX11)
+// scoped enums have a serious bug in 4.4.0, so define BOOST_NO_CXX11_SCOPED_ENUMS before 4.5.1
+// See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38064
+#  define BOOST_NO_CXX11_SCOPED_ENUMS
+#endif
+
+// C++0x features in 4.6.n and later
+//
+#if (BOOST_GCC_VERSION < 40600) || !defined(BOOST_GCC_CXX11)
+#define BOOST_NO_CXX11_CONSTEXPR
+#define BOOST_NO_CXX11_NOEXCEPT
+#define BOOST_NO_CXX11_NULLPTR
+#define BOOST_NO_CXX11_RANGE_BASED_FOR
+#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
+#endif
+
+// C++0x features in 4.7.n and later
+//
+#if (BOOST_GCC_VERSION < 40700) || !defined(BOOST_GCC_CXX11)
+#  define BOOST_NO_CXX11_FINAL
+#  define BOOST_NO_CXX11_TEMPLATE_ALIASES
+#  define BOOST_NO_CXX11_USER_DEFINED_LITERALS
+#  define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS
+#endif
+
+// C++0x features in 4.8.n and later
+//
+#if (BOOST_GCC_VERSION < 40800) || !defined(BOOST_GCC_CXX11)
+#  define BOOST_NO_CXX11_ALIGNAS
+#endif
+
+// C++0x features in 4.8.1 and later
+//
+#if (BOOST_GCC_VERSION < 40801) || !defined(BOOST_GCC_CXX11)
+#  define BOOST_NO_CXX11_DECLTYPE_N3276
+#  define BOOST_NO_CXX11_REF_QUALIFIERS
+#  define BOOST_NO_CXX14_BINARY_LITERALS
+#endif
+
+// C++14 features in 4.9.0 and later
+//
+#if (BOOST_GCC_VERSION < 40900) || (__cplusplus < 201300)
+#  define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION
+#  define BOOST_NO_CXX14_GENERIC_LAMBDAS
+#  define BOOST_NO_CXX14_DIGIT_SEPARATORS
+#  define BOOST_NO_CXX14_DECLTYPE_AUTO
+#  if !((BOOST_GCC_VERSION >= 40801) && (BOOST_GCC_VERSION < 40900) && defined(BOOST_GCC_CXX11))
+#     define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES
+#  endif
+#endif
+
+
+// C++ 14:
+#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304)
+#  define BOOST_NO_CXX14_AGGREGATE_NSDMI
+#endif
+#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304)
+#  define BOOST_NO_CXX14_CONSTEXPR
+#endif
+#if !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304)
+#  define BOOST_NO_CXX14_VARIABLE_TEMPLATES
+#endif
+
+//
+// Unused attribute:
+#if __GNUC__ >= 4
+#  define BOOST_ATTRIBUTE_UNUSED __attribute__((__unused__))
+#endif
+//
+// __builtin_unreachable:
+#if BOOST_GCC_VERSION >= 40800
+#define BOOST_UNREACHABLE_RETURN(x) __builtin_unreachable();
+#endif
+
+#ifndef BOOST_COMPILER
+#  define BOOST_COMPILER "GNU C++ version " __VERSION__
+#endif
+
+// ConceptGCC compiler:
+//   http://www.generic-programming.org/software/ConceptGCC/
+#ifdef __GXX_CONCEPTS__
+#  define BOOST_HAS_CONCEPTS
+#  define BOOST_COMPILER "ConceptGCC version " __VERSION__
+#endif
+
+// versions check:
+// we don't know gcc prior to version 3.30:
+#if (BOOST_GCC_VERSION< 30300)
+#  error "Compiler not configured - please reconfigure"
+#endif
+//
+// last known and checked version is 4.9:
+#if (BOOST_GCC_VERSION > 40900)
+#  if defined(BOOST_ASSERT_CONFIG)
+#     error "Unknown compiler version - please run the configure tests and report the results"
+#  else
+// we don't emit warnings here anymore since there are no defect macros defined for
+// gcc post 3.4, so any failures are gcc regressions...
+//#     warning "Unknown compiler version - please run the configure tests and report the results"
+#  endif
+#endif
diff --git a/third_party/boost/boost/config/no_tr1/functional.hpp b/third_party/boost/boost/config/no_tr1/functional.hpp
new file mode 100644
index 0000000..e395efc
--- /dev/null
+++ b/third_party/boost/boost/config/no_tr1/functional.hpp
@@ -0,0 +1,28 @@
+//  (C) Copyright John Maddock 2005.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// The aim of this header is just to include <functional> but to do
+// so in a way that does not result in recursive inclusion of
+// the Boost TR1 components if boost/tr1/tr1/functional is in the
+// include search path.  We have to do this to avoid circular
+// dependencies:
+//
+
+#ifndef BOOST_CONFIG_FUNCTIONAL
+#  define BOOST_CONFIG_FUNCTIONAL
+
+#  ifndef BOOST_TR1_NO_RECURSION
+#     define BOOST_TR1_NO_RECURSION
+#     define BOOST_CONFIG_NO_FUNCTIONAL_RECURSION
+#  endif
+
+#  include <functional>
+
+#  ifdef BOOST_CONFIG_NO_FUNCTIONAL_RECURSION
+#     undef BOOST_TR1_NO_RECURSION
+#     undef BOOST_CONFIG_NO_FUNCTIONAL_RECURSION
+#  endif
+
+#endif
diff --git a/third_party/boost/boost/config/no_tr1/memory.hpp b/third_party/boost/boost/config/no_tr1/memory.hpp
new file mode 100644
index 0000000..2b5d208
--- /dev/null
+++ b/third_party/boost/boost/config/no_tr1/memory.hpp
@@ -0,0 +1,28 @@
+//  (C) Copyright John Maddock 2005.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// The aim of this header is just to include <memory> but to do
+// so in a way that does not result in recursive inclusion of
+// the Boost TR1 components if boost/tr1/tr1/memory is in the
+// include search path.  We have to do this to avoid circular
+// dependencies:
+//
+
+#ifndef BOOST_CONFIG_MEMORY
+#  define BOOST_CONFIG_MEMORY
+
+#  ifndef BOOST_TR1_NO_RECURSION
+#     define BOOST_TR1_NO_RECURSION
+#     define BOOST_CONFIG_NO_MEMORY_RECURSION
+#  endif
+
+#  include <memory>
+
+#  ifdef BOOST_CONFIG_NO_MEMORY_RECURSION
+#     undef BOOST_TR1_NO_RECURSION
+#     undef BOOST_CONFIG_NO_MEMORY_RECURSION
+#  endif
+
+#endif
diff --git a/third_party/boost/boost/config/platform/linux.hpp b/third_party/boost/boost/config/platform/linux.hpp
new file mode 100644
index 0000000..ada1439
--- /dev/null
+++ b/third_party/boost/boost/config/platform/linux.hpp
@@ -0,0 +1,103 @@
+//  (C) Copyright John Maddock 2001 - 2003.
+//  (C) Copyright Jens Maurer 2001 - 2003.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org for most recent version.
+
+//  linux specific config options:
+
+#define BOOST_PLATFORM "linux"
+
+// make sure we have __GLIBC_PREREQ if available at all
+#ifdef __cplusplus
+#include <cstdlib>
+#else
+#include <stdlib.h>
+#endif
+
+//
+// <stdint.h> added to glibc 2.1.1
+// We can only test for 2.1 though:
+//
+#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1)))
+   // <stdint.h> defines int64_t unconditionally, but <sys/types.h> defines
+   // int64_t only if __GNUC__.  Thus, assume a fully usable <stdint.h>
+   // only when using GCC.
+#  if defined __GNUC__
+#    define BOOST_HAS_STDINT_H
+#  endif
+#endif
+
+#if defined(__LIBCOMO__)
+   //
+   // como on linux doesn't have std:: c functions:
+   // NOTE: versions of libcomo prior to beta28 have octal version numbering,
+   // e.g. version 25 is 21 (dec)
+   //
+#  if __LIBCOMO_VERSION__ <= 20
+#    define BOOST_NO_STDC_NAMESPACE
+#  endif
+
+#  if __LIBCOMO_VERSION__ <= 21
+#    define BOOST_NO_SWPRINTF
+#  endif
+
+#endif
+
+//
+// If glibc is past version 2 then we definitely have
+// gettimeofday, earlier versions may or may not have it:
+//
+#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+#  define BOOST_HAS_GETTIMEOFDAY
+#endif
+
+#ifdef __USE_POSIX199309
+#  define BOOST_HAS_NANOSLEEP
+#endif
+
+#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
+// __GLIBC_PREREQ is available since 2.1.2
+
+   // swprintf is available since glibc 2.2.0
+#  if !__GLIBC_PREREQ(2,2) || (!defined(__USE_ISOC99) && !defined(__USE_UNIX98))
+#    define BOOST_NO_SWPRINTF
+#  endif
+#else
+#  define BOOST_NO_SWPRINTF
+#endif
+
+// boilerplate code:
+#define BOOST_HAS_UNISTD_H
+#include <boost/config/posix_features.hpp>
+#ifdef __USE_GNU
+#define BOOST_HAS_PTHREAD_YIELD
+#endif
+
+#ifndef __GNUC__
+//
+// if the compiler is not gcc we still need to be able to parse
+// the GNU system headers, some of which (mainly <stdint.h>)
+// use GNU specific extensions:
+//
+#  ifndef __extension__
+#     define __extension__
+#  endif
+#  ifndef __const__
+#     define __const__ const
+#  endif
+#  ifndef __volatile__
+#     define __volatile__ volatile
+#  endif
+#  ifndef __signed__
+#     define __signed__ signed
+#  endif
+#  ifndef __typeof__
+#     define __typeof__ typeof
+#  endif
+#  ifndef __inline__
+#     define __inline__ inline
+#  endif
+#endif
diff --git a/third_party/boost/boost/config/platform/macos.hpp b/third_party/boost/boost/config/platform/macos.hpp
new file mode 100644
index 0000000..62b4468
--- /dev/null
+++ b/third_party/boost/boost/config/platform/macos.hpp
@@ -0,0 +1,84 @@
+//  (C) Copyright John Maddock 2001 - 2003.
+//  (C) Copyright Darin Adler 2001 - 2002.
+//  (C) Copyright Bill Kempf 2002.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org for most recent version.
+
+//  Mac OS specific config options:
+
+#define BOOST_PLATFORM "Mac OS"
+
+#if __MACH__ && !defined(_MSL_USING_MSL_C)
+
+// Using the Mac OS X system BSD-style C library.
+
+#  ifndef BOOST_HAS_UNISTD_H
+#    define BOOST_HAS_UNISTD_H
+#  endif
+//
+// Begin by including our boilerplate code for POSIX
+// feature detection, this is safe even when using
+// the MSL as Metrowerks supply their own <unistd.h>
+// to replace the platform-native BSD one. G++ users
+// should also always be able to do this on MaxOS X.
+//
+#  include <boost/config/posix_features.hpp>
+#  ifndef BOOST_HAS_STDINT_H
+#     define BOOST_HAS_STDINT_H
+#  endif
+
+//
+// BSD runtime has pthreads, sigaction, sched_yield and gettimeofday,
+// of these only pthreads are advertised in <unistd.h>, so set the
+// other options explicitly:
+//
+#  define BOOST_HAS_SCHED_YIELD
+#  define BOOST_HAS_GETTIMEOFDAY
+#  define BOOST_HAS_SIGACTION
+
+#  if (__GNUC__ < 3) && !defined( __APPLE_CC__)
+
+// GCC strange "ignore std" mode works better if you pretend everything
+// is in the std namespace, for the most part.
+
+#    define BOOST_NO_STDC_NAMESPACE
+#  endif
+
+#  if (__GNUC__ >= 4)
+
+// Both gcc and intel require these.
+#    define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
+#    define BOOST_HAS_NANOSLEEP
+
+#  endif
+
+#else
+
+// Using the MSL C library.
+
+// We will eventually support threads in non-Carbon builds, but we do
+// not support this yet.
+#  if ( defined(TARGET_API_MAC_CARBON) && TARGET_API_MAC_CARBON ) || ( defined(TARGET_CARBON) && TARGET_CARBON )
+
+#  if !defined(BOOST_HAS_PTHREADS)
+// MPTasks support is deprecated/removed from Boost:
+//#    define BOOST_HAS_MPTASKS
+#  elif ( __dest_os == __mac_os_x )
+// We are doing a Carbon/Mach-O/MSL build which has pthreads, but only the
+// gettimeofday and no posix.
+#  define BOOST_HAS_GETTIMEOFDAY
+#  endif
+
+#ifdef BOOST_HAS_PTHREADS
+#  define BOOST_HAS_THREADS
+#endif
+
+// The remote call manager depends on this.
+#    define BOOST_BIND_ENABLE_PASCAL
+
+#  endif
+
+#endif
diff --git a/third_party/boost/boost/config/posix_features.hpp b/third_party/boost/boost/config/posix_features.hpp
new file mode 100644
index 0000000..8664a95
--- /dev/null
+++ b/third_party/boost/boost/config/posix_features.hpp
@@ -0,0 +1,91 @@
+//  (C) Copyright John Maddock 2001 - 2003.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+//  See http://www.boost.org for most recent version.
+
+// All POSIX feature tests go in this file,
+// Note that we test _POSIX_C_SOURCE and _XOPEN_SOURCE as well
+// _POSIX_VERSION and _XOPEN_VERSION: on some systems POSIX API's
+// may be present but none-functional unless _POSIX_C_SOURCE and
+// _XOPEN_SOURCE have been defined to the right value (it's up
+// to the user to do this *before* including any header, although
+// in most cases the compiler will do this for you).
+
+#  if defined(BOOST_HAS_UNISTD_H)
+#     include <unistd.h>
+
+      // XOpen has <nl_types.h>, but is this the correct version check?
+#     if defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 3)
+#        define BOOST_HAS_NL_TYPES_H
+#     endif
+
+      // POSIX version 6 requires <stdint.h>
+#     if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 200100)
+#        define BOOST_HAS_STDINT_H
+#     endif
+
+      // POSIX version 2 requires <dirent.h>
+#     if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199009L)
+#        define BOOST_HAS_DIRENT_H
+#     endif
+
+      // POSIX version 3 requires <signal.h> to have sigaction:
+#     if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199506L)
+#        define BOOST_HAS_SIGACTION
+#     endif
+      // POSIX defines _POSIX_THREADS > 0 for pthread support,
+      // however some platforms define _POSIX_THREADS without
+      // a value, hence the (_POSIX_THREADS+0 >= 0) check.
+      // Strictly speaking this may catch platforms with a
+      // non-functioning stub <pthreads.h>, but such occurrences should
+      // occur very rarely if at all.
+#     if defined(_POSIX_THREADS) && (_POSIX_THREADS+0 >= 0) && !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_MPTASKS)
+#        define BOOST_HAS_PTHREADS
+#     endif
+
+      // BOOST_HAS_NANOSLEEP:
+      // This is predicated on _POSIX_TIMERS or _XOPEN_REALTIME:
+#     if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS+0 >= 0)) \
+             || (defined(_XOPEN_REALTIME) && (_XOPEN_REALTIME+0 >= 0))
+#        define BOOST_HAS_NANOSLEEP
+#     endif
+
+      // BOOST_HAS_CLOCK_GETTIME:
+      // This is predicated on _POSIX_TIMERS (also on _XOPEN_REALTIME
+      // but at least one platform - linux - defines that flag without
+      // defining clock_gettime):
+#     if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS+0 >= 0))
+#        define BOOST_HAS_CLOCK_GETTIME
+#     endif
+
+      // BOOST_HAS_SCHED_YIELD:
+      // This is predicated on _POSIX_PRIORITY_SCHEDULING or
+      // on _POSIX_THREAD_PRIORITY_SCHEDULING or on _XOPEN_REALTIME.
+#     if defined(_POSIX_PRIORITY_SCHEDULING) && (_POSIX_PRIORITY_SCHEDULING+0 > 0)\
+            || (defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING+0 > 0))\
+            || (defined(_XOPEN_REALTIME) && (_XOPEN_REALTIME+0 >= 0))
+#        define BOOST_HAS_SCHED_YIELD
+#     endif
+
+      // BOOST_HAS_GETTIMEOFDAY:
+      // BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE:
+      // These are predicated on _XOPEN_VERSION, and appears to be first released
+      // in issue 4, version 2 (_XOPEN_VERSION > 500).
+      // Likewise for the functions log1p and expm1.
+#     if defined(_XOPEN_VERSION) && (_XOPEN_VERSION+0 >= 500)
+#        define BOOST_HAS_GETTIMEOFDAY
+#        if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE+0 >= 500)
+#           define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
+#        endif
+#        ifndef BOOST_HAS_LOG1P
+#           define BOOST_HAS_LOG1P
+#        endif
+#        ifndef BOOST_HAS_EXPM1
+#           define BOOST_HAS_EXPM1
+#        endif
+#     endif
+
+#  endif
diff --git a/third_party/boost/boost/config/select_compiler_config.hpp b/third_party/boost/boost/config/select_compiler_config.hpp
new file mode 100644
index 0000000..db71657
--- /dev/null
+++ b/third_party/boost/boost/config/select_compiler_config.hpp
@@ -0,0 +1,147 @@
+//  Boost compiler configuration selection header file
+
+//  (C) Copyright John Maddock 2001 - 2003.
+//  (C) Copyright Martin Wille 2003.
+//  (C) Copyright Guillaume Melquiond 2003.
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  (See accompanying file LICENSE_1_0.txt or copy at
+//   http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org/ for most recent version.
+
+// locate which compiler we are using and define
+// BOOST_COMPILER_CONFIG as needed:
+
+#if defined __CUDACC__
+//  NVIDIA CUDA C++ compiler for GPU
+#   include "boost/config/compiler/nvcc.hpp"
+
+#endif
+
+#if defined(__GCCXML__)
+// GCC-XML emulates other compilers, it has to appear first here!
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc_xml.hpp"
+
+#elif defined(_CRAYC)
+// EDG based Cray compiler:
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/cray.hpp"
+
+#elif defined __COMO__
+//  Comeau C++
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/comeau.hpp"
+
+#elif defined(__PATHSCALE__) && (__PATHCC__ >= 4)
+// PathScale EKOPath compiler (has to come before clang and gcc)
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/pathscale.hpp"
+
+#elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC)
+//  Intel
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/intel.hpp"
+
+#elif defined __clang__ && !defined(__CUDACC__) && !defined(__ibmxl__)
+// when using clang and cuda at same time, you want to appear as gcc
+//  Clang C++ emulates GCC, so it has to appear early.
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/clang.hpp"
+
+#elif defined __DMC__
+//  Digital Mars C++
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/digitalmars.hpp"
+
+# elif defined(__GNUC__) && !defined(__ibmxl__)
+//  GNU C++:
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc.hpp"
+
+#elif defined __KCC
+//  Kai C++
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/kai.hpp"
+
+#elif defined __sgi
+//  SGI MIPSpro C++
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/sgi_mipspro.hpp"
+
+#elif defined __DECCXX
+//  Compaq Tru64 Unix cxx
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/compaq_cxx.hpp"
+
+#elif defined __ghs
+//  Greenhills C++
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/greenhills.hpp"
+
+#elif defined __CODEGEARC__
+//  CodeGear - must be checked for before Borland
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/codegear.hpp"
+
+#elif defined __BORLANDC__
+//  Borland
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/borland.hpp"
+
+#elif defined  __MWERKS__
+//  Metrowerks CodeWarrior
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/metrowerks.hpp"
+
+#elif defined  __SUNPRO_CC
+//  Sun Workshop Compiler C++
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/sunpro_cc.hpp"
+
+#elif defined __HP_aCC
+//  HP aCC
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/hp_acc.hpp"
+
+#elif defined(__MRC__) || defined(__SC__)
+//  MPW MrCpp or SCpp
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/mpw.hpp"
+
+#elif defined(__ibmxl__)
+// IBM XL C/C++ for Linux (Little Endian)
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/xlcpp.hpp"
+
+#elif defined(__IBMCPP__)
+//  IBM Visual Age or IBM XL C/C++ for Linux (Big Endian)
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/vacpp.hpp"
+
+#elif defined(__PGI)
+//  Portland Group Inc.
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/pgi.hpp"
+
+#elif defined _MSC_VER
+//  Microsoft Visual C++
+//
+//  Must remain the last #elif since some other vendors (Metrowerks, for
+//  example) also #define _MSC_VER
+#   define BOOST_COMPILER_CONFIG "boost/config/compiler/visualc.hpp"
+
+#elif defined (BOOST_ASSERT_CONFIG)
+// this must come last - generate an error if we don't
+// recognise the compiler:
+#  error "Unknown compiler - please configure (http://www.boost.org/libs/config/config.htm#configuring) and report the results to the main boost mailing list (http://www.boost.org/more/mailing_lists.htm#main)"
+
+#endif
+
+#if 0
+//
+// This section allows dependency scanners to find all the headers we *might* include:
+//
+#include "boost/config/compiler/gcc_xml.hpp"
+#include "boost/config/compiler/cray.hpp"
+#include "boost/config/compiler/comeau.hpp"
+#include "boost/config/compiler/pathscale.hpp"
+#include "boost/config/compiler/intel.hpp"
+#include "boost/config/compiler/clang.hpp"
+#include "boost/config/compiler/digitalmars.hpp"
+#include "boost/config/compiler/gcc.hpp"
+#include "boost/config/compiler/kai.hpp"
+#include "boost/config/compiler/sgi_mipspro.hpp"
+#include "boost/config/compiler/compaq_cxx.hpp"
+#include "boost/config/compiler/greenhills.hpp"
+#include "boost/config/compiler/codegear.hpp"
+#include "boost/config/compiler/borland.hpp"
+#include "boost/config/compiler/metrowerks.hpp"
+#include "boost/config/compiler/sunpro_cc.hpp"
+#include "boost/config/compiler/hp_acc.hpp"
+#include "boost/config/compiler/mpw.hpp"
+#include "boost/config/compiler/vacpp.hpp"
+#include "boost/config/compiler/pgi.hpp"
+#include "boost/config/compiler/visualc.hpp"
+
+#endif
diff --git a/third_party/boost/boost/config/select_platform_config.hpp b/third_party/boost/boost/config/select_platform_config.hpp
new file mode 100644
index 0000000..b914ad2
--- /dev/null
+++ b/third_party/boost/boost/config/select_platform_config.hpp
@@ -0,0 +1,136 @@
+//  Boost compiler configuration selection header file
+
+//  (C) Copyright John Maddock 2001 - 2002.
+//  (C) Copyright Jens Maurer 2001.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org for most recent version.
+
+// locate which platform we are on and define BOOST_PLATFORM_CONFIG as needed.
+// Note that we define the headers to include using "header_name" not
+// <header_name> in order to prevent macro expansion within the header
+// name (for example "linux" is a macro on linux systems).
+
+#if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC)
+// linux, also other platforms (Hurd etc) that use GLIBC, should these really have their own config headers though?
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/linux.hpp"
+
+#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
+// BSD:
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/bsd.hpp"
+
+#elif defined(sun) || defined(__sun)
+// solaris:
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/solaris.hpp"
+
+#elif defined(__sgi)
+// SGI Irix:
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/irix.hpp"
+
+#elif defined(__hpux)
+// hp unix:
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/hpux.hpp"
+
+#elif defined(__CYGWIN__)
+// cygwin is not win32:
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/cygwin.hpp"
+
+#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+// win32:
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/win32.hpp"
+
+#elif defined(__HAIKU__)
+// Haiku
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/haiku.hpp"
+
+#elif defined(__BEOS__)
+// BeOS
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/beos.hpp"
+
+#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+// MacOS
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/macos.hpp"
+
+#elif defined(__IBMCPP__) || defined(_AIX)
+// IBM
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/aix.hpp"
+
+#elif defined(__amigaos__)
+// AmigaOS
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/amigaos.hpp"
+
+#elif defined(__QNXNTO__)
+// QNX:
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/qnxnto.hpp"
+
+#elif defined(__VXWORKS__)
+// vxWorks:
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/vxworks.hpp"
+
+#elif defined(__SYMBIAN32__)
+// Symbian:
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/symbian.hpp"
+
+#elif defined(_CRAYC)
+// Cray:
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/cray.hpp"
+
+#elif defined(__VMS)
+// VMS:
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/vms.hpp"
+
+#elif defined(__CloudABI__)
+// Nuxi CloudABI:
+#  define BOOST_PLATFORM_CONFIG "boost/config/platform/cloudabi.hpp"
+#else
+
+#  if defined(unix) \
+      || defined(__unix) \
+      || defined(_XOPEN_SOURCE) \
+      || defined(_POSIX_SOURCE)
+
+   // generic unix platform:
+
+#  ifndef BOOST_HAS_UNISTD_H
+#     define BOOST_HAS_UNISTD_H
+#  endif
+
+#  include <boost/config/posix_features.hpp>
+
+#  endif
+
+#  if defined (BOOST_ASSERT_CONFIG)
+      // this must come last - generate an error if we don't
+      // recognise the platform:
+#     error "Unknown platform - please configure and report the results to boost.org"
+#  endif
+
+#endif
+
+#if 0
+//
+// This section allows dependency scanners to find all the files we *might* include:
+//
+#  include "boost/config/platform/linux.hpp"
+#  include "boost/config/platform/bsd.hpp"
+#  include "boost/config/platform/solaris.hpp"
+#  include "boost/config/platform/irix.hpp"
+#  include "boost/config/platform/hpux.hpp"
+#  include "boost/config/platform/cygwin.hpp"
+#  include "boost/config/platform/win32.hpp"
+#  include "boost/config/platform/beos.hpp"
+#  include "boost/config/platform/macos.hpp"
+#  include "boost/config/platform/aix.hpp"
+#  include "boost/config/platform/amigaos.hpp"
+#  include "boost/config/platform/qnxnto.hpp"
+#  include "boost/config/platform/vxworks.hpp"
+#  include "boost/config/platform/symbian.hpp"
+#  include "boost/config/platform/cray.hpp"
+#  include "boost/config/platform/vms.hpp"
+#  include <boost/config/posix_features.hpp>
+
+
+
+#endif
diff --git a/third_party/boost/boost/config/select_stdlib_config.hpp b/third_party/boost/boost/config/select_stdlib_config.hpp
new file mode 100644
index 0000000..a88dd7e
--- /dev/null
+++ b/third_party/boost/boost/config/select_stdlib_config.hpp
@@ -0,0 +1,104 @@
+//  Boost compiler configuration selection header file
+
+//  (C) Copyright John Maddock 2001 - 2003.
+//  (C) Copyright Jens Maurer 2001 - 2002.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+
+//  See http://www.boost.org for most recent version.
+
+// locate which std lib we are using and define BOOST_STDLIB_CONFIG as needed:
+
+// First include <cstddef> to determine if some version of STLport is in use as the std lib
+// (do not rely on this header being included since users can short-circuit this header
+//  if they know whose std lib they are using.)
+#ifdef __cplusplus
+#  include <cstddef>
+#else
+#  include <stddef.h>
+#endif
+
+#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
+// STLPort library; this _must_ come first, otherwise since
+// STLport typically sits on top of some other library, we
+// can end up detecting that first rather than STLport:
+#  define BOOST_STDLIB_CONFIG "boost/config/stdlib/stlport.hpp"
+
+#else
+
+// If our std lib was not some version of STLport, and has not otherwise
+// been detected, then include <utility> as it is about
+// the smallest of the std lib headers that includes real C++ stuff.
+// Some std libs do not include their C++-related macros in <cstddef>
+// so this additional include makes sure we get those definitions.
+// Note: do not rely on this header being included since users can short-circuit this
+// #include if they know whose std lib they are using.
+#if !defined(__LIBCOMO__) && !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER)\
+   && !defined(_LIBCPP_VERSION) && !defined(__GLIBCPP__) && !defined(__GLIBCXX__)\
+   && !defined(__STL_CONFIG_H) && !defined(__MSL_CPP__) && !defined(__IBMCPP__)\
+   && !defined(MSIPL_COMPILE_H) && !defined(_YVALS) && !defined(_CPPLIB_VER)
+#include <utility>
+#endif
+
+#if defined(__LIBCOMO__)
+// Comeau STL:
+#define BOOST_STDLIB_CONFIG "boost/config/stdlib/libcomo.hpp"
+
+#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER)
+// Rogue Wave library:
+#  define BOOST_STDLIB_CONFIG "boost/config/stdlib/roguewave.hpp"
+
+#elif defined(_LIBCPP_VERSION)
+// libc++
+#  define BOOST_STDLIB_CONFIG "boost/config/stdlib/libcpp.hpp"
+
+#elif defined(__GLIBCPP__) || defined(__GLIBCXX__)
+// GNU libstdc++ 3
+#  define BOOST_STDLIB_CONFIG "boost/config/stdlib/libstdcpp3.hpp"
+
+#elif defined(__STL_CONFIG_H)
+// generic SGI STL
+#  define BOOST_STDLIB_CONFIG "boost/config/stdlib/sgi.hpp"
+
+#elif defined(__MSL_CPP__)
+// MSL standard lib:
+#  define BOOST_STDLIB_CONFIG "boost/config/stdlib/msl.hpp"
+
+#elif defined(__IBMCPP__)
+// take the default VACPP std lib
+#  define BOOST_STDLIB_CONFIG "boost/config/stdlib/vacpp.hpp"
+
+#elif defined(MSIPL_COMPILE_H)
+// Modena C++ standard library
+#  define BOOST_STDLIB_CONFIG "boost/config/stdlib/modena.hpp"
+
+#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
+// Dinkumware Library (this has to appear after any possible replacement libraries):
+#  define BOOST_STDLIB_CONFIG "boost/config/stdlib/dinkumware.hpp"
+
+#elif defined (BOOST_ASSERT_CONFIG)
+// this must come last - generate an error if we don't
+// recognise the library:
+#  error "Unknown standard library - please configure and report the results to boost.org"
+
+#endif
+
+#endif
+
+#if 0
+//
+// This section allows dependency scanners to find all the files we *might* include:
+//
+#  include "boost/config/stdlib/stlport.hpp"
+#  include "boost/config/stdlib/libcomo.hpp"
+#  include "boost/config/stdlib/roguewave.hpp"
+#  include "boost/config/stdlib/libcpp.hpp"
+#  include "boost/config/stdlib/libstdcpp3.hpp"
+#  include "boost/config/stdlib/sgi.hpp"
+#  include "boost/config/stdlib/msl.hpp"
+#  include "boost/config/stdlib/vacpp.hpp"
+#  include "boost/config/stdlib/modena.hpp"
+#  include "boost/config/stdlib/dinkumware.hpp"
+#endif
diff --git a/third_party/boost/boost/config/stdlib/libcpp.hpp b/third_party/boost/boost/config/stdlib/libcpp.hpp
new file mode 100644
index 0000000..ab5d123
--- /dev/null
+++ b/third_party/boost/boost/config/stdlib/libcpp.hpp
@@ -0,0 +1,80 @@
+//  (C) Copyright Christopher Jefferson 2011.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org for most recent version.
+
+//  config for libc++
+//  Might need more in here later.
+
+#if !defined(_LIBCPP_VERSION)
+#  include <ciso646>
+#  if !defined(_LIBCPP_VERSION)
+#      error "This is not libc++!"
+#  endif
+#endif
+
+#define BOOST_STDLIB "libc++ version " BOOST_STRINGIZE(_LIBCPP_VERSION)
+
+#define BOOST_HAS_THREADS
+
+#ifdef _LIBCPP_HAS_NO_VARIADICS
+#    define BOOST_NO_CXX11_HDR_TUPLE
+#endif
+
+// BOOST_NO_CXX11_ALLOCATOR should imply no support for the C++11
+// allocator model. The C++11 allocator model requires a conforming
+// std::allocator_traits which is only possible with C++11 template
+// aliases since members rebind_alloc and rebind_traits require it.
+#if defined(_LIBCPP_HAS_NO_TEMPLATE_ALIASES)
+#    define BOOST_NO_CXX11_ALLOCATOR
+#endif
+
+#if __cplusplus < 201103
+#  define BOOST_NO_CXX11_HDR_ARRAY
+#  define BOOST_NO_CXX11_HDR_CODECVT
+#  define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE
+#  define BOOST_NO_CXX11_HDR_FORWARD_LIST
+#  define BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+#  define BOOST_NO_CXX11_HDR_MUTEX
+#  define BOOST_NO_CXX11_HDR_RANDOM
+#  define BOOST_NO_CXX11_HDR_RATIO
+#  define BOOST_NO_CXX11_HDR_REGEX
+#  define BOOST_NO_CXX11_HDR_SYSTEM_ERROR
+#  define BOOST_NO_CXX11_HDR_THREAD
+#  define BOOST_NO_CXX11_HDR_TUPLE
+#  define BOOST_NO_CXX11_HDR_TYPEINDEX
+#  define BOOST_NO_CXX11_HDR_UNORDERED_MAP
+#  define BOOST_NO_CXX11_HDR_UNORDERED_SET
+#  define BOOST_NO_CXX11_NUMERIC_LIMITS
+#  define BOOST_NO_CXX11_ALLOCATOR
+#  define BOOST_NO_CXX11_SMART_PTR
+#  define BOOST_NO_CXX11_HDR_FUNCTIONAL
+#  define BOOST_NO_CXX11_STD_ALIGN
+#  define BOOST_NO_CXX11_ADDRESSOF
+#endif
+
+//
+// These appear to be unusable/incomplete so far:
+//
+#  define BOOST_NO_CXX11_HDR_CHRONO
+#  define BOOST_NO_CXX11_HDR_FUTURE
+#  define BOOST_NO_CXX11_HDR_TYPE_TRAITS
+#  define BOOST_NO_CXX11_ATOMIC_SMART_PTR
+#  define BOOST_NO_CXX11_HDR_ATOMIC
+
+// libc++ uses a non-standard messages_base
+#define BOOST_NO_STD_MESSAGES
+
+#if defined(__has_include)
+#if !__has_include(<shared_mutex>)
+#  define BOOST_NO_CXX14_HDR_SHARED_MUTEX
+#elif __cplusplus <= 201103
+#  define BOOST_NO_CXX14_HDR_SHARED_MUTEX
+#endif
+#elif __cplusplus < 201402
+#  define BOOST_NO_CXX14_HDR_SHARED_MUTEX
+#endif
+
+//  --- end ---
diff --git a/third_party/boost/boost/config/stdlib/libstdcpp3.hpp b/third_party/boost/boost/config/stdlib/libstdcpp3.hpp
new file mode 100644
index 0000000..bcfa213
--- /dev/null
+++ b/third_party/boost/boost/config/stdlib/libstdcpp3.hpp
@@ -0,0 +1,281 @@
+//  (C) Copyright John Maddock 2001.
+//  (C) Copyright Jens Maurer 2001.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org for most recent version.
+
+//  config for libstdc++ v3
+//  not much to go in here:
+
+#define BOOST_GNU_STDLIB 1
+
+#ifdef __GLIBCXX__
+#define BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCXX__)
+#else
+#define BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCPP__)
+#endif
+
+#if !defined(_GLIBCPP_USE_WCHAR_T) && !defined(_GLIBCXX_USE_WCHAR_T)
+#  define BOOST_NO_CWCHAR
+#  define BOOST_NO_CWCTYPE
+#  define BOOST_NO_STD_WSTRING
+#  define BOOST_NO_STD_WSTREAMBUF
+#endif
+
+#if defined(__osf__) && !defined(_REENTRANT) \
+  && ( defined(_GLIBCXX_HAVE_GTHR_DEFAULT) || defined(_GLIBCPP_HAVE_GTHR_DEFAULT) )
+// GCC 3 on Tru64 forces the definition of _REENTRANT when any std lib header
+// file is included, therefore for consistency we define it here as well.
+#  define _REENTRANT
+#endif
+
+#ifdef __GLIBCXX__ // gcc 3.4 and greater:
+#  if defined(_GLIBCXX_HAVE_GTHR_DEFAULT) \
+        || defined(_GLIBCXX__PTHREADS) \
+        || defined(_GLIBCXX_HAS_GTHREADS) \
+        || defined(_WIN32) \
+        || defined(_AIX) \
+        || defined(__HAIKU__)
+      //
+      // If the std lib has thread support turned on, then turn it on in Boost
+      // as well.  We do this because some gcc-3.4 std lib headers define _REENTANT
+      // while others do not...
+      //
+#     define BOOST_HAS_THREADS
+#  else
+#     define BOOST_DISABLE_THREADS
+#  endif
+#elif defined(__GLIBCPP__) \
+        && !defined(_GLIBCPP_HAVE_GTHR_DEFAULT) \
+        && !defined(_GLIBCPP__PTHREADS)
+   // disable thread support if the std lib was built single threaded:
+#  define BOOST_DISABLE_THREADS
+#endif
+
+#if (defined(linux) || defined(__linux) || defined(__linux__)) && defined(__arm__) && defined(_GLIBCPP_HAVE_GTHR_DEFAULT)
+// linux on arm apparently doesn't define _REENTRANT
+// so just turn on threading support whenever the std lib is thread safe:
+#  define BOOST_HAS_THREADS
+#endif
+
+#if !defined(_GLIBCPP_USE_LONG_LONG) \
+    && !defined(_GLIBCXX_USE_LONG_LONG)\
+    && defined(BOOST_HAS_LONG_LONG)
+// May have been set by compiler/*.hpp, but "long long" without library
+// support is useless.
+#  undef BOOST_HAS_LONG_LONG
+#endif
+
+// Apple doesn't seem to reliably defined a *unix* macro
+#if !defined(CYGWIN) && (  defined(__unix__)  \
+                        || defined(__unix)    \
+                        || defined(unix)      \
+                        || defined(__APPLE__) \
+                        || defined(__APPLE)   \
+                        || defined(APPLE))
+#  include <unistd.h>
+#endif
+
+#if defined(__GLIBCXX__) || (defined(__GLIBCPP__) && __GLIBCPP__>=20020514) // GCC >= 3.1.0
+#  define BOOST_STD_EXTENSION_NAMESPACE __gnu_cxx
+#  define BOOST_HAS_SLIST
+#  define BOOST_HAS_HASH
+#  define BOOST_SLIST_HEADER <ext/slist>
+# if !defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3)
+#   define BOOST_HASH_SET_HEADER <ext/hash_set>
+#   define BOOST_HASH_MAP_HEADER <ext/hash_map>
+# else
+#   define BOOST_HASH_SET_HEADER <backward/hash_set>
+#   define BOOST_HASH_MAP_HEADER <backward/hash_map>
+# endif
+#endif
+
+//
+// Decide whether we have C++11 support turned on:
+//
+#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103)
+#  define BOOST_LIBSTDCXX11
+#endif
+//
+//  Decide which version of libstdc++ we have, normally
+//  stdlibc++ C++0x support is detected via __GNUC__, __GNUC_MINOR__, and possibly
+//  __GNUC_PATCHLEVEL__ at the suggestion of Jonathan Wakely, one of the stdlibc++
+//  developers. He also commented:
+//
+//       "I'm not sure how useful __GLIBCXX__ is for your purposes, for instance in
+//       GCC 4.2.4 it is set to 20080519 but in GCC 4.3.0 it is set to 20080305.
+//       Although 4.3.0 was released earlier than 4.2.4, it has better C++0x support
+//       than any release in the 4.2 series."
+//
+//  Another resource for understanding stdlibc++ features is:
+//  http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#manual.intro.status.standard.200x
+//
+//  However, using the GCC version number fails when the compiler is clang since this
+//  only ever claims to emulate GCC-4.2, see https://svn.boost.org/trac/boost/ticket/7473
+//  for a long discussion on this issue.  What we can do though is use clang's __has_include
+//  to detect the presence of a C++11 header that was introduced with a specific GCC release.
+//  We still have to be careful though as many such headers were buggy and/or incomplete when
+//  first introduced, so we only check for headers that were fully featured from day 1, and then
+//  use that to infer the underlying GCC version:
+//
+#ifdef __clang__
+
+#if __has_include(<experimental/any>)
+#  define BOOST_LIBSTDCXX_VERSION 50100
+#elif __has_include(<shared_mutex>)
+#  define BOOST_LIBSTDCXX_VERSION 40900
+#elif __has_include(<ext/cmath>)
+#  define BOOST_LIBSTDCXX_VERSION 40800
+#elif __has_include(<scoped_allocator>)
+#  define BOOST_LIBSTDCXX_VERSION 40700
+#elif __has_include(<typeindex>)
+#  define BOOST_LIBSTDCXX_VERSION 40600
+#elif __has_include(<future>)
+#  define BOOST_LIBSTDCXX_VERSION 40500
+#elif  __has_include(<ratio>)
+#  define BOOST_LIBSTDCXX_VERSION 40400
+#elif __has_include(<array>)
+#  define BOOST_LIBSTDCXX_VERSION 40300
+#endif
+//
+//  GCC 4.8 and 9 add working versions of <atomic> and <regex> respectively.
+//  However, we have no test for these as the headers were present but broken
+//  in early GCC versions.
+//
+#endif
+
+#if defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130) && (__cplusplus >= 201103L)
+//
+// Oracle Solaris compiler uses it's own verison of libstdc++ but doesn't
+// set __GNUC__
+//
+#define BOOST_LIBSTDCXX_VERSION 40800
+#endif
+
+#if !defined(BOOST_LIBSTDCXX_VERSION)
+#  define BOOST_LIBSTDCXX_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+#endif
+
+//  C++0x headers in GCC 4.3.0 and later
+//
+#if (BOOST_LIBSTDCXX_VERSION < 40300) || !defined(BOOST_LIBSTDCXX11)
+#  define BOOST_NO_CXX11_HDR_ARRAY
+#  define BOOST_NO_CXX11_HDR_TUPLE
+#  define BOOST_NO_CXX11_HDR_UNORDERED_MAP
+#  define BOOST_NO_CXX11_HDR_UNORDERED_SET
+#  define BOOST_NO_CXX11_HDR_FUNCTIONAL
+#endif
+
+//  C++0x headers in GCC 4.4.0 and later
+//
+#if (BOOST_LIBSTDCXX_VERSION < 40400) || !defined(BOOST_LIBSTDCXX11)
+#  define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE
+#  define BOOST_NO_CXX11_HDR_FORWARD_LIST
+#  define BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+#  define BOOST_NO_CXX11_HDR_MUTEX
+#  define BOOST_NO_CXX11_HDR_RATIO
+#  define BOOST_NO_CXX11_HDR_SYSTEM_ERROR
+#  define BOOST_NO_CXX11_SMART_PTR
+#else
+#  define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG
+#  define BOOST_HAS_TR1_COMPLEX_OVERLOADS
+#endif
+
+//  C++0x features in GCC 4.5.0 and later
+//
+#if (BOOST_LIBSTDCXX_VERSION < 40500) || !defined(BOOST_LIBSTDCXX11)
+#  define BOOST_NO_CXX11_NUMERIC_LIMITS
+#  define BOOST_NO_CXX11_HDR_FUTURE
+#  define BOOST_NO_CXX11_HDR_RANDOM
+#endif
+
+//  C++0x features in GCC 4.6.0 and later
+//
+#if (BOOST_LIBSTDCXX_VERSION < 40600) || !defined(BOOST_LIBSTDCXX11)
+#  define BOOST_NO_CXX11_HDR_TYPEINDEX
+#  define BOOST_NO_CXX11_ADDRESSOF
+#endif
+
+//  C++0x features in GCC 4.7.0 and later
+//
+#if (BOOST_LIBSTDCXX_VERSION < 40700) || !defined(BOOST_LIBSTDCXX11)
+// Note that although <chrono> existed prior to 4.7, "steady_clock" is spelled "monotonic_clock"
+// so 4.7.0 is the first truely conforming one.
+#  define BOOST_NO_CXX11_HDR_CHRONO
+#  define BOOST_NO_CXX11_ALLOCATOR
+#endif
+//  C++0x features in GCC 4.8.0 and later
+//
+#if (BOOST_LIBSTDCXX_VERSION < 40800) || !defined(BOOST_LIBSTDCXX11)
+// Note that although <atomic> existed prior to gcc 4.8 it was largely unimplemented for many types:
+#  define BOOST_NO_CXX11_HDR_ATOMIC
+#  define BOOST_NO_CXX11_HDR_THREAD
+#endif
+//  C++0x features in GCC 4.9.0 and later
+//
+#if (BOOST_LIBSTDCXX_VERSION < 40900) || !defined(BOOST_LIBSTDCXX11)
+// Although <regex> is present and compilable against, the actual implementation is not functional
+// even for the simplest patterns such as "\d" or "[0-9]". This is the case at least in gcc up to 4.8, inclusively.
+#  define BOOST_NO_CXX11_HDR_REGEX
+#endif
+
+#if defined(__clang_major__) && ((__clang_major__ < 3) || ((__clang_major__ == 3) && (__clang_minor__ < 7)))
+// As of clang-3.6, libstdc++ header <atomic> throws up errors with clang:
+#  define BOOST_NO_CXX11_HDR_ATOMIC
+#endif
+//
+//  C++0x features in GCC 5.1 and later
+//
+#if (BOOST_LIBSTDCXX_VERSION < 50100) || !defined(BOOST_LIBSTDCXX11)
+#  define BOOST_NO_CXX11_HDR_TYPE_TRAITS
+#  define BOOST_NO_CXX11_HDR_CODECVT
+#  define BOOST_NO_CXX11_ATOMIC_SMART_PTR
+#  define BOOST_NO_CXX11_STD_ALIGN
+#endif
+
+#if defined(__has_include)
+#if !__has_include(<shared_mutex>)
+#  define BOOST_NO_CXX14_HDR_SHARED_MUTEX
+#elif __cplusplus <= 201103
+#  define BOOST_NO_CXX14_HDR_SHARED_MUTEX
+#endif
+#elif __cplusplus < 201402 || (BOOST_LIBSTDCXX_VERSION < 40900) || !defined(BOOST_LIBSTDCXX11)
+#  define BOOST_NO_CXX14_HDR_SHARED_MUTEX
+#endif
+
+//
+// Headers not present on Solaris with the Oracle compiler:
+#if defined(__SUNPRO_CC)
+#define BOOST_NO_CXX11_HDR_FUTURE
+#define BOOST_NO_CXX11_HDR_FORWARD_LIST
+#define BOOST_NO_CXX11_HDR_ATOMIC
+// shared_ptr is present, but is not convertible to bool
+// which causes all kinds of problems especially in Boost.Thread
+// but probably elsewhere as well.
+#define BOOST_NO_CXX11_SMART_PTR
+#endif
+
+#if (!defined(_GLIBCXX_HAS_GTHREADS) || !defined(_GLIBCXX_USE_C99_STDINT_TR1))
+   // Headers not always available:
+#  ifndef BOOST_NO_CXX11_HDR_CONDITION_VARIABLE
+#     define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE
+#  endif
+#  ifndef BOOST_NO_CXX11_HDR_MUTEX
+#     define BOOST_NO_CXX11_HDR_MUTEX
+#  endif
+#  ifndef BOOST_NO_CXX11_HDR_THREAD
+#     define BOOST_NO_CXX11_HDR_THREAD
+#  endif
+#  ifndef BOOST_NO_CXX14_HDR_SHARED_MUTEX
+#     define BOOST_NO_CXX14_HDR_SHARED_MUTEX
+#  endif
+#endif
+
+#if (!defined(_GTHREAD_USE_MUTEX_TIMEDLOCK) || (_GTHREAD_USE_MUTEX_TIMEDLOCK == 0)) && !defined(BOOST_NO_CXX11_HDR_MUTEX)
+// Timed mutexes are not always available:
+#  define BOOST_NO_CXX11_HDR_MUTEX
+#endif
+
+//  --- end ---
diff --git a/third_party/boost/boost/config/suffix.hpp b/third_party/boost/boost/config/suffix.hpp
new file mode 100644
index 0000000..b395e37
--- /dev/null
+++ b/third_party/boost/boost/config/suffix.hpp
@@ -0,0 +1,1007 @@
+//  Boost config.hpp configuration header file  ------------------------------//
+//  boostinspect:ndprecated_macros -- tell the inspect tool to ignore this file
+
+//  Copyright (c) 2001-2003 John Maddock
+//  Copyright (c) 2001 Darin Adler
+//  Copyright (c) 2001 Peter Dimov
+//  Copyright (c) 2002 Bill Kempf
+//  Copyright (c) 2002 Jens Maurer
+//  Copyright (c) 2002-2003 David Abrahams
+//  Copyright (c) 2003 Gennaro Prota
+//  Copyright (c) 2003 Eric Friedman
+//  Copyright (c) 2010 Eric Jourdanneau, Joel Falcou
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org/ for most recent version.
+
+//  Boost config.hpp policy and rationale documentation has been moved to
+//  http://www.boost.org/libs/config/
+//
+//  This file is intended to be stable, and relatively unchanging.
+//  It should contain boilerplate code only - no compiler specific
+//  code unless it is unavoidable - no changes unless unavoidable.
+
+#ifndef BOOST_CONFIG_SUFFIX_HPP
+#define BOOST_CONFIG_SUFFIX_HPP
+
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+//
+// Some GCC-4.x versions issue warnings even when __extension__ is used,
+// so use this as a workaround:
+//
+#pragma GCC system_header
+#endif
+
+//
+// ensure that visibility macros are always defined, thus symplifying use
+//
+#ifndef BOOST_SYMBOL_EXPORT
+# define BOOST_SYMBOL_EXPORT
+#endif
+#ifndef BOOST_SYMBOL_IMPORT
+# define BOOST_SYMBOL_IMPORT
+#endif
+#ifndef BOOST_SYMBOL_VISIBLE
+# define BOOST_SYMBOL_VISIBLE
+#endif
+
+//
+// look for long long by looking for the appropriate macros in <limits.h>.
+// Note that we use limits.h rather than climits for maximal portability,
+// remember that since these just declare a bunch of macros, there should be
+// no namespace issues from this.
+//
+#if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_LONG_LONG)                                              \
+   && !defined(BOOST_MSVC) && !defined(__BORLANDC__)
+# include <limits.h>
+# if (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX))
+#   define BOOST_HAS_LONG_LONG
+# else
+#   define BOOST_NO_LONG_LONG
+# endif
+#endif
+
+// GCC 3.x will clean up all of those nasty macro definitions that
+// BOOST_NO_CTYPE_FUNCTIONS is intended to help work around, so undefine
+// it under GCC 3.x.
+#if defined(__GNUC__) && (__GNUC__ >= 3) && defined(BOOST_NO_CTYPE_FUNCTIONS)
+#  undef BOOST_NO_CTYPE_FUNCTIONS
+#endif
+
+//
+// Assume any extensions are in namespace std:: unless stated otherwise:
+//
+#  ifndef BOOST_STD_EXTENSION_NAMESPACE
+#    define BOOST_STD_EXTENSION_NAMESPACE std
+#  endif
+
+//
+// If cv-qualified specializations are not allowed, then neither are cv-void ones:
+//
+#  if defined(BOOST_NO_CV_SPECIALIZATIONS) \
+      && !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
+#     define BOOST_NO_CV_VOID_SPECIALIZATIONS
+#  endif
+
+//
+// If there is no numeric_limits template, then it can't have any compile time
+// constants either!
+//
+#  if defined(BOOST_NO_LIMITS) \
+      && !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS)
+#     define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
+#     define BOOST_NO_MS_INT64_NUMERIC_LIMITS
+#     define BOOST_NO_LONG_LONG_NUMERIC_LIMITS
+#  endif
+
+//
+// if there is no long long then there is no specialisation
+// for numeric_limits<long long> either:
+//
+#if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS)
+#  define BOOST_NO_LONG_LONG_NUMERIC_LIMITS
+#endif
+
+//
+// if there is no __int64 then there is no specialisation
+// for numeric_limits<__int64> either:
+//
+#if !defined(BOOST_HAS_MS_INT64) && !defined(BOOST_NO_MS_INT64_NUMERIC_LIMITS)
+#  define BOOST_NO_MS_INT64_NUMERIC_LIMITS
+#endif
+
+//
+// if member templates are supported then so is the
+// VC6 subset of member templates:
+//
+#  if !defined(BOOST_NO_MEMBER_TEMPLATES) \
+       && !defined(BOOST_MSVC6_MEMBER_TEMPLATES)
+#     define BOOST_MSVC6_MEMBER_TEMPLATES
+#  endif
+
+//
+// Without partial specialization, can't test for partial specialisation bugs:
+//
+#  if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
+      && !defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG)
+#     define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG
+#  endif
+
+//
+// Without partial specialization, we can't have array-type partial specialisations:
+//
+#  if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
+      && !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS)
+#     define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS
+#  endif
+
+//
+// Without partial specialization, std::iterator_traits can't work:
+//
+#  if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
+      && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
+#     define BOOST_NO_STD_ITERATOR_TRAITS
+#  endif
+
+//
+// Without partial specialization, partial
+// specialization with default args won't work either:
+//
+#  if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
+      && !defined(BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS)
+#     define BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS
+#  endif
+
+//
+// Without member template support, we can't have template constructors
+// in the standard library either:
+//
+#  if defined(BOOST_NO_MEMBER_TEMPLATES) \
+      && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \
+      && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)
+#     define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
+#  endif
+
+//
+// Without member template support, we can't have a conforming
+// std::allocator template either:
+//
+#  if defined(BOOST_NO_MEMBER_TEMPLATES) \
+      && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \
+      && !defined(BOOST_NO_STD_ALLOCATOR)
+#     define BOOST_NO_STD_ALLOCATOR
+#  endif
+
+//
+// without ADL support then using declarations will break ADL as well:
+//
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL)
+#  define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL
+#endif
+
+//
+// Without typeid support we have no dynamic RTTI either:
+//
+#if defined(BOOST_NO_TYPEID) && !defined(BOOST_NO_RTTI)
+#  define BOOST_NO_RTTI
+#endif
+
+//
+// If we have a standard allocator, then we have a partial one as well:
+//
+#if !defined(BOOST_NO_STD_ALLOCATOR)
+#  define BOOST_HAS_PARTIAL_STD_ALLOCATOR
+#endif
+
+//
+// We can't have a working std::use_facet if there is no std::locale:
+//
+#  if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_USE_FACET)
+#     define BOOST_NO_STD_USE_FACET
+#  endif
+
+//
+// We can't have a std::messages facet if there is no std::locale:
+//
+#  if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_MESSAGES)
+#     define BOOST_NO_STD_MESSAGES
+#  endif
+
+//
+// We can't have a working std::wstreambuf if there is no std::locale:
+//
+#  if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_WSTREAMBUF)
+#     define BOOST_NO_STD_WSTREAMBUF
+#  endif
+
+//
+// We can't have a <cwctype> if there is no <cwchar>:
+//
+#  if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_CWCTYPE)
+#     define BOOST_NO_CWCTYPE
+#  endif
+
+//
+// We can't have a swprintf if there is no <cwchar>:
+//
+#  if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_SWPRINTF)
+#     define BOOST_NO_SWPRINTF
+#  endif
+
+//
+// If Win32 support is turned off, then we must turn off
+// threading support also, unless there is some other
+// thread API enabled:
+//
+#if defined(BOOST_DISABLE_WIN32) && defined(_WIN32) \
+   && !defined(BOOST_DISABLE_THREADS) && !defined(BOOST_HAS_PTHREADS)
+#  define BOOST_DISABLE_THREADS
+#endif
+
+//
+// Turn on threading support if the compiler thinks that it's in
+// multithreaded mode.  We put this here because there are only a
+// limited number of macros that identify this (if there's any missing
+// from here then add to the appropriate compiler section):
+//
+#if (defined(__MT__) || defined(_MT) || defined(_REENTRANT) \
+    || defined(_PTHREADS) || defined(__APPLE__) || defined(__DragonFly__)) \
+    && !defined(BOOST_HAS_THREADS)
+#  define BOOST_HAS_THREADS
+#endif
+
+//
+// Turn threading support off if BOOST_DISABLE_THREADS is defined:
+//
+#if defined(BOOST_DISABLE_THREADS) && defined(BOOST_HAS_THREADS)
+#  undef BOOST_HAS_THREADS
+#endif
+
+//
+// Turn threading support off if we don't recognise the threading API:
+//
+#if defined(BOOST_HAS_THREADS) && !defined(BOOST_HAS_PTHREADS)\
+      && !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_BETHREADS)\
+      && !defined(BOOST_HAS_MPTASKS)
+#  undef BOOST_HAS_THREADS
+#endif
+
+//
+// Turn threading detail macros off if we don't (want to) use threading
+//
+#ifndef BOOST_HAS_THREADS
+#  undef BOOST_HAS_PTHREADS
+#  undef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
+#  undef BOOST_HAS_PTHREAD_YIELD
+#  undef BOOST_HAS_PTHREAD_DELAY_NP
+#  undef BOOST_HAS_WINTHREADS
+#  undef BOOST_HAS_BETHREADS
+#  undef BOOST_HAS_MPTASKS
+#endif
+
+//
+// If the compiler claims to be C99 conformant, then it had better
+// have a <stdint.h>:
+//
+#  if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
+#     define BOOST_HAS_STDINT_H
+#     ifndef BOOST_HAS_LOG1P
+#        define BOOST_HAS_LOG1P
+#     endif
+#     ifndef BOOST_HAS_EXPM1
+#        define BOOST_HAS_EXPM1
+#     endif
+#  endif
+
+//
+// Define BOOST_NO_SLIST and BOOST_NO_HASH if required.
+// Note that this is for backwards compatibility only.
+//
+#  if !defined(BOOST_HAS_SLIST) && !defined(BOOST_NO_SLIST)
+#     define BOOST_NO_SLIST
+#  endif
+
+#  if !defined(BOOST_HAS_HASH) && !defined(BOOST_NO_HASH)
+#     define BOOST_NO_HASH
+#  endif
+
+//
+// Set BOOST_SLIST_HEADER if not set already:
+//
+#if defined(BOOST_HAS_SLIST) && !defined(BOOST_SLIST_HEADER)
+#  define BOOST_SLIST_HEADER <slist>
+#endif
+
+//
+// Set BOOST_HASH_SET_HEADER if not set already:
+//
+#if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_SET_HEADER)
+#  define BOOST_HASH_SET_HEADER <hash_set>
+#endif
+
+//
+// Set BOOST_HASH_MAP_HEADER if not set already:
+//
+#if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_MAP_HEADER)
+#  define BOOST_HASH_MAP_HEADER <hash_map>
+#endif
+
+//  BOOST_HAS_ABI_HEADERS
+//  This macro gets set if we have headers that fix the ABI,
+//  and prevent ODR violations when linking to external libraries:
+#if defined(BOOST_ABI_PREFIX) && defined(BOOST_ABI_SUFFIX) && !defined(BOOST_HAS_ABI_HEADERS)
+#  define BOOST_HAS_ABI_HEADERS
+#endif
+
+#if defined(BOOST_HAS_ABI_HEADERS) && defined(BOOST_DISABLE_ABI_HEADERS)
+#  undef BOOST_HAS_ABI_HEADERS
+#endif
+
+//  BOOST_NO_STDC_NAMESPACE workaround  --------------------------------------//
+//  Because std::size_t usage is so common, even in boost headers which do not
+//  otherwise use the C library, the <cstddef> workaround is included here so
+//  that ugly workaround code need not appear in many other boost headers.
+//  NOTE WELL: This is a workaround for non-conforming compilers; <cstddef>
+//  must still be #included in the usual places so that <cstddef> inclusion
+//  works as expected with standard conforming compilers.  The resulting
+//  double inclusion of <cstddef> is harmless.
+
+# if defined(BOOST_NO_STDC_NAMESPACE) && defined(__cplusplus)
+#   include <cstddef>
+    namespace std { using ::ptrdiff_t; using ::size_t; }
+# endif
+
+//  Workaround for the unfortunate min/max macros defined by some platform headers
+
+#define BOOST_PREVENT_MACRO_SUBSTITUTION
+
+#ifndef BOOST_USING_STD_MIN
+#  define BOOST_USING_STD_MIN() using std::min
+#endif
+
+#ifndef BOOST_USING_STD_MAX
+#  define BOOST_USING_STD_MAX() using std::max
+#endif
+
+//  BOOST_NO_STD_MIN_MAX workaround  -----------------------------------------//
+
+#  if defined(BOOST_NO_STD_MIN_MAX) && defined(__cplusplus)
+
+namespace std {
+  template <class _Tp>
+  inline const _Tp& min BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) {
+    return __b < __a ? __b : __a;
+  }
+  template <class _Tp>
+  inline const _Tp& max BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) {
+    return  __a < __b ? __b : __a;
+  }
+}
+
+#  endif
+
+// BOOST_STATIC_CONSTANT workaround --------------------------------------- //
+// On compilers which don't allow in-class initialization of static integral
+// constant members, we must use enums as a workaround if we want the constants
+// to be available at compile-time. This macro gives us a convenient way to
+// declare such constants.
+
+#  ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
+#       define BOOST_STATIC_CONSTANT(type, assignment) enum { assignment }
+#  else
+#     define BOOST_STATIC_CONSTANT(type, assignment) static const type assignment
+#  endif
+
+// BOOST_USE_FACET / HAS_FACET workaround ----------------------------------//
+// When the standard library does not have a conforming std::use_facet there
+// are various workarounds available, but they differ from library to library.
+// The same problem occurs with has_facet.
+// These macros provide a consistent way to access a locale's facets.
+// Usage:
+//    replace
+//       std::use_facet<Type>(loc);
+//    with
+//       BOOST_USE_FACET(Type, loc);
+//    Note do not add a std:: prefix to the front of BOOST_USE_FACET!
+//  Use for BOOST_HAS_FACET is analogous.
+
+#if defined(BOOST_NO_STD_USE_FACET)
+#  ifdef BOOST_HAS_TWO_ARG_USE_FACET
+#     define BOOST_USE_FACET(Type, loc) std::use_facet(loc, static_cast<Type*>(0))
+#     define BOOST_HAS_FACET(Type, loc) std::has_facet(loc, static_cast<Type*>(0))
+#  elif defined(BOOST_HAS_MACRO_USE_FACET)
+#     define BOOST_USE_FACET(Type, loc) std::_USE(loc, Type)
+#     define BOOST_HAS_FACET(Type, loc) std::_HAS(loc, Type)
+#  elif defined(BOOST_HAS_STLP_USE_FACET)
+#     define BOOST_USE_FACET(Type, loc) (*std::_Use_facet<Type >(loc))
+#     define BOOST_HAS_FACET(Type, loc) std::has_facet< Type >(loc)
+#  endif
+#else
+#  define BOOST_USE_FACET(Type, loc) std::use_facet< Type >(loc)
+#  define BOOST_HAS_FACET(Type, loc) std::has_facet< Type >(loc)
+#endif
+
+// BOOST_NESTED_TEMPLATE workaround ------------------------------------------//
+// Member templates are supported by some compilers even though they can't use
+// the A::template member<U> syntax, as a workaround replace:
+//
+// typedef typename A::template rebind<U> binder;
+//
+// with:
+//
+// typedef typename A::BOOST_NESTED_TEMPLATE rebind<U> binder;
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_KEYWORD
+#  define BOOST_NESTED_TEMPLATE template
+#else
+#  define BOOST_NESTED_TEMPLATE
+#endif
+
+// BOOST_UNREACHABLE_RETURN(x) workaround -------------------------------------//
+// Normally evaluates to nothing, unless BOOST_NO_UNREACHABLE_RETURN_DETECTION
+// is defined, in which case it evaluates to return x; Use when you have a return
+// statement that can never be reached.
+
+#ifndef BOOST_UNREACHABLE_RETURN
+#  ifdef BOOST_NO_UNREACHABLE_RETURN_DETECTION
+#     define BOOST_UNREACHABLE_RETURN(x) return x;
+#  else
+#     define BOOST_UNREACHABLE_RETURN(x)
+#  endif
+#endif
+
+// BOOST_DEDUCED_TYPENAME workaround ------------------------------------------//
+//
+// Some compilers don't support the use of `typename' for dependent
+// types in deduced contexts, e.g.
+//
+//     template <class T> void f(T, typename T::type);
+//                                  ^^^^^^^^
+// Replace these declarations with:
+//
+//     template <class T> void f(T, BOOST_DEDUCED_TYPENAME T::type);
+
+#ifndef BOOST_NO_DEDUCED_TYPENAME
+#  define BOOST_DEDUCED_TYPENAME typename
+#else
+#  define BOOST_DEDUCED_TYPENAME
+#endif
+
+#ifndef BOOST_NO_TYPENAME_WITH_CTOR
+#  define BOOST_CTOR_TYPENAME typename
+#else
+#  define BOOST_CTOR_TYPENAME
+#endif
+
+// long long workaround ------------------------------------------//
+// On gcc (and maybe other compilers?) long long is alway supported
+// but it's use may generate either warnings (with -ansi), or errors
+// (with -pedantic -ansi) unless it's use is prefixed by __extension__
+//
+#if defined(BOOST_HAS_LONG_LONG) && defined(__cplusplus)
+namespace boost{
+#  ifdef __GNUC__
+   __extension__ typedef long long long_long_type;
+   __extension__ typedef unsigned long long ulong_long_type;
+#  else
+   typedef long long long_long_type;
+   typedef unsigned long long ulong_long_type;
+#  endif
+}
+#endif
+// same again for __int128:
+#if defined(BOOST_HAS_INT128) && defined(__cplusplus)
+namespace boost{
+#  ifdef __GNUC__
+   __extension__ typedef __int128 int128_type;
+   __extension__ typedef unsigned __int128 uint128_type;
+#  else
+   typedef __int128 int128_type;
+   typedef unsigned __int128 uint128_type;
+#  endif
+}
+#endif
+// same again for __float128:
+#if defined(BOOST_HAS_FLOAT128) && defined(__cplusplus)
+namespace boost {
+#  ifdef __GNUC__
+   __extension__ typedef __float128 float128_type;
+#  else
+   typedef __float128 float128_type;
+#  endif
+}
+#endif
+
+// BOOST_[APPEND_]EXPLICIT_TEMPLATE_[NON_]TYPE macros --------------------------//
+
+// These macros are obsolete. Port away and remove.
+
+#  define BOOST_EXPLICIT_TEMPLATE_TYPE(t)
+#  define BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t)
+#  define BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t, v)
+#  define BOOST_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v)
+
+#  define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t)
+#  define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t)
+#  define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v)
+#  define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v)
+
+// When BOOST_NO_STD_TYPEINFO is defined, we can just import
+// the global definition into std namespace:
+#if defined(BOOST_NO_STD_TYPEINFO) && defined(__cplusplus)
+#include <typeinfo>
+namespace std{ using ::type_info; }
+#endif
+
+// ---------------------------------------------------------------------------//
+
+//
+// Helper macro BOOST_STRINGIZE:
+// Converts the parameter X to a string after macro replacement
+// on X has been performed.
+//
+#define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X)
+#define BOOST_DO_STRINGIZE(X) #X
+
+//
+// Helper macro BOOST_JOIN:
+// The following piece of macro magic joins the two
+// arguments together, even when one of the arguments is
+// itself a macro (see 16.3.1 in C++ standard).  The key
+// is that macro expansion of macro arguments does not
+// occur in BOOST_DO_JOIN2 but does in BOOST_DO_JOIN.
+//
+#define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y )
+#define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y)
+#define BOOST_DO_JOIN2( X, Y ) X##Y
+
+//
+// Set some default values for compiler/library/platform names.
+// These are for debugging config setup only:
+//
+#  ifndef BOOST_COMPILER
+#     define BOOST_COMPILER "Unknown ISO C++ Compiler"
+#  endif
+#  ifndef BOOST_STDLIB
+#     define BOOST_STDLIB "Unknown ISO standard library"
+#  endif
+#  ifndef BOOST_PLATFORM
+#     if defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) \
+         || defined(_POSIX_SOURCE)
+#        define BOOST_PLATFORM "Generic Unix"
+#     else
+#        define BOOST_PLATFORM "Unknown"
+#     endif
+#  endif
+
+//
+// Set some default values GPU support
+//
+#  ifndef BOOST_GPU_ENABLED
+#  define BOOST_GPU_ENABLED
+#  endif
+
+// BOOST_FORCEINLINE ---------------------------------------------//
+// Macro to use in place of 'inline' to force a function to be inline
+#if !defined(BOOST_FORCEINLINE)
+#  if defined(_MSC_VER)
+#    define BOOST_FORCEINLINE __forceinline
+#  elif defined(__GNUC__) && __GNUC__ > 3
+     // Clang also defines __GNUC__ (as 4)
+#    define BOOST_FORCEINLINE inline __attribute__ ((__always_inline__))
+#  else
+#    define BOOST_FORCEINLINE inline
+#  endif
+#endif
+
+// BOOST_NOINLINE ---------------------------------------------//
+// Macro to use in place of 'inline' to prevent a function to be inlined
+#if !defined(BOOST_NOINLINE)
+#  if defined(_MSC_VER)
+#    define BOOST_NOINLINE __declspec(noinline)
+#  elif defined(__GNUC__) && __GNUC__ > 3
+     // Clang also defines __GNUC__ (as 4)
+#    if defined(__CUDACC__)
+       // nvcc doesn't always parse __noinline__,
+       // see: https://svn.boost.org/trac/boost/ticket/9392
+#      define BOOST_NOINLINE __attribute__ ((noinline))
+#    else
+#      define BOOST_NOINLINE __attribute__ ((__noinline__))
+#    endif
+#  else
+#    define BOOST_NOINLINE
+#  endif
+#endif
+
+// BOOST_NORETURN ---------------------------------------------//
+// Macro to use before a function declaration/definition to designate
+// the function as not returning normally (i.e. with a return statement
+// or by leaving the function scope, if the function return type is void).
+#if !defined(BOOST_NORETURN)
+#  if defined(_MSC_VER)
+#    define BOOST_NORETURN __declspec(noreturn)
+#  elif defined(__GNUC__)
+#    define BOOST_NORETURN __attribute__ ((__noreturn__))
+#  else
+#    define BOOST_NO_NORETURN
+#    define BOOST_NORETURN
+#  endif
+#endif
+
+// Branch prediction hints
+// These macros are intended to wrap conditional expressions that yield true or false
+//
+//  if (BOOST_LIKELY(var == 10))
+//  {
+//     // the most probable code here
+//  }
+//
+#if !defined(BOOST_LIKELY)
+#  define BOOST_LIKELY(x) x
+#endif
+#if !defined(BOOST_UNLIKELY)
+#  define BOOST_UNLIKELY(x) x
+#endif
+
+// Type and data alignment specification
+//
+#if !defined(BOOST_NO_CXX11_ALIGNAS)
+#  define BOOST_ALIGNMENT(x) alignas(x)
+#elif defined(_MSC_VER)
+#  define BOOST_ALIGNMENT(x) __declspec(align(x))
+#elif defined(__GNUC__)
+#  define BOOST_ALIGNMENT(x) __attribute__ ((__aligned__(x)))
+#else
+#  define BOOST_NO_ALIGNMENT
+#  define BOOST_ALIGNMENT(x)
+#endif
+
+// Lack of non-public defaulted functions is implied by the lack of any defaulted functions
+#if !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS) && defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
+#  define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS
+#endif
+
+// Defaulted and deleted function declaration helpers
+// These macros are intended to be inside a class definition.
+// BOOST_DEFAULTED_FUNCTION accepts the function declaration and its
+// body, which will be used if the compiler doesn't support defaulted functions.
+// BOOST_DELETED_FUNCTION only accepts the function declaration. It
+// will expand to a private function declaration, if the compiler doesn't support
+// deleted functions. Because of this it is recommended to use BOOST_DELETED_FUNCTION
+// in the end of the class definition.
+//
+//  class my_class
+//  {
+//  public:
+//      // Default-constructible
+//      BOOST_DEFAULTED_FUNCTION(my_class(), {})
+//      // Copying prohibited
+//      BOOST_DELETED_FUNCTION(my_class(my_class const&))
+//      BOOST_DELETED_FUNCTION(my_class& operator= (my_class const&))
+//  };
+//
+#if !(defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS))
+#   define BOOST_DEFAULTED_FUNCTION(fun, body) fun = default;
+#else
+#   define BOOST_DEFAULTED_FUNCTION(fun, body) fun body
+#endif
+
+#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
+#   define BOOST_DELETED_FUNCTION(fun) fun = delete;
+#else
+#   define BOOST_DELETED_FUNCTION(fun) private: fun;
+#endif
+
+//
+// Set BOOST_NO_DECLTYPE_N3276 when BOOST_NO_DECLTYPE is defined
+//
+#if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
+#define BOOST_NO_CXX11_DECLTYPE_N3276 BOOST_NO_CXX11_DECLTYPE
+#endif
+
+//  -------------------- Deprecated macros for 1.50 ---------------------------
+//  These will go away in a future release
+
+//  Use BOOST_NO_CXX11_HDR_UNORDERED_SET or BOOST_NO_CXX11_HDR_UNORDERED_MAP
+//           instead of BOOST_NO_STD_UNORDERED
+#if defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP) || defined (BOOST_NO_CXX11_HDR_UNORDERED_SET)
+# ifndef BOOST_NO_CXX11_STD_UNORDERED
+#  define BOOST_NO_CXX11_STD_UNORDERED
+# endif
+#endif
+
+//  Use BOOST_NO_CXX11_HDR_INITIALIZER_LIST instead of BOOST_NO_INITIALIZER_LISTS
+#if defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_INITIALIZER_LISTS)
+#  define BOOST_NO_INITIALIZER_LISTS
+#endif
+
+//  Use BOOST_NO_CXX11_HDR_ARRAY instead of BOOST_NO_0X_HDR_ARRAY
+#if defined(BOOST_NO_CXX11_HDR_ARRAY) && !defined(BOOST_NO_0X_HDR_ARRAY)
+#  define BOOST_NO_0X_HDR_ARRAY
+#endif
+//  Use BOOST_NO_CXX11_HDR_CHRONO instead of BOOST_NO_0X_HDR_CHRONO
+#if defined(BOOST_NO_CXX11_HDR_CHRONO) && !defined(BOOST_NO_0X_HDR_CHRONO)
+#  define BOOST_NO_0X_HDR_CHRONO
+#endif
+//  Use BOOST_NO_CXX11_HDR_CODECVT instead of BOOST_NO_0X_HDR_CODECVT
+#if defined(BOOST_NO_CXX11_HDR_CODECVT) && !defined(BOOST_NO_0X_HDR_CODECVT)
+#  define BOOST_NO_0X_HDR_CODECVT
+#endif
+//  Use BOOST_NO_CXX11_HDR_CONDITION_VARIABLE instead of BOOST_NO_0X_HDR_CONDITION_VARIABLE
+#if defined(BOOST_NO_CXX11_HDR_CONDITION_VARIABLE) && !defined(BOOST_NO_0X_HDR_CONDITION_VARIABLE)
+#  define BOOST_NO_0X_HDR_CONDITION_VARIABLE
+#endif
+//  Use BOOST_NO_CXX11_HDR_FORWARD_LIST instead of BOOST_NO_0X_HDR_FORWARD_LIST
+#if defined(BOOST_NO_CXX11_HDR_FORWARD_LIST) && !defined(BOOST_NO_0X_HDR_FORWARD_LIST)
+#  define BOOST_NO_0X_HDR_FORWARD_LIST
+#endif
+//  Use BOOST_NO_CXX11_HDR_FUTURE instead of BOOST_NO_0X_HDR_FUTURE
+#if defined(BOOST_NO_CXX11_HDR_FUTURE) && !defined(BOOST_NO_0X_HDR_FUTURE)
+#  define BOOST_NO_0X_HDR_FUTURE
+#endif
+
+//  Use BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+//  instead of BOOST_NO_0X_HDR_INITIALIZER_LIST or BOOST_NO_INITIALIZER_LISTS
+#ifdef BOOST_NO_CXX11_HDR_INITIALIZER_LIST
+# ifndef BOOST_NO_0X_HDR_INITIALIZER_LIST
+#  define BOOST_NO_0X_HDR_INITIALIZER_LIST
+# endif
+# ifndef BOOST_NO_INITIALIZER_LISTS
+#  define BOOST_NO_INITIALIZER_LISTS
+# endif
+#endif
+
+//  Use BOOST_NO_CXX11_HDR_MUTEX instead of BOOST_NO_0X_HDR_MUTEX
+#if defined(BOOST_NO_CXX11_HDR_MUTEX) && !defined(BOOST_NO_0X_HDR_MUTEX)
+#  define BOOST_NO_0X_HDR_MUTEX
+#endif
+//  Use BOOST_NO_CXX11_HDR_RANDOM instead of BOOST_NO_0X_HDR_RANDOM
+#if defined(BOOST_NO_CXX11_HDR_RANDOM) && !defined(BOOST_NO_0X_HDR_RANDOM)
+#  define BOOST_NO_0X_HDR_RANDOM
+#endif
+//  Use BOOST_NO_CXX11_HDR_RATIO instead of BOOST_NO_0X_HDR_RATIO
+#if defined(BOOST_NO_CXX11_HDR_RATIO) && !defined(BOOST_NO_0X_HDR_RATIO)
+#  define BOOST_NO_0X_HDR_RATIO
+#endif
+//  Use BOOST_NO_CXX11_HDR_REGEX instead of BOOST_NO_0X_HDR_REGEX
+#if defined(BOOST_NO_CXX11_HDR_REGEX) && !defined(BOOST_NO_0X_HDR_REGEX)
+#  define BOOST_NO_0X_HDR_REGEX
+#endif
+//  Use BOOST_NO_CXX11_HDR_SYSTEM_ERROR instead of BOOST_NO_0X_HDR_SYSTEM_ERROR
+#if defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) && !defined(BOOST_NO_0X_HDR_SYSTEM_ERROR)
+#  define BOOST_NO_0X_HDR_SYSTEM_ERROR
+#endif
+//  Use BOOST_NO_CXX11_HDR_THREAD instead of BOOST_NO_0X_HDR_THREAD
+#if defined(BOOST_NO_CXX11_HDR_THREAD) && !defined(BOOST_NO_0X_HDR_THREAD)
+#  define BOOST_NO_0X_HDR_THREAD
+#endif
+//  Use BOOST_NO_CXX11_HDR_TUPLE instead of BOOST_NO_0X_HDR_TUPLE
+#if defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_0X_HDR_TUPLE)
+#  define BOOST_NO_0X_HDR_TUPLE
+#endif
+//  Use BOOST_NO_CXX11_HDR_TYPE_TRAITS instead of BOOST_NO_0X_HDR_TYPE_TRAITS
+#if defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_NO_0X_HDR_TYPE_TRAITS)
+#  define BOOST_NO_0X_HDR_TYPE_TRAITS
+#endif
+//  Use BOOST_NO_CXX11_HDR_TYPEINDEX instead of BOOST_NO_0X_HDR_TYPEINDEX
+#if defined(BOOST_NO_CXX11_HDR_TYPEINDEX) && !defined(BOOST_NO_0X_HDR_TYPEINDEX)
+#  define BOOST_NO_0X_HDR_TYPEINDEX
+#endif
+//  Use BOOST_NO_CXX11_HDR_UNORDERED_MAP instead of BOOST_NO_0X_HDR_UNORDERED_MAP
+#if defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP) && !defined(BOOST_NO_0X_HDR_UNORDERED_MAP)
+#  define BOOST_NO_0X_HDR_UNORDERED_MAP
+#endif
+//  Use BOOST_NO_CXX11_HDR_UNORDERED_SET instead of BOOST_NO_0X_HDR_UNORDERED_SET
+#if defined(BOOST_NO_CXX11_HDR_UNORDERED_SET) && !defined(BOOST_NO_0X_HDR_UNORDERED_SET)
+#  define BOOST_NO_0X_HDR_UNORDERED_SET
+#endif
+
+//  ------------------ End of deprecated macros for 1.50 ---------------------------
+
+//  -------------------- Deprecated macros for 1.51 ---------------------------
+//  These will go away in a future release
+
+//  Use     BOOST_NO_CXX11_AUTO_DECLARATIONS instead of   BOOST_NO_AUTO_DECLARATIONS
+#if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && !defined(BOOST_NO_AUTO_DECLARATIONS)
+#  define BOOST_NO_AUTO_DECLARATIONS
+#endif
+//  Use     BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS instead of   BOOST_NO_AUTO_MULTIDECLARATIONS
+#if defined(BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS) && !defined(BOOST_NO_AUTO_MULTIDECLARATIONS)
+#  define BOOST_NO_AUTO_MULTIDECLARATIONS
+#endif
+//  Use     BOOST_NO_CXX11_CHAR16_T instead of   BOOST_NO_CHAR16_T
+#if defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CHAR16_T)
+#  define BOOST_NO_CHAR16_T
+#endif
+//  Use     BOOST_NO_CXX11_CHAR32_T instead of   BOOST_NO_CHAR32_T
+#if defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CHAR32_T)
+#  define BOOST_NO_CHAR32_T
+#endif
+//  Use     BOOST_NO_CXX11_TEMPLATE_ALIASES instead of   BOOST_NO_TEMPLATE_ALIASES
+#if defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !defined(BOOST_NO_TEMPLATE_ALIASES)
+#  define BOOST_NO_TEMPLATE_ALIASES
+#endif
+//  Use     BOOST_NO_CXX11_CONSTEXPR instead of   BOOST_NO_CONSTEXPR
+#if defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CONSTEXPR)
+#  define BOOST_NO_CONSTEXPR
+#endif
+//  Use     BOOST_NO_CXX11_DECLTYPE_N3276 instead of   BOOST_NO_DECLTYPE_N3276
+#if defined(BOOST_NO_CXX11_DECLTYPE_N3276) && !defined(BOOST_NO_DECLTYPE_N3276)
+#  define BOOST_NO_DECLTYPE_N3276
+#endif
+//  Use     BOOST_NO_CXX11_DECLTYPE instead of   BOOST_NO_DECLTYPE
+#if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_DECLTYPE)
+#  define BOOST_NO_DECLTYPE
+#endif
+//  Use     BOOST_NO_CXX11_DEFAULTED_FUNCTIONS instead of   BOOST_NO_DEFAULTED_FUNCTIONS
+#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_DEFAULTED_FUNCTIONS)
+#  define BOOST_NO_DEFAULTED_FUNCTIONS
+#endif
+//  Use     BOOST_NO_CXX11_DELETED_FUNCTIONS instead of   BOOST_NO_DELETED_FUNCTIONS
+#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_DELETED_FUNCTIONS)
+#  define BOOST_NO_DELETED_FUNCTIONS
+#endif
+//  Use     BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS instead of   BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
+#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) && !defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS)
+#  define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS
+#endif
+//  Use     BOOST_NO_CXX11_EXTERN_TEMPLATE instead of   BOOST_NO_EXTERN_TEMPLATE
+#if defined(BOOST_NO_CXX11_EXTERN_TEMPLATE) && !defined(BOOST_NO_EXTERN_TEMPLATE)
+#  define BOOST_NO_EXTERN_TEMPLATE
+#endif
+//  Use     BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS instead of   BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS
+#if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && !defined(BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS)
+#  define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS
+#endif
+//  Use     BOOST_NO_CXX11_LAMBDAS instead of   BOOST_NO_LAMBDAS
+#if defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_LAMBDAS)
+#  define BOOST_NO_LAMBDAS
+#endif
+//  Use     BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS instead of   BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS
+#if defined(BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS) && !defined(BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS)
+#  define BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS
+#endif
+//  Use     BOOST_NO_CXX11_NOEXCEPT instead of   BOOST_NO_NOEXCEPT
+#if defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_NOEXCEPT)
+#  define BOOST_NO_NOEXCEPT
+#endif
+//  Use     BOOST_NO_CXX11_NULLPTR instead of   BOOST_NO_NULLPTR
+#if defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_NULLPTR)
+#  define BOOST_NO_NULLPTR
+#endif
+//  Use     BOOST_NO_CXX11_RAW_LITERALS instead of   BOOST_NO_RAW_LITERALS
+#if defined(BOOST_NO_CXX11_RAW_LITERALS) && !defined(BOOST_NO_RAW_LITERALS)
+#  define BOOST_NO_RAW_LITERALS
+#endif
+//  Use     BOOST_NO_CXX11_RVALUE_REFERENCES instead of   BOOST_NO_RVALUE_REFERENCES
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_RVALUE_REFERENCES)
+#  define BOOST_NO_RVALUE_REFERENCES
+#endif
+//  Use     BOOST_NO_CXX11_SCOPED_ENUMS instead of   BOOST_NO_SCOPED_ENUMS
+#if defined(BOOST_NO_CXX11_SCOPED_ENUMS) && !defined(BOOST_NO_SCOPED_ENUMS)
+#  define BOOST_NO_SCOPED_ENUMS
+#endif
+//  Use     BOOST_NO_CXX11_STATIC_ASSERT instead of   BOOST_NO_STATIC_ASSERT
+#if defined(BOOST_NO_CXX11_STATIC_ASSERT) && !defined(BOOST_NO_STATIC_ASSERT)
+#  define BOOST_NO_STATIC_ASSERT
+#endif
+//  Use     BOOST_NO_CXX11_STD_UNORDERED instead of   BOOST_NO_STD_UNORDERED
+#if defined(BOOST_NO_CXX11_STD_UNORDERED) && !defined(BOOST_NO_STD_UNORDERED)
+#  define BOOST_NO_STD_UNORDERED
+#endif
+//  Use     BOOST_NO_CXX11_UNICODE_LITERALS instead of   BOOST_NO_UNICODE_LITERALS
+#if defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(BOOST_NO_UNICODE_LITERALS)
+#  define BOOST_NO_UNICODE_LITERALS
+#endif
+//  Use     BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX instead of   BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX
+#if defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !defined(BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX)
+#  define BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX
+#endif
+//  Use     BOOST_NO_CXX11_VARIADIC_TEMPLATES instead of   BOOST_NO_VARIADIC_TEMPLATES
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
+#  define BOOST_NO_VARIADIC_TEMPLATES
+#endif
+//  Use     BOOST_NO_CXX11_VARIADIC_MACROS instead of   BOOST_NO_VARIADIC_MACROS
+#if defined(BOOST_NO_CXX11_VARIADIC_MACROS) && !defined(BOOST_NO_VARIADIC_MACROS)
+#  define BOOST_NO_VARIADIC_MACROS
+#endif
+//  Use     BOOST_NO_CXX11_NUMERIC_LIMITS instead of   BOOST_NO_NUMERIC_LIMITS_LOWEST
+#if defined(BOOST_NO_CXX11_NUMERIC_LIMITS) && !defined(BOOST_NO_NUMERIC_LIMITS_LOWEST)
+#  define BOOST_NO_NUMERIC_LIMITS_LOWEST
+#endif
+//  ------------------ End of deprecated macros for 1.51 ---------------------------
+
+
+
+//
+// Helper macros BOOST_NOEXCEPT, BOOST_NOEXCEPT_IF, BOOST_NOEXCEPT_EXPR
+// These aid the transition to C++11 while still supporting C++03 compilers
+//
+#ifdef BOOST_NO_CXX11_NOEXCEPT
+#  define BOOST_NOEXCEPT
+#  define BOOST_NOEXCEPT_OR_NOTHROW throw()
+#  define BOOST_NOEXCEPT_IF(Predicate)
+#  define BOOST_NOEXCEPT_EXPR(Expression) false
+#else
+#  define BOOST_NOEXCEPT noexcept
+#  define BOOST_NOEXCEPT_OR_NOTHROW noexcept
+#  define BOOST_NOEXCEPT_IF(Predicate) noexcept((Predicate))
+#  define BOOST_NOEXCEPT_EXPR(Expression) noexcept((Expression))
+#endif
+//
+// Helper macro BOOST_FALLTHROUGH
+// Fallback definition of BOOST_FALLTHROUGH macro used to mark intended
+// fall-through between case labels in a switch statement. We use a definition
+// that requires a semicolon after it to avoid at least one type of misuse even
+// on unsupported compilers.
+//
+#ifndef BOOST_FALLTHROUGH
+#  define BOOST_FALLTHROUGH ((void)0)
+#endif
+
+//
+// constexpr workarounds
+//
+#if defined(BOOST_NO_CXX11_CONSTEXPR)
+#define BOOST_CONSTEXPR
+#define BOOST_CONSTEXPR_OR_CONST const
+#else
+#define BOOST_CONSTEXPR constexpr
+#define BOOST_CONSTEXPR_OR_CONST constexpr
+#endif
+#if defined(BOOST_NO_CXX14_CONSTEXPR)
+#define BOOST_CXX14_CONSTEXPR
+#else
+#define BOOST_CXX14_CONSTEXPR constexpr
+#endif
+
+//
+// Unused variable/typedef workarounds:
+//
+#ifndef BOOST_ATTRIBUTE_UNUSED
+#  define BOOST_ATTRIBUTE_UNUSED
+#endif
+
+#define BOOST_STATIC_CONSTEXPR  static BOOST_CONSTEXPR_OR_CONST
+
+//
+// Set BOOST_HAS_STATIC_ASSERT when BOOST_NO_CXX11_STATIC_ASSERT is not defined
+//
+#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) && !defined(BOOST_HAS_STATIC_ASSERT)
+#  define BOOST_HAS_STATIC_ASSERT
+#endif
+
+//
+// Set BOOST_HAS_RVALUE_REFS when BOOST_NO_CXX11_RVALUE_REFERENCES is not defined
+//
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_HAS_RVALUE_REFS)
+#define BOOST_HAS_RVALUE_REFS
+#endif
+
+//
+// Set BOOST_HAS_VARIADIC_TMPL when BOOST_NO_CXX11_VARIADIC_TEMPLATES is not defined
+//
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_HAS_VARIADIC_TMPL)
+#define BOOST_HAS_VARIADIC_TMPL
+#endif
+//
+// Set BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS when
+// BOOST_NO_CXX11_VARIADIC_TEMPLATES is set:
+//
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS)
+#  define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS
+#endif
+
+//
+// Finish off with checks for macros that are depricated / no longer supported,
+// if any of these are set then it's very likely that much of Boost will no
+// longer work.  So stop with a #error for now, but give the user a chance
+// to continue at their own risk if they really want to:
+//
+#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_CONFIG_ALLOW_DEPRECATED)
+#  error "You are using a compiler which lacks features which are now a minimum requirement in order to use Boost, define BOOST_CONFIG_ALLOW_DEPRECATED if you want to continue at your own risk!!!"
+#endif
+
+#endif
diff --git a/third_party/boost/boost/config/user.hpp b/third_party/boost/boost/config/user.hpp
new file mode 100644
index 0000000..e5ce1a1
--- /dev/null
+++ b/third_party/boost/boost/config/user.hpp
@@ -0,0 +1,132 @@
+//  boost/config/user.hpp  ---------------------------------------------------//
+
+//  (C) Copyright John Maddock 2001.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  Do not check in modified versions of this file,
+//  This file may be customized by the end user, but not by boost.
+
+//
+//  Use this file to define a site and compiler specific
+//  configuration policy:
+//
+
+// define this to locate a compiler config file:
+// #define BOOST_COMPILER_CONFIG <myheader>
+
+// define this to locate a stdlib config file:
+// #define BOOST_STDLIB_CONFIG   <myheader>
+
+// define this to locate a platform config file:
+// #define BOOST_PLATFORM_CONFIG <myheader>
+
+// define this to disable compiler config,
+// use if your compiler config has nothing to set:
+// #define BOOST_NO_COMPILER_CONFIG
+
+// define this to disable stdlib config,
+// use if your stdlib config has nothing to set:
+// #define BOOST_NO_STDLIB_CONFIG
+
+// define this to disable platform config,
+// use if your platform config has nothing to set:
+// #define BOOST_NO_PLATFORM_CONFIG
+
+// define this to disable all config options,
+// excluding the user config.  Use if your
+// setup is fully ISO compliant, and has no
+// useful extensions, or for autoconf generated
+// setups:
+// #define BOOST_NO_CONFIG
+
+// define this to make the config "optimistic"
+// about unknown compiler versions.  Normally
+// unknown compiler versions are assumed to have
+// all the defects of the last known version, however
+// setting this flag, causes the config to assume
+// that unknown compiler versions are fully conformant
+// with the standard:
+// #define BOOST_STRICT_CONFIG
+
+// define this to cause the config to halt compilation
+// with an #error if it encounters anything unknown --
+// either an unknown compiler version or an unknown
+// compiler/platform/library:
+// #define BOOST_ASSERT_CONFIG
+
+
+// define if you want to disable threading support, even
+// when available:
+// #define BOOST_DISABLE_THREADS
+
+// define when you want to disable Win32 specific features
+// even when available:
+// #define BOOST_DISABLE_WIN32
+
+// BOOST_DISABLE_ABI_HEADERS: Stops boost headers from including any
+// prefix/suffix headers that normally control things like struct
+// packing and alignment.
+// #define BOOST_DISABLE_ABI_HEADERS
+
+// BOOST_ABI_PREFIX: A prefix header to include in place of whatever
+// boost.config would normally select, any replacement should set up
+// struct packing and alignment options as required.
+// #define BOOST_ABI_PREFIX my-header-name
+
+// BOOST_ABI_SUFFIX: A suffix header to include in place of whatever
+// boost.config would normally select, any replacement should undo
+// the effects of the prefix header.
+// #define BOOST_ABI_SUFFIX my-header-name
+
+// BOOST_ALL_DYN_LINK: Forces all libraries that have separate source,
+// to be linked as dll's rather than static libraries on Microsoft Windows
+// (this macro is used to turn on __declspec(dllimport) modifiers, so that
+// the compiler knows which symbols to look for in a dll rather than in a
+// static library).  Note that there may be some libraries that can only
+// be linked in one way (statically or dynamically), in these cases this
+// macro has no effect.
+// #define BOOST_ALL_DYN_LINK
+
+// BOOST_WHATEVER_DYN_LINK: Forces library "whatever" to be linked as a dll
+// rather than a static library on Microsoft Windows: replace the WHATEVER
+// part of the macro name with the name of the library that you want to
+// dynamically link to, for example use BOOST_DATE_TIME_DYN_LINK or
+// BOOST_REGEX_DYN_LINK etc (this macro is used to turn on __declspec(dllimport)
+// modifiers, so that the compiler knows which symbols to look for in a dll
+// rather than in a static library).
+// Note that there may be some libraries that can only
+// be linked in one way (statically or dynamically),
+// in these cases this macro is unsupported.
+// #define BOOST_WHATEVER_DYN_LINK
+
+// BOOST_ALL_NO_LIB: Tells the config system not to automatically select
+// which libraries to link against.
+// Normally if a compiler supports #pragma lib, then the correct library
+// build variant will be automatically selected and linked against,
+// simply by the act of including one of that library's headers.
+// This macro turns that feature off.
+// #define BOOST_ALL_NO_LIB
+
+// BOOST_WHATEVER_NO_LIB: Tells the config system not to automatically
+// select which library to link against for library "whatever",
+// replace WHATEVER in the macro name with the name of the library;
+// for example BOOST_DATE_TIME_NO_LIB or BOOST_REGEX_NO_LIB.
+// Normally if a compiler supports #pragma lib, then the correct library
+// build variant will be automatically selected and linked against, simply
+// by the act of including one of that library's headers.  This macro turns
+// that feature off.
+// #define BOOST_WHATEVER_NO_LIB
+
+// BOOST_LIB_BUILDID: Set to the same value as the value passed to Boost.Build's
+// --buildid command line option.  For example if you built using:
+//
+// bjam address-model=64 --buildid=amd64
+//
+// then compile your code with:
+//
+// -DBOOST_LIB_BUILDID = amd64
+//
+// to ensure the correct libraries are selected at link time.
+// #define BOOST_LIB_BUILDID amd64
diff --git a/third_party/boost/boost/core/addressof.hpp b/third_party/boost/boost/core/addressof.hpp
new file mode 100644
index 0000000..889b582
--- /dev/null
+++ b/third_party/boost/boost/core/addressof.hpp
@@ -0,0 +1,162 @@
+// Copyright (C) 2002 Brad King (brad.king@kitware.com)
+//                    Douglas Gregor (gregod@cs.rpi.edu)
+//
+// Copyright (C) 2002, 2008, 2013 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_CORE_ADDRESSOF_HPP
+#define BOOST_CORE_ADDRESSOF_HPP
+
+# include <boost/config.hpp>
+# include <boost/detail/workaround.hpp>
+# include <cstddef>
+
+namespace boost
+{
+
+namespace detail
+{
+
+template<class T> struct addr_impl_ref
+{
+    T & v_;
+
+    BOOST_FORCEINLINE addr_impl_ref( T & v ): v_( v ) {}
+    BOOST_FORCEINLINE operator T& () const { return v_; }
+
+private:
+    addr_impl_ref & operator=(const addr_impl_ref &);
+};
+
+template<class T> struct addressof_impl
+{
+    static BOOST_FORCEINLINE T * f( T & v, long )
+    {
+        return reinterpret_cast<T*>(
+            &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
+    }
+
+    static BOOST_FORCEINLINE T * f( T * v, int )
+    {
+        return v;
+    }
+};
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) )
+
+    typedef decltype(nullptr) addr_nullptr_t;
+
+#else
+
+    typedef std::nullptr_t addr_nullptr_t;
+
+#endif
+
+template<> struct addressof_impl< addr_nullptr_t >
+{
+    typedef addr_nullptr_t T;
+
+    static BOOST_FORCEINLINE T * f( T & v, int )
+    {
+        return &v;
+    }
+};
+
+template<> struct addressof_impl< addr_nullptr_t const >
+{
+    typedef addr_nullptr_t const T;
+
+    static BOOST_FORCEINLINE T * f( T & v, int )
+    {
+        return &v;
+    }
+};
+
+template<> struct addressof_impl< addr_nullptr_t volatile >
+{
+    typedef addr_nullptr_t volatile T;
+
+    static BOOST_FORCEINLINE T * f( T & v, int )
+    {
+        return &v;
+    }
+};
+
+template<> struct addressof_impl< addr_nullptr_t const volatile >
+{
+    typedef addr_nullptr_t const volatile T;
+
+    static BOOST_FORCEINLINE T * f( T & v, int )
+    {
+        return &v;
+    }
+};
+
+#endif
+
+} // namespace detail
+
+template<class T>
+BOOST_FORCEINLINE
+T * addressof( T & v )
+{
+#if (defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) ) ) || (defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120))
+
+    return boost::detail::addressof_impl<T>::f( v, 0 );
+
+#else
+
+    return boost::detail::addressof_impl<T>::f( boost::detail::addr_impl_ref<T>( v ), 0 );
+
+#endif
+}
+
+#if defined( __SUNPRO_CC ) && BOOST_WORKAROUND( __SUNPRO_CC, BOOST_TESTED_AT( 0x590 ) )
+
+namespace detail
+{
+
+template<class T> struct addressof_addp
+{
+    typedef T * type;
+};
+
+} // namespace detail
+
+template< class T, std::size_t N >
+BOOST_FORCEINLINE
+typename detail::addressof_addp< T[N] >::type addressof( T (&t)[N] )
+{
+    return &t;
+}
+
+#endif
+
+// Borland doesn't like casting an array reference to a char reference
+// but these overloads work around the problem.
+#if defined( __BORLANDC__ ) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+template<typename T,std::size_t N>
+BOOST_FORCEINLINE
+T (*addressof(T (&t)[N]))[N]
+{
+   return reinterpret_cast<T(*)[N]>(&t);
+}
+
+template<typename T,std::size_t N>
+BOOST_FORCEINLINE
+const T (*addressof(const T (&t)[N]))[N]
+{
+   return reinterpret_cast<const T(*)[N]>(&t);
+}
+#endif
+
+} // namespace boost
+
+#endif // BOOST_CORE_ADDRESSOF_HPP
diff --git a/third_party/boost/boost/core/checked_delete.hpp b/third_party/boost/boost/core/checked_delete.hpp
new file mode 100644
index 0000000..b086e03
--- /dev/null
+++ b/third_party/boost/boost/core/checked_delete.hpp
@@ -0,0 +1,69 @@
+#ifndef BOOST_CORE_CHECKED_DELETE_HPP
+#define BOOST_CORE_CHECKED_DELETE_HPP
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  boost/checked_delete.hpp
+//
+//  Copyright (c) 2002, 2003 Peter Dimov
+//  Copyright (c) 2003 Daniel Frey
+//  Copyright (c) 2003 Howard Hinnant
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  See http://www.boost.org/libs/core/doc/html/core/checked_delete.html for documentation.
+//
+
+namespace boost
+{
+
+// verify that types are complete for increased safety
+
+template<class T> inline void checked_delete(T * x)
+{
+    // intentionally complex - simplification causes regressions
+    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
+    (void) sizeof(type_must_be_complete);
+    delete x;
+}
+
+template<class T> inline void checked_array_delete(T * x)
+{
+    typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
+    (void) sizeof(type_must_be_complete);
+    delete [] x;
+}
+
+template<class T> struct checked_deleter
+{
+    typedef void result_type;
+    typedef T * argument_type;
+
+    void operator()(T * x) const
+    {
+        // boost:: disables ADL
+        boost::checked_delete(x);
+    }
+};
+
+template<class T> struct checked_array_deleter
+{
+    typedef void result_type;
+    typedef T * argument_type;
+
+    void operator()(T * x) const
+    {
+        boost::checked_array_delete(x);
+    }
+};
+
+} // namespace boost
+
+#endif  // #ifndef BOOST_CORE_CHECKED_DELETE_HPP
diff --git a/third_party/boost/boost/core/demangle.hpp b/third_party/boost/boost/core/demangle.hpp
new file mode 100644
index 0000000..44aeb8d
--- /dev/null
+++ b/third_party/boost/boost/core/demangle.hpp
@@ -0,0 +1,128 @@
+#ifndef BOOST_CORE_DEMANGLE_HPP_INCLUDED
+#define BOOST_CORE_DEMANGLE_HPP_INCLUDED
+
+// core::demangle
+//
+// Copyright 2014 Peter Dimov
+// Copyright 2014 Andrey Semashev
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/config.hpp>
+#include <string>
+
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+# pragma once
+#endif
+
+#if defined( __clang__ ) && defined( __has_include )
+# if __has_include(<cxxabi.h>)
+#  define BOOST_CORE_HAS_CXXABI_H
+# endif
+#elif defined( __GLIBCXX__ ) || defined( __GLIBCPP__ )
+# define BOOST_CORE_HAS_CXXABI_H
+#endif
+
+#if defined( BOOST_CORE_HAS_CXXABI_H )
+# include <cxxabi.h>
+// For some archtectures (mips, mips64, x86, x86_64) cxxabi.h in Android NDK is implemented by gabi++ library
+// (https://android.googlesource.com/platform/ndk/+/master/sources/cxx-stl/gabi++/), which does not implement
+// abi::__cxa_demangle(). We detect this implementation by checking the include guard here.
+# if defined( __GABIXX_CXXABI_H__ )
+#  undef BOOST_CORE_HAS_CXXABI_H
+# else
+#  include <cstdlib>
+#  include <cstddef>
+# endif
+#endif
+
+namespace boost
+{
+
+namespace core
+{
+
+inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT;
+inline void demangle_free( char const * name ) BOOST_NOEXCEPT;
+
+class scoped_demangled_name
+{
+private:
+    char const * m_p;
+
+public:
+    explicit scoped_demangled_name( char const * name ) BOOST_NOEXCEPT :
+        m_p( demangle_alloc( name ) )
+    {
+    }
+
+    ~scoped_demangled_name() BOOST_NOEXCEPT
+    {
+        demangle_free( m_p );
+    }
+
+    char const * get() const BOOST_NOEXCEPT
+    {
+        return m_p;
+    }
+
+    BOOST_DELETED_FUNCTION(scoped_demangled_name( scoped_demangled_name const& ))
+    BOOST_DELETED_FUNCTION(scoped_demangled_name& operator= ( scoped_demangled_name const& ))
+};
+
+
+#if defined( BOOST_CORE_HAS_CXXABI_H )
+
+inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT
+{
+    int status = 0;
+    std::size_t size = 0;
+    return abi::__cxa_demangle( name, NULL, &size, &status );
+}
+
+inline void demangle_free( char const * name ) BOOST_NOEXCEPT
+{
+    std::free( const_cast< char* >( name ) );
+}
+
+inline std::string demangle( char const * name )
+{
+    scoped_demangled_name demangled_name( name );
+    char const * const p = demangled_name.get();
+    if( p )
+    {
+        return p;
+    }
+    else
+    {
+        return name;
+    }
+}
+
+#else
+
+inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT
+{
+    return name;
+}
+
+inline void demangle_free( char const * ) BOOST_NOEXCEPT
+{
+}
+
+inline std::string demangle( char const * name )
+{
+    return name;
+}
+
+#endif
+
+} // namespace core
+
+} // namespace boost
+
+#undef BOOST_CORE_HAS_CXXABI_H
+
+#endif // #ifndef BOOST_CORE_DEMANGLE_HPP_INCLUDED
diff --git a/third_party/boost/boost/core/enable_if.hpp b/third_party/boost/boost/core/enable_if.hpp
new file mode 100644
index 0000000..b947dab
--- /dev/null
+++ b/third_party/boost/boost/core/enable_if.hpp
@@ -0,0 +1,128 @@
+// Boost enable_if library
+
+// Copyright 2003 (c) The Trustees of Indiana University.
+
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+//    Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
+//             Jeremiah Willcock (jewillco at osl.iu.edu)
+//             Andrew Lumsdaine (lums at osl.iu.edu)
+
+
+#ifndef BOOST_CORE_ENABLE_IF_HPP
+#define BOOST_CORE_ENABLE_IF_HPP
+
+#include "boost/config.hpp"
+
+// Even the definition of enable_if causes problems on some compilers,
+// so it's macroed out for all compilers that do not support SFINAE
+
+#ifndef BOOST_NO_SFINAE
+
+namespace boost
+{
+  template<typename T, typename R=void>
+  struct enable_if_has_type
+  {
+    typedef R type;
+  };
+
+  template <bool B, class T = void>
+  struct enable_if_c {
+    typedef T type;
+  };
+
+  template <class T>
+  struct enable_if_c<false, T> {};
+
+  template <class Cond, class T = void>
+  struct enable_if : public enable_if_c<Cond::value, T> {};
+
+  template <bool B, class T>
+  struct lazy_enable_if_c {
+    typedef typename T::type type;
+  };
+
+  template <class T>
+  struct lazy_enable_if_c<false, T> {};
+
+  template <class Cond, class T>
+  struct lazy_enable_if : public lazy_enable_if_c<Cond::value, T> {};
+
+
+  template <bool B, class T = void>
+  struct disable_if_c {
+    typedef T type;
+  };
+
+  template <class T>
+  struct disable_if_c<true, T> {};
+
+  template <class Cond, class T = void>
+  struct disable_if : public disable_if_c<Cond::value, T> {};
+
+  template <bool B, class T>
+  struct lazy_disable_if_c {
+    typedef typename T::type type;
+  };
+
+  template <class T>
+  struct lazy_disable_if_c<true, T> {};
+
+  template <class Cond, class T>
+  struct lazy_disable_if : public lazy_disable_if_c<Cond::value, T> {};
+
+} // namespace boost
+
+#else
+
+namespace boost {
+
+  namespace detail { typedef void enable_if_default_T; }
+
+  template <typename T>
+  struct enable_if_does_not_work_on_this_compiler;
+
+  template<typename T, typename R=void>
+  struct enable_if_has_type : enable_if_does_not_work_on_this_compiler<T>
+  { };
+
+  template <bool B, class T = detail::enable_if_default_T>
+  struct enable_if_c : enable_if_does_not_work_on_this_compiler<T>
+  { };
+
+  template <bool B, class T = detail::enable_if_default_T>
+  struct disable_if_c : enable_if_does_not_work_on_this_compiler<T>
+  { };
+
+  template <bool B, class T = detail::enable_if_default_T>
+  struct lazy_enable_if_c : enable_if_does_not_work_on_this_compiler<T>
+  { };
+
+  template <bool B, class T = detail::enable_if_default_T>
+  struct lazy_disable_if_c : enable_if_does_not_work_on_this_compiler<T>
+  { };
+
+  template <class Cond, class T = detail::enable_if_default_T>
+  struct enable_if : enable_if_does_not_work_on_this_compiler<T>
+  { };
+
+  template <class Cond, class T = detail::enable_if_default_T>
+  struct disable_if : enable_if_does_not_work_on_this_compiler<T>
+  { };
+
+  template <class Cond, class T = detail::enable_if_default_T>
+  struct lazy_enable_if : enable_if_does_not_work_on_this_compiler<T>
+  { };
+
+  template <class Cond, class T = detail::enable_if_default_T>
+  struct lazy_disable_if : enable_if_does_not_work_on_this_compiler<T>
+  { };
+
+} // namespace boost
+
+#endif // BOOST_NO_SFINAE
+
+#endif
diff --git a/third_party/boost/boost/core/explicit_operator_bool.hpp b/third_party/boost/boost/core/explicit_operator_bool.hpp
new file mode 100644
index 0000000..a8936e2
--- /dev/null
+++ b/third_party/boost/boost/core/explicit_operator_bool.hpp
@@ -0,0 +1,154 @@
+/*
+ *          Copyright Andrey Semashev 2007 - 2013.
+ * Distributed under the Boost Software License, Version 1.0.
+ *    (See accompanying file LICENSE_1_0.txt or copy at
+ *          http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+/*!
+ * \file   explicit_operator_bool.hpp
+ * \author Andrey Semashev
+ * \date   08.03.2009
+ *
+ * This header defines a compatibility macro that implements an unspecified
+ * \c bool operator idiom, which is superseded with explicit conversion operators in
+ * C++11.
+ */
+
+#ifndef BOOST_CORE_EXPLICIT_OPERATOR_BOOL_HPP
+#define BOOST_CORE_EXPLICIT_OPERATOR_BOOL_HPP
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+
+/*!
+ * \brief The macro defines an explicit operator of conversion to \c bool
+ *
+ * The macro should be used inside the definition of a class that has to
+ * support the conversion. The class should also implement <tt>operator!</tt>,
+ * in terms of which the conversion operator will be implemented.
+ */
+#define BOOST_EXPLICIT_OPERATOR_BOOL()\
+    BOOST_FORCEINLINE explicit operator bool () const\
+    {\
+        return !this->operator! ();\
+    }
+
+/*!
+ * \brief The macro defines a noexcept explicit operator of conversion to \c bool
+ *
+ * The macro should be used inside the definition of a class that has to
+ * support the conversion. The class should also implement <tt>operator!</tt>,
+ * in terms of which the conversion operator will be implemented.
+ */
+#define BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()\
+    BOOST_FORCEINLINE explicit operator bool () const BOOST_NOEXCEPT\
+    {\
+        return !this->operator! ();\
+    }
+
+/*!
+ * \brief The macro defines a constexpr explicit operator of conversion to \c bool
+ *
+ * The macro should be used inside the definition of a class that has to
+ * support the conversion. The class should also implement <tt>operator!</tt>,
+ * in terms of which the conversion operator will be implemented.
+ */
+#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\
+    BOOST_FORCEINLINE BOOST_CONSTEXPR explicit operator bool () const BOOST_NOEXCEPT\
+    {\
+        return !this->operator! ();\
+    }
+
+#else // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG)
+// Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
+#define BOOST_NO_UNSPECIFIED_BOOL
+#endif // (defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) && !defined(BOOST_NO_COMPILER_CONFIG)
+
+#if !defined(BOOST_NO_UNSPECIFIED_BOOL)
+
+namespace boost {
+
+namespace detail {
+
+#if !defined(_MSC_VER) && !defined(__IBMCPP__)
+
+    struct unspecified_bool
+    {
+        // NOTE TO THE USER: If you see this in error messages then you tried
+        // to apply an unsupported operator on the object that supports
+        // explicit conversion to bool.
+        struct OPERATORS_NOT_ALLOWED;
+        static void true_value(OPERATORS_NOT_ALLOWED*) {}
+    };
+    typedef void (*unspecified_bool_type)(unspecified_bool::OPERATORS_NOT_ALLOWED*);
+
+#else
+
+    // MSVC and VACPP are too eager to convert pointer to function to void* even though they shouldn't
+    struct unspecified_bool
+    {
+        // NOTE TO THE USER: If you see this in error messages then you tried
+        // to apply an unsupported operator on the object that supports
+        // explicit conversion to bool.
+        struct OPERATORS_NOT_ALLOWED;
+        void true_value(OPERATORS_NOT_ALLOWED*) {}
+    };
+    typedef void (unspecified_bool::*unspecified_bool_type)(unspecified_bool::OPERATORS_NOT_ALLOWED*);
+
+#endif
+
+} // namespace detail
+
+} // namespace boost
+
+#define BOOST_EXPLICIT_OPERATOR_BOOL()\
+    BOOST_FORCEINLINE operator boost::detail::unspecified_bool_type () const\
+    {\
+        return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\
+    }
+
+#define BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()\
+    BOOST_FORCEINLINE operator boost::detail::unspecified_bool_type () const BOOST_NOEXCEPT\
+    {\
+        return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\
+    }
+
+#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\
+    BOOST_FORCEINLINE BOOST_CONSTEXPR operator boost::detail::unspecified_bool_type () const BOOST_NOEXCEPT\
+    {\
+        return (!this->operator! () ? &boost::detail::unspecified_bool::true_value : (boost::detail::unspecified_bool_type)0);\
+    }
+
+#else // !defined(BOOST_NO_UNSPECIFIED_BOOL)
+
+#define BOOST_EXPLICIT_OPERATOR_BOOL()\
+    BOOST_FORCEINLINE operator bool () const\
+    {\
+        return !this->operator! ();\
+    }
+
+#define BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()\
+    BOOST_FORCEINLINE operator bool () const BOOST_NOEXCEPT\
+    {\
+        return !this->operator! ();\
+    }
+
+#define BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL()\
+    BOOST_FORCEINLINE BOOST_CONSTEXPR operator bool () const BOOST_NOEXCEPT\
+    {\
+        return !this->operator! ();\
+    }
+
+#endif // !defined(BOOST_NO_UNSPECIFIED_BOOL)
+
+#endif // !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+
+#endif // BOOST_CORE_EXPLICIT_OPERATOR_BOOL_HPP
diff --git a/third_party/boost/boost/core/is_same.hpp b/third_party/boost/boost/core/is_same.hpp
new file mode 100644
index 0000000..f373c65
--- /dev/null
+++ b/third_party/boost/boost/core/is_same.hpp
@@ -0,0 +1,40 @@
+#ifndef BOOST_CORE_IS_SAME_HPP_INCLUDED
+#define BOOST_CORE_IS_SAME_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+// is_same<T1,T2>::value is true when T1 == T2
+//
+// Copyright 2014 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/config.hpp>
+
+namespace boost
+{
+
+namespace core
+{
+
+template< class T1, class T2 > struct is_same
+{
+    BOOST_STATIC_CONSTANT( bool, value = false );
+};
+
+template< class T > struct is_same< T, T >
+{
+    BOOST_STATIC_CONSTANT( bool, value = true );
+};
+
+} // namespace core
+
+} // namespace boost
+
+#endif // #ifndef BOOST_CORE_IS_SAME_HPP_INCLUDED
diff --git a/third_party/boost/boost/core/no_exceptions_support.hpp b/third_party/boost/boost/core/no_exceptions_support.hpp
new file mode 100644
index 0000000..09b93c9
--- /dev/null
+++ b/third_party/boost/boost/core/no_exceptions_support.hpp
@@ -0,0 +1,44 @@
+#ifndef BOOST_CORE_NO_EXCEPTIONS_SUPPORT_HPP
+#define BOOST_CORE_NO_EXCEPTIONS_SUPPORT_HPP
+
+#if defined(_MSC_VER)
+#  pragma once
+#endif
+
+//----------------------------------------------------------------------
+// (C) Copyright 2004 Pavel Vozenilek.
+// Use, modification and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+// This file contains helper macros used when exception support may be
+// disabled (as indicated by macro BOOST_NO_EXCEPTIONS).
+//
+// Before picking up these macros you may consider using RAII techniques
+// to deal with exceptions - their syntax can be always the same with
+// or without exception support enabled.
+//----------------------------------------------------------------------
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+#if !(defined BOOST_NO_EXCEPTIONS)
+#    define BOOST_TRY { try
+#    define BOOST_CATCH(x) catch(x)
+#    define BOOST_RETHROW throw;
+#    define BOOST_CATCH_END }
+#else
+#    if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#        define BOOST_TRY { if ("")
+#        define BOOST_CATCH(x) else if (!"")
+#    else
+#        define BOOST_TRY { if (true)
+#        define BOOST_CATCH(x) else if (false)
+#    endif
+#    define BOOST_RETHROW
+#    define BOOST_CATCH_END }
+#endif
+
+
+#endif
diff --git a/third_party/boost/boost/core/noncopyable.hpp b/third_party/boost/boost/core/noncopyable.hpp
new file mode 100644
index 0000000..6ae8c24
--- /dev/null
+++ b/third_party/boost/boost/core/noncopyable.hpp
@@ -0,0 +1,48 @@
+//  Boost noncopyable.hpp header file  --------------------------------------//
+
+//  (C) Copyright Beman Dawes 1999-2003. Distributed under the Boost
+//  Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org/libs/utility for documentation.
+
+#ifndef BOOST_CORE_NONCOPYABLE_HPP
+#define BOOST_CORE_NONCOPYABLE_HPP
+
+#include <boost/config.hpp>
+
+namespace boost {
+
+//  Private copy constructor and copy assignment ensure classes derived from
+//  class noncopyable cannot be copied.
+
+//  Contributed by Dave Abrahams
+
+namespace noncopyable_  // protection from unintended ADL
+{
+  class noncopyable
+  {
+  protected:
+#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)
+      BOOST_CONSTEXPR noncopyable() = default;
+      ~noncopyable() = default;
+#else
+      noncopyable() {}
+      ~noncopyable() {}
+#endif
+#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
+      noncopyable( const noncopyable& ) = delete;
+      noncopyable& operator=( const noncopyable& ) = delete;
+#else
+  private:  // emphasize the following members are private
+      noncopyable( const noncopyable& );
+      noncopyable& operator=( const noncopyable& );
+#endif
+  };
+}
+
+typedef noncopyable_::noncopyable noncopyable;
+
+} // namespace boost
+
+#endif  // BOOST_CORE_NONCOPYABLE_HPP
diff --git a/third_party/boost/boost/core/ref.hpp b/third_party/boost/boost/core/ref.hpp
new file mode 100644
index 0000000..47dc858
--- /dev/null
+++ b/third_party/boost/boost/core/ref.hpp
@@ -0,0 +1,301 @@
+#ifndef BOOST_CORE_REF_HPP
+#define BOOST_CORE_REF_HPP
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+#include <boost/config.hpp>
+#include <boost/utility/addressof.hpp>
+#include <boost/detail/workaround.hpp>
+
+//
+//  ref.hpp - ref/cref, useful helper functions
+//
+//  Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
+//  Copyright (C) 2001, 2002 Peter Dimov
+//  Copyright (C) 2002 David Abrahams
+//
+//  Copyright (C) 2014 Glen Joseph Fernandes
+//  glenfe at live dot com
+//  Copyright (C) 2014 Agustin Berge
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//  See http://www.boost.org/libs/core/doc/html/core/ref.html for documentation.
+//
+
+/**
+ @file
+*/
+
+/**
+ Boost namespace.
+*/
+namespace boost
+{
+
+#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
+
+    struct ref_workaround_tag {};
+
+#endif
+
+// reference_wrapper
+
+/**
+ @brief Contains a reference to an object of type `T`.
+
+ `reference_wrapper` is primarily used to "feed" references to
+ function templates (algorithms) that take their parameter by
+ value. It provides an implicit conversion to `T&`, which
+ usually allows the function templates to work on references
+ unmodified.
+*/
+template<class T> class reference_wrapper
+{
+public:
+    /**
+     Type `T`.
+    */
+    typedef T type;
+
+    /**
+     Constructs a `reference_wrapper` object that stores a
+     reference to `t`.
+
+     @remark Does not throw.
+    */
+    BOOST_FORCEINLINE explicit reference_wrapper(T& t): t_(boost::addressof(t)) {}
+
+#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
+
+    BOOST_FORCEINLINE explicit reference_wrapper( T & t, ref_workaround_tag ): t_( boost::addressof( t ) ) {}
+
+#endif
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+    /**
+     @remark Construction from a temporary object is disabled.
+    */
+    BOOST_DELETED_FUNCTION(reference_wrapper(T&& t))
+public:
+#endif
+
+    /**
+     @return The stored reference.
+     @remark Does not throw.
+    */
+    BOOST_FORCEINLINE operator T& () const { return *t_; }
+
+    /**
+     @return The stored reference.
+     @remark Does not throw.
+    */
+    BOOST_FORCEINLINE T& get() const { return *t_; }
+
+    /**
+     @return A pointer to the object referenced by the stored
+       reference.
+     @remark Does not throw.
+    */
+    BOOST_FORCEINLINE T* get_pointer() const { return t_; }
+
+private:
+
+    T* t_;
+};
+
+// ref
+
+/**
+ @cond
+*/
+#if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x581) )
+#  define BOOST_REF_CONST
+#else
+#  define BOOST_REF_CONST const
+#endif
+/**
+ @endcond
+*/
+
+/**
+ @return `reference_wrapper<T>(t)`
+ @remark Does not throw.
+*/
+template<class T> BOOST_FORCEINLINE reference_wrapper<T> BOOST_REF_CONST ref( T & t )
+{
+#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 )
+
+    return reference_wrapper<T>( t, ref_workaround_tag() );
+
+#else
+
+    return reference_wrapper<T>( t );
+
+#endif
+}
+
+// cref
+
+/**
+ @return `reference_wrapper<T const>(t)`
+ @remark Does not throw.
+*/
+template<class T> BOOST_FORCEINLINE reference_wrapper<T const> BOOST_REF_CONST cref( T const & t )
+{
+    return reference_wrapper<T const>(t);
+}
+
+#undef BOOST_REF_CONST
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+/**
+ @cond
+*/
+#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
+#  define BOOST_REF_DELETE
+#else
+#  define BOOST_REF_DELETE = delete
+#endif
+/**
+ @endcond
+*/
+
+/**
+ @remark Construction from a temporary object is disabled.
+*/
+template<class T> void ref(T const&&) BOOST_REF_DELETE;
+
+/**
+ @remark Construction from a temporary object is disabled.
+*/
+template<class T> void cref(T const&&) BOOST_REF_DELETE;
+
+#undef BOOST_REF_DELETE
+
+#endif
+
+// is_reference_wrapper
+
+/**
+ @brief Determine if a type `T` is an instantiation of
+ `reference_wrapper`.
+
+ The value static constant will be true if the type `T` is a
+ specialization of `reference_wrapper`.
+*/
+template<typename T> struct is_reference_wrapper
+{
+    BOOST_STATIC_CONSTANT( bool, value = false );
+};
+
+/**
+ @cond
+*/
+template<typename T> struct is_reference_wrapper< reference_wrapper<T> >
+{
+    BOOST_STATIC_CONSTANT( bool, value = true );
+};
+
+#if !defined(BOOST_NO_CV_SPECIALIZATIONS)
+
+template<typename T> struct is_reference_wrapper< reference_wrapper<T> const >
+{
+    BOOST_STATIC_CONSTANT( bool, value = true );
+};
+
+template<typename T> struct is_reference_wrapper< reference_wrapper<T> volatile >
+{
+    BOOST_STATIC_CONSTANT( bool, value = true );
+};
+
+template<typename T> struct is_reference_wrapper< reference_wrapper<T> const volatile >
+{
+    BOOST_STATIC_CONSTANT( bool, value = true );
+};
+
+#endif // !defined(BOOST_NO_CV_SPECIALIZATIONS)
+
+/**
+ @endcond
+*/
+
+
+// unwrap_reference
+
+/**
+ @brief Find the type in a `reference_wrapper`.
+
+ The `typedef` type is `T::type` if `T` is a
+ `reference_wrapper`, `T` otherwise.
+*/
+template<typename T> struct unwrap_reference
+{
+    typedef T type;
+};
+
+/**
+ @cond
+*/
+template<typename T> struct unwrap_reference< reference_wrapper<T> >
+{
+    typedef T type;
+};
+
+#if !defined(BOOST_NO_CV_SPECIALIZATIONS)
+
+template<typename T> struct unwrap_reference< reference_wrapper<T> const >
+{
+    typedef T type;
+};
+
+template<typename T> struct unwrap_reference< reference_wrapper<T> volatile >
+{
+    typedef T type;
+};
+
+template<typename T> struct unwrap_reference< reference_wrapper<T> const volatile >
+{
+    typedef T type;
+};
+
+#endif // !defined(BOOST_NO_CV_SPECIALIZATIONS)
+
+/**
+ @endcond
+*/
+
+// unwrap_ref
+
+/**
+ @return `unwrap_reference<T>::type&(t)`
+ @remark Does not throw.
+*/
+template<class T> BOOST_FORCEINLINE typename unwrap_reference<T>::type& unwrap_ref( T & t )
+{
+    return t;
+}
+
+// get_pointer
+
+/**
+ @cond
+*/
+template<class T> BOOST_FORCEINLINE T* get_pointer( reference_wrapper<T> const & r )
+{
+    return r.get_pointer();
+}
+/**
+ @endcond
+*/
+
+} // namespace boost
+
+#endif // #ifndef BOOST_CORE_REF_HPP
diff --git a/third_party/boost/boost/core/swap.hpp b/third_party/boost/boost/core/swap.hpp
new file mode 100644
index 0000000..baa1be9
--- /dev/null
+++ b/third_party/boost/boost/core/swap.hpp
@@ -0,0 +1,60 @@
+// Copyright (C) 2007, 2008 Steven Watanabe, Joseph Gauterin, Niels Dekker
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// For more information, see http://www.boost.org
+
+
+#ifndef BOOST_CORE_SWAP_HPP
+#define BOOST_CORE_SWAP_HPP
+
+// Note: the implementation of this utility contains various workarounds:
+// - swap_impl is put outside the boost namespace, to avoid infinite
+// recursion (causing stack overflow) when swapping objects of a primitive
+// type.
+// - swap_impl has a using-directive, rather than a using-declaration,
+// because some compilers (including MSVC 7.1, Borland 5.9.3, and
+// Intel 8.1) don't do argument-dependent lookup when it has a
+// using-declaration instead.
+// - boost::swap has two template arguments, instead of one, to
+// avoid ambiguity when swapping objects of a Boost type that does
+// not have its own boost::swap overload.
+
+#include <utility> //for std::swap (C++11)
+#include <algorithm> //for std::swap (C++98)
+#include <cstddef> //for std::size_t
+#include <boost/config.hpp>
+
+namespace boost_swap_impl
+{
+  template<class T>
+  BOOST_GPU_ENABLED
+  void swap_impl(T& left, T& right)
+  {
+    using namespace std;//use std::swap if argument dependent lookup fails
+    swap(left,right);
+  }
+
+  template<class T, std::size_t N>
+  BOOST_GPU_ENABLED
+  void swap_impl(T (& left)[N], T (& right)[N])
+  {
+    for (std::size_t i = 0; i < N; ++i)
+    {
+      ::boost_swap_impl::swap_impl(left[i], right[i]);
+    }
+  }
+}
+
+namespace boost
+{
+  template<class T1, class T2>
+  BOOST_GPU_ENABLED
+  void swap(T1& left, T2& right)
+  {
+    ::boost_swap_impl::swap_impl(left, right);
+  }
+}
+
+#endif
diff --git a/third_party/boost/boost/core/typeinfo.hpp b/third_party/boost/boost/core/typeinfo.hpp
new file mode 100644
index 0000000..9dbe2c5
--- /dev/null
+++ b/third_party/boost/boost/core/typeinfo.hpp
@@ -0,0 +1,151 @@
+#ifndef BOOST_CORE_TYPEINFO_HPP_INCLUDED
+#define BOOST_CORE_TYPEINFO_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//  core::typeinfo, BOOST_CORE_TYPEID
+//
+//  Copyright 2007, 2014 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/config.hpp>
+
+#if defined( BOOST_NO_TYPEID )
+
+#include <boost/current_function.hpp>
+#include <functional>
+
+namespace boost
+{
+
+namespace core
+{
+
+class typeinfo
+{
+private:
+
+    typeinfo( typeinfo const& );
+    typeinfo& operator=( typeinfo const& );
+
+    char const * name_;
+
+public:
+
+    explicit typeinfo( char const * name ): name_( name )
+    {
+    }
+
+    bool operator==( typeinfo const& rhs ) const
+    {
+        return this == &rhs;
+    }
+
+    bool operator!=( typeinfo const& rhs ) const
+    {
+        return this != &rhs;
+    }
+
+    bool before( typeinfo const& rhs ) const
+    {
+        return std::less< typeinfo const* >()( this, &rhs );
+    }
+
+    char const* name() const
+    {
+        return name_;
+    }
+};
+
+inline char const * demangled_name( core::typeinfo const & ti )
+{
+    return ti.name();
+}
+
+} // namespace core
+
+namespace detail
+{
+
+template<class T> struct core_typeid_
+{
+    static boost::core::typeinfo ti_;
+
+    static char const * name()
+    {
+        return BOOST_CURRENT_FUNCTION;
+    }
+};
+
+#if defined(__SUNPRO_CC)
+// see #4199, the Sun Studio compiler gets confused about static initialization
+// constructor arguments. But an assignment works just fine.
+template<class T> boost::core::typeinfo core_typeid_< T >::ti_ = core_typeid_< T >::name();
+#else
+template<class T> boost::core::typeinfo core_typeid_< T >::ti_(core_typeid_< T >::name());
+#endif
+
+template<class T> struct core_typeid_< T & >: core_typeid_< T >
+{
+};
+
+template<class T> struct core_typeid_< T const >: core_typeid_< T >
+{
+};
+
+template<class T> struct core_typeid_< T volatile >: core_typeid_< T >
+{
+};
+
+template<class T> struct core_typeid_< T const volatile >: core_typeid_< T >
+{
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#define BOOST_CORE_TYPEID(T) (boost::detail::core_typeid_<T>::ti_)
+
+#else
+
+#include <boost/core/demangle.hpp>
+#include <typeinfo>
+
+namespace boost
+{
+
+namespace core
+{
+
+#if defined( BOOST_NO_STD_TYPEINFO )
+
+typedef ::type_info typeinfo;
+
+#else
+
+typedef std::type_info typeinfo;
+
+#endif
+
+inline std::string demangled_name( core::typeinfo const & ti )
+{
+    return core::demangle( ti.name() );
+}
+
+} // namespace core
+
+} // namespace boost
+
+#define BOOST_CORE_TYPEID(T) typeid(T)
+
+#endif
+
+#endif  // #ifndef BOOST_CORE_TYPEINFO_HPP_INCLUDED
diff --git a/third_party/boost/boost/cstdint.hpp b/third_party/boost/boost/cstdint.hpp
new file mode 100644
index 0000000..0651dd5
--- /dev/null
+++ b/third_party/boost/boost/cstdint.hpp
@@ -0,0 +1,542 @@
+//  boost cstdint.hpp header file  ------------------------------------------//
+
+//  (C) Copyright Beman Dawes 1999.
+//  (C) Copyright Jens Mauer 2001
+//  (C) Copyright John Maddock 2001
+//  Distributed under the Boost
+//  Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org/libs/integer for documentation.
+
+//  Revision History
+//   31 Oct 01  use BOOST_HAS_LONG_LONG to check for "long long" (Jens M.)
+//   16 Apr 01  check LONGLONG_MAX when looking for "long long" (Jens Maurer)
+//   23 Jan 01  prefer "long" over "int" for int32_t and intmax_t (Jens Maurer)
+//   12 Nov 00  Merged <boost/stdint.h> (Jens Maurer)
+//   23 Sep 00  Added INTXX_C macro support (John Maddock).
+//   22 Sep 00  Better 64-bit support (John Maddock)
+//   29 Jun 00  Reimplement to avoid including stdint.h within namespace boost
+//    8 Aug 99  Initial version (Beman Dawes)
+
+
+#ifndef BOOST_CSTDINT_HPP
+#define BOOST_CSTDINT_HPP
+
+//
+// Since we always define the INT#_C macros as per C++0x,
+// define __STDC_CONSTANT_MACROS so that <stdint.h> does the right
+// thing if possible, and so that the user knows that the macros
+// are actually defined as per C99.
+//
+#ifndef __STDC_CONSTANT_MACROS
+#  define __STDC_CONSTANT_MACROS
+#endif
+
+#include <boost/config.hpp>
+
+//
+// Note that GLIBC is a bit inconsistent about whether int64_t is defined or not
+// depending upon what headers happen to have been included first...
+// so we disable use of stdint.h when GLIBC does not define __GLIBC_HAVE_LONG_LONG.
+// See https://svn.boost.org/trac/boost/ticket/3548 and http://sources.redhat.com/bugzilla/show_bug.cgi?id=10990
+//
+#if defined(BOOST_HAS_STDINT_H)					\
+  && (!defined(__GLIBC__)					\
+      || defined(__GLIBC_HAVE_LONG_LONG)			\
+      || (defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 17)))))
+
+// The following #include is an implementation artifact; not part of interface.
+# ifdef __hpux
+// HP-UX has a vaguely nice <stdint.h> in a non-standard location
+#   include <inttypes.h>
+#   ifdef __STDC_32_MODE__
+      // this is triggered with GCC, because it defines __cplusplus < 199707L
+#     define BOOST_NO_INT64_T
+#   endif
+# elif defined(__FreeBSD__) || defined(__IBMCPP__) || defined(_AIX)
+#   include <inttypes.h>
+# else
+#   include <stdint.h>
+
+// There is a bug in Cygwin two _C macros
+#   if defined(__STDC_CONSTANT_MACROS) && defined(__CYGWIN__)
+#     undef INTMAX_C
+#     undef UINTMAX_C
+#     define INTMAX_C(c) c##LL
+#     define UINTMAX_C(c) c##ULL
+#   endif
+
+# endif
+
+#if defined(__QNX__) && defined(__EXT_QNX)
+
+// QNX (Dinkumware stdlib) defines these as non-standard names.
+// Reflect to the standard names.
+
+typedef ::intleast8_t int_least8_t;
+typedef ::intfast8_t int_fast8_t;
+typedef ::uintleast8_t uint_least8_t;
+typedef ::uintfast8_t uint_fast8_t;
+
+typedef ::intleast16_t int_least16_t;
+typedef ::intfast16_t int_fast16_t;
+typedef ::uintleast16_t uint_least16_t;
+typedef ::uintfast16_t uint_fast16_t;
+
+typedef ::intleast32_t int_least32_t;
+typedef ::intfast32_t int_fast32_t;
+typedef ::uintleast32_t uint_least32_t;
+typedef ::uintfast32_t uint_fast32_t;
+
+# ifndef BOOST_NO_INT64_T
+
+typedef ::intleast64_t int_least64_t;
+typedef ::intfast64_t int_fast64_t;
+typedef ::uintleast64_t uint_least64_t;
+typedef ::uintfast64_t uint_fast64_t;
+
+# endif
+
+#endif
+
+namespace boost
+{
+
+  using ::int8_t;
+  using ::int_least8_t;
+  using ::int_fast8_t;
+  using ::uint8_t;
+  using ::uint_least8_t;
+  using ::uint_fast8_t;
+
+  using ::int16_t;
+  using ::int_least16_t;
+  using ::int_fast16_t;
+  using ::uint16_t;
+  using ::uint_least16_t;
+  using ::uint_fast16_t;
+
+  using ::int32_t;
+  using ::int_least32_t;
+  using ::int_fast32_t;
+  using ::uint32_t;
+  using ::uint_least32_t;
+  using ::uint_fast32_t;
+
+# ifndef BOOST_NO_INT64_T
+
+  using ::int64_t;
+  using ::int_least64_t;
+  using ::int_fast64_t;
+  using ::uint64_t;
+  using ::uint_least64_t;
+  using ::uint_fast64_t;
+
+# endif
+
+  using ::intmax_t;
+  using ::uintmax_t;
+
+} // namespace boost
+
+#elif defined(__FreeBSD__) && (__FreeBSD__ <= 4) || defined(__osf__) || defined(__VMS) || defined(__SOLARIS9__) || defined(__NetBSD__)
+// FreeBSD and Tru64 have an <inttypes.h> that contains much of what we need.
+# include <inttypes.h>
+
+namespace boost {
+
+  using ::int8_t;
+  typedef int8_t int_least8_t;
+  typedef int8_t int_fast8_t;
+  using ::uint8_t;
+  typedef uint8_t uint_least8_t;
+  typedef uint8_t uint_fast8_t;
+
+  using ::int16_t;
+  typedef int16_t int_least16_t;
+  typedef int16_t int_fast16_t;
+  using ::uint16_t;
+  typedef uint16_t uint_least16_t;
+  typedef uint16_t uint_fast16_t;
+
+  using ::int32_t;
+  typedef int32_t int_least32_t;
+  typedef int32_t int_fast32_t;
+  using ::uint32_t;
+  typedef uint32_t uint_least32_t;
+  typedef uint32_t uint_fast32_t;
+
+# ifndef BOOST_NO_INT64_T
+
+  using ::int64_t;
+  typedef int64_t int_least64_t;
+  typedef int64_t int_fast64_t;
+  using ::uint64_t;
+  typedef uint64_t uint_least64_t;
+  typedef uint64_t uint_fast64_t;
+
+  typedef int64_t intmax_t;
+  typedef uint64_t uintmax_t;
+
+# else
+
+  typedef int32_t intmax_t;
+  typedef uint32_t uintmax_t;
+
+# endif
+
+} // namespace boost
+
+#else  // BOOST_HAS_STDINT_H
+
+# include <boost/limits.hpp> // implementation artifact; not part of interface
+# include <limits.h>         // needed for limits macros
+
+
+namespace boost
+{
+
+//  These are fairly safe guesses for some 16-bit, and most 32-bit and 64-bit
+//  platforms.  For other systems, they will have to be hand tailored.
+//
+//  Because the fast types are assumed to be the same as the undecorated types,
+//  it may be possible to hand tailor a more efficient implementation.  Such
+//  an optimization may be illusionary; on the Intel x86-family 386 on, for
+//  example, byte arithmetic and load/stores are as fast as "int" sized ones.
+
+//  8-bit types  ------------------------------------------------------------//
+
+# if UCHAR_MAX == 0xff
+     typedef signed char     int8_t;
+     typedef signed char     int_least8_t;
+     typedef signed char     int_fast8_t;
+     typedef unsigned char   uint8_t;
+     typedef unsigned char   uint_least8_t;
+     typedef unsigned char   uint_fast8_t;
+# else
+#    error defaults not correct; you must hand modify boost/cstdint.hpp
+# endif
+
+//  16-bit types  -----------------------------------------------------------//
+
+# if USHRT_MAX == 0xffff
+#  if defined(__crayx1)
+     // The Cray X1 has a 16-bit short, however it is not recommend
+     // for use in performance critical code.
+     typedef short           int16_t;
+     typedef short           int_least16_t;
+     typedef int             int_fast16_t;
+     typedef unsigned short  uint16_t;
+     typedef unsigned short  uint_least16_t;
+     typedef unsigned int    uint_fast16_t;
+#  else
+     typedef short           int16_t;
+     typedef short           int_least16_t;
+     typedef short           int_fast16_t;
+     typedef unsigned short  uint16_t;
+     typedef unsigned short  uint_least16_t;
+     typedef unsigned short  uint_fast16_t;
+#  endif
+# elif (USHRT_MAX == 0xffffffff) && defined(__MTA__)
+      // On MTA / XMT short is 32 bits unless the -short16 compiler flag is specified
+      // MTA / XMT does support the following non-standard integer types
+      typedef __short16           int16_t;
+      typedef __short16           int_least16_t;
+      typedef __short16           int_fast16_t;
+      typedef unsigned __short16  uint16_t;
+      typedef unsigned __short16  uint_least16_t;
+      typedef unsigned __short16  uint_fast16_t;
+# elif (USHRT_MAX == 0xffffffff) && defined(CRAY)
+     // no 16-bit types on Cray:
+     typedef short           int_least16_t;
+     typedef short           int_fast16_t;
+     typedef unsigned short  uint_least16_t;
+     typedef unsigned short  uint_fast16_t;
+# else
+#    error defaults not correct; you must hand modify boost/cstdint.hpp
+# endif
+
+//  32-bit types  -----------------------------------------------------------//
+
+# if UINT_MAX == 0xffffffff
+     typedef int             int32_t;
+     typedef int             int_least32_t;
+     typedef int             int_fast32_t;
+     typedef unsigned int    uint32_t;
+     typedef unsigned int    uint_least32_t;
+     typedef unsigned int    uint_fast32_t;
+# elif (USHRT_MAX == 0xffffffff)
+     typedef short             int32_t;
+     typedef short             int_least32_t;
+     typedef short             int_fast32_t;
+     typedef unsigned short    uint32_t;
+     typedef unsigned short    uint_least32_t;
+     typedef unsigned short    uint_fast32_t;
+# elif ULONG_MAX == 0xffffffff
+     typedef long            int32_t;
+     typedef long            int_least32_t;
+     typedef long            int_fast32_t;
+     typedef unsigned long   uint32_t;
+     typedef unsigned long   uint_least32_t;
+     typedef unsigned long   uint_fast32_t;
+# elif (UINT_MAX == 0xffffffffffffffff) && defined(__MTA__)
+      // Integers are 64 bits on the MTA / XMT
+      typedef __int32           int32_t;
+      typedef __int32           int_least32_t;
+      typedef __int32           int_fast32_t;
+      typedef unsigned __int32  uint32_t;
+      typedef unsigned __int32  uint_least32_t;
+      typedef unsigned __int32  uint_fast32_t;
+# else
+#    error defaults not correct; you must hand modify boost/cstdint.hpp
+# endif
+
+//  64-bit types + intmax_t and uintmax_t  ----------------------------------//
+
+# if defined(BOOST_HAS_LONG_LONG) && \
+   !defined(BOOST_MSVC) && !defined(__BORLANDC__) && \
+   (!defined(__GLIBCPP__) || defined(_GLIBCPP_USE_LONG_LONG)) && \
+   (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX))
+#    if defined(__hpux)
+     // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions
+#    elif (defined(ULLONG_MAX) && ULLONG_MAX == 18446744073709551615ULL) || (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 18446744073709551615ULL) || (defined(ULONGLONG_MAX) && ULONGLONG_MAX == 18446744073709551615ULL)
+                                                                 // 2**64 - 1
+#    else
+#       error defaults not correct; you must hand modify boost/cstdint.hpp
+#    endif
+
+     typedef  ::boost::long_long_type            intmax_t;
+     typedef  ::boost::ulong_long_type   uintmax_t;
+     typedef  ::boost::long_long_type            int64_t;
+     typedef  ::boost::long_long_type            int_least64_t;
+     typedef  ::boost::long_long_type            int_fast64_t;
+     typedef  ::boost::ulong_long_type   uint64_t;
+     typedef  ::boost::ulong_long_type   uint_least64_t;
+     typedef  ::boost::ulong_long_type   uint_fast64_t;
+
+# elif ULONG_MAX != 0xffffffff
+
+#    if ULONG_MAX == 18446744073709551615 // 2**64 - 1
+     typedef long                 intmax_t;
+     typedef unsigned long        uintmax_t;
+     typedef long                 int64_t;
+     typedef long                 int_least64_t;
+     typedef long                 int_fast64_t;
+     typedef unsigned long        uint64_t;
+     typedef unsigned long        uint_least64_t;
+     typedef unsigned long        uint_fast64_t;
+#    else
+#       error defaults not correct; you must hand modify boost/cstdint.hpp
+#    endif
+# elif defined(__GNUC__) && defined(BOOST_HAS_LONG_LONG)
+     __extension__ typedef long long            intmax_t;
+     __extension__ typedef unsigned long long   uintmax_t;
+     __extension__ typedef long long            int64_t;
+     __extension__ typedef long long            int_least64_t;
+     __extension__ typedef long long            int_fast64_t;
+     __extension__ typedef unsigned long long   uint64_t;
+     __extension__ typedef unsigned long long   uint_least64_t;
+     __extension__ typedef unsigned long long   uint_fast64_t;
+# elif defined(BOOST_HAS_MS_INT64)
+     //
+     // we have Borland/Intel/Microsoft __int64:
+     //
+     typedef __int64             intmax_t;
+     typedef unsigned __int64    uintmax_t;
+     typedef __int64             int64_t;
+     typedef __int64             int_least64_t;
+     typedef __int64             int_fast64_t;
+     typedef unsigned __int64    uint64_t;
+     typedef unsigned __int64    uint_least64_t;
+     typedef unsigned __int64    uint_fast64_t;
+# else // assume no 64-bit integers
+#  define BOOST_NO_INT64_T
+     typedef int32_t              intmax_t;
+     typedef uint32_t             uintmax_t;
+# endif
+
+} // namespace boost
+
+
+#endif // BOOST_HAS_STDINT_H
+
+// intptr_t/uintptr_t are defined separately because they are optional and not universally available
+#if defined(BOOST_WINDOWS) && !defined(_WIN32_WCE) && !defined(BOOST_HAS_STDINT_H)
+// Older MSVC don't have stdint.h and have intptr_t/uintptr_t defined in stddef.h
+#include <stddef.h>
+#endif
+
+// PGI seems to not support intptr_t/uintptr_t properly. BOOST_HAS_STDINT_H is not defined for this compiler by Boost.Config.
+#if !defined(__PGIC__)
+
+#if (defined(BOOST_WINDOWS) && !defined(_WIN32_WCE)) \
+    || (defined(_XOPEN_UNIX) && (_XOPEN_UNIX+0 > 0) && !defined(__UCLIBC__)) \
+    || defined(__CYGWIN__) \
+    || defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \
+    || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(sun)
+
+namespace boost {
+    using ::intptr_t;
+    using ::uintptr_t;
+}
+#define BOOST_HAS_INTPTR_T
+
+// Clang pretends to be GCC, so it'll match this condition
+#elif defined(__GNUC__) && defined(__INTPTR_TYPE__) && defined(__UINTPTR_TYPE__)
+
+namespace boost {
+    typedef __INTPTR_TYPE__ intptr_t;
+    typedef __UINTPTR_TYPE__ uintptr_t;
+}
+#define BOOST_HAS_INTPTR_T
+
+#endif
+
+#endif // !defined(__PGIC__)
+
+#endif // BOOST_CSTDINT_HPP
+
+
+/****************************************************
+
+Macro definition section:
+
+Added 23rd September 2000 (John Maddock).
+Modified 11th September 2001 to be excluded when
+BOOST_HAS_STDINT_H is defined (John Maddock).
+Modified 11th Dec 2009 to always define the
+INT#_C macros if they're not already defined (John Maddock).
+
+******************************************************/
+
+#if !defined(BOOST__STDC_CONSTANT_MACROS_DEFINED) && \
+   (!defined(INT8_C) || !defined(INT16_C) || !defined(INT32_C) || !defined(INT64_C))
+//
+// For the following code we get several warnings along the lines of:
+//
+// boost/cstdint.hpp:428:35: error: use of C99 long long integer constant
+//
+// So we declare this a system header to suppress these warnings.
+//
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+#pragma GCC system_header
+#endif
+
+#include <limits.h>
+# define BOOST__STDC_CONSTANT_MACROS_DEFINED
+# if defined(BOOST_HAS_MS_INT64)
+//
+// Borland/Intel/Microsoft compilers have width specific suffixes:
+//
+#ifndef INT8_C
+#  define INT8_C(value)     value##i8
+#endif
+#ifndef INT16_C
+#  define INT16_C(value)    value##i16
+#endif
+#ifndef INT32_C
+#  define INT32_C(value)    value##i32
+#endif
+#ifndef INT64_C
+#  define INT64_C(value)    value##i64
+#endif
+#  ifdef __BORLANDC__
+    // Borland bug: appending ui8 makes the type a signed char
+#   define UINT8_C(value)    static_cast<unsigned char>(value##u)
+#  else
+#   define UINT8_C(value)    value##ui8
+#  endif
+#ifndef UINT16_C
+#  define UINT16_C(value)   value##ui16
+#endif
+#ifndef UINT32_C
+#  define UINT32_C(value)   value##ui32
+#endif
+#ifndef UINT64_C
+#  define UINT64_C(value)   value##ui64
+#endif
+#ifndef INTMAX_C
+#  define INTMAX_C(value)   value##i64
+#  define UINTMAX_C(value)  value##ui64
+#endif
+
+# else
+//  do it the old fashioned way:
+
+//  8-bit types  ------------------------------------------------------------//
+
+#  if (UCHAR_MAX == 0xff) && !defined(INT8_C)
+#   define INT8_C(value) static_cast<boost::int8_t>(value)
+#   define UINT8_C(value) static_cast<boost::uint8_t>(value##u)
+#  endif
+
+//  16-bit types  -----------------------------------------------------------//
+
+#  if (USHRT_MAX == 0xffff) && !defined(INT16_C)
+#   define INT16_C(value) static_cast<boost::int16_t>(value)
+#   define UINT16_C(value) static_cast<boost::uint16_t>(value##u)
+#  endif
+
+//  32-bit types  -----------------------------------------------------------//
+#ifndef INT32_C
+#  if (UINT_MAX == 0xffffffff)
+#   define INT32_C(value) value
+#   define UINT32_C(value) value##u
+#  elif ULONG_MAX == 0xffffffff
+#   define INT32_C(value) value##L
+#   define UINT32_C(value) value##uL
+#  endif
+#endif
+
+//  64-bit types + intmax_t and uintmax_t  ----------------------------------//
+#ifndef INT64_C
+#  if defined(BOOST_HAS_LONG_LONG) && \
+    (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX) || defined(_ULLONG_MAX) || defined(_LLONG_MAX))
+
+#    if defined(__hpux)
+        // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions
+#       define INT64_C(value) value##LL
+#       define UINT64_C(value) value##uLL
+#    elif (defined(ULLONG_MAX) && ULLONG_MAX == 18446744073709551615ULL) ||  \
+        (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 18446744073709551615ULL) ||  \
+        (defined(ULONGLONG_MAX) && ULONGLONG_MAX == 18446744073709551615ULL) || \
+        (defined(_ULLONG_MAX) && _ULLONG_MAX == 18446744073709551615ULL) || \
+        (defined(_LLONG_MAX) && _LLONG_MAX == 9223372036854775807LL)
+
+#       define INT64_C(value) value##LL
+#       define UINT64_C(value) value##uLL
+#    else
+#       error defaults not correct; you must hand modify boost/cstdint.hpp
+#    endif
+#  elif ULONG_MAX != 0xffffffff
+
+#    if ULONG_MAX == 18446744073709551615U // 2**64 - 1
+#       define INT64_C(value) value##L
+#       define UINT64_C(value) value##uL
+#    else
+#       error defaults not correct; you must hand modify boost/cstdint.hpp
+#    endif
+#  elif defined(BOOST_HAS_LONG_LONG)
+     // Usual macros not defined, work things out for ourselves:
+#    if(~0uLL == 18446744073709551615ULL)
+#       define INT64_C(value) value##LL
+#       define UINT64_C(value) value##uLL
+#    else
+#       error defaults not correct; you must hand modify boost/cstdint.hpp
+#    endif
+#  else
+#    error defaults not correct; you must hand modify boost/cstdint.hpp
+#  endif
+
+#  ifdef BOOST_NO_INT64_T
+#   define INTMAX_C(value) INT32_C(value)
+#   define UINTMAX_C(value) UINT32_C(value)
+#  else
+#   define INTMAX_C(value) INT64_C(value)
+#   define UINTMAX_C(value) UINT64_C(value)
+#  endif
+#endif
+# endif // Borland/Microsoft specific width suffixes
+
+#endif // INT#_C macros.
diff --git a/third_party/boost/boost/current_function.hpp b/third_party/boost/boost/current_function.hpp
new file mode 100644
index 0000000..5c113f8
--- /dev/null
+++ b/third_party/boost/boost/current_function.hpp
@@ -0,0 +1,71 @@
+#ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED
+#define BOOST_CURRENT_FUNCTION_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  boost/current_function.hpp - BOOST_CURRENT_FUNCTION
+//
+//  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+//
+//  http://www.boost.org/libs/assert/current_function.html
+//
+
+namespace boost
+{
+
+namespace detail
+{
+
+inline void current_function_helper()
+{
+
+#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__)
+
+# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
+
+#elif defined(__DMC__) && (__DMC__ >= 0x810)
+
+# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
+
+#elif defined(__FUNCSIG__)
+
+# define BOOST_CURRENT_FUNCTION __FUNCSIG__
+
+#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
+
+# define BOOST_CURRENT_FUNCTION __FUNCTION__
+
+#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
+
+# define BOOST_CURRENT_FUNCTION __FUNC__
+
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
+
+# define BOOST_CURRENT_FUNCTION __func__
+
+#elif defined(__cplusplus) && (__cplusplus >= 201103)
+
+# define BOOST_CURRENT_FUNCTION __func__
+
+#else
+
+# define BOOST_CURRENT_FUNCTION "(unknown)"
+
+#endif
+
+}
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED
diff --git a/third_party/boost/boost/detail/call_traits.hpp b/third_party/boost/boost/detail/call_traits.hpp
new file mode 100644
index 0000000..36dea00
--- /dev/null
+++ b/third_party/boost/boost/detail/call_traits.hpp
@@ -0,0 +1,172 @@
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/utility for most recent version including documentation.
+
+// call_traits: defines typedefs for function usage
+// (see libs/utility/call_traits.htm)
+
+/* Release notes:
+   23rd July 2000:
+      Fixed array specialization. (JM)
+      Added Borland specific fixes for reference types
+      (issue raised by Steve Cleary).
+*/
+
+#ifndef BOOST_DETAIL_CALL_TRAITS_HPP
+#define BOOST_DETAIL_CALL_TRAITS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#include <boost/config.hpp>
+#endif
+#include <cstddef>
+
+#include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/type_traits/is_enum.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/detail/workaround.hpp>
+
+namespace boost{
+
+namespace detail{
+
+template <typename T, bool small_>
+struct ct_imp2
+{
+   typedef const T& param_type;
+};
+
+template <typename T>
+struct ct_imp2<T, true>
+{
+   typedef const T param_type;
+};
+
+template <typename T, bool isp, bool b1, bool b2>
+struct ct_imp
+{
+   typedef const T& param_type;
+};
+
+template <typename T, bool isp, bool b2>
+struct ct_imp<T, isp, true, b2>
+{
+   typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type;
+};
+
+template <typename T, bool isp, bool b1>
+struct ct_imp<T, isp, b1, true>
+{
+   typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type;
+};
+
+template <typename T, bool b1, bool b2>
+struct ct_imp<T, true, b1, b2>
+{
+   typedef const T param_type;
+};
+
+}
+
+template <typename T>
+struct call_traits
+{
+public:
+   typedef T value_type;
+   typedef T& reference;
+   typedef const T& const_reference;
+   //
+   // C++ Builder workaround: we should be able to define a compile time
+   // constant and pass that as a single template parameter to ct_imp<T,bool>,
+   // however compiler bugs prevent this - instead pass three bool's to
+   // ct_imp<T,bool,bool,bool> and add an extra partial specialisation
+   // of ct_imp to handle the logic. (JM)
+   typedef typename boost::detail::ct_imp<
+      T,
+      ::boost::is_pointer<T>::value,
+      ::boost::is_arithmetic<T>::value,
+      ::boost::is_enum<T>::value
+   >::param_type param_type;
+};
+
+template <typename T>
+struct call_traits<T&>
+{
+   typedef T& value_type;
+   typedef T& reference;
+   typedef const T& const_reference;
+   typedef T& param_type;  // hh removed const
+};
+
+#if BOOST_WORKAROUND( __BORLANDC__,  < 0x5A0 )
+// these are illegal specialisations; cv-qualifies applied to
+// references have no effect according to [8.3.2p1],
+// C++ Builder requires them though as it treats cv-qualified
+// references as distinct types...
+template <typename T>
+struct call_traits<T&const>
+{
+   typedef T& value_type;
+   typedef T& reference;
+   typedef const T& const_reference;
+   typedef T& param_type;  // hh removed const
+};
+template <typename T>
+struct call_traits<T&volatile>
+{
+   typedef T& value_type;
+   typedef T& reference;
+   typedef const T& const_reference;
+   typedef T& param_type;  // hh removed const
+};
+template <typename T>
+struct call_traits<T&const volatile>
+{
+   typedef T& value_type;
+   typedef T& reference;
+   typedef const T& const_reference;
+   typedef T& param_type;  // hh removed const
+};
+
+template <typename T>
+struct call_traits< T * >
+{
+   typedef T * value_type;
+   typedef T * & reference;
+   typedef T * const & const_reference;
+   typedef T * const param_type;  // hh removed const
+};
+#endif
+#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS)
+template <typename T, std::size_t N>
+struct call_traits<T [N]>
+{
+private:
+   typedef T array_type[N];
+public:
+   // degrades array to pointer:
+   typedef const T* value_type;
+   typedef array_type& reference;
+   typedef const array_type& const_reference;
+   typedef const T* const param_type;
+};
+
+template <typename T, std::size_t N>
+struct call_traits<const T [N]>
+{
+private:
+   typedef const T array_type[N];
+public:
+   // degrades array to pointer:
+   typedef const T* value_type;
+   typedef array_type& reference;
+   typedef const array_type& const_reference;
+   typedef const T* const param_type;
+};
+#endif
+
+}
+
+#endif // BOOST_DETAIL_CALL_TRAITS_HPP
diff --git a/third_party/boost/boost/detail/indirect_traits.hpp b/third_party/boost/boost/detail/indirect_traits.hpp
new file mode 100644
index 0000000..f7ce383
--- /dev/null
+++ b/third_party/boost/boost/detail/indirect_traits.hpp
@@ -0,0 +1,204 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef INDIRECT_TRAITS_DWA2002131_HPP
+# define INDIRECT_TRAITS_DWA2002131_HPP
+# include <boost/type_traits/is_function.hpp>
+# include <boost/type_traits/is_reference.hpp>
+# include <boost/type_traits/is_pointer.hpp>
+# include <boost/type_traits/is_class.hpp>
+# include <boost/type_traits/is_const.hpp>
+# include <boost/type_traits/is_volatile.hpp>
+# include <boost/type_traits/is_member_function_pointer.hpp>
+# include <boost/type_traits/is_member_pointer.hpp>
+# include <boost/type_traits/remove_cv.hpp>
+# include <boost/type_traits/remove_reference.hpp>
+# include <boost/type_traits/remove_pointer.hpp>
+
+# include <boost/detail/workaround.hpp>
+
+# include <boost/mpl/eval_if.hpp>
+# include <boost/mpl/if.hpp>
+# include <boost/mpl/bool.hpp>
+# include <boost/mpl/and.hpp>
+# include <boost/mpl/not.hpp>
+# include <boost/mpl/aux_/lambda_support.hpp>
+
+
+namespace boost { namespace detail {
+
+namespace indirect_traits {
+
+template <class T>
+struct is_reference_to_const : mpl::false_
+{
+};
+
+template <class T>
+struct is_reference_to_const<T const&> : mpl::true_
+{
+};
+
+#   if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround
+template<class T>
+struct is_reference_to_const<T const volatile&> : mpl::true_
+{
+};
+#   endif
+
+template <class T>
+struct is_reference_to_function : mpl::false_
+{
+};
+
+template <class T>
+struct is_reference_to_function<T&> : is_function<T>
+{
+};
+
+template <class T>
+struct is_pointer_to_function : mpl::false_
+{
+};
+
+// There's no such thing as a pointer-to-cv-function, so we don't need
+// specializations for those
+template <class T>
+struct is_pointer_to_function<T*> : is_function<T>
+{
+};
+
+template <class T>
+struct is_reference_to_member_function_pointer_impl : mpl::false_
+{
+};
+
+template <class T>
+struct is_reference_to_member_function_pointer_impl<T&>
+    : is_member_function_pointer<typename remove_cv<T>::type>
+{
+};
+
+
+template <class T>
+struct is_reference_to_member_function_pointer
+    : is_reference_to_member_function_pointer_impl<T>
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_member_function_pointer,(T))
+};
+
+template <class T>
+struct is_reference_to_function_pointer_aux
+    : mpl::and_<
+          is_reference<T>
+        , is_pointer_to_function<
+              typename remove_cv<
+                  typename remove_reference<T>::type
+              >::type
+          >
+      >
+{
+    // There's no such thing as a pointer-to-cv-function, so we don't need specializations for those
+};
+
+template <class T>
+struct is_reference_to_function_pointer
+    : mpl::if_<
+          is_reference_to_function<T>
+        , mpl::false_
+        , is_reference_to_function_pointer_aux<T>
+     >::type
+{
+};
+
+template <class T>
+struct is_reference_to_non_const
+    : mpl::and_<
+          is_reference<T>
+        , mpl::not_<
+             is_reference_to_const<T>
+          >
+      >
+{
+};
+
+template <class T>
+struct is_reference_to_volatile : mpl::false_
+{
+};
+
+template <class T>
+struct is_reference_to_volatile<T volatile&> : mpl::true_
+{
+};
+
+#   if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround
+template <class T>
+struct is_reference_to_volatile<T const volatile&> : mpl::true_
+{
+};
+#   endif
+
+
+template <class T>
+struct is_reference_to_pointer : mpl::false_
+{
+};
+
+template <class T>
+struct is_reference_to_pointer<T*&> : mpl::true_
+{
+};
+
+template <class T>
+struct is_reference_to_pointer<T* const&> : mpl::true_
+{
+};
+
+template <class T>
+struct is_reference_to_pointer<T* volatile&> : mpl::true_
+{
+};
+
+template <class T>
+struct is_reference_to_pointer<T* const volatile&> : mpl::true_
+{
+};
+
+template <class T>
+struct is_reference_to_class
+    : mpl::and_<
+          is_reference<T>
+        , is_class<
+              typename remove_cv<
+                  typename remove_reference<T>::type
+              >::type
+          >
+      >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_reference_to_class,(T))
+};
+
+template <class T>
+struct is_pointer_to_class
+    : mpl::and_<
+          is_pointer<T>
+        , is_class<
+              typename remove_cv<
+                  typename remove_pointer<T>::type
+              >::type
+          >
+      >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_pointer_to_class,(T))
+};
+
+
+}
+
+using namespace indirect_traits;
+
+}} // namespace boost::python::detail
+
+#endif // INDIRECT_TRAITS_DWA2002131_HPP
diff --git a/third_party/boost/boost/detail/iterator.hpp b/third_party/boost/boost/detail/iterator.hpp
new file mode 100644
index 0000000..c2e8f1e
--- /dev/null
+++ b/third_party/boost/boost/detail/iterator.hpp
@@ -0,0 +1,26 @@
+// (C) Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef ITERATOR_DWA122600_HPP_
+#define ITERATOR_DWA122600_HPP_
+
+// This header is obsolete and will be deprecated.
+
+#include <iterator>
+
+namespace boost
+{
+
+namespace detail
+{
+
+using std::iterator_traits;
+using std::distance;
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // ITERATOR_DWA122600_HPP_
diff --git a/third_party/boost/boost/detail/no_exceptions_support.hpp b/third_party/boost/boost/detail/no_exceptions_support.hpp
new file mode 100644
index 0000000..7d17454
--- /dev/null
+++ b/third_party/boost/boost/detail/no_exceptions_support.hpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2014 Glen Fernandes
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef BOOST_DETAIL_NO_EXCEPTIONS_SUPPORT_HPP
+#define BOOST_DETAIL_NO_EXCEPTIONS_SUPPORT_HPP
+
+// The header file at this path is deprecated;
+// use boost/core/no_exceptions_support.hpp instead.
+
+#include <boost/core/no_exceptions_support.hpp>
+
+#endif
diff --git a/third_party/boost/boost/detail/reference_content.hpp b/third_party/boost/boost/detail/reference_content.hpp
new file mode 100644
index 0000000..36b80d2
--- /dev/null
+++ b/third_party/boost/boost/detail/reference_content.hpp
@@ -0,0 +1,120 @@
+//-----------------------------------------------------------------------------
+// boost detail/reference_content.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_DETAIL_REFERENCE_CONTENT_HPP
+#define BOOST_DETAIL_REFERENCE_CONTENT_HPP
+
+#include "boost/config.hpp"
+
+#   include "boost/mpl/bool.hpp"
+#   include "boost/type_traits/has_nothrow_copy.hpp"
+
+#include "boost/mpl/void.hpp"
+
+namespace boost {
+
+namespace detail {
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class template reference_content
+//
+// Non-Assignable wrapper for references.
+//
+template <typename RefT>
+class reference_content
+{
+private: // representation
+
+    RefT content_;
+
+public: // structors
+
+    ~reference_content()
+    {
+    }
+
+    reference_content(RefT r)
+        : content_( r )
+    {
+    }
+
+    reference_content(const reference_content& operand)
+        : content_( operand.content_ )
+    {
+    }
+
+private: // non-Assignable
+
+    reference_content& operator=(const reference_content&);
+
+public: // queries
+
+    RefT get() const
+    {
+        return content_;
+    }
+
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) metafunction make_reference_content
+//
+// Wraps with reference_content if specified type is reference.
+//
+
+template <typename T = mpl::void_> struct make_reference_content;
+
+
+template <typename T>
+struct make_reference_content
+{
+    typedef T type;
+};
+
+template <typename T>
+struct make_reference_content< T& >
+{
+    typedef reference_content<T&> type;
+};
+
+
+template <>
+struct make_reference_content< mpl::void_ >
+{
+    template <typename T>
+    struct apply
+        : make_reference_content<T>
+    {
+    };
+
+    typedef mpl::void_ type;
+};
+
+} // namespace detail
+
+///////////////////////////////////////////////////////////////////////////////
+// reference_content<T&> type traits specializations
+//
+
+
+template <typename T>
+struct has_nothrow_copy<
+      ::boost::detail::reference_content< T& >
+    >
+    : mpl::true_
+{
+};
+
+
+} // namespace boost
+
+#endif // BOOST_DETAIL_REFERENCE_CONTENT_HPP
diff --git a/third_party/boost/boost/detail/sp_typeinfo.hpp b/third_party/boost/boost/detail/sp_typeinfo.hpp
new file mode 100644
index 0000000..4e4de55
--- /dev/null
+++ b/third_party/boost/boost/detail/sp_typeinfo.hpp
@@ -0,0 +1,36 @@
+#ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
+#define BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//  detail/sp_typeinfo.hpp
+//
+//  Deprecated, please use boost/core/typeinfo.hpp
+//
+//  Copyright 2007 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/core/typeinfo.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+typedef boost::core::typeinfo sp_typeinfo;
+
+} // namespace detail
+
+} // namespace boost
+
+#define BOOST_SP_TYPEID(T) BOOST_CORE_TYPEID(T)
+
+#endif  // #ifndef BOOST_DETAIL_SP_TYPEINFO_HPP_INCLUDED
diff --git a/third_party/boost/boost/detail/templated_streams.hpp b/third_party/boost/boost/detail/templated_streams.hpp
new file mode 100644
index 0000000..82042d2
--- /dev/null
+++ b/third_party/boost/boost/detail/templated_streams.hpp
@@ -0,0 +1,74 @@
+//-----------------------------------------------------------------------------
+// boost detail/templated_streams.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_DETAIL_TEMPLATED_STREAMS_HPP
+#define BOOST_DETAIL_TEMPLATED_STREAMS_HPP
+
+#include "boost/config.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) BOOST_TEMPLATED_STREAM_* macros
+//
+// Provides workaround platforms without stream class templates.
+//
+
+#if !defined(BOOST_NO_STD_LOCALE)
+
+#define BOOST_TEMPLATED_STREAM_TEMPLATE(E,T) \
+    template < typename E , typename T >
+
+#define BOOST_TEMPLATED_STREAM_TEMPLATE_ALLOC(E,T,A) \
+    template < typename E , typename T , typename A >
+
+#define BOOST_TEMPLATED_STREAM_ARGS(E,T) \
+    typename E , typename T
+
+#define BOOST_TEMPLATED_STREAM_ARGS_ALLOC(E,T,A) \
+    typename E , typename T , typename A
+
+#define BOOST_TEMPLATED_STREAM_COMMA        ,
+
+#define BOOST_TEMPLATED_STREAM_ELEM(E)      E
+#define BOOST_TEMPLATED_STREAM_TRAITS(T)    T
+#define BOOST_TEMPLATED_STREAM_ALLOC(A)     A
+
+#define BOOST_TEMPLATED_STREAM(X,E,T) \
+    BOOST_JOIN(std::basic_,X)< E , T >
+
+#define BOOST_TEMPLATED_STREAM_WITH_ALLOC(X,E,T,A) \
+    BOOST_JOIN(std::basic_,X)< E , T , A >
+
+#else // defined(BOOST_NO_STD_LOCALE)
+
+#define BOOST_TEMPLATED_STREAM_TEMPLATE(E,T) /**/
+
+#define BOOST_TEMPLATED_STREAM_TEMPLATE_ALLOC(E,T,A) /**/
+
+#define BOOST_TEMPLATED_STREAM_ARGS(E,T) /**/
+
+#define BOOST_TEMPLATED_STREAM_ARGS_ALLOC(E,T,A) /**/
+
+#define BOOST_TEMPLATED_STREAM_COMMA        /**/
+
+#define BOOST_TEMPLATED_STREAM_ELEM(E)      char
+#define BOOST_TEMPLATED_STREAM_TRAITS(T)    std::char_traits<char>
+#define BOOST_TEMPLATED_STREAM_ALLOC(A)     std::allocator<char>
+
+#define BOOST_TEMPLATED_STREAM(X,E,T) \
+    std::X
+
+#define BOOST_TEMPLATED_STREAM_WITH_ALLOC(X,E,T,A) \
+    std::X
+
+#endif // BOOST_NO_STD_LOCALE
+
+#endif // BOOST_DETAIL_TEMPLATED_STREAMS_HPP
diff --git a/third_party/boost/boost/detail/workaround.hpp b/third_party/boost/boost/detail/workaround.hpp
new file mode 100644
index 0000000..8e5648e
--- /dev/null
+++ b/third_party/boost/boost/detail/workaround.hpp
@@ -0,0 +1,267 @@
+// Copyright David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef WORKAROUND_DWA2002126_HPP
+# define WORKAROUND_DWA2002126_HPP
+
+// Compiler/library version workaround macro
+//
+// Usage:
+//
+//     #if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+//        // workaround for eVC4 and VC6
+//        ... // workaround code here
+//     #endif
+//
+// When BOOST_STRICT_CONFIG is defined, expands to 0. Otherwise, the
+// first argument must be undefined or expand to a numeric
+// value. The above expands to:
+//
+//     (BOOST_MSVC) != 0 && (BOOST_MSVC) < 1300
+//
+// When used for workarounds that apply to the latest known version
+// and all earlier versions of a compiler, the following convention
+// should be observed:
+//
+//     #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1301))
+//
+// The version number in this case corresponds to the last version in
+// which the workaround was known to have been required. When
+// BOOST_DETECT_OUTDATED_WORKAROUNDS is not the defined, the macro
+// BOOST_TESTED_AT(x) expands to "!= 0", which effectively activates
+// the workaround for any version of the compiler. When
+// BOOST_DETECT_OUTDATED_WORKAROUNDS is defined, a compiler warning or
+// error will be issued if the compiler version exceeds the argument
+// to BOOST_TESTED_AT().  This can be used to locate workarounds which
+// may be obsoleted by newer versions.
+
+# ifndef BOOST_STRICT_CONFIG
+
+#include <boost/config.hpp>
+
+#ifndef __BORLANDC__
+#define __BORLANDC___WORKAROUND_GUARD 1
+#else
+#define __BORLANDC___WORKAROUND_GUARD 0
+#endif
+#ifndef __CODEGEARC__
+#define __CODEGEARC___WORKAROUND_GUARD 1
+#else
+#define __CODEGEARC___WORKAROUND_GUARD 0
+#endif
+#ifndef _MSC_VER
+#define _MSC_VER_WORKAROUND_GUARD 1
+#else
+#define _MSC_VER_WORKAROUND_GUARD 0
+#endif
+#ifndef _MSC_FULL_VER
+#define _MSC_FULL_VER_WORKAROUND_GUARD 1
+#else
+#define _MSC_FULL_VER_WORKAROUND_GUARD 0
+#endif
+#ifndef BOOST_MSVC
+#define BOOST_MSVC_WORKAROUND_GUARD 1
+#else
+#define BOOST_MSVC_WORKAROUND_GUARD 0
+#endif
+#ifndef BOOST_MSVC_FULL_VER
+#define BOOST_MSVC_FULL_VER_WORKAROUND_GUARD 1
+#else
+#define BOOST_MSVC_FULL_VER_WORKAROUND_GUARD 0
+#endif
+#ifndef __GNUC__
+#define __GNUC___WORKAROUND_GUARD 1
+#else
+#define __GNUC___WORKAROUND_GUARD 0
+#endif
+#ifndef __GNUC_MINOR__
+#define __GNUC_MINOR___WORKAROUND_GUARD 1
+#else
+#define __GNUC_MINOR___WORKAROUND_GUARD 0
+#endif
+#ifndef __GNUC_PATCHLEVEL__
+#define __GNUC_PATCHLEVEL___WORKAROUND_GUARD 1
+#else
+#define __GNUC_PATCHLEVEL___WORKAROUND_GUARD 0
+#endif
+#ifndef __IBMCPP__
+#define __IBMCPP___WORKAROUND_GUARD 1
+#else
+#define __IBMCPP___WORKAROUND_GUARD 0
+#endif
+#ifndef __SUNPRO_CC
+#define __SUNPRO_CC_WORKAROUND_GUARD 1
+#else
+#define __SUNPRO_CC_WORKAROUND_GUARD 0
+#endif
+#ifndef __DECCXX_VER
+#define __DECCXX_VER_WORKAROUND_GUARD 1
+#else
+#define __DECCXX_VER_WORKAROUND_GUARD 0
+#endif
+#ifndef __MWERKS__
+#define __MWERKS___WORKAROUND_GUARD 1
+#else
+#define __MWERKS___WORKAROUND_GUARD 0
+#endif
+#ifndef __EDG__
+#define __EDG___WORKAROUND_GUARD 1
+#else
+#define __EDG___WORKAROUND_GUARD 0
+#endif
+#ifndef __EDG_VERSION__
+#define __EDG_VERSION___WORKAROUND_GUARD 1
+#else
+#define __EDG_VERSION___WORKAROUND_GUARD 0
+#endif
+#ifndef __HP_aCC
+#define __HP_aCC_WORKAROUND_GUARD 1
+#else
+#define __HP_aCC_WORKAROUND_GUARD 0
+#endif
+#ifndef __hpxstd98
+#define __hpxstd98_WORKAROUND_GUARD 1
+#else
+#define __hpxstd98_WORKAROUND_GUARD 0
+#endif
+#ifndef _CRAYC
+#define _CRAYC_WORKAROUND_GUARD 1
+#else
+#define _CRAYC_WORKAROUND_GUARD 0
+#endif
+#ifndef __DMC__
+#define __DMC___WORKAROUND_GUARD 1
+#else
+#define __DMC___WORKAROUND_GUARD 0
+#endif
+#ifndef MPW_CPLUS
+#define MPW_CPLUS_WORKAROUND_GUARD 1
+#else
+#define MPW_CPLUS_WORKAROUND_GUARD 0
+#endif
+#ifndef __COMO__
+#define __COMO___WORKAROUND_GUARD 1
+#else
+#define __COMO___WORKAROUND_GUARD 0
+#endif
+#ifndef __COMO_VERSION__
+#define __COMO_VERSION___WORKAROUND_GUARD 1
+#else
+#define __COMO_VERSION___WORKAROUND_GUARD 0
+#endif
+#ifndef __INTEL_COMPILER
+#define __INTEL_COMPILER_WORKAROUND_GUARD 1
+#else
+#define __INTEL_COMPILER_WORKAROUND_GUARD 0
+#endif
+#ifndef __ICL
+#define __ICL_WORKAROUND_GUARD 1
+#else
+#define __ICL_WORKAROUND_GUARD 0
+#endif
+#ifndef _COMPILER_VERSION
+#define _COMPILER_VERSION_WORKAROUND_GUARD 1
+#else
+#define _COMPILER_VERSION_WORKAROUND_GUARD 0
+#endif
+
+#ifndef _RWSTD_VER
+#define _RWSTD_VER_WORKAROUND_GUARD 1
+#else
+#define _RWSTD_VER_WORKAROUND_GUARD 0
+#endif
+#ifndef BOOST_RWSTD_VER
+#define BOOST_RWSTD_VER_WORKAROUND_GUARD 1
+#else
+#define BOOST_RWSTD_VER_WORKAROUND_GUARD 0
+#endif
+#ifndef __GLIBCPP__
+#define __GLIBCPP___WORKAROUND_GUARD 1
+#else
+#define __GLIBCPP___WORKAROUND_GUARD 0
+#endif
+#ifndef _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC
+#define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 1
+#else
+#define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 0
+#endif
+#ifndef __SGI_STL_PORT
+#define __SGI_STL_PORT_WORKAROUND_GUARD 1
+#else
+#define __SGI_STL_PORT_WORKAROUND_GUARD 0
+#endif
+#ifndef _STLPORT_VERSION
+#define _STLPORT_VERSION_WORKAROUND_GUARD 1
+#else
+#define _STLPORT_VERSION_WORKAROUND_GUARD 0
+#endif
+#ifndef __LIBCOMO_VERSION__
+#define __LIBCOMO_VERSION___WORKAROUND_GUARD 1
+#else
+#define __LIBCOMO_VERSION___WORKAROUND_GUARD 0
+#endif
+#ifndef _CPPLIB_VER
+#define _CPPLIB_VER_WORKAROUND_GUARD 1
+#else
+#define _CPPLIB_VER_WORKAROUND_GUARD 0
+#endif
+
+#ifndef BOOST_INTEL_CXX_VERSION
+#define BOOST_INTEL_CXX_VERSION_WORKAROUND_GUARD 1
+#else
+#define BOOST_INTEL_CXX_VERSION_WORKAROUND_GUARD 0
+#endif
+#ifndef BOOST_INTEL_WIN
+#define BOOST_INTEL_WIN_WORKAROUND_GUARD 1
+#else
+#define BOOST_INTEL_WIN_WORKAROUND_GUARD 0
+#endif
+#ifndef BOOST_DINKUMWARE_STDLIB
+#define BOOST_DINKUMWARE_STDLIB_WORKAROUND_GUARD 1
+#else
+#define BOOST_DINKUMWARE_STDLIB_WORKAROUND_GUARD 0
+#endif
+#ifndef BOOST_INTEL
+#define BOOST_INTEL_WORKAROUND_GUARD 1
+#else
+#define BOOST_INTEL_WORKAROUND_GUARD 0
+#endif
+// Always define to zero, if it's used it'll be defined my MPL:
+#define BOOST_MPL_CFG_GCC_WORKAROUND_GUARD 0
+
+#  define BOOST_WORKAROUND(symbol, test)                \
+         ((symbol ## _WORKAROUND_GUARD + 0 == 0) &&     \
+         (symbol != 0) && (1 % (( (symbol test) ) + 1)))
+//                              ^ ^           ^ ^
+// The extra level of parenthesis nesting above, along with the
+// BOOST_OPEN_PAREN indirection below, is required to satisfy the
+// broken preprocessor in MWCW 8.3 and earlier.
+//
+// The basic mechanism works as follows:
+//      (symbol test) + 1        =>   if (symbol test) then 2 else 1
+//      1 % ((symbol test) + 1)  =>   if (symbol test) then 1 else 0
+//
+// The complication with % is for cooperation with BOOST_TESTED_AT().
+// When "test" is BOOST_TESTED_AT(x) and
+// BOOST_DETECT_OUTDATED_WORKAROUNDS is #defined,
+//
+//      symbol test              =>   if (symbol <= x) then 1 else -1
+//      (symbol test) + 1        =>   if (symbol <= x) then 2 else 0
+//      1 % ((symbol test) + 1)  =>   if (symbol <= x) then 1 else divide-by-zero
+//
+
+#  ifdef BOOST_DETECT_OUTDATED_WORKAROUNDS
+#   define BOOST_OPEN_PAREN (
+#   define BOOST_TESTED_AT(value)  > value) ?(-1): BOOST_OPEN_PAREN 1
+#  else
+#   define BOOST_TESTED_AT(value) != ((value)-(value))
+#  endif
+
+# else
+
+#  define BOOST_WORKAROUND(symbol, test) 0
+
+# endif
+
+#endif // WORKAROUND_DWA2002126_HPP
diff --git a/third_party/boost/boost/enable_shared_from_this.hpp b/third_party/boost/boost/enable_shared_from_this.hpp
new file mode 100644
index 0000000..b1bb63d
--- /dev/null
+++ b/third_party/boost/boost/enable_shared_from_this.hpp
@@ -0,0 +1,18 @@
+#ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
+#define BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
+
+//
+//  enable_shared_from_this.hpp
+//
+//  Copyright (c) 2002 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+//
+//  http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
+//
+
+#include <boost/smart_ptr/enable_shared_from_this.hpp>
+
+#endif  // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
diff --git a/third_party/boost/boost/exception/exception.hpp b/third_party/boost/boost/exception/exception.hpp
new file mode 100644
index 0000000..1f2bd9c
--- /dev/null
+++ b/third_party/boost/boost/exception/exception.hpp
@@ -0,0 +1,499 @@
+//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc.
+
+//Distributed under the Boost Software License, Version 1.0. (See accompanying
+//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef UUID_274DA366004E11DCB1DDFE2E56D89593
+#define UUID_274DA366004E11DCB1DDFE2E56D89593
+#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
+#pragma GCC system_header
+#endif
+#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
+#pragma warning(push,1)
+#endif
+
+namespace
+boost
+    {
+    namespace
+    exception_detail
+        {
+        template <class T>
+        class
+        refcount_ptr
+            {
+            public:
+
+            refcount_ptr():
+                px_(0)
+                {
+                }
+
+            ~refcount_ptr()
+                {
+                release();
+                }
+
+            refcount_ptr( refcount_ptr const & x ):
+                px_(x.px_)
+                {
+                add_ref();
+                }
+
+            refcount_ptr &
+            operator=( refcount_ptr const & x )
+                {
+                adopt(x.px_);
+                return *this;
+                }
+
+            void
+            adopt( T * px )
+                {
+                release();
+                px_=px;
+                add_ref();
+                }
+
+            T *
+            get() const
+                {
+                return px_;
+                }
+
+            private:
+
+            T * px_;
+
+            void
+            add_ref()
+                {
+                if( px_ )
+                    px_->add_ref();
+                }
+
+            void
+            release()
+                {
+                if( px_ && px_->release() )
+                    px_=0;
+                }
+            };
+        }
+
+    ////////////////////////////////////////////////////////////////////////
+
+    template <class Tag,class T>
+    class error_info;
+
+    typedef error_info<struct throw_function_,char const *> throw_function;
+    typedef error_info<struct throw_file_,char const *> throw_file;
+    typedef error_info<struct throw_line_,int> throw_line;
+
+    template <>
+    class
+    error_info<throw_function_,char const *>
+        {
+        public:
+        typedef char const * value_type;
+        value_type v_;
+        explicit
+        error_info( value_type v ):
+            v_(v)
+            {
+            }
+        };
+
+    template <>
+    class
+    error_info<throw_file_,char const *>
+        {
+        public:
+        typedef char const * value_type;
+        value_type v_;
+        explicit
+        error_info( value_type v ):
+            v_(v)
+            {
+            }
+        };
+
+    template <>
+    class
+    error_info<throw_line_,int>
+        {
+        public:
+        typedef int value_type;
+        value_type v_;
+        explicit
+        error_info( value_type v ):
+            v_(v)
+            {
+            }
+        };
+
+#if defined(__GNUC__)
+# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
+#  pragma GCC visibility push (default)
+# endif
+#endif
+    class exception;
+#if defined(__GNUC__)
+# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
+#  pragma GCC visibility pop
+# endif
+#endif
+
+    template <class T>
+    class shared_ptr;
+
+    namespace
+    exception_detail
+        {
+        class error_info_base;
+        struct type_info_;
+
+        struct
+        error_info_container
+            {
+            virtual char const * diagnostic_information( char const * ) const = 0;
+            virtual shared_ptr<error_info_base> get( type_info_ const & ) const = 0;
+            virtual void set( shared_ptr<error_info_base> const &, type_info_ const & ) = 0;
+            virtual void add_ref() const = 0;
+            virtual bool release() const = 0;
+            virtual refcount_ptr<exception_detail::error_info_container> clone() const = 0;
+
+            protected:
+
+            ~error_info_container() throw()
+                {
+                }
+            };
+
+        template <class>
+        struct get_info;
+
+        template <>
+        struct get_info<throw_function>;
+
+        template <>
+        struct get_info<throw_file>;
+
+        template <>
+        struct get_info<throw_line>;
+
+        char const * get_diagnostic_information( exception const &, char const * );
+
+        void copy_boost_exception( exception *, exception const * );
+
+        template <class E,class Tag,class T>
+        E const & set_info( E const &, error_info<Tag,T> const & );
+
+        template <class E>
+        E const & set_info( E const &, throw_function const & );
+
+        template <class E>
+        E const & set_info( E const &, throw_file const & );
+
+        template <class E>
+        E const & set_info( E const &, throw_line const & );
+        }
+
+#if defined(__GNUC__)
+# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
+#  pragma GCC visibility push (default)
+# endif
+#endif
+    class
+    exception
+        {
+        //<N3757>
+        public:
+        template <class Tag> void set( typename Tag::type const & );
+        template <class Tag> typename Tag::type const * get() const;
+        //</N3757>
+
+        protected:
+
+        exception():
+            throw_function_(0),
+            throw_file_(0),
+            throw_line_(-1)
+            {
+            }
+
+#ifdef __HP_aCC
+        //On HP aCC, this protected copy constructor prevents throwing boost::exception.
+        //On all other platforms, the same effect is achieved by the pure virtual destructor.
+        exception( exception const & x ) throw():
+            data_(x.data_),
+            throw_function_(x.throw_function_),
+            throw_file_(x.throw_file_),
+            throw_line_(x.throw_line_)
+            {
+            }
+#endif
+
+        virtual ~exception() throw()
+#ifndef __HP_aCC
+            = 0 //Workaround for HP aCC, =0 incorrectly leads to link errors.
+#endif
+            ;
+
+#if (defined(__MWERKS__) && __MWERKS__<=0x3207) || (defined(_MSC_VER) && _MSC_VER<=1310)
+        public:
+#else
+        private:
+
+        template <class E>
+        friend E const & exception_detail::set_info( E const &, throw_function const & );
+
+        template <class E>
+        friend E const & exception_detail::set_info( E const &, throw_file const & );
+
+        template <class E>
+        friend E const & exception_detail::set_info( E const &, throw_line const & );
+
+        template <class E,class Tag,class T>
+        friend E const & exception_detail::set_info( E const &, error_info<Tag,T> const & );
+
+        friend char const * exception_detail::get_diagnostic_information( exception const &, char const * );
+
+        template <class>
+        friend struct exception_detail::get_info;
+        friend struct exception_detail::get_info<throw_function>;
+        friend struct exception_detail::get_info<throw_file>;
+        friend struct exception_detail::get_info<throw_line>;
+        friend void exception_detail::copy_boost_exception( exception *, exception const * );
+#endif
+        mutable exception_detail::refcount_ptr<exception_detail::error_info_container> data_;
+        mutable char const * throw_function_;
+        mutable char const * throw_file_;
+        mutable int throw_line_;
+        };
+#if defined(__GNUC__)
+# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
+#  pragma GCC visibility pop
+# endif
+#endif
+
+    inline
+    exception::
+    ~exception() throw()
+        {
+        }
+
+    namespace
+    exception_detail
+        {
+        template <class E>
+        E const &
+        set_info( E const & x, throw_function const & y )
+            {
+            x.throw_function_=y.v_;
+            return x;
+            }
+
+        template <class E>
+        E const &
+        set_info( E const & x, throw_file const & y )
+            {
+            x.throw_file_=y.v_;
+            return x;
+            }
+
+        template <class E>
+        E const &
+        set_info( E const & x, throw_line const & y )
+            {
+            x.throw_line_=y.v_;
+            return x;
+            }
+        }
+
+    ////////////////////////////////////////////////////////////////////////
+
+    namespace
+    exception_detail
+        {
+#if defined(__GNUC__)
+# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
+#  pragma GCC visibility push (default)
+# endif
+#endif
+        template <class T>
+        struct
+        error_info_injector:
+            public T,
+            public exception
+            {
+            explicit
+            error_info_injector( T const & x ):
+                T(x)
+                {
+                }
+
+            ~error_info_injector() throw()
+                {
+                }
+            };
+#if defined(__GNUC__)
+# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
+#  pragma GCC visibility pop
+# endif
+#endif
+
+        struct large_size { char c[256]; };
+        large_size dispatch_boost_exception( exception const * );
+
+        struct small_size { };
+        small_size dispatch_boost_exception( void const * );
+
+        template <class,int>
+        struct enable_error_info_helper;
+
+        template <class T>
+        struct
+        enable_error_info_helper<T,sizeof(large_size)>
+            {
+            typedef T type;
+            };
+
+        template <class T>
+        struct
+        enable_error_info_helper<T,sizeof(small_size)>
+            {
+            typedef error_info_injector<T> type;
+            };
+
+        template <class T>
+        struct
+        enable_error_info_return_type
+            {
+            typedef typename enable_error_info_helper<T,sizeof(exception_detail::dispatch_boost_exception(static_cast<T *>(0)))>::type type;
+            };
+        }
+
+    template <class T>
+    inline
+    typename
+    exception_detail::enable_error_info_return_type<T>::type
+    enable_error_info( T const & x )
+        {
+        typedef typename exception_detail::enable_error_info_return_type<T>::type rt;
+        return rt(x);
+        }
+
+    ////////////////////////////////////////////////////////////////////////
+
+    namespace
+    exception_detail
+        {
+#if defined(__GNUC__)
+# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
+#  pragma GCC visibility push (default)
+# endif
+#endif
+        class
+        clone_base
+            {
+            public:
+
+            virtual clone_base const * clone() const = 0;
+            virtual void rethrow() const = 0;
+
+            virtual
+            ~clone_base() throw()
+                {
+                }
+            };
+#if defined(__GNUC__)
+# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
+#  pragma GCC visibility pop
+# endif
+#endif
+
+        inline
+        void
+        copy_boost_exception( exception * a, exception const * b )
+            {
+            refcount_ptr<error_info_container> data;
+            if( error_info_container * d=b->data_.get() )
+                data = d->clone();
+            a->throw_file_ = b->throw_file_;
+            a->throw_line_ = b->throw_line_;
+            a->throw_function_ = b->throw_function_;
+            a->data_ = data;
+            }
+
+        inline
+        void
+        copy_boost_exception( void *, void const * )
+            {
+            }
+
+#if defined(__GNUC__)
+# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
+#  pragma GCC visibility push (default)
+# endif
+#endif
+        template <class T>
+        class
+        clone_impl:
+            public T,
+            public virtual clone_base
+            {
+            struct clone_tag { };
+            clone_impl( clone_impl const & x, clone_tag ):
+                T(x)
+                {
+                copy_boost_exception(this,&x);
+                }
+
+            public:
+
+            explicit
+            clone_impl( T const & x ):
+                T(x)
+                {
+                copy_boost_exception(this,&x);
+                }
+
+            ~clone_impl() throw()
+                {
+                }
+
+            private:
+
+            clone_base const *
+            clone() const
+                {
+                return new clone_impl(*this,clone_tag());
+                }
+
+            void
+            rethrow() const
+                {
+                throw*this;
+                }
+            };
+        }
+#if defined(__GNUC__)
+# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
+#  pragma GCC visibility pop
+# endif
+#endif
+
+    template <class T>
+    inline
+    exception_detail::clone_impl<T>
+    enable_current_exception( T const & x )
+        {
+        return exception_detail::clone_impl<T>(x);
+        }
+    }
+
+#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
+#pragma warning(pop)
+#endif
+#endif
diff --git a/third_party/boost/boost/function.hpp b/third_party/boost/boost/function.hpp
new file mode 100644
index 0000000..b72842b
--- /dev/null
+++ b/third_party/boost/boost/function.hpp
@@ -0,0 +1,66 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2001-2003. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org/libs/function
+
+// William Kempf, Jesse Jones and Karl Nelson were all very helpful in the
+// design of this library.
+
+#include <functional> // unary_function, binary_function
+
+#include <boost/preprocessor/iterate.hpp>
+#include <boost/detail/workaround.hpp>
+
+#ifndef BOOST_FUNCTION_MAX_ARGS
+#  define BOOST_FUNCTION_MAX_ARGS 10
+#endif // BOOST_FUNCTION_MAX_ARGS
+
+// Include the prologue here so that the use of file-level iteration
+// in anything that may be included by function_template.hpp doesn't break
+#include <boost/function/detail/prologue.hpp>
+
+// Older Visual Age C++ version do not handle the file iteration well
+#if BOOST_WORKAROUND(__IBMCPP__, >= 500) && BOOST_WORKAROUND(__IBMCPP__, < 800)
+#  if BOOST_FUNCTION_MAX_ARGS >= 0
+#    include <boost/function/function0.hpp>
+#  endif
+#  if BOOST_FUNCTION_MAX_ARGS >= 1
+#    include <boost/function/function1.hpp>
+#  endif
+#  if BOOST_FUNCTION_MAX_ARGS >= 2
+#    include <boost/function/function2.hpp>
+#  endif
+#  if BOOST_FUNCTION_MAX_ARGS >= 3
+#    include <boost/function/function3.hpp>
+#  endif
+#  if BOOST_FUNCTION_MAX_ARGS >= 4
+#    include <boost/function/function4.hpp>
+#  endif
+#  if BOOST_FUNCTION_MAX_ARGS >= 5
+#    include <boost/function/function5.hpp>
+#  endif
+#  if BOOST_FUNCTION_MAX_ARGS >= 6
+#    include <boost/function/function6.hpp>
+#  endif
+#  if BOOST_FUNCTION_MAX_ARGS >= 7
+#    include <boost/function/function7.hpp>
+#  endif
+#  if BOOST_FUNCTION_MAX_ARGS >= 8
+#    include <boost/function/function8.hpp>
+#  endif
+#  if BOOST_FUNCTION_MAX_ARGS >= 9
+#    include <boost/function/function9.hpp>
+#  endif
+#  if BOOST_FUNCTION_MAX_ARGS >= 10
+#    include <boost/function/function10.hpp>
+#  endif
+#else
+// What is the '3' for?
+#  define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_FUNCTION_MAX_ARGS,<boost/function/detail/function_iterate.hpp>))
+#  include BOOST_PP_ITERATE()
+#  undef BOOST_PP_ITERATION_PARAMS_1
+#endif
diff --git a/third_party/boost/boost/function/detail/function_iterate.hpp b/third_party/boost/boost/function/detail/function_iterate.hpp
new file mode 100644
index 0000000..d144e2f
--- /dev/null
+++ b/third_party/boost/boost/function/detail/function_iterate.hpp
@@ -0,0 +1,15 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2003. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+#if !defined(BOOST_PP_IS_ITERATING)
+# error Boost.Function - do not include this file!
+#endif
+
+#define BOOST_FUNCTION_NUM_ARGS BOOST_PP_ITERATION()
+#include <boost/function/detail/maybe_include.hpp>
+#undef BOOST_FUNCTION_NUM_ARGS
diff --git a/third_party/boost/boost/function/detail/maybe_include.hpp b/third_party/boost/boost/function/detail/maybe_include.hpp
new file mode 100644
index 0000000..92f71bb
--- /dev/null
+++ b/third_party/boost/boost/function/detail/maybe_include.hpp
@@ -0,0 +1,267 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2003. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#if BOOST_FUNCTION_NUM_ARGS == 0
+#  ifndef BOOST_FUNCTION_0
+#    define BOOST_FUNCTION_0
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 1
+#  ifndef BOOST_FUNCTION_1
+#    define BOOST_FUNCTION_1
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 2
+#  ifndef BOOST_FUNCTION_2
+#    define BOOST_FUNCTION_2
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 3
+#  ifndef BOOST_FUNCTION_3
+#    define BOOST_FUNCTION_3
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 4
+#  ifndef BOOST_FUNCTION_4
+#    define BOOST_FUNCTION_4
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 5
+#  ifndef BOOST_FUNCTION_5
+#    define BOOST_FUNCTION_5
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 6
+#  ifndef BOOST_FUNCTION_6
+#    define BOOST_FUNCTION_6
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 7
+#  ifndef BOOST_FUNCTION_7
+#    define BOOST_FUNCTION_7
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 8
+#  ifndef BOOST_FUNCTION_8
+#    define BOOST_FUNCTION_8
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 9
+#  ifndef BOOST_FUNCTION_9
+#    define BOOST_FUNCTION_9
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 10
+#  ifndef BOOST_FUNCTION_10
+#    define BOOST_FUNCTION_10
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 11
+#  ifndef BOOST_FUNCTION_11
+#    define BOOST_FUNCTION_11
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 12
+#  ifndef BOOST_FUNCTION_12
+#    define BOOST_FUNCTION_12
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 13
+#  ifndef BOOST_FUNCTION_13
+#    define BOOST_FUNCTION_13
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 14
+#  ifndef BOOST_FUNCTION_14
+#    define BOOST_FUNCTION_14
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 15
+#  ifndef BOOST_FUNCTION_15
+#    define BOOST_FUNCTION_15
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 16
+#  ifndef BOOST_FUNCTION_16
+#    define BOOST_FUNCTION_16
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 17
+#  ifndef BOOST_FUNCTION_17
+#    define BOOST_FUNCTION_17
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 18
+#  ifndef BOOST_FUNCTION_18
+#    define BOOST_FUNCTION_18
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 19
+#  ifndef BOOST_FUNCTION_19
+#    define BOOST_FUNCTION_19
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 20
+#  ifndef BOOST_FUNCTION_20
+#    define BOOST_FUNCTION_20
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 21
+#  ifndef BOOST_FUNCTION_21
+#    define BOOST_FUNCTION_21
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 22
+#  ifndef BOOST_FUNCTION_22
+#    define BOOST_FUNCTION_22
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 23
+#  ifndef BOOST_FUNCTION_23
+#    define BOOST_FUNCTION_23
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 24
+#  ifndef BOOST_FUNCTION_24
+#    define BOOST_FUNCTION_24
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 25
+#  ifndef BOOST_FUNCTION_25
+#    define BOOST_FUNCTION_25
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 26
+#  ifndef BOOST_FUNCTION_26
+#    define BOOST_FUNCTION_26
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 27
+#  ifndef BOOST_FUNCTION_27
+#    define BOOST_FUNCTION_27
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 28
+#  ifndef BOOST_FUNCTION_28
+#    define BOOST_FUNCTION_28
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 29
+#  ifndef BOOST_FUNCTION_29
+#    define BOOST_FUNCTION_29
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 30
+#  ifndef BOOST_FUNCTION_30
+#    define BOOST_FUNCTION_30
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 31
+#  ifndef BOOST_FUNCTION_31
+#    define BOOST_FUNCTION_31
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 32
+#  ifndef BOOST_FUNCTION_32
+#    define BOOST_FUNCTION_32
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 33
+#  ifndef BOOST_FUNCTION_33
+#    define BOOST_FUNCTION_33
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 34
+#  ifndef BOOST_FUNCTION_34
+#    define BOOST_FUNCTION_34
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 35
+#  ifndef BOOST_FUNCTION_35
+#    define BOOST_FUNCTION_35
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 36
+#  ifndef BOOST_FUNCTION_36
+#    define BOOST_FUNCTION_36
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 37
+#  ifndef BOOST_FUNCTION_37
+#    define BOOST_FUNCTION_37
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 38
+#  ifndef BOOST_FUNCTION_38
+#    define BOOST_FUNCTION_38
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 39
+#  ifndef BOOST_FUNCTION_39
+#    define BOOST_FUNCTION_39
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 40
+#  ifndef BOOST_FUNCTION_40
+#    define BOOST_FUNCTION_40
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 41
+#  ifndef BOOST_FUNCTION_41
+#    define BOOST_FUNCTION_41
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 42
+#  ifndef BOOST_FUNCTION_42
+#    define BOOST_FUNCTION_42
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 43
+#  ifndef BOOST_FUNCTION_43
+#    define BOOST_FUNCTION_43
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 44
+#  ifndef BOOST_FUNCTION_44
+#    define BOOST_FUNCTION_44
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 45
+#  ifndef BOOST_FUNCTION_45
+#    define BOOST_FUNCTION_45
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 46
+#  ifndef BOOST_FUNCTION_46
+#    define BOOST_FUNCTION_46
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 47
+#  ifndef BOOST_FUNCTION_47
+#    define BOOST_FUNCTION_47
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 48
+#  ifndef BOOST_FUNCTION_48
+#    define BOOST_FUNCTION_48
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 49
+#  ifndef BOOST_FUNCTION_49
+#    define BOOST_FUNCTION_49
+#    include <boost/function/function_template.hpp>
+#  endif
+#elif BOOST_FUNCTION_NUM_ARGS == 50
+#  ifndef BOOST_FUNCTION_50
+#    define BOOST_FUNCTION_50
+#    include <boost/function/function_template.hpp>
+#  endif
+#else
+#  error Cannot handle Boost.Function objects that accept more than 50 arguments!
+#endif
diff --git a/third_party/boost/boost/function/detail/prologue.hpp b/third_party/boost/boost/function/detail/prologue.hpp
new file mode 100644
index 0000000..53d0f05
--- /dev/null
+++ b/third_party/boost/boost/function/detail/prologue.hpp
@@ -0,0 +1,26 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2002-2003. Use, modification and
+//  distribution is subject to the Boost Software License, Version
+//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_FUNCTION_PROLOGUE_HPP
+#define BOOST_FUNCTION_PROLOGUE_HPP
+#  include <cassert>
+#  include <algorithm>
+#  include <boost/config/no_tr1/functional.hpp> // unary_function, binary_function
+#  include <boost/throw_exception.hpp>
+#  include <boost/config.hpp>
+#  include <boost/function/function_base.hpp>
+#  include <boost/mem_fn.hpp>
+#  include <boost/type_traits/is_integral.hpp>
+#  include <boost/preprocessor/enum.hpp>
+#  include <boost/preprocessor/enum_params.hpp>
+#  include <boost/preprocessor/cat.hpp>
+#  include <boost/preprocessor/repeat.hpp>
+#  include <boost/preprocessor/inc.hpp>
+#  include <boost/type_traits/is_void.hpp>
+#endif // BOOST_FUNCTION_PROLOGUE_HPP
diff --git a/third_party/boost/boost/function/function_base.hpp b/third_party/boost/boost/function/function_base.hpp
new file mode 100644
index 0000000..d683988
--- /dev/null
+++ b/third_party/boost/boost/function/function_base.hpp
@@ -0,0 +1,892 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2001-2006
+//  Copyright Emil Dotchevski 2007
+//  Use, modification and distribution is subject to the Boost Software License, Version 1.0.
+//  (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_FUNCTION_BASE_HEADER
+#define BOOST_FUNCTION_BASE_HEADER
+
+#include <stdexcept>
+#include <string>
+#include <memory>
+#include <new>
+#include <boost/config.hpp>
+#include <boost/detail/sp_typeinfo.hpp>
+#include <boost/assert.hpp>
+#include <boost/integer.hpp>
+#include <boost/type_traits/has_trivial_copy.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_volatile.hpp>
+#include <boost/type_traits/composite_traits.hpp>
+#include <boost/ref.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/type_traits/alignment_of.hpp>
+#ifndef BOOST_NO_SFINAE
+#  include "boost/utility/enable_if.hpp"
+#else
+#  include "boost/mpl/bool.hpp"
+#endif
+#include <boost/function_equal.hpp>
+#include <boost/function/function_fwd.hpp>
+
+#if defined(BOOST_MSVC)
+#   pragma warning( push )
+#   pragma warning( disable : 4793 ) // complaint about native code generation
+#   pragma warning( disable : 4127 ) // "conditional expression is constant"
+#endif
+
+// Define BOOST_FUNCTION_STD_NS to the namespace that contains type_info.
+#ifdef BOOST_NO_STD_TYPEINFO
+// Embedded VC++ does not have type_info in namespace std
+#  define BOOST_FUNCTION_STD_NS
+#else
+#  define BOOST_FUNCTION_STD_NS std
+#endif
+
+// Borrowed from Boost.Python library: determines the cases where we
+// need to use std::type_info::name to compare instead of operator==.
+#if defined( BOOST_NO_TYPEID )
+#  define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y))
+#elif defined(__GNUC__) \
+ || defined(_AIX) \
+ || (   defined(__sgi) && defined(__host_mips))
+#  include <cstring>
+#  define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) \
+     (std::strcmp((X).name(),(Y).name()) == 0)
+# else
+#  define BOOST_FUNCTION_COMPARE_TYPE_ID(X,Y) ((X)==(Y))
+#endif
+
+#if defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406 && !defined(BOOST_STRICT_CONFIG)
+#  define BOOST_FUNCTION_TARGET_FIX(x) x
+#else
+#  define BOOST_FUNCTION_TARGET_FIX(x)
+#endif // __ICL etc
+
+#  define BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor,Type)              \
+      typename ::boost::enable_if_c<          \
+                           !(::boost::is_integral<Functor>::value), \
+                           Type>::type
+
+namespace boost {
+  namespace detail {
+    namespace function {
+      class X;
+
+      /**
+       * A buffer used to store small function objects in
+       * boost::function. It is a union containing function pointers,
+       * object pointers, and a structure that resembles a bound
+       * member function pointer.
+       */
+      union function_buffer
+      {
+        // For pointers to function objects
+        mutable void* obj_ptr;
+
+        // For pointers to std::type_info objects
+        struct type_t {
+          // (get_functor_type_tag, check_functor_type_tag).
+          const detail::sp_typeinfo* type;
+
+          // Whether the type is const-qualified.
+          bool const_qualified;
+          // Whether the type is volatile-qualified.
+          bool volatile_qualified;
+        } type;
+
+        // For function pointers of all kinds
+        mutable void (*func_ptr)();
+
+        // For bound member pointers
+        struct bound_memfunc_ptr_t {
+          void (X::*memfunc_ptr)(int);
+          void* obj_ptr;
+        } bound_memfunc_ptr;
+
+        // For references to function objects. We explicitly keep
+        // track of the cv-qualifiers on the object referenced.
+        struct obj_ref_t {
+          mutable void* obj_ptr;
+          bool is_const_qualified;
+          bool is_volatile_qualified;
+        } obj_ref;
+
+        // To relax aliasing constraints
+        mutable char data;
+      };
+
+      /**
+       * The unusable class is a placeholder for unused function arguments
+       * It is also completely unusable except that it constructable from
+       * anything. This helps compilers without partial specialization to
+       * handle Boost.Function objects returning void.
+       */
+      struct unusable
+      {
+        unusable() {}
+        template<typename T> unusable(const T&) {}
+      };
+
+      /* Determine the return type. This supports compilers that do not support
+       * void returns or partial specialization by silently changing the return
+       * type to "unusable".
+       */
+      template<typename T> struct function_return_type { typedef T type; };
+
+      template<>
+      struct function_return_type<void>
+      {
+        typedef unusable type;
+      };
+
+      // The operation type to perform on the given functor/function pointer
+      enum functor_manager_operation_type {
+        clone_functor_tag,
+        move_functor_tag,
+        destroy_functor_tag,
+        check_functor_type_tag,
+        get_functor_type_tag
+      };
+
+      // Tags used to decide between different types of functions
+      struct function_ptr_tag {};
+      struct function_obj_tag {};
+      struct member_ptr_tag {};
+      struct function_obj_ref_tag {};
+
+      template<typename F>
+      class get_function_tag
+      {
+        typedef typename mpl::if_c<(is_pointer<F>::value),
+                                   function_ptr_tag,
+                                   function_obj_tag>::type ptr_or_obj_tag;
+
+        typedef typename mpl::if_c<(is_member_pointer<F>::value),
+                                   member_ptr_tag,
+                                   ptr_or_obj_tag>::type ptr_or_obj_or_mem_tag;
+
+        typedef typename mpl::if_c<(is_reference_wrapper<F>::value),
+                                   function_obj_ref_tag,
+                                   ptr_or_obj_or_mem_tag>::type or_ref_tag;
+
+      public:
+        typedef or_ref_tag type;
+      };
+
+      // The trivial manager does nothing but return the same pointer (if we
+      // are cloning) or return the null pointer (if we are deleting).
+      template<typename F>
+      struct reference_manager
+      {
+        static inline void
+        manage(const function_buffer& in_buffer, function_buffer& out_buffer,
+               functor_manager_operation_type op)
+        {
+          switch (op) {
+          case clone_functor_tag:
+            out_buffer.obj_ref = in_buffer.obj_ref;
+            return;
+
+          case move_functor_tag:
+            out_buffer.obj_ref = in_buffer.obj_ref;
+            in_buffer.obj_ref.obj_ptr = 0;
+            return;
+
+          case destroy_functor_tag:
+            out_buffer.obj_ref.obj_ptr = 0;
+            return;
+
+          case check_functor_type_tag:
+            {
+              const detail::sp_typeinfo& check_type
+                = *out_buffer.type.type;
+
+              // Check whether we have the same type. We can add
+              // cv-qualifiers, but we can't take them away.
+              if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(F))
+                  && (!in_buffer.obj_ref.is_const_qualified
+                      || out_buffer.type.const_qualified)
+                  && (!in_buffer.obj_ref.is_volatile_qualified
+                      || out_buffer.type.volatile_qualified))
+                out_buffer.obj_ptr = in_buffer.obj_ref.obj_ptr;
+              else
+                out_buffer.obj_ptr = 0;
+            }
+            return;
+
+          case get_functor_type_tag:
+            out_buffer.type.type = &BOOST_SP_TYPEID(F);
+            out_buffer.type.const_qualified = in_buffer.obj_ref.is_const_qualified;
+            out_buffer.type.volatile_qualified = in_buffer.obj_ref.is_volatile_qualified;
+            return;
+          }
+        }
+      };
+
+      /**
+       * Determine if boost::function can use the small-object
+       * optimization with the function object type F.
+       */
+      template<typename F>
+      struct function_allows_small_object_optimization
+      {
+        BOOST_STATIC_CONSTANT
+          (bool,
+           value = ((sizeof(F) <= sizeof(function_buffer) &&
+                     (alignment_of<function_buffer>::value
+                      % alignment_of<F>::value == 0))));
+      };
+
+      template <typename F,typename A>
+      struct functor_wrapper: public F, public A
+      {
+        functor_wrapper( F f, A a ):
+          F(f),
+          A(a)
+        {
+        }
+
+        functor_wrapper(const functor_wrapper& f) :
+          F(static_cast<const F&>(f)),
+          A(static_cast<const A&>(f))
+        {
+        }
+      };
+
+      /**
+       * The functor_manager class contains a static function "manage" which
+       * can clone or destroy the given function/function object pointer.
+       */
+      template<typename Functor>
+      struct functor_manager_common
+      {
+        typedef Functor functor_type;
+
+        // Function pointers
+        static inline void
+        manage_ptr(const function_buffer& in_buffer, function_buffer& out_buffer,
+                functor_manager_operation_type op)
+        {
+          if (op == clone_functor_tag)
+            out_buffer.func_ptr = in_buffer.func_ptr;
+          else if (op == move_functor_tag) {
+            out_buffer.func_ptr = in_buffer.func_ptr;
+            in_buffer.func_ptr = 0;
+          } else if (op == destroy_functor_tag)
+            out_buffer.func_ptr = 0;
+          else if (op == check_functor_type_tag) {
+            const boost::detail::sp_typeinfo& check_type
+              = *out_buffer.type.type;
+            if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
+              out_buffer.obj_ptr = &in_buffer.func_ptr;
+            else
+              out_buffer.obj_ptr = 0;
+          } else /* op == get_functor_type_tag */ {
+            out_buffer.type.type = &BOOST_SP_TYPEID(Functor);
+            out_buffer.type.const_qualified = false;
+            out_buffer.type.volatile_qualified = false;
+          }
+        }
+
+        // Function objects that fit in the small-object buffer.
+        static inline void
+        manage_small(const function_buffer& in_buffer, function_buffer& out_buffer,
+                functor_manager_operation_type op)
+        {
+          if (op == clone_functor_tag || op == move_functor_tag) {
+            const functor_type* in_functor =
+              reinterpret_cast<const functor_type*>(&in_buffer.data);
+            new (reinterpret_cast<void*>(&out_buffer.data)) functor_type(*in_functor);
+
+            if (op == move_functor_tag) {
+              functor_type* f = reinterpret_cast<functor_type*>(&in_buffer.data);
+              (void)f; // suppress warning about the value of f not being used (MSVC)
+              f->~Functor();
+            }
+          } else if (op == destroy_functor_tag) {
+            // Some compilers (Borland, vc6, ...) are unhappy with ~functor_type.
+             functor_type* f = reinterpret_cast<functor_type*>(&out_buffer.data);
+             (void)f; // suppress warning about the value of f not being used (MSVC)
+             f->~Functor();
+          } else if (op == check_functor_type_tag) {
+            const detail::sp_typeinfo& check_type
+              = *out_buffer.type.type;
+            if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
+              out_buffer.obj_ptr = &in_buffer.data;
+            else
+              out_buffer.obj_ptr = 0;
+          } else /* op == get_functor_type_tag */ {
+            out_buffer.type.type = &BOOST_SP_TYPEID(Functor);
+            out_buffer.type.const_qualified = false;
+            out_buffer.type.volatile_qualified = false;
+          }
+        }
+      };
+
+      template<typename Functor>
+      struct functor_manager
+      {
+      private:
+        typedef Functor functor_type;
+
+        // Function pointers
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
+                functor_manager_operation_type op, function_ptr_tag)
+        {
+          functor_manager_common<Functor>::manage_ptr(in_buffer,out_buffer,op);
+        }
+
+        // Function objects that fit in the small-object buffer.
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
+                functor_manager_operation_type op, mpl::true_)
+        {
+          functor_manager_common<Functor>::manage_small(in_buffer,out_buffer,op);
+        }
+
+        // Function objects that require heap allocation
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
+                functor_manager_operation_type op, mpl::false_)
+        {
+          if (op == clone_functor_tag) {
+            // Clone the functor
+            // GCC 2.95.3 gets the CV qualifiers wrong here, so we
+            // can't do the static_cast that we should do.
+            // jewillco: Changing this to static_cast because GCC 2.95.3 is
+            // obsolete.
+            const functor_type* f =
+              static_cast<const functor_type*>(in_buffer.obj_ptr);
+            functor_type* new_f = new functor_type(*f);
+            out_buffer.obj_ptr = new_f;
+          } else if (op == move_functor_tag) {
+            out_buffer.obj_ptr = in_buffer.obj_ptr;
+            in_buffer.obj_ptr = 0;
+          } else if (op == destroy_functor_tag) {
+            /* Cast from the void pointer to the functor pointer type */
+            functor_type* f =
+              static_cast<functor_type*>(out_buffer.obj_ptr);
+            delete f;
+            out_buffer.obj_ptr = 0;
+          } else if (op == check_functor_type_tag) {
+            const detail::sp_typeinfo& check_type
+              = *out_buffer.type.type;
+            if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
+              out_buffer.obj_ptr = in_buffer.obj_ptr;
+            else
+              out_buffer.obj_ptr = 0;
+          } else /* op == get_functor_type_tag */ {
+            out_buffer.type.type = &BOOST_SP_TYPEID(Functor);
+            out_buffer.type.const_qualified = false;
+            out_buffer.type.volatile_qualified = false;
+          }
+        }
+
+        // For function objects, we determine whether the function
+        // object can use the small-object optimization buffer or
+        // whether we need to allocate it on the heap.
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
+                functor_manager_operation_type op, function_obj_tag)
+        {
+          manager(in_buffer, out_buffer, op,
+                  mpl::bool_<(function_allows_small_object_optimization<functor_type>::value)>());
+        }
+
+        // For member pointers, we use the small-object optimization buffer.
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
+                functor_manager_operation_type op, member_ptr_tag)
+        {
+          manager(in_buffer, out_buffer, op, mpl::true_());
+        }
+
+      public:
+        /* Dispatch to an appropriate manager based on whether we have a
+           function pointer or a function object pointer. */
+        static inline void
+        manage(const function_buffer& in_buffer, function_buffer& out_buffer,
+               functor_manager_operation_type op)
+        {
+          typedef typename get_function_tag<functor_type>::type tag_type;
+          switch (op) {
+          case get_functor_type_tag:
+            out_buffer.type.type = &BOOST_SP_TYPEID(functor_type);
+            out_buffer.type.const_qualified = false;
+            out_buffer.type.volatile_qualified = false;
+            return;
+
+          default:
+            manager(in_buffer, out_buffer, op, tag_type());
+            return;
+          }
+        }
+      };
+
+      template<typename Functor, typename Allocator>
+      struct functor_manager_a
+      {
+      private:
+        typedef Functor functor_type;
+
+        // Function pointers
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
+                functor_manager_operation_type op, function_ptr_tag)
+        {
+          functor_manager_common<Functor>::manage_ptr(in_buffer,out_buffer,op);
+        }
+
+        // Function objects that fit in the small-object buffer.
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
+                functor_manager_operation_type op, mpl::true_)
+        {
+          functor_manager_common<Functor>::manage_small(in_buffer,out_buffer,op);
+        }
+
+        // Function objects that require heap allocation
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
+                functor_manager_operation_type op, mpl::false_)
+        {
+          typedef functor_wrapper<Functor,Allocator> functor_wrapper_type;
+          typedef typename Allocator::template rebind<functor_wrapper_type>::other
+            wrapper_allocator_type;
+          typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
+
+          if (op == clone_functor_tag) {
+            // Clone the functor
+            // GCC 2.95.3 gets the CV qualifiers wrong here, so we
+            // can't do the static_cast that we should do.
+            const functor_wrapper_type* f =
+              static_cast<const functor_wrapper_type*>(in_buffer.obj_ptr);
+            wrapper_allocator_type wrapper_allocator(static_cast<Allocator const &>(*f));
+            wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
+            wrapper_allocator.construct(copy, *f);
+
+            // Get back to the original pointer type
+            functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
+            out_buffer.obj_ptr = new_f;
+          } else if (op == move_functor_tag) {
+            out_buffer.obj_ptr = in_buffer.obj_ptr;
+            in_buffer.obj_ptr = 0;
+          } else if (op == destroy_functor_tag) {
+            /* Cast from the void pointer to the functor_wrapper_type */
+            functor_wrapper_type* victim =
+              static_cast<functor_wrapper_type*>(in_buffer.obj_ptr);
+            wrapper_allocator_type wrapper_allocator(static_cast<Allocator const &>(*victim));
+            wrapper_allocator.destroy(victim);
+            wrapper_allocator.deallocate(victim,1);
+            out_buffer.obj_ptr = 0;
+          } else if (op == check_functor_type_tag) {
+            const detail::sp_typeinfo& check_type
+              = *out_buffer.type.type;
+            if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, BOOST_SP_TYPEID(Functor)))
+              out_buffer.obj_ptr = in_buffer.obj_ptr;
+            else
+              out_buffer.obj_ptr = 0;
+          } else /* op == get_functor_type_tag */ {
+            out_buffer.type.type = &BOOST_SP_TYPEID(Functor);
+            out_buffer.type.const_qualified = false;
+            out_buffer.type.volatile_qualified = false;
+          }
+        }
+
+        // For function objects, we determine whether the function
+        // object can use the small-object optimization buffer or
+        // whether we need to allocate it on the heap.
+        static inline void
+        manager(const function_buffer& in_buffer, function_buffer& out_buffer,
+                functor_manager_operation_type op, function_obj_tag)
+        {
+          manager(in_buffer, out_buffer, op,
+                  mpl::bool_<(function_allows_small_object_optimization<functor_type>::value)>());
+        }
+
+      public:
+        /* Dispatch to an appropriate manager based on whether we have a
+           function pointer or a function object pointer. */
+        static inline void
+        manage(const function_buffer& in_buffer, function_buffer& out_buffer,
+               functor_manager_operation_type op)
+        {
+          typedef typename get_function_tag<functor_type>::type tag_type;
+          switch (op) {
+          case get_functor_type_tag:
+            out_buffer.type.type = &BOOST_SP_TYPEID(functor_type);
+            out_buffer.type.const_qualified = false;
+            out_buffer.type.volatile_qualified = false;
+            return;
+
+          default:
+            manager(in_buffer, out_buffer, op, tag_type());
+            return;
+          }
+        }
+      };
+
+      // A type that is only used for comparisons against zero
+      struct useless_clear_type {};
+
+#ifdef BOOST_NO_SFINAE
+      // These routines perform comparisons between a Boost.Function
+      // object and an arbitrary function object (when the last
+      // parameter is mpl::bool_<false>) or against zero (when the
+      // last parameter is mpl::bool_<true>). They are only necessary
+      // for compilers that don't support SFINAE.
+      template<typename Function, typename Functor>
+        bool
+        compare_equal(const Function& f, const Functor&, int, mpl::bool_<true>)
+        { return f.empty(); }
+
+      template<typename Function, typename Functor>
+        bool
+        compare_not_equal(const Function& f, const Functor&, int,
+                          mpl::bool_<true>)
+        { return !f.empty(); }
+
+      template<typename Function, typename Functor>
+        bool
+        compare_equal(const Function& f, const Functor& g, long,
+                      mpl::bool_<false>)
+        {
+          if (const Functor* fp = f.template target<Functor>())
+            return function_equal(*fp, g);
+          else return false;
+        }
+
+      template<typename Function, typename Functor>
+        bool
+        compare_equal(const Function& f, const reference_wrapper<Functor>& g,
+                      int, mpl::bool_<false>)
+        {
+          if (const Functor* fp = f.template target<Functor>())
+            return fp == g.get_pointer();
+          else return false;
+        }
+
+      template<typename Function, typename Functor>
+        bool
+        compare_not_equal(const Function& f, const Functor& g, long,
+                          mpl::bool_<false>)
+        {
+          if (const Functor* fp = f.template target<Functor>())
+            return !function_equal(*fp, g);
+          else return true;
+        }
+
+      template<typename Function, typename Functor>
+        bool
+        compare_not_equal(const Function& f,
+                          const reference_wrapper<Functor>& g, int,
+                          mpl::bool_<false>)
+        {
+          if (const Functor* fp = f.template target<Functor>())
+            return fp != g.get_pointer();
+          else return true;
+        }
+#endif // BOOST_NO_SFINAE
+
+      /**
+       * Stores the "manager" portion of the vtable for a
+       * boost::function object.
+       */
+      struct vtable_base
+      {
+        void (*manager)(const function_buffer& in_buffer,
+                        function_buffer& out_buffer,
+                        functor_manager_operation_type op);
+      };
+    } // end namespace function
+  } // end namespace detail
+
+/**
+ * The function_base class contains the basic elements needed for the
+ * function1, function2, function3, etc. classes. It is common to all
+ * functions (and as such can be used to tell if we have one of the
+ * functionN objects).
+ */
+class function_base
+{
+public:
+  function_base() : vtable(0) { }
+
+  /** Determine if the function is empty (i.e., has no target). */
+  bool empty() const { return !vtable; }
+
+  /** Retrieve the type of the stored function object, or BOOST_SP_TYPEID(void)
+      if this is empty. */
+  const detail::sp_typeinfo& target_type() const
+  {
+    if (!vtable) return BOOST_SP_TYPEID(void);
+
+    detail::function::function_buffer type;
+    get_vtable()->manager(functor, type, detail::function::get_functor_type_tag);
+    return *type.type.type;
+  }
+
+  template<typename Functor>
+    Functor* target()
+    {
+      if (!vtable) return 0;
+
+      detail::function::function_buffer type_result;
+      type_result.type.type = &BOOST_SP_TYPEID(Functor);
+      type_result.type.const_qualified = is_const<Functor>::value;
+      type_result.type.volatile_qualified = is_volatile<Functor>::value;
+      get_vtable()->manager(functor, type_result,
+                      detail::function::check_functor_type_tag);
+      return static_cast<Functor*>(type_result.obj_ptr);
+    }
+
+  template<typename Functor>
+    const Functor* target() const
+    {
+      if (!vtable) return 0;
+
+      detail::function::function_buffer type_result;
+      type_result.type.type = &BOOST_SP_TYPEID(Functor);
+      type_result.type.const_qualified = true;
+      type_result.type.volatile_qualified = is_volatile<Functor>::value;
+      get_vtable()->manager(functor, type_result,
+                      detail::function::check_functor_type_tag);
+      // GCC 2.95.3 gets the CV qualifiers wrong here, so we
+      // can't do the static_cast that we should do.
+      return static_cast<const Functor*>(type_result.obj_ptr);
+    }
+
+  template<typename F>
+    bool contains(const F& f) const
+    {
+      if (const F* fp = this->template target<F>())
+      {
+        return function_equal(*fp, f);
+      } else {
+        return false;
+      }
+    }
+
+#if defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3
+  // GCC 3.3 and newer cannot copy with the global operator==, due to
+  // problems with instantiation of function return types before it
+  // has been verified that the argument types match up.
+  template<typename Functor>
+    BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+    operator==(Functor g) const
+    {
+      if (const Functor* fp = target<Functor>())
+        return function_equal(*fp, g);
+      else return false;
+    }
+
+  template<typename Functor>
+    BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+    operator!=(Functor g) const
+    {
+      if (const Functor* fp = target<Functor>())
+        return !function_equal(*fp, g);
+      else return true;
+    }
+#endif
+
+public: // should be protected, but GCC 2.95.3 will fail to allow access
+  detail::function::vtable_base* get_vtable() const {
+    return reinterpret_cast<detail::function::vtable_base*>(
+             reinterpret_cast<std::size_t>(vtable) & ~static_cast<std::size_t>(0x01));
+  }
+
+  bool has_trivial_copy_and_destroy() const {
+    return reinterpret_cast<std::size_t>(vtable) & 0x01;
+  }
+
+  detail::function::vtable_base* vtable;
+  mutable detail::function::function_buffer functor;
+};
+
+/**
+ * The bad_function_call exception class is thrown when a boost::function
+ * object is invoked
+ */
+class bad_function_call : public std::runtime_error
+{
+public:
+  bad_function_call() : std::runtime_error("call to empty boost::function") {}
+};
+
+#ifndef BOOST_NO_SFINAE
+inline bool operator==(const function_base& f,
+                       detail::function::useless_clear_type*)
+{
+  return f.empty();
+}
+
+inline bool operator!=(const function_base& f,
+                       detail::function::useless_clear_type*)
+{
+  return !f.empty();
+}
+
+inline bool operator==(detail::function::useless_clear_type*,
+                       const function_base& f)
+{
+  return f.empty();
+}
+
+inline bool operator!=(detail::function::useless_clear_type*,
+                       const function_base& f)
+{
+  return !f.empty();
+}
+#endif
+
+#ifdef BOOST_NO_SFINAE
+// Comparisons between boost::function objects and arbitrary function objects
+template<typename Functor>
+  inline bool operator==(const function_base& f, Functor g)
+  {
+    typedef mpl::bool_<(is_integral<Functor>::value)> integral;
+    return detail::function::compare_equal(f, g, 0, integral());
+  }
+
+template<typename Functor>
+  inline bool operator==(Functor g, const function_base& f)
+  {
+    typedef mpl::bool_<(is_integral<Functor>::value)> integral;
+    return detail::function::compare_equal(f, g, 0, integral());
+  }
+
+template<typename Functor>
+  inline bool operator!=(const function_base& f, Functor g)
+  {
+    typedef mpl::bool_<(is_integral<Functor>::value)> integral;
+    return detail::function::compare_not_equal(f, g, 0, integral());
+  }
+
+template<typename Functor>
+  inline bool operator!=(Functor g, const function_base& f)
+  {
+    typedef mpl::bool_<(is_integral<Functor>::value)> integral;
+    return detail::function::compare_not_equal(f, g, 0, integral());
+  }
+#else
+
+#  if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
+// Comparisons between boost::function objects and arbitrary function
+// objects. GCC 3.3 and before has an obnoxious bug that prevents this
+// from working.
+template<typename Functor>
+  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+  operator==(const function_base& f, Functor g)
+  {
+    if (const Functor* fp = f.template target<Functor>())
+      return function_equal(*fp, g);
+    else return false;
+  }
+
+template<typename Functor>
+  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+  operator==(Functor g, const function_base& f)
+  {
+    if (const Functor* fp = f.template target<Functor>())
+      return function_equal(g, *fp);
+    else return false;
+  }
+
+template<typename Functor>
+  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+  operator!=(const function_base& f, Functor g)
+  {
+    if (const Functor* fp = f.template target<Functor>())
+      return !function_equal(*fp, g);
+    else return true;
+  }
+
+template<typename Functor>
+  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+  operator!=(Functor g, const function_base& f)
+  {
+    if (const Functor* fp = f.template target<Functor>())
+      return !function_equal(g, *fp);
+    else return true;
+  }
+#  endif
+
+template<typename Functor>
+  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+  operator==(const function_base& f, reference_wrapper<Functor> g)
+  {
+    if (const Functor* fp = f.template target<Functor>())
+      return fp == g.get_pointer();
+    else return false;
+  }
+
+template<typename Functor>
+  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+  operator==(reference_wrapper<Functor> g, const function_base& f)
+  {
+    if (const Functor* fp = f.template target<Functor>())
+      return g.get_pointer() == fp;
+    else return false;
+  }
+
+template<typename Functor>
+  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+  operator!=(const function_base& f, reference_wrapper<Functor> g)
+  {
+    if (const Functor* fp = f.template target<Functor>())
+      return fp != g.get_pointer();
+    else return true;
+  }
+
+template<typename Functor>
+  BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool)
+  operator!=(reference_wrapper<Functor> g, const function_base& f)
+  {
+    if (const Functor* fp = f.template target<Functor>())
+      return g.get_pointer() != fp;
+    else return true;
+  }
+
+#endif // Compiler supporting SFINAE
+
+namespace detail {
+  namespace function {
+    inline bool has_empty_target(const function_base* f)
+    {
+      return f->empty();
+    }
+
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310)
+    inline bool has_empty_target(const void*)
+    {
+      return false;
+    }
+#else
+    inline bool has_empty_target(...)
+    {
+      return false;
+    }
+#endif
+  } // end namespace function
+} // end namespace detail
+} // end namespace boost
+
+#undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL
+#undef BOOST_FUNCTION_COMPARE_TYPE_ID
+
+#if defined(BOOST_MSVC)
+#   pragma warning( pop )
+#endif
+
+#endif // BOOST_FUNCTION_BASE_HEADER
diff --git a/third_party/boost/boost/function/function_fwd.hpp b/third_party/boost/boost/function/function_fwd.hpp
new file mode 100644
index 0000000..ea0bf26
--- /dev/null
+++ b/third_party/boost/boost/function/function_fwd.hpp
@@ -0,0 +1,69 @@
+// Boost.Function library
+//  Copyright (C) Douglas Gregor 2008
+//
+//  Use, modification and distribution is subject to the Boost
+//  Software License, Version 1.0.  (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// For more information, see http://www.boost.org
+#ifndef BOOST_FUNCTION_FWD_HPP
+#define BOOST_FUNCTION_FWD_HPP
+#include <boost/config.hpp>
+
+#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 && !defined(BOOST_STRICT_CONFIG)
+// Work around a compiler bug.
+// boost::python::objects::function has to be seen by the compiler before the
+// boost::function class template.
+namespace boost { namespace python { namespace objects {
+  class function;
+}}}
+#endif
+
+#if defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG)                         \
+ || !(defined(BOOST_STRICT_CONFIG) || !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540)
+#  define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX
+#endif
+
+namespace boost {
+  class bad_function_call;
+
+#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
+  // Preferred syntax
+  template<typename Signature> class function;
+
+  template<typename Signature>
+  inline void swap(function<Signature>& f1, function<Signature>& f2)
+  {
+    f1.swap(f2);
+  }
+#endif // have partial specialization
+
+  // Portable syntax
+  template<typename R> class function0;
+  template<typename R, typename T1> class function1;
+  template<typename R, typename T1, typename T2> class function2;
+  template<typename R, typename T1, typename T2, typename T3> class function3;
+  template<typename R, typename T1, typename T2, typename T3, typename T4>
+    class function4;
+  template<typename R, typename T1, typename T2, typename T3, typename T4,
+           typename T5>
+    class function5;
+  template<typename R, typename T1, typename T2, typename T3, typename T4,
+           typename T5, typename T6>
+    class function6;
+  template<typename R, typename T1, typename T2, typename T3, typename T4,
+           typename T5, typename T6, typename T7>
+    class function7;
+  template<typename R, typename T1, typename T2, typename T3, typename T4,
+           typename T5, typename T6, typename T7, typename T8>
+    class function8;
+  template<typename R, typename T1, typename T2, typename T3, typename T4,
+           typename T5, typename T6, typename T7, typename T8, typename T9>
+    class function9;
+  template<typename R, typename T1, typename T2, typename T3, typename T4,
+           typename T5, typename T6, typename T7, typename T8, typename T9,
+           typename T10>
+    class function10;
+}
+
+#endif
diff --git a/third_party/boost/boost/function/function_template.hpp b/third_party/boost/boost/function/function_template.hpp
new file mode 100644
index 0000000..30fa383
--- /dev/null
+++ b/third_party/boost/boost/function/function_template.hpp
@@ -0,0 +1,1190 @@
+// Boost.Function library
+
+//  Copyright Douglas Gregor 2001-2006
+//  Copyright Emil Dotchevski 2007
+//  Use, modification and distribution is subject to the Boost Software License, Version 1.0.
+//  (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+// Note: this header is a header template and must NOT have multiple-inclusion
+// protection.
+#include <boost/function/detail/prologue.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+
+#if defined(BOOST_MSVC)
+#   pragma warning( push )
+#   pragma warning( disable : 4127 ) // "conditional expression is constant"
+#endif
+
+#define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
+
+#define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)
+
+#define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I)
+
+#define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY)
+
+#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
+#   define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a)
+#else
+#   include <boost/move/utility_core.hpp>
+#   define BOOST_FUNCTION_ARG(J,I,D) ::boost::forward< BOOST_PP_CAT(T,I) >(BOOST_PP_CAT(a,I))
+#   define BOOST_FUNCTION_ARGS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG,BOOST_PP_EMPTY)
+#endif
+
+#define BOOST_FUNCTION_ARG_TYPE(J,I,D) \
+  typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type);
+
+#define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY)
+
+// Comma if nonzero number of arguments
+#if BOOST_FUNCTION_NUM_ARGS == 0
+#  define BOOST_FUNCTION_COMMA
+#else
+#  define BOOST_FUNCTION_COMMA ,
+#endif // BOOST_FUNCTION_NUM_ARGS > 0
+
+// Class names used in this version of the code
+#define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_FUNCTION_INVOKER \
+  BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
+  BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \
+  BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
+  BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_FUNCTION_REF_INVOKER \
+  BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \
+  BOOST_JOIN(void_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_MEMBER_INVOKER \
+  BOOST_JOIN(function_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_VOID_MEMBER_INVOKER \
+  BOOST_JOIN(function_void_mem_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_GET_FUNCTION_INVOKER \
+  BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
+  BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \
+  BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_GET_MEMBER_INVOKER \
+  BOOST_JOIN(get_member_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_GET_INVOKER \
+  BOOST_JOIN(get_invoker,BOOST_FUNCTION_NUM_ARGS)
+#define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS)
+
+#ifndef BOOST_NO_VOID_RETURNS
+#  define BOOST_FUNCTION_VOID_RETURN_TYPE void
+#  define BOOST_FUNCTION_RETURN(X) X
+#else
+#  define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable
+#  define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE ()
+#endif
+
+namespace boost {
+  namespace detail {
+    namespace function {
+      template<
+        typename FunctionPtr,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+        >
+      struct BOOST_FUNCTION_FUNCTION_INVOKER
+      {
+        static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
+                        BOOST_FUNCTION_PARMS)
+        {
+          FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
+          return f(BOOST_FUNCTION_ARGS);
+        }
+      };
+
+      template<
+        typename FunctionPtr,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+        >
+      struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER
+      {
+        static BOOST_FUNCTION_VOID_RETURN_TYPE
+        invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA
+               BOOST_FUNCTION_PARMS)
+
+        {
+          FunctionPtr f = reinterpret_cast<FunctionPtr>(function_ptr.func_ptr);
+          BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS));
+        }
+      };
+
+      template<
+        typename FunctionObj,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+      >
+      struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
+      {
+        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
+                        BOOST_FUNCTION_PARMS)
+
+        {
+          FunctionObj* f;
+          if (function_allows_small_object_optimization<FunctionObj>::value)
+            f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
+          else
+            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
+          return (*f)(BOOST_FUNCTION_ARGS);
+        }
+      };
+
+      template<
+        typename FunctionObj,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+      >
+      struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
+      {
+        static BOOST_FUNCTION_VOID_RETURN_TYPE
+        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
+               BOOST_FUNCTION_PARMS)
+
+        {
+          FunctionObj* f;
+          if (function_allows_small_object_optimization<FunctionObj>::value)
+            f = reinterpret_cast<FunctionObj*>(&function_obj_ptr.data);
+          else
+            f = reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
+          BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
+        }
+      };
+
+      template<
+        typename FunctionObj,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+      >
+      struct BOOST_FUNCTION_FUNCTION_REF_INVOKER
+      {
+        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
+                        BOOST_FUNCTION_PARMS)
+
+        {
+          FunctionObj* f =
+            reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
+          return (*f)(BOOST_FUNCTION_ARGS);
+        }
+      };
+
+      template<
+        typename FunctionObj,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+      >
+      struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
+      {
+        static BOOST_FUNCTION_VOID_RETURN_TYPE
+        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
+               BOOST_FUNCTION_PARMS)
+
+        {
+          FunctionObj* f =
+            reinterpret_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
+          BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS));
+        }
+      };
+
+#if BOOST_FUNCTION_NUM_ARGS > 0
+      /* Handle invocation of member pointers. */
+      template<
+        typename MemberPtr,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+      >
+      struct BOOST_FUNCTION_MEMBER_INVOKER
+      {
+        static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
+                        BOOST_FUNCTION_PARMS)
+
+        {
+          MemberPtr* f =
+            reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
+          return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS);
+        }
+      };
+
+      template<
+        typename MemberPtr,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+      >
+      struct BOOST_FUNCTION_VOID_MEMBER_INVOKER
+      {
+        static BOOST_FUNCTION_VOID_RETURN_TYPE
+        invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA
+               BOOST_FUNCTION_PARMS)
+
+        {
+          MemberPtr* f =
+            reinterpret_cast<MemberPtr*>(&function_obj_ptr.data);
+          BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS));
+        }
+      };
+#endif
+
+      template<
+        typename FunctionPtr,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+      >
+      struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
+      {
+        typedef typename mpl::if_c<(is_void<R>::value),
+                            BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
+                            FunctionPtr,
+                            R BOOST_FUNCTION_COMMA
+                            BOOST_FUNCTION_TEMPLATE_ARGS
+                          >,
+                          BOOST_FUNCTION_FUNCTION_INVOKER<
+                            FunctionPtr,
+                            R BOOST_FUNCTION_COMMA
+                            BOOST_FUNCTION_TEMPLATE_ARGS
+                          >
+                       >::type type;
+      };
+
+      template<
+        typename FunctionObj,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+       >
+      struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
+      {
+        typedef typename mpl::if_c<(is_void<R>::value),
+                            BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
+                            FunctionObj,
+                            R BOOST_FUNCTION_COMMA
+                            BOOST_FUNCTION_TEMPLATE_ARGS
+                          >,
+                          BOOST_FUNCTION_FUNCTION_OBJ_INVOKER<
+                            FunctionObj,
+                            R BOOST_FUNCTION_COMMA
+                            BOOST_FUNCTION_TEMPLATE_ARGS
+                          >
+                       >::type type;
+      };
+
+      template<
+        typename FunctionObj,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+       >
+      struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
+      {
+        typedef typename mpl::if_c<(is_void<R>::value),
+                            BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER<
+                            FunctionObj,
+                            R BOOST_FUNCTION_COMMA
+                            BOOST_FUNCTION_TEMPLATE_ARGS
+                          >,
+                          BOOST_FUNCTION_FUNCTION_REF_INVOKER<
+                            FunctionObj,
+                            R BOOST_FUNCTION_COMMA
+                            BOOST_FUNCTION_TEMPLATE_ARGS
+                          >
+                       >::type type;
+      };
+
+#if BOOST_FUNCTION_NUM_ARGS > 0
+      /* Retrieve the appropriate invoker for a member pointer.  */
+      template<
+        typename MemberPtr,
+        typename R BOOST_FUNCTION_COMMA
+        BOOST_FUNCTION_TEMPLATE_PARMS
+       >
+      struct BOOST_FUNCTION_GET_MEMBER_INVOKER
+      {
+        typedef typename mpl::if_c<(is_void<R>::value),
+                            BOOST_FUNCTION_VOID_MEMBER_INVOKER<
+                            MemberPtr,
+                            R BOOST_FUNCTION_COMMA
+                            BOOST_FUNCTION_TEMPLATE_ARGS
+                          >,
+                          BOOST_FUNCTION_MEMBER_INVOKER<
+                            MemberPtr,
+                            R BOOST_FUNCTION_COMMA
+                            BOOST_FUNCTION_TEMPLATE_ARGS
+                          >
+                       >::type type;
+      };
+#endif
+
+      /* Given the tag returned by get_function_tag, retrieve the
+         actual invoker that will be used for the given function
+         object.
+
+         Each specialization contains an "apply" nested class template
+         that accepts the function object, return type, function
+         argument types, and allocator. The resulting "apply" class
+         contains two typedefs, "invoker_type" and "manager_type",
+         which correspond to the invoker and manager types. */
+      template<typename Tag>
+      struct BOOST_FUNCTION_GET_INVOKER { };
+
+      /* Retrieve the invoker for a function pointer. */
+      template<>
+      struct BOOST_FUNCTION_GET_INVOKER<function_ptr_tag>
+      {
+        template<typename FunctionPtr,
+                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
+        struct apply
+        {
+          typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
+                             FunctionPtr,
+                             R BOOST_FUNCTION_COMMA
+                             BOOST_FUNCTION_TEMPLATE_ARGS
+                           >::type
+            invoker_type;
+
+          typedef functor_manager<FunctionPtr> manager_type;
+        };
+
+        template<typename FunctionPtr,
+                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
+                 typename Allocator>
+        struct apply_a
+        {
+          typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
+                             FunctionPtr,
+                             R BOOST_FUNCTION_COMMA
+                             BOOST_FUNCTION_TEMPLATE_ARGS
+                           >::type
+            invoker_type;
+
+          typedef functor_manager<FunctionPtr> manager_type;
+        };
+      };
+
+#if BOOST_FUNCTION_NUM_ARGS > 0
+      /* Retrieve the invoker for a member pointer. */
+      template<>
+      struct BOOST_FUNCTION_GET_INVOKER<member_ptr_tag>
+      {
+        template<typename MemberPtr,
+                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
+        struct apply
+        {
+          typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
+                             MemberPtr,
+                             R BOOST_FUNCTION_COMMA
+                             BOOST_FUNCTION_TEMPLATE_ARGS
+                           >::type
+            invoker_type;
+
+          typedef functor_manager<MemberPtr> manager_type;
+        };
+
+        template<typename MemberPtr,
+                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
+                 typename Allocator>
+        struct apply_a
+        {
+          typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER<
+                             MemberPtr,
+                             R BOOST_FUNCTION_COMMA
+                             BOOST_FUNCTION_TEMPLATE_ARGS
+                           >::type
+            invoker_type;
+
+          typedef functor_manager<MemberPtr> manager_type;
+        };
+      };
+#endif
+
+      /* Retrieve the invoker for a function object. */
+      template<>
+      struct BOOST_FUNCTION_GET_INVOKER<function_obj_tag>
+      {
+        template<typename FunctionObj,
+                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
+        struct apply
+        {
+          typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
+                             FunctionObj,
+                             R BOOST_FUNCTION_COMMA
+                             BOOST_FUNCTION_TEMPLATE_ARGS
+                           >::type
+            invoker_type;
+
+          typedef functor_manager<FunctionObj> manager_type;
+        };
+
+        template<typename FunctionObj,
+                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
+                 typename Allocator>
+        struct apply_a
+        {
+          typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
+                             FunctionObj,
+                             R BOOST_FUNCTION_COMMA
+                             BOOST_FUNCTION_TEMPLATE_ARGS
+                           >::type
+            invoker_type;
+
+          typedef functor_manager_a<FunctionObj, Allocator> manager_type;
+        };
+      };
+
+      /* Retrieve the invoker for a reference to a function object. */
+      template<>
+      struct BOOST_FUNCTION_GET_INVOKER<function_obj_ref_tag>
+      {
+        template<typename RefWrapper,
+                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
+        struct apply
+        {
+          typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
+                             typename RefWrapper::type,
+                             R BOOST_FUNCTION_COMMA
+                             BOOST_FUNCTION_TEMPLATE_ARGS
+                           >::type
+            invoker_type;
+
+          typedef reference_manager<typename RefWrapper::type> manager_type;
+        };
+
+        template<typename RefWrapper,
+                 typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
+                 typename Allocator>
+        struct apply_a
+        {
+          typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER<
+                             typename RefWrapper::type,
+                             R BOOST_FUNCTION_COMMA
+                             BOOST_FUNCTION_TEMPLATE_ARGS
+                           >::type
+            invoker_type;
+
+          typedef reference_manager<typename RefWrapper::type> manager_type;
+        };
+      };
+
+
+      /**
+       * vtable for a specific boost::function instance. This
+       * structure must be an aggregate so that we can use static
+       * initialization in boost::function's assign_to and assign_to_a
+       * members. It therefore cannot have any constructors,
+       * destructors, base classes, etc.
+       */
+      template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
+      struct BOOST_FUNCTION_VTABLE
+      {
+#ifndef BOOST_NO_VOID_RETURNS
+        typedef R         result_type;
+#else
+        typedef typename function_return_type<R>::type result_type;
+#endif // BOOST_NO_VOID_RETURNS
+
+        typedef result_type (*invoker_type)(function_buffer&
+                                            BOOST_FUNCTION_COMMA
+                                            BOOST_FUNCTION_TEMPLATE_ARGS);
+
+        template<typename F>
+        bool assign_to(F f, function_buffer& functor) const
+        {
+          typedef typename get_function_tag<F>::type tag;
+          return assign_to(f, functor, tag());
+        }
+        template<typename F,typename Allocator>
+        bool assign_to_a(F f, function_buffer& functor, Allocator a) const
+        {
+          typedef typename get_function_tag<F>::type tag;
+          return assign_to_a(f, functor, a, tag());
+        }
+
+        void clear(function_buffer& functor) const
+        {
+          if (base.manager)
+            base.manager(functor, functor, destroy_functor_tag);
+        }
+
+      private:
+        // Function pointers
+        template<typename FunctionPtr>
+        bool
+        assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) const
+        {
+          this->clear(functor);
+          if (f) {
+            // should be a reinterpret cast, but some compilers insist
+            // on giving cv-qualifiers to free functions
+            functor.func_ptr = reinterpret_cast<void (*)()>(f);
+            return true;
+          } else {
+            return false;
+          }
+        }
+        template<typename FunctionPtr,typename Allocator>
+        bool
+        assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag) const
+        {
+          return assign_to(f,functor,function_ptr_tag());
+        }
+
+        // Member pointers
+#if BOOST_FUNCTION_NUM_ARGS > 0
+        template<typename MemberPtr>
+        bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag) const
+        {
+          // DPG TBD: Add explicit support for member function
+          // objects, so we invoke through mem_fn() but we retain the
+          // right target_type() values.
+          if (f) {
+            this->assign_to(boost::mem_fn(f), functor);
+            return true;
+          } else {
+            return false;
+          }
+        }
+        template<typename MemberPtr,typename Allocator>
+        bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag) const
+        {
+          // DPG TBD: Add explicit support for member function
+          // objects, so we invoke through mem_fn() but we retain the
+          // right target_type() values.
+          if (f) {
+            this->assign_to_a(boost::mem_fn(f), functor, a);
+            return true;
+          } else {
+            return false;
+          }
+        }
+#endif // BOOST_FUNCTION_NUM_ARGS > 0
+
+        // Function objects
+        // Assign to a function object using the small object optimization
+        template<typename FunctionObj>
+        void
+        assign_functor(FunctionObj f, function_buffer& functor, mpl::true_) const
+        {
+          new (reinterpret_cast<void*>(&functor.data)) FunctionObj(f);
+        }
+        template<typename FunctionObj,typename Allocator>
+        void
+        assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_) const
+        {
+          assign_functor(f,functor,mpl::true_());
+        }
+
+        // Assign to a function object allocated on the heap.
+        template<typename FunctionObj>
+        void
+        assign_functor(FunctionObj f, function_buffer& functor, mpl::false_) const
+        {
+          functor.obj_ptr = new FunctionObj(f);
+        }
+        template<typename FunctionObj,typename Allocator>
+        void
+        assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_) const
+        {
+          typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type;
+          typedef typename Allocator::template rebind<functor_wrapper_type>::other
+            wrapper_allocator_type;
+          typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
+          wrapper_allocator_type wrapper_allocator(a);
+          wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
+          wrapper_allocator.construct(copy, functor_wrapper_type(f,a));
+          functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
+          functor.obj_ptr = new_f;
+        }
+
+        template<typename FunctionObj>
+        bool
+        assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) const
+        {
+          if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
+            assign_functor(f, functor,
+                           mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
+            return true;
+          } else {
+            return false;
+          }
+        }
+        template<typename FunctionObj,typename Allocator>
+        bool
+        assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag) const
+        {
+          if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
+            assign_functor_a(f, functor, a,
+                           mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
+            return true;
+          } else {
+            return false;
+          }
+        }
+
+        // Reference to a function object
+        template<typename FunctionObj>
+        bool
+        assign_to(const reference_wrapper<FunctionObj>& f,
+                  function_buffer& functor, function_obj_ref_tag) const
+        {
+          functor.obj_ref.obj_ptr = (void *)(f.get_pointer());
+          functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
+          functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
+          return true;
+        }
+        template<typename FunctionObj,typename Allocator>
+        bool
+        assign_to_a(const reference_wrapper<FunctionObj>& f,
+                  function_buffer& functor, Allocator, function_obj_ref_tag) const
+        {
+          return assign_to(f,functor,function_obj_ref_tag());
+        }
+
+      public:
+        vtable_base base;
+        invoker_type invoker;
+      };
+    } // end namespace function
+  } // end namespace detail
+
+  template<
+    typename R BOOST_FUNCTION_COMMA
+    BOOST_FUNCTION_TEMPLATE_PARMS
+  >
+  class BOOST_FUNCTION_FUNCTION : public function_base
+
+#if BOOST_FUNCTION_NUM_ARGS == 1
+
+    , public std::unary_function<T0,R>
+
+#elif BOOST_FUNCTION_NUM_ARGS == 2
+
+    , public std::binary_function<T0,T1,R>
+
+#endif
+
+  {
+  public:
+#ifndef BOOST_NO_VOID_RETURNS
+    typedef R         result_type;
+#else
+    typedef  typename boost::detail::function::function_return_type<R>::type
+      result_type;
+#endif // BOOST_NO_VOID_RETURNS
+
+  private:
+    typedef boost::detail::function::BOOST_FUNCTION_VTABLE<
+              R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
+      vtable_type;
+
+    vtable_type* get_vtable() const {
+      return reinterpret_cast<vtable_type*>(
+               reinterpret_cast<std::size_t>(vtable) & ~static_cast<std::size_t>(0x01));
+    }
+
+    struct clear_type {};
+
+  public:
+    BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
+
+    // add signature for boost::lambda
+    template<typename Args>
+    struct sig
+    {
+      typedef result_type type;
+    };
+
+#if BOOST_FUNCTION_NUM_ARGS == 1
+    typedef T0 argument_type;
+#elif BOOST_FUNCTION_NUM_ARGS == 2
+    typedef T0 first_argument_type;
+    typedef T1 second_argument_type;
+#endif
+
+    BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS);
+    BOOST_FUNCTION_ARG_TYPES
+
+    typedef BOOST_FUNCTION_FUNCTION self_type;
+
+    BOOST_FUNCTION_FUNCTION() : function_base() { }
+
+    // MSVC chokes if the following two constructors are collapsed into
+    // one with a default parameter.
+    template<typename Functor>
+    BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f
+#ifndef BOOST_NO_SFINAE
+                            ,typename boost::enable_if_c<
+                             !(is_integral<Functor>::value),
+                                        int>::type = 0
+#endif // BOOST_NO_SFINAE
+                            ) :
+      function_base()
+    {
+      this->assign_to(f);
+    }
+    template<typename Functor,typename Allocator>
+    BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a
+#ifndef BOOST_NO_SFINAE
+                            ,typename boost::enable_if_c<
+                              !(is_integral<Functor>::value),
+                                        int>::type = 0
+#endif // BOOST_NO_SFINAE
+                            ) :
+      function_base()
+    {
+      this->assign_to_a(f,a);
+    }
+
+#ifndef BOOST_NO_SFINAE
+    BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
+#else
+    BOOST_FUNCTION_FUNCTION(int zero) : function_base()
+    {
+      BOOST_ASSERT(zero == 0);
+    }
+#endif
+
+    BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base()
+    {
+      this->assign_to_own(f);
+    }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION&& f) : function_base()
+    {
+      this->move_assign(f);
+    }
+#endif
+
+    ~BOOST_FUNCTION_FUNCTION() { clear(); }
+
+    result_type operator()(BOOST_FUNCTION_PARMS) const
+    {
+      if (this->empty())
+        boost::throw_exception(bad_function_call());
+
+      return get_vtable()->invoker
+               (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS);
+    }
+
+    // The distinction between when to use BOOST_FUNCTION_FUNCTION and
+    // when to use self_type is obnoxious. MSVC cannot handle self_type as
+    // the return type of these assignment operators, but Borland C++ cannot
+    // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to
+    // construct.
+    template<typename Functor>
+#ifndef BOOST_NO_SFINAE
+    typename boost::enable_if_c<
+                  !(is_integral<Functor>::value),
+               BOOST_FUNCTION_FUNCTION&>::type
+#else
+    BOOST_FUNCTION_FUNCTION&
+#endif
+    operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
+    {
+      this->clear();
+      BOOST_TRY  {
+        this->assign_to(f);
+      } BOOST_CATCH (...) {
+        vtable = 0;
+        BOOST_RETHROW;
+      }
+      BOOST_CATCH_END
+      return *this;
+    }
+    template<typename Functor,typename Allocator>
+    void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a)
+    {
+      this->clear();
+      BOOST_TRY{
+        this->assign_to_a(f,a);
+      } BOOST_CATCH (...) {
+        vtable = 0;
+        BOOST_RETHROW;
+      }
+      BOOST_CATCH_END
+    }
+
+#ifndef BOOST_NO_SFINAE
+    BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
+    {
+      this->clear();
+      return *this;
+    }
+#else
+    BOOST_FUNCTION_FUNCTION& operator=(int zero)
+    {
+      BOOST_ASSERT(zero == 0);
+      this->clear();
+      return *this;
+    }
+#endif
+
+    // Assignment from another BOOST_FUNCTION_FUNCTION
+    BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
+    {
+      if (&f == this)
+        return *this;
+
+      this->clear();
+      BOOST_TRY {
+        this->assign_to_own(f);
+      } BOOST_CATCH (...) {
+        vtable = 0;
+        BOOST_RETHROW;
+      }
+      BOOST_CATCH_END
+      return *this;
+    }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    // Move assignment from another BOOST_FUNCTION_FUNCTION
+    BOOST_FUNCTION_FUNCTION& operator=(BOOST_FUNCTION_FUNCTION&& f)
+    {
+
+      if (&f == this)
+        return *this;
+
+      this->clear();
+      BOOST_TRY {
+        this->move_assign(f);
+      } BOOST_CATCH (...) {
+        vtable = 0;
+        BOOST_RETHROW;
+      }
+      BOOST_CATCH_END
+      return *this;
+    }
+#endif
+
+    void swap(BOOST_FUNCTION_FUNCTION& other)
+    {
+      if (&other == this)
+        return;
+
+      BOOST_FUNCTION_FUNCTION tmp;
+      tmp.move_assign(*this);
+      this->move_assign(other);
+      other.move_assign(tmp);
+    }
+
+    // Clear out a target, if there is one
+    void clear()
+    {
+      if (vtable) {
+        if (!this->has_trivial_copy_and_destroy())
+          get_vtable()->clear(this->functor);
+        vtable = 0;
+      }
+    }
+
+#if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG)
+    // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
+    operator bool () const { return !this->empty(); }
+#else
+  private:
+    struct dummy {
+      void nonnull() {}
+    };
+
+    typedef void (dummy::*safe_bool)();
+
+  public:
+    operator safe_bool () const
+      { return (this->empty())? 0 : &dummy::nonnull; }
+
+    bool operator!() const
+      { return this->empty(); }
+#endif
+
+  private:
+    void assign_to_own(const BOOST_FUNCTION_FUNCTION& f)
+    {
+      if (!f.empty()) {
+        this->vtable = f.vtable;
+        if (this->has_trivial_copy_and_destroy())
+          this->functor = f.functor;
+        else
+          get_vtable()->base.manager(f.functor, this->functor,
+                                     boost::detail::function::clone_functor_tag);
+      }
+    }
+
+    template<typename Functor>
+    void assign_to(Functor f)
+    {
+      using boost::detail::function::vtable_base;
+
+      typedef typename boost::detail::function::get_function_tag<Functor>::type tag;
+      typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
+      typedef typename get_invoker::
+                         template apply<Functor, R BOOST_FUNCTION_COMMA
+                        BOOST_FUNCTION_TEMPLATE_ARGS>
+        handler_type;
+
+      typedef typename handler_type::invoker_type invoker_type;
+      typedef typename handler_type::manager_type manager_type;
+
+      // Note: it is extremely important that this initialization use
+      // static initialization. Otherwise, we will have a race
+      // condition here in multi-threaded code. See
+      // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
+      static const vtable_type stored_vtable =
+        { { &manager_type::manage }, &invoker_type::invoke };
+
+      if (stored_vtable.assign_to(f, functor)) {
+        std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
+        // coverity[pointless_expression]: suppress coverity warnings on apparant if(const).
+        if (boost::has_trivial_copy_constructor<Functor>::value &&
+            boost::has_trivial_destructor<Functor>::value &&
+            boost::detail::function::function_allows_small_object_optimization<Functor>::value)
+          value |= static_cast<std::size_t>(0x01);
+        vtable = reinterpret_cast<boost::detail::function::vtable_base *>(value);
+      } else
+        vtable = 0;
+    }
+
+    template<typename Functor,typename Allocator>
+    void assign_to_a(Functor f,Allocator a)
+    {
+      using boost::detail::function::vtable_base;
+
+      typedef typename boost::detail::function::get_function_tag<Functor>::type tag;
+      typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER<tag> get_invoker;
+      typedef typename get_invoker::
+                         template apply_a<Functor, R BOOST_FUNCTION_COMMA
+                         BOOST_FUNCTION_TEMPLATE_ARGS,
+                         Allocator>
+        handler_type;
+
+      typedef typename handler_type::invoker_type invoker_type;
+      typedef typename handler_type::manager_type manager_type;
+
+      // Note: it is extremely important that this initialization use
+      // static initialization. Otherwise, we will have a race
+      // condition here in multi-threaded code. See
+      // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/.
+      static const vtable_type stored_vtable =
+        { { &manager_type::manage }, &invoker_type::invoke };
+
+      if (stored_vtable.assign_to_a(f, functor, a)) {
+        std::size_t value = reinterpret_cast<std::size_t>(&stored_vtable.base);
+        // coverity[pointless_expression]: suppress coverity warnings on apparant if(const).
+        if (boost::has_trivial_copy_constructor<Functor>::value &&
+            boost::has_trivial_destructor<Functor>::value &&
+            boost::detail::function::function_allows_small_object_optimization<Functor>::value)
+          value |= static_cast<std::size_t>(0x01);
+        vtable = reinterpret_cast<boost::detail::function::vtable_base *>(value);
+      } else
+        vtable = 0;
+    }
+
+    // Moves the value from the specified argument to *this. If the argument
+    // has its function object allocated on the heap, move_assign will pass
+    // its buffer to *this, and set the argument's buffer pointer to NULL.
+    void move_assign(BOOST_FUNCTION_FUNCTION& f)
+    {
+      if (&f == this)
+        return;
+
+      BOOST_TRY {
+        if (!f.empty()) {
+          this->vtable = f.vtable;
+          if (this->has_trivial_copy_and_destroy())
+            this->functor = f.functor;
+          else
+            get_vtable()->base.manager(f.functor, this->functor,
+                                     boost::detail::function::move_functor_tag);
+          f.vtable = 0;
+        } else {
+          clear();
+        }
+      } BOOST_CATCH (...) {
+        vtable = 0;
+        BOOST_RETHROW;
+      }
+      BOOST_CATCH_END
+    }
+  };
+
+  template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
+  inline void swap(BOOST_FUNCTION_FUNCTION<
+                     R BOOST_FUNCTION_COMMA
+                     BOOST_FUNCTION_TEMPLATE_ARGS
+                   >& f1,
+                   BOOST_FUNCTION_FUNCTION<
+                     R BOOST_FUNCTION_COMMA
+                     BOOST_FUNCTION_TEMPLATE_ARGS
+                   >& f2)
+  {
+    f1.swap(f2);
+  }
+
+// Poison comparisons between boost::function objects of the same type.
+template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
+  void operator==(const BOOST_FUNCTION_FUNCTION<
+                          R BOOST_FUNCTION_COMMA
+                          BOOST_FUNCTION_TEMPLATE_ARGS>&,
+                  const BOOST_FUNCTION_FUNCTION<
+                          R BOOST_FUNCTION_COMMA
+                          BOOST_FUNCTION_TEMPLATE_ARGS>&);
+template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
+  void operator!=(const BOOST_FUNCTION_FUNCTION<
+                          R BOOST_FUNCTION_COMMA
+                          BOOST_FUNCTION_TEMPLATE_ARGS>&,
+                  const BOOST_FUNCTION_FUNCTION<
+                          R BOOST_FUNCTION_COMMA
+                          BOOST_FUNCTION_TEMPLATE_ARGS>& );
+
+#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
+
+#if BOOST_FUNCTION_NUM_ARGS == 0
+#define BOOST_FUNCTION_PARTIAL_SPEC R (void)
+#else
+#define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS,T))
+#endif
+
+template<typename R BOOST_FUNCTION_COMMA
+         BOOST_FUNCTION_TEMPLATE_PARMS>
+class function<BOOST_FUNCTION_PARTIAL_SPEC>
+  : public BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
+{
+  typedef BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> base_type;
+  typedef function self_type;
+
+  struct clear_type {};
+
+public:
+
+  function() : base_type() {}
+
+  template<typename Functor>
+  function(Functor f
+#ifndef BOOST_NO_SFINAE
+           ,typename boost::enable_if_c<
+                          !(is_integral<Functor>::value),
+                       int>::type = 0
+#endif
+           ) :
+    base_type(f)
+  {
+  }
+  template<typename Functor,typename Allocator>
+  function(Functor f, Allocator a
+#ifndef BOOST_NO_SFINAE
+           ,typename boost::enable_if_c<
+                           !(is_integral<Functor>::value),
+                       int>::type = 0
+#endif
+           ) :
+    base_type(f,a)
+  {
+  }
+
+#ifndef BOOST_NO_SFINAE
+  function(clear_type*) : base_type() {}
+#endif
+
+  function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
+
+  function(const base_type& f) : base_type(static_cast<const base_type&>(f)){}
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+  // Move constructors
+  function(self_type&& f): base_type(static_cast<base_type&&>(f)){}
+  function(base_type&& f): base_type(static_cast<base_type&&>(f)){}
+#endif
+
+  self_type& operator=(const self_type& f)
+  {
+    self_type(f).swap(*this);
+    return *this;
+  }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+  self_type& operator=(self_type&& f)
+  {
+    self_type(static_cast<self_type&&>(f)).swap(*this);
+    return *this;
+  }
+#endif
+
+  template<typename Functor>
+#ifndef BOOST_NO_SFINAE
+  typename boost::enable_if_c<
+                         !(is_integral<Functor>::value),
+                      self_type&>::type
+#else
+  self_type&
+#endif
+  operator=(Functor f)
+  {
+    self_type(f).swap(*this);
+    return *this;
+  }
+
+#ifndef BOOST_NO_SFINAE
+  self_type& operator=(clear_type*)
+  {
+    this->clear();
+    return *this;
+  }
+#endif
+
+  self_type& operator=(const base_type& f)
+  {
+    self_type(f).swap(*this);
+    return *this;
+  }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+  self_type& operator=(base_type&& f)
+  {
+    self_type(static_cast<base_type&&>(f)).swap(*this);
+    return *this;
+  }
+#endif
+};
+
+#undef BOOST_FUNCTION_PARTIAL_SPEC
+#endif // have partial specialization
+
+} // end namespace boost
+
+// Cleanup after ourselves...
+#undef BOOST_FUNCTION_VTABLE
+#undef BOOST_FUNCTION_COMMA
+#undef BOOST_FUNCTION_FUNCTION
+#undef BOOST_FUNCTION_FUNCTION_INVOKER
+#undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
+#undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
+#undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
+#undef BOOST_FUNCTION_FUNCTION_REF_INVOKER
+#undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER
+#undef BOOST_FUNCTION_MEMBER_INVOKER
+#undef BOOST_FUNCTION_VOID_MEMBER_INVOKER
+#undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
+#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
+#undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER
+#undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
+#undef BOOST_FUNCTION_GET_INVOKER
+#undef BOOST_FUNCTION_TEMPLATE_PARMS
+#undef BOOST_FUNCTION_TEMPLATE_ARGS
+#undef BOOST_FUNCTION_PARMS
+#undef BOOST_FUNCTION_PARM
+#ifdef BOOST_FUNCTION_ARG
+#   undef BOOST_FUNCTION_ARG
+#endif
+#undef BOOST_FUNCTION_ARGS
+#undef BOOST_FUNCTION_ARG_TYPE
+#undef BOOST_FUNCTION_ARG_TYPES
+#undef BOOST_FUNCTION_VOID_RETURN_TYPE
+#undef BOOST_FUNCTION_RETURN
+
+#if defined(BOOST_MSVC)
+#   pragma warning( pop )
+#endif
diff --git a/third_party/boost/boost/function_equal.hpp b/third_party/boost/boost/function_equal.hpp
new file mode 100644
index 0000000..2d76c75
--- /dev/null
+++ b/third_party/boost/boost/function_equal.hpp
@@ -0,0 +1,28 @@
+//  Copyright Douglas Gregor 2004.
+//  Copyright 2005 Peter Dimov
+
+//  Use, modification and distribution is subject to
+//  the Boost Software License, Version 1.0.
+//  (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+#ifndef BOOST_FUNCTION_EQUAL_HPP
+#define BOOST_FUNCTION_EQUAL_HPP
+
+namespace boost {
+
+template<typename F, typename G>
+  bool function_equal_impl(const F& f, const G& g, long)
+  { return f == g; }
+
+// function_equal_impl needs to be unqualified to pick
+// user overloads on two-phase compilers
+
+template<typename F, typename G>
+  bool function_equal(const F& f, const G& g)
+  { return function_equal_impl(f, g, 0); }
+
+} // end namespace boost
+
+#endif // BOOST_FUNCTION_EQUAL_HPP
diff --git a/third_party/boost/boost/function_output_iterator.hpp b/third_party/boost/boost/function_output_iterator.hpp
new file mode 100644
index 0000000..dd8c44d
--- /dev/null
+++ b/third_party/boost/boost/function_output_iterator.hpp
@@ -0,0 +1,62 @@
+// (C) Copyright Jeremy Siek 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Revision History:
+
+// 27 Feb 2001   Jeremy Siek
+//      Initial checkin.
+
+#ifndef BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
+#define BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
+
+#include <iterator>
+
+namespace boost {
+namespace iterators {
+
+  template <class UnaryFunction>
+  class function_output_iterator {
+    typedef function_output_iterator self;
+  public:
+    typedef std::output_iterator_tag iterator_category;
+    typedef void                value_type;
+    typedef void                difference_type;
+    typedef void                pointer;
+    typedef void                reference;
+
+    explicit function_output_iterator() {}
+
+    explicit function_output_iterator(const UnaryFunction& f)
+      : m_f(f) {}
+
+    struct output_proxy {
+      output_proxy(UnaryFunction& f) : m_f(f) { }
+      template <class T> output_proxy& operator=(const T& value) {
+        m_f(value);
+        return *this;
+      }
+      UnaryFunction& m_f;
+    };
+    output_proxy operator*() { return output_proxy(m_f); }
+    self& operator++() { return *this; }
+    self& operator++(int) { return *this; }
+  private:
+    UnaryFunction m_f;
+  };
+
+  template <class UnaryFunction>
+  inline function_output_iterator<UnaryFunction>
+  make_function_output_iterator(const UnaryFunction& f = UnaryFunction()) {
+    return function_output_iterator<UnaryFunction>(f);
+  }
+
+} // namespace iterators
+
+using iterators::function_output_iterator;
+using iterators::make_function_output_iterator;
+
+} // namespace boost
+
+#endif // BOOST_FUNCTION_OUTPUT_ITERATOR_HPP
diff --git a/third_party/boost/boost/functional/hash/hash_fwd.hpp b/third_party/boost/boost/functional/hash/hash_fwd.hpp
new file mode 100644
index 0000000..333ffbf
--- /dev/null
+++ b/third_party/boost/boost/functional/hash/hash_fwd.hpp
@@ -0,0 +1,36 @@
+
+// Copyright 2005-2009 Daniel James.
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  Based on Peter Dimov's proposal
+//  http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf
+//  issue 6.18.
+
+#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP)
+#define BOOST_FUNCTIONAL_HASH_FWD_HPP
+
+#include <boost/config.hpp>
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#pragma once
+#endif
+
+#include <cstddef>
+#include <boost/detail/workaround.hpp>
+
+namespace boost
+{
+    template <class T> struct hash;
+
+    template <class T> void hash_combine(std::size_t& seed, T const& v);
+
+    template <class It> std::size_t hash_range(It, It);
+    template <class It> void hash_range(std::size_t&, It, It);
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
+    template <class T> inline std::size_t hash_range(T*, T*);
+    template <class T> inline void hash_range(std::size_t&, T*, T*);
+#endif
+}
+
+#endif
diff --git a/third_party/boost/boost/functional/hash_fwd.hpp b/third_party/boost/boost/functional/hash_fwd.hpp
new file mode 100644
index 0000000..eea9073
--- /dev/null
+++ b/third_party/boost/boost/functional/hash_fwd.hpp
@@ -0,0 +1,11 @@
+
+// Copyright 2005-2009 Daniel James.
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/config.hpp>
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#pragma once
+#endif
+
+#include <boost/functional/hash/hash_fwd.hpp>
diff --git a/third_party/boost/boost/get_pointer.hpp b/third_party/boost/boost/get_pointer.hpp
new file mode 100644
index 0000000..b2d96f5
--- /dev/null
+++ b/third_party/boost/boost/get_pointer.hpp
@@ -0,0 +1,76 @@
+// Copyright Peter Dimov and David Abrahams 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef GET_POINTER_DWA20021219_HPP
+#define GET_POINTER_DWA20021219_HPP
+
+#include <boost/config.hpp>
+
+// In order to avoid circular dependencies with Boost.TR1
+// we make sure that our include of <memory> doesn't try to
+// pull in the TR1 headers: that's why we use this header
+// rather than including <memory> directly:
+#include <boost/config/no_tr1/memory.hpp>  // std::auto_ptr
+
+namespace boost {
+
+// get_pointer(p) extracts a ->* capable pointer from p
+
+template<class T> T * get_pointer(T * p)
+{
+    return p;
+}
+
+// get_pointer(shared_ptr<T> const & p) has been moved to shared_ptr.hpp
+
+#if !defined( BOOST_NO_AUTO_PTR )
+
+#if defined( __GNUC__ ) && (defined( __GXX_EXPERIMENTAL_CXX0X__ ) || (__cplusplus >= 201103L))
+#if defined( BOOST_GCC )
+#if BOOST_GCC >= 40600
+#define BOOST_CORE_DETAIL_DISABLE_LIBSTDCXX_DEPRECATED_WARNINGS
+#endif // BOOST_GCC >= 40600
+#elif defined( __clang__ ) && defined( __has_warning )
+#if __has_warning("-Wdeprecated-declarations")
+#define BOOST_CORE_DETAIL_DISABLE_LIBSTDCXX_DEPRECATED_WARNINGS
+#endif // __has_warning("-Wdeprecated-declarations")
+#endif
+#endif // defined( __GNUC__ ) && (defined( __GXX_EXPERIMENTAL_CXX0X__ ) || (__cplusplus >= 201103L))
+
+#if defined( BOOST_CORE_DETAIL_DISABLE_LIBSTDCXX_DEPRECATED_WARNINGS )
+// Disable libstdc++ warnings about std::auto_ptr being deprecated in C++11 mode
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#define BOOST_CORE_DETAIL_DISABLED_DEPRECATED_WARNINGS
+#endif
+
+template<class T> T * get_pointer(std::auto_ptr<T> const& p)
+{
+    return p.get();
+}
+
+#if defined( BOOST_CORE_DETAIL_DISABLE_LIBSTDCXX_DEPRECATED_WARNINGS )
+#pragma GCC diagnostic pop
+#undef BOOST_CORE_DETAIL_DISABLE_LIBSTDCXX_DEPRECATED_WARNINGS
+#endif
+
+#endif // !defined( BOOST_NO_AUTO_PTR )
+
+#if !defined( BOOST_NO_CXX11_SMART_PTR )
+
+template<class T> T * get_pointer( std::unique_ptr<T> const& p )
+{
+    return p.get();
+}
+
+template<class T> T * get_pointer( std::shared_ptr<T> const& p )
+{
+    return p.get();
+}
+
+#endif
+
+} // namespace boost
+
+#endif // GET_POINTER_DWA20021219_HPP
diff --git a/third_party/boost/boost/integer.hpp b/third_party/boost/boost/integer.hpp
new file mode 100644
index 0000000..9fa0019
--- /dev/null
+++ b/third_party/boost/boost/integer.hpp
@@ -0,0 +1,262 @@
+//  boost integer.hpp header file  -------------------------------------------//
+
+//  Copyright Beman Dawes and Daryle Walker 1999.  Distributed under the Boost
+//  Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org/libs/integer for documentation.
+
+//  Revision History
+//   22 Sep 01  Added value-based integer templates. (Daryle Walker)
+//   01 Apr 01  Modified to use new <boost/limits.hpp> header. (John Maddock)
+//   30 Jul 00  Add typename syntax fix (Jens Maurer)
+//   28 Aug 99  Initial version
+
+#ifndef BOOST_INTEGER_HPP
+#define BOOST_INTEGER_HPP
+
+#include <boost/integer_fwd.hpp>  // self include
+
+#include <boost/integer_traits.hpp>  // for boost::::boost::integer_traits
+#include <boost/limits.hpp>          // for ::std::numeric_limits
+#include <boost/cstdint.hpp>         // for boost::int64_t and BOOST_NO_INTEGRAL_INT64_T
+#include <boost/static_assert.hpp>
+
+//
+// We simply cannot include this header on gcc without getting copious warnings of the kind:
+//
+// boost/integer.hpp:77:30: warning: use of C99 long long integer constant
+//
+// And yet there is no other reasonable implementation, so we declare this a system header
+// to suppress these warnings.
+//
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+#pragma GCC system_header
+#endif
+
+namespace boost
+{
+
+  //  Helper templates  ------------------------------------------------------//
+
+  //  fast integers from least integers
+  //  int_fast_t<> works correctly for unsigned too, in spite of the name.
+  template< typename LeastInt >
+  struct int_fast_t
+  {
+     typedef LeastInt fast;
+     typedef fast     type;
+  }; // imps may specialize
+
+  namespace detail{
+
+  //  convert category to type
+  template< int Category > struct int_least_helper {}; // default is empty
+  template< int Category > struct uint_least_helper {}; // default is empty
+
+  //  specializatons: 1=long, 2=int, 3=short, 4=signed char,
+  //     6=unsigned long, 7=unsigned int, 8=unsigned short, 9=unsigned char
+  //  no specializations for 0 and 5: requests for a type > long are in error
+#ifdef BOOST_HAS_LONG_LONG
+  template<> struct int_least_helper<1> { typedef boost::long_long_type least; };
+#elif defined(BOOST_HAS_MS_INT64)
+  template<> struct int_least_helper<1> { typedef __int64 least; };
+#endif
+  template<> struct int_least_helper<2> { typedef long least; };
+  template<> struct int_least_helper<3> { typedef int least; };
+  template<> struct int_least_helper<4> { typedef short least; };
+  template<> struct int_least_helper<5> { typedef signed char least; };
+#ifdef BOOST_HAS_LONG_LONG
+  template<> struct uint_least_helper<1> { typedef boost::ulong_long_type least; };
+#elif defined(BOOST_HAS_MS_INT64)
+  template<> struct uint_least_helper<1> { typedef unsigned __int64 least; };
+#endif
+  template<> struct uint_least_helper<2> { typedef unsigned long least; };
+  template<> struct uint_least_helper<3> { typedef unsigned int least; };
+  template<> struct uint_least_helper<4> { typedef unsigned short least; };
+  template<> struct uint_least_helper<5> { typedef unsigned char least; };
+
+  template <int Bits>
+  struct exact_signed_base_helper{};
+  template <int Bits>
+  struct exact_unsigned_base_helper{};
+
+  template <> struct exact_signed_base_helper<sizeof(signed char)* CHAR_BIT> { typedef signed char exact; };
+  template <> struct exact_unsigned_base_helper<sizeof(unsigned char)* CHAR_BIT> { typedef unsigned char exact; };
+#if USHRT_MAX != UCHAR_MAX
+  template <> struct exact_signed_base_helper<sizeof(short)* CHAR_BIT> { typedef short exact; };
+  template <> struct exact_unsigned_base_helper<sizeof(unsigned short)* CHAR_BIT> { typedef unsigned short exact; };
+#endif
+#if UINT_MAX != USHRT_MAX
+  template <> struct exact_signed_base_helper<sizeof(int)* CHAR_BIT> { typedef int exact; };
+  template <> struct exact_unsigned_base_helper<sizeof(unsigned int)* CHAR_BIT> { typedef unsigned int exact; };
+#endif
+#if ULONG_MAX != UINT_MAX && ( !defined __TI_COMPILER_VERSION__ || \
+    ( __TI_COMPILER_VERSION__ >= 7000000 && !defined __TI_40BIT_LONG__ ) )
+  template <> struct exact_signed_base_helper<sizeof(long)* CHAR_BIT> { typedef long exact; };
+  template <> struct exact_unsigned_base_helper<sizeof(unsigned long)* CHAR_BIT> { typedef unsigned long exact; };
+#endif
+#if defined(BOOST_HAS_LONG_LONG) &&\
+   ((defined(ULLONG_MAX) && (ULLONG_MAX != ULONG_MAX)) ||\
+    (defined(ULONG_LONG_MAX) && (ULONG_LONG_MAX != ULONG_MAX)) ||\
+    (defined(ULONGLONG_MAX) && (ULONGLONG_MAX != ULONG_MAX)) ||\
+    (defined(_ULLONG_MAX) && (_ULLONG_MAX != ULONG_MAX)))
+  template <> struct exact_signed_base_helper<sizeof(boost::long_long_type)* CHAR_BIT> { typedef boost::long_long_type exact; };
+  template <> struct exact_unsigned_base_helper<sizeof(boost::ulong_long_type)* CHAR_BIT> { typedef boost::ulong_long_type exact; };
+#endif
+
+
+  } // namespace detail
+
+  //  integer templates specifying number of bits  ---------------------------//
+
+  //  signed
+  template< int Bits >   // bits (including sign) required
+  struct int_t : public boost::detail::exact_signed_base_helper<Bits>
+  {
+      BOOST_STATIC_ASSERT_MSG(Bits <= (int)(sizeof(boost::intmax_t) * CHAR_BIT),
+         "No suitable signed integer type with the requested number of bits is available.");
+      typedef typename boost::detail::int_least_helper
+        <
+#ifdef BOOST_HAS_LONG_LONG
+          (Bits <= (int)(sizeof(boost::long_long_type) * CHAR_BIT)) +
+#else
+           1 +
+#endif
+          (Bits-1 <= ::std::numeric_limits<long>::digits) +
+          (Bits-1 <= ::std::numeric_limits<int>::digits) +
+          (Bits-1 <= ::std::numeric_limits<short>::digits) +
+          (Bits-1 <= ::std::numeric_limits<signed char>::digits)
+        >::least  least;
+      typedef typename int_fast_t<least>::type  fast;
+  };
+
+  //  unsigned
+  template< int Bits >   // bits required
+  struct uint_t : public boost::detail::exact_unsigned_base_helper<Bits>
+  {
+     BOOST_STATIC_ASSERT_MSG(Bits <= (int)(sizeof(boost::uintmax_t) * CHAR_BIT),
+         "No suitable unsigned integer type with the requested number of bits is available.");
+#if (defined(__BORLANDC__) || defined(__CODEGEAR__)) && defined(BOOST_NO_INTEGRAL_INT64_T)
+     // It's really not clear why this workaround should be needed... shrug I guess!  JM
+     BOOST_STATIC_CONSTANT(int, s =
+           6 +
+          (Bits <= ::std::numeric_limits<unsigned long>::digits) +
+          (Bits <= ::std::numeric_limits<unsigned int>::digits) +
+          (Bits <= ::std::numeric_limits<unsigned short>::digits) +
+          (Bits <= ::std::numeric_limits<unsigned char>::digits));
+     typedef typename detail::int_least_helper< ::boost::uint_t<Bits>::s>::least least;
+#else
+      typedef typename boost::detail::uint_least_helper
+        <
+#ifdef BOOST_HAS_LONG_LONG
+          (Bits <= (int)(sizeof(boost::long_long_type) * CHAR_BIT)) +
+#else
+           1 +
+#endif
+          (Bits <= ::std::numeric_limits<unsigned long>::digits) +
+          (Bits <= ::std::numeric_limits<unsigned int>::digits) +
+          (Bits <= ::std::numeric_limits<unsigned short>::digits) +
+          (Bits <= ::std::numeric_limits<unsigned char>::digits)
+        >::least  least;
+#endif
+      typedef typename int_fast_t<least>::type  fast;
+      // int_fast_t<> works correctly for unsigned too, in spite of the name.
+  };
+
+  //  integer templates specifying extreme value  ----------------------------//
+
+  //  signed
+#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG)
+  template< boost::long_long_type MaxValue >   // maximum value to require support
+#else
+  template< long MaxValue >   // maximum value to require support
+#endif
+  struct int_max_value_t
+  {
+      typedef typename boost::detail::int_least_helper
+        <
+#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG)
+          (MaxValue <= ::boost::integer_traits<boost::long_long_type>::const_max) +
+#else
+           1 +
+#endif
+          (MaxValue <= ::boost::integer_traits<long>::const_max) +
+          (MaxValue <= ::boost::integer_traits<int>::const_max) +
+          (MaxValue <= ::boost::integer_traits<short>::const_max) +
+          (MaxValue <= ::boost::integer_traits<signed char>::const_max)
+        >::least  least;
+      typedef typename int_fast_t<least>::type  fast;
+  };
+
+#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG)
+  template< boost::long_long_type MinValue >   // minimum value to require support
+#else
+  template< long MinValue >   // minimum value to require support
+#endif
+  struct int_min_value_t
+  {
+      typedef typename boost::detail::int_least_helper
+        <
+#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG)
+          (MinValue >= ::boost::integer_traits<boost::long_long_type>::const_min) +
+#else
+           1 +
+#endif
+          (MinValue >= ::boost::integer_traits<long>::const_min) +
+          (MinValue >= ::boost::integer_traits<int>::const_min) +
+          (MinValue >= ::boost::integer_traits<short>::const_min) +
+          (MinValue >= ::boost::integer_traits<signed char>::const_min)
+        >::least  least;
+      typedef typename int_fast_t<least>::type  fast;
+  };
+
+  //  unsigned
+#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG)
+  template< boost::ulong_long_type MaxValue >   // minimum value to require support
+#else
+  template< unsigned long MaxValue >   // minimum value to require support
+#endif
+  struct uint_value_t
+  {
+#if (defined(__BORLANDC__) || defined(__CODEGEAR__))
+     // It's really not clear why this workaround should be needed... shrug I guess!  JM
+#if defined(BOOST_NO_INTEGRAL_INT64_T)
+      BOOST_STATIC_CONSTANT(unsigned, which =
+           1 +
+          (MaxValue <= ::boost::integer_traits<unsigned long>::const_max) +
+          (MaxValue <= ::boost::integer_traits<unsigned int>::const_max) +
+          (MaxValue <= ::boost::integer_traits<unsigned short>::const_max) +
+          (MaxValue <= ::boost::integer_traits<unsigned char>::const_max));
+      typedef typename detail::int_least_helper< ::boost::uint_value_t<MaxValue>::which>::least least;
+#else // BOOST_NO_INTEGRAL_INT64_T
+      BOOST_STATIC_CONSTANT(unsigned, which =
+           1 +
+          (MaxValue <= ::boost::integer_traits<boost::ulong_long_type>::const_max) +
+          (MaxValue <= ::boost::integer_traits<unsigned long>::const_max) +
+          (MaxValue <= ::boost::integer_traits<unsigned int>::const_max) +
+          (MaxValue <= ::boost::integer_traits<unsigned short>::const_max) +
+          (MaxValue <= ::boost::integer_traits<unsigned char>::const_max));
+      typedef typename detail::uint_least_helper< ::boost::uint_value_t<MaxValue>::which>::least least;
+#endif // BOOST_NO_INTEGRAL_INT64_T
+#else
+      typedef typename boost::detail::uint_least_helper
+        <
+#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG)
+          (MaxValue <= ::boost::integer_traits<boost::ulong_long_type>::const_max) +
+#else
+           1 +
+#endif
+          (MaxValue <= ::boost::integer_traits<unsigned long>::const_max) +
+          (MaxValue <= ::boost::integer_traits<unsigned int>::const_max) +
+          (MaxValue <= ::boost::integer_traits<unsigned short>::const_max) +
+          (MaxValue <= ::boost::integer_traits<unsigned char>::const_max)
+        >::least  least;
+#endif
+      typedef typename int_fast_t<least>::type  fast;
+  };
+
+
+} // namespace boost
+
+#endif  // BOOST_INTEGER_HPP
diff --git a/third_party/boost/boost/integer_fwd.hpp b/third_party/boost/boost/integer_fwd.hpp
new file mode 100644
index 0000000..10577ae
--- /dev/null
+++ b/third_party/boost/boost/integer_fwd.hpp
@@ -0,0 +1,187 @@
+//  Boost integer_fwd.hpp header file  ---------------------------------------//
+
+//  (C) Copyright Dave Abrahams and Daryle Walker 2001. Distributed under the Boost
+//  Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org/libs/integer for documentation.
+
+#ifndef BOOST_INTEGER_FWD_HPP
+#define BOOST_INTEGER_FWD_HPP
+
+#include <climits>  // for UCHAR_MAX, etc.
+#include <cstddef>  // for std::size_t
+
+#include <boost/config.hpp>  // for BOOST_NO_INTRINSIC_WCHAR_T
+#include <boost/limits.hpp>  // for std::numeric_limits
+#include <boost/cstdint.hpp>  // For intmax_t
+
+
+namespace boost
+{
+
+#ifdef BOOST_NO_INTEGRAL_INT64_T
+     typedef unsigned long static_log2_argument_type;
+     typedef          int  static_log2_result_type;
+     typedef long          static_min_max_signed_type;
+     typedef unsigned long static_min_max_unsigned_type;
+#else
+     typedef boost::uintmax_t static_min_max_unsigned_type;
+     typedef boost::intmax_t  static_min_max_signed_type;
+     typedef boost::uintmax_t static_log2_argument_type;
+     typedef int              static_log2_result_type;
+#endif
+
+//  From <boost/cstdint.hpp>  ------------------------------------------------//
+
+// Only has typedefs or using statements, with #conditionals
+
+
+//  From <boost/integer_traits.hpp>  -----------------------------------------//
+
+template < class T >
+    class integer_traits;
+
+template <  >
+    class integer_traits< bool >;
+
+template <  >
+    class integer_traits< char >;
+
+template <  >
+    class integer_traits< signed char >;
+
+template <  >
+    class integer_traits< unsigned char >;
+
+#ifndef BOOST_NO_INTRINSIC_WCHAR_T
+template <  >
+    class integer_traits< wchar_t >;
+#endif
+
+template <  >
+    class integer_traits< short >;
+
+template <  >
+    class integer_traits< unsigned short >;
+
+template <  >
+    class integer_traits< int >;
+
+template <  >
+    class integer_traits< unsigned int >;
+
+template <  >
+    class integer_traits< long >;
+
+template <  >
+    class integer_traits< unsigned long >;
+
+#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG)
+template <  >
+class integer_traits<  ::boost::long_long_type>;
+
+template <  >
+class integer_traits<  ::boost::ulong_long_type >;
+#elif !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_MS_INT64)
+template <  >
+class integer_traits<__int64>;
+
+template <  >
+class integer_traits<unsigned __int64>;
+#endif
+
+
+//  From <boost/integer.hpp>  ------------------------------------------------//
+
+template < typename LeastInt >
+    struct int_fast_t;
+
+template< int Bits >
+    struct int_t;
+
+template< int Bits >
+    struct uint_t;
+
+#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG)
+    template< boost::long_long_type MaxValue >   // maximum value to require support
+#else
+  template< long MaxValue >   // maximum value to require support
+#endif
+    struct int_max_value_t;
+
+#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG)
+  template< boost::long_long_type MinValue >   // minimum value to require support
+#else
+  template< long MinValue >   // minimum value to require support
+#endif
+    struct int_min_value_t;
+
+#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG)
+  template< boost::ulong_long_type MaxValue >   // maximum value to require support
+#else
+  template< unsigned long MaxValue >   // maximum value to require support
+#endif
+    struct uint_value_t;
+
+
+//  From <boost/integer/integer_mask.hpp>  -----------------------------------//
+
+template < std::size_t Bit >
+    struct high_bit_mask_t;
+
+template < std::size_t Bits >
+    struct low_bits_mask_t;
+
+template <  >
+    struct low_bits_mask_t< ::std::numeric_limits<unsigned char>::digits >;
+
+//  From <boost/integer/static_log2.hpp>  ------------------------------------//
+
+template <static_log2_argument_type Value >
+    struct static_log2;
+
+template <> struct static_log2<0u>;
+
+
+//  From <boost/integer/static_min_max.hpp>  ---------------------------------//
+
+template <static_min_max_signed_type Value1, static_min_max_signed_type Value2>
+    struct static_signed_min;
+
+template <static_min_max_signed_type Value1, static_min_max_signed_type Value2>
+    struct static_signed_max;
+
+template <static_min_max_unsigned_type Value1, static_min_max_unsigned_type Value2>
+    struct static_unsigned_min;
+
+template <static_min_max_unsigned_type Value1, static_min_max_unsigned_type Value2>
+    struct static_unsigned_max;
+
+
+//  From <boost/integer/common_factor_ct.hpp>
+
+#ifdef BOOST_NO_INTEGRAL_INT64_T
+     typedef unsigned long static_gcd_type;
+#else
+     typedef boost::uintmax_t static_gcd_type;
+#endif
+
+template < static_gcd_type Value1, static_gcd_type Value2 >
+    struct static_gcd;
+template < static_gcd_type Value1, static_gcd_type Value2 >
+    struct static_lcm;
+
+
+//  From <boost/integer/common_factor_rt.hpp>
+
+template < typename IntegerType >
+    class gcd_evaluator;
+template < typename IntegerType >
+    class lcm_evaluator;
+
+
+}  // namespace boost
+
+
+#endif  // BOOST_INTEGER_FWD_HPP
diff --git a/third_party/boost/boost/integer_traits.hpp b/third_party/boost/boost/integer_traits.hpp
new file mode 100644
index 0000000..26a8b4e
--- /dev/null
+++ b/third_party/boost/boost/integer_traits.hpp
@@ -0,0 +1,253 @@
+/* boost integer_traits.hpp header file
+ *
+ * Copyright Jens Maurer 2000
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * $Id$
+ *
+ * Idea by Beman Dawes, Ed Brey, Steve Cleary, and Nathan Myers
+ */
+
+//  See http://www.boost.org/libs/integer for documentation.
+
+
+#ifndef BOOST_INTEGER_TRAITS_HPP
+#define BOOST_INTEGER_TRAITS_HPP
+
+#include <boost/config.hpp>
+#include <boost/limits.hpp>
+
+// These are an implementation detail and not part of the interface
+#include <limits.h>
+// we need wchar.h for WCHAR_MAX/MIN but not all platforms provide it,
+// and some may have <wchar.h> but not <cwchar> ...
+#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) && (!defined(BOOST_NO_CWCHAR) || defined(sun) || defined(__sun) || defined(__QNX__))
+#include <wchar.h>
+#endif
+
+//
+// We simply cannot include this header on gcc without getting copious warnings of the kind:
+//
+// ../../../boost/integer_traits.hpp:164:66: warning: use of C99 long long integer constant
+//
+// And yet there is no other reasonable implementation, so we declare this a system header
+// to suppress these warnings.
+//
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+#pragma GCC system_header
+#endif
+
+namespace boost {
+template<class T>
+class integer_traits : public std::numeric_limits<T>
+{
+public:
+  BOOST_STATIC_CONSTANT(bool, is_integral = false);
+};
+
+namespace detail {
+template<class T, T min_val, T max_val>
+class integer_traits_base
+{
+public:
+  BOOST_STATIC_CONSTANT(bool, is_integral = true);
+  BOOST_STATIC_CONSTANT(T, const_min = min_val);
+  BOOST_STATIC_CONSTANT(T, const_max = max_val);
+};
+
+#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
+//  A definition is required even for integral static constants
+template<class T, T min_val, T max_val>
+const bool integer_traits_base<T, min_val, max_val>::is_integral;
+
+template<class T, T min_val, T max_val>
+const T integer_traits_base<T, min_val, max_val>::const_min;
+
+template<class T, T min_val, T max_val>
+const T integer_traits_base<T, min_val, max_val>::const_max;
+#endif
+
+} // namespace detail
+
+template<>
+class integer_traits<bool>
+  : public std::numeric_limits<bool>,
+    public detail::integer_traits_base<bool, false, true>
+{ };
+
+template<>
+class integer_traits<char>
+  : public std::numeric_limits<char>,
+    public detail::integer_traits_base<char, CHAR_MIN, CHAR_MAX>
+{ };
+
+template<>
+class integer_traits<signed char>
+  : public std::numeric_limits<signed char>,
+    public detail::integer_traits_base<signed char, SCHAR_MIN, SCHAR_MAX>
+{ };
+
+template<>
+class integer_traits<unsigned char>
+  : public std::numeric_limits<unsigned char>,
+    public detail::integer_traits_base<unsigned char, 0, UCHAR_MAX>
+{ };
+
+#ifndef BOOST_NO_INTRINSIC_WCHAR_T
+template<>
+class integer_traits<wchar_t>
+  : public std::numeric_limits<wchar_t>,
+    // Don't trust WCHAR_MIN and WCHAR_MAX with Mac OS X's native
+    // library: they are wrong!
+#if defined(WCHAR_MIN) && defined(WCHAR_MAX) && !defined(__APPLE__)
+    public detail::integer_traits_base<wchar_t, WCHAR_MIN, WCHAR_MAX>
+#elif defined(__BORLANDC__) || defined(__CYGWIN__) || defined(__MINGW32__) || (defined(__BEOS__) && defined(__GNUC__))
+    // No WCHAR_MIN and WCHAR_MAX, whar_t is short and unsigned:
+    public detail::integer_traits_base<wchar_t, 0, 0xffff>
+#elif (defined(__sgi) && (!defined(__SGI_STL_PORT) || __SGI_STL_PORT < 0x400))\
+    || (defined __APPLE__)\
+    || (defined(__OpenBSD__) && defined(__GNUC__))\
+    || (defined(__NetBSD__) && defined(__GNUC__))\
+    || (defined(__FreeBSD__) && defined(__GNUC__))\
+    || (defined(__DragonFly__) && defined(__GNUC__))\
+    || (defined(__hpux) && defined(__GNUC__) && (__GNUC__ == 3) && !defined(__SGI_STL_PORT))
+    // No WCHAR_MIN and WCHAR_MAX, wchar_t has the same range as int.
+    //  - SGI MIPSpro with native library
+    //  - gcc 3.x on HP-UX
+    //  - Mac OS X with native library
+    //  - gcc on FreeBSD, OpenBSD and NetBSD
+    public detail::integer_traits_base<wchar_t, INT_MIN, INT_MAX>
+#else
+#error No WCHAR_MIN and WCHAR_MAX present, please adjust integer_traits<> for your compiler.
+#endif
+{ };
+#endif // BOOST_NO_INTRINSIC_WCHAR_T
+
+template<>
+class integer_traits<short>
+  : public std::numeric_limits<short>,
+    public detail::integer_traits_base<short, SHRT_MIN, SHRT_MAX>
+{ };
+
+template<>
+class integer_traits<unsigned short>
+  : public std::numeric_limits<unsigned short>,
+    public detail::integer_traits_base<unsigned short, 0, USHRT_MAX>
+{ };
+
+template<>
+class integer_traits<int>
+  : public std::numeric_limits<int>,
+    public detail::integer_traits_base<int, INT_MIN, INT_MAX>
+{ };
+
+template<>
+class integer_traits<unsigned int>
+  : public std::numeric_limits<unsigned int>,
+    public detail::integer_traits_base<unsigned int, 0, UINT_MAX>
+{ };
+
+template<>
+class integer_traits<long>
+  : public std::numeric_limits<long>,
+    public detail::integer_traits_base<long, LONG_MIN, LONG_MAX>
+{ };
+
+template<>
+class integer_traits<unsigned long>
+  : public std::numeric_limits<unsigned long>,
+    public detail::integer_traits_base<unsigned long, 0, ULONG_MAX>
+{ };
+
+#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T)
+#if defined(ULLONG_MAX) && defined(BOOST_HAS_LONG_LONG)
+
+template<>
+class integer_traits< ::boost::long_long_type>
+  : public std::numeric_limits< ::boost::long_long_type>,
+    public detail::integer_traits_base< ::boost::long_long_type, LLONG_MIN, LLONG_MAX>
+{ };
+
+template<>
+class integer_traits< ::boost::ulong_long_type>
+  : public std::numeric_limits< ::boost::ulong_long_type>,
+    public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULLONG_MAX>
+{ };
+
+#elif defined(ULONG_LONG_MAX) && defined(BOOST_HAS_LONG_LONG)
+
+template<>
+class integer_traits< ::boost::long_long_type>  : public std::numeric_limits< ::boost::long_long_type>,    public detail::integer_traits_base< ::boost::long_long_type, LONG_LONG_MIN, LONG_LONG_MAX>{ };
+template<>
+class integer_traits< ::boost::ulong_long_type>
+  : public std::numeric_limits< ::boost::ulong_long_type>,
+    public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULONG_LONG_MAX>
+{ };
+
+#elif defined(ULONGLONG_MAX) && defined(BOOST_HAS_LONG_LONG)
+
+template<>
+class integer_traits< ::boost::long_long_type>
+  : public std::numeric_limits< ::boost::long_long_type>,
+    public detail::integer_traits_base< ::boost::long_long_type, LONGLONG_MIN, LONGLONG_MAX>
+{ };
+
+template<>
+class integer_traits< ::boost::ulong_long_type>
+  : public std::numeric_limits< ::boost::ulong_long_type>,
+    public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULONGLONG_MAX>
+{ };
+
+#elif defined(_LLONG_MAX) && defined(_C2) && defined(BOOST_HAS_LONG_LONG)
+
+template<>
+class integer_traits< ::boost::long_long_type>
+  : public std::numeric_limits< ::boost::long_long_type>,
+    public detail::integer_traits_base< ::boost::long_long_type, -_LLONG_MAX - _C2, _LLONG_MAX>
+{ };
+
+template<>
+class integer_traits< ::boost::ulong_long_type>
+  : public std::numeric_limits< ::boost::ulong_long_type>,
+    public detail::integer_traits_base< ::boost::ulong_long_type, 0, _ULLONG_MAX>
+{ };
+
+#elif defined(BOOST_HAS_LONG_LONG)
+//
+// we have long long but no constants, this happens for example with gcc in -ansi mode,
+// we'll just have to work out the values for ourselves (assumes 2's compliment representation):
+//
+template<>
+class integer_traits< ::boost::long_long_type>
+  : public std::numeric_limits< ::boost::long_long_type>,
+    public detail::integer_traits_base< ::boost::long_long_type, (1LL << (sizeof(::boost::long_long_type) * CHAR_BIT - 1)), ~(1LL << (sizeof(::boost::long_long_type) * CHAR_BIT - 1))>
+{ };
+
+template<>
+class integer_traits< ::boost::ulong_long_type>
+  : public std::numeric_limits< ::boost::ulong_long_type>,
+    public detail::integer_traits_base< ::boost::ulong_long_type, 0, ~0uLL>
+{ };
+
+#elif defined(BOOST_HAS_MS_INT64)
+
+template<>
+class integer_traits< __int64>
+  : public std::numeric_limits< __int64>,
+    public detail::integer_traits_base< __int64, _I64_MIN, _I64_MAX>
+{ };
+
+template<>
+class integer_traits< unsigned __int64>
+  : public std::numeric_limits< unsigned __int64>,
+    public detail::integer_traits_base< unsigned __int64, 0, _UI64_MAX>
+{ };
+
+#endif
+#endif
+
+} // namespace boost
+
+#endif /* BOOST_INTEGER_TRAITS_HPP */
diff --git a/third_party/boost/boost/is_placeholder.hpp b/third_party/boost/boost/is_placeholder.hpp
new file mode 100644
index 0000000..5f1b544
--- /dev/null
+++ b/third_party/boost/boost/is_placeholder.hpp
@@ -0,0 +1,31 @@
+#ifndef BOOST_IS_PLACEHOLDER_HPP_INCLUDED
+#define BOOST_IS_PLACEHOLDER_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined( _MSC_VER ) && ( _MSC_VER >= 1020 )
+# pragma once
+#endif
+
+
+//  is_placeholder.hpp - TR1 is_placeholder metafunction
+//
+//  Copyright (c) 2006 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+
+
+namespace boost
+{
+
+template< class T > struct is_placeholder
+{
+    enum _vt { value = 0 };
+};
+
+} // namespace boost
+
+#endif // #ifndef BOOST_IS_PLACEHOLDER_HPP_INCLUDED
diff --git a/third_party/boost/boost/iterator.hpp b/third_party/boost/boost/iterator.hpp
new file mode 100644
index 0000000..c9c6197
--- /dev/null
+++ b/third_party/boost/boost/iterator.hpp
@@ -0,0 +1,20 @@
+//  (C) Copyright Beman Dawes 2000. Distributed under the Boost
+//  Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_ITERATOR_HPP
+#define BOOST_ITERATOR_HPP
+
+// This header is obsolete and will be deprecated.
+
+#include <iterator>
+#include <cstddef>           // std::ptrdiff_t
+
+namespace boost
+{
+
+using std::iterator;
+
+} // namespace boost
+
+#endif // BOOST_ITERATOR_HPP
diff --git a/third_party/boost/boost/iterator/detail/config_def.hpp b/third_party/boost/boost/iterator/detail/config_def.hpp
new file mode 100644
index 0000000..bf37fbb
--- /dev/null
+++ b/third_party/boost/boost/iterator/detail/config_def.hpp
@@ -0,0 +1,128 @@
+// (C) Copyright David Abrahams 2002.
+// (C) Copyright Jeremy Siek    2002.
+// (C) Copyright Thomas Witt    2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// no include guard multiple inclusion intended
+
+//
+// This is a temporary workaround until the bulk of this is
+// available in boost config.
+// 23/02/03 thw
+//
+
+#include <boost/config.hpp> // for prior
+#include <boost/detail/workaround.hpp>
+
+#ifdef BOOST_ITERATOR_CONFIG_DEF
+# error you have nested config_def #inclusion.
+#else
+# define BOOST_ITERATOR_CONFIG_DEF
+#endif
+
+// We enable this always now.  Otherwise, the simple case in
+// libs/iterator/test/constant_iterator_arrow.cpp fails to compile
+// because the operator-> return is improperly deduced as a non-const
+// pointer.
+#if 1 || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)           \
+    || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x531))
+
+// Recall that in general, compilers without partial specialization
+// can't strip constness.  Consider counting_iterator, which normally
+// passes a const Value to iterator_facade.  As a result, any code
+// which makes a std::vector of the iterator's value_type will fail
+// when its allocator declares functions overloaded on reference and
+// const_reference (the same type).
+//
+// Furthermore, Borland 5.5.1 drops constness in enough ways that we
+// end up using a proxy for operator[] when we otherwise shouldn't.
+// Using reference constness gives it an extra hint that it can
+// return the value_type from operator[] directly, but is not
+// strictly necessary.  Not sure how best to resolve this one.
+
+# define BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY 1
+
+#endif
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x5A0))                      \
+    || (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) && defined(_MSC_VER)) \
+    || BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))                \
+    || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
+
+# define BOOST_NO_LVALUE_RETURN_DETECTION
+
+# if 0 // test code
+  struct v  {};
+
+  typedef  char (&no)[3];
+
+  template <class T>
+  no foo(T const&, ...);
+
+  template <class T>
+  char foo(T&, int);
+
+
+  struct value_iterator
+  {
+      v operator*() const;
+  };
+
+  template <class T>
+  struct lvalue_deref_helper
+  {
+      static T& x;
+      enum { value = (sizeof(foo(*x,0)) == 1) };
+  };
+
+  int z2[(lvalue_deref_helper<v*>::value == 1) ? 1 : -1];
+  int z[(lvalue_deref_helper<value_iterator>::value) == 1 ? -1 : 1 ];
+# endif
+
+#endif
+
+#if BOOST_WORKAROUND(__MWERKS__, <=0x2407)
+#  define BOOST_NO_IS_CONVERTIBLE // "is_convertible doesn't work for simple types"
+#endif
+
+#if BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4) && !defined(__EDG_VERSION__)   \
+    || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
+#  define BOOST_NO_IS_CONVERTIBLE_TEMPLATE // The following program fails to compile:
+
+#  if 0 // test code
+    #include <boost/type_traits/is_convertible.hpp>
+    template <class T>
+    struct foo
+    {
+        foo(T);
+
+        template <class U>
+        foo(foo<U> const& other) : p(other.p) { }
+
+        T p;
+    };
+
+    bool x = boost::is_convertible<foo<int const*>, foo<int*> >::value;
+#  endif
+
+#endif
+
+
+#if !defined(BOOST_MSVC) && (defined(BOOST_NO_SFINAE) || defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_IS_CONVERTIBLE_TEMPLATE))
+# define BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
+#endif
+
+# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+
+// GCC-2.95 (obsolete) eagerly instantiates templated constructors and conversion
+// operators in convertibility checks, causing premature errors.
+//
+// Borland's problems are harder to diagnose due to lack of an
+// instantiation stack backtrace.  They may be due in part to the fact
+// that it drops cv-qualification willy-nilly in templates.
+#  define BOOST_NO_ONE_WAY_ITERATOR_INTEROP
+# endif
+
+// no include guard; multiple inclusion intended
diff --git a/third_party/boost/boost/iterator/detail/config_undef.hpp b/third_party/boost/boost/iterator/detail/config_undef.hpp
new file mode 100644
index 0000000..a32529c
--- /dev/null
+++ b/third_party/boost/boost/iterator/detail/config_undef.hpp
@@ -0,0 +1,24 @@
+// (C) Copyright Thomas Witt    2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// no include guard multiple inclusion intended
+
+//
+// This is a temporary workaround until the bulk of this is
+// available in boost config.
+// 23/02/03 thw
+//
+
+#undef BOOST_NO_IS_CONVERTIBLE
+#undef BOOST_NO_IS_CONVERTIBLE_TEMPLATE
+#undef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
+#undef BOOST_NO_LVALUE_RETURN_DETECTION
+#undef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
+
+#ifdef BOOST_ITERATOR_CONFIG_DEF
+# undef BOOST_ITERATOR_CONFIG_DEF
+#else
+# error missing or nested #include config_def
+#endif
diff --git a/third_party/boost/boost/iterator/detail/enable_if.hpp b/third_party/boost/boost/iterator/detail/enable_if.hpp
new file mode 100644
index 0000000..071f5fe
--- /dev/null
+++ b/third_party/boost/boost/iterator/detail/enable_if.hpp
@@ -0,0 +1,83 @@
+// (C) Copyright David Abrahams 2002.
+// (C) Copyright Jeremy Siek    2002.
+// (C) Copyright Thomas Witt    2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_ENABLE_IF_23022003THW_HPP
+#define BOOST_ENABLE_IF_23022003THW_HPP
+
+#include <boost/detail/workaround.hpp>
+#include <boost/mpl/identity.hpp>
+
+#include <boost/iterator/detail/config_def.hpp>
+
+//
+// Boost iterators uses its own enable_if cause we need
+// special semantics for deficient compilers.
+// 23/02/03 thw
+//
+
+namespace boost
+{
+
+  namespace iterators
+  {
+    //
+    // Base machinery for all kinds of enable if
+    //
+    template<bool>
+    struct enabled
+    {
+      template<typename T>
+      struct base
+      {
+        typedef T type;
+      };
+    };
+
+    //
+    // For compilers that don't support "Substitution Failure Is Not An Error"
+    // enable_if falls back to always enabled. See comments
+    // on operator implementation for consequences.
+    //
+    template<>
+    struct enabled<false>
+    {
+      template<typename T>
+      struct base
+      {
+#ifdef BOOST_NO_SFINAE
+
+        typedef T type;
+
+        // This way to do it would give a nice error message containing
+        // invalid overload, but has the big disadvantage that
+        // there is no reference to user code in the error message.
+        //
+        // struct invalid_overload;
+        // typedef invalid_overload type;
+        //
+#endif
+      };
+    };
+
+
+    template <class Cond,
+              class Return>
+    struct enable_if
+# if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_IS_CONVERTIBLE)
+      : enabled<(Cond::value)>::template base<Return>
+# else
+      : mpl::identity<Return>
+# endif
+    {
+    };
+
+  } // namespace iterators
+
+} // namespace boost
+
+#include <boost/iterator/detail/config_undef.hpp>
+
+#endif // BOOST_ENABLE_IF_23022003THW_HPP
diff --git a/third_party/boost/boost/iterator/detail/facade_iterator_category.hpp b/third_party/boost/boost/iterator/detail/facade_iterator_category.hpp
new file mode 100644
index 0000000..67fdf44
--- /dev/null
+++ b/third_party/boost/boost/iterator/detail/facade_iterator_category.hpp
@@ -0,0 +1,193 @@
+// Copyright David Abrahams 2003. Use, modification and distribution is
+// subject to the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+#ifndef FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
+# define FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
+
+# include <boost/iterator/iterator_categories.hpp>
+
+# include <boost/mpl/or.hpp>  // used in iterator_tag inheritance logic
+# include <boost/mpl/and.hpp>
+# include <boost/mpl/if.hpp>
+# include <boost/mpl/eval_if.hpp>
+# include <boost/mpl/identity.hpp>
+# include <boost/mpl/assert.hpp>
+
+# include <boost/type_traits/is_same.hpp>
+# include <boost/type_traits/is_const.hpp>
+# include <boost/type_traits/is_reference.hpp>
+# include <boost/type_traits/is_convertible.hpp>
+
+# include <boost/type_traits/is_same.hpp>
+
+# include <boost/iterator/detail/config_def.hpp> // try to keep this last
+
+# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
+#  include <boost/detail/indirect_traits.hpp>
+# endif
+
+//
+// iterator_category deduction for iterator_facade
+//
+
+namespace boost {
+namespace iterators {
+
+// forward declaration
+struct use_default;
+
+namespace detail {
+
+struct input_output_iterator_tag
+  : std::input_iterator_tag
+{
+    // Using inheritance for only input_iterator_tag helps to avoid
+    // ambiguities when a stdlib implementation dispatches on a
+    // function which is overloaded on both input_iterator_tag and
+    // output_iterator_tag, as STLPort does, in its __valid_range
+    // function.  I claim it's better to avoid the ambiguity in these
+    // cases.
+    operator std::output_iterator_tag() const
+    {
+        return std::output_iterator_tag();
+    }
+};
+
+//
+// True iff the user has explicitly disabled writability of this
+// iterator.  Pass the iterator_facade's Value parameter and its
+// nested ::reference type.
+//
+template <class ValueParam, class Reference>
+struct iterator_writability_disabled
+# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY // Adding Thomas' logic?
+  : mpl::or_<
+        is_const<Reference>
+      , boost::detail::indirect_traits::is_reference_to_const<Reference>
+      , is_const<ValueParam>
+    >
+# else
+  : is_const<ValueParam>
+# endif
+{};
+
+
+//
+// Convert an iterator_facade's traversal category, Value parameter,
+// and ::reference type to an appropriate old-style category.
+//
+// Due to changeset 21683, this now never results in a category convertible
+// to output_iterator_tag.
+//
+// Change at: https://svn.boost.org/trac/boost/changeset/21683
+template <class Traversal, class ValueParam, class Reference>
+struct iterator_facade_default_category
+  : mpl::eval_if<
+        mpl::and_<
+            is_reference<Reference>
+          , is_convertible<Traversal,forward_traversal_tag>
+        >
+      , mpl::eval_if<
+            is_convertible<Traversal,random_access_traversal_tag>
+          , mpl::identity<std::random_access_iterator_tag>
+          , mpl::if_<
+                is_convertible<Traversal,bidirectional_traversal_tag>
+              , std::bidirectional_iterator_tag
+              , std::forward_iterator_tag
+            >
+        >
+      , typename mpl::eval_if<
+            mpl::and_<
+                is_convertible<Traversal, single_pass_traversal_tag>
+
+                // check for readability
+              , is_convertible<Reference, ValueParam>
+            >
+          , mpl::identity<std::input_iterator_tag>
+          , mpl::identity<Traversal>
+        >
+    >
+{
+};
+
+// True iff T is convertible to an old-style iterator category.
+template <class T>
+struct is_iterator_category
+  : mpl::or_<
+        is_convertible<T,std::input_iterator_tag>
+      , is_convertible<T,std::output_iterator_tag>
+    >
+{
+};
+
+template <class T>
+struct is_iterator_traversal
+  : is_convertible<T,incrementable_traversal_tag>
+{};
+
+//
+// A composite iterator_category tag convertible to Category (a pure
+// old-style category) and Traversal (a pure traversal tag).
+// Traversal must be a strict increase of the traversal power given by
+// Category.
+//
+template <class Category, class Traversal>
+struct iterator_category_with_traversal
+  : Category, Traversal
+{
+    // Make sure this isn't used to build any categories where
+    // convertibility to Traversal is redundant.  Should just use the
+    // Category element in that case.
+    BOOST_MPL_ASSERT_NOT((
+        is_convertible<
+              typename iterator_category_to_traversal<Category>::type
+            , Traversal
+          >));
+
+    BOOST_MPL_ASSERT((is_iterator_category<Category>));
+    BOOST_MPL_ASSERT_NOT((is_iterator_category<Traversal>));
+    BOOST_MPL_ASSERT_NOT((is_iterator_traversal<Category>));
+#  if !BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1310))
+    BOOST_MPL_ASSERT((is_iterator_traversal<Traversal>));
+#  endif
+};
+
+// Computes an iterator_category tag whose traversal is Traversal and
+// which is appropriate for an iterator
+template <class Traversal, class ValueParam, class Reference>
+struct facade_iterator_category_impl
+{
+    BOOST_MPL_ASSERT_NOT((is_iterator_category<Traversal>));
+
+    typedef typename iterator_facade_default_category<
+        Traversal,ValueParam,Reference
+    >::type category;
+
+    typedef typename mpl::if_<
+        is_same<
+            Traversal
+          , typename iterator_category_to_traversal<category>::type
+        >
+      , category
+      , iterator_category_with_traversal<category,Traversal>
+    >::type type;
+};
+
+//
+// Compute an iterator_category for iterator_facade
+//
+template <class CategoryOrTraversal, class ValueParam, class Reference>
+struct facade_iterator_category
+  : mpl::eval_if<
+        is_iterator_category<CategoryOrTraversal>
+      , mpl::identity<CategoryOrTraversal> // old-style categories are fine as-is
+      , facade_iterator_category_impl<CategoryOrTraversal,ValueParam,Reference>
+    >
+{
+};
+
+}}} // namespace boost::iterators::detail
+
+# include <boost/iterator/detail/config_undef.hpp>
+
+#endif // FACADE_ITERATOR_CATEGORY_DWA20031118_HPP
diff --git a/third_party/boost/boost/iterator/interoperable.hpp b/third_party/boost/boost/iterator/interoperable.hpp
new file mode 100644
index 0000000..6f3c872
--- /dev/null
+++ b/third_party/boost/boost/iterator/interoperable.hpp
@@ -0,0 +1,54 @@
+// (C) Copyright David Abrahams 2002.
+// (C) Copyright Jeremy Siek    2002.
+// (C) Copyright Thomas Witt    2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_INTEROPERABLE_23022003THW_HPP
+# define BOOST_INTEROPERABLE_23022003THW_HPP
+
+# include <boost/mpl/bool.hpp>
+# include <boost/mpl/or.hpp>
+
+# include <boost/type_traits/is_convertible.hpp>
+
+# include <boost/iterator/detail/config_def.hpp> // must appear last
+
+namespace boost {
+namespace iterators {
+
+  //
+  // Meta function that determines whether two
+  // iterator types are considered interoperable.
+  //
+  // Two iterator types A,B are considered interoperable if either
+  // A is convertible to B or vice versa.
+  // This interoperability definition is in sync with the
+  // standards requirements on constant/mutable container
+  // iterators (23.1 [lib.container.requirements]).
+  //
+  // For compilers that don't support is_convertible
+  // is_interoperable gives false positives. See comments
+  // on operator implementation for consequences.
+  //
+  template <typename A, typename B>
+  struct is_interoperable
+# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
+    : mpl::true_
+# else
+    : mpl::or_<
+          is_convertible< A, B >
+        , is_convertible< B, A > >
+# endif
+  {
+  };
+
+} // namespace iterators
+
+using iterators::is_interoperable;
+
+} // namespace boost
+
+# include <boost/iterator/detail/config_undef.hpp>
+
+#endif // BOOST_INTEROPERABLE_23022003THW_HPP
diff --git a/third_party/boost/boost/iterator/iterator_adaptor.hpp b/third_party/boost/boost/iterator/iterator_adaptor.hpp
new file mode 100644
index 0000000..87cfd05
--- /dev/null
+++ b/third_party/boost/boost/iterator/iterator_adaptor.hpp
@@ -0,0 +1,360 @@
+// (C) Copyright David Abrahams 2002.
+// (C) Copyright Jeremy Siek    2002.
+// (C) Copyright Thomas Witt    2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
+#define BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
+
+#include <boost/static_assert.hpp>
+#include <boost/iterator.hpp>
+#include <boost/detail/iterator.hpp>
+
+#include <boost/iterator/iterator_categories.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/iterator/detail/enable_if.hpp>
+
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/or.hpp>
+
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+
+#ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
+# include <boost/type_traits/remove_reference.hpp>
+#endif
+
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/iterator/detail/config_def.hpp>
+
+#include <boost/iterator/iterator_traits.hpp>
+
+namespace boost {
+namespace iterators {
+
+  // Used as a default template argument internally, merely to
+  // indicate "use the default", this can also be passed by users
+  // explicitly in order to specify that the default should be used.
+  struct use_default;
+
+} // namespace iterators
+
+using iterators::use_default;
+
+// the incompleteness of use_default causes massive problems for
+// is_convertible (naturally).  This workaround is fortunately not
+// needed for vc6/vc7.
+template<class To>
+struct is_convertible<use_default,To>
+  : mpl::false_ {};
+
+namespace iterators {
+
+  namespace detail
+  {
+
+    //
+    // Result type used in enable_if_convertible meta function.
+    // This can be an incomplete type, as only pointers to
+    // enable_if_convertible< ... >::type are used.
+    // We could have used void for this, but conversion to
+    // void* is just to easy.
+    //
+    struct enable_type;
+  }
+
+
+  //
+  // enable_if for use in adapted iterators constructors.
+  //
+  // In order to provide interoperability between adapted constant and
+  // mutable iterators, adapted iterators will usually provide templated
+  // conversion constructors of the following form
+  //
+  // template <class BaseIterator>
+  // class adapted_iterator :
+  //   public iterator_adaptor< adapted_iterator<Iterator>, Iterator >
+  // {
+  // public:
+  //
+  //   ...
+  //
+  //   template <class OtherIterator>
+  //   adapted_iterator(
+  //       OtherIterator const& it
+  //     , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0);
+  //
+  //   ...
+  // };
+  //
+  // enable_if_convertible is used to remove those overloads from the overload
+  // set that cannot be instantiated. For all practical purposes only overloads
+  // for constant/mutable interaction will remain. This has the advantage that
+  // meta functions like boost::is_convertible do not return false positives,
+  // as they can only look at the signature of the conversion constructor
+  // and not at the actual instantiation.
+  //
+  // enable_if_interoperable can be safely used in user code. It falls back to
+  // always enabled for compilers that don't support enable_if or is_convertible.
+  // There is no need for compiler specific workarounds in user code.
+  //
+  // The operators implementation relies on boost::is_convertible not returning
+  // false positives for user/library defined iterator types. See comments
+  // on operator implementation for consequences.
+  //
+#  if defined(BOOST_NO_IS_CONVERTIBLE) || defined(BOOST_NO_SFINAE)
+
+  template <class From, class To>
+  struct enable_if_convertible
+  {
+      typedef boost::iterators::detail::enable_type type;
+  };
+
+#  elif BOOST_WORKAROUND(_MSC_FULL_VER, BOOST_TESTED_AT(13102292))
+
+  // For some reason vc7.1 needs us to "cut off" instantiation
+  // of is_convertible in a few cases.
+  template<typename From, typename To>
+  struct enable_if_convertible
+    : iterators::enable_if<
+        mpl::or_<
+            is_same<From,To>
+          , is_convertible<From, To>
+        >
+      , boost::iterators::detail::enable_type
+    >
+  {};
+
+#  else
+
+  template<typename From, typename To>
+  struct enable_if_convertible
+    : iterators::enable_if<
+          is_convertible<From, To>
+        , boost::iterators::detail::enable_type
+      >
+  {};
+
+# endif
+
+  //
+  // Default template argument handling for iterator_adaptor
+  //
+  namespace detail
+  {
+    // If T is use_default, return the result of invoking
+    // DefaultNullaryFn, otherwise return T.
+    template <class T, class DefaultNullaryFn>
+    struct ia_dflt_help
+      : mpl::eval_if<
+            is_same<T, use_default>
+          , DefaultNullaryFn
+          , mpl::identity<T>
+        >
+    {
+    };
+
+    // A metafunction which computes an iterator_adaptor's base class,
+    // a specialization of iterator_facade.
+    template <
+        class Derived
+      , class Base
+      , class Value
+      , class Traversal
+      , class Reference
+      , class Difference
+    >
+    struct iterator_adaptor_base
+    {
+        typedef iterator_facade<
+            Derived
+
+# ifdef BOOST_ITERATOR_REF_CONSTNESS_KILLS_WRITABILITY
+          , typename boost::iterators::detail::ia_dflt_help<
+                Value
+              , mpl::eval_if<
+                    is_same<Reference,use_default>
+                  , iterator_value<Base>
+                  , remove_reference<Reference>
+                >
+            >::type
+# else
+          , typename boost::iterators::detail::ia_dflt_help<
+                Value, iterator_value<Base>
+            >::type
+# endif
+
+          , typename boost::iterators::detail::ia_dflt_help<
+                Traversal
+              , iterator_traversal<Base>
+            >::type
+
+          , typename boost::iterators::detail::ia_dflt_help<
+                Reference
+              , mpl::eval_if<
+                    is_same<Value,use_default>
+                  , iterator_reference<Base>
+                  , add_reference<Value>
+                >
+            >::type
+
+          , typename boost::iterators::detail::ia_dflt_help<
+                Difference, iterator_difference<Base>
+            >::type
+        >
+        type;
+    };
+
+    // workaround for aC++ CR JAGaf33512
+    template <class Tr1, class Tr2>
+    inline void iterator_adaptor_assert_traversal ()
+    {
+      BOOST_STATIC_ASSERT((is_convertible<Tr1, Tr2>::value));
+    }
+  }
+
+  //
+  // Iterator Adaptor
+  //
+  // The parameter ordering changed slightly with respect to former
+  // versions of iterator_adaptor The idea is that when the user needs
+  // to fiddle with the reference type it is highly likely that the
+  // iterator category has to be adjusted as well.  Any of the
+  // following four template arguments may be ommitted or explicitly
+  // replaced by use_default.
+  //
+  //   Value - if supplied, the value_type of the resulting iterator, unless
+  //      const. If const, a conforming compiler strips constness for the
+  //      value_type. If not supplied, iterator_traits<Base>::value_type is used
+  //
+  //   Category - the traversal category of the resulting iterator. If not
+  //      supplied, iterator_traversal<Base>::type is used.
+  //
+  //   Reference - the reference type of the resulting iterator, and in
+  //      particular, the result type of operator*(). If not supplied but
+  //      Value is supplied, Value& is used. Otherwise
+  //      iterator_traits<Base>::reference is used.
+  //
+  //   Difference - the difference_type of the resulting iterator. If not
+  //      supplied, iterator_traits<Base>::difference_type is used.
+  //
+  template <
+      class Derived
+    , class Base
+    , class Value        = use_default
+    , class Traversal    = use_default
+    , class Reference    = use_default
+    , class Difference   = use_default
+  >
+  class iterator_adaptor
+    : public boost::iterators::detail::iterator_adaptor_base<
+        Derived, Base, Value, Traversal, Reference, Difference
+      >::type
+  {
+      friend class iterator_core_access;
+
+   protected:
+      typedef typename boost::iterators::detail::iterator_adaptor_base<
+          Derived, Base, Value, Traversal, Reference, Difference
+      >::type super_t;
+   public:
+      iterator_adaptor() {}
+
+      explicit iterator_adaptor(Base const &iter)
+          : m_iterator(iter)
+      {
+      }
+
+      typedef Base base_type;
+
+      Base const& base() const
+        { return m_iterator; }
+
+   protected:
+      // for convenience in derived classes
+      typedef iterator_adaptor<Derived,Base,Value,Traversal,Reference,Difference> iterator_adaptor_;
+
+      //
+      // lvalue access to the Base object for Derived
+      //
+      Base const& base_reference() const
+        { return m_iterator; }
+
+      Base& base_reference()
+        { return m_iterator; }
+
+   private:
+      //
+      // Core iterator interface for iterator_facade.  This is private
+      // to prevent temptation for Derived classes to use it, which
+      // will often result in an error.  Derived classes should use
+      // base_reference(), above, to get direct access to m_iterator.
+      //
+      typename super_t::reference dereference() const
+        { return *m_iterator; }
+
+      template <
+      class OtherDerived, class OtherIterator, class V, class C, class R, class D
+      >
+      bool equal(iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& x) const
+      {
+        // Maybe readd with same_distance
+        //           BOOST_STATIC_ASSERT(
+        //               (detail::same_category_and_difference<Derived,OtherDerived>::value)
+        //               );
+          return m_iterator == x.base();
+      }
+
+      typedef typename iterator_category_to_traversal<
+          typename super_t::iterator_category
+      >::type my_traversal;
+
+# define BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(cat) \
+      boost::iterators::detail::iterator_adaptor_assert_traversal<my_traversal, cat>();
+
+      void advance(typename super_t::difference_type n)
+      {
+          BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
+          m_iterator += n;
+      }
+
+      void increment() { ++m_iterator; }
+
+      void decrement()
+      {
+          BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(bidirectional_traversal_tag)
+           --m_iterator;
+      }
+
+      template <
+          class OtherDerived, class OtherIterator, class V, class C, class R, class D
+      >
+      typename super_t::difference_type distance_to(
+          iterator_adaptor<OtherDerived, OtherIterator, V, C, R, D> const& y) const
+      {
+          BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL(random_access_traversal_tag)
+          // Maybe readd with same_distance
+          //           BOOST_STATIC_ASSERT(
+          //               (detail::same_category_and_difference<Derived,OtherDerived>::value)
+          //               );
+          return y.base() - m_iterator;
+      }
+
+# undef BOOST_ITERATOR_ADAPTOR_ASSERT_TRAVERSAL
+
+   private: // data members
+      Base m_iterator;
+  };
+
+} // namespace iterators
+
+using iterators::iterator_adaptor;
+using iterators::enable_if_convertible;
+
+} // namespace boost
+
+#include <boost/iterator/detail/config_undef.hpp>
+
+#endif // BOOST_ITERATOR_ADAPTOR_23022003THW_HPP
diff --git a/third_party/boost/boost/iterator/iterator_categories.hpp b/third_party/boost/boost/iterator/iterator_categories.hpp
new file mode 100644
index 0000000..71202c9
--- /dev/null
+++ b/third_party/boost/boost/iterator/iterator_categories.hpp
@@ -0,0 +1,215 @@
+// (C) Copyright Jeremy Siek 2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_ITERATOR_CATEGORIES_HPP
+# define BOOST_ITERATOR_CATEGORIES_HPP
+
+# include <boost/config.hpp>
+# include <boost/detail/iterator.hpp>
+# include <boost/iterator/detail/config_def.hpp>
+
+# include <boost/detail/workaround.hpp>
+
+# include <boost/mpl/eval_if.hpp>
+# include <boost/mpl/identity.hpp>
+# include <boost/mpl/placeholders.hpp>
+# include <boost/mpl/aux_/lambda_support.hpp>
+
+# include <boost/type_traits/is_convertible.hpp>
+
+# include <boost/static_assert.hpp>
+
+namespace boost {
+namespace iterators {
+
+//
+// Traversal Categories
+//
+
+struct no_traversal_tag {};
+
+struct incrementable_traversal_tag
+  : no_traversal_tag
+{
+//     incrementable_traversal_tag() {}
+//     incrementable_traversal_tag(std::output_iterator_tag const&) {};
+};
+
+struct single_pass_traversal_tag
+  : incrementable_traversal_tag
+{
+//     single_pass_traversal_tag() {}
+//     single_pass_traversal_tag(std::input_iterator_tag const&) {};
+};
+
+struct forward_traversal_tag
+  : single_pass_traversal_tag
+{
+//     forward_traversal_tag() {}
+//     forward_traversal_tag(std::forward_iterator_tag const&) {};
+};
+
+struct bidirectional_traversal_tag
+  : forward_traversal_tag
+{
+//     bidirectional_traversal_tag() {};
+//     bidirectional_traversal_tag(std::bidirectional_iterator_tag const&) {};
+};
+
+struct random_access_traversal_tag
+  : bidirectional_traversal_tag
+{
+//     random_access_traversal_tag() {};
+//     random_access_traversal_tag(std::random_access_iterator_tag const&) {};
+};
+
+namespace detail
+{
+  //
+  // Convert a "strictly old-style" iterator category to a traversal
+  // tag.  This is broken out into a separate metafunction to reduce
+  // the cost of instantiating iterator_category_to_traversal, below,
+  // for new-style types.
+  //
+  template <class Cat>
+  struct old_category_to_traversal
+    : mpl::eval_if<
+          is_convertible<Cat,std::random_access_iterator_tag>
+        , mpl::identity<random_access_traversal_tag>
+        , mpl::eval_if<
+              is_convertible<Cat,std::bidirectional_iterator_tag>
+            , mpl::identity<bidirectional_traversal_tag>
+            , mpl::eval_if<
+                  is_convertible<Cat,std::forward_iterator_tag>
+                , mpl::identity<forward_traversal_tag>
+                , mpl::eval_if<
+                      is_convertible<Cat,std::input_iterator_tag>
+                    , mpl::identity<single_pass_traversal_tag>
+                    , mpl::eval_if<
+                          is_convertible<Cat,std::output_iterator_tag>
+                        , mpl::identity<incrementable_traversal_tag>
+                        , void
+                      >
+                  >
+              >
+          >
+      >
+  {};
+
+} // namespace detail
+
+//
+// Convert an iterator category into a traversal tag
+//
+template <class Cat>
+struct iterator_category_to_traversal
+  : mpl::eval_if< // if already convertible to a traversal tag, we're done.
+        is_convertible<Cat,incrementable_traversal_tag>
+      , mpl::identity<Cat>
+      , boost::iterators::detail::old_category_to_traversal<Cat>
+    >
+{};
+
+// Trait to get an iterator's traversal category
+template <class Iterator = mpl::_1>
+struct iterator_traversal
+  : iterator_category_to_traversal<
+        typename boost::detail::iterator_traits<Iterator>::iterator_category
+    >
+{};
+
+# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
+// Hack because BOOST_MPL_AUX_LAMBDA_SUPPORT doesn't seem to work
+// out well.  Instantiating the nested apply template also
+// requires instantiating iterator_traits on the
+// placeholder. Instead we just specialize it as a metafunction
+// class.
+template <>
+struct iterator_traversal<mpl::_1>
+{
+    template <class T>
+    struct apply : iterator_traversal<T>
+    {};
+};
+template <>
+struct iterator_traversal<mpl::_>
+  : iterator_traversal<mpl::_1>
+{};
+# endif
+
+//
+// Convert an iterator traversal to one of the traversal tags.
+//
+template <class Traversal>
+struct pure_traversal_tag
+  : mpl::eval_if<
+        is_convertible<Traversal,random_access_traversal_tag>
+      , mpl::identity<random_access_traversal_tag>
+      , mpl::eval_if<
+            is_convertible<Traversal,bidirectional_traversal_tag>
+          , mpl::identity<bidirectional_traversal_tag>
+          , mpl::eval_if<
+                is_convertible<Traversal,forward_traversal_tag>
+              , mpl::identity<forward_traversal_tag>
+              , mpl::eval_if<
+                    is_convertible<Traversal,single_pass_traversal_tag>
+                  , mpl::identity<single_pass_traversal_tag>
+                  , mpl::eval_if<
+                        is_convertible<Traversal,incrementable_traversal_tag>
+                      , mpl::identity<incrementable_traversal_tag>
+                      , void
+                    >
+                >
+            >
+        >
+    >
+{
+};
+
+//
+// Trait to retrieve one of the iterator traversal tags from the iterator category or traversal.
+//
+template <class Iterator = mpl::_1>
+struct pure_iterator_traversal
+  : pure_traversal_tag<typename iterator_traversal<Iterator>::type>
+{};
+
+# ifdef BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
+template <>
+struct pure_iterator_traversal<mpl::_1>
+{
+    template <class T>
+    struct apply : pure_iterator_traversal<T>
+    {};
+};
+template <>
+struct pure_iterator_traversal<mpl::_>
+  : pure_iterator_traversal<mpl::_1>
+{};
+# endif
+
+} // namespace iterators
+
+using iterators::no_traversal_tag;
+using iterators::incrementable_traversal_tag;
+using iterators::single_pass_traversal_tag;
+using iterators::forward_traversal_tag;
+using iterators::bidirectional_traversal_tag;
+using iterators::random_access_traversal_tag;
+using iterators::iterator_category_to_traversal;
+using iterators::iterator_traversal;
+
+// This import is needed for backward compatibility with Boost.Range:
+// boost/range/detail/demote_iterator_traversal_tag.hpp
+// It should be removed when that header is fixed.
+namespace detail {
+using iterators::pure_traversal_tag;
+} // namespace detail
+
+} // namespace boost
+
+#include <boost/iterator/detail/config_undef.hpp>
+
+#endif // BOOST_ITERATOR_CATEGORIES_HPP
diff --git a/third_party/boost/boost/iterator/iterator_facade.hpp b/third_party/boost/boost/iterator/iterator_facade.hpp
new file mode 100644
index 0000000..7b11d0a
--- /dev/null
+++ b/third_party/boost/boost/iterator/iterator_facade.hpp
@@ -0,0 +1,980 @@
+// (C) Copyright David Abrahams 2002.
+// (C) Copyright Jeremy Siek    2002.
+// (C) Copyright Thomas Witt    2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_ITERATOR_FACADE_23022003THW_HPP
+#define BOOST_ITERATOR_FACADE_23022003THW_HPP
+
+#include <boost/config.hpp>
+#include <boost/iterator.hpp>
+#include <boost/iterator/interoperable.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+
+#include <boost/iterator/detail/facade_iterator_category.hpp>
+#include <boost/iterator/detail/enable_if.hpp>
+
+#include <boost/static_assert.hpp>
+#include <boost/utility/addressof.hpp>
+
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_pointer.hpp>
+#include <boost/type_traits/add_lvalue_reference.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/is_pod.hpp>
+
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/always.hpp>
+#include <boost/mpl/apply.hpp>
+#include <boost/mpl/identity.hpp>
+
+#include <boost/iterator/detail/config_def.hpp> // this goes last
+
+namespace boost {
+namespace iterators {
+
+  // This forward declaration is required for the friend declaration
+  // in iterator_core_access
+  template <class I, class V, class TC, class R, class D> class iterator_facade;
+
+  namespace detail
+  {
+    // A binary metafunction class that always returns bool.  VC6
+    // ICEs on mpl::always<bool>, probably because of the default
+    // parameters.
+    struct always_bool2
+    {
+        template <class T, class U>
+        struct apply
+        {
+            typedef bool type;
+        };
+    };
+
+    // The type trait checks if the category or traversal is at least as advanced as the specified required traversal
+    template< typename CategoryOrTraversal, typename Required >
+    struct is_traversal_at_least :
+        public boost::is_convertible< typename iterator_category_to_traversal< CategoryOrTraversal >::type, Required >
+    {};
+
+    //
+    // enable if for use in operator implementation.
+    //
+    template <
+        class Facade1
+      , class Facade2
+      , class Return
+    >
+    struct enable_if_interoperable :
+        public boost::iterators::enable_if<
+            is_interoperable< Facade1, Facade2 >
+          , Return
+        >
+    {};
+
+    //
+    // enable if for use in implementation of operators specific for random access traversal.
+    //
+    template <
+        class Facade1
+      , class Facade2
+      , class Return
+    >
+    struct enable_if_interoperable_and_random_access_traversal :
+        public boost::iterators::enable_if<
+            mpl::and_<
+                is_interoperable< Facade1, Facade2 >
+              , is_traversal_at_least< typename iterator_category< Facade1 >::type, random_access_traversal_tag >
+              , is_traversal_at_least< typename iterator_category< Facade2 >::type, random_access_traversal_tag >
+            >
+          , Return
+        >
+    {};
+
+    //
+    // Generates associated types for an iterator_facade with the
+    // given parameters.
+    //
+    template <
+        class ValueParam
+      , class CategoryOrTraversal
+      , class Reference
+      , class Difference
+    >
+    struct iterator_facade_types
+    {
+        typedef typename facade_iterator_category<
+            CategoryOrTraversal, ValueParam, Reference
+        >::type iterator_category;
+
+        typedef typename remove_const<ValueParam>::type value_type;
+
+        // Not the real associated pointer type
+        typedef typename mpl::eval_if<
+            boost::iterators::detail::iterator_writability_disabled<ValueParam,Reference>
+          , add_pointer<const value_type>
+          , add_pointer<value_type>
+        >::type pointer;
+
+# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)                          \
+    && (BOOST_WORKAROUND(_STLPORT_VERSION, BOOST_TESTED_AT(0x452))              \
+        || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, BOOST_TESTED_AT(310)))     \
+    || BOOST_WORKAROUND(BOOST_RWSTD_VER, BOOST_TESTED_AT(0x20101))              \
+    || BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, <= 310)
+
+        // To interoperate with some broken library/compiler
+        // combinations, user-defined iterators must be derived from
+        // std::iterator.  It is possible to implement a standard
+        // library for broken compilers without this limitation.
+#  define BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE 1
+
+        typedef
+           iterator<iterator_category, value_type, Difference, pointer, Reference>
+        base;
+# endif
+    };
+
+    // iterators whose dereference operators reference the same value
+    // for all iterators into the same sequence (like many input
+    // iterators) need help with their postfix ++: the referenced
+    // value must be read and stored away before the increment occurs
+    // so that *a++ yields the originally referenced element and not
+    // the next one.
+    template <class Iterator>
+    class postfix_increment_proxy
+    {
+        typedef typename iterator_value<Iterator>::type value_type;
+     public:
+        explicit postfix_increment_proxy(Iterator const& x)
+          : stored_value(*x)
+        {}
+
+        // Returning a mutable reference allows nonsense like
+        // (*r++).mutate(), but it imposes fewer assumptions about the
+        // behavior of the value_type.  In particular, recall that
+        // (*r).mutate() is legal if operator* returns by value.
+        value_type&
+        operator*() const
+        {
+            return this->stored_value;
+        }
+     private:
+        mutable value_type stored_value;
+    };
+
+    //
+    // In general, we can't determine that such an iterator isn't
+    // writable -- we also need to store a copy of the old iterator so
+    // that it can be written into.
+    template <class Iterator>
+    class writable_postfix_increment_proxy
+    {
+        typedef typename iterator_value<Iterator>::type value_type;
+     public:
+        explicit writable_postfix_increment_proxy(Iterator const& x)
+          : stored_value(*x)
+          , stored_iterator(x)
+        {}
+
+        // Dereferencing must return a proxy so that both *r++ = o and
+        // value_type(*r++) can work.  In this case, *r is the same as
+        // *r++, and the conversion operator below is used to ensure
+        // readability.
+        writable_postfix_increment_proxy const&
+        operator*() const
+        {
+            return *this;
+        }
+
+        // Provides readability of *r++
+        operator value_type&() const
+        {
+            return stored_value;
+        }
+
+        // Provides writability of *r++
+        template <class T>
+        T const& operator=(T const& x) const
+        {
+            *this->stored_iterator = x;
+            return x;
+        }
+
+        // This overload just in case only non-const objects are writable
+        template <class T>
+        T& operator=(T& x) const
+        {
+            *this->stored_iterator = x;
+            return x;
+        }
+
+        // Provides X(r++)
+        operator Iterator const&() const
+        {
+            return stored_iterator;
+        }
+
+     private:
+        mutable value_type stored_value;
+        Iterator stored_iterator;
+    };
+
+# ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+    template <class Reference, class Value>
+    struct is_non_proxy_reference_impl
+    {
+        static Reference r;
+
+        template <class R>
+        static typename mpl::if_<
+            is_convertible<
+                R const volatile*
+              , Value const volatile*
+            >
+          , char[1]
+          , char[2]
+        >::type& helper(R const&);
+
+        BOOST_STATIC_CONSTANT(bool, value = sizeof(helper(r)) == 1);
+    };
+
+    template <class Reference, class Value>
+    struct is_non_proxy_reference
+      : mpl::bool_<
+            is_non_proxy_reference_impl<Reference, Value>::value
+        >
+    {};
+# else
+    template <class Reference, class Value>
+    struct is_non_proxy_reference
+      : is_convertible<
+            typename remove_reference<Reference>::type
+            const volatile*
+          , Value const volatile*
+        >
+    {};
+# endif
+
+    // A metafunction to choose the result type of postfix ++
+    //
+    // Because the C++98 input iterator requirements say that *r++ has
+    // type T (value_type), implementations of some standard
+    // algorithms like lexicographical_compare may use constructions
+    // like:
+    //
+    //          *r++ < *s++
+    //
+    // If *r++ returns a proxy (as required if r is writable but not
+    // multipass), this sort of expression will fail unless the proxy
+    // supports the operator<.  Since there are any number of such
+    // operations, we're not going to try to support them.  Therefore,
+    // even if r++ returns a proxy, *r++ will only return a proxy if
+    // *r also returns a proxy.
+    template <class Iterator, class Value, class Reference, class CategoryOrTraversal>
+    struct postfix_increment_result
+      : mpl::eval_if<
+            mpl::and_<
+                // A proxy is only needed for readable iterators
+                is_convertible<
+                    Reference
+                    // Use add_lvalue_reference to form `reference to Value` due to
+                    // some (strict) C++03 compilers (e.g. `gcc -std=c++03`) reject
+                    // 'reference-to-reference' in the template which described in CWG
+                    // DR106.
+                    // http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_defects.html#106
+                  , typename add_lvalue_reference<Value const>::type
+                >
+
+                // No multipass iterator can have values that disappear
+                // before positions can be re-visited
+              , mpl::not_<
+                    is_convertible<
+                        typename iterator_category_to_traversal<CategoryOrTraversal>::type
+                      , forward_traversal_tag
+                    >
+                >
+            >
+          , mpl::if_<
+                is_non_proxy_reference<Reference,Value>
+              , postfix_increment_proxy<Iterator>
+              , writable_postfix_increment_proxy<Iterator>
+            >
+          , mpl::identity<Iterator>
+        >
+    {};
+
+    // operator->() needs special support for input iterators to strictly meet the
+    // standard's requirements. If *i is not a reference type, we must still
+    // produce an lvalue to which a pointer can be formed.  We do that by
+    // returning a proxy object containing an instance of the reference object.
+    template <class Reference, class Pointer>
+    struct operator_arrow_dispatch // proxy references
+    {
+        struct proxy
+        {
+            explicit proxy(Reference const & x) : m_ref(x) {}
+            Reference* operator->() { return boost::addressof(m_ref); }
+            // This function is needed for MWCW and BCC, which won't call
+            // operator-> again automatically per 13.3.1.2 para 8
+            operator Reference*() { return boost::addressof(m_ref); }
+            Reference m_ref;
+        };
+        typedef proxy result_type;
+        static result_type apply(Reference const & x)
+        {
+            return result_type(x);
+        }
+    };
+
+    template <class T, class Pointer>
+    struct operator_arrow_dispatch<T&, Pointer> // "real" references
+    {
+        typedef Pointer result_type;
+        static result_type apply(T& x)
+        {
+            return boost::addressof(x);
+        }
+    };
+
+    // A proxy return type for operator[], needed to deal with
+    // iterators that may invalidate referents upon destruction.
+    // Consider the temporary iterator in *(a + n)
+    template <class Iterator>
+    class operator_brackets_proxy
+    {
+        // Iterator is actually an iterator_facade, so we do not have to
+        // go through iterator_traits to access the traits.
+        typedef typename Iterator::reference  reference;
+        typedef typename Iterator::value_type value_type;
+
+     public:
+        operator_brackets_proxy(Iterator const& iter)
+          : m_iter(iter)
+        {}
+
+        operator reference() const
+        {
+            return *m_iter;
+        }
+
+        operator_brackets_proxy& operator=(value_type const& val)
+        {
+            *m_iter = val;
+            return *this;
+        }
+
+     private:
+        Iterator m_iter;
+    };
+
+    // A metafunction that determines whether operator[] must return a
+    // proxy, or whether it can simply return a copy of the value_type.
+    template <class ValueType, class Reference>
+    struct use_operator_brackets_proxy
+      : mpl::not_<
+            mpl::and_<
+                // Really we want an is_copy_constructible trait here,
+                // but is_POD will have to suffice in the meantime.
+                boost::is_POD<ValueType>
+              , iterator_writability_disabled<ValueType,Reference>
+            >
+        >
+    {};
+
+    template <class Iterator, class Value, class Reference>
+    struct operator_brackets_result
+    {
+        typedef typename mpl::if_<
+            use_operator_brackets_proxy<Value,Reference>
+          , operator_brackets_proxy<Iterator>
+          , Value
+        >::type type;
+    };
+
+    template <class Iterator>
+    operator_brackets_proxy<Iterator> make_operator_brackets_result(Iterator const& iter, mpl::true_)
+    {
+        return operator_brackets_proxy<Iterator>(iter);
+    }
+
+    template <class Iterator>
+    typename Iterator::value_type make_operator_brackets_result(Iterator const& iter, mpl::false_)
+    {
+      return *iter;
+    }
+
+    struct choose_difference_type
+    {
+        template <class I1, class I2>
+        struct apply
+          :
+# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
+          iterator_difference<I1>
+# else
+          mpl::eval_if<
+              is_convertible<I2,I1>
+            , iterator_difference<I1>
+            , iterator_difference<I2>
+          >
+# endif
+        {};
+
+    };
+
+    template <
+        class Derived
+      , class Value
+      , class CategoryOrTraversal
+      , class Reference
+      , class Difference
+      , bool IsBidirectionalTraversal
+      , bool IsRandomAccessTraversal
+    >
+    class iterator_facade_base;
+
+  } // namespace detail
+
+
+  // Macros which describe the declarations of binary operators
+# ifdef BOOST_NO_STRICT_ITERATOR_INTEROPERABILITY
+#  define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler)       \
+    template <                                                              \
+        class Derived1, class V1, class TC1, class Reference1, class Difference1 \
+      , class Derived2, class V2, class TC2, class Reference2, class Difference2 \
+    >                                                                       \
+    prefix typename mpl::apply2<result_type,Derived1,Derived2>::type \
+    operator op(                                                            \
+        iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs   \
+      , iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
+# else
+#  define BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, enabler)   \
+    template <                                                          \
+        class Derived1, class V1, class TC1, class Reference1, class Difference1 \
+      , class Derived2, class V2, class TC2, class Reference2, class Difference2 \
+    >                                                                   \
+    prefix typename enabler<                                            \
+        Derived1, Derived2                                              \
+      , typename mpl::apply2<result_type,Derived1,Derived2>::type       \
+    >::type                                                             \
+    operator op(                                                        \
+        iterator_facade<Derived1, V1, TC1, Reference1, Difference1> const& lhs   \
+      , iterator_facade<Derived2, V2, TC2, Reference2, Difference2> const& rhs)
+# endif
+
+#  define BOOST_ITERATOR_FACADE_INTEROP_HEAD(prefix, op, result_type)       \
+    BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable)
+
+#  define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(prefix, op, result_type)       \
+    BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL(prefix, op, result_type, boost::iterators::detail::enable_if_interoperable_and_random_access_traversal)
+
+#  define BOOST_ITERATOR_FACADE_PLUS_HEAD(prefix,args)              \
+    template <class Derived, class V, class TC, class R, class D>   \
+    prefix typename boost::iterators::enable_if<                    \
+        boost::iterators::detail::is_traversal_at_least< TC, boost::iterators::random_access_traversal_tag >,  \
+        Derived                                                     \
+    >::type operator+ args
+
+  //
+  // Helper class for granting access to the iterator core interface.
+  //
+  // The simple core interface is used by iterator_facade. The core
+  // interface of a user/library defined iterator type should not be made public
+  // so that it does not clutter the public interface. Instead iterator_core_access
+  // should be made friend so that iterator_facade can access the core
+  // interface through iterator_core_access.
+  //
+  class iterator_core_access
+  {
+# if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
+      // Tasteless as this may seem, making all members public allows member templates
+      // to work in the absence of member template friends.
+   public:
+# else
+
+      template <class I, class V, class TC, class R, class D> friend class iterator_facade;
+      template <class I, class V, class TC, class R, class D, bool IsBidirectionalTraversal, bool IsRandomAccessTraversal>
+      friend class detail::iterator_facade_base;
+
+#  define BOOST_ITERATOR_FACADE_RELATION(op)                                \
+      BOOST_ITERATOR_FACADE_INTEROP_HEAD(friend,op, boost::iterators::detail::always_bool2);
+
+      BOOST_ITERATOR_FACADE_RELATION(==)
+      BOOST_ITERATOR_FACADE_RELATION(!=)
+
+#  undef BOOST_ITERATOR_FACADE_RELATION
+
+#  define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op)                                \
+      BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(friend,op, boost::iterators::detail::always_bool2);
+
+      BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<)
+      BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>)
+      BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=)
+      BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=)
+
+#  undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
+
+      BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(
+          friend, -, boost::iterators::detail::choose_difference_type)
+      ;
+
+      BOOST_ITERATOR_FACADE_PLUS_HEAD(
+          friend inline
+        , (iterator_facade<Derived, V, TC, R, D> const&
+        , typename Derived::difference_type)
+      )
+      ;
+
+      BOOST_ITERATOR_FACADE_PLUS_HEAD(
+          friend inline
+        , (typename Derived::difference_type
+        , iterator_facade<Derived, V, TC, R, D> const&)
+      )
+      ;
+
+# endif
+
+      template <class Facade>
+      static typename Facade::reference dereference(Facade const& f)
+      {
+          return f.dereference();
+      }
+
+      template <class Facade>
+      static void increment(Facade& f)
+      {
+          f.increment();
+      }
+
+      template <class Facade>
+      static void decrement(Facade& f)
+      {
+          f.decrement();
+      }
+
+      template <class Facade1, class Facade2>
+      static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::true_)
+      {
+          return f1.equal(f2);
+      }
+
+      template <class Facade1, class Facade2>
+      static bool equal(Facade1 const& f1, Facade2 const& f2, mpl::false_)
+      {
+          return f2.equal(f1);
+      }
+
+      template <class Facade>
+      static void advance(Facade& f, typename Facade::difference_type n)
+      {
+          f.advance(n);
+      }
+
+      template <class Facade1, class Facade2>
+      static typename Facade1::difference_type distance_from(
+          Facade1 const& f1, Facade2 const& f2, mpl::true_)
+      {
+          return -f1.distance_to(f2);
+      }
+
+      template <class Facade1, class Facade2>
+      static typename Facade2::difference_type distance_from(
+          Facade1 const& f1, Facade2 const& f2, mpl::false_)
+      {
+          return f2.distance_to(f1);
+      }
+
+      //
+      // Curiously Recurring Template interface.
+      //
+      template <class I, class V, class TC, class R, class D>
+      static I& derived(iterator_facade<I,V,TC,R,D>& facade)
+      {
+          return *static_cast<I*>(&facade);
+      }
+
+      template <class I, class V, class TC, class R, class D>
+      static I const& derived(iterator_facade<I,V,TC,R,D> const& facade)
+      {
+          return *static_cast<I const*>(&facade);
+      }
+
+      // objects of this class are useless
+      BOOST_DELETED_FUNCTION(iterator_core_access())
+  };
+
+  namespace detail {
+
+    // Implementation for forward traversal iterators
+    template <
+        class Derived
+      , class Value
+      , class CategoryOrTraversal
+      , class Reference
+      , class Difference
+    >
+    class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
+# ifdef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
+        : public boost::iterators::detail::iterator_facade_types<
+             Value, CategoryOrTraversal, Reference, Difference
+          >::base
+#  undef BOOST_ITERATOR_FACADE_NEEDS_ITERATOR_BASE
+# endif
+    {
+    private:
+        typedef boost::iterators::detail::iterator_facade_types<
+            Value, CategoryOrTraversal, Reference, Difference
+        > associated_types;
+
+        typedef boost::iterators::detail::operator_arrow_dispatch<
+            Reference
+          , typename associated_types::pointer
+        > operator_arrow_dispatch_;
+
+    public:
+        typedef typename associated_types::value_type value_type;
+        typedef Reference reference;
+        typedef Difference difference_type;
+
+        typedef typename operator_arrow_dispatch_::result_type pointer;
+
+        typedef typename associated_types::iterator_category iterator_category;
+
+    public:
+        reference operator*() const
+        {
+            return iterator_core_access::dereference(this->derived());
+        }
+
+        pointer operator->() const
+        {
+            return operator_arrow_dispatch_::apply(*this->derived());
+        }
+
+        Derived& operator++()
+        {
+            iterator_core_access::increment(this->derived());
+            return this->derived();
+        }
+
+    protected:
+        //
+        // Curiously Recurring Template interface.
+        //
+        Derived& derived()
+        {
+            return *static_cast<Derived*>(this);
+        }
+
+        Derived const& derived() const
+        {
+            return *static_cast<Derived const*>(this);
+        }
+    };
+
+    // Implementation for bidirectional traversal iterators
+    template <
+        class Derived
+      , class Value
+      , class CategoryOrTraversal
+      , class Reference
+      , class Difference
+    >
+    class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > :
+        public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, false, false >
+    {
+    public:
+        Derived& operator--()
+        {
+            iterator_core_access::decrement(this->derived());
+            return this->derived();
+        }
+
+        Derived operator--(int)
+        {
+            Derived tmp(this->derived());
+            --*this;
+            return tmp;
+        }
+    };
+
+    // Implementation for random access traversal iterators
+    template <
+        class Derived
+      , class Value
+      , class CategoryOrTraversal
+      , class Reference
+      , class Difference
+    >
+    class iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, true > :
+        public iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false >
+    {
+    private:
+        typedef iterator_facade_base< Derived, Value, CategoryOrTraversal, Reference, Difference, true, false > base_type;
+
+    public:
+        typedef typename base_type::reference reference;
+        typedef typename base_type::difference_type difference_type;
+
+    public:
+        typename boost::iterators::detail::operator_brackets_result<Derived, Value, reference>::type
+        operator[](difference_type n) const
+        {
+            typedef boost::iterators::detail::use_operator_brackets_proxy<Value, Reference> use_proxy;
+
+            return boost::iterators::detail::make_operator_brackets_result<Derived>(
+                this->derived() + n
+              , use_proxy()
+            );
+        }
+
+        Derived& operator+=(difference_type n)
+        {
+            iterator_core_access::advance(this->derived(), n);
+            return this->derived();
+        }
+
+        Derived& operator-=(difference_type n)
+        {
+            iterator_core_access::advance(this->derived(), -n);
+            return this->derived();
+        }
+
+        Derived operator-(difference_type x) const
+        {
+            Derived result(this->derived());
+            return result -= x;
+        }
+    };
+
+  } // namespace detail
+
+  //
+  // iterator_facade - use as a public base class for defining new
+  // standard-conforming iterators.
+  //
+  template <
+      class Derived             // The derived iterator type being constructed
+    , class Value
+    , class CategoryOrTraversal
+    , class Reference   = Value&
+    , class Difference  = std::ptrdiff_t
+  >
+  class iterator_facade :
+      public detail::iterator_facade_base<
+          Derived,
+          Value,
+          CategoryOrTraversal,
+          Reference,
+          Difference,
+          detail::is_traversal_at_least< CategoryOrTraversal, bidirectional_traversal_tag >::value,
+          detail::is_traversal_at_least< CategoryOrTraversal, random_access_traversal_tag >::value
+      >
+  {
+  protected:
+      // For use by derived classes
+      typedef iterator_facade<Derived,Value,CategoryOrTraversal,Reference,Difference> iterator_facade_;
+  };
+
+  template <class I, class V, class TC, class R, class D>
+  inline typename boost::iterators::detail::postfix_increment_result<I,V,R,TC>::type
+  operator++(
+      iterator_facade<I,V,TC,R,D>& i
+    , int
+  )
+  {
+      typename boost::iterators::detail::postfix_increment_result<I,V,R,TC>::type
+          tmp(*static_cast<I*>(&i));
+
+      ++i;
+
+      return tmp;
+  }
+
+
+  //
+  // Comparison operator implementation. The library supplied operators
+  // enables the user to provide fully interoperable constant/mutable
+  // iterator types. I.e. the library provides all operators
+  // for all mutable/constant iterator combinations.
+  //
+  // Note though that this kind of interoperability for constant/mutable
+  // iterators is not required by the standard for container iterators.
+  // All the standard asks for is a conversion mutable -> constant.
+  // Most standard library implementations nowadays provide fully interoperable
+  // iterator implementations, but there are still heavily used implementations
+  // that do not provide them. (Actually it's even worse, they do not provide
+  // them for only a few iterators.)
+  //
+  // ?? Maybe a BOOST_ITERATOR_NO_FULL_INTEROPERABILITY macro should
+  //    enable the user to turn off mixed type operators
+  //
+  // The library takes care to provide only the right operator overloads.
+  // I.e.
+  //
+  // bool operator==(Iterator,      Iterator);
+  // bool operator==(ConstIterator, Iterator);
+  // bool operator==(Iterator,      ConstIterator);
+  // bool operator==(ConstIterator, ConstIterator);
+  //
+  //   ...
+  //
+  // In order to do so it uses c++ idioms that are not yet widely supported
+  // by current compiler releases. The library is designed to degrade gracefully
+  // in the face of compiler deficiencies. In general compiler
+  // deficiencies result in less strict error checking and more obscure
+  // error messages, functionality is not affected.
+  //
+  // For full operation compiler support for "Substitution Failure Is Not An Error"
+  // (aka. enable_if) and boost::is_convertible is required.
+  //
+  // The following problems occur if support is lacking.
+  //
+  // Pseudo code
+  //
+  // ---------------
+  // AdaptorA<Iterator1> a1;
+  // AdaptorA<Iterator2> a2;
+  //
+  // // This will result in a no such overload error in full operation
+  // // If enable_if or is_convertible is not supported
+  // // The instantiation will fail with an error hopefully indicating that
+  // // there is no operator== for Iterator1, Iterator2
+  // // The same will happen if no enable_if is used to remove
+  // // false overloads from the templated conversion constructor
+  // // of AdaptorA.
+  //
+  // a1 == a2;
+  // ----------------
+  //
+  // AdaptorA<Iterator> a;
+  // AdaptorB<Iterator> b;
+  //
+  // // This will result in a no such overload error in full operation
+  // // If enable_if is not supported the static assert used
+  // // in the operator implementation will fail.
+  // // This will accidently work if is_convertible is not supported.
+  //
+  // a == b;
+  // ----------------
+  //
+
+# ifdef BOOST_NO_ONE_WAY_ITERATOR_INTEROP
+#  define BOOST_ITERATOR_CONVERTIBLE(a,b) mpl::true_()
+# else
+#  define BOOST_ITERATOR_CONVERTIBLE(a,b) is_convertible<a,b>()
+# endif
+
+# define BOOST_ITERATOR_FACADE_INTEROP(op, result_type, return_prefix, base_op) \
+  BOOST_ITERATOR_FACADE_INTEROP_HEAD(inline, op, result_type)                   \
+  {                                                                             \
+      /* For those compilers that do not support enable_if */                   \
+      BOOST_STATIC_ASSERT((                                                     \
+          is_interoperable< Derived1, Derived2 >::value                         \
+      ));                                                                       \
+      return_prefix iterator_core_access::base_op(                              \
+          *static_cast<Derived1 const*>(&lhs)                                   \
+        , *static_cast<Derived2 const*>(&rhs)                                   \
+        , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1)                         \
+      );                                                                        \
+  }
+
+# define BOOST_ITERATOR_FACADE_RELATION(op, return_prefix, base_op) \
+  BOOST_ITERATOR_FACADE_INTEROP(                                    \
+      op                                                            \
+    , boost::iterators::detail::always_bool2                                   \
+    , return_prefix                                                 \
+    , base_op                                                       \
+  )
+
+  BOOST_ITERATOR_FACADE_RELATION(==, return, equal)
+  BOOST_ITERATOR_FACADE_RELATION(!=, return !, equal)
+
+# undef BOOST_ITERATOR_FACADE_RELATION
+
+
+# define BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(op, result_type, return_prefix, base_op) \
+  BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD(inline, op, result_type)                   \
+  {                                                                             \
+      /* For those compilers that do not support enable_if */                   \
+      BOOST_STATIC_ASSERT((                                                     \
+          is_interoperable< Derived1, Derived2 >::value &&                      \
+          boost::iterators::detail::is_traversal_at_least< typename iterator_category< Derived1 >::type, random_access_traversal_tag >::value && \
+          boost::iterators::detail::is_traversal_at_least< typename iterator_category< Derived2 >::type, random_access_traversal_tag >::value \
+      ));                                                                       \
+      return_prefix iterator_core_access::base_op(                              \
+          *static_cast<Derived1 const*>(&lhs)                                   \
+        , *static_cast<Derived2 const*>(&rhs)                                   \
+        , BOOST_ITERATOR_CONVERTIBLE(Derived2,Derived1)                         \
+      );                                                                        \
+  }
+
+# define BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(op, return_prefix, base_op) \
+  BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(                                    \
+      op                                                            \
+    , boost::iterators::detail::always_bool2                                   \
+    , return_prefix                                                 \
+    , base_op                                                       \
+  )
+
+  BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<, return 0 >, distance_from)
+  BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>, return 0 <, distance_from)
+  BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(<=, return 0 >=, distance_from)
+  BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION(>=, return 0 <=, distance_from)
+
+# undef BOOST_ITERATOR_FACADE_RANDOM_ACCESS_RELATION
+
+  // operator- requires an additional part in the static assertion
+  BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS(
+      -
+    , boost::iterators::detail::choose_difference_type
+    , return
+    , distance_from
+  )
+
+# undef BOOST_ITERATOR_FACADE_INTEROP
+# undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS
+
+# define BOOST_ITERATOR_FACADE_PLUS(args)           \
+  BOOST_ITERATOR_FACADE_PLUS_HEAD(inline, args)     \
+  {                                                 \
+      Derived tmp(static_cast<Derived const&>(i));  \
+      return tmp += n;                              \
+  }
+
+  BOOST_ITERATOR_FACADE_PLUS((
+      iterator_facade<Derived, V, TC, R, D> const& i
+    , typename Derived::difference_type n
+  ))
+
+  BOOST_ITERATOR_FACADE_PLUS((
+      typename Derived::difference_type n
+    , iterator_facade<Derived, V, TC, R, D> const& i
+  ))
+
+# undef BOOST_ITERATOR_FACADE_PLUS
+# undef BOOST_ITERATOR_FACADE_PLUS_HEAD
+
+# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD
+# undef BOOST_ITERATOR_FACADE_INTEROP_RANDOM_ACCESS_HEAD
+# undef BOOST_ITERATOR_FACADE_INTEROP_HEAD_IMPL
+
+} // namespace iterators
+
+using iterators::iterator_core_access;
+using iterators::iterator_facade;
+
+} // namespace boost
+
+#include <boost/iterator/detail/config_undef.hpp>
+
+#endif // BOOST_ITERATOR_FACADE_23022003THW_HPP
diff --git a/third_party/boost/boost/iterator/iterator_traits.hpp b/third_party/boost/boost/iterator/iterator_traits.hpp
new file mode 100644
index 0000000..1a5f1e0
--- /dev/null
+++ b/third_party/boost/boost/iterator/iterator_traits.hpp
@@ -0,0 +1,60 @@
+// Copyright David Abrahams 2003.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef ITERATOR_TRAITS_DWA200347_HPP
+# define ITERATOR_TRAITS_DWA200347_HPP
+
+# include <boost/detail/iterator.hpp>
+# include <boost/detail/workaround.hpp>
+
+namespace boost {
+namespace iterators {
+
+// Macro for supporting old compilers, no longer needed but kept
+// for backwards compatibility (it was documented).
+#define BOOST_ITERATOR_CATEGORY iterator_category
+
+
+template <class Iterator>
+struct iterator_value
+{
+    typedef typename boost::detail::iterator_traits<Iterator>::value_type type;
+};
+
+template <class Iterator>
+struct iterator_reference
+{
+    typedef typename boost::detail::iterator_traits<Iterator>::reference type;
+};
+
+
+template <class Iterator>
+struct iterator_pointer
+{
+    typedef typename boost::detail::iterator_traits<Iterator>::pointer type;
+};
+
+template <class Iterator>
+struct iterator_difference
+{
+    typedef typename boost::detail::iterator_traits<Iterator>::difference_type type;
+};
+
+template <class Iterator>
+struct iterator_category
+{
+    typedef typename boost::detail::iterator_traits<Iterator>::iterator_category type;
+};
+
+} // namespace iterators
+
+using iterators::iterator_value;
+using iterators::iterator_reference;
+using iterators::iterator_pointer;
+using iterators::iterator_difference;
+using iterators::iterator_category;
+
+} // namespace boost
+
+#endif // ITERATOR_TRAITS_DWA200347_HPP
diff --git a/third_party/boost/boost/iterator/reverse_iterator.hpp b/third_party/boost/boost/iterator/reverse_iterator.hpp
new file mode 100644
index 0000000..3bef39e
--- /dev/null
+++ b/third_party/boost/boost/iterator/reverse_iterator.hpp
@@ -0,0 +1,74 @@
+// (C) Copyright David Abrahams 2002.
+// (C) Copyright Jeremy Siek    2002.
+// (C) Copyright Thomas Witt    2002.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+#ifndef BOOST_REVERSE_ITERATOR_23022003THW_HPP
+#define BOOST_REVERSE_ITERATOR_23022003THW_HPP
+
+#include <boost/next_prior.hpp>
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+
+namespace boost {
+namespace iterators {
+
+  //
+  //
+  //
+  template <class Iterator>
+  class reverse_iterator
+      : public iterator_adaptor< reverse_iterator<Iterator>, Iterator >
+  {
+      typedef iterator_adaptor< reverse_iterator<Iterator>, Iterator > super_t;
+
+      friend class iterator_core_access;
+
+   public:
+      reverse_iterator() {}
+
+      explicit reverse_iterator(Iterator x)
+          : super_t(x) {}
+
+      template<class OtherIterator>
+      reverse_iterator(
+          reverse_iterator<OtherIterator> const& r
+          , typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
+          )
+          : super_t(r.base())
+      {}
+
+   private:
+      typename super_t::reference dereference() const { return *boost::prior(this->base()); }
+
+      void increment() { --this->base_reference(); }
+      void decrement() { ++this->base_reference(); }
+
+      void advance(typename super_t::difference_type n)
+      {
+          this->base_reference() += -n;
+      }
+
+      template <class OtherIterator>
+      typename super_t::difference_type
+      distance_to(reverse_iterator<OtherIterator> const& y) const
+      {
+          return this->base_reference() - y.base();
+      }
+  };
+
+  template <class BidirectionalIterator>
+  inline reverse_iterator<BidirectionalIterator> make_reverse_iterator(BidirectionalIterator x)
+  {
+      return reverse_iterator<BidirectionalIterator>(x);
+  }
+
+} // namespace iterators
+
+using iterators::reverse_iterator;
+using iterators::make_reverse_iterator;
+
+} // namespace boost
+
+#endif // BOOST_REVERSE_ITERATOR_23022003THW_HPP
diff --git a/third_party/boost/boost/limits.hpp b/third_party/boost/boost/limits.hpp
new file mode 100644
index 0000000..d335de2
--- /dev/null
+++ b/third_party/boost/boost/limits.hpp
@@ -0,0 +1,145 @@
+
+//  (C) Copyright John maddock 1999.
+//  (C) David Abrahams 2002.  Distributed under the Boost
+//  Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// use this header as a workaround for missing <limits>
+
+//  See http://www.boost.org/libs/compatibility/index.html for documentation.
+
+#ifndef BOOST_LIMITS
+#define BOOST_LIMITS
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_NO_LIMITS
+#  error "There is no std::numeric_limits suppport available."
+#else
+# include <limits>
+#endif
+
+#if (defined(BOOST_HAS_LONG_LONG) && defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS)) \
+      || (defined(BOOST_HAS_MS_INT64) && defined(BOOST_NO_MS_INT64_NUMERIC_LIMITS))
+// Add missing specializations for numeric_limits:
+#ifdef BOOST_HAS_MS_INT64
+#  define BOOST_LLT __int64
+#  define BOOST_ULLT unsigned __int64
+#else
+#  define BOOST_LLT  ::boost::long_long_type
+#  define BOOST_ULLT  ::boost::ulong_long_type
+#endif
+
+#include <climits>  // for CHAR_BIT
+
+namespace std
+{
+  template<>
+  class numeric_limits<BOOST_LLT>
+  {
+   public:
+
+      BOOST_STATIC_CONSTANT(bool, is_specialized = true);
+#ifdef BOOST_HAS_MS_INT64
+      static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0x8000000000000000i64; }
+      static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0x7FFFFFFFFFFFFFFFi64; }
+#elif defined(LLONG_MAX)
+      static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LLONG_MIN; }
+      static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LLONG_MAX; }
+#elif defined(LONGLONG_MAX)
+      static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LONGLONG_MIN; }
+      static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return LONGLONG_MAX; }
+#else
+      static BOOST_LLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 1LL << (sizeof(BOOST_LLT) * CHAR_BIT - 1); }
+      static BOOST_LLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ~(min)(); }
+#endif
+      BOOST_STATIC_CONSTANT(int, digits = sizeof(BOOST_LLT) * CHAR_BIT -1);
+      BOOST_STATIC_CONSTANT(int, digits10 = (CHAR_BIT * sizeof (BOOST_LLT) - 1) * 301L / 1000);
+      BOOST_STATIC_CONSTANT(bool, is_signed = true);
+      BOOST_STATIC_CONSTANT(bool, is_integer = true);
+      BOOST_STATIC_CONSTANT(bool, is_exact = true);
+      BOOST_STATIC_CONSTANT(int, radix = 2);
+      static BOOST_LLT epsilon() throw() { return 0; };
+      static BOOST_LLT round_error() throw() { return 0; };
+
+      BOOST_STATIC_CONSTANT(int, min_exponent = 0);
+      BOOST_STATIC_CONSTANT(int, min_exponent10 = 0);
+      BOOST_STATIC_CONSTANT(int, max_exponent = 0);
+      BOOST_STATIC_CONSTANT(int, max_exponent10 = 0);
+
+      BOOST_STATIC_CONSTANT(bool, has_infinity = false);
+      BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = false);
+      BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = false);
+      BOOST_STATIC_CONSTANT(bool, has_denorm = false);
+      BOOST_STATIC_CONSTANT(bool, has_denorm_loss = false);
+      static BOOST_LLT infinity() throw() { return 0; };
+      static BOOST_LLT quiet_NaN() throw() { return 0; };
+      static BOOST_LLT signaling_NaN() throw() { return 0; };
+      static BOOST_LLT denorm_min() throw() { return 0; };
+
+      BOOST_STATIC_CONSTANT(bool, is_iec559 = false);
+      BOOST_STATIC_CONSTANT(bool, is_bounded = true);
+      BOOST_STATIC_CONSTANT(bool, is_modulo = true);
+
+      BOOST_STATIC_CONSTANT(bool, traps = false);
+      BOOST_STATIC_CONSTANT(bool, tinyness_before = false);
+      BOOST_STATIC_CONSTANT(float_round_style, round_style = round_toward_zero);
+
+  };
+
+  template<>
+  class numeric_limits<BOOST_ULLT>
+  {
+   public:
+
+      BOOST_STATIC_CONSTANT(bool, is_specialized = true);
+#ifdef BOOST_HAS_MS_INT64
+      static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0ui64; }
+      static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0xFFFFFFFFFFFFFFFFui64; }
+#elif defined(ULLONG_MAX) && defined(ULLONG_MIN)
+      static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULLONG_MIN; }
+      static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULLONG_MAX; }
+#elif defined(ULONGLONG_MAX) && defined(ULONGLONG_MIN)
+      static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULONGLONG_MIN; }
+      static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ULONGLONG_MAX; }
+#else
+      static BOOST_ULLT min BOOST_PREVENT_MACRO_SUBSTITUTION (){ return 0uLL; }
+      static BOOST_ULLT max BOOST_PREVENT_MACRO_SUBSTITUTION (){ return ~0uLL; }
+#endif
+      BOOST_STATIC_CONSTANT(int, digits = sizeof(BOOST_LLT) * CHAR_BIT);
+      BOOST_STATIC_CONSTANT(int, digits10 = (CHAR_BIT * sizeof (BOOST_LLT)) * 301L / 1000);
+      BOOST_STATIC_CONSTANT(bool, is_signed = false);
+      BOOST_STATIC_CONSTANT(bool, is_integer = true);
+      BOOST_STATIC_CONSTANT(bool, is_exact = true);
+      BOOST_STATIC_CONSTANT(int, radix = 2);
+      static BOOST_ULLT epsilon() throw() { return 0; };
+      static BOOST_ULLT round_error() throw() { return 0; };
+
+      BOOST_STATIC_CONSTANT(int, min_exponent = 0);
+      BOOST_STATIC_CONSTANT(int, min_exponent10 = 0);
+      BOOST_STATIC_CONSTANT(int, max_exponent = 0);
+      BOOST_STATIC_CONSTANT(int, max_exponent10 = 0);
+
+      BOOST_STATIC_CONSTANT(bool, has_infinity = false);
+      BOOST_STATIC_CONSTANT(bool, has_quiet_NaN = false);
+      BOOST_STATIC_CONSTANT(bool, has_signaling_NaN = false);
+      BOOST_STATIC_CONSTANT(bool, has_denorm = false);
+      BOOST_STATIC_CONSTANT(bool, has_denorm_loss = false);
+      static BOOST_ULLT infinity() throw() { return 0; };
+      static BOOST_ULLT quiet_NaN() throw() { return 0; };
+      static BOOST_ULLT signaling_NaN() throw() { return 0; };
+      static BOOST_ULLT denorm_min() throw() { return 0; };
+
+      BOOST_STATIC_CONSTANT(bool, is_iec559 = false);
+      BOOST_STATIC_CONSTANT(bool, is_bounded = true);
+      BOOST_STATIC_CONSTANT(bool, is_modulo = true);
+
+      BOOST_STATIC_CONSTANT(bool, traps = false);
+      BOOST_STATIC_CONSTANT(bool, tinyness_before = false);
+      BOOST_STATIC_CONSTANT(float_round_style, round_style = round_toward_zero);
+
+  };
+}
+#endif
+
+#endif
diff --git a/third_party/boost/boost/math/common_factor_ct.hpp b/third_party/boost/boost/math/common_factor_ct.hpp
new file mode 100644
index 0000000..173e797
--- /dev/null
+++ b/third_party/boost/boost/math/common_factor_ct.hpp
@@ -0,0 +1,97 @@
+//  Boost common_factor_ct.hpp header file  ----------------------------------//
+
+//  (C) Copyright Daryle Walker and Stephen Cleary 2001-2002.
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org for updates, documentation, and revision history.
+
+#ifndef BOOST_MATH_COMMON_FACTOR_CT_HPP
+#define BOOST_MATH_COMMON_FACTOR_CT_HPP
+
+#include <boost/math_fwd.hpp>  // self include
+#include <boost/config.hpp>  // for BOOST_STATIC_CONSTANT, etc.
+#include <boost/mpl/integral_c.hpp>
+
+namespace boost
+{
+namespace math
+{
+
+//  Implementation details  --------------------------------------------------//
+
+namespace detail
+{
+    // Build GCD with Euclid's recursive algorithm
+    template < static_gcd_type Value1, static_gcd_type Value2 >
+    struct static_gcd_helper_t
+    {
+    private:
+        BOOST_STATIC_CONSTANT( static_gcd_type, new_value1 = Value2 );
+        BOOST_STATIC_CONSTANT( static_gcd_type, new_value2 = Value1 % Value2 );
+
+        #ifndef __BORLANDC__
+        #define BOOST_DETAIL_GCD_HELPER_VAL(Value) static_cast<static_gcd_type>(Value)
+        #else
+        typedef static_gcd_helper_t  self_type;
+        #define BOOST_DETAIL_GCD_HELPER_VAL(Value)  (self_type:: Value )
+        #endif
+
+        typedef static_gcd_helper_t< BOOST_DETAIL_GCD_HELPER_VAL(new_value1),
+         BOOST_DETAIL_GCD_HELPER_VAL(new_value2) >  next_step_type;
+
+        #undef BOOST_DETAIL_GCD_HELPER_VAL
+
+    public:
+        BOOST_STATIC_CONSTANT( static_gcd_type, value = next_step_type::value );
+    };
+
+    // Non-recursive case
+    template < static_gcd_type Value1 >
+    struct static_gcd_helper_t< Value1, 0UL >
+    {
+        BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 );
+    };
+
+    // Build the LCM from the GCD
+    template < static_gcd_type Value1, static_gcd_type Value2 >
+    struct static_lcm_helper_t
+    {
+        typedef static_gcd_helper_t<Value1, Value2>  gcd_type;
+
+        BOOST_STATIC_CONSTANT( static_gcd_type, value = Value1 / gcd_type::value
+         * Value2 );
+    };
+
+    // Special case for zero-GCD values
+    template < >
+    struct static_lcm_helper_t< 0UL, 0UL >
+    {
+        BOOST_STATIC_CONSTANT( static_gcd_type, value = 0UL );
+    };
+
+}  // namespace detail
+
+
+//  Compile-time greatest common divisor evaluator class declaration  --------//
+
+template < static_gcd_type Value1, static_gcd_type Value2 >
+struct static_gcd : public mpl::integral_c<static_gcd_type, (detail::static_gcd_helper_t<Value1, Value2>::value) >
+{
+};  // boost::math::static_gcd
+
+
+//  Compile-time least common multiple evaluator class declaration  ----------//
+
+template < static_gcd_type Value1, static_gcd_type Value2 >
+struct static_lcm : public mpl::integral_c<static_gcd_type, (detail::static_lcm_helper_t<Value1, Value2>::value) >
+{
+};  // boost::math::static_lcm
+
+
+}  // namespace math
+}  // namespace boost
+
+
+#endif  // BOOST_MATH_COMMON_FACTOR_CT_HPP
diff --git a/third_party/boost/boost/math_fwd.hpp b/third_party/boost/boost/math_fwd.hpp
new file mode 100644
index 0000000..f9b7915
--- /dev/null
+++ b/third_party/boost/boost/math_fwd.hpp
@@ -0,0 +1,108 @@
+//  Boost math_fwd.hpp header file  ------------------------------------------//
+
+//  (C) Copyright Hubert Holin and Daryle Walker 2001-2002.  Distributed under the Boost
+//  Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org/libs/math for documentation.
+
+#ifndef BOOST_MATH_FWD_HPP
+#define BOOST_MATH_FWD_HPP
+
+#include <boost/cstdint.hpp>
+
+namespace boost
+{
+namespace math
+{
+
+
+//  From <boost/math/quaternion.hpp>  ----------------------------------------//
+
+template < typename T >
+    class quaternion;
+
+template < >
+    class quaternion< float >;
+template < >
+    class quaternion< double >;
+template < >
+    class quaternion< long double >;
+
+// Also has many function templates (including operators)
+
+
+//  From <boost/math/octonion.hpp>  ------------------------------------------//
+
+template < typename T >
+    class octonion;
+
+template < >
+    class octonion< float >;
+template < >
+    class octonion< double >;
+template < >
+    class octonion< long double >;
+
+// Also has many function templates (including operators)
+
+
+//  From <boost/math/special_functions/acosh.hpp>  ---------------------------//
+
+// Only has function template
+
+
+//  From <boost/math/special_functions/asinh.hpp>  ---------------------------//
+
+// Only has function template
+
+
+//  From <boost/math/special_functions/atanh.hpp>  ---------------------------//
+
+// Only has function template
+
+
+//  From <boost/math/special_functions/sinc.hpp>  ----------------------------//
+
+// Only has function templates
+
+
+//  From <boost/math/special_functions/sinhc.hpp>  ---------------------------//
+
+// Only has function templates
+
+
+//  From <boost/math/common_factor.hpp>  -------------------------------------//
+
+// Only #includes other headers
+
+
+//  From <boost/math/common_factor_ct.hpp>  ----------------------------------//
+
+#ifdef BOOST_NO_INTEGRAL_INT64_T
+     typedef unsigned long static_gcd_type;
+#else
+     typedef boost::uintmax_t static_gcd_type;
+#endif
+
+template < static_gcd_type Value1, static_gcd_type Value2 >
+    struct static_gcd;
+template < static_gcd_type Value1, static_gcd_type Value2 >
+    struct static_lcm;
+
+
+//  From <boost/math/common_factor_rt.hpp>  ----------------------------------//
+
+template < typename IntegerType >
+    class gcd_evaluator;
+template < typename IntegerType >
+    class lcm_evaluator;
+
+// Also has a couple of function templates
+
+
+}  // namespace math
+}  // namespace boost
+
+
+#endif  // BOOST_MATH_FWD_HPP
diff --git a/third_party/boost/boost/mem_fn.hpp b/third_party/boost/boost/mem_fn.hpp
new file mode 100644
index 0000000..3bcd2c5
--- /dev/null
+++ b/third_party/boost/boost/mem_fn.hpp
@@ -0,0 +1,24 @@
+#ifndef BOOST_MEM_FN_HPP_INCLUDED
+#define BOOST_MEM_FN_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  mem_fn.hpp - a generalization of std::mem_fun[_ref]
+//
+//  Copyright (c) 2009 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+//
+//  See http://www.boost.org/libs/bind/mem_fn.html for documentation.
+//
+
+#include <boost/bind/mem_fn.hpp>
+
+#endif // #ifndef BOOST_MEM_FN_HPP_INCLUDED
diff --git a/third_party/boost/boost/move/adl_move_swap.hpp b/third_party/boost/boost/move/adl_move_swap.hpp
new file mode 100644
index 0000000..fcd5f19
--- /dev/null
+++ b/third_party/boost/boost/move/adl_move_swap.hpp
@@ -0,0 +1,233 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright 2007, 2008 Steven Watanabe, Joseph Gauterin, Niels Dekker
+// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/container for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_ADL_MOVE_SWAP_HPP
+#define BOOST_MOVE_ADL_MOVE_SWAP_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+//Based on Boost.Core's swap.
+//Many thanks to Steven Watanabe, Joseph Gauterin and Niels Dekker.
+
+#include <boost/config.hpp>
+#include <cstddef> //for std::size_t
+
+//Try to avoid including <algorithm>, as it's quite big
+#if defined(_MSC_VER) && defined(BOOST_DINKUMWARE_STDLIB)
+   #include <utility>   //Dinkum libraries define std::swap in utility which is lighter than algorithm
+#elif defined(BOOST_GNU_STDLIB)
+   //For non-GCC compilers, where GNUC version is not very reliable, or old GCC versions
+   //use the good old stl_algobase header, which is quite lightweight
+   #if !defined(BOOST_GCC) || ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 3)))
+      #include <bits/stl_algobase.h>
+   #elif (__GNUC__ == 4) && (__GNUC_MINOR__ == 3)
+      //In GCC 4.3 a tiny stl_move.h was created with swap and move utilities
+      #include <bits/stl_move.h>
+   #else
+      //In GCC 4.4 stl_move.h was renamed to move.h
+      #include <bits/move.h>
+   #endif
+#elif defined(_LIBCPP_VERSION)
+   #include <type_traits>  //The initial import of libc++ defines std::swap and still there
+#elif __cplusplus >= 201103L
+   #include <utility>    //Fallback for C++ >= 2011
+#else
+   #include <algorithm>  //Fallback for C++98/03
+#endif
+
+#include <boost/move/utility_core.hpp> //for boost::move
+
+#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+namespace boost_move_member_swap {
+
+struct dont_care
+{
+   dont_care(...);
+};
+
+struct private_type
+{
+   static private_type p;
+   private_type const &operator,(int) const;
+};
+
+typedef char yes_type;
+struct no_type{ char dummy[2]; };
+
+template<typename T>
+no_type is_private_type(T const &);
+
+yes_type is_private_type(private_type const &);
+
+template <typename Type>
+class has_member_function_named_swap
+{
+   struct BaseMixin
+   {
+      void swap();
+   };
+
+   struct Base : public Type, public BaseMixin { Base(); };
+   template <typename T, T t> class Helper{};
+
+   template <typename U>
+   static no_type deduce(U*, Helper<void (BaseMixin::*)(), &U::swap>* = 0);
+   static yes_type deduce(...);
+
+   public:
+   static const bool value = sizeof(yes_type) == sizeof(deduce((Base*)(0)));
+};
+
+template<typename Fun, bool HasFunc>
+struct has_member_swap_impl
+{
+   static const bool value = false;
+};
+
+template<typename Fun>
+struct has_member_swap_impl<Fun, true>
+{
+   struct FunWrap : Fun
+   {
+      FunWrap();
+
+      using Fun::swap;
+      private_type swap(dont_care) const;
+   };
+
+   static Fun &declval_fun();
+   static FunWrap declval_wrap();
+
+   static bool const value =
+      sizeof(no_type) == sizeof(is_private_type( (declval_wrap().swap(declval_fun()), 0)) );
+};
+
+template<typename Fun>
+struct has_member_swap : public has_member_swap_impl
+      <Fun, has_member_function_named_swap<Fun>::value>
+{};
+
+}  //namespace boost_move_member_swap
+
+namespace boost_move_adl_swap{
+
+template<class P1, class P2, bool = P1::value>
+struct and_op_impl
+{  static const bool value = false; };
+
+template<class P1, class P2>
+struct and_op_impl<P1, P2, true>
+{  static const bool value = P2::value;   };
+
+template<class P1, class P2>
+struct and_op
+   : and_op_impl<P1, P2>
+{};
+
+//////
+
+template<class P1, class P2, bool = P1::value>
+struct and_op_not_impl
+{  static const bool value = false; };
+
+template<class P1, class P2>
+struct and_op_not_impl<P1, P2, true>
+{  static const bool value = !P2::value;   };
+
+template<class P1, class P2>
+struct and_op_not
+   : and_op_not_impl<P1, P2>
+{};
+
+template<class T>
+void swap_proxy(T& x, T& y, typename boost::move_detail::enable_if_c<!boost::move_detail::has_move_emulation_enabled_impl<T>::value>::type* = 0)
+{
+   //use std::swap if argument dependent lookup fails
+   //Use using directive ("using namespace xxx;") instead as some older compilers
+   //don't do ADL with using declarations ("using ns::func;").
+   using namespace std;
+   swap(x, y);
+}
+
+template<class T>
+void swap_proxy(T& x, T& y
+               , typename boost::move_detail::enable_if< and_op_not_impl<boost::move_detail::has_move_emulation_enabled_impl<T>
+                                                                        , boost_move_member_swap::has_member_swap<T> >
+                                                       >::type* = 0)
+{  T t(::boost::move(x)); x = ::boost::move(y); y = ::boost::move(t);  }
+
+template<class T>
+void swap_proxy(T& x, T& y
+               , typename boost::move_detail::enable_if< and_op_impl< boost::move_detail::has_move_emulation_enabled_impl<T>
+                                                                    , boost_move_member_swap::has_member_swap<T> >
+                                                       >::type* = 0)
+{  x.swap(y);  }
+
+}  //namespace boost_move_adl_swap{
+
+#else
+
+namespace boost_move_adl_swap{
+
+template<class T>
+void swap_proxy(T& x, T& y)
+{
+   using std::swap;
+   swap(x, y);
+}
+
+}  //namespace boost_move_adl_swap{
+
+#endif   //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+namespace boost_move_adl_swap{
+
+template<class T, std::size_t N>
+void swap_proxy(T (& x)[N], T (& y)[N])
+{
+   for (std::size_t i = 0; i < N; ++i){
+      ::boost_move_adl_swap::swap_proxy(x[i], y[i]);
+   }
+}
+
+}  //namespace boost_move_adl_swap {
+
+#endif   //!defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+namespace boost{
+
+//! Exchanges the values of a and b, using Argument Dependent Lookup (ADL) to select a
+//! specialized swap function if available. If no specialized swap function is available,
+//! std::swap is used.
+//!
+//! <b>Exception</b>: If T uses Boost.Move's move emulation and the compiler has
+//! no rvalue references then:
+//!
+//!   -  If T has a <code>T::swap(T&)</code> member, that member is called.
+//!   -  Otherwise a move-based swap is called, equivalent to:
+//!      <code>T t(::boost::move(x)); x = ::boost::move(y); y = ::boost::move(t);</code>.
+template<class T>
+void adl_move_swap(T& x, T& y)
+{
+   ::boost_move_adl_swap::swap_proxy(x, y);
+}
+
+}  //namespace boost{
+
+#endif   //#ifndef BOOST_MOVE_ADL_MOVE_SWAP_HPP
diff --git a/third_party/boost/boost/move/algorithm.hpp b/third_party/boost/boost/move/algorithm.hpp
new file mode 100644
index 0000000..fbda0f4
--- /dev/null
+++ b/third_party/boost/boost/move/algorithm.hpp
@@ -0,0 +1,282 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_ALGORITHM_HPP
+#define BOOST_MOVE_ALGORITHM_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+
+#include <boost/move/utility_core.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/detail/no_exceptions_support.hpp>
+
+#include <algorithm> //copy, copy_backward
+#include <memory>    //uninitialized_copy
+
+namespace boost {
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               move
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#if !defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
+
+   //! <b>Effects</b>: Moves elements in the range [first,last) into the range [result,result + (last -
+   //!   first)) starting from first and proceeding to last. For each non-negative integer n < (last-first),
+   //!   performs *(result + n) = ::boost::move (*(first + n)).
+   //!
+   //! <b>Effects</b>: result + (last - first).
+   //!
+   //! <b>Requires</b>: result shall not be in the range [first,last).
+   //!
+   //! <b>Complexity</b>: Exactly last - first move assignments.
+   template <typename I, // I models InputIterator
+            typename O> // O models OutputIterator
+   O move(I f, I l, O result)
+   {
+      while (f != l) {
+         *result = ::boost::move(*f);
+         ++f; ++result;
+      }
+      return result;
+   }
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                               move_backward
+   //
+   //////////////////////////////////////////////////////////////////////////////
+
+   //! <b>Effects</b>: Moves elements in the range [first,last) into the range
+   //!   [result - (last-first),result) starting from last - 1 and proceeding to
+   //!   first. For each positive integer n <= (last - first),
+   //!   performs *(result - n) = ::boost::move(*(last - n)).
+   //!
+   //! <b>Requires</b>: result shall not be in the range [first,last).
+   //!
+   //! <b>Returns</b>: result - (last - first).
+   //!
+   //! <b>Complexity</b>: Exactly last - first assignments.
+   template <typename I, // I models BidirectionalIterator
+   typename O> // O models BidirectionalIterator
+   O move_backward(I f, I l, O result)
+   {
+      while (f != l) {
+         --l; --result;
+         *result = ::boost::move(*l);
+      }
+      return result;
+   }
+
+#else
+
+   using ::std::move_backward;
+
+#endif   //!defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                               uninitialized_move
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! <b>Effects</b>:
+//!   \code
+//!   for (; first != last; ++result, ++first)
+//!      new (static_cast<void*>(&*result))
+//!         typename iterator_traits<ForwardIterator>::value_type(boost::move(*first));
+//!   \endcode
+//!
+//! <b>Returns</b>: result
+template
+   <typename I, // I models InputIterator
+    typename F> // F models ForwardIterator
+F uninitialized_move(I f, I l, F r
+   /// @cond
+//   ,typename ::boost::move_detail::enable_if<has_move_emulation_enabled<typename std::iterator_traits<I>::value_type> >::type* = 0
+   /// @endcond
+   )
+{
+   typedef typename std::iterator_traits<I>::value_type input_value_type;
+
+   F back = r;
+   BOOST_TRY{
+      while (f != l) {
+         void * const addr = static_cast<void*>(::boost::move_detail::addressof(*r));
+         ::new(addr) input_value_type(::boost::move(*f));
+         ++f; ++r;
+      }
+   }
+   BOOST_CATCH(...){
+	   for (; back != r; ++back){
+         back->~input_value_type();
+      }
+	   BOOST_RETHROW;
+   }
+   BOOST_CATCH_END
+   return r;
+}
+
+/// @cond
+/*
+template
+   <typename I,   // I models InputIterator
+    typename F>   // F models ForwardIterator
+F uninitialized_move(I f, I l, F r,
+   typename ::boost::move_detail::disable_if<has_move_emulation_enabled<typename std::iterator_traits<I>::value_type> >::type* = 0)
+{
+   return std::uninitialized_copy(f, l, r);
+}
+*/
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                            uninitialized_copy_or_move
+//
+//////////////////////////////////////////////////////////////////////////////
+
+namespace move_detail {
+
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+inline F uninitialized_move_move_iterator(I f, I l, F r
+//                             ,typename ::boost::move_detail::enable_if< has_move_emulation_enabled<typename I::value_type> >::type* = 0
+)
+{
+   return ::boost::uninitialized_move(f, l, r);
+}
+/*
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+F uninitialized_move_move_iterator(I f, I l, F r,
+                                   typename ::boost::move_detail::disable_if< has_move_emulation_enabled<typename I::value_type> >::type* = 0)
+{
+   return std::uninitialized_copy(f.base(), l.base(), r);
+}
+*/
+}  //namespace move_detail {
+
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+inline F uninitialized_copy_or_move(I f, I l, F r,
+                             typename ::boost::move_detail::enable_if< move_detail::is_move_iterator<I> >::type* = 0)
+{
+   return ::boost::move_detail::uninitialized_move_move_iterator(f, l, r);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                            copy_or_move
+//
+//////////////////////////////////////////////////////////////////////////////
+
+namespace move_detail {
+
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+inline F move_move_iterator(I f, I l, F r
+//                             ,typename ::boost::move_detail::enable_if< has_move_emulation_enabled<typename I::value_type> >::type* = 0
+)
+{
+   return ::boost::move(f, l, r);
+}
+/*
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+F move_move_iterator(I f, I l, F r,
+                                   typename ::boost::move_detail::disable_if< has_move_emulation_enabled<typename I::value_type> >::type* = 0)
+{
+   return std::copy(f.base(), l.base(), r);
+}
+*/
+
+}  //namespace move_detail {
+
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+inline F copy_or_move(I f, I l, F r,
+                             typename ::boost::move_detail::enable_if< move_detail::is_move_iterator<I> >::type* = 0)
+{
+   return ::boost::move_detail::move_move_iterator(f, l, r);
+}
+
+/// @endcond
+
+//! <b>Effects</b>:
+//!   \code
+//!   for (; first != last; ++result, ++first)
+//!      new (static_cast<void*>(&*result))
+//!         typename iterator_traits<ForwardIterator>::value_type(*first);
+//!   \endcode
+//!
+//! <b>Returns</b>: result
+//!
+//! <b>Note</b>: This function is provided because
+//!   <i>std::uninitialized_copy</i> from some STL implementations
+//!    is not compatible with <i>move_iterator</i>
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+inline F uninitialized_copy_or_move(I f, I l, F r
+   /// @cond
+   ,typename ::boost::move_detail::disable_if< move_detail::is_move_iterator<I> >::type* = 0
+   /// @endcond
+   )
+{
+   return std::uninitialized_copy(f, l, r);
+}
+
+//! <b>Effects</b>:
+//!   \code
+//!   for (; first != last; ++result, ++first)
+//!      *result = *first;
+//!   \endcode
+//!
+//! <b>Returns</b>: result
+//!
+//! <b>Note</b>: This function is provided because
+//!   <i>std::uninitialized_copy</i> from some STL implementations
+//!    is not compatible with <i>move_iterator</i>
+template
+<typename I,   // I models InputIterator
+typename F>   // F models ForwardIterator
+inline F copy_or_move(I f, I l, F r
+   /// @cond
+   ,typename ::boost::move_detail::disable_if< move_detail::is_move_iterator<I> >::type* = 0
+   /// @endcond
+   )
+{
+   return std::copy(f, l, r);
+}
+
+}  //namespace boost {
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_ALGORITHM_HPP
diff --git a/third_party/boost/boost/move/core.hpp b/third_party/boost/boost/move/core.hpp
new file mode 100644
index 0000000..54aece0
--- /dev/null
+++ b/third_party/boost/boost/move/core.hpp
@@ -0,0 +1,501 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+//! This header implements macros to define movable classes and
+//! move-aware functions
+
+#ifndef BOOST_MOVE_CORE_HPP
+#define BOOST_MOVE_CORE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/workaround.hpp>
+
+// @cond
+
+//boost_move_no_copy_constructor_or_assign typedef
+//used to detect noncopyable types for other Boost libraries.
+#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+   #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
+      private:\
+      TYPE(TYPE &);\
+      TYPE& operator=(TYPE &);\
+      public:\
+      typedef int boost_move_no_copy_constructor_or_assign; \
+      private:\
+   //
+#else
+   #define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
+      public:\
+      TYPE(TYPE const &) = delete;\
+      TYPE& operator=(TYPE const &) = delete;\
+      public:\
+      typedef int boost_move_no_copy_constructor_or_assign; \
+      private:\
+   //
+#endif   //BOOST_NO_CXX11_DELETED_FUNCTIONS
+
+// @endcond
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   #include <boost/move/detail/type_traits.hpp>
+
+   #if defined(BOOST_MOVE_ADDRESS_SANITIZER_ON)
+      #define BOOST_MOVE_TO_RV_CAST(RV_TYPE, ARG) reinterpret_cast<RV_TYPE>(ARG)
+   #else
+      #define BOOST_MOVE_TO_RV_CAST(RV_TYPE, ARG) static_cast<RV_TYPE>(ARG)
+   #endif
+
+   //Move emulation rv breaks standard aliasing rules so add workarounds for some compilers
+   #if defined(__GNUC__) && (__GNUC__ >= 4) && \
+      (\
+         defined(BOOST_GCC) ||   \
+         (defined(BOOST_INTEL) && (BOOST_INTEL_CXX_VERSION >= 1300)) \
+      )
+      #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
+   #else
+      #define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS
+   #endif
+
+   namespace boost {
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                            struct rv
+   //
+   //////////////////////////////////////////////////////////////////////////////
+   template <class T>
+   class rv
+      : public ::boost::move_detail::if_c
+         < ::boost::move_detail::is_class<T>::value
+         , T
+         , ::boost::move_detail::nat
+         >::type
+   {
+      rv();
+      ~rv() throw();
+      rv(rv const&);
+      void operator=(rv const&);
+   } BOOST_MOVE_ATTRIBUTE_MAY_ALIAS;
+
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                            is_rv
+   //
+   //////////////////////////////////////////////////////////////////////////////
+
+   namespace move_detail {
+
+   template <class T>
+   struct is_rv
+        //Derive from integral constant because some Boost code assummes it has
+        //a "type" internal typedef
+      : integral_constant<bool, ::boost::move_detail::is_rv_impl<T>::value >
+   {};
+
+   template <class T>
+   struct is_not_rv
+   {
+      static const bool value = !is_rv<T>::value;
+   };
+
+   }  //namespace move_detail {
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                               has_move_emulation_enabled
+   //
+   //////////////////////////////////////////////////////////////////////////////
+   template<class T>
+   struct has_move_emulation_enabled
+      : ::boost::move_detail::has_move_emulation_enabled_impl<T>
+   {};
+
+   template<class T>
+   struct has_move_emulation_disabled
+   {
+      static const bool value = !::boost::move_detail::has_move_emulation_enabled_impl<T>::value;
+   };
+
+   }  //namespace boost {
+
+   #define BOOST_RV_REF(TYPE)\
+      ::boost::rv< TYPE >& \
+   //
+
+   #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
+      ::boost::rv< TYPE<ARG1, ARG2> >& \
+   //
+
+   #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
+      ::boost::rv< TYPE<ARG1, ARG2, ARG3> >& \
+   //
+
+   #define BOOST_RV_REF_BEG\
+      ::boost::rv<   \
+   //
+
+   #define BOOST_RV_REF_END\
+      >& \
+   //
+
+   #define BOOST_RV_REF_BEG_IF_CXX11 \
+      \
+   //
+
+   #define BOOST_RV_REF_END_IF_CXX11 \
+      \
+   //
+
+   #define BOOST_FWD_REF(TYPE)\
+      const TYPE & \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF(TYPE)\
+      const ::boost::rv< TYPE >& \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF_BEG \
+      const ::boost::rv<  \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF_END \
+      >& \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
+      const ::boost::rv< TYPE<ARG1, ARG2> >& \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
+      const ::boost::rv< TYPE<ARG1, ARG2, ARG3> >& \
+   //
+
+   #define BOOST_CATCH_CONST_RLVALUE(TYPE)\
+      const ::boost::rv< TYPE >& \
+   //
+
+   namespace boost {
+   namespace move_detail {
+
+   template <class Ret, class T>
+   inline typename ::boost::move_detail::enable_if_c
+      <  ::boost::move_detail::is_lvalue_reference<Ret>::value ||
+        !::boost::has_move_emulation_enabled<T>::value
+      , T&>::type
+         move_return(T& x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   template <class Ret, class T>
+   inline typename ::boost::move_detail::enable_if_c
+      < !::boost::move_detail::is_lvalue_reference<Ret>::value &&
+         ::boost::has_move_emulation_enabled<T>::value
+      , ::boost::rv<T>&>::type
+         move_return(T& x) BOOST_NOEXCEPT
+   {
+      return *BOOST_MOVE_TO_RV_CAST(::boost::rv<T>*, ::boost::move_detail::addressof(x));
+   }
+
+   template <class Ret, class T>
+   inline typename ::boost::move_detail::enable_if_c
+      < !::boost::move_detail::is_lvalue_reference<Ret>::value &&
+         ::boost::has_move_emulation_enabled<T>::value
+      , ::boost::rv<T>&>::type
+         move_return(::boost::rv<T>& x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   }  //namespace move_detail {
+   }  //namespace boost {
+
+   #define BOOST_MOVE_RET(RET_TYPE, REF)\
+      boost::move_detail::move_return< RET_TYPE >(REF)
+   //
+
+   #define BOOST_MOVE_BASE(BASE_TYPE, ARG) \
+      ::boost::move((BASE_TYPE&)(ARG))
+   //
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                         BOOST_MOVABLE_BUT_NOT_COPYABLE
+   //
+   //////////////////////////////////////////////////////////////////////////////
+   #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
+      BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
+      public:\
+      operator ::boost::rv<TYPE>&() \
+      {  return *BOOST_MOVE_TO_RV_CAST(::boost::rv<TYPE>*, this);  }\
+      operator const ::boost::rv<TYPE>&() const \
+      {  return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv<TYPE>*, this);  }\
+      private:\
+   //
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                         BOOST_COPYABLE_AND_MOVABLE
+   //
+   //////////////////////////////////////////////////////////////////////////////
+
+   #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
+      public:\
+      TYPE& operator=(TYPE &t)\
+      {  this->operator=(const_cast<const TYPE &>(t)); return *this;}\
+      public:\
+      operator ::boost::rv<TYPE>&() \
+      {  return *BOOST_MOVE_TO_RV_CAST(::boost::rv<TYPE>*, this);  }\
+      operator const ::boost::rv<TYPE>&() const \
+      {  return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv<TYPE>*, this);  }\
+      private:\
+   //
+
+   #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
+      public:\
+      operator ::boost::rv<TYPE>&() \
+      {  return *BOOST_MOVE_TO_RV_CAST(::boost::rv<TYPE>*, this);  }\
+      operator const ::boost::rv<TYPE>&() const \
+      {  return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv<TYPE>*, this);  }\
+      private:\
+   //
+
+   namespace boost{
+   namespace move_detail{
+
+   template< class T>
+   struct forward_type
+   { typedef const T &type; };
+
+   template< class T>
+   struct forward_type< boost::rv<T> >
+   { typedef T type; };
+
+   }}
+
+#else    //BOOST_NO_CXX11_RVALUE_REFERENCES
+
+   //! This macro marks a type as movable but not copyable, disabling copy construction
+   //! and assignment. The user will need to write a move constructor/assignment as explained
+   //! in the documentation to fully write a movable but not copyable class.
+   #define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
+      BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
+      public:\
+      typedef int boost_move_emulation_t;\
+   //
+
+   //! This macro marks a type as copyable and movable.
+   //! The user will need to write a move constructor/assignment and a copy assignment
+   //! as explained in the documentation to fully write a copyable and movable class.
+   #define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
+   //
+
+   #if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+   #define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
+   //
+   #endif   //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   namespace boost {
+
+   //!This trait yields to a compile-time true boolean if T was marked as
+   //!BOOST_MOVABLE_BUT_NOT_COPYABLE or BOOST_COPYABLE_AND_MOVABLE and
+   //!rvalue references are not available on the platform. False otherwise.
+   template<class T>
+   struct has_move_emulation_enabled
+   {
+      static const bool value = false;
+   };
+
+   template<class T>
+   struct has_move_emulation_disabled
+   {
+      static const bool value = true;
+   };
+
+   }  //namespace boost{
+
+   //!This macro is used to achieve portable syntax in move
+   //!constructors and assignments for classes marked as
+   //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE
+   #define BOOST_RV_REF(TYPE)\
+      TYPE && \
+   //
+
+   //!This macro is used to achieve portable syntax in move
+   //!constructors and assignments for template classes marked as
+   //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE.
+   //!As macros have problems with comma-separated template arguments,
+   //!the template argument must be preceded with BOOST_RV_REF_BEG
+   //!and ended with BOOST_RV_REF_END
+   #define BOOST_RV_REF_BEG\
+         \
+   //
+
+   //!This macro is used to achieve portable syntax in move
+   //!constructors and assignments for template classes marked as
+   //!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE.
+   //!As macros have problems with comma-separated template arguments,
+   //!the template argument must be preceded with BOOST_RV_REF_BEG
+   //!and ended with BOOST_RV_REF_END
+   #define BOOST_RV_REF_END\
+      && \
+   //
+
+   //!This macro expands to BOOST_RV_REF_BEG if BOOST_NO_CXX11_RVALUE_REFERENCES
+   //!is not defined, empty otherwise
+   #define BOOST_RV_REF_BEG_IF_CXX11 \
+      BOOST_RV_REF_BEG \
+   //
+
+   //!This macro expands to BOOST_RV_REF_END if BOOST_NO_CXX11_RVALUE_REFERENCES
+   //!is not defined, empty otherwise
+   #define BOOST_RV_REF_END_IF_CXX11 \
+      BOOST_RV_REF_END \
+   //
+
+   //!This macro is used to achieve portable syntax in copy
+   //!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE.
+   #define BOOST_COPY_ASSIGN_REF(TYPE)\
+      const TYPE & \
+   //
+
+   //! This macro is used to implement portable perfect forwarding
+   //! as explained in the documentation.
+   #define BOOST_FWD_REF(TYPE)\
+      TYPE && \
+   //
+
+   #if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   #define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
+      TYPE<ARG1, ARG2> && \
+   //
+
+   #define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
+      TYPE<ARG1, ARG2, ARG3> && \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF_BEG \
+      const \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF_END \
+      & \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
+      const TYPE<ARG1, ARG2> & \
+   //
+
+   #define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
+      const TYPE<ARG1, ARG2, ARG3>& \
+   //
+
+   #define BOOST_CATCH_CONST_RLVALUE(TYPE)\
+      const TYPE & \
+   //
+
+   #endif   //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   #if !defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+      //!This macro is used to achieve portable move return semantics.
+      //!The C++11 Standard allows implicit move returns when the object to be returned
+      //!is designated by a lvalue and:
+      //!   - The criteria for elision of a copy operation are met OR
+      //!   - The criteria would be met save for the fact that the source object is a function parameter
+      //!
+      //!For C++11 conforming compilers this macros only yields to REF:
+      //! <code>return BOOST_MOVE_RET(RET_TYPE, REF);</code> -> <code>return REF;</code>
+      //!
+      //!For compilers without rvalue references
+      //!this macro does an explicit move if the move emulation is activated
+      //!and the return type (RET_TYPE) is not a reference.
+      //!
+      //!For non-conforming compilers with rvalue references like Visual 2010 & 2012,
+      //!an explicit move is performed if RET_TYPE is not a reference.
+      //!
+      //! <b>Caution</b>: When using this macro in non-conforming or C++03
+      //!compilers, a move will be performed even if the C++11 standard does not allow it
+      //!(e.g. returning a static variable). The user is responsible for using this macro
+      //!only to return local objects that met C++11 criteria.
+      #define BOOST_MOVE_RET(RET_TYPE, REF)\
+         REF
+      //
+
+   #else //!defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+      #include <boost/move/detail/meta_utils.hpp>
+
+      namespace boost {
+      namespace move_detail {
+
+      template <class Ret, class T>
+      inline typename ::boost::move_detail::enable_if_c
+         <  ::boost::move_detail::is_lvalue_reference<Ret>::value
+         , T&>::type
+            move_return(T& x) BOOST_NOEXCEPT
+      {
+         return x;
+      }
+
+      template <class Ret, class T>
+      inline typename ::boost::move_detail::enable_if_c
+         < !::boost::move_detail::is_lvalue_reference<Ret>::value
+         , Ret && >::type
+            move_return(T&& t) BOOST_NOEXCEPT
+      {
+         return static_cast< Ret&& >(t);
+      }
+
+      }  //namespace move_detail {
+      }  //namespace boost {
+
+      #define BOOST_MOVE_RET(RET_TYPE, REF)\
+         boost::move_detail::move_return< RET_TYPE >(REF)
+      //
+
+   #endif   //!defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   //!This macro is used to achieve portable optimal move constructors.
+   //!
+   //!When implementing the move constructor, in C++03 compilers the moved-from argument must be
+   //!cast to the base type before calling `::boost::move()` due to rvalue reference limitations.
+   //!
+   //!In C++11 compilers the cast from a rvalue reference of a derived type to a rvalue reference of
+   //!a base type is implicit.
+   #define BOOST_MOVE_BASE(BASE_TYPE, ARG) \
+      ::boost::move((BASE_TYPE&)(ARG))
+   //
+
+   namespace boost {
+   namespace move_detail {
+
+   template< class T> struct forward_type { typedef T type; };
+
+   }}
+
+#endif   //BOOST_NO_CXX11_RVALUE_REFERENCES
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_CORE_HPP
diff --git a/third_party/boost/boost/move/detail/config_begin.hpp b/third_party/boost/boost/move/detail/config_begin.hpp
new file mode 100644
index 0000000..342390b
--- /dev/null
+++ b/third_party/boost/boost/move/detail/config_begin.hpp
@@ -0,0 +1,19 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_CONFIG_HPP
+#include <boost/config.hpp>
+#endif
+
+#ifdef BOOST_MSVC
+#  pragma warning (push)
+#  pragma warning (disable : 4324) // structure was padded due to __declspec(align())
+#  pragma warning (disable : 4675) // "function":  resolved overload was found by argument-dependent lookup
+#  pragma warning (disable : 4996) // "function": was declared deprecated (_CRT_SECURE_NO_DEPRECATE/_SCL_SECURE_NO_WARNINGS)
+#endif
diff --git a/third_party/boost/boost/move/detail/config_end.hpp b/third_party/boost/boost/move/detail/config_end.hpp
new file mode 100644
index 0000000..71a99e9
--- /dev/null
+++ b/third_party/boost/boost/move/detail/config_end.hpp
@@ -0,0 +1,12 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+#if defined BOOST_MSVC
+#  pragma warning (pop)
+#endif
diff --git a/third_party/boost/boost/move/detail/iterator_traits.hpp b/third_party/boost/boost/move/detail/iterator_traits.hpp
new file mode 100644
index 0000000..a75ee03
--- /dev/null
+++ b/third_party/boost/boost/move/detail/iterator_traits.hpp
@@ -0,0 +1,73 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_DETAIL_ITERATOR_TRAITS_HPP
+#define BOOST_MOVE_DETAIL_ITERATOR_TRAITS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <cstddef>
+
+#include <boost/move/detail/std_ns_begin.hpp>
+BOOST_MOVE_STD_NS_BEG
+
+struct input_iterator_tag;
+struct forward_iterator_tag;
+struct bidirectional_iterator_tag;
+struct random_access_iterator_tag;
+struct output_iterator_tag;
+
+BOOST_MOVE_STD_NS_END
+#include <boost/move/detail/std_ns_end.hpp>
+
+namespace boost{  namespace movelib{
+
+template<class Iterator>
+struct iterator_traits
+{
+   typedef typename Iterator::difference_type   difference_type;
+   typedef typename Iterator::value_type        value_type;
+   typedef typename Iterator::pointer           pointer;
+   typedef typename Iterator::reference         reference;
+   typedef typename Iterator::iterator_category iterator_category;
+};
+
+template<class T>
+struct iterator_traits<T*>
+{
+   typedef std::ptrdiff_t                    difference_type;
+   typedef T                                 value_type;
+   typedef T*                                pointer;
+   typedef T&                                reference;
+   typedef std::random_access_iterator_tag   iterator_category;
+};
+
+template<class T>
+struct iterator_traits<const T*>
+{
+   typedef std::ptrdiff_t                    difference_type;
+   typedef T                                 value_type;
+   typedef const T*                          pointer;
+   typedef const T&                          reference;
+   typedef std::random_access_iterator_tag   iterator_category;
+};
+
+}} //namespace boost {  namespace movelib{
+
+#endif //#ifndef BOOST_MOVE_DETAIL_ITERATOR_TRAITS_HPP
diff --git a/third_party/boost/boost/move/detail/meta_utils.hpp b/third_party/boost/boost/move/detail/meta_utils.hpp
new file mode 100644
index 0000000..323c13a
--- /dev/null
+++ b/third_party/boost/boost/move/detail/meta_utils.hpp
@@ -0,0 +1,564 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2015.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP
+#define BOOST_MOVE_DETAIL_META_UTILS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+#include <boost/move/detail/meta_utils_core.hpp>
+#include <cstddef>   //for std::size_t
+
+//Small meta-typetraits to support move
+
+namespace boost {
+
+//Forward declare boost::rv
+template <class T> class rv;
+
+namespace move_detail {
+
+//////////////////////////////////////
+//          is_different
+//////////////////////////////////////
+template<class T, class U>
+struct is_different
+{
+   static const bool value = !is_same<T, U>::value;
+};
+
+//////////////////////////////////////
+//             apply
+//////////////////////////////////////
+template<class F, class Param>
+struct apply
+{
+   typedef typename F::template apply<Param>::type type;
+};
+
+//////////////////////////////////////
+//             bool_
+//////////////////////////////////////
+
+template< bool C_ >
+struct bool_ : integral_constant<bool, C_>
+{
+     operator bool() const { return C_; }
+   bool operator()() const { return C_; }
+};
+
+typedef bool_<true>        true_;
+typedef bool_<false>       false_;
+
+//////////////////////////////////////
+//              nat
+//////////////////////////////////////
+struct nat{};
+
+//////////////////////////////////////
+//          yes_type/no_type
+//////////////////////////////////////
+typedef char yes_type;
+
+struct no_type
+{
+   char _[2];
+};
+
+//////////////////////////////////////
+//            natify
+//////////////////////////////////////
+template <class T> struct natify{};
+
+//////////////////////////////////////
+//          remove_reference
+//////////////////////////////////////
+template<class T>
+struct remove_reference
+{
+   typedef T type;
+};
+
+template<class T>
+struct remove_reference<T&>
+{
+   typedef T type;
+};
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template<class T>
+struct remove_reference<T&&>
+{
+   typedef T type;
+};
+
+#else
+
+template<class T>
+struct remove_reference< rv<T> >
+{
+   typedef T type;
+};
+
+template<class T>
+struct remove_reference< rv<T> &>
+{
+   typedef T type;
+};
+
+template<class T>
+struct remove_reference< const rv<T> &>
+{
+   typedef T type;
+};
+
+#endif
+
+//////////////////////////////////////
+//             remove_pointer
+//////////////////////////////////////
+
+template< class T > struct remove_pointer                    { typedef T type;   };
+template< class T > struct remove_pointer<T*>                { typedef T type;   };
+template< class T > struct remove_pointer<T* const>          { typedef T type;   };
+template< class T > struct remove_pointer<T* volatile>       { typedef T type;   };
+template< class T > struct remove_pointer<T* const volatile> { typedef T type;   };
+
+//////////////////////////////////////
+//             add_pointer
+//////////////////////////////////////
+template< class T >
+struct add_pointer
+{
+   typedef typename remove_reference<T>::type* type;
+};
+
+//////////////////////////////////////
+//             add_const
+//////////////////////////////////////
+template<class T>
+struct add_const
+{
+   typedef const T type;
+};
+
+template<class T>
+struct add_const<T&>
+{
+   typedef const T& type;
+};
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template<class T>
+struct add_const<T&&>
+{
+   typedef T&& type;
+};
+
+#endif
+
+//////////////////////////////////////
+//      add_lvalue_reference
+//////////////////////////////////////
+template<class T>
+struct add_lvalue_reference
+{  typedef T& type;  };
+
+template<class T> struct add_lvalue_reference<T&>                 {  typedef T& type;  };
+template<>        struct add_lvalue_reference<void>               {  typedef void type;   };
+template<>        struct add_lvalue_reference<const void>         {  typedef const void type;  };
+template<>        struct add_lvalue_reference<volatile void>      {  typedef volatile void type;   };
+template<>        struct add_lvalue_reference<const volatile void>{  typedef const volatile void type;   };
+
+template<class T>
+struct add_const_lvalue_reference
+{
+   typedef typename remove_reference<T>::type         t_unreferenced;
+   typedef typename add_const<t_unreferenced>::type   t_unreferenced_const;
+   typedef typename add_lvalue_reference
+      <t_unreferenced_const>::type                    type;
+};
+
+//////////////////////////////////////
+//             is_lvalue_reference
+//////////////////////////////////////
+template<class T>
+struct is_lvalue_reference
+{
+    static const bool value = false;
+};
+
+template<class T>
+struct is_lvalue_reference<T&>
+{
+    static const bool value = true;
+};
+
+
+//////////////////////////////////////
+//             identity
+//////////////////////////////////////
+template <class T>
+struct identity
+{
+   typedef T type;
+   typedef typename add_const_lvalue_reference<T>::type reference;
+   reference operator()(reference t)
+   {  return t;   }
+};
+
+//////////////////////////////////////
+//          is_class_or_union
+//////////////////////////////////////
+template<class T>
+struct is_class_or_union
+{
+   struct twochar { char dummy[2]; };
+   template <class U>
+   static char is_class_or_union_tester(void(U::*)(void));
+   template <class U>
+   static twochar is_class_or_union_tester(...);
+   static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char);
+};
+
+//////////////////////////////////////
+//             addressof
+//////////////////////////////////////
+template<class T>
+struct addr_impl_ref
+{
+   T & v_;
+   inline addr_impl_ref( T & v ): v_( v ) {}
+   inline operator T& () const { return v_; }
+
+   private:
+   addr_impl_ref & operator=(const addr_impl_ref &);
+};
+
+template<class T>
+struct addressof_impl
+{
+   static inline T * f( T & v, long )
+   {
+      return reinterpret_cast<T*>(
+         &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
+   }
+
+   static inline T * f( T * v, int )
+   {  return v;  }
+};
+
+template<class T>
+inline T * addressof( T & v )
+{
+   return ::boost::move_detail::addressof_impl<T>::f
+      ( ::boost::move_detail::addr_impl_ref<T>( v ), 0 );
+}
+
+//////////////////////////////////////
+//          has_pointer_type
+//////////////////////////////////////
+template <class T>
+struct has_pointer_type
+{
+   struct two { char c[2]; };
+   template <class U> static two test(...);
+   template <class U> static char test(typename U::pointer* = 0);
+   static const bool value = sizeof(test<T>(0)) == 1;
+};
+
+//////////////////////////////////////
+//           is_convertible
+//////////////////////////////////////
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+
+//use intrinsic since in MSVC
+//overaligned types can't go through ellipsis
+template <class T, class U>
+struct is_convertible
+{
+   static const bool value = __is_convertible_to(T, U);
+};
+
+#else
+
+template <class T, class U>
+class is_convertible
+{
+   typedef typename add_lvalue_reference<T>::type t_reference;
+   typedef char true_t;
+   class false_t { char dummy[2]; };
+   static false_t dispatch(...);
+   static true_t  dispatch(U);
+   static t_reference       trigger();
+   public:
+   static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
+};
+
+#endif
+
+template<
+      bool C
+    , typename F1
+    , typename F2
+    >
+struct eval_if_c
+    : if_c<C,F1,F2>::type
+{};
+
+template<
+      typename C
+    , typename T1
+    , typename T2
+    >
+struct eval_if
+    : if_<C,T1,T2>::type
+{};
+
+
+#if defined(BOOST_GCC) && (BOOST_GCC <= 40000)
+#define BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN
+#endif
+
+template<class T, class U, class R = void>
+struct enable_if_convertible
+   : enable_if< is_convertible<T, U>, R>
+{};
+
+template<class T, class U, class R = void>
+struct disable_if_convertible
+   : disable_if< is_convertible<T, U>, R>
+{};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         and_
+//
+//////////////////////////////////////////////////////////////////////////////
+template<bool, class B = true_, class C = true_, class D = true_>
+struct and_impl
+   : and_impl<B::value, C, D>
+{};
+
+template<>
+struct and_impl<true, true_, true_, true_>
+{
+   static const bool value = true;
+};
+
+template<class B, class C, class D>
+struct and_impl<false, B, C, D>
+{
+   static const bool value = false;
+};
+
+template<class A, class B, class C = true_, class D = true_>
+struct and_
+   : and_impl<A::value, B, C, D>
+{};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                            or_
+//
+//////////////////////////////////////////////////////////////////////////////
+template<bool, class B = false_, class C = false_, class D = false_>
+struct or_impl
+   : or_impl<B::value, C, D>
+{};
+
+template<>
+struct or_impl<false, false_, false_, false_>
+{
+   static const bool value = false;
+};
+
+template<class B, class C, class D>
+struct or_impl<true, B, C, D>
+{
+   static const bool value = true;
+};
+
+template<class A, class B, class C = false_, class D = false_>
+struct or_
+   : or_impl<A::value, B, C, D>
+{};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         not_
+//
+//////////////////////////////////////////////////////////////////////////////
+template<class T>
+struct not_
+{
+   static const bool value = !T::value;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// enable_if_and / disable_if_and / enable_if_or / disable_if_or
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template<class R, class A, class B, class C = true_, class D = true_>
+struct enable_if_and
+   : enable_if_c< and_<A, B, C, D>::value, R>
+{};
+
+template<class R, class A, class B, class C = true_, class D = true_>
+struct disable_if_and
+   : disable_if_c< and_<A, B, C, D>::value, R>
+{};
+
+template<class R, class A, class B, class C = false_, class D = false_>
+struct enable_if_or
+   : enable_if_c< or_<A, B, C, D>::value, R>
+{};
+
+template<class R, class A, class B, class C = false_, class D = false_>
+struct disable_if_or
+   : disable_if_c< or_<A, B, C, D>::value, R>
+{};
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                      has_move_emulation_enabled_impl
+//
+//////////////////////////////////////////////////////////////////////////////
+template<class T>
+struct has_move_emulation_enabled_impl
+   : is_convertible< T, ::boost::rv<T>& >
+{};
+
+template<class T>
+struct has_move_emulation_enabled_impl<T&>
+{  static const bool value = false;  };
+
+template<class T>
+struct has_move_emulation_enabled_impl< ::boost::rv<T> >
+{  static const bool value = false;  };
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                            is_rv_impl
+//
+//////////////////////////////////////////////////////////////////////////////
+
+template <class T>
+struct is_rv_impl
+{  static const bool value = false;  };
+
+template <class T>
+struct is_rv_impl< rv<T> >
+{  static const bool value = true;  };
+
+template <class T>
+struct is_rv_impl< const rv<T> >
+{  static const bool value = true;  };
+
+// Code from Jeffrey Lee Hellrung, many thanks
+
+template< class T >
+struct is_rvalue_reference
+{  static const bool value = false;  };
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template< class T >
+struct is_rvalue_reference< T&& >
+{  static const bool value = true;  };
+
+#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template< class T >
+struct is_rvalue_reference< boost::rv<T>& >
+{  static const bool value = true;  };
+
+template< class T >
+struct is_rvalue_reference< const boost::rv<T>& >
+{  static const bool value = true;  };
+
+#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template< class T >
+struct add_rvalue_reference
+{ typedef T&& type; };
+
+#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+namespace detail_add_rvalue_reference
+{
+   template< class T
+            , bool emulation = has_move_emulation_enabled_impl<T>::value
+            , bool rv        = is_rv_impl<T>::value  >
+   struct add_rvalue_reference_impl { typedef T type; };
+
+   template< class T, bool emulation>
+   struct add_rvalue_reference_impl< T, emulation, true > { typedef T & type; };
+
+   template< class T, bool rv >
+   struct add_rvalue_reference_impl< T, true, rv > { typedef ::boost::rv<T>& type; };
+} // namespace detail_add_rvalue_reference
+
+template< class T >
+struct add_rvalue_reference
+   : detail_add_rvalue_reference::add_rvalue_reference_impl<T>
+{ };
+
+template< class T >
+struct add_rvalue_reference<T &>
+{  typedef T & type; };
+
+#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template< class T > struct remove_rvalue_reference { typedef T type; };
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+   template< class T > struct remove_rvalue_reference< T&& >                  { typedef T type; };
+#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+   template< class T > struct remove_rvalue_reference< rv<T> >                { typedef T type; };
+   template< class T > struct remove_rvalue_reference< const rv<T> >          { typedef T type; };
+   template< class T > struct remove_rvalue_reference< volatile rv<T> >       { typedef T type; };
+   template< class T > struct remove_rvalue_reference< const volatile rv<T> > { typedef T type; };
+   template< class T > struct remove_rvalue_reference< rv<T>& >               { typedef T type; };
+   template< class T > struct remove_rvalue_reference< const rv<T>& >         { typedef T type; };
+   template< class T > struct remove_rvalue_reference< volatile rv<T>& >      { typedef T type; };
+   template< class T > struct remove_rvalue_reference< const volatile rv<T>& >{ typedef T type; };
+#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+
+// Ideas from Boost.Move review, Jeffrey Lee Hellrung:
+//
+//- TypeTraits metafunctions is_lvalue_reference, add_lvalue_reference, and remove_lvalue_reference ?
+//  Perhaps add_reference and remove_reference can be modified so that they behave wrt emulated rvalue
+//  references the same as wrt real rvalue references, i.e., add_reference< rv<T>& > -> T& rather than
+//  rv<T>& (since T&& & -> T&).
+//
+//- Add'l TypeTraits has_[trivial_]move_{constructor,assign}...?
+//
+//- An as_lvalue(T& x) function, which amounts to an identity operation in C++0x, but strips emulated
+//  rvalue references in C++03.  This may be necessary to prevent "accidental moves".
+
+}  //namespace move_detail {
+}  //namespace boost {
+
+#endif //#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP
diff --git a/third_party/boost/boost/move/detail/meta_utils_core.hpp b/third_party/boost/boost/move/detail/meta_utils_core.hpp
new file mode 100644
index 0000000..7efdd20
--- /dev/null
+++ b/third_party/boost/boost/move/detail/meta_utils_core.hpp
@@ -0,0 +1,120 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2015-2015.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_DETAIL_META_UTILS_CORE_HPP
+#define BOOST_MOVE_DETAIL_META_UTILS_CORE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+//Small meta-typetraits to support move
+
+namespace boost {
+namespace move_detail {
+
+//////////////////////////////////////
+//             if_c
+//////////////////////////////////////
+template<bool C, typename T1, typename T2>
+struct if_c
+{
+   typedef T1 type;
+};
+
+template<typename T1, typename T2>
+struct if_c<false,T1,T2>
+{
+   typedef T2 type;
+};
+
+//////////////////////////////////////
+//             if_
+//////////////////////////////////////
+template<typename T1, typename T2, typename T3>
+struct if_ : if_c<0 != T1::value, T2, T3>
+{};
+
+//////////////////////////////////////
+//          enable_if_c
+//////////////////////////////////////
+template <bool B, class T = void>
+struct enable_if_c
+{
+   typedef T type;
+};
+
+template <class T>
+struct enable_if_c<false, T> {};
+
+//////////////////////////////////////
+//           enable_if
+//////////////////////////////////////
+template <class Cond, class T = void>
+struct enable_if : enable_if_c<Cond::value, T> {};
+
+//////////////////////////////////////
+//          disable_if_c
+//////////////////////////////////////
+template <bool B, class T = void>
+struct disable_if_c
+   : enable_if_c<!B, T>
+{};
+
+//////////////////////////////////////
+//          disable_if
+//////////////////////////////////////
+template <class Cond, class T = void>
+struct disable_if : enable_if_c<!Cond::value, T> {};
+
+//////////////////////////////////////
+//          integral_constant
+//////////////////////////////////////
+template<class T, T v>
+struct integral_constant
+{
+   static const T value = v;
+   typedef T value_type;
+   typedef integral_constant<T, v> type;
+
+     operator T() const { return value; }
+   T operator()() const { return value; }
+};
+
+typedef integral_constant<bool, true >  true_type;
+typedef integral_constant<bool, false > false_type;
+
+
+//////////////////////////////////////
+//             is_same
+//////////////////////////////////////
+template<class T, class U>
+struct is_same
+{
+   static const bool value = false;
+};
+
+template<class T>
+struct is_same<T, T>
+{
+   static const bool value = true;
+};
+
+}  //namespace move_detail {
+}  //namespace boost {
+
+#endif //#ifndef BOOST_MOVE_DETAIL_META_UTILS_CORE_HPP
diff --git a/third_party/boost/boost/move/detail/std_ns_begin.hpp b/third_party/boost/boost/move/detail/std_ns_begin.hpp
new file mode 100644
index 0000000..ea76e6b
--- /dev/null
+++ b/third_party/boost/boost/move/detail/std_ns_begin.hpp
@@ -0,0 +1,29 @@
+#//////////////////////////////////////////////////////////////////////////////
+#//
+#// (C) Copyright Ion Gaztanaga 2015-2015.
+#// Distributed under the Boost Software License, Version 1.0.
+#// (See accompanying file LICENSE_1_0.txt or copy at
+#// http://www.boost.org/LICENSE_1_0.txt)
+#//
+#// See http://www.boost.org/libs/move for documentation.
+#//
+#//////////////////////////////////////////////////////////////////////////////
+#
+#if defined(_LIBCPP_VERSION)
+   #if defined(__clang__)
+      #define BOOST_MOVE_STD_NS_GCC_DIAGNOSTIC_PUSH
+      #pragma GCC diagnostic push
+      #pragma GCC diagnostic ignored "-Wc++11-extensions"
+   #endif
+   #define BOOST_MOVE_STD_NS_BEG _LIBCPP_BEGIN_NAMESPACE_STD
+   #define BOOST_MOVE_STD_NS_END _LIBCPP_END_NAMESPACE_STD
+#elif defined(BOOST_GNU_STDLIB) && defined(_GLIBCXX_BEGIN_NAMESPACE_VERSION)  //GCC >= 4.6
+   #define BOOST_MOVE_STD_NS_BEG namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION
+   #define BOOST_MOVE_STD_NS_END _GLIBCXX_END_NAMESPACE_VERSION  } // namespace
+#elif defined(BOOST_GNU_STDLIB) && defined(_GLIBCXX_BEGIN_NAMESPACE)  //GCC >= 4.2
+   #define BOOST_MOVE_STD_NS_BEG _GLIBCXX_BEGIN_NAMESPACE(std)
+   #define BOOST_MOVE_STD_NS_END _GLIBCXX_END_NAMESPACE
+#else
+   #define BOOST_MOVE_STD_NS_BEG namespace std{
+   #define BOOST_MOVE_STD_NS_END }
+#endif
diff --git a/third_party/boost/boost/move/detail/std_ns_end.hpp b/third_party/boost/boost/move/detail/std_ns_end.hpp
new file mode 100644
index 0000000..0975059
--- /dev/null
+++ b/third_party/boost/boost/move/detail/std_ns_end.hpp
@@ -0,0 +1,14 @@
+#//////////////////////////////////////////////////////////////////////////////
+#//
+#// (C) Copyright Ion Gaztanaga 2015-2015.
+#// Distributed under the Boost Software License, Version 1.0.
+#// (See accompanying file LICENSE_1_0.txt or copy at
+#// http://www.boost.org/LICENSE_1_0.txt)
+#//
+#// See http://www.boost.org/libs/move for documentation.
+#//
+#//////////////////////////////////////////////////////////////////////////////
+#ifdef BOOST_MOVE_STD_NS_GCC_DIAGNOSTIC_PUSH
+   #pragma GCC diagnostic pop
+   #undef BOOST_MOVE_STD_NS_GCC_DIAGNOSTIC_PUSH
+#endif   //BOOST_MOVE_STD_NS_GCC_DIAGNOSTIC_PUSH
diff --git a/third_party/boost/boost/move/detail/type_traits.hpp b/third_party/boost/boost/move/detail/type_traits.hpp
new file mode 100644
index 0000000..7f7b087
--- /dev/null
+++ b/third_party/boost/boost/move/detail/type_traits.hpp
@@ -0,0 +1,1078 @@
+//////////////////////////////////////////////////////////////////////////////
+// (C) Copyright John Maddock 2000.
+// (C) Copyright Ion Gaztanaga 2005-2015.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+// The alignment and Type traits implementation comes from
+// John Maddock's TypeTraits library.
+//
+// Some other tricks come from Howard Hinnant's papers and StackOverflow replies
+//////////////////////////////////////////////////////////////////////////////
+#ifndef BOOST_MOVE_DETAIL_TYPE_TRAITS_HPP
+#define BOOST_MOVE_DETAIL_TYPE_TRAITS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/workaround.hpp>
+
+// move/detail
+#include <boost/move/detail/meta_utils.hpp>
+// other
+#include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
+// std
+#include <cstddef>
+
+//Use of Boost.TypeTraits leads to long preprocessed source code due to
+//MPL dependencies. We'll use intrinsics directly and make or own
+//simplified version of TypeTraits.
+//If someday Boost.TypeTraits dependencies are minimized, we should
+//revisit this file redirecting code to Boost.TypeTraits traits.
+
+//These traits don't care about volatile, reference or other checks
+//made by Boost.TypeTraits because no volatile or reference types
+//can be hold in Boost.Containers. This helps to avoid any Boost.TypeTraits
+//dependency.
+
+// Helper macros for builtin compiler support.
+// If your compiler has builtin support for any of the following
+// traits concepts, then redefine the appropriate macros to pick
+// up on the compiler support:
+//
+// (these should largely ignore cv-qualifiers)
+// BOOST_MOVE_IS_POD(T) should evaluate to true if T is a POD type
+// BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) should evaluate to true if "T x;" has no effect
+// BOOST_MOVE_HAS_TRIVIAL_COPY(T) should evaluate to true if T(t) <==> memcpy
+// BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) should evaluate to true if T(boost::move(t)) <==> memcpy
+// BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) should evaluate to true if t = u <==> memcpy
+// BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) should evaluate to true if t = boost::move(u) <==> memcpy
+// BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) should evaluate to true if ~T() has no effect
+// BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) should evaluate to true if "T x;" can not throw
+// BOOST_MOVE_HAS_NOTHROW_COPY(T) should evaluate to true if T(t) can not throw
+// BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) should evaluate to true if t = u can not throw
+// BOOST_MOVE_IS_ENUM(T) should evaluate to true it t is a union type.
+//
+// The following can also be defined: when detected our implementation is greatly simplified.
+//
+// BOOST_ALIGNMENT_OF(T) should evaluate to the alignment requirements of type T.
+
+#if defined(__MSL_CPP__) && (__MSL_CPP__ >= 0x8000)
+    // Metrowerks compiler is acquiring intrinsic type traits support
+    // post version 8.  We hook into the published interface to pick up
+    // user defined specializations as well as compiler intrinsics as
+    // and when they become available:
+#   include <msl_utility>
+#   define BOOST_MOVE_IS_UNION(T) BOOST_STD_EXTENSION_NAMESPACE::is_union<T>::value
+#   define BOOST_MOVE_IS_POD(T) BOOST_STD_EXTENSION_NAMESPACE::is_POD<T>::value
+#   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_default_ctor<T>::value
+#   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_copy_ctor<T>::value
+#   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_assignment<T>::value
+#   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_dtor<T>::value
+#endif
+
+#if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\
+         || (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500))
+#   define BOOST_MOVE_IS_UNION(T) __is_union(T)
+#   define BOOST_MOVE_IS_POD(T)                    (__is_pod(T) && __has_trivial_constructor(T))
+#   define BOOST_MOVE_IS_EMPTY(T)                  __is_empty(T)
+#   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T)   __has_trivial_constructor(T)
+#   define BOOST_MOVE_HAS_TRIVIAL_COPY(T)          (__has_trivial_copy(T)|| ::boost::move_detail::is_pod<T>::value)
+#   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T)        (__has_trivial_assign(T) || ::boost::move_detail::is_pod<T>::value)
+#   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T)    (__has_trivial_destructor(T) || ::boost::move_detail::is_pod<T>::value)
+#   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T)   (__has_nothrow_constructor(T) || ::boost::move_detail::is_trivially_default_constructible<T>::value)
+#   define BOOST_MOVE_HAS_NOTHROW_COPY(T)          (__has_nothrow_copy(T) || ::boost::move_detail::is_trivially_copy_constructible<T>::value)
+#   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T)        (__has_nothrow_assign(T) || ::boost::move_detail::is_trivially_copy_assignable<T>::value)
+
+#   define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
+#   if defined(_MSC_VER) && (_MSC_VER >= 1700)
+#       define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T)   (__has_trivial_move_constructor(T) || ::boost::move_detail::is_pod<T>::value)
+#       define BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T)        (__has_trivial_move_assign(T) || ::boost::move_detail::is_pod<T>::value)
+#   endif
+#endif
+
+#if defined(BOOST_CLANG) && defined(__has_feature)
+
+#   if __has_feature(is_union)
+#     define BOOST_MOVE_IS_UNION(T) __is_union(T)
+#   endif
+#   if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_pod)
+#     define BOOST_MOVE_IS_POD(T) __is_pod(T)
+#   endif
+#   if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_empty)
+#     define BOOST_MOVE_IS_EMPTY(T) __is_empty(T)
+#   endif
+#   if __has_feature(has_trivial_constructor)
+#     define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T)
+#   endif
+#   if __has_feature(has_trivial_copy)
+#     //There are problems with deleted copy constructors detected as trivially copyable.
+#     //http://stackoverflow.com/questions/12754886/has-trivial-copy-behaves-differently-in-clang-and-gcc-whos-right
+#     define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T) && ::boost::move_detail::is_copy_constructible<T>::value)
+#   endif
+#   if __has_feature(has_trivial_assign)
+#     define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) )
+#   endif
+#   if __has_feature(has_trivial_destructor)
+#     define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
+#   endif
+#   if __has_feature(has_nothrow_constructor)
+#     define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) __has_nothrow_constructor(T)
+#   endif
+#   if __has_feature(has_nothrow_copy)
+#     define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T))
+#   endif
+#   if __has_feature(is_nothrow_copy_assignable)
+#     define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T))
+#   endif
+#   if __has_feature(is_enum)
+#     define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
+#   endif
+#   if __has_feature(has_trivial_move_constructor)
+#     define BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) __has_trivial_move_constructor(T)
+#   endif
+#   if __has_feature(has_trivial_move_assign)
+#     define BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T) __has_trivial_move_assign(T)
+#   endif
+#   define BOOST_MOVE_ALIGNMENT_OF(T) __alignof(T)
+#endif
+
+#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) && !defined(__GCCXML__))) && !defined(BOOST_CLANG)
+
+#ifdef BOOST_INTEL
+#  define BOOST_MOVE_INTEL_TT_OPTS || ::boost::move_detail::is_pod<T>::value
+#else
+#  define BOOST_MOVE_INTEL_TT_OPTS
+#endif
+
+#   define BOOST_MOVE_IS_UNION(T) __is_union(T)
+#   define BOOST_MOVE_IS_POD(T) __is_pod(T)
+#   define BOOST_MOVE_IS_EMPTY(T) __is_empty(T)
+#   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) ((__has_trivial_constructor(T) BOOST_MOVE_INTEL_TT_OPTS))
+#   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) ((__has_trivial_copy(T) BOOST_MOVE_INTEL_TT_OPTS))
+#   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) ((__has_trivial_assign(T) BOOST_MOVE_INTEL_TT_OPTS) )
+#   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) BOOST_MOVE_INTEL_TT_OPTS)
+#   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) BOOST_MOVE_INTEL_TT_OPTS)
+#   define BOOST_MOVE_HAS_NOTHROW_COPY(T) ((__has_nothrow_copy(T) BOOST_MOVE_INTEL_TT_OPTS))
+#   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) ((__has_nothrow_assign(T) BOOST_MOVE_INTEL_TT_OPTS))
+
+#   define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
+#   if (!defined(unix) && !defined(__unix__)) || defined(__LP64__)
+      // GCC sometimes lies about alignment requirements
+      // of type double on 32-bit unix platforms, use the
+      // old implementation instead in that case:
+#     define BOOST_MOVE_ALIGNMENT_OF(T) __alignof__(T)
+#   endif
+#endif
+
+#if defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600)
+
+#   define BOOST_MOVE_IS_UNION(T) __is_union(T)
+#   define BOOST_MOVE_IS_POD(T) __is_pod(T)
+#   define BOOST_MOVE_IS_EMPTY(T) __is_empty(T)
+#   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T)
+#   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T))
+#   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T))
+#   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
+#   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) __has_nothrow_constructor(T)
+#   define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T))
+#   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T))
+
+#   define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
+#   define BOOST_MOVE_ALIGNMENT_OF(T) __alignof__(T)
+#endif
+
+# if defined(__CODEGEARC__)
+#   define BOOST_MOVE_IS_UNION(T) __is_union(T)
+#   define BOOST_MOVE_IS_POD(T) __is_pod(T)
+#   define BOOST_MOVE_IS_EMPTY(T) __is_empty(T)
+#   define BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T) (__has_trivial_default_constructor(T))
+#   define BOOST_MOVE_HAS_TRIVIAL_COPY(T) (__has_trivial_copy_constructor(T))
+#   define BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T))
+#   define BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T))
+#   define BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_default_constructor(T))
+#   define BOOST_MOVE_HAS_NOTHROW_COPY(T) (__has_nothrow_copy_constructor(T))
+#   define BOOST_MOVE_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T))
+
+#   define BOOST_MOVE_IS_ENUM(T) __is_enum(T)
+#   define BOOST_MOVE_ALIGNMENT_OF(T) alignof(T)
+
+#endif
+
+//Fallback definitions
+
+#ifdef BOOST_MOVE_IS_UNION
+   #define BOOST_MOVE_IS_UNION_IMPL(T) BOOST_MOVE_IS_UNION(T)
+#else
+   #define BOOST_MOVE_IS_UNION_IMPL(T) false
+#endif
+
+#ifdef BOOST_MOVE_IS_POD
+   //in some compilers the intrinsic is limited to class types so add scalar and void
+   #define BOOST_MOVE_IS_POD_IMPL(T) (::boost::move_detail::is_scalar<T>::value ||\
+                                      ::boost::move_detail::is_void<T>::value   ||\
+                                       BOOST_MOVE_IS_POD(T))
+#else
+   #define BOOST_MOVE_IS_POD_IMPL(T) \
+      (::boost::move_detail::is_scalar<T>::value || ::boost::move_detail::is_void<T>::value)
+#endif
+
+#ifdef BOOST_MOVE_IS_EMPTY
+   #define BOOST_MOVE_IS_EMPTY_IMPL(T) BOOST_MOVE_IS_EMPTY(T)
+#else
+   #define BOOST_MOVE_IS_EMPTY_IMPL(T)    ::boost::move_detail::is_empty_nonintrinsic<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_TRIVIAL_COPY
+   #define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_TRIVIAL_COPY(T)
+#else
+   #define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR
+   #define BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T)  BOOST_MOVE_HAS_TRIVIAL_CONSTRUCTOR(T)
+#else
+   #define BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T)  ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_TRIVIAL_COPY
+   #define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_TRIVIAL_COPY(T)
+#else
+   #define BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR
+   #define BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T)
+#else
+   #define BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_TRIVIAL_ASSIGN
+   #define BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) BOOST_MOVE_HAS_TRIVIAL_ASSIGN(T)
+#else
+   #define BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN
+   #define BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T)  BOOST_MOVE_HAS_TRIVIAL_MOVE_ASSIGN(T)
+#else
+   #define BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T)  ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR
+   #define BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T)   BOOST_MOVE_HAS_TRIVIAL_DESTRUCTOR(T)
+#else
+   #define BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR
+   #define BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T)  BOOST_MOVE_HAS_NOTHROW_CONSTRUCTOR(T)
+#else
+   #define BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T)  ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_NOTHROW_COPY
+   #define BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_NOTHROW_COPY(T)
+#else
+   #define BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_NOTHROW_MOVE
+   #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T)   BOOST_MOVE_HAS_NOTHROW_MOVE(T)
+#else
+   #define BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T)   ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_NOTHROW_ASSIGN
+   #define BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T) BOOST_MOVE_HAS_NOTHROW_ASSIGN(T)
+#else
+   #define BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN
+   #define BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T) BOOST_MOVE_HAS_NOTHROW_MOVE_ASSIGN(T)
+#else
+   #define BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T) ::boost::move_detail::is_pod<T>::value
+#endif
+
+#ifdef BOOST_MOVE_IS_ENUM
+   #define BOOST_MOVE_IS_ENUM_IMPL(T)   BOOST_MOVE_IS_ENUM(T)
+#else
+   #define BOOST_MOVE_IS_ENUM_IMPL(T)   ::boost::move_detail::is_enum_nonintrinsic<T>::value
+#endif
+
+namespace boost {
+namespace move_detail {
+
+//////////////////////////
+//    is_reference
+//////////////////////////
+template<class T>
+struct is_reference
+{  static const bool value = false; };
+
+template<class T>
+struct is_reference<T&>
+{  static const bool value = true; };
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+template<class T>
+struct is_reference<T&&>
+{  static const bool value = true; };
+#endif
+
+//////////////////////////
+//    is_pointer
+//////////////////////////
+template<class T>
+struct is_pointer
+{  static const bool value = false; };
+
+template<class T>
+struct is_pointer<T*>
+{  static const bool value = true; };
+
+//////////////////////////
+//       is_const
+//////////////////////////
+template<class T>
+struct is_const
+{  static const bool value = false; };
+
+template<class T>
+struct is_const<const T>
+{  static const bool value = true; };
+
+//////////////////////////
+//       unvoid_ref
+//////////////////////////
+template <typename T> struct unvoid_ref : add_lvalue_reference<T>{};
+template <> struct unvoid_ref<void>                { typedef unvoid_ref & type; };
+template <> struct unvoid_ref<const void>          { typedef unvoid_ref & type; };
+template <> struct unvoid_ref<volatile void>       { typedef unvoid_ref & type; };
+template <> struct unvoid_ref<const volatile void> { typedef unvoid_ref & type; };
+
+template <typename T>
+struct add_reference : add_lvalue_reference<T>
+{};
+
+//////////////////////////
+//    add_const_reference
+//////////////////////////
+template <class T>
+struct add_const_reference
+{  typedef const T &type;   };
+
+template <class T>
+struct add_const_reference<T&>
+{  typedef T& type;   };
+
+//////////////////////////
+//    add_const_if_c
+//////////////////////////
+template<class T, bool Add>
+struct add_const_if_c
+   : if_c<Add, typename add_const<T>::type, T>
+{};
+
+//////////////////////////
+//    remove_const
+//////////////////////////
+template<class T>
+struct remove_const
+{  typedef T type;   };
+
+template<class T>
+struct remove_const< const T>
+{  typedef T type;   };
+
+//////////////////////////
+//    remove_cv
+//////////////////////////
+template<typename T> struct remove_cv                    {  typedef T type;   };
+template<typename T> struct remove_cv<const T>           {  typedef T type;   };
+template<typename T> struct remove_cv<const volatile T>  {  typedef T type;   };
+template<typename T> struct remove_cv<volatile T>        {  typedef T type;   };
+
+//////////////////////////
+//    make_unsigned
+//////////////////////////
+template <class T>
+struct make_unsigned_impl                                         {  typedef T type;   };
+template <> struct make_unsigned_impl<signed char>                {  typedef unsigned char  type; };
+template <> struct make_unsigned_impl<signed short>               {  typedef unsigned short type; };
+template <> struct make_unsigned_impl<signed int>                 {  typedef unsigned int   type; };
+template <> struct make_unsigned_impl<signed long>                {  typedef unsigned long  type; };
+#ifdef BOOST_HAS_LONG_LONG
+template <> struct make_unsigned_impl< ::boost::long_long_type >  {  typedef ::boost::ulong_long_type type; };
+#endif
+
+template <class T>
+struct make_unsigned
+   : make_unsigned_impl<typename remove_cv<T>::type>
+{};
+
+//////////////////////////
+//    is_floating_point
+//////////////////////////
+template<class T> struct is_floating_point_cv               {  static const bool value = false; };
+template<>        struct is_floating_point_cv<float>        {  static const bool value = true; };
+template<>        struct is_floating_point_cv<double>       {  static const bool value = true; };
+template<>        struct is_floating_point_cv<long double>  {  static const bool value = true; };
+
+template<class T>
+struct is_floating_point
+   : is_floating_point_cv<typename remove_cv<T>::type>
+{};
+
+//////////////////////////
+//    is_integral
+//////////////////////////
+template<class T> struct is_integral_cv                    {  static const bool value = false; };
+template<> struct is_integral_cv<                     bool>{  static const bool value = true; };
+template<> struct is_integral_cv<                     char>{  static const bool value = true; };
+template<> struct is_integral_cv<            unsigned char>{  static const bool value = true; };
+template<> struct is_integral_cv<              signed char>{  static const bool value = true; };
+#ifndef BOOST_NO_CXX11_CHAR16_T
+template<> struct is_integral_cv<                 char16_t>{  static const bool value = true; };
+#endif
+#ifndef BOOST_NO_CXX11_CHAR32_T
+template<> struct is_integral_cv<                 char32_t>{  static const bool value = true; };
+#endif
+#ifndef BOOST_NO_INTRINSIC_WCHAR_T
+template<> struct is_integral_cv<                  wchar_t>{  static const bool value = true; };
+#endif
+template<> struct is_integral_cv<                    short>{  static const bool value = true; };
+template<> struct is_integral_cv<           unsigned short>{  static const bool value = true; };
+template<> struct is_integral_cv<                      int>{  static const bool value = true; };
+template<> struct is_integral_cv<             unsigned int>{  static const bool value = true; };
+template<> struct is_integral_cv<                     long>{  static const bool value = true; };
+template<> struct is_integral_cv<            unsigned long>{  static const bool value = true; };
+#ifdef BOOST_HAS_LONG_LONG
+template<> struct is_integral_cv< ::boost:: long_long_type>{  static const bool value = true; };
+template<> struct is_integral_cv< ::boost::ulong_long_type>{  static const bool value = true; };
+#endif
+
+template<class T>
+struct is_integral
+   : public is_integral_cv<typename remove_cv<T>::type>
+{};
+
+//////////////////////////////////////
+//          remove_all_extents
+//////////////////////////////////////
+template <class T>
+struct remove_all_extents
+{  typedef T type;};
+
+template <class T>
+struct remove_all_extents<T[]>
+{  typedef typename remove_all_extents<T>::type type; };
+
+template <class T, std::size_t N>
+struct remove_all_extents<T[N]>
+{  typedef typename remove_all_extents<T>::type type;};
+
+//////////////////////////
+//    is_scalar
+//////////////////////////
+template<class T>
+struct is_scalar
+{  static const bool value = is_integral<T>::value || is_floating_point<T>::value; };
+
+//////////////////////////
+//       is_void
+//////////////////////////
+template<class T>
+struct is_void_cv
+{  static const bool value = false; };
+
+template<>
+struct is_void_cv<void>
+{  static const bool value = true; };
+
+template<class T>
+struct is_void
+   : is_void_cv<typename remove_cv<T>::type>
+{};
+
+//////////////////////////////////////
+//          is_array
+//////////////////////////////////////
+template<class T>
+struct is_array
+{  static const bool value = false; };
+
+template<class T>
+struct is_array<T[]>
+{  static const bool value = true;  };
+
+template<class T, std::size_t N>
+struct is_array<T[N]>
+{  static const bool value = true;  };
+
+//////////////////////////////////////
+//           is_member_pointer
+//////////////////////////////////////
+template <class T>         struct is_member_pointer_cv         {  static const bool value = false; };
+template <class T, class U>struct is_member_pointer_cv<T U::*> {  static const bool value = true; };
+
+template <class T>
+struct is_member_pointer
+    : is_member_pointer_cv<typename remove_cv<T>::type>
+{};
+
+//////////////////////////////////////
+//          is_nullptr_t
+//////////////////////////////////////
+template <class T>
+struct is_nullptr_t_cv
+{  static const bool value = false; };
+
+#if !defined(BOOST_NO_CXX11_NULLPTR)
+template <>
+struct is_nullptr_t_cv
+   #if !defined(BOOST_NO_CXX11_DECLTYPE)
+   <decltype(nullptr)>
+   #else
+   <std::nullptr_t>
+   #endif
+{  static const bool value = true; };
+#endif
+
+template <class T>
+struct is_nullptr_t
+   : is_nullptr_t_cv<typename remove_cv<T>::type>
+{};
+
+//////////////////////////////////////
+//          is_function
+//////////////////////////////////////
+//Inspired by libc++, thanks to Howard Hinnant
+//For a function to pointer an lvalue of function type T can be implicitly converted to a prvalue
+//pointer to that function. This does not apply to non-static member functions because lvalues
+//that refer to non-static member functions do not exist.
+template <class T>
+struct is_reference_convertible_to_pointer
+{
+   struct twochar { char dummy[2]; };
+   template <class U> static char    test(U*);
+   template <class U> static twochar test(...);
+   static T& source();
+   static const bool value = sizeof(char) == sizeof(test<T>(source()));
+};
+//Filter out:
+// - class types that might have implicit conversions
+// - void (to avoid forming a reference to void later)
+// - references (e.g.: filtering reference to functions)
+// - nullptr_t (convertible to pointer)
+template < class T
+         , bool Filter = is_class_or_union<T>::value  ||
+                         is_void<T>::value            ||
+                         is_reference<T>::value       ||
+                         is_nullptr_t<T>::value       >
+struct is_function_impl
+{  static const bool value = is_reference_convertible_to_pointer<T>::value; };
+
+template <class T>
+struct is_function_impl<T, true>
+{  static const bool value = false; };
+
+template <class T>
+struct is_function
+   : is_function_impl<T>
+{};
+
+//////////////////////////////////////
+//       is_union
+//////////////////////////////////////
+template<class T>
+struct is_union_noextents_cv
+{  static const bool value = BOOST_MOVE_IS_UNION_IMPL(T); };
+
+template<class T>
+struct is_union
+   : is_union_noextents_cv<typename remove_cv<typename remove_all_extents<T>::type>::type>
+{};
+
+//////////////////////////////////////
+//             is_class
+//////////////////////////////////////
+template <class T>
+struct is_class
+{
+   static const bool value = is_class_or_union<T>::value && ! is_union<T>::value;
+};
+
+
+//////////////////////////////////////
+//             is_arithmetic
+//////////////////////////////////////
+template <class T>
+struct is_arithmetic
+{
+   static const bool value = is_floating_point<T>::value ||
+                             is_integral<T>::value;
+};
+
+//////////////////////////////////////
+//    is_member_function_pointer
+//////////////////////////////////////
+template <class T>
+struct is_member_function_pointer_cv
+{
+   static const bool value = false;
+};
+
+template <class T, class C>
+struct is_member_function_pointer_cv<T C::*>
+   : is_function<T>
+{};
+
+template <class T>
+struct is_member_function_pointer
+    : is_member_function_pointer_cv<typename remove_cv<T>::type>
+{};
+
+//////////////////////////////////////
+//             is_enum
+//////////////////////////////////////
+#if !defined(BOOST_MOVE_IS_ENUM)
+//Based on (http://howardhinnant.github.io/TypeHiearchy.pdf)
+template <class T>
+struct is_enum_nonintrinsic
+{
+   static const bool value =  !is_arithmetic<T>::value     &&
+                              !is_reference<T>::value      &&
+                              !is_class_or_union<T>::value &&
+                              !is_array<T>::value          &&
+                              !is_void<T>::value           &&
+                              !is_nullptr_t<T>::value      &&
+                              !is_member_pointer<T>::value &&
+                              !is_pointer<T>::value        &&
+                              !is_function<T>::value;
+};
+#endif
+
+template <class T>
+struct is_enum
+{  static const bool value = BOOST_MOVE_IS_ENUM_IMPL(T);  };
+
+//////////////////////////////////////
+//       is_pod
+//////////////////////////////////////
+template<class T>
+struct is_pod_noextents_cv  //for non-c++11 compilers, a safe fallback
+{  static const bool value = BOOST_MOVE_IS_POD_IMPL(T); };
+
+template<class T>
+struct is_pod
+   : is_pod_noextents_cv<typename remove_cv<typename remove_all_extents<T>::type>::type>
+{};
+
+//////////////////////////////////////
+//             is_empty
+//////////////////////////////////////
+#if !defined(BOOST_MOVE_IS_EMPTY)
+
+template <typename T>
+struct empty_helper_t1 : public T
+{
+   empty_helper_t1();  // hh compiler bug workaround
+   int i[256];
+   private:
+
+   empty_helper_t1(const empty_helper_t1&);
+   empty_helper_t1& operator=(const empty_helper_t1&);
+};
+
+struct empty_helper_t2 { int i[256]; };
+
+template <typename T, bool IsClass = is_class<T>::value >
+struct is_empty_nonintrinsic
+{
+   static const bool value = false;
+};
+
+template <typename T>
+struct is_empty_nonintrinsic<T, true>
+{
+   static const bool value = sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2);
+};
+#endif
+
+template <class T>
+struct is_empty
+{  static const bool value = BOOST_MOVE_IS_EMPTY_IMPL(T);  };
+
+
+template<class T>
+struct has_boost_move_no_copy_constructor_or_assign_type
+{
+   template <class U>
+   static yes_type test(typename U::boost_move_no_copy_constructor_or_assign*);
+
+   template <class U>
+   static no_type test(...);
+
+   static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
+};
+
+//////////////////////////////////////
+//       is_copy_constructible
+//////////////////////////////////////
+#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_CXX11_DECLTYPE) \
+   && !defined(BOOST_INTEL_CXX_VERSION) && \
+      !(defined(BOOST_MSVC) && _MSC_VER == 1800)
+#define BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE
+#endif
+
+template<class T>
+struct is_copy_constructible
+{
+   // Intel compiler has problems with SFINAE for copy constructors and deleted functions:
+   //
+   // error: function *function_name* cannot be referenced -- it is a deleted function
+   // static yes_type test(U&, decltype(U(boost::declval<U&>()))* = 0);
+   //                                                        ^
+   // MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See:
+   // https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken
+   #if defined(BOOST_MOVE_TT_CXX11_IS_COPY_CONSTRUCTIBLE)
+      template<class U> static typename add_reference<U>::type source();
+      static no_type test(...);
+      #ifdef BOOST_NO_CXX11_DECLTYPE
+         template <class U>
+         static yes_type test(U&, bool_<sizeof(U(source<U>()))>* = 0);
+      #else
+         template <class U>
+         static yes_type test(U&, decltype(U(source<U>()))* = 0);
+      #endif
+      static const bool value = sizeof(test(source<T>())) == sizeof(yes_type);
+   #else
+   static const bool value = !has_boost_move_no_copy_constructor_or_assign_type<T>::value;
+   #endif
+};
+
+
+//////////////////////////////////////
+//       is_copy_assignable
+//////////////////////////////////////
+#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_CXX11_DECLTYPE) \
+   && !defined(BOOST_INTEL_CXX_VERSION) && \
+      !(defined(BOOST_MSVC) && _MSC_VER == 1800)
+#define BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE
+#endif
+
+template <class T>
+struct is_copy_assignable
+{
+// Intel compiler has problems with SFINAE for copy constructors and deleted functions:
+//
+// error: function *function_name* cannot be referenced -- it is a deleted function
+// static boost::type_traits::yes_type test(T1&, decltype(T1(boost::declval<T1&>()))* = 0);
+//                                                        ^
+//
+// MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See:
+// https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken
+#if defined(BOOST_MOVE_TT_CXX11_IS_COPY_ASSIGNABLE)
+   typedef char yes_type;
+   struct no_type { char dummy[2]; };
+
+   template <class U>   static typename add_reference<U>::type source();
+   template <class U>   static decltype(source<U&>() = source<const U&>(), yes_type() ) test(int);
+   template <class>     static no_type test(...);
+
+   static const bool value = sizeof(test<T>(0)) == sizeof(yes_type);
+#else
+   static const bool value = !has_boost_move_no_copy_constructor_or_assign_type<T>::value;
+#endif
+};
+
+//////////////////////////////////////
+//       is_trivially_destructible
+//////////////////////////////////////
+template<class T>
+struct is_trivially_destructible
+{  static const bool value = BOOST_MOVE_IS_TRIVIALLY_DESTRUCTIBLE(T); };
+
+//////////////////////////////////////
+//       is_trivially_default_constructible
+//////////////////////////////////////
+template<class T>
+struct is_trivially_default_constructible
+{  static const bool value = BOOST_MOVE_IS_TRIVIALLY_DEFAULT_CONSTRUCTIBLE(T); };
+
+//////////////////////////////////////
+//       is_trivially_copy_constructible
+//////////////////////////////////////
+template<class T>
+struct is_trivially_copy_constructible
+{
+   //In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with
+   //deleted copy constructors so make sure the type is copy constructible.
+   static const bool value = ::boost::move_detail::is_pod<T>::value ||
+                             ( ::boost::move_detail::is_copy_constructible<T>::value &&
+                               BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) );
+};
+
+//////////////////////////////////////
+//       is_trivially_move_constructible
+//////////////////////////////////////
+template<class T>
+struct is_trivially_move_constructible
+{  static const bool value = BOOST_MOVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE(T); };
+
+//////////////////////////////////////
+//       is_trivially_copy_assignable
+//////////////////////////////////////
+template<class T>
+struct is_trivially_copy_assignable
+{
+   //In several compilers BOOST_MOVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE return true even with
+   //deleted copy constructors so make sure the type is copy constructible.
+   static const bool value = ::boost::move_detail::is_pod<T>::value ||
+                             ( ::boost::move_detail::is_copy_assignable<T>::value &&
+                               BOOST_MOVE_IS_TRIVIALLY_COPY_ASSIGNABLE(T) );
+};
+
+//////////////////////////////////////
+//       is_trivially_move_assignable
+//////////////////////////////////////
+template<class T>
+struct is_trivially_move_assignable
+{  static const bool value = BOOST_MOVE_IS_TRIVIALLY_MOVE_ASSIGNABLE(T);  };
+
+//////////////////////////////////////
+//       is_nothrow_default_constructible
+//////////////////////////////////////
+template<class T>
+struct is_nothrow_default_constructible
+   : is_pod<T>
+{  static const bool value = BOOST_MOVE_IS_NOTHROW_DEFAULT_CONSTRUCTIBLE(T);  };
+
+//////////////////////////////////////
+//    is_nothrow_copy_constructible
+//////////////////////////////////////
+template<class T>
+struct is_nothrow_copy_constructible
+{  static const bool value = BOOST_MOVE_IS_NOTHROW_COPY_CONSTRUCTIBLE(T);  };
+
+//////////////////////////////////////
+//    is_nothrow_move_constructible
+//////////////////////////////////////
+template<class T>
+struct is_nothrow_move_constructible
+{  static const bool value = BOOST_MOVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE(T);  };
+
+//////////////////////////////////////
+//       is_nothrow_copy_assignable
+//////////////////////////////////////
+template<class T>
+struct is_nothrow_copy_assignable
+{  static const bool value = BOOST_MOVE_IS_NOTHROW_COPY_ASSIGNABLE(T);  };
+
+//////////////////////////////////////
+//    is_nothrow_move_assignable
+//////////////////////////////////////
+template<class T>
+struct is_nothrow_move_assignable
+{  static const bool value = BOOST_MOVE_IS_NOTHROW_MOVE_ASSIGNABLE(T);  };
+
+//////////////////////////////////////
+//    is_nothrow_swappable
+//////////////////////////////////////
+template<class T>
+struct is_nothrow_swappable
+{
+   static const bool value = is_empty<T>::value || is_pod<T>::value;
+};
+
+//////////////////////////////////////
+//       alignment_of
+//////////////////////////////////////
+template <typename T>
+struct alignment_of_hack
+{
+   T t1;
+   char c;
+   T t2;
+   alignment_of_hack();
+};
+
+template <unsigned A, unsigned S>
+struct alignment_logic
+{  static const std::size_t value = A < S ? A : S; };
+
+template< typename T >
+struct alignment_of_impl
+#if defined(BOOST_MSVC) && (BOOST_MSVC >= 1400)
+    // With MSVC both the native __alignof operator
+    // and our own logic gets things wrong from time to time :-(
+    // Using a combination of the two seems to make the most of a bad job:
+   : alignment_logic< sizeof(alignment_of_hack<T>) - 2*sizeof(T), __alignof(T)>
+{};
+#elif !defined(BOOST_MOVE_ALIGNMENT_OF)
+   : alignment_logic< sizeof(alignment_of_hack<T>) - 2*sizeof(T), sizeof(T)>
+{};
+#else
+{  static const std::size_t value = BOOST_MOVE_ALIGNMENT_OF(T);  };
+#endif
+
+template< typename T >
+struct alignment_of
+   : alignment_of_impl<T>
+{};
+
+class alignment_dummy;
+typedef void (*function_ptr)();
+typedef int (alignment_dummy::*member_ptr);
+typedef int (alignment_dummy::*member_function_ptr)();
+struct alignment_struct
+{  long double dummy[4];  };
+
+/////////////////////////////
+//    max_align_t
+/////////////////////////////
+//This is not standard, but should work with all compilers
+union max_align
+{
+   char        char_;
+   short       short_;
+   int         int_;
+   long        long_;
+   #ifdef BOOST_HAS_LONG_LONG
+   ::boost::long_long_type   long_long_;
+   #endif
+   float       float_;
+   double      double_;
+   void *      void_ptr_;
+   long double long_double_[4];
+   alignment_dummy *unknown_class_ptr_;
+   function_ptr function_ptr_;
+   member_function_ptr member_function_ptr_;
+   alignment_struct alignment_struct_;
+};
+
+typedef union max_align max_align_t;
+
+/////////////////////////////
+//    aligned_storage
+/////////////////////////////
+
+#if !defined(BOOST_NO_ALIGNMENT)
+
+template<std::size_t Len, std::size_t Align>
+struct aligned_storage_impl;
+
+#define BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(A)\
+template<std::size_t Len>\
+struct BOOST_ALIGNMENT(A) aligned_storage_impl<Len, A>\
+{\
+   char dummy[Len];\
+   typedef aligned_storage_impl<Len, A> type;\
+};\
+//
+
+//Up to 4K alignment (typical page size)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x1)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x2)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x4)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x8)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x10)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x20)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x40)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x80)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x100)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x200)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x400)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x800)
+BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT(0x1000)
+
+#undef BOOST_MOVE_ALIGNED_STORAGE_WITH_BOOST_ALIGNMENT
+
+#else //BOOST_NO_ALIGNMENT
+
+template<class T, std::size_t Len>
+union aligned_union
+{
+   T aligner;
+   char dummy[Len];
+};
+
+template<std::size_t Len, std::size_t Align, class T, bool Ok>
+struct aligned_next;
+
+template<std::size_t Len, std::size_t Align, class T>
+struct aligned_next<Len, Align, T, true>
+{
+   BOOST_STATIC_ASSERT((alignment_of<T>::value == Align));
+   typedef aligned_union<T, Len> type;
+};
+
+//End of search defaults to max_align_t
+template<std::size_t Len, std::size_t Align>
+struct aligned_next<Len, Align, max_align_t, false>
+{	typedef aligned_union<max_align_t, Len> type;   };
+
+//Now define a search list through types
+#define BOOST_MOVE_ALIGNED_NEXT_STEP(TYPE, NEXT_TYPE)\
+   template<std::size_t Len, std::size_t Align>\
+   struct aligned_next<Len, Align, TYPE, false>\
+      : aligned_next<Len, Align, NEXT_TYPE, Align == alignment_of<NEXT_TYPE>::value>\
+   {};\
+   //
+   BOOST_MOVE_ALIGNED_NEXT_STEP(long double, max_align_t)
+   BOOST_MOVE_ALIGNED_NEXT_STEP(double, long double)
+   #ifdef BOOST_HAS_LONG_LONG
+      BOOST_MOVE_ALIGNED_NEXT_STEP(::boost::long_long_type, double)
+      BOOST_MOVE_ALIGNED_NEXT_STEP(long, ::boost::long_long_type)
+   #else
+      BOOST_MOVE_ALIGNED_NEXT_STEP(long, double)
+   #endif
+   BOOST_MOVE_ALIGNED_NEXT_STEP(int, long)
+   BOOST_MOVE_ALIGNED_NEXT_STEP(short, int)
+   BOOST_MOVE_ALIGNED_NEXT_STEP(char, short)
+#undef BOOST_MOVE_ALIGNED_NEXT_STEP
+
+template<std::size_t Len, std::size_t Align>
+struct aligned_storage_impl
+   : aligned_next<Len, Align, char, Align == alignment_of<char>::value>
+{};
+
+#endif
+
+template<std::size_t Len, std::size_t Align = alignment_of<max_align_t>::value>
+struct aligned_storage
+{
+   //Sanity checks for input parameters
+   BOOST_STATIC_ASSERT(Align > 0);
+
+   //Sanity checks for output type
+   typedef typename aligned_storage_impl<Len ? Len : 1, Align>::type type;
+   static const std::size_t value = alignment_of<type>::value;
+   BOOST_STATIC_ASSERT(value >= Align);
+   BOOST_STATIC_ASSERT((value % Align) == 0);
+
+   //Just in case someone instantiates aligned_storage
+   //instead of aligned_storage::type (typical error).
+   private:
+   aligned_storage();
+};
+
+}  //namespace move_detail {
+}  //namespace boost {
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif   //#ifndef BOOST_MOVE_DETAIL_TYPE_TRAITS_HPP
diff --git a/third_party/boost/boost/move/detail/workaround.hpp b/third_party/boost/boost/move/detail/workaround.hpp
new file mode 100644
index 0000000..b3f81b1
--- /dev/null
+++ b/third_party/boost/boost/move/detail/workaround.hpp
@@ -0,0 +1,55 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/interprocess for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+#ifndef BOOST_MOVE_DETAIL_WORKAROUND_HPP
+#define BOOST_MOVE_DETAIL_WORKAROUND_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#if    !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+   #define BOOST_MOVE_PERFECT_FORWARDING
+#endif
+
+#if defined(__has_feature)
+   #define BOOST_MOVE_HAS_FEATURE __has_feature
+#else
+   #define BOOST_MOVE_HAS_FEATURE(x) 0
+#endif
+
+#if BOOST_MOVE_HAS_FEATURE(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+   #define BOOST_MOVE_ADDRESS_SANITIZER_ON
+#endif
+
+//Macros for documentation purposes. For code, expands to the argument
+#define BOOST_MOVE_IMPDEF(TYPE) TYPE
+#define BOOST_MOVE_SEEDOC(TYPE) TYPE
+#define BOOST_MOVE_DOC0PTR(TYPE) TYPE
+#define BOOST_MOVE_DOC1ST(TYPE1, TYPE2) TYPE2
+#define BOOST_MOVE_I ,
+#define BOOST_MOVE_DOCIGN(T1) T1
+
+#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 5) && !defined(__clang__)
+   //Pre-standard rvalue binding rules
+   #define BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+#elif defined(_MSC_VER) && (_MSC_VER == 1600)
+   //Standard rvalue binding rules but with some bugs
+   #define BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
+   #define BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG
+#elif defined(_MSC_VER) && (_MSC_VER == 1700)
+   #define BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG
+#endif
+
+#endif   //#ifndef BOOST_MOVE_DETAIL_WORKAROUND_HPP
diff --git a/third_party/boost/boost/move/iterator.hpp b/third_party/boost/boost/move/iterator.hpp
new file mode 100644
index 0000000..1b39e26
--- /dev/null
+++ b/third_party/boost/boost/move/iterator.hpp
@@ -0,0 +1,312 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_ITERATOR_HPP
+#define BOOST_MOVE_ITERATOR_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/detail/iterator_traits.hpp>
+#include <boost/move/utility_core.hpp>
+
+namespace boost {
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                            move_iterator
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! Class template move_iterator is an iterator adaptor with the same behavior
+//! as the underlying iterator except that its dereference operator implicitly
+//! converts the value returned by the underlying iterator's dereference operator
+//! to an rvalue reference. Some generic algorithms can be called with move
+//! iterators to replace copying with moving.
+template <class It>
+class move_iterator
+{
+   public:
+   typedef It                                                              iterator_type;
+   typedef typename boost::movelib::iterator_traits<iterator_type>::value_type        value_type;
+   #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
+   typedef value_type &&                                                   reference;
+   #else
+   typedef typename ::boost::move_detail::if_
+      < ::boost::has_move_emulation_enabled<value_type>
+      , ::boost::rv<value_type>&
+      , value_type & >::type                                               reference;
+   #endif
+   typedef It                                                              pointer;
+   typedef typename boost::movelib::iterator_traits<iterator_type>::difference_type   difference_type;
+   typedef typename boost::movelib::iterator_traits<iterator_type>::iterator_category iterator_category;
+
+   move_iterator()
+   {}
+
+   explicit move_iterator(It i)
+      :  m_it(i)
+   {}
+
+   template <class U>
+   move_iterator(const move_iterator<U>& u)
+      :  m_it(u.base())
+   {}
+
+   iterator_type base() const
+   {  return m_it;   }
+
+   reference operator*() const
+   {
+      #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
+      return *m_it;
+      #else
+      return ::boost::move(*m_it);
+      #endif
+   }
+
+   pointer   operator->() const
+   {  return m_it;   }
+
+   move_iterator& operator++()
+   {  ++m_it; return *this;   }
+
+   move_iterator<iterator_type>  operator++(int)
+   {  move_iterator<iterator_type> tmp(*this); ++(*this); return tmp;   }
+
+   move_iterator& operator--()
+   {  --m_it; return *this;   }
+
+   move_iterator<iterator_type>  operator--(int)
+   {  move_iterator<iterator_type> tmp(*this); --(*this); return tmp;   }
+
+   move_iterator<iterator_type>  operator+ (difference_type n) const
+   {  return move_iterator<iterator_type>(m_it + n);  }
+
+   move_iterator& operator+=(difference_type n)
+   {  m_it += n; return *this;   }
+
+   move_iterator<iterator_type>  operator- (difference_type n) const
+   {  return move_iterator<iterator_type>(m_it - n);  }
+
+   move_iterator& operator-=(difference_type n)
+   {  m_it -= n; return *this;   }
+
+   reference operator[](difference_type n) const
+   {
+      #if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
+      return m_it[n];
+      #else
+      return ::boost::move(m_it[n]);
+      #endif
+   }
+
+   friend bool operator==(const move_iterator& x, const move_iterator& y)
+   {  return x.base() == y.base();  }
+
+   friend bool operator!=(const move_iterator& x, const move_iterator& y)
+   {  return x.base() != y.base();  }
+
+   friend bool operator< (const move_iterator& x, const move_iterator& y)
+   {  return x.base() < y.base();   }
+
+   friend bool operator<=(const move_iterator& x, const move_iterator& y)
+   {  return x.base() <= y.base();  }
+
+   friend bool operator> (const move_iterator& x, const move_iterator& y)
+   {  return x.base() > y.base();  }
+
+   friend bool operator>=(const move_iterator& x, const move_iterator& y)
+   {  return x.base() >= y.base();  }
+
+   friend difference_type operator-(const move_iterator& x, const move_iterator& y)
+   {  return x.base() - y.base();   }
+
+   friend move_iterator operator+(difference_type n, const move_iterator& x)
+   {  return move_iterator(x.base() + n);   }
+
+   private:
+   It m_it;
+};
+
+//is_move_iterator
+namespace move_detail {
+
+template <class I>
+struct is_move_iterator
+{
+   static const bool value = false;
+};
+
+template <class I>
+struct is_move_iterator< ::boost::move_iterator<I> >
+{
+   static const bool value = true;
+};
+
+}  //namespace move_detail {
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                            move_iterator
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//!
+//! <b>Returns</b>: move_iterator<It>(i).
+template<class It>
+inline move_iterator<It> make_move_iterator(const It &it)
+{  return move_iterator<It>(it); }
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         back_move_insert_iterator
+//
+//////////////////////////////////////////////////////////////////////////////
+
+
+//! A move insert iterator that move constructs elements at the
+//! back of a container
+template <typename C> // C models Container
+class back_move_insert_iterator
+{
+   C* container_m;
+
+   public:
+   typedef C                           container_type;
+   typedef typename C::value_type      value_type;
+   typedef typename C::reference       reference;
+   typedef typename C::pointer         pointer;
+   typedef typename C::difference_type difference_type;
+   typedef std::output_iterator_tag    iterator_category;
+
+   explicit back_move_insert_iterator(C& x) : container_m(&x) { }
+
+   back_move_insert_iterator& operator=(reference x)
+   { container_m->push_back(boost::move(x)); return *this; }
+
+   back_move_insert_iterator& operator=(BOOST_RV_REF(value_type) x)
+   {  reference rx = x; return this->operator=(rx);  }
+
+   back_move_insert_iterator& operator*()     { return *this; }
+   back_move_insert_iterator& operator++()    { return *this; }
+   back_move_insert_iterator& operator++(int) { return *this; }
+};
+
+//!
+//! <b>Returns</b>: back_move_insert_iterator<C>(x).
+template <typename C> // C models Container
+inline back_move_insert_iterator<C> back_move_inserter(C& x)
+{
+   return back_move_insert_iterator<C>(x);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         front_move_insert_iterator
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! A move insert iterator that move constructs elements int the
+//! front of a container
+template <typename C> // C models Container
+class front_move_insert_iterator
+{
+   C* container_m;
+
+public:
+   typedef C                           container_type;
+   typedef typename C::value_type      value_type;
+   typedef typename C::reference       reference;
+   typedef typename C::pointer         pointer;
+   typedef typename C::difference_type difference_type;
+   typedef std::output_iterator_tag    iterator_category;
+
+   explicit front_move_insert_iterator(C& x) : container_m(&x) { }
+
+   front_move_insert_iterator& operator=(reference x)
+   { container_m->push_front(boost::move(x)); return *this; }
+
+   front_move_insert_iterator& operator=(BOOST_RV_REF(value_type) x)
+   {  reference rx = x; return this->operator=(rx);  }
+
+   front_move_insert_iterator& operator*()     { return *this; }
+   front_move_insert_iterator& operator++()    { return *this; }
+   front_move_insert_iterator& operator++(int) { return *this; }
+};
+
+//!
+//! <b>Returns</b>: front_move_insert_iterator<C>(x).
+template <typename C> // C models Container
+inline front_move_insert_iterator<C> front_move_inserter(C& x)
+{
+   return front_move_insert_iterator<C>(x);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//                         insert_move_iterator
+//
+//////////////////////////////////////////////////////////////////////////////
+template <typename C> // C models Container
+class move_insert_iterator
+{
+   C* container_m;
+   typename C::iterator pos_;
+
+   public:
+   typedef C                           container_type;
+   typedef typename C::value_type      value_type;
+   typedef typename C::reference       reference;
+   typedef typename C::pointer         pointer;
+   typedef typename C::difference_type difference_type;
+   typedef std::output_iterator_tag    iterator_category;
+
+   explicit move_insert_iterator(C& x, typename C::iterator pos)
+      : container_m(&x), pos_(pos)
+   {}
+
+   move_insert_iterator& operator=(reference x)
+   {
+      pos_ = container_m->insert(pos_, ::boost::move(x));
+      ++pos_;
+      return *this;
+   }
+
+   move_insert_iterator& operator=(BOOST_RV_REF(value_type) x)
+   {  reference rx = x; return this->operator=(rx);  }
+
+   move_insert_iterator& operator*()     { return *this; }
+   move_insert_iterator& operator++()    { return *this; }
+   move_insert_iterator& operator++(int) { return *this; }
+};
+
+//!
+//! <b>Returns</b>: move_insert_iterator<C>(x, it).
+template <typename C> // C models Container
+inline move_insert_iterator<C> move_inserter(C& x, typename C::iterator it)
+{
+   return move_insert_iterator<C>(x, it);
+}
+
+}  //namespace boost {
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_ITERATOR_HPP
diff --git a/third_party/boost/boost/move/move.hpp b/third_party/boost/boost/move/move.hpp
new file mode 100644
index 0000000..62dddbc
--- /dev/null
+++ b/third_party/boost/boost/move/move.hpp
@@ -0,0 +1,35 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright David Abrahams, Vicente Botet 2009.
+// (C) Copyright Ion Gaztanaga 2009-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+//! A general library header that includes
+//! the rest of top-level headers.
+
+#ifndef BOOST_MOVE_MOVE_HPP
+#define BOOST_MOVE_MOVE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/move/iterator.hpp>
+#include <boost/move/traits.hpp>
+#include <boost/move/algorithm.hpp>
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_MOVE_HPP
diff --git a/third_party/boost/boost/move/traits.hpp b/third_party/boost/boost/move/traits.hpp
new file mode 100644
index 0000000..b48b8f6
--- /dev/null
+++ b/third_party/boost/boost/move/traits.hpp
@@ -0,0 +1,77 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2009-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+
+#ifndef BOOST_MOVE_TRAITS_HPP
+#define BOOST_MOVE_TRAITS_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+#include <boost/move/core.hpp>
+#endif
+#include <boost/move/detail/meta_utils.hpp>
+#include <boost/move/detail/type_traits.hpp>
+
+namespace boost {
+
+//! If this trait yields to true
+//! (<i>has_trivial_destructor_after_move &lt;T&gt;::value == true</i>)
+//! means that if T is used as argument of a move construction/assignment,
+//! there is no need to call T's destructor.
+//! This optimization tipically is used to improve containers' performance.
+//!
+//! By default this trait is true if the type has trivial destructor,
+//! every class should specialize this trait if it wants to improve performance
+//! when inserted in containers.
+template <class T>
+struct has_trivial_destructor_after_move
+   : ::boost::move_detail::is_trivially_destructible<T>
+{};
+
+//! By default this traits returns
+//! <pre>boost::is_nothrow_move_constructible<T>::value && boost::is_nothrow_move_assignable<T>::value </pre>.
+//! Classes with non-throwing move constructor
+//! and assignment can specialize this trait to obtain some performance improvements.
+template <class T>
+struct has_nothrow_move
+{
+   static const bool value = boost::move_detail::is_nothrow_move_constructible<T>::value &&
+                             boost::move_detail::is_nothrow_move_assignable<T>::value;
+};
+
+namespace move_detail {
+
+template <class T>
+struct is_nothrow_move_constructible_or_uncopyable
+{
+   //The standard requires is_nothrow_move_constructible for move_if_noexcept
+   //but a user (usually in C++03) might specialize has_nothrow_move which includes it
+   static const bool value = is_nothrow_move_constructible<T>::value ||
+                             has_nothrow_move<T>::value ||
+                            !is_copy_constructible<T>::value;
+};
+
+}  //move_detail {
+}  //namespace boost {
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_TRAITS_HPP
diff --git a/third_party/boost/boost/move/utility.hpp b/third_party/boost/boost/move/utility.hpp
new file mode 100644
index 0000000..8f9c20b
--- /dev/null
+++ b/third_party/boost/boost/move/utility.hpp
@@ -0,0 +1,149 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+//! This header includes core utilities from <tt><boost/move/utility_core.hpp></tt> and defines
+//! some more advanced utilities such as:
+
+#ifndef BOOST_MOVE_MOVE_UTILITY_HPP
+#define BOOST_MOVE_MOVE_UTILITY_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/utility_core.hpp>
+#include <boost/move/traits.hpp>
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   namespace boost {
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                            move_if_noexcept()
+   //
+   //////////////////////////////////////////////////////////////////////////////
+
+   template <class T>
+   inline typename ::boost::move_detail::enable_if_c
+      < enable_move_utility_emulation<T>::value && !has_move_emulation_enabled<T>::value
+      , typename ::boost::move_detail::add_const<T>::type &
+      >::type
+         move_if_noexcept(T& x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   template <class T>
+   inline typename ::boost::move_detail::enable_if_c
+      < enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value
+            && ::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value, rv<T>&>::type
+         move_if_noexcept(T& x) BOOST_NOEXCEPT
+   {
+      return *static_cast<rv<T>* >(::boost::move_detail::addressof(x));
+   }
+
+   template <class T>
+   inline typename ::boost::move_detail::enable_if_c
+      < enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value
+            && ::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value
+      , rv<T>&
+      >::type
+         move_if_noexcept(rv<T>& x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   template <class T>
+   inline typename ::boost::move_detail::enable_if_c
+      < enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value
+            && !::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value
+      , typename ::boost::move_detail::add_const<T>::type &
+      >::type
+         move_if_noexcept(T& x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   template <class T>
+   inline typename ::boost::move_detail::enable_if_c
+      < enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value
+            && !::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value
+      , typename ::boost::move_detail::add_const<T>::type &
+      >::type
+         move_if_noexcept(rv<T>& x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   }  //namespace boost
+
+#else    //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   #if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
+      #include <utility>
+
+      namespace boost{
+
+      using ::std::move_if_noexcept;
+
+      }  //namespace boost
+
+   #else //!BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
+
+      namespace boost {
+
+      //////////////////////////////////////////////////////////////////////////////
+      //
+      //                            move_if_noexcept()
+      //
+      //////////////////////////////////////////////////////////////////////////////
+      #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
+         //! This function provides a way to convert a reference into a rvalue reference
+         //! in compilers with rvalue references. For other compilers converts T & into
+         //! <i>::boost::rv<T> &</i> so that move emulation is activated. Reference
+         //! would be converted to rvalue reference only if input type is nothrow move
+         //! constructible or if it has no copy constructor. In all other cases const
+         //! reference would be returned
+         template <class T>
+         rvalue_reference_or_const_lvalue_reference move_if_noexcept(input_reference) noexcept;
+
+      #else //BOOST_MOVE_DOXYGEN_INVOKED
+
+         template <class T>
+         typename ::boost::move_detail::enable_if_c
+            < ::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value, T&&>::type
+               move_if_noexcept(T& x) BOOST_NOEXCEPT
+         {  return ::boost::move(x);   }
+
+         template <class T>
+         typename ::boost::move_detail::enable_if_c
+            < !::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value, const T&>::type
+               move_if_noexcept(T& x) BOOST_NOEXCEPT
+         {  return x;  }
+
+      #endif //BOOST_MOVE_DOXYGEN_INVOKED
+
+      }  //namespace boost {
+
+   #endif   //#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
+
+#endif   //BOOST_NO_CXX11_RVALUE_REFERENCES
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_MOVE_UTILITY_HPP
diff --git a/third_party/boost/boost/move/utility_core.hpp b/third_party/boost/boost/move/utility_core.hpp
new file mode 100644
index 0000000..1b932c3
--- /dev/null
+++ b/third_party/boost/boost/move/utility_core.hpp
@@ -0,0 +1,317 @@
+//////////////////////////////////////////////////////////////////////////////
+//
+// (C) Copyright Ion Gaztanaga 2012-2012.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/move for documentation.
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//! \file
+//! This header defines core utilities to ease the development
+//! of move-aware functions. This header minimizes dependencies
+//! from other libraries.
+
+#ifndef BOOST_MOVE_MOVE_UTILITY_CORE_HPP
+#define BOOST_MOVE_MOVE_UTILITY_CORE_HPP
+
+#ifndef BOOST_CONFIG_HPP
+#  include <boost/config.hpp>
+#endif
+#
+#if defined(BOOST_HAS_PRAGMA_ONCE)
+#  pragma once
+#endif
+
+#include <boost/move/detail/config_begin.hpp>
+#include <boost/move/core.hpp>
+#include <boost/move/detail/meta_utils.hpp>
+#include <boost/static_assert.hpp>
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   namespace boost {
+
+   template<class T>
+   struct enable_move_utility_emulation
+   {
+      static const bool value = true;
+   };
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                            move()
+   //
+   //////////////////////////////////////////////////////////////////////////////
+
+   template <class T>
+   inline typename ::boost::move_detail::enable_if_and
+      < T &
+      , enable_move_utility_emulation<T>
+      , has_move_emulation_disabled<T>
+      >::type
+         move(T& x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   template <class T>
+   inline typename ::boost::move_detail::enable_if_and
+      < rv<T>&
+      , enable_move_utility_emulation<T>
+      , has_move_emulation_enabled<T>
+      >::type
+         move(T& x) BOOST_NOEXCEPT
+   {
+      return *BOOST_MOVE_TO_RV_CAST(::boost::rv<T>*, ::boost::move_detail::addressof(x) );
+   }
+
+   template <class T>
+   inline typename ::boost::move_detail::enable_if_and
+      < rv<T>&
+      , enable_move_utility_emulation<T>
+      , has_move_emulation_enabled<T>
+      >::type
+         move(rv<T>& x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                            forward()
+   //
+   //////////////////////////////////////////////////////////////////////////////
+
+   template <class T>
+   inline typename ::boost::move_detail::enable_if_and
+      < T &
+      , enable_move_utility_emulation<T>
+      , ::boost::move_detail::is_rv<T>
+      >::type
+         forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
+   {
+      return const_cast<T&>(x);
+   }
+
+   template <class T>
+   inline typename ::boost::move_detail::enable_if_and
+      < const T &
+      , enable_move_utility_emulation<T>
+      , ::boost::move_detail::is_not_rv<T>
+      >::type
+         forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   //////////////////////////////////////////////////////////////////////////////
+   //
+   //                        move_if_not_lvalue_reference()
+   //
+   //////////////////////////////////////////////////////////////////////////////
+
+   template <class T>
+   inline typename ::boost::move_detail::enable_if_and
+      < T &
+      , enable_move_utility_emulation<T>
+      , ::boost::move_detail::is_rv<T>
+      >::type
+         move_if_not_lvalue_reference(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
+   {
+      return const_cast<T&>(x);
+   }
+
+   template <class T>
+   inline typename ::boost::move_detail::enable_if_and
+      < typename ::boost::move_detail::add_lvalue_reference<T>::type
+      , enable_move_utility_emulation<T>
+      , ::boost::move_detail::is_not_rv<T>
+      , ::boost::move_detail::or_
+         < ::boost::move_detail::is_lvalue_reference<T>
+         , has_move_emulation_disabled<T>
+         >
+      >::type
+         move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type &x) BOOST_NOEXCEPT
+   {
+      return x;
+   }
+
+   template <class T>
+   inline typename ::boost::move_detail::enable_if_and
+      < rv<T>&
+      , enable_move_utility_emulation<T>
+      , ::boost::move_detail::is_not_rv<T>
+      , ::boost::move_detail::and_
+         < ::boost::move_detail::not_< ::boost::move_detail::is_lvalue_reference<T> >
+         , has_move_emulation_enabled<T>
+         >
+      >::type
+         move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type &x) BOOST_NOEXCEPT
+   {
+      return move(x);
+   }
+
+   }  //namespace boost
+
+#else    //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+   #if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
+      #include <utility>
+
+      namespace boost{
+
+      using ::std::move;
+      using ::std::forward;
+
+      }  //namespace boost
+
+   #else //!BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
+
+      namespace boost {
+
+      //! This trait's internal boolean `value` is false in compilers with rvalue references
+      //! and true in compilers without rvalue references.
+      //!
+      //! A user can specialize this trait for a type T to false to SFINAE out `move` and `forward`
+      //! so that the user can define a different move emulation for that type in namespace boost
+      //! (e.g. another Boost library for its types) and avoid any overload ambiguity.
+      template<class T>
+      struct enable_move_utility_emulation
+      {
+         static const bool value = false;
+      };
+
+      //////////////////////////////////////////////////////////////////////////////
+      //
+      //                                  move
+      //
+      //////////////////////////////////////////////////////////////////////////////
+
+      #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
+         //! This function provides a way to convert a reference into a rvalue reference
+         //! in compilers with rvalue references. For other compilers if `T` is Boost.Move
+         //! enabled type then it converts `T&` into <tt>::boost::rv<T> &</tt> so that
+         //! move emulation is activated, else it returns `T &`.
+         template <class T>
+         rvalue_reference move(input_reference) noexcept;
+
+      #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
+
+         //Old move approach, lvalues could bind to rvalue references
+         template <class T>
+         inline typename ::boost::move_detail::remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
+         {  return t;   }
+
+      #else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+
+         template <class T>
+         inline typename ::boost::move_detail::remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
+         { return static_cast<typename ::boost::move_detail::remove_reference<T>::type &&>(t); }
+
+      #endif   //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+
+      //////////////////////////////////////////////////////////////////////////////
+      //
+      //                                  forward
+      //
+      //////////////////////////////////////////////////////////////////////////////
+
+
+      #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
+         //! This function provides limited form of forwarding that is usually enough for
+         //! in-place construction and avoids the exponential overloading for
+         //! achieve the limited forwarding in C++03.
+         //!
+         //! For compilers with rvalue references this function provides perfect forwarding.
+         //!
+         //! Otherwise:
+         //! * If input_reference binds to const ::boost::rv<T> & then it output_reference is
+         //!   ::boost::rv<T> &
+         //!
+         //! * Else, output_reference is equal to input_reference.
+         template <class T> output_reference forward(input_reference) noexcept;
+      #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
+
+         //Old move approach, lvalues could bind to rvalue references
+
+         template <class T>
+         inline T&& forward(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT
+         {  return t;   }
+
+      #else //Old move
+
+         template <class T>
+         inline T&& forward(typename ::boost::move_detail::remove_reference<T>::type& t) BOOST_NOEXCEPT
+         {  return static_cast<T&&>(t);   }
+
+         template <class T>
+         inline T&& forward(typename ::boost::move_detail::remove_reference<T>::type&& t) BOOST_NOEXCEPT
+         {
+            //"boost::forward<T> error: 'T' is a lvalue reference, can't forward as rvalue.";
+            BOOST_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference<T>::value);
+            return static_cast<T&&>(t);
+         }
+
+      #endif   //BOOST_MOVE_DOXYGEN_INVOKED
+
+      //////////////////////////////////////////////////////////////////////////////
+      //
+      //                         move_if_not_lvalue_reference
+      //
+      //////////////////////////////////////////////////////////////////////////////
+
+
+      #if defined(BOOST_MOVE_DOXYGEN_INVOKED)
+         //! <b>Effects</b>: Calls `boost::move` if `input_reference` is not a lvalue reference.
+         //!   Otherwise returns the reference
+         template <class T> output_reference move_if_not_lvalue_reference(input_reference) noexcept;
+      #elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
+
+         //Old move approach, lvalues could bind to rvalue references
+
+         template <class T>
+         inline T&& move_if_not_lvalue_reference(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT
+         {  return t;   }
+
+      #else //Old move
+
+         template <class T>
+         inline T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type& t) BOOST_NOEXCEPT
+         {  return static_cast<T&&>(t);   }
+
+         template <class T>
+         inline T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type&& t) BOOST_NOEXCEPT
+         {
+            //"boost::forward<T> error: 'T' is a lvalue reference, can't forward as rvalue.";
+            BOOST_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference<T>::value);
+            return static_cast<T&&>(t);
+         }
+
+      #endif   //BOOST_MOVE_DOXYGEN_INVOKED
+
+      }  //namespace boost {
+
+   #endif   //#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
+
+#endif   //BOOST_NO_CXX11_RVALUE_REFERENCES
+
+#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+namespace boost{
+namespace move_detail{
+
+template <typename T>
+typename boost::move_detail::add_rvalue_reference<T>::type declval();
+
+}  //namespace move_detail{
+}  //namespace boost{
+
+#endif   //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
+
+
+#include <boost/move/detail/config_end.hpp>
+
+#endif //#ifndef BOOST_MOVE_MOVE_UTILITY_CORE_HPP
diff --git a/third_party/boost/boost/mpl/O1_size.hpp b/third_party/boost/boost/mpl/O1_size.hpp
new file mode 100644
index 0000000..517276e
--- /dev/null
+++ b/third_party/boost/boost/mpl/O1_size.hpp
@@ -0,0 +1,40 @@
+
+#ifndef BOOST_MPL_O1_SIZE_HPP_INCLUDED
+#define BOOST_MPL_O1_SIZE_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/O1_size_fwd.hpp>
+#include <boost/mpl/sequence_tag.hpp>
+#include <boost/mpl/aux_/O1_size_impl.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost { namespace mpl {
+
+// returns sequence size if it's an O(1) operation; otherwise returns -1
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    >
+struct O1_size
+    : O1_size_impl< typename sequence_tag<Sequence>::type >
+        ::template apply< Sequence >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1, O1_size, (Sequence))
+};
+
+BOOST_MPL_AUX_NA_SPEC(1, O1_size)
+
+}}
+
+#endif // BOOST_MPL_O1_SIZE_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/O1_size_fwd.hpp b/third_party/boost/boost/mpl/O1_size_fwd.hpp
new file mode 100644
index 0000000..bba2897
--- /dev/null
+++ b/third_party/boost/boost/mpl/O1_size_fwd.hpp
@@ -0,0 +1,24 @@
+
+#ifndef BOOST_MPL_O1_SIZE_FWD_HPP_INCLUDED
+#define BOOST_MPL_O1_SIZE_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+namespace boost { namespace mpl {
+
+template< typename Tag > struct O1_size_impl;
+template< typename Sequence > struct O1_size;
+
+}}
+
+#endif // BOOST_MPL_O1_SIZE_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/advance.hpp b/third_party/boost/boost/mpl/advance.hpp
new file mode 100644
index 0000000..8cde024
--- /dev/null
+++ b/third_party/boost/boost/mpl/advance.hpp
@@ -0,0 +1,76 @@
+
+#ifndef BOOST_MPL_ADVANCE_HPP_INCLUDED
+#define BOOST_MPL_ADVANCE_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/advance_fwd.hpp>
+#include <boost/mpl/less.hpp>
+#include <boost/mpl/negate.hpp>
+#include <boost/mpl/long.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/tag.hpp>
+#include <boost/mpl/apply_wrap.hpp>
+#include <boost/mpl/aux_/advance_forward.hpp>
+#include <boost/mpl/aux_/advance_backward.hpp>
+#include <boost/mpl/aux_/value_wknd.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/nttp_decl.hpp>
+
+namespace boost { namespace mpl {
+
+// default implementation for forward/bidirectional iterators
+template< typename Tag >
+struct advance_impl
+{
+    template< typename Iterator, typename N > struct apply
+    {
+        typedef typename less< N,long_<0> >::type backward_;
+        typedef typename if_< backward_, negate<N>, N >::type offset_;
+
+        typedef typename if_<
+              backward_
+            , aux::advance_backward< BOOST_MPL_AUX_VALUE_WKND(offset_)::value >
+            , aux::advance_forward< BOOST_MPL_AUX_VALUE_WKND(offset_)::value >
+            >::type f_;
+
+        typedef typename apply_wrap1<f_,Iterator>::type type;
+    };
+};
+
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Iterator)
+    , typename BOOST_MPL_AUX_NA_PARAM(N)
+    >
+struct advance
+    : advance_impl< typename tag<Iterator>::type >
+        ::template apply<Iterator,N>
+{
+};
+
+template<
+      typename Iterator
+    , BOOST_MPL_AUX_NTTP_DECL(long, N)
+    >
+struct advance_c
+    : advance_impl< typename tag<Iterator>::type >
+        ::template apply<Iterator,long_<N> >
+{
+};
+
+BOOST_MPL_AUX_NA_SPEC(2, advance)
+
+}}
+
+#endif // BOOST_MPL_ADVANCE_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/advance_fwd.hpp b/third_party/boost/boost/mpl/advance_fwd.hpp
new file mode 100644
index 0000000..5bf75a1
--- /dev/null
+++ b/third_party/boost/boost/mpl/advance_fwd.hpp
@@ -0,0 +1,28 @@
+
+#ifndef BOOST_MPL_ADVANCE_FWD_HPP_INCLUDED
+#define BOOST_MPL_ADVANCE_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/common_name_wknd.hpp>
+
+namespace boost { namespace mpl {
+
+BOOST_MPL_AUX_COMMON_NAME_WKND(advance)
+
+template< typename Tag > struct advance_impl;
+template< typename Iterator, typename N > struct advance;
+
+}}
+
+#endif // BOOST_MPL_ADVANCE_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/always.hpp b/third_party/boost/boost/mpl/always.hpp
new file mode 100644
index 0000000..5863813
--- /dev/null
+++ b/third_party/boost/boost/mpl/always.hpp
@@ -0,0 +1,38 @@
+
+#ifndef BOOST_MPL_ALWAYS_HPP_INCLUDED
+#define BOOST_MPL_ALWAYS_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/preprocessor/default_params.hpp>
+#include <boost/mpl/aux_/na.hpp>
+#include <boost/mpl/aux_/arity_spec.hpp>
+
+namespace boost { namespace mpl {
+
+template< typename Value > struct always
+{
+    template<
+        BOOST_MPL_PP_DEFAULT_PARAMS(BOOST_MPL_LIMIT_METAFUNCTION_ARITY, typename T, na)
+        >
+    struct apply
+    {
+        typedef Value type;
+    };
+};
+
+BOOST_MPL_AUX_ARITY_SPEC(0, always)
+
+}}
+
+#endif // BOOST_MPL_ALWAYS_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/and.hpp b/third_party/boost/boost/mpl/and.hpp
new file mode 100644
index 0000000..6465ff0
--- /dev/null
+++ b/third_party/boost/boost/mpl/and.hpp
@@ -0,0 +1,60 @@
+
+#ifndef BOOST_MPL_AND_HPP_INCLUDED
+#define BOOST_MPL_AND_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   include <boost/mpl/bool.hpp>
+#   include <boost/mpl/aux_/nested_type_wknd.hpp>
+#   include <boost/mpl/aux_/na_spec.hpp>
+#   include <boost/mpl/aux_/lambda_support.hpp>
+
+// agurt, 19/may/04: workaround a conflict with <iso646.h> header's
+// 'or' and 'and' macros, see http://tinyurl.com/3et69; 'defined(and)'
+// has to be checked in a separate condition, otherwise GCC complains
+// about 'and' being an alternative token
+#if defined(_MSC_VER) && !defined(__clang__)
+#ifndef __GCCXML__
+#if defined(and)
+#   pragma push_macro("and")
+#   undef and
+#   define and(x)
+#endif
+#endif
+#endif
+
+#   define BOOST_MPL_PREPROCESSED_HEADER and.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#if defined(_MSC_VER) && !defined(__clang__)
+#ifndef __GCCXML__
+#if defined(and)
+#   pragma pop_macro("and")
+#endif
+#endif
+#endif
+
+#else
+
+#   define AUX778076_OP_NAME and_
+#   define AUX778076_OP_VALUE1 false
+#   define AUX778076_OP_VALUE2 true
+#   include <boost/mpl/aux_/logical_op.hpp>
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_AND_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/apply.hpp b/third_party/boost/boost/mpl/apply.hpp
new file mode 100644
index 0000000..06087ad
--- /dev/null
+++ b/third_party/boost/boost/mpl/apply.hpp
@@ -0,0 +1,229 @@
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+///// header body
+
+#ifndef BOOST_MPL_APPLY_HPP_INCLUDED
+#define BOOST_MPL_APPLY_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/apply_fwd.hpp>
+#   include <boost/mpl/apply_wrap.hpp>
+#   include <boost/mpl/placeholders.hpp>
+#   include <boost/mpl/lambda.hpp>
+#   include <boost/mpl/aux_/na.hpp>
+#   include <boost/mpl/aux_/lambda_support.hpp>
+#endif
+
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER apply.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   include <boost/mpl/limits/arity.hpp>
+#   include <boost/mpl/aux_/preprocessor/params.hpp>
+#   include <boost/mpl/aux_/preprocessor/default_params.hpp>
+#   include <boost/mpl/aux_/preprocessor/partial_spec_params.hpp>
+#   include <boost/mpl/aux_/preprocessor/enum.hpp>
+#   include <boost/mpl/aux_/config/lambda.hpp>
+#   include <boost/mpl/aux_/config/dtp.hpp>
+#   include <boost/mpl/aux_/nttp_decl.hpp>
+#   include <boost/mpl/aux_/config/eti.hpp>
+#   include <boost/mpl/aux_/config/msvc.hpp>
+#   include <boost/mpl/aux_/config/workaround.hpp>
+
+#   include <boost/preprocessor/comma_if.hpp>
+#   include <boost/preprocessor/inc.hpp>
+#   include <boost/preprocessor/iterate.hpp>
+#   include <boost/preprocessor/cat.hpp>
+
+namespace boost { namespace mpl {
+
+// local macros, #undef-ined at the end of the header
+#   define AUX778076_APPLY_PARAMS(param) \
+    BOOST_MPL_PP_PARAMS( \
+          BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
+        , param \
+        ) \
+    /**/
+
+#   define AUX778076_APPLY_DEF_PARAMS(param, value) \
+    BOOST_MPL_PP_DEFAULT_PARAMS( \
+          BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
+        , param \
+        , value \
+        ) \
+    /**/
+
+#   define AUX778076_APPLY_N_PARAMS(n, param) \
+    BOOST_MPL_PP_PARAMS(n, param) \
+    /**/
+
+#   define AUX778076_APPLY_N_COMMA_PARAMS(n, param) \
+    BOOST_PP_COMMA_IF(n) \
+    BOOST_MPL_PP_PARAMS(n, param) \
+    /**/
+
+#   define AUX778076_APPLY_N_PARTIAL_SPEC_PARAMS(n, param, def) \
+    BOOST_PP_COMMA_IF(n) \
+    BOOST_MPL_PP_PARTIAL_SPEC_PARAMS(n, param, def) \
+    /**/
+
+#   define AUX778076_APPLY_N_SPEC_PARAMS(n, param) \
+    BOOST_MPL_PP_ENUM(BOOST_PP_INC(n), param) \
+    /**/
+
+
+#define BOOST_PP_ITERATION_PARAMS_1 \
+    (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, <boost/mpl/apply.hpp>))
+#include BOOST_PP_ITERATE()
+
+#   if !defined(BOOST_MPL_CFG_NO_APPLY_TEMPLATE)
+// real C++ version is already taken care of
+#   if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+namespace aux {
+// apply_count_args
+#define AUX778076_COUNT_ARGS_PREFIX apply
+#define AUX778076_COUNT_ARGS_DEFAULT na
+#define AUX778076_COUNT_ARGS_ARITY BOOST_MPL_LIMIT_METAFUNCTION_ARITY
+#include <boost/mpl/aux_/count_args.hpp>
+}
+
+
+template<
+      typename F, AUX778076_APPLY_DEF_PARAMS(typename T, na)
+    >
+struct apply
+    : aux::apply_chooser<
+          aux::apply_count_args< AUX778076_APPLY_PARAMS(T) >::value
+        >::template result_< F, AUX778076_APPLY_PARAMS(T) >::type
+{
+};
+
+#   endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+#   endif // BOOST_MPL_CFG_NO_APPLY_TEMPLATE
+
+#   undef AUX778076_APPLY_N_SPEC_PARAMS
+#   undef AUX778076_APPLY_N_PARTIAL_SPEC_PARAMS
+#   undef AUX778076_APPLY_N_COMMA_PARAMS
+#   undef AUX778076_APPLY_N_PARAMS
+#   undef AUX778076_APPLY_DEF_PARAMS
+#   undef AUX778076_APPLY_PARAMS
+
+}}
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_APPLY_HPP_INCLUDED
+
+///// iteration, depth == 1
+
+// For gcc 4.4 compatability, we must include the
+// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
+#else // BOOST_PP_IS_ITERATING
+#if BOOST_PP_ITERATION_DEPTH() == 1
+
+#   define i_ BOOST_PP_FRAME_ITERATION(1)
+
+template<
+      typename F AUX778076_APPLY_N_COMMA_PARAMS(i_, typename T)
+    >
+struct BOOST_PP_CAT(apply,i_)
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+    : BOOST_PP_CAT(apply_wrap,i_)<
+          typename lambda<F>::type
+        AUX778076_APPLY_N_COMMA_PARAMS(i_, T)
+        >
+{
+#else
+{
+    typedef typename BOOST_PP_CAT(apply_wrap,i_)<
+          typename lambda<F>::type
+        AUX778076_APPLY_N_COMMA_PARAMS(i_, T)
+        >::type type;
+#endif
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(
+          BOOST_PP_INC(i_)
+        , BOOST_PP_CAT(apply,i_)
+        , (F AUX778076_APPLY_N_COMMA_PARAMS(i_,T))
+        )
+};
+
+
+#if defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
+/// workaround for ETI bug
+template<>
+struct BOOST_PP_CAT(apply,i_)<AUX778076_APPLY_N_SPEC_PARAMS(i_, int)>
+{
+    typedef int type;
+};
+#endif
+
+#   if !defined(BOOST_MPL_CFG_NO_APPLY_TEMPLATE)
+#   if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+#if i_ == BOOST_MPL_LIMIT_METAFUNCTION_ARITY
+/// primary template (not a specialization!)
+template<
+      typename F AUX778076_APPLY_N_COMMA_PARAMS(i_, typename T)
+    >
+struct apply
+    : BOOST_PP_CAT(apply,i_)< F AUX778076_APPLY_N_COMMA_PARAMS(i_, T) >
+{
+};
+#else
+template<
+      typename F AUX778076_APPLY_N_COMMA_PARAMS(i_, typename T)
+    >
+struct apply< F AUX778076_APPLY_N_PARTIAL_SPEC_PARAMS(i_, T, na) >
+    : BOOST_PP_CAT(apply,i_)< F AUX778076_APPLY_N_COMMA_PARAMS(i_, T) >
+{
+};
+#endif
+
+#   else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+#if !defined(BOOST_MPL_CFG_NO_APPLY_TEMPLATE)
+namespace aux {
+
+template<>
+struct apply_chooser<i_>
+{
+    template<
+          typename F, AUX778076_APPLY_PARAMS(typename T)
+        >
+    struct result_
+    {
+        typedef BOOST_PP_CAT(apply,i_)<
+              F AUX778076_APPLY_N_COMMA_PARAMS(i_, T)
+            > type;
+    };
+};
+
+} // namespace aux
+#endif
+
+#   endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+#   endif // BOOST_MPL_CFG_NO_APPLY_TEMPLATE
+
+#   undef i_
+
+#endif // BOOST_PP_ITERATION_DEPTH()
+#endif // BOOST_PP_IS_ITERATING
diff --git a/third_party/boost/boost/mpl/apply_fwd.hpp b/third_party/boost/boost/mpl/apply_fwd.hpp
new file mode 100644
index 0000000..dc66b1d
--- /dev/null
+++ b/third_party/boost/boost/mpl/apply_fwd.hpp
@@ -0,0 +1,107 @@
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+///// header body
+
+#ifndef BOOST_MPL_APPLY_FWD_HPP_INCLUDED
+#define BOOST_MPL_APPLY_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/aux_/na.hpp>
+#endif
+
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER apply_fwd.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   include <boost/mpl/limits/arity.hpp>
+#   include <boost/mpl/aux_/preprocessor/params.hpp>
+#   include <boost/mpl/aux_/preprocessor/default_params.hpp>
+#   include <boost/mpl/aux_/config/ctps.hpp>
+#   include <boost/mpl/aux_/nttp_decl.hpp>
+
+#   include <boost/preprocessor/comma_if.hpp>
+#   include <boost/preprocessor/iterate.hpp>
+#   include <boost/preprocessor/cat.hpp>
+
+// agurt, 15/jan/02: top-level 'apply' template gives an ICE on MSVC
+// (for known reasons)
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+#   define BOOST_MPL_CFG_NO_APPLY_TEMPLATE
+#endif
+
+namespace boost { namespace mpl {
+
+// local macro, #undef-ined at the end of the header
+#   define AUX778076_APPLY_DEF_PARAMS(param, value) \
+    BOOST_MPL_PP_DEFAULT_PARAMS( \
+          BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
+        , param \
+        , value \
+        ) \
+    /**/
+
+#   define AUX778076_APPLY_N_COMMA_PARAMS(n, param) \
+    BOOST_PP_COMMA_IF(n) \
+    BOOST_MPL_PP_PARAMS(n, param) \
+    /**/
+
+#   if !defined(BOOST_MPL_CFG_NO_APPLY_TEMPLATE)
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+// forward declaration
+template<
+      typename F, AUX778076_APPLY_DEF_PARAMS(typename T, na)
+    >
+struct apply;
+#else
+namespace aux {
+template< BOOST_AUX_NTTP_DECL(int, arity_) > struct apply_chooser;
+}
+#endif
+
+#   endif // BOOST_MPL_CFG_NO_APPLY_TEMPLATE
+
+#define BOOST_PP_ITERATION_PARAMS_1 \
+    (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, <boost/mpl/apply_fwd.hpp>))
+#include BOOST_PP_ITERATE()
+
+
+#   undef AUX778076_APPLY_N_COMMA_PARAMS
+#   undef AUX778076_APPLY_DEF_PARAMS
+
+}}
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_APPLY_FWD_HPP_INCLUDED
+
+///// iteration
+
+#else
+#define i_ BOOST_PP_FRAME_ITERATION(1)
+
+template<
+      typename F AUX778076_APPLY_N_COMMA_PARAMS(i_, typename T)
+    >
+struct BOOST_PP_CAT(apply,i_);
+
+#undef i_
+#endif // BOOST_PP_IS_ITERATING
diff --git a/third_party/boost/boost/mpl/apply_wrap.hpp b/third_party/boost/boost/mpl/apply_wrap.hpp
new file mode 100644
index 0000000..24ede22
--- /dev/null
+++ b/third_party/boost/boost/mpl/apply_wrap.hpp
@@ -0,0 +1,234 @@
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+///// header body
+
+#ifndef BOOST_MPL_APPLY_WRAP_HPP_INCLUDED
+#define BOOST_MPL_APPLY_WRAP_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2008
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/aux_/arity.hpp>
+#   include <boost/mpl/aux_/has_apply.hpp>
+#   include <boost/mpl/aux_/na.hpp>
+#   include <boost/mpl/aux_/msvc_never_true.hpp>
+#endif
+
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER apply_wrap.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   include <boost/mpl/limits/arity.hpp>
+#   include <boost/mpl/aux_/preprocessor/params.hpp>
+#   include <boost/mpl/aux_/preprocessor/enum.hpp>
+#   include <boost/mpl/aux_/preprocessor/add.hpp>
+#   include <boost/mpl/aux_/config/bcc.hpp>
+#   include <boost/mpl/aux_/config/ctps.hpp>
+#   include <boost/mpl/aux_/config/dtp.hpp>
+#   include <boost/mpl/aux_/config/eti.hpp>
+#   include <boost/mpl/aux_/config/msvc.hpp>
+#   include <boost/mpl/aux_/config/workaround.hpp>
+
+#   include <boost/preprocessor/comma_if.hpp>
+#   include <boost/preprocessor/logical/and.hpp>
+#   include <boost/preprocessor/inc.hpp>
+#   include <boost/preprocessor/iterate.hpp>
+
+
+namespace boost { namespace mpl {
+
+// local macros, #undef-ined at the end of the header
+#   define AUX778076_APPLY_WRAP_PARAMS(n, param) \
+    BOOST_MPL_PP_PARAMS(n, param) \
+    /**/
+
+#   define AUX778076_APPLY_WRAP_SPEC_PARAMS(n, param) \
+    BOOST_MPL_PP_ENUM(BOOST_PP_INC(n), param) \
+    /**/
+
+
+#define BOOST_PP_ITERATION_PARAMS_1 \
+    (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, <boost/mpl/apply_wrap.hpp>))
+#include BOOST_PP_ITERATE()
+
+
+#   undef AUX778076_APPLY_WRAP_SPEC_PARAMS
+#   undef AUX778076_APPLY_WRAP_PARAMS
+
+}}
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_APPLY_WRAP_HPP_INCLUDED
+
+///// iteration, depth == 1
+
+// For gcc 4.4 compatability, we must include the
+// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
+#else // BOOST_PP_IS_ITERATING
+#if BOOST_PP_ITERATION_DEPTH() == 1
+
+#   define i_ BOOST_PP_FRAME_ITERATION(1)
+
+#   if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+// MSVC version
+
+#define AUX778076_MSVC_DTW_NAME BOOST_PP_CAT(msvc_apply,i_)
+#define AUX778076_MSVC_DTW_ORIGINAL_NAME apply
+#define AUX778076_MSVC_DTW_ARITY i_
+#include <boost/mpl/aux_/msvc_dtw.hpp>
+
+template<
+      typename F BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, typename T)
+    >
+struct BOOST_PP_CAT(apply_wrap,i_)
+{
+    // Metafunction forwarding confuses vc6
+    typedef typename BOOST_PP_CAT(msvc_apply,i_)<F>::template result_<
+          AUX778076_APPLY_WRAP_PARAMS(i_, T)
+        >::type type;
+};
+
+#   elif defined(BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES)
+// MWCW/Borland version
+
+template<
+      int N, typename F BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, typename T)
+    >
+struct BOOST_PP_CAT(apply_wrap_impl,i_);
+
+#define BOOST_PP_ITERATION_PARAMS_2 \
+    (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY - i_, <boost/mpl/apply_wrap.hpp>))
+#include BOOST_PP_ITERATE()
+
+template<
+      typename F BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, typename T)
+    >
+struct BOOST_PP_CAT(apply_wrap,i_)
+    : BOOST_PP_CAT(apply_wrap_impl,i_)<
+          ::boost::mpl::aux::arity<F,i_>::value
+        , F
+        BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, T)
+        >::type
+{
+};
+
+#   else
+// ISO98 C++, with minor concession to vc7
+
+template<
+      typename F BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, typename T)
+#if i_ == 0
+    , typename has_apply_ = typename aux::has_apply<F>::type
+#endif
+    >
+struct BOOST_PP_CAT(apply_wrap,i_)
+// metafunction forwarding confuses MSVC 7.0
+#if !BOOST_WORKAROUND(BOOST_MSVC, == 1300)
+    : F::template apply< AUX778076_APPLY_WRAP_PARAMS(i_, T) >
+{
+#else
+{
+    typedef typename F::template apply<
+         AUX778076_APPLY_WRAP_PARAMS(i_, T)
+        >::type type;
+#endif
+};
+
+#if i_ == 0 && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+template< typename F >
+struct BOOST_PP_CAT(apply_wrap,i_)<F,true_>
+    : F::apply
+{
+};
+#endif
+
+#   endif // workarounds
+
+#if defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
+/// workaround for ETI bug
+template<>
+struct BOOST_PP_CAT(apply_wrap,i_)<AUX778076_APPLY_WRAP_SPEC_PARAMS(i_, int)>
+{
+    typedef int type;
+};
+#endif
+
+#   undef i_
+
+///// iteration, depth == 2
+
+#elif BOOST_PP_ITERATION_DEPTH() == 2
+
+#   define j_ BOOST_PP_FRAME_ITERATION(2)
+
+#if i_ == 0 && j_ == 0 \
+    && defined(BOOST_MPL_CFG_BCC590_WORKAROUNDS) \
+    && !defined(BOOST_MPL_CFG_NO_HAS_APPLY)
+
+template< typename F, bool F_has_apply >
+struct apply_wrap_impl0_bcb {
+    typedef typename F::template apply< na > type;
+};
+
+template< typename F >
+struct apply_wrap_impl0_bcb< F, true > {
+    typedef typename F::apply type;
+};
+
+template<
+      typename F BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, typename T)
+    >
+struct BOOST_PP_CAT(apply_wrap_impl,i_)<
+          BOOST_MPL_PP_ADD(i_, j_)
+        , F
+        BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, T)
+        >
+{
+    typedef apply_wrap_impl0_bcb< F, aux::has_apply< F >::value >::type type;
+};
+#else
+
+template<
+      typename F BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, typename T)
+    >
+struct BOOST_PP_CAT(apply_wrap_impl,i_)<
+          BOOST_MPL_PP_ADD(i_, j_)
+        , F
+        BOOST_PP_COMMA_IF(i_) AUX778076_APPLY_WRAP_PARAMS(i_, T)
+        >
+{
+    typedef typename F::template apply<
+          AUX778076_APPLY_WRAP_PARAMS(i_, T)
+#if i_ == 0 && j_ == 0
+/// since the defaults are "lost", we have to pass *something* even for nullary
+/// metafunction classes
+        na
+#else
+        BOOST_PP_COMMA_IF(BOOST_PP_AND(i_, j_)) BOOST_MPL_PP_ENUM(j_, na)
+#endif
+        > type;
+};
+
+#endif
+
+#   undef j_
+
+#endif // BOOST_PP_ITERATION_DEPTH()
+#endif // BOOST_PP_IS_ITERATING
diff --git a/third_party/boost/boost/mpl/arg.hpp b/third_party/boost/boost/mpl/arg.hpp
new file mode 100644
index 0000000..2c7051c
--- /dev/null
+++ b/third_party/boost/boost/mpl/arg.hpp
@@ -0,0 +1,131 @@
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+///// header body
+
+#ifndef BOOST_MPL_ARG_HPP_INCLUDED
+#define BOOST_MPL_ARG_HPP_INCLUDED
+
+// Copyright Peter Dimov 2001-2002
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/arg_fwd.hpp>
+#   include <boost/mpl/aux_/na.hpp>
+#   include <boost/mpl/aux_/na_assert.hpp>
+#   include <boost/mpl/aux_/arity_spec.hpp>
+#   include <boost/mpl/aux_/arg_typedef.hpp>
+#endif
+
+#include <boost/mpl/aux_/config/static_constant.hpp>
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER arg.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   include <boost/mpl/limits/arity.hpp>
+#   include <boost/mpl/aux_/preprocessor/default_params.hpp>
+#   include <boost/mpl/aux_/preprocessor/params.hpp>
+#   include <boost/mpl/aux_/config/lambda.hpp>
+#   include <boost/mpl/aux_/config/dtp.hpp>
+#   include <boost/mpl/aux_/nttp_decl.hpp>
+
+#   include <boost/preprocessor/iterate.hpp>
+#   include <boost/preprocessor/inc.hpp>
+#   include <boost/preprocessor/cat.hpp>
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+
+// local macro, #undef-ined at the end of the header
+#if !defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES)
+#   define AUX778076_ARG_N_DEFAULT_PARAMS(param,value) \
+    BOOST_MPL_PP_DEFAULT_PARAMS( \
+          BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
+        , param \
+        , value \
+        ) \
+    /**/
+#else
+#   define AUX778076_ARG_N_DEFAULT_PARAMS(param,value) \
+    BOOST_MPL_PP_PARAMS( \
+          BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
+        , param \
+        ) \
+    /**/
+#endif
+
+#define BOOST_PP_ITERATION_PARAMS_1 \
+    (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, <boost/mpl/arg.hpp>))
+#include BOOST_PP_ITERATE()
+
+
+#   undef AUX778076_ARG_N_DEFAULT_PARAMS
+
+BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(1,int,arg)
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_ARG_HPP_INCLUDED
+
+///// iteration
+
+#else
+#define i_ BOOST_PP_FRAME_ITERATION(1)
+
+#if i_ > 0
+
+template<> struct arg<i_>
+{
+    BOOST_STATIC_CONSTANT(int, value = i_);
+    typedef arg<BOOST_PP_INC(i_)> next;
+    BOOST_MPL_AUX_ARG_TYPEDEF(na, tag)
+    BOOST_MPL_AUX_ARG_TYPEDEF(na, type)
+
+    template<
+          AUX778076_ARG_N_DEFAULT_PARAMS(typename U, na)
+        >
+    struct apply
+    {
+        typedef BOOST_PP_CAT(U,i_) type;
+        BOOST_MPL_AUX_ASSERT_NOT_NA(type);
+    };
+};
+
+#else
+
+template<> struct arg<-1>
+{
+    BOOST_STATIC_CONSTANT(int, value = -1);
+    BOOST_MPL_AUX_ARG_TYPEDEF(na, tag)
+    BOOST_MPL_AUX_ARG_TYPEDEF(na, type)
+
+    template<
+          AUX778076_ARG_N_DEFAULT_PARAMS(typename U, na)
+        >
+    struct apply
+    {
+        typedef U1 type;
+        BOOST_MPL_AUX_ASSERT_NOT_NA(type);
+    };
+};
+
+#endif // i_ > 0
+
+#undef i_
+#endif // BOOST_PP_IS_ITERATING
diff --git a/third_party/boost/boost/mpl/arg_fwd.hpp b/third_party/boost/boost/mpl/arg_fwd.hpp
new file mode 100644
index 0000000..a4bfc2f
--- /dev/null
+++ b/third_party/boost/boost/mpl/arg_fwd.hpp
@@ -0,0 +1,28 @@
+
+#ifndef BOOST_MPL_ARG_FWD_HPP_INCLUDED
+#define BOOST_MPL_ARG_FWD_HPP_INCLUDED
+
+// Copyright Peter Dimov 2001-2002
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/adl_barrier.hpp>
+#include <boost/mpl/aux_/nttp_decl.hpp>
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+
+template< BOOST_MPL_AUX_NTTP_DECL(int, N) > struct arg;
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+BOOST_MPL_AUX_ADL_BARRIER_DECL(arg)
+
+#endif // BOOST_MPL_ARG_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/assert.hpp b/third_party/boost/boost/mpl/assert.hpp
new file mode 100644
index 0000000..8bf8c97
--- /dev/null
+++ b/third_party/boost/boost/mpl/assert.hpp
@@ -0,0 +1,439 @@
+
+#ifndef BOOST_MPL_ASSERT_HPP_INCLUDED
+#define BOOST_MPL_ASSERT_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2006
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/aux_/value_wknd.hpp>
+#include <boost/mpl/aux_/nested_type_wknd.hpp>
+#include <boost/mpl/aux_/yes_no.hpp>
+#include <boost/mpl/aux_/na.hpp>
+#include <boost/mpl/aux_/adl_barrier.hpp>
+
+#include <boost/mpl/aux_/config/nttp.hpp>
+#include <boost/mpl/aux_/config/dtp.hpp>
+#include <boost/mpl/aux_/config/gcc.hpp>
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/gpu.hpp>
+#include <boost/mpl/aux_/config/static_constant.hpp>
+#include <boost/mpl/aux_/config/pp_counter.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#include <boost/preprocessor/cat.hpp>
+
+#include <boost/config.hpp> // make sure 'size_t' is placed into 'std'
+#include <cstddef>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1700)
+#include <boost/mpl/if.hpp>
+#endif
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \
+    || (BOOST_MPL_CFG_GCC != 0) \
+    || BOOST_WORKAROUND(__IBMCPP__, <= 600)
+#   define BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES
+#endif
+
+#if BOOST_WORKAROUND(__MWERKS__, < 0x3202) \
+    || BOOST_WORKAROUND(__EDG_VERSION__, <= 238) \
+    || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \
+    || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840))
+#   define BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER
+#endif
+
+// agurt, 10/nov/06: use enums for Borland (which cannot cope with static constants)
+// and GCC (which issues "unused variable" warnings when static constants are used
+// at a function scope)
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \
+    || (BOOST_MPL_CFG_GCC != 0) || (BOOST_MPL_CFG_GPU != 0)
+#   define BOOST_MPL_AUX_ASSERT_CONSTANT(T, expr) enum { expr }
+#else
+#   define BOOST_MPL_AUX_ASSERT_CONSTANT(T, expr) BOOST_STATIC_CONSTANT(T, expr)
+#endif
+
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+
+struct failed {};
+
+// agurt, 24/aug/04: MSVC 7.1 workaround here and below: return/accept
+// 'assert<false>' by reference; can't apply it unconditionally -- apparently it
+// degrades the quality of GCC diagnostics
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+#   define AUX778076_ASSERT_ARG(x) x&
+#else
+#   define AUX778076_ASSERT_ARG(x) x
+#endif
+
+template< bool C >  struct assert        { typedef void* type; };
+template<>          struct assert<false> { typedef AUX778076_ASSERT_ARG(assert) type; };
+
+template< bool C >
+int assertion_failed( typename assert<C>::type );
+
+template< bool C >
+struct assertion
+{
+    static int failed( assert<false> );
+};
+
+template<>
+struct assertion<true>
+{
+    static int failed( void* );
+};
+
+struct assert_
+{
+#if !defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES)
+    template< typename T1, typename T2 = na, typename T3 = na, typename T4 = na > struct types {};
+#endif
+    static assert_ const arg;
+    enum relations { equal = 1, not_equal, greater, greater_equal, less, less_equal };
+};
+
+
+#if !defined(BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES)
+
+bool operator==( failed, failed );
+bool operator!=( failed, failed );
+bool operator>( failed, failed );
+bool operator>=( failed, failed );
+bool operator<( failed, failed );
+bool operator<=( failed, failed );
+
+#if defined(__EDG_VERSION__)
+template< bool (*)(failed, failed), long x, long y > struct assert_relation {};
+#   define BOOST_MPL_AUX_ASSERT_RELATION(x, y, r) assert_relation<r,x,y>
+#else
+template< BOOST_MPL_AUX_NTTP_DECL(long, x), BOOST_MPL_AUX_NTTP_DECL(long, y), bool (*)(failed, failed) >
+struct assert_relation {};
+#   define BOOST_MPL_AUX_ASSERT_RELATION(x, y, r) assert_relation<x,y,r>
+#endif
+
+#else // BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES
+
+boost::mpl::aux::weighted_tag<1>::type operator==( assert_, assert_ );
+boost::mpl::aux::weighted_tag<2>::type operator!=( assert_, assert_ );
+boost::mpl::aux::weighted_tag<3>::type operator>(  assert_, assert_ );
+boost::mpl::aux::weighted_tag<4>::type operator>=( assert_, assert_ );
+boost::mpl::aux::weighted_tag<5>::type operator<( assert_, assert_ );
+boost::mpl::aux::weighted_tag<6>::type operator<=( assert_, assert_ );
+
+template< assert_::relations r, long x, long y > struct assert_relation {};
+
+#endif
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1700)
+
+template<class Pred>
+struct extract_assert_pred;
+
+template<class Pred>
+struct extract_assert_pred<void(Pred)> { typedef Pred type; };
+
+template<class Pred>
+struct eval_assert {
+    typedef typename extract_assert_pred<Pred>::type P;
+    typedef typename P::type p_type;
+    typedef typename ::boost::mpl::if_c<p_type::value,
+        AUX778076_ASSERT_ARG(assert<false>),
+        failed ************ P::************
+    >::type type;
+};
+
+template<class Pred>
+struct eval_assert_not {
+    typedef typename extract_assert_pred<Pred>::type P;
+    typedef typename P::type p_type;
+    typedef typename ::boost::mpl::if_c<!p_type::value,
+        AUX778076_ASSERT_ARG(assert<false>),
+        failed ************ ::boost::mpl::not_<P>::************
+    >::type type;
+};
+
+template< typename T >
+T make_assert_arg();
+
+#elif !defined(BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER)
+
+template< bool > struct assert_arg_pred_impl { typedef int type; };
+template<> struct assert_arg_pred_impl<true> { typedef void* type; };
+
+template< typename P > struct assert_arg_pred
+{
+    typedef typename P::type p_type;
+    typedef typename assert_arg_pred_impl< p_type::value >::type type;
+};
+
+template< typename P > struct assert_arg_pred_not
+{
+    typedef typename P::type p_type;
+    BOOST_MPL_AUX_ASSERT_CONSTANT( bool, p = !p_type::value );
+    typedef typename assert_arg_pred_impl<p>::type type;
+};
+
+template< typename Pred >
+failed ************ (Pred::************
+      assert_arg( void (*)(Pred), typename assert_arg_pred<Pred>::type )
+    );
+
+template< typename Pred >
+failed ************ (boost::mpl::not_<Pred>::************
+      assert_not_arg( void (*)(Pred), typename assert_arg_pred_not<Pred>::type )
+    );
+
+template< typename Pred >
+AUX778076_ASSERT_ARG(assert<false>)
+assert_arg( void (*)(Pred), typename assert_arg_pred_not<Pred>::type );
+
+template< typename Pred >
+AUX778076_ASSERT_ARG(assert<false>)
+assert_not_arg( void (*)(Pred), typename assert_arg_pred<Pred>::type );
+
+
+#else // BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER
+
+template< bool c, typename Pred > struct assert_arg_type_impl
+{
+    typedef failed      ************ Pred::* mwcw83_wknd;
+    typedef mwcw83_wknd ************* type;
+};
+
+template< typename Pred > struct assert_arg_type_impl<true,Pred>
+{
+    typedef AUX778076_ASSERT_ARG(assert<false>) type;
+};
+
+template< typename Pred > struct assert_arg_type
+    : assert_arg_type_impl< BOOST_MPL_AUX_VALUE_WKND(BOOST_MPL_AUX_NESTED_TYPE_WKND(Pred))::value, Pred >
+{
+};
+
+template< typename Pred >
+typename assert_arg_type<Pred>::type
+assert_arg(void (*)(Pred), int);
+
+template< typename Pred >
+typename assert_arg_type< boost::mpl::not_<Pred> >::type
+assert_not_arg(void (*)(Pred), int);
+
+#   if !defined(BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES)
+template< long x, long y, bool (*r)(failed, failed) >
+typename assert_arg_type_impl< false,BOOST_MPL_AUX_ASSERT_RELATION(x,y,r) >::type
+assert_rel_arg( BOOST_MPL_AUX_ASSERT_RELATION(x,y,r) );
+#   else
+template< assert_::relations r, long x, long y >
+typename assert_arg_type_impl< false,assert_relation<r,x,y> >::type
+assert_rel_arg( assert_relation<r,x,y> );
+#   endif
+
+#endif // BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER
+
+#undef AUX778076_ASSERT_ARG
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1700)
+
+// BOOST_MPL_ASSERT((pred<x,...>))
+
+#define BOOST_MPL_ASSERT(pred) \
+BOOST_MPL_AUX_ASSERT_CONSTANT( \
+      std::size_t \
+    , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \
+          boost::mpl::assertion_failed<false>( \
+              boost::mpl::make_assert_arg< \
+                  typename boost::mpl::eval_assert<void pred>::type \
+                >() \
+            ) \
+        ) \
+    ) \
+/**/
+
+// BOOST_MPL_ASSERT_NOT((pred<x,...>))
+
+#define BOOST_MPL_ASSERT_NOT(pred) \
+BOOST_MPL_AUX_ASSERT_CONSTANT( \
+      std::size_t \
+    , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \
+          boost::mpl::assertion_failed<false>( \
+              boost::mpl::make_assert_arg< \
+                  typename boost::mpl::eval_assert_not<void pred>::type \
+                >() \
+            ) \
+        ) \
+    ) \
+/**/
+
+#else
+
+// BOOST_MPL_ASSERT((pred<x,...>))
+
+#define BOOST_MPL_ASSERT(pred) \
+BOOST_MPL_AUX_ASSERT_CONSTANT( \
+      std::size_t \
+    , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \
+          boost::mpl::assertion_failed<false>( \
+              boost::mpl::assert_arg( (void (*) pred)0, 1 ) \
+            ) \
+        ) \
+    ) \
+/**/
+
+// BOOST_MPL_ASSERT_NOT((pred<x,...>))
+
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+#   define BOOST_MPL_ASSERT_NOT(pred) \
+enum { \
+      BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \
+          boost::mpl::assertion<false>::failed( \
+              boost::mpl::assert_not_arg( (void (*) pred)0, 1 ) \
+            ) \
+        ) \
+}\
+/**/
+#else
+#   define BOOST_MPL_ASSERT_NOT(pred) \
+BOOST_MPL_AUX_ASSERT_CONSTANT( \
+      std::size_t \
+    , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \
+          boost::mpl::assertion_failed<false>( \
+              boost::mpl::assert_not_arg( (void (*) pred)0, 1 ) \
+            ) \
+        ) \
+   ) \
+/**/
+#endif
+
+#endif
+
+// BOOST_MPL_ASSERT_RELATION(x, ==|!=|<=|<|>=|>, y)
+
+#if defined(BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES)
+
+#   if !defined(BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER)
+// agurt, 9/nov/06: 'enum' below is a workaround for gcc 4.0.4/4.1.1 bugs #29522 and #29518
+#   define BOOST_MPL_ASSERT_RELATION_IMPL(counter, x, rel, y)      \
+enum { BOOST_PP_CAT(mpl_assert_rel_value,counter) = (x rel y) }; \
+BOOST_MPL_AUX_ASSERT_CONSTANT( \
+      std::size_t \
+    , BOOST_PP_CAT(mpl_assertion_in_line_,counter) = sizeof( \
+        boost::mpl::assertion_failed<BOOST_PP_CAT(mpl_assert_rel_value,counter)>( \
+            (boost::mpl::failed ************ ( boost::mpl::assert_relation< \
+                  boost::mpl::assert_::relations( sizeof( \
+                      boost::mpl::assert_::arg rel boost::mpl::assert_::arg \
+                    ) ) \
+                , x \
+                , y \
+                >::************)) 0 ) \
+        ) \
+    ) \
+/**/
+#   else
+#   define BOOST_MPL_ASSERT_RELATION_IMPL(counter, x, rel, y)    \
+BOOST_MPL_AUX_ASSERT_CONSTANT( \
+      std::size_t \
+    , BOOST_PP_CAT(mpl_assert_rel,counter) = sizeof( \
+          boost::mpl::assert_::arg rel boost::mpl::assert_::arg \
+        ) \
+    ); \
+BOOST_MPL_AUX_ASSERT_CONSTANT( bool, BOOST_PP_CAT(mpl_assert_rel_value,counter) = (x rel y) ); \
+BOOST_MPL_AUX_ASSERT_CONSTANT( \
+      std::size_t \
+    , BOOST_PP_CAT(mpl_assertion_in_line_,counter) = sizeof( \
+        boost::mpl::assertion_failed<BOOST_PP_CAT(mpl_assert_rel_value,counter)>( \
+              boost::mpl::assert_rel_arg( boost::mpl::assert_relation< \
+                  boost::mpl::assert_::relations(BOOST_PP_CAT(mpl_assert_rel,counter)) \
+                , x \
+                , y \
+                >() ) \
+            ) \
+        ) \
+    ) \
+/**/
+#   endif
+
+#   define BOOST_MPL_ASSERT_RELATION(x, rel, y) \
+BOOST_MPL_ASSERT_RELATION_IMPL(BOOST_MPL_AUX_PP_COUNTER(), x, rel, y) \
+/**/
+
+#else // !BOOST_MPL_CFG_ASSERT_USE_RELATION_NAMES
+
+#   if defined(BOOST_MPL_CFG_ASSERT_BROKEN_POINTER_TO_POINTER_TO_MEMBER)
+#   define BOOST_MPL_ASSERT_RELATION(x, rel, y) \
+BOOST_MPL_AUX_ASSERT_CONSTANT( \
+      std::size_t \
+    , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \
+        boost::mpl::assertion_failed<(x rel y)>( boost::mpl::assert_rel_arg( \
+              boost::mpl::BOOST_MPL_AUX_ASSERT_RELATION(x,y,(&boost::mpl::operator rel))() \
+            ) ) \
+        ) \
+    ) \
+/**/
+#   else
+#   define BOOST_MPL_ASSERT_RELATION(x, rel, y) \
+BOOST_MPL_AUX_ASSERT_CONSTANT( \
+      std::size_t \
+    , BOOST_PP_CAT(mpl_assertion_in_line_,BOOST_MPL_AUX_PP_COUNTER()) = sizeof( \
+        boost::mpl::assertion_failed<(x rel y)>( (boost::mpl::failed ************ ( \
+            boost::mpl::BOOST_MPL_AUX_ASSERT_RELATION(x,y,(&boost::mpl::operator rel))::************))0 ) \
+        ) \
+    ) \
+/**/
+#   endif
+
+#endif
+
+
+// BOOST_MPL_ASSERT_MSG( (pred<x,...>::value), USER_PROVIDED_MESSAGE, (types<x,...>) )
+
+#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202))
+#   define BOOST_MPL_ASSERT_MSG_IMPL( counter, c, msg, types_ ) \
+struct msg; \
+typedef struct BOOST_PP_CAT(msg,counter) : boost::mpl::assert_ \
+{ \
+    using boost::mpl::assert_::types; \
+    static boost::mpl::failed ************ (msg::************ assert_arg()) types_ \
+    { return 0; } \
+} BOOST_PP_CAT(mpl_assert_arg,counter); \
+BOOST_MPL_AUX_ASSERT_CONSTANT( \
+      std::size_t \
+    , BOOST_PP_CAT(mpl_assertion_in_line_,counter) = sizeof( \
+        boost::mpl::assertion<(c)>::failed( BOOST_PP_CAT(mpl_assert_arg,counter)::assert_arg() ) \
+        ) \
+    ) \
+/**/
+#else
+#   define BOOST_MPL_ASSERT_MSG_IMPL( counter, c, msg, types_ )  \
+struct msg; \
+typedef struct BOOST_PP_CAT(msg,counter) : boost::mpl::assert_ \
+{ \
+    static boost::mpl::failed ************ (msg::************ assert_arg()) types_ \
+    { return 0; } \
+} BOOST_PP_CAT(mpl_assert_arg,counter); \
+BOOST_MPL_AUX_ASSERT_CONSTANT( \
+      std::size_t \
+    , BOOST_PP_CAT(mpl_assertion_in_line_,counter) = sizeof( \
+        boost::mpl::assertion_failed<(c)>( BOOST_PP_CAT(mpl_assert_arg,counter)::assert_arg() ) \
+        ) \
+    ) \
+/**/
+#endif
+
+#define BOOST_MPL_ASSERT_MSG( c, msg, types_ ) \
+BOOST_MPL_ASSERT_MSG_IMPL( BOOST_MPL_AUX_PP_COUNTER(), c, msg, types_ ) \
+/**/
+
+#endif // BOOST_MPL_ASSERT_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/O1_size_impl.hpp b/third_party/boost/boost/mpl/aux_/O1_size_impl.hpp
new file mode 100644
index 0000000..de64dda
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/O1_size_impl.hpp
@@ -0,0 +1,87 @@
+
+#ifndef BOOST_MPL_O1_SIZE_IMPL_HPP_INCLUDED
+#define BOOST_MPL_O1_SIZE_IMPL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/O1_size_fwd.hpp>
+#include <boost/mpl/long.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/aux_/has_size.hpp>
+#include <boost/mpl/aux_/config/forwarding.hpp>
+#include <boost/mpl/aux_/config/static_constant.hpp>
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+namespace boost { namespace mpl {
+
+// default implementation - returns 'Sequence::size' if sequence has a 'size'
+// member, and -1 otherwise; conrete sequences might override it by
+// specializing either the 'O1_size_impl' or the primary 'O1_size' template
+
+#   if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
+    && !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
+
+namespace aux {
+template< typename Sequence > struct O1_size_impl
+    : Sequence::size
+{
+};
+}
+
+template< typename Tag >
+struct O1_size_impl
+{
+    template< typename Sequence > struct apply
+#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING)
+        : if_<
+              aux::has_size<Sequence>
+            , aux::O1_size_impl<Sequence>
+            , long_<-1>
+            >::type
+    {
+#else
+    {
+        typedef typename if_<
+              aux::has_size<Sequence>
+            , aux::O1_size_impl<Sequence>
+            , long_<-1>
+            >::type type;
+
+        BOOST_STATIC_CONSTANT(long, value =
+              (if_<
+                  aux::has_size<Sequence>
+                , aux::O1_size_impl<Sequence>
+                , long_<-1>
+                >::type::value)
+            );
+#endif
+    };
+};
+
+#   else // BOOST_MSVC
+
+template< typename Tag >
+struct O1_size_impl
+{
+    template< typename Sequence > struct apply
+        : long_<-1>
+        {
+        };
+};
+
+#   endif
+
+}}
+
+#endif // BOOST_MPL_O1_SIZE_IMPL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/adl_barrier.hpp b/third_party/boost/boost/mpl/aux_/adl_barrier.hpp
new file mode 100644
index 0000000..0d28876
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/adl_barrier.hpp
@@ -0,0 +1,48 @@
+
+#ifndef BOOST_MPL_AUX_ADL_BARRIER_HPP_INCLUDED
+#define BOOST_MPL_AUX_ADL_BARRIER_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/adl.hpp>
+#include <boost/mpl/aux_/config/gcc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_ADL_BARRIER_NAMESPACE)
+
+#   define BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE mpl_
+#   define BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN namespace mpl_ {
+#   define BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE }
+#   define BOOST_MPL_AUX_ADL_BARRIER_DECL(type) \
+    namespace boost { namespace mpl { \
+    using ::BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::type; \
+    } } \
+/**/
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+namespace BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE { namespace aux {} }
+namespace boost { namespace mpl { using namespace BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE;
+namespace aux { using namespace BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::aux; }
+}}
+#endif
+
+#else // BOOST_MPL_CFG_NO_ADL_BARRIER_NAMESPACE
+
+#   define BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE boost::mpl
+#   define BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN namespace boost { namespace mpl {
+#   define BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE }}
+#   define BOOST_MPL_AUX_ADL_BARRIER_DECL(type) /**/
+
+#endif
+
+#endif // BOOST_MPL_AUX_ADL_BARRIER_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/advance_backward.hpp b/third_party/boost/boost/mpl/aux_/advance_backward.hpp
new file mode 100644
index 0000000..886d850
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/advance_backward.hpp
@@ -0,0 +1,128 @@
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+///// header body
+
+#ifndef BOOST_MPL_AUX778076_ADVANCE_BACKWARD_HPP_INCLUDED
+#define BOOST_MPL_AUX778076_ADVANCE_BACKWARD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/prior.hpp>
+#   include <boost/mpl/apply_wrap.hpp>
+#endif
+
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if    !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER advance_backward.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   include <boost/mpl/limits/unrolling.hpp>
+#   include <boost/mpl/aux_/nttp_decl.hpp>
+#   include <boost/mpl/aux_/config/eti.hpp>
+
+#   include <boost/preprocessor/iterate.hpp>
+#   include <boost/preprocessor/cat.hpp>
+#   include <boost/preprocessor/inc.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+
+// forward declaration
+template< BOOST_MPL_AUX_NTTP_DECL(long, N) > struct advance_backward;
+
+#   define BOOST_PP_ITERATION_PARAMS_1 \
+    (3,(0, BOOST_MPL_LIMIT_UNROLLING, <boost/mpl/aux_/advance_backward.hpp>))
+#   include BOOST_PP_ITERATE()
+
+// implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING
+template< BOOST_MPL_AUX_NTTP_DECL(long, N) >
+struct advance_backward
+{
+    template< typename Iterator > struct apply
+    {
+        typedef typename apply_wrap1<
+              advance_backward<BOOST_MPL_LIMIT_UNROLLING>
+            , Iterator
+            >::type chunk_result_;
+
+        typedef typename apply_wrap1<
+              advance_backward<(
+                (N - BOOST_MPL_LIMIT_UNROLLING) < 0
+                    ? 0
+                    : N - BOOST_MPL_LIMIT_UNROLLING
+                    )>
+            , chunk_result_
+            >::type type;
+    };
+};
+
+}}}
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_AUX778076_ADVANCE_BACKWARD_HPP_INCLUDED
+
+///// iteration, depth == 1
+
+// For gcc 4.4 compatability, we must include the
+// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
+#else // BOOST_PP_IS_ITERATING
+#if BOOST_PP_ITERATION_DEPTH() == 1
+#define i_ BOOST_PP_FRAME_ITERATION(1)
+
+template<>
+struct advance_backward< BOOST_PP_FRAME_ITERATION(1) >
+{
+    template< typename Iterator > struct apply
+    {
+        typedef Iterator iter0;
+
+#if i_ > 0
+#   define BOOST_PP_ITERATION_PARAMS_2 \
+    (3,(1, BOOST_PP_FRAME_ITERATION(1), <boost/mpl/aux_/advance_backward.hpp>))
+#   include BOOST_PP_ITERATE()
+#endif
+
+        typedef BOOST_PP_CAT(iter,BOOST_PP_FRAME_ITERATION(1)) type;
+    };
+
+#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
+    /// ETI workaround
+    template<> struct apply<int>
+    {
+        typedef int type;
+    };
+#endif
+};
+
+#undef i_
+
+///// iteration, depth == 2
+
+#elif BOOST_PP_ITERATION_DEPTH() == 2
+
+#   define AUX778076_ITER_0 BOOST_PP_CAT(iter,BOOST_PP_DEC(BOOST_PP_FRAME_ITERATION(2)))
+#   define AUX778076_ITER_1 BOOST_PP_CAT(iter,BOOST_PP_FRAME_ITERATION(2))
+
+        typedef typename prior<AUX778076_ITER_0>::type AUX778076_ITER_1;
+
+#   undef AUX778076_ITER_1
+#   undef AUX778076_ITER_0
+
+#endif // BOOST_PP_ITERATION_DEPTH()
+#endif // BOOST_PP_IS_ITERATING
diff --git a/third_party/boost/boost/mpl/aux_/advance_forward.hpp b/third_party/boost/boost/mpl/aux_/advance_forward.hpp
new file mode 100644
index 0000000..5cb720f
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/advance_forward.hpp
@@ -0,0 +1,127 @@
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+///// header body
+
+#ifndef BOOST_MPL_AUX_ADVANCE_FORWARD_HPP_INCLUDED
+#define BOOST_MPL_AUX_ADVANCE_FORWARD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/next.hpp>
+#   include <boost/mpl/apply_wrap.hpp>
+#endif
+
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if    !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER advance_forward.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   include <boost/mpl/limits/unrolling.hpp>
+#   include <boost/mpl/aux_/nttp_decl.hpp>
+#   include <boost/mpl/aux_/config/eti.hpp>
+
+#   include <boost/preprocessor/iterate.hpp>
+#   include <boost/preprocessor/cat.hpp>
+#   include <boost/preprocessor/inc.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+
+// forward declaration
+template< BOOST_MPL_AUX_NTTP_DECL(long, N) > struct advance_forward;
+
+#   define BOOST_PP_ITERATION_PARAMS_1 \
+    (3,(0, BOOST_MPL_LIMIT_UNROLLING, <boost/mpl/aux_/advance_forward.hpp>))
+#   include BOOST_PP_ITERATE()
+
+// implementation for N that exceeds BOOST_MPL_LIMIT_UNROLLING
+template< BOOST_MPL_AUX_NTTP_DECL(long, N) >
+struct advance_forward
+{
+    template< typename Iterator > struct apply
+    {
+        typedef typename apply_wrap1<
+              advance_forward<BOOST_MPL_LIMIT_UNROLLING>
+            , Iterator
+            >::type chunk_result_;
+
+        typedef typename apply_wrap1<
+              advance_forward<(
+                (N - BOOST_MPL_LIMIT_UNROLLING) < 0
+                    ? 0
+                    : N - BOOST_MPL_LIMIT_UNROLLING
+                    )>
+            , chunk_result_
+            >::type type;
+    };
+};
+
+}}}
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_AUX_ADVANCE_FORWARD_HPP_INCLUDED
+
+///// iteration, depth == 1
+
+// For gcc 4.4 compatability, we must include the
+// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
+#else // BOOST_PP_IS_ITERATING
+#if BOOST_PP_ITERATION_DEPTH() == 1
+#define i_ BOOST_PP_FRAME_ITERATION(1)
+
+template<>
+struct advance_forward< BOOST_PP_FRAME_ITERATION(1) >
+{
+    template< typename Iterator > struct apply
+    {
+        typedef Iterator iter0;
+
+#if i_ > 0
+#   define BOOST_PP_ITERATION_PARAMS_2 \
+    (3,(1, i_, <boost/mpl/aux_/advance_forward.hpp>))
+#   include BOOST_PP_ITERATE()
+#endif
+        typedef BOOST_PP_CAT(iter,i_) type;
+    };
+
+#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
+    /// ETI workaround
+    template<> struct apply<int>
+    {
+        typedef int type;
+    };
+#endif
+};
+
+#undef i_
+
+///// iteration, depth == 2
+
+#elif BOOST_PP_ITERATION_DEPTH() == 2
+
+#   define AUX778076_ITER_0 BOOST_PP_CAT(iter,BOOST_PP_DEC(BOOST_PP_FRAME_ITERATION(2)))
+#   define AUX778076_ITER_1 BOOST_PP_CAT(iter,BOOST_PP_FRAME_ITERATION(2))
+
+        typedef typename next<AUX778076_ITER_0>::type AUX778076_ITER_1;
+
+#   undef AUX778076_ITER_1
+#   undef AUX778076_ITER_0
+
+#endif // BOOST_PP_ITERATION_DEPTH()
+#endif // BOOST_PP_IS_ITERATING
diff --git a/third_party/boost/boost/mpl/aux_/arg_typedef.hpp b/third_party/boost/boost/mpl/aux_/arg_typedef.hpp
new file mode 100644
index 0000000..c80b04a
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/arg_typedef.hpp
@@ -0,0 +1,31 @@
+
+#ifndef BOOST_MPL_AUX_ARG_TYPEDEF_HPP_INCLUDED
+#define BOOST_MPL_AUX_ARG_TYPEDEF_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/lambda.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) \
+    || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840))
+
+#   define BOOST_MPL_AUX_ARG_TYPEDEF(T, name) typedef T name;
+
+#else
+
+#   define BOOST_MPL_AUX_ARG_TYPEDEF(T, name) /**/
+
+#endif
+
+#endif // BOOST_MPL_AUX_ARG_TYPEDEF_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/arity.hpp b/third_party/boost/boost/mpl/aux_/arity.hpp
new file mode 100644
index 0000000..d1bb010
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/arity.hpp
@@ -0,0 +1,39 @@
+
+#ifndef BOOST_MPL_AUX_ARITY_HPP_INCLUDED
+#define BOOST_MPL_AUX_ARITY_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/dtp.hpp>
+
+#if defined(BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES)
+
+#   include <boost/mpl/aux_/nttp_decl.hpp>
+#   include <boost/mpl/aux_/config/static_constant.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+
+// agurt, 15/mar/02: it's possible to implement the template so that it will
+// "just work" and do not require any specialization, but not on the compilers
+// that require the arity workaround in the first place
+template< typename F, BOOST_MPL_AUX_NTTP_DECL(int, N) >
+struct arity
+{
+    BOOST_STATIC_CONSTANT(int, value = N);
+};
+
+}}}
+
+#endif // BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES
+
+#endif // BOOST_MPL_AUX_ARITY_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/arity_spec.hpp b/third_party/boost/boost/mpl/aux_/arity_spec.hpp
new file mode 100644
index 0000000..652b0a6
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/arity_spec.hpp
@@ -0,0 +1,67 @@
+
+#ifndef BOOST_MPL_AUX_ARITY_SPEC_HPP_INCLUDED
+#define BOOST_MPL_AUX_ARITY_SPEC_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/limits/arity.hpp>
+#include <boost/mpl/aux_/config/dtp.hpp>
+#include <boost/mpl/aux_/preprocessor/params.hpp>
+#include <boost/mpl/aux_/arity.hpp>
+#include <boost/mpl/aux_/template_arity_fwd.hpp>
+#include <boost/mpl/aux_/config/ttp.hpp>
+#include <boost/mpl/aux_/config/lambda.hpp>
+#include <boost/mpl/aux_/config/static_constant.hpp>
+
+#if defined(BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES)
+#   define BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(i,type,name) \
+namespace aux { \
+template< BOOST_MPL_AUX_NTTP_DECL(int, N), BOOST_MPL_PP_PARAMS(i,type T) > \
+struct arity< \
+      name< BOOST_MPL_PP_PARAMS(i,T) > \
+    , N \
+    > \
+{ \
+    BOOST_STATIC_CONSTANT(int \
+        , value = BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
+        ); \
+}; \
+} \
+/**/
+#else
+#   define BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(i,type,name) /**/
+#endif
+
+#   define BOOST_MPL_AUX_ARITY_SPEC(i,name) \
+    BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(i,typename,name) \
+/**/
+
+
+#if defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) \
+    && !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT)
+#   define BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(i, name) \
+namespace aux { \
+template< BOOST_MPL_PP_PARAMS(i,typename T) > \
+struct template_arity< name<BOOST_MPL_PP_PARAMS(i,T)> > \
+    : int_<i> \
+{ \
+}; \
+} \
+/**/
+#else
+#   define BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(i, name) /**/
+#endif
+
+
+#endif // BOOST_MPL_AUX_ARITY_SPEC_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/begin_end_impl.hpp b/third_party/boost/boost/mpl/aux_/begin_end_impl.hpp
new file mode 100644
index 0000000..1ba612c
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/begin_end_impl.hpp
@@ -0,0 +1,101 @@
+
+#ifndef BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED
+#define BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/begin_end_fwd.hpp>
+#include <boost/mpl/sequence_tag_fwd.hpp>
+#include <boost/mpl/void.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/aux_/has_begin.hpp>
+#include <boost/mpl/aux_/na.hpp>
+#include <boost/mpl/aux_/traits_lambda_spec.hpp>
+#include <boost/mpl/aux_/config/eti.hpp>
+
+namespace boost { namespace mpl {
+
+
+namespace aux {
+
+template< typename Sequence >
+struct begin_type
+{
+    typedef typename Sequence::begin type;
+};
+template< typename Sequence >
+struct end_type
+{
+    typedef typename Sequence::end type;
+};
+
+}
+
+// default implementation; conrete sequences might override it by
+// specializing either the 'begin_impl/end_impl' or the primary
+// 'begin/end' templates
+
+template< typename Tag >
+struct begin_impl
+{
+    template< typename Sequence > struct apply
+    {
+        typedef typename eval_if<aux::has_begin<Sequence, true_>,
+                                 aux::begin_type<Sequence>, void_>::type type;
+    };
+};
+
+template< typename Tag >
+struct end_impl
+{
+    template< typename Sequence > struct apply
+    {
+        typedef typename eval_if<aux::has_begin<Sequence, true_>,
+                                 aux::end_type<Sequence>, void_>::type type;
+    };
+};
+
+// specialize 'begin_trait/end_trait' for two pre-defined tags
+
+#   define AUX778076_IMPL_SPEC(name, tag, result) \
+template<> \
+struct name##_impl<tag> \
+{ \
+    template< typename Sequence > struct apply \
+    { \
+        typedef result type; \
+    }; \
+}; \
+/**/
+
+// a sequence with nested 'begin/end' typedefs; just query them
+AUX778076_IMPL_SPEC(begin, nested_begin_end_tag, typename Sequence::begin)
+AUX778076_IMPL_SPEC(end, nested_begin_end_tag, typename Sequence::end)
+
+// if a type 'T' does not contain 'begin/end' or 'tag' members
+// and doesn't specialize either 'begin/end' or 'begin_impl/end_impl'
+// templates, then we end up here
+AUX778076_IMPL_SPEC(begin, non_sequence_tag, void_)
+AUX778076_IMPL_SPEC(end, non_sequence_tag, void_)
+AUX778076_IMPL_SPEC(begin, na, void_)
+AUX778076_IMPL_SPEC(end, na, void_)
+
+#   undef AUX778076_IMPL_SPEC
+
+
+BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(1,begin_impl)
+BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(1,end_impl)
+
+}}
+
+#endif // BOOST_MPL_AUX_BEGIN_END_IMPL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/clear_impl.hpp b/third_party/boost/boost/mpl/aux_/clear_impl.hpp
new file mode 100644
index 0000000..1319b4e
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/clear_impl.hpp
@@ -0,0 +1,35 @@
+
+#ifndef BOOST_MPL_AUX_CLEAR_IMPL_HPP_INCLUDED
+#define BOOST_MPL_AUX_CLEAR_IMPL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/clear_fwd.hpp>
+#include <boost/mpl/aux_/traits_lambda_spec.hpp>
+#include <boost/mpl/aux_/config/eti.hpp>
+
+namespace boost { namespace mpl {
+
+// no default implementation; the definition is needed to make MSVC happy
+
+template< typename Tag >
+struct clear_impl
+{
+    template< typename Sequence > struct apply;
+};
+
+BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1, clear_impl)
+
+}}
+
+#endif // BOOST_MPL_AUX_CLEAR_IMPL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/common_name_wknd.hpp b/third_party/boost/boost/mpl/aux_/common_name_wknd.hpp
new file mode 100644
index 0000000..2a81bdc
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/common_name_wknd.hpp
@@ -0,0 +1,34 @@
+
+#ifndef BOOST_MPL_AUX_COMMON_NAME_WKND_HPP_INCLUDED
+#define BOOST_MPL_AUX_COMMON_NAME_WKND_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, < 0x561)
+// agurt, 12/nov/02: to suppress the bogus "Cannot have both a template class
+// and function named 'xxx'" diagnostic
+#   define BOOST_MPL_AUX_COMMON_NAME_WKND(name) \
+namespace name_##wknd { \
+template< typename > void name(); \
+} \
+/**/
+
+#else
+
+#   define BOOST_MPL_AUX_COMMON_NAME_WKND(name) /**/
+
+#endif // __BORLANDC__
+
+#endif // BOOST_MPL_AUX_COMMON_NAME_WKND_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/comparison_op.hpp b/third_party/boost/boost/mpl/aux_/comparison_op.hpp
new file mode 100644
index 0000000..fd218b1
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/comparison_op.hpp
@@ -0,0 +1,83 @@
+
+// NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/bool.hpp>
+#   include <boost/mpl/aux_/value_wknd.hpp>
+#endif
+
+#if !defined(AUX778076_OP_PREFIX)
+#   define AUX778076_OP_PREFIX AUX778076_OP_NAME
+#endif
+
+#define AUX778076_OP_ARITY 2
+
+#include <boost/mpl/aux_/numeric_op.hpp>
+#include <boost/mpl/aux_/config/static_constant.hpp>
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER AUX778076_OP_PREFIX.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   include <boost/mpl/aux_/config/integral.hpp>
+#   include <boost/preprocessor/cat.hpp>
+
+namespace boost { namespace mpl {
+
+// MSVC workaround: implement less in terms of greater
+#if 0 AUX778076_OP_TOKEN 1 && !(1 AUX778076_OP_TOKEN 0) && !(0 AUX778076_OP_TOKEN 0)
+#   define AUX778076_OP(N1, N2) \
+    ( BOOST_MPL_AUX_VALUE_WKND(N2)::value > BOOST_MPL_AUX_VALUE_WKND(N1)::value ) \
+/**/
+#else
+#   define AUX778076_OP(N1, N2) \
+    ( BOOST_MPL_AUX_VALUE_WKND(N1)::value \
+          AUX778076_OP_TOKEN BOOST_MPL_AUX_VALUE_WKND(N2)::value \
+        ) \
+/**/
+#endif
+
+template<>
+struct AUX778076_OP_IMPL_NAME<integral_c_tag,integral_c_tag>
+{
+    template< typename N1, typename N2 > struct apply
+#if !defined(BOOST_MPL_CFG_NO_NESTED_VALUE_ARITHMETIC)
+        : bool_< AUX778076_OP(N1, N2) >
+    {
+#else
+    {
+        BOOST_STATIC_CONSTANT(bool, value = AUX778076_OP(N1, N2));
+        typedef bool_<value> type;
+#endif
+    };
+};
+
+#undef AUX778076_OP
+
+}}
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+
+#undef AUX778076_OP_TAG_NAME
+#undef AUX778076_OP_IMPL_NAME
+#undef AUX778076_OP_ARITY
+#undef AUX778076_OP_PREFIX
+#undef AUX778076_OP_NAME
+#undef AUX778076_OP_TOKEN
diff --git a/third_party/boost/boost/mpl/aux_/config/adl.hpp b/third_party/boost/boost/mpl/aux_/config/adl.hpp
new file mode 100644
index 0000000..b8d02de
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/adl.hpp
@@ -0,0 +1,40 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_ADL_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_ADL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/intel.hpp>
+#include <boost/mpl/aux_/config/gcc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+// agurt, 25/apr/04: technically, the ADL workaround is only needed for GCC,
+// but putting everything expect public, user-specializable metafunctions into
+// a separate global namespace has a nice side effect of reducing the length
+// of template instantiation symbols, so we apply the workaround on all
+// platforms that can handle it
+
+#if !defined(BOOST_MPL_CFG_NO_ADL_BARRIER_NAMESPACE) \
+    && (   BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
+        || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \
+        || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) \
+        || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) \
+        || BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, BOOST_TESTED_AT(810)) \
+        )
+
+#   define BOOST_MPL_CFG_NO_ADL_BARRIER_NAMESPACE
+
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_ADL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/arrays.hpp b/third_party/boost/boost/mpl/aux_/config/arrays.hpp
new file mode 100644
index 0000000..7c6998b
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/arrays.hpp
@@ -0,0 +1,30 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_ARRAYS_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_ARRAYS_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2003-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if    !defined(BOOST_MPL_CFG_NO_DEPENDENT_ARRAY_TYPES) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE) \
+    && ( BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \
+        || BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
+        )
+
+#   define BOOST_MPL_CFG_NO_DEPENDENT_ARRAY_TYPES
+
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_ARRAYS_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/bcc.hpp b/third_party/boost/boost/mpl/aux_/config/bcc.hpp
new file mode 100644
index 0000000..e628875
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/bcc.hpp
@@ -0,0 +1,28 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_BCC_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_BCC_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2008
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date: 2004-09-02 10:41:37 -0500 (Thu, 02 Sep 2004) $
+// $Revision: 24874 $
+
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if    !defined(BOOST_MPL_CFG_BCC590_WORKAROUNDS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE) \
+    && BOOST_WORKAROUND(__BORLANDC__, >= 0x590) \
+    && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610))
+
+#   define BOOST_MPL_CFG_BCC590_WORKAROUNDS
+
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_BCC_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/bind.hpp b/third_party/boost/boost/mpl/aux_/config/bind.hpp
new file mode 100644
index 0000000..58a87f0
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/bind.hpp
@@ -0,0 +1,33 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_BIND_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_BIND_HPP_INCLUDED
+
+// Copyright David Abrahams 2002
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if    !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE) \
+    && (   BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
+        || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \
+        )
+
+#   define BOOST_MPL_CFG_NO_BIND_TEMPLATE
+
+#endif
+
+//#define BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT
+
+#endif // BOOST_MPL_AUX_CONFIG_BIND_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/compiler.hpp b/third_party/boost/boost/mpl/aux_/config/compiler.hpp
new file mode 100644
index 0000000..bb84638
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/compiler.hpp
@@ -0,0 +1,66 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_COMPILER_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_COMPILER_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2008
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_CFG_COMPILER_DIR)
+
+#   include <boost/mpl/aux_/config/dtp.hpp>
+#   include <boost/mpl/aux_/config/ttp.hpp>
+#   include <boost/mpl/aux_/config/ctps.hpp>
+#   include <boost/mpl/aux_/config/msvc.hpp>
+#   include <boost/mpl/aux_/config/gcc.hpp>
+#   include <boost/mpl/aux_/config/workaround.hpp>
+
+#   if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+#       define BOOST_MPL_CFG_COMPILER_DIR msvc60
+
+#   elif BOOST_WORKAROUND(BOOST_MSVC, == 1300)
+#       define BOOST_MPL_CFG_COMPILER_DIR msvc70
+
+#   elif BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, BOOST_TESTED_AT(0x0304))
+#       define BOOST_MPL_CFG_COMPILER_DIR gcc
+
+#   elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610))
+#       if !defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES)
+#           define BOOST_MPL_CFG_COMPILER_DIR bcc551
+#       elif BOOST_WORKAROUND(__BORLANDC__, >= 0x590)
+#           define BOOST_MPL_CFG_COMPILER_DIR bcc
+#       else
+#           define BOOST_MPL_CFG_COMPILER_DIR bcc_pre590
+#       endif
+
+#   elif BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840))
+#       define BOOST_MPL_CFG_COMPILER_DIR dmc
+
+#   elif defined(__MWERKS__)
+#       if defined(BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES)
+#           define BOOST_MPL_CFG_COMPILER_DIR mwcw
+#       else
+#           define BOOST_MPL_CFG_COMPILER_DIR plain
+#       endif
+
+#   elif defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+#       define BOOST_MPL_CFG_COMPILER_DIR no_ctps
+
+#   elif defined(BOOST_MPL_CFG_NO_TEMPLATE_TEMPLATE_PARAMETERS)
+#       define BOOST_MPL_CFG_COMPILER_DIR no_ttp
+
+#   else
+#       define BOOST_MPL_CFG_COMPILER_DIR plain
+#   endif
+
+#endif // BOOST_MPL_CFG_COMPILER_DIR
+
+#endif // BOOST_MPL_AUX_CONFIG_COMPILER_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/ctps.hpp b/third_party/boost/boost/mpl/aux_/config/ctps.hpp
new file mode 100644
index 0000000..130384f
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/ctps.hpp
@@ -0,0 +1,30 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_CTPS_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_CTPS_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/workaround.hpp>
+#include <boost/config.hpp>
+
+#if    !defined(BOOST_MPL_CFG_NO_NONTYPE_TEMPLATE_PARTIAL_SPEC) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE) \
+    && BOOST_WORKAROUND(__BORLANDC__, < 0x582)
+
+#   define BOOST_MPL_CFG_NO_NONTYPE_TEMPLATE_PARTIAL_SPEC
+
+#endif
+
+// BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION is defined in <boost/config.hpp>
+
+#endif // BOOST_MPL_AUX_CONFIG_CTPS_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/dtp.hpp b/third_party/boost/boost/mpl/aux_/config/dtp.hpp
new file mode 100644
index 0000000..7b76cb9
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/dtp.hpp
@@ -0,0 +1,46 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_DTP_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_DTP_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+// MWCW 7.x-8.0 "losts" default template parameters of nested class
+// templates when their owner classes are passed as arguments to other
+// templates; Borland 5.5.1 "forgets" them from the very beginning (if
+// the owner class is a class template), and Borland 5.6 isn't even
+// able to compile a definition of nested class template with DTP
+
+#if    !defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE) \
+    && BOOST_WORKAROUND(__BORLANDC__, >= 0x560) \
+    && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610))
+
+#   define BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES
+
+#endif
+
+
+#if    !defined(BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE) \
+    && (   BOOST_WORKAROUND(__MWERKS__, <= 0x3001) \
+        || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \
+        || defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES) \
+        )
+
+#   define BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES
+
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_DTP_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/eti.hpp b/third_party/boost/boost/mpl/aux_/config/eti.hpp
new file mode 100644
index 0000000..b9e8f44
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/eti.hpp
@@ -0,0 +1,47 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_ETI_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_ETI_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+// flags for MSVC 6.5's so-called "early template instantiation bug"
+#if    !defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE) \
+    && BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+
+#   define BOOST_MPL_CFG_MSVC_60_ETI_BUG
+
+#endif
+
+#if    !defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE) \
+    && BOOST_WORKAROUND(BOOST_MSVC, == 1300)
+
+#   define BOOST_MPL_CFG_MSVC_70_ETI_BUG
+
+#endif
+
+#if    !defined(BOOST_MPL_CFG_MSVC_ETI_BUG) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE) \
+    && ( defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG) \
+        || defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG) \
+        )
+
+#   define BOOST_MPL_CFG_MSVC_ETI_BUG
+
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_ETI_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/forwarding.hpp b/third_party/boost/boost/mpl/aux_/config/forwarding.hpp
new file mode 100644
index 0000000..9793096
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/forwarding.hpp
@@ -0,0 +1,27 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_FORWARDING_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_FORWARDING_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if    !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE) \
+    && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610))
+
+#   define BOOST_MPL_CFG_NO_NESTED_FORWARDING
+
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_FORWARDING_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/gcc.hpp b/third_party/boost/boost/mpl/aux_/config/gcc.hpp
new file mode 100644
index 0000000..80b7efd
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/gcc.hpp
@@ -0,0 +1,23 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_GCC_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_GCC_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if defined(__GNUC__) && !defined(__EDG_VERSION__)
+#   define BOOST_MPL_CFG_GCC ((__GNUC__ << 8) | __GNUC_MINOR__)
+#else
+#   define BOOST_MPL_CFG_GCC 0
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_GCC_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/gpu.hpp b/third_party/boost/boost/mpl/aux_/config/gpu.hpp
new file mode 100644
index 0000000..0e5ed78
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/gpu.hpp
@@ -0,0 +1,35 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_GPU_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_GPU_HPP_INCLUDED
+
+// Copyright Eric Niebler 2014
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/config.hpp>
+
+#if !defined(BOOST_MPL_CFG_GPU_ENABLED) \
+
+#   define BOOST_MPL_CFG_GPU_ENABLED BOOST_GPU_ENABLED
+
+#endif
+
+#if defined __CUDACC__
+
+#    define BOOST_MPL_CFG_GPU 1
+
+#else
+
+#    define BOOST_MPL_CFG_GPU 0
+
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_GPU_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/has_apply.hpp b/third_party/boost/boost/mpl/aux_/config/has_apply.hpp
new file mode 100644
index 0000000..ec85046
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/has_apply.hpp
@@ -0,0 +1,32 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_HAS_APPLY_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_HAS_APPLY_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/has_xxx.hpp>
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_HAS_APPLY) \
+    && (   defined(BOOST_MPL_CFG_NO_HAS_XXX) \
+        || BOOST_WORKAROUND(__EDG_VERSION__, < 300) \
+        || BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
+        || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) \
+        )
+
+#   define BOOST_MPL_CFG_NO_HAS_APPLY
+
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_HAS_APPLY_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/has_xxx.hpp b/third_party/boost/boost/mpl/aux_/config/has_xxx.hpp
new file mode 100644
index 0000000..d9198a7
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/has_xxx.hpp
@@ -0,0 +1,34 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_HAS_XXX_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_HAS_XXX_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2004
+// Copyright David Abrahams 2002-2003
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/overload_resolution.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+// agurt, 11/jan/03: signals a stub-only 'has_xxx' implementation
+
+#if !defined(BOOST_MPL_CFG_NO_HAS_XXX) \
+    && (   defined(BOOST_MPL_CFG_BROKEN_OVERLOAD_RESOLUTION) \
+        || BOOST_WORKAROUND(__GNUC__, <= 2) \
+        || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) \
+        )
+
+#   define BOOST_MPL_CFG_NO_HAS_XXX
+#   define BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
+
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_HAS_XXX_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/integral.hpp b/third_party/boost/boost/mpl/aux_/config/integral.hpp
new file mode 100644
index 0000000..46ac9b2
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/integral.hpp
@@ -0,0 +1,38 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_INTEGRAL_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_INTEGRAL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if    !defined(BOOST_MPL_CFG_BCC_INTEGRAL_CONSTANTS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE) \
+    && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610))
+
+#   define BOOST_MPL_CFG_BCC_INTEGRAL_CONSTANTS
+
+#endif
+
+#if    !defined(BOOST_MPL_CFG_NO_NESTED_VALUE_ARITHMETIC) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE) \
+    && ( BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
+        || BOOST_WORKAROUND(__EDG_VERSION__, <= 238) \
+        )
+
+#   define BOOST_MPL_CFG_NO_NESTED_VALUE_ARITHMETIC
+
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_INTEGRAL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/intel.hpp b/third_party/boost/boost/mpl/aux_/config/intel.hpp
new file mode 100644
index 0000000..da01738
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/intel.hpp
@@ -0,0 +1,21 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_INTEL_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_INTEL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+
+// BOOST_INTEL_CXX_VERSION is defined here:
+#include <boost/config.hpp>
+
+#endif // BOOST_MPL_AUX_CONFIG_INTEL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/lambda.hpp b/third_party/boost/boost/mpl/aux_/config/lambda.hpp
new file mode 100644
index 0000000..b6d91b5
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/lambda.hpp
@@ -0,0 +1,32 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_LAMBDA_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_LAMBDA_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/ttp.hpp>
+#include <boost/mpl/aux_/config/ctps.hpp>
+
+// agurt, 15/jan/02: full-fledged implementation requires both
+// template template parameters _and_ partial specialization
+
+#if    !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) \
+    && (   defined(BOOST_MPL_CFG_NO_TEMPLATE_TEMPLATE_PARAMETERS) \
+        || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
+        )
+
+#   define BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
+
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_LAMBDA_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/msvc.hpp b/third_party/boost/boost/mpl/aux_/config/msvc.hpp
new file mode 100644
index 0000000..8b9ae41
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/msvc.hpp
@@ -0,0 +1,21 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_MSVC_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_MSVC_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+
+// BOOST_MSVC is defined here:
+#include <boost/config.hpp>
+
+#endif // BOOST_MPL_AUX_CONFIG_MSVC_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/msvc_typename.hpp b/third_party/boost/boost/mpl/aux_/config/msvc_typename.hpp
new file mode 100644
index 0000000..7577908
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/msvc_typename.hpp
@@ -0,0 +1,26 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_MSVC_TYPENAME_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_MSVC_TYPENAME_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+#   define BOOST_MSVC_TYPENAME
+#else
+#   define BOOST_MSVC_TYPENAME typename
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_MSVC_TYPENAME_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/nttp.hpp b/third_party/boost/boost/mpl/aux_/config/nttp.hpp
new file mode 100644
index 0000000..85233ef
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/nttp.hpp
@@ -0,0 +1,41 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_NTTP_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_NTTP_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+// MSVC 6.5 ICE-s on the code as simple as this (see "aux_/nttp_decl.hpp"
+// for a workaround):
+//
+//    namespace std {
+//    template< typename Char > struct string;
+//    }
+//
+//    void foo(std::string<char>);
+//
+//    namespace boost { namespace mpl {
+//    template< int > struct arg;
+//    }}
+
+#if    !defined(BOOST_MPL_CFG_NTTP_BUG) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE) \
+    && BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+
+#   define BOOST_MPL_CFG_NTTP_BUG
+
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_NTTP_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/overload_resolution.hpp b/third_party/boost/boost/mpl/aux_/config/overload_resolution.hpp
new file mode 100644
index 0000000..8ac8259
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/overload_resolution.hpp
@@ -0,0 +1,29 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_OVERLOAD_RESOLUTION_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_OVERLOAD_RESOLUTION_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if    !defined(BOOST_MPL_CFG_BROKEN_OVERLOAD_RESOLUTION) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE) \
+    && (   BOOST_WORKAROUND(__BORLANDC__, < 0x590) \
+        || BOOST_WORKAROUND(__MWERKS__, < 0x3001) \
+        )
+
+#   define BOOST_MPL_CFG_BROKEN_OVERLOAD_RESOLUTION
+
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_OVERLOAD_RESOLUTION_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/pp_counter.hpp b/third_party/boost/boost/mpl/aux_/config/pp_counter.hpp
new file mode 100644
index 0000000..a0d1340
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/pp_counter.hpp
@@ -0,0 +1,26 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_PP_COUNTER_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_PP_COUNTER_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2006
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_AUX_PP_COUNTER)
+#   include <boost/mpl/aux_/config/msvc.hpp>
+#   if BOOST_WORKAROUND(BOOST_MSVC, >= 1300)
+#       define BOOST_MPL_AUX_PP_COUNTER() __COUNTER__
+#   else
+#       define BOOST_MPL_AUX_PP_COUNTER() __LINE__
+#   endif
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_PP_COUNTER_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/preprocessor.hpp b/third_party/boost/boost/mpl/aux_/config/preprocessor.hpp
new file mode 100644
index 0000000..1522724
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/preprocessor.hpp
@@ -0,0 +1,39 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_PREPROCESSOR_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_PREPROCESSOR_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if !defined(BOOST_MPL_CFG_BROKEN_PP_MACRO_EXPANSION) \
+    && (   BOOST_WORKAROUND(__MWERKS__, <= 0x3003) \
+        || BOOST_WORKAROUND(__BORLANDC__, < 0x582) \
+        || BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(502)) \
+        )
+
+#   define BOOST_MPL_CFG_BROKEN_PP_MACRO_EXPANSION
+
+#endif
+
+#if !defined(BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES)
+#   define BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES
+#endif
+
+#if !defined(BOOST_NEEDS_TOKEN_PASTING_OP_FOR_TOKENS_JUXTAPOSING) \
+    && BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840))
+#   define BOOST_NEEDS_TOKEN_PASTING_OP_FOR_TOKENS_JUXTAPOSING
+#endif
+
+
+#endif // BOOST_MPL_AUX_CONFIG_PREPROCESSOR_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/static_constant.hpp b/third_party/boost/boost/mpl/aux_/config/static_constant.hpp
new file mode 100644
index 0000000..90b5ce5
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/static_constant.hpp
@@ -0,0 +1,25 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_STATIC_CONSTANT_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_STATIC_CONSTANT_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+// BOOST_STATIC_CONSTANT is defined here:
+#   include <boost/config.hpp>
+#else
+// undef the macro for the preprocessing mode
+#   undef BOOST_STATIC_CONSTANT
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_STATIC_CONSTANT_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/ttp.hpp b/third_party/boost/boost/mpl/aux_/config/ttp.hpp
new file mode 100644
index 0000000..cb68533
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/ttp.hpp
@@ -0,0 +1,41 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_TTP_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_TTP_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/gcc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_TEMPLATE_TEMPLATE_PARAMETERS) \
+    && ( defined(BOOST_NO_TEMPLATE_TEMPLATES) \
+      || BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x590) ) \
+       )
+
+#   define BOOST_MPL_CFG_NO_TEMPLATE_TEMPLATE_PARAMETERS
+
+#endif
+
+
+#if    !defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE) \
+    && (   BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, BOOST_TESTED_AT(0x0302)) \
+        || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \
+        )
+
+#   define BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING
+
+#endif
+
+#endif // BOOST_MPL_AUX_CONFIG_TTP_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/use_preprocessed.hpp b/third_party/boost/boost/mpl/aux_/config/use_preprocessed.hpp
new file mode 100644
index 0000000..a741e55
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/use_preprocessed.hpp
@@ -0,0 +1,19 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_USE_PREPROCESSED_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_USE_PREPROCESSED_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+// #define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+
+#endif // BOOST_MPL_AUX_CONFIG_USE_PREPROCESSED_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/config/workaround.hpp b/third_party/boost/boost/mpl/aux_/config/workaround.hpp
new file mode 100644
index 0000000..b379bfd
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/config/workaround.hpp
@@ -0,0 +1,19 @@
+
+#ifndef BOOST_MPL_AUX_CONFIG_WORKAROUND_HPP_INCLUDED
+#define BOOST_MPL_AUX_CONFIG_WORKAROUND_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/detail/workaround.hpp>
+
+#endif // BOOST_MPL_AUX_CONFIG_WORKAROUND_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/empty_impl.hpp b/third_party/boost/boost/mpl/aux_/empty_impl.hpp
new file mode 100644
index 0000000..aeb0caa
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/empty_impl.hpp
@@ -0,0 +1,43 @@
+
+#ifndef BOOST_MPL_AUX_EMPTY_IMPL_HPP_INCLUDED
+#define BOOST_MPL_AUX_EMPTY_IMPL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/empty_fwd.hpp>
+#include <boost/mpl/begin_end.hpp>
+#include <boost/mpl/aux_/traits_lambda_spec.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace mpl {
+
+// default implementation; conrete sequences might override it by
+// specializing either the 'empty_impl' or the primary 'empty' template
+
+template< typename Tag >
+struct empty_impl
+{
+    template< typename Sequence > struct apply
+        : is_same<
+              typename begin<Sequence>::type
+            , typename end<Sequence>::type
+            >
+    {
+    };
+};
+
+BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1,empty_impl)
+
+}}
+
+#endif // BOOST_MPL_AUX_EMPTY_IMPL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/find_if_pred.hpp b/third_party/boost/boost/mpl/aux_/find_if_pred.hpp
new file mode 100644
index 0000000..ebff52a
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/find_if_pred.hpp
@@ -0,0 +1,31 @@
+
+#ifndef BOOST_MPL_AUX_FIND_IF_PRED_HPP_INCLUDED
+#define BOOST_MPL_AUX_FIND_IF_PRED_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+// Copyright Eric Friedman 2002
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+#include <boost/mpl/aux_/iter_apply.hpp>
+#include <boost/mpl/not.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+
+template< typename Predicate >
+struct find_if_pred
+{
+    template< typename Iterator >
+    struct apply
+    {
+        typedef not_< aux::iter_apply1<Predicate,Iterator> > type;
+    };
+};
+
+}}}
+
+#endif // BOOST_MPL_AUX_FIND_IF_PRED_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/fold_impl.hpp b/third_party/boost/boost/mpl/aux_/fold_impl.hpp
new file mode 100644
index 0000000..75ff7ba
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/fold_impl.hpp
@@ -0,0 +1,43 @@
+
+#ifndef BOOST_MPL_AUX_FOLD_IMPL_HPP_INCLUDED
+#define BOOST_MPL_AUX_FOLD_IMPL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/next_prior.hpp>
+#   include <boost/mpl/apply.hpp>
+#   include <boost/mpl/deref.hpp>
+#   include <boost/mpl/aux_/config/ctps.hpp>
+#   if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+#       include <boost/mpl/if.hpp>
+#       include <boost/type_traits/is_same.hpp>
+#   endif
+#endif
+
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER fold_impl.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   define AUX778076_FOLD_IMPL_OP(iter) typename deref<iter>::type
+#   define AUX778076_FOLD_IMPL_NAME_PREFIX fold
+#   include <boost/mpl/aux_/fold_impl_body.hpp>
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_AUX_FOLD_IMPL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/front_impl.hpp b/third_party/boost/boost/mpl/aux_/front_impl.hpp
new file mode 100644
index 0000000..6e4ef74
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/front_impl.hpp
@@ -0,0 +1,41 @@
+
+#ifndef BOOST_MPL_AUX_FRONT_IMPL_HPP_INCLUDED
+#define BOOST_MPL_AUX_FRONT_IMPL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/front_fwd.hpp>
+#include <boost/mpl/begin_end.hpp>
+#include <boost/mpl/deref.hpp>
+#include <boost/mpl/aux_/traits_lambda_spec.hpp>
+
+namespace boost { namespace mpl {
+
+// default implementation; conrete sequences might override it by
+// specializing either the 'front_impl' or the primary 'front' template
+
+template< typename Tag >
+struct front_impl
+{
+    template< typename Sequence > struct apply
+    {
+        typedef typename begin<Sequence>::type iter_;
+        typedef typename deref<iter_>::type type;
+    };
+};
+
+BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1,front_impl)
+
+}}
+
+#endif // BOOST_MPL_AUX_FRONT_IMPL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/full_lambda.hpp b/third_party/boost/boost/mpl/aux_/full_lambda.hpp
new file mode 100644
index 0000000..0218781
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/full_lambda.hpp
@@ -0,0 +1,354 @@
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+///// header body
+
+#ifndef BOOST_MPL_AUX_FULL_LAMBDA_HPP_INCLUDED
+#define BOOST_MPL_AUX_FULL_LAMBDA_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/lambda_fwd.hpp>
+#   include <boost/mpl/bind_fwd.hpp>
+#   include <boost/mpl/protect.hpp>
+#   include <boost/mpl/quote.hpp>
+#   include <boost/mpl/arg.hpp>
+#   include <boost/mpl/bool.hpp>
+#   include <boost/mpl/int_fwd.hpp>
+#   include <boost/mpl/aux_/template_arity.hpp>
+#   include <boost/mpl/aux_/na_spec.hpp>
+#   include <boost/mpl/aux_/config/ttp.hpp>
+#   if defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING)
+#       include <boost/mpl/if.hpp>
+#   endif
+#endif
+
+#include <boost/mpl/aux_/lambda_arity_param.hpp>
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER full_lambda.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   include <boost/mpl/limits/arity.hpp>
+#   include <boost/mpl/aux_/preprocessor/default_params.hpp>
+#   include <boost/mpl/aux_/preprocessor/params.hpp>
+#   include <boost/mpl/aux_/preprocessor/enum.hpp>
+#   include <boost/mpl/aux_/preprocessor/repeat.hpp>
+#   include <boost/mpl/aux_/config/dmc_ambiguous_ctps.hpp>
+
+#   include <boost/preprocessor/iterate.hpp>
+#   include <boost/preprocessor/comma_if.hpp>
+#   include <boost/preprocessor/inc.hpp>
+#   include <boost/preprocessor/cat.hpp>
+
+namespace boost { namespace mpl {
+
+// local macros, #undef-ined at the end of the header
+#   define AUX778076_LAMBDA_PARAMS(i_, param) \
+    BOOST_MPL_PP_PARAMS(i_, param) \
+    /**/
+
+#   define AUX778076_BIND_PARAMS(param) \
+    BOOST_MPL_PP_PARAMS( \
+          BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
+        , param \
+        ) \
+    /**/
+
+#   define AUX778076_BIND_N_PARAMS(i_, param) \
+    BOOST_PP_COMMA_IF(i_) \
+    BOOST_MPL_PP_PARAMS(i_, param) \
+    /**/
+
+#   define AUX778076_ARITY_PARAM(param) \
+    BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(param) \
+    /**/
+
+
+#define n_ BOOST_MPL_LIMIT_METAFUNCTION_ARITY
+namespace aux {
+
+template<
+      BOOST_MPL_PP_DEFAULT_PARAMS(n_,bool C,false)
+    >
+struct lambda_or
+    : true_
+{
+};
+
+template<>
+struct lambda_or< BOOST_MPL_PP_ENUM(n_,false) >
+    : false_
+{
+};
+
+} // namespace aux
+#undef n_
+
+template<
+      typename T
+    , typename Tag
+    AUX778076_ARITY_PARAM(typename Arity)
+    >
+struct lambda
+{
+    typedef false_ is_le;
+    typedef T result_;
+    typedef T type;
+};
+
+template<
+      typename T
+    >
+struct is_lambda_expression
+    : lambda<T>::is_le
+{
+};
+
+
+template< int N, typename Tag >
+struct lambda< arg<N>,Tag AUX778076_ARITY_PARAM(int_<-1>) >
+{
+    typedef true_ is_le;
+    typedef mpl::arg<N> result_; // qualified for the sake of MIPSpro 7.41
+    typedef mpl::protect<result_> type;
+};
+
+
+#define BOOST_PP_ITERATION_PARAMS_1 \
+    (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, <boost/mpl/aux_/full_lambda.hpp>))
+#include BOOST_PP_ITERATE()
+
+/// special case for 'protect'
+template< typename T, typename Tag >
+struct lambda< mpl::protect<T>,Tag AUX778076_ARITY_PARAM(int_<1>) >
+{
+    typedef false_ is_le;
+    typedef mpl::protect<T> result_;
+    typedef result_ type;
+};
+
+/// specializations for the main 'bind' form
+template<
+      typename F, AUX778076_BIND_PARAMS(typename T)
+    , typename Tag
+    >
+struct lambda<
+          bind<F,AUX778076_BIND_PARAMS(T)>
+        , Tag
+        AUX778076_ARITY_PARAM(int_<BOOST_PP_INC(BOOST_MPL_LIMIT_METAFUNCTION_ARITY)>)
+        >
+{
+    typedef false_ is_le;
+    typedef bind<F, AUX778076_BIND_PARAMS(T)> result_;
+    typedef result_ type;
+};
+
+
+#if defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING)
+
+template<
+      typename F
+    , typename Tag1
+    , typename Tag2
+    , typename Arity
+    >
+struct lambda<
+          lambda<F,Tag1,Arity>
+        , Tag2
+        , int_<3>
+        >
+{
+    typedef lambda< F,Tag2 > l1;
+    typedef lambda< Tag1,Tag2 > l2;
+
+    typedef typename l1::is_le is_le;
+    typedef bind1< quote1<aux::template_arity>, typename l1::result_ > arity_;
+    typedef lambda< typename if_<is_le,arity_,Arity>::type,Tag2 > l3;
+
+    typedef aux::le_result3<is_le, Tag2, mpl::lambda, l1, l2, l3> le_result_;
+    typedef typename le_result_::result_ result_;
+    typedef typename le_result_::type type;
+};
+
+#elif !defined(BOOST_MPL_CFG_DMC_AMBIGUOUS_CTPS)
+
+/// workaround for MWCW 8.3+/EDG < 303, leads to ambiguity on Digital Mars
+template<
+      typename F, typename Tag1, typename Tag2
+    >
+struct lambda<
+          lambda< F,Tag1 >
+        , Tag2
+        >
+{
+    typedef lambda< F,Tag2 > l1;
+    typedef lambda< Tag1,Tag2 > l2;
+
+    typedef typename l1::is_le is_le;
+    typedef aux::le_result2<is_le, Tag2, mpl::lambda, l1, l2> le_result_;
+    typedef typename le_result_::result_ result_;
+    typedef typename le_result_::type type;
+};
+
+#endif
+
+#   undef AUX778076_ARITY_PARAM
+#   undef AUX778076_BIND_N_PARAMS
+#   undef AUX778076_BIND_PARAMS
+#   undef AUX778076_LAMBDA_PARAMS
+
+#if !defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING)
+BOOST_MPL_AUX_NA_SPEC(2, lambda)
+#else
+BOOST_MPL_AUX_NA_SPEC2(2, 3, lambda)
+#endif
+
+}}
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_AUX_FULL_LAMBDA_HPP_INCLUDED
+
+///// iteration, depth == 1
+
+// For gcc 4.4 compatability, we must include the
+// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
+#else // BOOST_PP_IS_ITERATING
+#if BOOST_PP_ITERATION_DEPTH() == 1
+#define i_ BOOST_PP_FRAME_ITERATION(1)
+
+#if i_ > 0
+
+namespace aux {
+
+#   define AUX778076_RESULT(unused, i_, T) \
+    BOOST_PP_COMMA_IF(i_) \
+    typename BOOST_PP_CAT(T, BOOST_PP_INC(i_))::result_ \
+    /**/
+
+#   define AUX778076_TYPE(unused, i_, T) \
+    BOOST_PP_COMMA_IF(i_) \
+    typename BOOST_PP_CAT(T, BOOST_PP_INC(i_))::type \
+    /**/
+
+template<
+      typename IsLE, typename Tag
+    , template< AUX778076_LAMBDA_PARAMS(i_, typename P) > class F
+    , AUX778076_LAMBDA_PARAMS(i_, typename L)
+    >
+struct BOOST_PP_CAT(le_result,i_)
+{
+    typedef F<
+          BOOST_MPL_PP_REPEAT(i_, AUX778076_TYPE, L)
+        > result_;
+
+    typedef result_ type;
+};
+
+template<
+      typename Tag
+    , template< AUX778076_LAMBDA_PARAMS(i_, typename P) > class F
+    , AUX778076_LAMBDA_PARAMS(i_, typename L)
+    >
+struct BOOST_PP_CAT(le_result,i_)< true_,Tag,F,AUX778076_LAMBDA_PARAMS(i_, L) >
+{
+    typedef BOOST_PP_CAT(bind,i_)<
+          BOOST_PP_CAT(quote,i_)<F,Tag>
+        , BOOST_MPL_PP_REPEAT(i_, AUX778076_RESULT, L)
+        > result_;
+
+    typedef mpl::protect<result_> type;
+};
+
+#   undef AUX778076_TYPE
+#   undef AUX778076_RESULT
+
+} // namespace aux
+
+
+#   define AUX778076_LAMBDA_TYPEDEF(unused, i_, T) \
+    typedef lambda< BOOST_PP_CAT(T, BOOST_PP_INC(i_)), Tag > \
+        BOOST_PP_CAT(l,BOOST_PP_INC(i_)); \
+/**/
+
+#   define AUX778076_IS_LE_TYPEDEF(unused, i_, unused2) \
+    typedef typename BOOST_PP_CAT(l,BOOST_PP_INC(i_))::is_le \
+        BOOST_PP_CAT(is_le,BOOST_PP_INC(i_)); \
+/**/
+
+#   define AUX778076_IS_LAMBDA_EXPR(unused, i_, unused2) \
+    BOOST_PP_COMMA_IF(i_) \
+    BOOST_PP_CAT(is_le,BOOST_PP_INC(i_))::value \
+/**/
+
+template<
+      template< AUX778076_LAMBDA_PARAMS(i_, typename P) > class F
+    , AUX778076_LAMBDA_PARAMS(i_, typename T)
+    , typename Tag
+    >
+struct lambda<
+          F<AUX778076_LAMBDA_PARAMS(i_, T)>
+        , Tag
+        AUX778076_ARITY_PARAM(int_<i_>)
+        >
+{
+    BOOST_MPL_PP_REPEAT(i_, AUX778076_LAMBDA_TYPEDEF, T)
+    BOOST_MPL_PP_REPEAT(i_, AUX778076_IS_LE_TYPEDEF, unused)
+
+    typedef typename aux::lambda_or<
+          BOOST_MPL_PP_REPEAT(i_, AUX778076_IS_LAMBDA_EXPR, unused)
+        >::type is_le;
+
+    typedef aux::BOOST_PP_CAT(le_result,i_)<
+          is_le, Tag, F, AUX778076_LAMBDA_PARAMS(i_, l)
+        > le_result_;
+
+    typedef typename le_result_::result_ result_;
+    typedef typename le_result_::type type;
+};
+
+
+#   undef AUX778076_IS_LAMBDA_EXPR
+#   undef AUX778076_IS_LE_TYPEDEF
+#   undef AUX778076_LAMBDA_TYPEDEF
+
+#endif // i_ > 0
+
+template<
+      typename F AUX778076_BIND_N_PARAMS(i_, typename T)
+    , typename Tag
+    >
+struct lambda<
+          BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_, T)>
+        , Tag
+        AUX778076_ARITY_PARAM(int_<BOOST_PP_INC(i_)>)
+        >
+{
+    typedef false_ is_le;
+    typedef BOOST_PP_CAT(bind,i_)<
+          F
+        AUX778076_BIND_N_PARAMS(i_, T)
+        > result_;
+
+    typedef result_ type;
+};
+
+#undef i_
+#endif // BOOST_PP_ITERATION_DEPTH()
+#endif // BOOST_PP_IS_ITERATING
diff --git a/third_party/boost/boost/mpl/aux_/has_apply.hpp b/third_party/boost/boost/mpl/aux_/has_apply.hpp
new file mode 100644
index 0000000..0bc3b52
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/has_apply.hpp
@@ -0,0 +1,32 @@
+
+#ifndef BOOST_MPL_AUX_HAS_APPLY_HPP_INCLUDED
+#define BOOST_MPL_AUX_HAS_APPLY_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/has_xxx.hpp>
+#include <boost/mpl/aux_/config/has_apply.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+#if !defined(BOOST_MPL_CFG_NO_HAS_APPLY)
+BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_apply, apply, false)
+#else
+template< typename T, typename fallback_ = false_ >
+struct has_apply
+    : fallback_
+{
+};
+#endif
+}}}
+
+#endif // BOOST_MPL_AUX_HAS_APPLY_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/has_begin.hpp b/third_party/boost/boost/mpl/aux_/has_begin.hpp
new file mode 100644
index 0000000..bfb0fee
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/has_begin.hpp
@@ -0,0 +1,23 @@
+
+#ifndef BOOST_MPL_AUX_HAS_BEGIN_HPP_INCLUDED
+#define BOOST_MPL_AUX_HAS_BEGIN_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/has_xxx.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_begin, begin, true)
+}}}
+
+#endif // BOOST_MPL_AUX_HAS_BEGIN_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/has_size.hpp b/third_party/boost/boost/mpl/aux_/has_size.hpp
new file mode 100644
index 0000000..83dbfe7
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/has_size.hpp
@@ -0,0 +1,23 @@
+
+#ifndef BOOST_MPL_AUX_HAS_SIZE_HPP_INCLUDED
+#define BOOST_MPL_AUX_HAS_SIZE_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/has_xxx.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+BOOST_MPL_HAS_XXX_TRAIT_DEF(size)
+}}}
+
+#endif // BOOST_MPL_AUX_HAS_SIZE_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/has_tag.hpp b/third_party/boost/boost/mpl/aux_/has_tag.hpp
new file mode 100644
index 0000000..55154a1
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/has_tag.hpp
@@ -0,0 +1,23 @@
+
+#ifndef BOOST_MPL_AUX_HAS_TAG_HPP_INCLUDED
+#define BOOST_MPL_AUX_HAS_TAG_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/has_xxx.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_tag, tag, false)
+}}}
+
+#endif // BOOST_MPL_AUX_HAS_TAG_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/has_type.hpp b/third_party/boost/boost/mpl/aux_/has_type.hpp
new file mode 100644
index 0000000..6f37667
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/has_type.hpp
@@ -0,0 +1,23 @@
+
+#ifndef BOOST_MPL_AUX_HAS_TYPE_HPP_INCLUDED
+#define BOOST_MPL_AUX_HAS_TYPE_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/has_xxx.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_type, type, true)
+}}}
+
+#endif // BOOST_MPL_AUX_HAS_TYPE_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/include_preprocessed.hpp b/third_party/boost/boost/mpl/aux_/include_preprocessed.hpp
new file mode 100644
index 0000000..7698b5a
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/include_preprocessed.hpp
@@ -0,0 +1,42 @@
+
+// NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION
+
+// Copyright Aleksey Gurtovoy 2000-2006
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/compiler.hpp>
+#include <boost/mpl/aux_/config/preprocessor.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/stringize.hpp>
+
+#if !defined(BOOST_NEEDS_TOKEN_PASTING_OP_FOR_TOKENS_JUXTAPOSING)
+#   define AUX778076_PREPROCESSED_HEADER \
+    BOOST_MPL_CFG_COMPILER_DIR/BOOST_MPL_PREPROCESSED_HEADER \
+/**/
+#else
+#   define AUX778076_PREPROCESSED_HEADER \
+    BOOST_PP_CAT(BOOST_MPL_CFG_COMPILER_DIR,/)##BOOST_MPL_PREPROCESSED_HEADER \
+/**/
+#endif
+
+#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(700))
+#   define AUX778076_INCLUDE_STRING BOOST_PP_STRINGIZE(boost/mpl/aux_/preprocessed/AUX778076_PREPROCESSED_HEADER)
+#   include AUX778076_INCLUDE_STRING
+#   undef AUX778076_INCLUDE_STRING
+#else
+#   include BOOST_PP_STRINGIZE(boost/mpl/aux_/preprocessed/AUX778076_PREPROCESSED_HEADER)
+#endif
+
+#   undef AUX778076_PREPROCESSED_HEADER
+
+#undef BOOST_MPL_PREPROCESSED_HEADER
diff --git a/third_party/boost/boost/mpl/aux_/inserter_algorithm.hpp b/third_party/boost/boost/mpl/aux_/inserter_algorithm.hpp
new file mode 100644
index 0000000..21f58b3
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/inserter_algorithm.hpp
@@ -0,0 +1,159 @@
+
+#ifndef BOOST_MPL_AUX_INSERTER_ALGORITHM_HPP_INCLUDED
+#define BOOST_MPL_AUX_INSERTER_ALGORITHM_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2003-2004
+// Copyright David Abrahams 2003-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/back_inserter.hpp>
+#include <boost/mpl/front_inserter.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/mpl/push_front.hpp>
+#include <boost/mpl/back_inserter.hpp>
+#include <boost/mpl/front_inserter.hpp>
+#include <boost/mpl/clear.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/aux_/na.hpp>
+#include <boost/mpl/aux_/common_name_wknd.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/preprocessor/params.hpp>
+#include <boost/mpl/aux_/preprocessor/default_params.hpp>
+#include <boost/mpl/aux_/config/ctps.hpp>
+
+#include <boost/preprocessor/arithmetic/dec.hpp>
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+#   define BOOST_MPL_AUX_INSERTER_ALGORITHM_DEF(arity, name) \
+BOOST_MPL_AUX_COMMON_NAME_WKND(name) \
+template< \
+      BOOST_MPL_PP_DEFAULT_PARAMS(arity, typename P, na) \
+    > \
+struct name \
+    : aux::name##_impl<BOOST_MPL_PP_PARAMS(arity, P)> \
+{ \
+}; \
+\
+template< \
+      BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), typename P) \
+    > \
+struct name< BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P),na > \
+    : if_< has_push_back< typename clear<P1>::type> \
+        , aux::name##_impl< \
+              BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \
+            , back_inserter< typename clear<P1>::type > \
+            > \
+        , aux::reverse_##name##_impl< \
+              BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \
+            , front_inserter< typename clear<P1>::type > \
+            > \
+        >::type \
+{ \
+}; \
+\
+template< \
+      BOOST_MPL_PP_DEFAULT_PARAMS(arity, typename P, na) \
+    > \
+struct reverse_##name \
+    : aux::reverse_##name##_impl<BOOST_MPL_PP_PARAMS(arity, P)> \
+{ \
+}; \
+\
+template< \
+      BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), typename P) \
+    > \
+struct reverse_##name< BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P),na > \
+    : if_< has_push_back<P1> \
+        , aux::reverse_##name##_impl< \
+              BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \
+            , back_inserter< typename clear<P1>::type > \
+            > \
+        , aux::name##_impl< \
+              BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \
+            , front_inserter< typename clear<P1>::type > \
+            > \
+        >::type \
+{ \
+}; \
+BOOST_MPL_AUX_NA_SPEC(arity, name) \
+BOOST_MPL_AUX_NA_SPEC(arity, reverse_##name) \
+/**/
+
+#else
+
+#   define BOOST_MPL_AUX_INSERTER_ALGORITHM_DEF(arity, name) \
+BOOST_MPL_AUX_COMMON_NAME_WKND(name) \
+template< \
+      BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), typename P) \
+    > \
+struct def_##name##_impl \
+    : if_< has_push_back<P1> \
+        , aux::name##_impl< \
+              BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \
+            , back_inserter< typename clear<P1>::type > \
+            > \
+        , aux::reverse_##name##_impl< \
+              BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \
+            , front_inserter< typename clear<P1>::type > \
+            > \
+        >::type \
+{ \
+}; \
+\
+template< \
+      BOOST_MPL_PP_DEFAULT_PARAMS(arity, typename P, na) \
+    > \
+struct name \
+{ \
+    typedef typename eval_if< \
+          is_na<BOOST_PP_CAT(P, arity)> \
+        , def_##name##_impl<BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P)> \
+        , aux::name##_impl<BOOST_MPL_PP_PARAMS(arity, P)> \
+        >::type type; \
+}; \
+\
+template< \
+      BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), typename P) \
+    > \
+struct def_reverse_##name##_impl \
+    : if_< has_push_back<P1> \
+        , aux::reverse_##name##_impl< \
+              BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \
+            , back_inserter< typename clear<P1>::type > \
+            > \
+        , aux::name##_impl< \
+              BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P) \
+            , front_inserter< typename clear<P1>::type > \
+            > \
+        >::type \
+{ \
+}; \
+template< \
+      BOOST_MPL_PP_DEFAULT_PARAMS(arity, typename P, na) \
+    > \
+struct reverse_##name \
+{ \
+    typedef typename eval_if< \
+          is_na<BOOST_PP_CAT(P, arity)> \
+        , def_reverse_##name##_impl<BOOST_MPL_PP_PARAMS(BOOST_PP_DEC(arity), P)> \
+        , aux::reverse_##name##_impl<BOOST_MPL_PP_PARAMS(arity, P)> \
+        >::type type; \
+}; \
+BOOST_MPL_AUX_NA_SPEC(arity, name) \
+BOOST_MPL_AUX_NA_SPEC(arity, reverse_##name) \
+/**/
+
+#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+#endif // BOOST_MPL_AUX_INSERTER_ALGORITHM_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/integral_wrapper.hpp b/third_party/boost/boost/mpl/aux_/integral_wrapper.hpp
new file mode 100644
index 0000000..8840958
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/integral_wrapper.hpp
@@ -0,0 +1,93 @@
+
+// Copyright Aleksey Gurtovoy 2000-2006
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+// NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION!
+
+#include <boost/mpl/integral_c_tag.hpp>
+#include <boost/mpl/aux_/static_cast.hpp>
+#include <boost/mpl/aux_/nttp_decl.hpp>
+#include <boost/mpl/aux_/config/static_constant.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#include <boost/preprocessor/cat.hpp>
+
+#if !defined(AUX_WRAPPER_NAME)
+#   define AUX_WRAPPER_NAME BOOST_PP_CAT(AUX_WRAPPER_VALUE_TYPE,_)
+#endif
+
+#if !defined(AUX_WRAPPER_PARAMS)
+#   define AUX_WRAPPER_PARAMS(N) BOOST_MPL_AUX_NTTP_DECL(AUX_WRAPPER_VALUE_TYPE, N)
+#endif
+
+#if !defined(AUX_WRAPPER_INST)
+#   if BOOST_WORKAROUND(__MWERKS__, <= 0x2407)
+#       define AUX_WRAPPER_INST(value) AUX_WRAPPER_NAME< value >
+#   else
+#       define AUX_WRAPPER_INST(value) BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::AUX_WRAPPER_NAME< value >
+#   endif
+#endif
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+
+template< AUX_WRAPPER_PARAMS(N) >
+struct AUX_WRAPPER_NAME
+{
+    BOOST_STATIC_CONSTANT(AUX_WRAPPER_VALUE_TYPE, value = N);
+// agurt, 08/mar/03: SGI MIPSpro C++ workaround, have to #ifdef because some
+// other compilers (e.g. MSVC) are not particulary happy about it
+#if BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
+    typedef struct AUX_WRAPPER_NAME type;
+#else
+    typedef AUX_WRAPPER_NAME type;
+#endif
+    typedef AUX_WRAPPER_VALUE_TYPE value_type;
+    typedef integral_c_tag tag;
+
+// have to #ifdef here: some compilers don't like the 'N + 1' form (MSVC),
+// while some other don't like 'value + 1' (Borland), and some don't like
+// either
+#if BOOST_WORKAROUND(__EDG_VERSION__, <= 243)
+ private:
+    BOOST_STATIC_CONSTANT(AUX_WRAPPER_VALUE_TYPE, next_value = BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N + 1)));
+    BOOST_STATIC_CONSTANT(AUX_WRAPPER_VALUE_TYPE, prior_value = BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N - 1)));
+ public:
+    typedef AUX_WRAPPER_INST(next_value) next;
+    typedef AUX_WRAPPER_INST(prior_value) prior;
+#elif BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x561)) \
+    || BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(502)) \
+    || (BOOST_WORKAROUND(__HP_aCC, <= 53800) && (BOOST_WORKAROUND(__hpxstd98, != 1)))
+    typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N + 1)) ) next;
+    typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (N - 1)) ) prior;
+#else
+    typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (value + 1)) ) next;
+    typedef AUX_WRAPPER_INST( BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (value - 1)) ) prior;
+#endif
+
+    // enables uniform function call syntax for families of overloaded
+    // functions that return objects of both arithmetic ('int', 'long',
+    // 'double', etc.) and wrapped integral types (for an example, see
+    // "mpl/example/power.cpp")
+    BOOST_CONSTEXPR operator AUX_WRAPPER_VALUE_TYPE() const { return static_cast<AUX_WRAPPER_VALUE_TYPE>(this->value); }
+};
+
+#if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
+template< AUX_WRAPPER_PARAMS(N) >
+AUX_WRAPPER_VALUE_TYPE const AUX_WRAPPER_INST(N)::value;
+#endif
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+
+#undef AUX_WRAPPER_NAME
+#undef AUX_WRAPPER_PARAMS
+#undef AUX_WRAPPER_INST
+#undef AUX_WRAPPER_VALUE_TYPE
diff --git a/third_party/boost/boost/mpl/aux_/is_msvc_eti_arg.hpp b/third_party/boost/boost/mpl/aux_/is_msvc_eti_arg.hpp
new file mode 100644
index 0000000..b555d91
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/is_msvc_eti_arg.hpp
@@ -0,0 +1,64 @@
+
+#ifndef BOOST_MPL_AUX_IS_MSVC_ETI_ARG_HPP_INCLUDED
+#define BOOST_MPL_AUX_IS_MSVC_ETI_ARG_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/yes_no.hpp>
+#include <boost/mpl/aux_/config/eti.hpp>
+#include <boost/mpl/aux_/config/static_constant.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+
+#if defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
+
+#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
+
+template< typename T >
+struct is_msvc_eti_arg
+{
+    BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+#else // BOOST_MPL_CFG_MSVC_60_ETI_BUG
+
+struct eti_int_convertible
+{
+    eti_int_convertible(int);
+};
+
+template< typename T >
+struct is_msvc_eti_arg
+{
+    static no_tag test(...);
+    static yes_tag test(eti_int_convertible);
+    static T& get();
+
+    BOOST_STATIC_CONSTANT(bool, value =
+          sizeof(test(get())) == sizeof(yes_tag)
+        );
+};
+
+#endif
+
+template<>
+struct is_msvc_eti_arg<int>
+{
+    BOOST_STATIC_CONSTANT(bool, value = true);
+};
+
+#endif // BOOST_MPL_CFG_MSVC_ETI_BUG
+
+}}}
+
+#endif // BOOST_MPL_AUX_IS_MSVC_ETI_ARG_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/iter_apply.hpp b/third_party/boost/boost/mpl/aux_/iter_apply.hpp
new file mode 100644
index 0000000..edbcd27
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/iter_apply.hpp
@@ -0,0 +1,47 @@
+
+#ifndef BOOST_MPL_ITER_APPLY_HPP_INCLUDED
+#define BOOST_MPL_ITER_APPLY_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/apply.hpp>
+#include <boost/mpl/deref.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+
+template<
+      typename F
+    , typename Iterator
+    >
+struct iter_apply1
+    : apply1< F,typename deref<Iterator>::type >
+{
+};
+
+template<
+      typename F
+    , typename Iterator1
+    , typename Iterator2
+    >
+struct iter_apply2
+    : apply2<
+          F
+        , typename deref<Iterator1>::type
+        , typename deref<Iterator2>::type
+        >
+{
+};
+
+}}}
+
+#endif // BOOST_MPL_ITER_APPLY_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/iter_fold_if_impl.hpp b/third_party/boost/boost/mpl/aux_/iter_fold_if_impl.hpp
new file mode 100644
index 0000000..66e2e33
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/iter_fold_if_impl.hpp
@@ -0,0 +1,210 @@
+
+#ifndef BOOST_MPL_AUX_ITER_FOLD_IF_IMPL_HPP_INCLUDED
+#define BOOST_MPL_AUX_ITER_FOLD_IF_IMPL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+// Copyright David Abrahams 2001-2002
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/identity.hpp>
+#   include <boost/mpl/next.hpp>
+#   include <boost/mpl/if.hpp>
+#   include <boost/mpl/apply.hpp>
+#   include <boost/mpl/aux_/value_wknd.hpp>
+#endif
+
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER iter_fold_if_impl.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   include <boost/mpl/limits/unrolling.hpp>
+#   include <boost/preprocessor/arithmetic/sub.hpp>
+#   include <boost/preprocessor/repeat.hpp>
+#   include <boost/preprocessor/inc.hpp>
+#   include <boost/preprocessor/dec.hpp>
+#   include <boost/preprocessor/cat.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+
+template< typename Iterator, typename State >
+struct iter_fold_if_null_step
+{
+    typedef State state;
+    typedef Iterator iterator;
+};
+
+template< bool >
+struct iter_fold_if_step_impl
+{
+    template<
+          typename Iterator
+        , typename State
+        , typename StateOp
+        , typename IteratorOp
+        >
+    struct result_
+    {
+        typedef typename apply2<StateOp,State,Iterator>::type state;
+        typedef typename IteratorOp::type iterator;
+    };
+};
+
+template<>
+struct iter_fold_if_step_impl<false>
+{
+    template<
+          typename Iterator
+        , typename State
+        , typename StateOp
+        , typename IteratorOp
+        >
+    struct result_
+    {
+        typedef State state;
+        typedef Iterator iterator;
+    };
+};
+
+// agurt, 25/jun/02: MSVC 6.5 workaround, had to get rid of inheritance
+// here and in 'iter_fold_if_backward_step', because sometimes it interfered
+// with the "early template instantiation bug" in _really_ ugly ways
+template<
+      typename Iterator
+    , typename State
+    , typename ForwardOp
+    , typename Predicate
+    >
+struct iter_fold_if_forward_step
+{
+    typedef typename apply2<Predicate,State,Iterator>::type not_last;
+    typedef typename iter_fold_if_step_impl<
+          BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value
+        >::template result_< Iterator,State,ForwardOp,mpl::next<Iterator> > impl_;
+
+    typedef typename impl_::state state;
+    typedef typename impl_::iterator iterator;
+};
+
+template<
+      typename Iterator
+    , typename State
+    , typename BackwardOp
+    , typename Predicate
+    >
+struct iter_fold_if_backward_step
+{
+    typedef typename apply2<Predicate,State,Iterator>::type not_last;
+    typedef typename iter_fold_if_step_impl<
+          BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value
+        >::template result_< Iterator,State,BackwardOp,identity<Iterator> > impl_;
+
+    typedef typename impl_::state state;
+    typedef typename impl_::iterator iterator;
+};
+
+
+// local macros, #undef-ined at the end of the header
+
+#   define AUX_ITER_FOLD_FORWARD_STEP(unused, i, unused2) \
+    typedef iter_fold_if_forward_step< \
+          typename BOOST_PP_CAT(forward_step,i)::iterator \
+        , typename BOOST_PP_CAT(forward_step,i)::state \
+        , ForwardOp \
+        , ForwardPredicate \
+        > BOOST_PP_CAT(forward_step, BOOST_PP_INC(i)); \
+    /**/
+
+#   define AUX_ITER_FOLD_BACKWARD_STEP_FUNC(i) \
+    typedef iter_fold_if_backward_step< \
+          typename BOOST_PP_CAT(forward_step,BOOST_PP_DEC(i))::iterator \
+        , typename BOOST_PP_CAT(backward_step,i)::state \
+        , BackwardOp \
+        , BackwardPredicate \
+        > BOOST_PP_CAT(backward_step,BOOST_PP_DEC(i)); \
+    /**/
+
+#   define AUX_ITER_FOLD_BACKWARD_STEP(unused, i, unused2) \
+    AUX_ITER_FOLD_BACKWARD_STEP_FUNC( \
+        BOOST_PP_SUB_D(1,BOOST_MPL_LIMIT_UNROLLING,i) \
+        ) \
+    /**/
+
+#   define AUX_LAST_FORWARD_STEP \
+    BOOST_PP_CAT(forward_step, BOOST_MPL_LIMIT_UNROLLING) \
+    /**/
+
+#   define AUX_LAST_BACKWARD_STEP \
+    BOOST_PP_CAT(backward_step, BOOST_MPL_LIMIT_UNROLLING) \
+    /**/
+
+template<
+      typename Iterator
+    , typename State
+    , typename ForwardOp
+    , typename ForwardPredicate
+    , typename BackwardOp
+    , typename BackwardPredicate
+    >
+struct iter_fold_if_impl
+{
+ private:
+    typedef iter_fold_if_null_step<Iterator,State> forward_step0;
+    BOOST_PP_REPEAT(
+          BOOST_MPL_LIMIT_UNROLLING
+        , AUX_ITER_FOLD_FORWARD_STEP
+        , unused
+        )
+
+    typedef typename if_<
+          typename AUX_LAST_FORWARD_STEP::not_last
+        , iter_fold_if_impl<
+              typename AUX_LAST_FORWARD_STEP::iterator
+            , typename AUX_LAST_FORWARD_STEP::state
+            , ForwardOp
+            , ForwardPredicate
+            , BackwardOp
+            , BackwardPredicate
+            >
+        , iter_fold_if_null_step<
+              typename AUX_LAST_FORWARD_STEP::iterator
+            , typename AUX_LAST_FORWARD_STEP::state
+            >
+        >::type AUX_LAST_BACKWARD_STEP;
+
+    BOOST_PP_REPEAT(
+          BOOST_MPL_LIMIT_UNROLLING
+        , AUX_ITER_FOLD_BACKWARD_STEP
+        , unused
+        )
+
+ public:
+    typedef typename backward_step0::state state;
+    typedef typename AUX_LAST_BACKWARD_STEP::iterator iterator;
+};
+
+#   undef AUX_LAST_BACKWARD_STEP
+#   undef AUX_LAST_FORWARD_STEP
+#   undef AUX_ITER_FOLD_BACKWARD_STEP
+#   undef AUX_ITER_FOLD_BACKWARD_STEP_FUNC
+#   undef AUX_ITER_FOLD_FORWARD_STEP
+
+}}}
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_AUX_ITER_FOLD_IF_IMPL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/iter_fold_impl.hpp b/third_party/boost/boost/mpl/aux_/iter_fold_impl.hpp
new file mode 100644
index 0000000..cb24338
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/iter_fold_impl.hpp
@@ -0,0 +1,42 @@
+
+#ifndef BOOST_MPL_AUX_ITER_FOLD_IMPL_HPP_INCLUDED
+#define BOOST_MPL_AUX_ITER_FOLD_IMPL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/next_prior.hpp>
+#   include <boost/mpl/apply.hpp>
+#   include <boost/mpl/aux_/config/ctps.hpp>
+#   if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+#       include <boost/mpl/if.hpp>
+#       include <boost/type_traits/is_same.hpp>
+#   endif
+#endif
+
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER iter_fold_impl.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   define AUX778076_FOLD_IMPL_OP(iter) iter
+#   define AUX778076_FOLD_IMPL_NAME_PREFIX iter_fold
+#   include <boost/mpl/aux_/fold_impl_body.hpp>
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_AUX_ITER_FOLD_IMPL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/lambda_arity_param.hpp b/third_party/boost/boost/mpl/aux_/lambda_arity_param.hpp
new file mode 100644
index 0000000..f3aaa49
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/lambda_arity_param.hpp
@@ -0,0 +1,25 @@
+
+#ifndef BOOST_MPL_AUX_LAMBDA_ARITY_PARAM_HPP_INCLUDED
+#define BOOST_MPL_AUX_LAMBDA_ARITY_PARAM_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/ttp.hpp>
+
+#if !defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING)
+#   define BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(param)
+#else
+#   define BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(param) , param
+#endif
+
+#endif // BOOST_MPL_AUX_LAMBDA_ARITY_PARAM_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/lambda_spec.hpp b/third_party/boost/boost/mpl/aux_/lambda_spec.hpp
new file mode 100644
index 0000000..015d5be
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/lambda_spec.hpp
@@ -0,0 +1,49 @@
+
+#ifndef BOOST_MPL_AUX_LAMBDA_SPEC_HPP_INCLUDED
+#define BOOST_MPL_AUX_LAMBDA_SPEC_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/void.hpp>
+#include <boost/mpl/lambda_fwd.hpp>
+#include <boost/mpl/int_fwd.hpp>
+#include <boost/mpl/aux_/preprocessor/params.hpp>
+#include <boost/mpl/aux_/lambda_arity_param.hpp>
+#include <boost/mpl/aux_/config/lambda.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT)
+
+#   define BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(i, name) \
+template< \
+      BOOST_MPL_PP_PARAMS(i, typename T) \
+    , typename Tag \
+    > \
+struct lambda< \
+      name< BOOST_MPL_PP_PARAMS(i, T) > \
+    , Tag \
+    BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(int_<i>) \
+    > \
+{ \
+    typedef false_ is_le; \
+    typedef name< BOOST_MPL_PP_PARAMS(i, T) > result_; \
+    typedef result_ type; \
+}; \
+/**/
+
+#else
+
+#   define BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(i, name) /**/
+
+#endif
+
+#endif // BOOST_MPL_AUX_LAMBDA_SPEC_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/lambda_support.hpp b/third_party/boost/boost/mpl/aux_/lambda_support.hpp
new file mode 100644
index 0000000..b1017b8
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/lambda_support.hpp
@@ -0,0 +1,169 @@
+
+#ifndef BOOST_MPL_AUX_LAMBDA_SUPPORT_HPP_INCLUDED
+#define BOOST_MPL_AUX_LAMBDA_SUPPORT_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/lambda.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT)
+
+#   define BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(i, name, params) /**/
+#   define BOOST_MPL_AUX_LAMBDA_SUPPORT(i,name,params) /**/
+
+#else
+
+#   include <boost/mpl/int_fwd.hpp>
+#   include <boost/mpl/aux_/yes_no.hpp>
+#   include <boost/mpl/aux_/na_fwd.hpp>
+#   include <boost/mpl/aux_/preprocessor/params.hpp>
+#   include <boost/mpl/aux_/preprocessor/enum.hpp>
+#   include <boost/mpl/aux_/config/msvc.hpp>
+#   include <boost/mpl/aux_/config/workaround.hpp>
+
+#   include <boost/preprocessor/tuple/to_list.hpp>
+#   include <boost/preprocessor/list/for_each_i.hpp>
+#   include <boost/preprocessor/inc.hpp>
+#   include <boost/preprocessor/cat.hpp>
+
+#   define BOOST_MPL_AUX_LAMBDA_SUPPORT_ARG_TYPEDEF_FUNC(R,typedef_,i,param) \
+    typedef_ param BOOST_PP_CAT(arg,BOOST_PP_INC(i)); \
+    /**/
+
+// agurt, 07/mar/03: restore an old revision for the sake of SGI MIPSpro C++
+#if BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
+
+#   define BOOST_MPL_AUX_LAMBDA_SUPPORT(i, name, params) \
+    typedef BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::int_<i> arity; \
+    BOOST_PP_LIST_FOR_EACH_I_R( \
+          1 \
+        , BOOST_MPL_AUX_LAMBDA_SUPPORT_ARG_TYPEDEF_FUNC \
+        , typedef \
+        , BOOST_PP_TUPLE_TO_LIST(i,params) \
+        ) \
+    struct rebind \
+    { \
+        template< BOOST_MPL_PP_PARAMS(i,typename U) > struct apply \
+            : name< BOOST_MPL_PP_PARAMS(i,U) > \
+        { \
+        }; \
+    }; \
+    /**/
+
+#   define BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(i, name, params) \
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(i, name, params) \
+    /**/
+
+#elif BOOST_WORKAROUND(__EDG_VERSION__, <= 244) && !defined(BOOST_INTEL_CXX_VERSION)
+// agurt, 18/jan/03: old EDG-based compilers actually enforce 11.4 para 9
+// (in strict mode), so we have to provide an alternative to the
+// MSVC-optimized implementation
+
+#   define BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(i, name, params) \
+    typedef BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::int_<i> arity; \
+    BOOST_PP_LIST_FOR_EACH_I_R( \
+          1 \
+        , BOOST_MPL_AUX_LAMBDA_SUPPORT_ARG_TYPEDEF_FUNC \
+        , typedef \
+        , BOOST_PP_TUPLE_TO_LIST(i,params) \
+        ) \
+    struct rebind; \
+/**/
+
+#   define BOOST_MPL_AUX_LAMBDA_SUPPORT(i, name, params) \
+    BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(i, name, params) \
+}; \
+template< BOOST_MPL_PP_PARAMS(i,typename T) > \
+struct name<BOOST_MPL_PP_PARAMS(i,T)>::rebind \
+{ \
+    template< BOOST_MPL_PP_PARAMS(i,typename U) > struct apply \
+        : name< BOOST_MPL_PP_PARAMS(i,U) > \
+    { \
+    }; \
+/**/
+
+#else // __EDG_VERSION__
+
+namespace boost { namespace mpl { namespace aux {
+template< typename T > struct has_rebind_tag;
+}}}
+
+#   define BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(i, name, params) \
+    typedef BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::int_<i> arity; \
+    BOOST_PP_LIST_FOR_EACH_I_R( \
+          1 \
+        , BOOST_MPL_AUX_LAMBDA_SUPPORT_ARG_TYPEDEF_FUNC \
+        , typedef \
+        , BOOST_PP_TUPLE_TO_LIST(i,params) \
+        ) \
+    friend class BOOST_PP_CAT(name,_rebind); \
+    typedef BOOST_PP_CAT(name,_rebind) rebind; \
+/**/
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610))
+#   define BOOST_MPL_AUX_LAMBDA_SUPPORT_HAS_REBIND(i, name, params) \
+template< BOOST_MPL_PP_PARAMS(i,typename T) > \
+::boost::mpl::aux::yes_tag operator|( \
+      ::boost::mpl::aux::has_rebind_tag<int> \
+    , name<BOOST_MPL_PP_PARAMS(i,T)>* \
+    ); \
+::boost::mpl::aux::no_tag operator|( \
+      ::boost::mpl::aux::has_rebind_tag<int> \
+    , name< BOOST_MPL_PP_ENUM(i,::boost::mpl::na) >* \
+    ); \
+/**/
+#elif !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+#   define BOOST_MPL_AUX_LAMBDA_SUPPORT_HAS_REBIND(i, name, params) \
+template< BOOST_MPL_PP_PARAMS(i,typename T) > \
+::boost::mpl::aux::yes_tag operator|( \
+      ::boost::mpl::aux::has_rebind_tag<int> \
+    , ::boost::mpl::aux::has_rebind_tag< name<BOOST_MPL_PP_PARAMS(i,T)> >* \
+    ); \
+/**/
+#else
+#   define BOOST_MPL_AUX_LAMBDA_SUPPORT_HAS_REBIND(i, name, params) /**/
+#endif
+
+#   if !defined(__BORLANDC__)
+#   define BOOST_MPL_AUX_LAMBDA_SUPPORT(i, name, params) \
+    BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(i, name, params) \
+}; \
+BOOST_MPL_AUX_LAMBDA_SUPPORT_HAS_REBIND(i, name, params) \
+class BOOST_PP_CAT(name,_rebind) \
+{ \
+ public: \
+    template< BOOST_MPL_PP_PARAMS(i,typename U) > struct apply \
+        : name< BOOST_MPL_PP_PARAMS(i,U) > \
+    { \
+    }; \
+/**/
+#   else
+#   define BOOST_MPL_AUX_LAMBDA_SUPPORT(i, name, params) \
+    BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(i, name, params) \
+}; \
+BOOST_MPL_AUX_LAMBDA_SUPPORT_HAS_REBIND(i, name, params) \
+class BOOST_PP_CAT(name,_rebind) \
+{ \
+ public: \
+    template< BOOST_MPL_PP_PARAMS(i,typename U) > struct apply \
+    { \
+        typedef typename name< BOOST_MPL_PP_PARAMS(i,U) >::type type; \
+    }; \
+/**/
+#   endif // __BORLANDC__
+
+#endif // __EDG_VERSION__
+
+#endif // BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
+
+#endif // BOOST_MPL_AUX_LAMBDA_SUPPORT_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/msvc_eti_base.hpp b/third_party/boost/boost/mpl/aux_/msvc_eti_base.hpp
new file mode 100644
index 0000000..82dbd6b
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/msvc_eti_base.hpp
@@ -0,0 +1,77 @@
+
+#ifndef BOOST_MPL_AUX_MSVC_ETI_BASE_HPP_INCLUDED
+#define BOOST_MPL_AUX_MSVC_ETI_BASE_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/is_msvc_eti_arg.hpp>
+#include <boost/mpl/aux_/config/eti.hpp>
+#include <boost/mpl/aux_/config/gcc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+
+#if defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG)
+
+template< bool > struct msvc_eti_base_impl
+{
+    template< typename T > struct result_
+        : T
+    {
+        typedef T type;
+    };
+};
+
+template<> struct msvc_eti_base_impl<true>
+{
+    template< typename T > struct result_
+    {
+        typedef result_ type;
+        typedef result_ first;
+        typedef result_ second;
+        typedef result_ tag;
+        enum { value = 0 };
+    };
+};
+
+template< typename T > struct msvc_eti_base
+    : msvc_eti_base_impl< is_msvc_eti_arg<T>::value >
+        ::template result_<T>
+{
+};
+
+#else // !BOOST_MPL_CFG_MSVC_70_ETI_BUG
+
+template< typename T > struct msvc_eti_base
+    : T
+{
+#if BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, BOOST_TESTED_AT(0x0304))
+    msvc_eti_base();
+#endif
+    typedef T type;
+};
+
+#endif
+
+template<> struct msvc_eti_base<int>
+{
+    typedef msvc_eti_base type;
+    typedef msvc_eti_base first;
+    typedef msvc_eti_base second;
+    typedef msvc_eti_base tag;
+    enum { value = 0 };
+};
+
+}}}
+
+#endif // BOOST_MPL_AUX_MSVC_ETI_BASE_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/msvc_never_true.hpp b/third_party/boost/boost/mpl/aux_/msvc_never_true.hpp
new file mode 100644
index 0000000..28650eb
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/msvc_never_true.hpp
@@ -0,0 +1,34 @@
+
+#ifndef BOOST_MPL_AUX_MSVC_NEVER_TRUE_HPP_INCLUDED
+#define BOOST_MPL_AUX_MSVC_NEVER_TRUE_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+
+namespace boost { namespace mpl { namespace aux {
+
+template< typename T >
+struct msvc_never_true
+{
+    enum { value = false };
+};
+
+}}}
+
+#endif // BOOST_MSVC
+
+#endif // BOOST_MPL_AUX_MSVC_NEVER_TRUE_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/msvc_type.hpp b/third_party/boost/boost/mpl/aux_/msvc_type.hpp
new file mode 100644
index 0000000..9e90694
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/msvc_type.hpp
@@ -0,0 +1,62 @@
+
+#ifndef BOOST_MPL_AUX_MSVC_TYPE_HPP_INCLUDED
+#define BOOST_MPL_AUX_MSVC_TYPE_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/eti.hpp>
+#include <boost/mpl/aux_/is_msvc_eti_arg.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+
+#if defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG)
+
+template< bool > struct msvc_type_impl
+{
+    template< typename T > struct result_
+    {
+        typedef typename T::type type;
+    };
+};
+
+template<> struct msvc_type_impl<true>
+{
+    template< typename T > struct result_
+    {
+        typedef result_ type;
+    };
+};
+
+template< typename T > struct msvc_type
+    : msvc_type_impl< is_msvc_eti_arg<T>::value >
+        ::template result_<T>
+{
+};
+
+#else // BOOST_MPL_CFG_MSVC_70_ETI_BUG
+
+template< typename T > struct msvc_type
+{
+    typedef typename T::type type;
+};
+
+template<> struct msvc_type<int>
+{
+    typedef int type;
+};
+
+#endif
+
+}}}
+
+#endif // BOOST_MPL_AUX_MSVC_TYPE_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/na.hpp b/third_party/boost/boost/mpl/aux_/na.hpp
new file mode 100644
index 0000000..5102233
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/na.hpp
@@ -0,0 +1,95 @@
+
+#ifndef BOOST_MPL_AUX_NA_HPP_INCLUDED
+#define BOOST_MPL_AUX_NA_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/aux_/na_fwd.hpp>
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/ctps.hpp>
+
+namespace boost { namespace mpl {
+
+template< typename T >
+struct is_na
+    : false_
+{
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+    using false_::value;
+#endif
+};
+
+template<>
+struct is_na<na>
+    : true_
+{
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+    using true_::value;
+#endif
+};
+
+template< typename T >
+struct is_not_na
+    : true_
+{
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+    using true_::value;
+#endif
+};
+
+template<>
+struct is_not_na<na>
+    : false_
+{
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+    using false_::value;
+#endif
+};
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+template< typename T, typename U > struct if_na
+{
+    typedef T type;
+};
+
+template< typename U > struct if_na<na,U>
+{
+    typedef U type;
+};
+#else
+template< typename T > struct if_na_impl
+{
+    template< typename U > struct apply
+    {
+        typedef T type;
+    };
+};
+
+template<> struct if_na_impl<na>
+{
+    template< typename U > struct apply
+    {
+        typedef U type;
+    };
+};
+
+template< typename T, typename U > struct if_na
+    : if_na_impl<T>::template apply<U>
+{
+};
+#endif
+
+}}
+
+#endif // BOOST_MPL_AUX_NA_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/na_assert.hpp b/third_party/boost/boost/mpl/aux_/na_assert.hpp
new file mode 100644
index 0000000..067ceba
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/na_assert.hpp
@@ -0,0 +1,34 @@
+
+#ifndef BOOST_MPL_AUX_NA_ASSERT_HPP_INCLUDED
+#define BOOST_MPL_AUX_NA_ASSERT_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/na.hpp>
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if !BOOST_WORKAROUND(_MSC_FULL_VER, <= 140050601)    \
+    && !BOOST_WORKAROUND(__EDG_VERSION__, <= 243)
+#   include <boost/mpl/assert.hpp>
+#   define BOOST_MPL_AUX_ASSERT_NOT_NA(x) \
+    BOOST_MPL_ASSERT_NOT((boost::mpl::is_na<type>)) \
+/**/
+#else
+#   include <boost/static_assert.hpp>
+#   define BOOST_MPL_AUX_ASSERT_NOT_NA(x) \
+    BOOST_STATIC_ASSERT(!boost::mpl::is_na<x>::value) \
+/**/
+#endif
+
+#endif // BOOST_MPL_AUX_NA_ASSERT_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/na_fwd.hpp b/third_party/boost/boost/mpl/aux_/na_fwd.hpp
new file mode 100644
index 0000000..cf9002f
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/na_fwd.hpp
@@ -0,0 +1,31 @@
+
+#ifndef BOOST_MPL_AUX_NA_FWD_HPP_INCLUDED
+#define BOOST_MPL_AUX_NA_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/adl_barrier.hpp>
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+
+// n.a. == not available
+struct na
+{
+    typedef na type;
+    enum { value = 0 };
+};
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+BOOST_MPL_AUX_ADL_BARRIER_DECL(na)
+
+#endif // BOOST_MPL_AUX_NA_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/na_spec.hpp b/third_party/boost/boost/mpl/aux_/na_spec.hpp
new file mode 100644
index 0000000..c10c4d7
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/na_spec.hpp
@@ -0,0 +1,175 @@
+
+#ifndef BOOST_MPL_AUX_NA_SPEC_HPP_INCLUDED
+#define BOOST_MPL_AUX_NA_SPEC_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/lambda_fwd.hpp>
+#   include <boost/mpl/int.hpp>
+#   include <boost/mpl/bool.hpp>
+#   include <boost/mpl/aux_/na.hpp>
+#   include <boost/mpl/aux_/arity.hpp>
+#   include <boost/mpl/aux_/template_arity_fwd.hpp>
+#endif
+
+#include <boost/mpl/aux_/preprocessor/params.hpp>
+#include <boost/mpl/aux_/preprocessor/enum.hpp>
+#include <boost/mpl/aux_/preprocessor/def_params_tail.hpp>
+#include <boost/mpl/aux_/lambda_arity_param.hpp>
+#include <boost/mpl/aux_/config/dtp.hpp>
+#include <boost/mpl/aux_/config/eti.hpp>
+#include <boost/mpl/aux_/nttp_decl.hpp>
+#include <boost/mpl/aux_/config/ttp.hpp>
+#include <boost/mpl/aux_/config/lambda.hpp>
+#include <boost/mpl/aux_/config/overload_resolution.hpp>
+
+
+#define BOOST_MPL_AUX_NA_PARAMS(i) \
+    BOOST_MPL_PP_ENUM(i, na) \
+/**/
+
+#if defined(BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES)
+#   define BOOST_MPL_AUX_NA_SPEC_ARITY(i, name) \
+namespace aux { \
+template< BOOST_MPL_AUX_NTTP_DECL(int, N) > \
+struct arity< \
+          name< BOOST_MPL_AUX_NA_PARAMS(i) > \
+        , N \
+        > \
+    : int_< BOOST_MPL_LIMIT_METAFUNCTION_ARITY > \
+{ \
+}; \
+} \
+/**/
+#else
+#   define BOOST_MPL_AUX_NA_SPEC_ARITY(i, name) /**/
+#endif
+
+#define BOOST_MPL_AUX_NA_SPEC_MAIN(i, name) \
+template<> \
+struct name< BOOST_MPL_AUX_NA_PARAMS(i) > \
+{ \
+    template< \
+          BOOST_MPL_PP_PARAMS(i, typename T) \
+        BOOST_MPL_PP_NESTED_DEF_PARAMS_TAIL(i, typename T, na) \
+        > \
+    struct apply \
+        : name< BOOST_MPL_PP_PARAMS(i, T) > \
+    { \
+    }; \
+}; \
+/**/
+
+#if defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT)
+#   define BOOST_MPL_AUX_NA_SPEC_LAMBDA(i, name) \
+template<> \
+struct lambda< \
+      name< BOOST_MPL_AUX_NA_PARAMS(i) > \
+    , void_ \
+    , true_ \
+    > \
+{ \
+    typedef false_ is_le; \
+    typedef name< BOOST_MPL_AUX_NA_PARAMS(i) > type; \
+}; \
+template<> \
+struct lambda< \
+      name< BOOST_MPL_AUX_NA_PARAMS(i) > \
+    , void_ \
+    , false_ \
+    > \
+{ \
+    typedef false_ is_le; \
+    typedef name< BOOST_MPL_AUX_NA_PARAMS(i) > type; \
+}; \
+/**/
+#else
+#   define BOOST_MPL_AUX_NA_SPEC_LAMBDA(i, name) \
+template< typename Tag > \
+struct lambda< \
+      name< BOOST_MPL_AUX_NA_PARAMS(i) > \
+    , Tag \
+    BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(int_<-1>) \
+    > \
+{ \
+    typedef false_ is_le; \
+    typedef name< BOOST_MPL_AUX_NA_PARAMS(i) > result_; \
+    typedef name< BOOST_MPL_AUX_NA_PARAMS(i) > type; \
+}; \
+/**/
+#endif
+
+#if defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING) \
+    || defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT) \
+        && defined(BOOST_MPL_CFG_BROKEN_OVERLOAD_RESOLUTION)
+#   define BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(i, j, name) \
+namespace aux { \
+template< BOOST_MPL_PP_PARAMS(j, typename T) > \
+struct template_arity< \
+          name< BOOST_MPL_PP_PARAMS(j, T) > \
+        > \
+    : int_<j> \
+{ \
+}; \
+\
+template<> \
+struct template_arity< \
+          name< BOOST_MPL_PP_ENUM(i, na) > \
+        > \
+    : int_<-1> \
+{ \
+}; \
+} \
+/**/
+#else
+#   define BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(i, j, name) /**/
+#endif
+
+#if defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
+#   define BOOST_MPL_AUX_NA_SPEC_ETI(i, name) \
+template<> \
+struct name< BOOST_MPL_PP_ENUM(i, int) > \
+{ \
+    typedef int type; \
+    enum { value = 0 }; \
+}; \
+/**/
+#else
+#   define BOOST_MPL_AUX_NA_SPEC_ETI(i, name) /**/
+#endif
+
+#define BOOST_MPL_AUX_NA_PARAM(param) param = na
+
+#define BOOST_MPL_AUX_NA_SPEC_NO_ETI(i, name) \
+BOOST_MPL_AUX_NA_SPEC_MAIN(i, name) \
+BOOST_MPL_AUX_NA_SPEC_LAMBDA(i, name) \
+BOOST_MPL_AUX_NA_SPEC_ARITY(i, name) \
+BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(i, i, name) \
+/**/
+
+#define BOOST_MPL_AUX_NA_SPEC(i, name) \
+BOOST_MPL_AUX_NA_SPEC_NO_ETI(i, name) \
+BOOST_MPL_AUX_NA_SPEC_ETI(i, name) \
+/**/
+
+#define BOOST_MPL_AUX_NA_SPEC2(i, j, name) \
+BOOST_MPL_AUX_NA_SPEC_MAIN(i, name) \
+BOOST_MPL_AUX_NA_SPEC_ETI(i, name) \
+BOOST_MPL_AUX_NA_SPEC_LAMBDA(i, name) \
+BOOST_MPL_AUX_NA_SPEC_ARITY(i, name) \
+BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(i, j, name) \
+/**/
+
+
+#endif // BOOST_MPL_AUX_NA_SPEC_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/nested_type_wknd.hpp b/third_party/boost/boost/mpl/aux_/nested_type_wknd.hpp
new file mode 100644
index 0000000..cd5f2f6
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/nested_type_wknd.hpp
@@ -0,0 +1,48 @@
+
+#ifndef BOOST_MPL_AUX_NESTED_TYPE_WKND_HPP_INCLUDED
+#define BOOST_MPL_AUX_NESTED_TYPE_WKND_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/gcc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, BOOST_TESTED_AT(0x0302)) \
+    || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x561)) \
+    || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x530)) \
+    || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840))
+
+namespace boost { namespace mpl { namespace aux {
+template< typename T > struct nested_type_wknd
+    : T::type
+{
+};
+}}}
+
+#if BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840))
+#   define BOOST_MPL_AUX_NESTED_TYPE_WKND(T) \
+    aux::nested_type_wknd<T> \
+/**/
+#else
+#   define BOOST_MPL_AUX_NESTED_TYPE_WKND(T) \
+    ::boost::mpl::aux::nested_type_wknd<T> \
+/**/
+#endif
+
+#else // !BOOST_MPL_CFG_GCC et al.
+
+#   define BOOST_MPL_AUX_NESTED_TYPE_WKND(T) T::type
+
+#endif
+
+#endif // BOOST_MPL_AUX_NESTED_TYPE_WKND_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/nttp_decl.hpp b/third_party/boost/boost/mpl/aux_/nttp_decl.hpp
new file mode 100644
index 0000000..6c41cba
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/nttp_decl.hpp
@@ -0,0 +1,35 @@
+
+#ifndef BOOST_MPL_AUX_NTTP_DECL_HPP_INCLUDED
+#define BOOST_MPL_AUX_NTTP_DECL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/nttp.hpp>
+
+#if defined(BOOST_MPL_CFG_NTTP_BUG)
+
+typedef bool        _mpl_nttp_bool;
+typedef int         _mpl_nttp_int;
+typedef unsigned    _mpl_nttp_unsigned;
+typedef long        _mpl_nttp_long;
+
+#   include <boost/preprocessor/cat.hpp>
+#   define BOOST_MPL_AUX_NTTP_DECL(T, x) BOOST_PP_CAT(_mpl_nttp_,T) x /**/
+
+#else
+
+#   define BOOST_MPL_AUX_NTTP_DECL(T, x) T x /**/
+
+#endif
+
+#endif // BOOST_MPL_AUX_NTTP_DECL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/numeric_cast_utils.hpp b/third_party/boost/boost/mpl/aux_/numeric_cast_utils.hpp
new file mode 100644
index 0000000..b197748
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/numeric_cast_utils.hpp
@@ -0,0 +1,77 @@
+
+#ifndef BOOST_MPL_AUX_NUMERIC_CAST_HPP_INCLUDED
+#define BOOST_MPL_AUX_NUMERIC_CAST_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2003-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/numeric_cast.hpp>
+#include <boost/mpl/apply_wrap.hpp>
+#include <boost/mpl/aux_/config/forwarding.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+
+template<
+      typename F
+    , typename Tag1
+    , typename Tag2
+    >
+struct cast1st_impl
+{
+    template< typename N1, typename N2 > struct apply
+#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING)
+        : apply_wrap2<
+              F
+            , typename apply_wrap1< BOOST_MPL_AUX_NUMERIC_CAST<Tag1,Tag2>,N1 >::type
+            , N2
+            >
+    {
+#else
+    {
+    typedef typename apply_wrap2<
+              F
+            , typename apply_wrap1< BOOST_MPL_AUX_NUMERIC_CAST<Tag1,Tag2>,N1 >::type
+            , N2
+            >::type type;
+#endif
+    };
+};
+
+template<
+      typename F
+    , typename Tag1
+    , typename Tag2
+    >
+struct cast2nd_impl
+{
+    template< typename N1, typename N2 > struct apply
+#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING)
+        : apply_wrap2<
+              F
+            , N1
+            , typename apply_wrap1< BOOST_MPL_AUX_NUMERIC_CAST<Tag2,Tag1>,N2 >::type
+            >
+    {
+#else
+    {
+        typedef typename apply_wrap2<
+              F
+            , N1
+            , typename apply_wrap1< BOOST_MPL_AUX_NUMERIC_CAST<Tag2,Tag1>,N2 >::type
+            >::type type;
+#endif
+    };
+};
+
+}}}
+
+#endif // BOOST_MPL_AUX_NUMERIC_CAST_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/numeric_op.hpp b/third_party/boost/boost/mpl/aux_/numeric_op.hpp
new file mode 100644
index 0000000..68bdd31
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/numeric_op.hpp
@@ -0,0 +1,315 @@
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+///// header body
+
+// NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION!
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/numeric_cast.hpp>
+#   include <boost/mpl/apply_wrap.hpp>
+#   include <boost/mpl/if.hpp>
+#   include <boost/mpl/tag.hpp>
+#   include <boost/mpl/aux_/numeric_cast_utils.hpp>
+#   include <boost/mpl/aux_/na.hpp>
+#   include <boost/mpl/aux_/na_spec.hpp>
+#   include <boost/mpl/aux_/lambda_support.hpp>
+#   include <boost/mpl/aux_/msvc_eti_base.hpp>
+#   include <boost/mpl/aux_/value_wknd.hpp>
+#   include <boost/mpl/aux_/config/eti.hpp>
+#   include <boost/mpl/aux_/nttp_decl.hpp>
+#endif
+
+#include <boost/mpl/aux_/config/static_constant.hpp>
+
+#if defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    || defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   include <boost/mpl/limits/arity.hpp>
+#   include <boost/mpl/aux_/preprocessor/partial_spec_params.hpp>
+#   include <boost/mpl/aux_/preprocessor/def_params_tail.hpp>
+#   include <boost/mpl/aux_/preprocessor/repeat.hpp>
+#   include <boost/mpl/aux_/preprocessor/ext_params.hpp>
+#   include <boost/mpl/aux_/preprocessor/params.hpp>
+#   include <boost/mpl/aux_/preprocessor/enum.hpp>
+#   include <boost/mpl/aux_/preprocessor/add.hpp>
+#   include <boost/mpl/aux_/preprocessor/sub.hpp>
+#   include <boost/mpl/aux_/config/ctps.hpp>
+#   include <boost/mpl/aux_/config/eti.hpp>
+#   include <boost/mpl/aux_/config/msvc.hpp>
+#   include <boost/mpl/aux_/config/workaround.hpp>
+
+#   include <boost/preprocessor/dec.hpp>
+#   include <boost/preprocessor/inc.hpp>
+#   include <boost/preprocessor/iterate.hpp>
+#   include <boost/preprocessor/cat.hpp>
+
+
+#if !defined(AUX778076_OP_ARITY)
+#   define AUX778076_OP_ARITY BOOST_MPL_LIMIT_METAFUNCTION_ARITY
+#endif
+
+#if !defined(AUX778076_OP_IMPL_NAME)
+#   define AUX778076_OP_IMPL_NAME BOOST_PP_CAT(AUX778076_OP_PREFIX,_impl)
+#endif
+
+#if !defined(AUX778076_OP_TAG_NAME)
+#   define AUX778076_OP_TAG_NAME BOOST_PP_CAT(AUX778076_OP_PREFIX,_tag)
+#endif
+
+namespace boost { namespace mpl {
+
+template<
+      typename Tag1
+    , typename Tag2
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+    , BOOST_MPL_AUX_NTTP_DECL(int, tag1_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag1)::value
+    , BOOST_MPL_AUX_NTTP_DECL(int, tag2_) = BOOST_MPL_AUX_MSVC_VALUE_WKND(Tag2)::value
+    >
+struct AUX778076_OP_IMPL_NAME
+    : if_c<
+          ( tag1_ > tag2_ )
+#else
+    >
+struct AUX778076_OP_IMPL_NAME
+    : if_c<
+          ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1)
+              > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2)
+            )
+#endif
+        , aux::cast2nd_impl< AUX778076_OP_IMPL_NAME<Tag1,Tag1>,Tag1,Tag2 >
+        , aux::cast1st_impl< AUX778076_OP_IMPL_NAME<Tag2,Tag2>,Tag1,Tag2 >
+        >::type
+{
+};
+
+/// for Digital Mars C++/compilers with no CTPS/TTP support
+template<> struct AUX778076_OP_IMPL_NAME<na,na>
+{
+    template< typename U1, typename U2 > struct apply
+    {
+        typedef apply type;
+        BOOST_STATIC_CONSTANT(int, value = 0);
+    };
+};
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+template< typename Tag > struct AUX778076_OP_IMPL_NAME<na,Tag>
+{
+    template< typename U1, typename U2 > struct apply
+    {
+        typedef apply type;
+        BOOST_STATIC_CONSTANT(int, value = 0);
+    };
+};
+
+template< typename Tag > struct AUX778076_OP_IMPL_NAME<Tag,na>
+{
+    template< typename U1, typename U2 > struct apply
+    {
+        typedef apply type;
+        BOOST_STATIC_CONSTANT(int, value = 0);
+    };
+};
+#else
+template<> struct AUX778076_OP_IMPL_NAME<na,integral_c_tag>
+{
+    template< typename U1, typename U2 > struct apply
+    {
+        typedef apply type;
+        BOOST_STATIC_CONSTANT(int, value = 0);
+    };
+};
+
+template<> struct AUX778076_OP_IMPL_NAME<integral_c_tag,na>
+{
+    template< typename U1, typename U2 > struct apply
+    {
+        typedef apply type;
+        BOOST_STATIC_CONSTANT(int, value = 0);
+    };
+};
+#endif
+
+
+#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
+    && BOOST_WORKAROUND(BOOST_MSVC, >= 1300)
+template< typename T > struct AUX778076_OP_TAG_NAME
+    : tag<T,na>
+{
+};
+#else
+template< typename T > struct AUX778076_OP_TAG_NAME
+{
+    typedef typename T::tag type;
+};
+#endif
+
+
+#if AUX778076_OP_ARITY != 2
+
+#   if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+#   define AUX778076_OP_RIGHT_OPERAND(unused, i, N) , BOOST_PP_CAT(N, BOOST_MPL_PP_ADD(i, 2))>
+#   define AUX778076_OP_N_CALLS(i, N) \
+    BOOST_MPL_PP_REPEAT( BOOST_PP_DEC(i), BOOST_MPL_PP_REPEAT_IDENTITY_FUNC, AUX778076_OP_NAME< ) \
+    N1 BOOST_MPL_PP_REPEAT( BOOST_MPL_PP_SUB(i, 1), AUX778076_OP_RIGHT_OPERAND, N ) \
+/**/
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(N1)
+    , typename BOOST_MPL_AUX_NA_PARAM(N2)
+    BOOST_MPL_PP_DEF_PARAMS_TAIL(2, typename N, na)
+    >
+struct AUX778076_OP_NAME
+    : AUX778076_OP_N_CALLS(AUX778076_OP_ARITY, N)
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(
+          AUX778076_OP_ARITY
+        , AUX778076_OP_NAME
+        , ( BOOST_MPL_PP_PARAMS(AUX778076_OP_ARITY, N) )
+        )
+};
+
+#define BOOST_PP_ITERATION_PARAMS_1 \
+    (3,( BOOST_PP_DEC(AUX778076_OP_ARITY), 2, <boost/mpl/aux_/numeric_op.hpp> ))
+#include BOOST_PP_ITERATE()
+
+#   undef AUX778076_OP_N_CALLS
+#   undef AUX778076_OP_RIGHT_OPERAND
+
+#   else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+/// forward declaration
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(N1)
+    , typename BOOST_MPL_AUX_NA_PARAM(N2)
+    >
+struct BOOST_PP_CAT(AUX778076_OP_NAME,2);
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(N1)
+    , typename BOOST_MPL_AUX_NA_PARAM(N2)
+    BOOST_MPL_PP_DEF_PARAMS_TAIL(2, typename N, na)
+    >
+struct AUX778076_OP_NAME
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
+    : aux::msvc_eti_base< typename if_<
+#else
+    : if_<
+#endif
+          is_na<N3>
+        , BOOST_PP_CAT(AUX778076_OP_NAME,2)<N1,N2>
+        , AUX778076_OP_NAME<
+              BOOST_PP_CAT(AUX778076_OP_NAME,2)<N1,N2>
+            , BOOST_MPL_PP_EXT_PARAMS(3, BOOST_PP_INC(AUX778076_OP_ARITY), N)
+            >
+        >::type
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
+    >
+#endif
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(
+          AUX778076_OP_ARITY
+        , AUX778076_OP_NAME
+        , ( BOOST_MPL_PP_PARAMS(AUX778076_OP_ARITY, N) )
+        )
+};
+
+template<
+      typename N1
+    , typename N2
+    >
+struct BOOST_PP_CAT(AUX778076_OP_NAME,2)
+
+#endif
+
+#else // AUX778076_OP_ARITY == 2
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(N1)
+    , typename BOOST_MPL_AUX_NA_PARAM(N2)
+    >
+struct AUX778076_OP_NAME
+
+#endif
+
+#if !defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
+    : AUX778076_OP_IMPL_NAME<
+          typename AUX778076_OP_TAG_NAME<N1>::type
+        , typename AUX778076_OP_TAG_NAME<N2>::type
+        >::template apply<N1,N2>::type
+#else
+    : aux::msvc_eti_base< typename apply_wrap2<
+          AUX778076_OP_IMPL_NAME<
+              typename AUX778076_OP_TAG_NAME<N1>::type
+            , typename AUX778076_OP_TAG_NAME<N2>::type
+            >
+        , N1
+        , N2
+        >::type >::type
+#endif
+{
+#if AUX778076_OP_ARITY != 2
+
+#   if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+    BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(
+          AUX778076_OP_ARITY
+        , AUX778076_OP_NAME
+        , ( BOOST_MPL_PP_PARTIAL_SPEC_PARAMS(2, N, na) )
+        )
+#   else
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(2, BOOST_PP_CAT(AUX778076_OP_NAME,2), (N1, N2))
+#   endif
+
+#else
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(2, AUX778076_OP_NAME, (N1, N2))
+#endif
+};
+
+BOOST_MPL_AUX_NA_SPEC2(2, AUX778076_OP_ARITY, AUX778076_OP_NAME)
+
+}}
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+
+///// iteration, depth == 1
+
+// For gcc 4.4 compatability, we must include the
+// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
+#else // BOOST_PP_IS_ITERATING
+#if BOOST_PP_ITERATION_DEPTH() == 1
+
+#   define i_ BOOST_PP_FRAME_ITERATION(1)
+
+template<
+      BOOST_MPL_PP_PARAMS(i_, typename N)
+    >
+struct AUX778076_OP_NAME<BOOST_MPL_PP_PARTIAL_SPEC_PARAMS(i_, N, na)>
+#if i_ != 2
+    : AUX778076_OP_N_CALLS(i_, N)
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(
+          AUX778076_OP_ARITY
+        , AUX778076_OP_NAME
+        , ( BOOST_MPL_PP_PARTIAL_SPEC_PARAMS(i_, N, na) )
+        )
+};
+#endif
+
+#   undef i_
+
+#endif // BOOST_PP_ITERATION_DEPTH()
+#endif // BOOST_PP_IS_ITERATING
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp
new file mode 100644
index 0000000..e8c7a32
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp
@@ -0,0 +1,96 @@
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/aux_/advance_backward.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl { namespace aux {
+
+template< long N > struct advance_backward;
+template<>
+struct advance_backward<0>
+{
+    template< typename Iterator > struct apply
+    {
+        typedef Iterator iter0;
+        typedef iter0 type;
+    };
+};
+
+template<>
+struct advance_backward<1>
+{
+    template< typename Iterator > struct apply
+    {
+        typedef Iterator iter0;
+        typedef typename prior<iter0>::type iter1;
+        typedef iter1 type;
+    };
+};
+
+template<>
+struct advance_backward<2>
+{
+    template< typename Iterator > struct apply
+    {
+        typedef Iterator iter0;
+        typedef typename prior<iter0>::type iter1;
+        typedef typename prior<iter1>::type iter2;
+        typedef iter2 type;
+    };
+};
+
+template<>
+struct advance_backward<3>
+{
+    template< typename Iterator > struct apply
+    {
+        typedef Iterator iter0;
+        typedef typename prior<iter0>::type iter1;
+        typedef typename prior<iter1>::type iter2;
+        typedef typename prior<iter2>::type iter3;
+        typedef iter3 type;
+    };
+};
+
+template<>
+struct advance_backward<4>
+{
+    template< typename Iterator > struct apply
+    {
+        typedef Iterator iter0;
+        typedef typename prior<iter0>::type iter1;
+        typedef typename prior<iter1>::type iter2;
+        typedef typename prior<iter2>::type iter3;
+        typedef typename prior<iter3>::type iter4;
+        typedef iter4 type;
+    };
+};
+
+template< long N >
+struct advance_backward
+{
+    template< typename Iterator > struct apply
+    {
+        typedef typename apply_wrap1<
+              advance_backward<4>
+            , Iterator
+            >::type chunk_result_;
+
+        typedef typename apply_wrap1<
+              advance_backward<(
+                (N - 4) < 0
+                    ? 0
+                    : N - 4
+                    )>
+            , chunk_result_
+            >::type type;
+    };
+};
+
+}}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp
new file mode 100644
index 0000000..e244fff
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp
@@ -0,0 +1,96 @@
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/aux_/advance_forward.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl { namespace aux {
+
+template< long N > struct advance_forward;
+template<>
+struct advance_forward<0>
+{
+    template< typename Iterator > struct apply
+    {
+        typedef Iterator iter0;
+        typedef iter0 type;
+    };
+};
+
+template<>
+struct advance_forward<1>
+{
+    template< typename Iterator > struct apply
+    {
+        typedef Iterator iter0;
+        typedef typename next<iter0>::type iter1;
+        typedef iter1 type;
+    };
+};
+
+template<>
+struct advance_forward<2>
+{
+    template< typename Iterator > struct apply
+    {
+        typedef Iterator iter0;
+        typedef typename next<iter0>::type iter1;
+        typedef typename next<iter1>::type iter2;
+        typedef iter2 type;
+    };
+};
+
+template<>
+struct advance_forward<3>
+{
+    template< typename Iterator > struct apply
+    {
+        typedef Iterator iter0;
+        typedef typename next<iter0>::type iter1;
+        typedef typename next<iter1>::type iter2;
+        typedef typename next<iter2>::type iter3;
+        typedef iter3 type;
+    };
+};
+
+template<>
+struct advance_forward<4>
+{
+    template< typename Iterator > struct apply
+    {
+        typedef Iterator iter0;
+        typedef typename next<iter0>::type iter1;
+        typedef typename next<iter1>::type iter2;
+        typedef typename next<iter2>::type iter3;
+        typedef typename next<iter3>::type iter4;
+        typedef iter4 type;
+    };
+};
+
+template< long N >
+struct advance_forward
+{
+    template< typename Iterator > struct apply
+    {
+        typedef typename apply_wrap1<
+              advance_forward<4>
+            , Iterator
+            >::type chunk_result_;
+
+        typedef typename apply_wrap1<
+              advance_forward<(
+                (N - 4) < 0
+                    ? 0
+                    : N - 4
+                    )>
+            , chunk_result_
+            >::type type;
+    };
+};
+
+}}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/and.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/and.hpp
new file mode 100644
index 0000000..899d4fe
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/and.hpp
@@ -0,0 +1,69 @@
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/and.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl {
+
+namespace aux {
+
+template< bool C_, typename T1, typename T2, typename T3, typename T4 >
+struct and_impl
+    : false_
+{
+};
+
+template< typename T1, typename T2, typename T3, typename T4 >
+struct and_impl< true,T1,T2,T3,T4 >
+    : and_impl<
+          BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value
+        , T2, T3, T4
+        , true_
+        >
+{
+};
+
+template<>
+struct and_impl<
+          true
+        , true_, true_, true_, true_
+        >
+    : true_
+{
+};
+
+} // namespace aux
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(T1)
+    , typename BOOST_MPL_AUX_NA_PARAM(T2)
+    , typename T3 = true_, typename T4 = true_, typename T5 = true_
+    >
+struct and_
+
+    : aux::and_impl<
+          BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value
+        , T2, T3, T4, T5
+        >
+
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(
+          5
+        , and_
+        , ( T1, T2, T3, T4, T5)
+        )
+};
+
+BOOST_MPL_AUX_NA_SPEC2(
+      2
+    , 5
+    , and_
+    )
+
+}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/apply.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/apply.hpp
new file mode 100644
index 0000000..55b3097
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/apply.hpp
@@ -0,0 +1,168 @@
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/apply.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl {
+
+template<
+      typename F
+    >
+struct apply0
+
+    : apply_wrap0<
+          typename lambda<F>::type
+
+        >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(
+          1
+        , apply0
+        , (F )
+        )
+};
+
+template<
+      typename F
+    >
+struct apply< F,na,na,na,na,na >
+    : apply0<F>
+{
+};
+
+template<
+      typename F, typename T1
+    >
+struct apply1
+
+    : apply_wrap1<
+          typename lambda<F>::type
+        , T1
+        >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(
+          2
+        , apply1
+        , (F, T1)
+        )
+};
+
+template<
+      typename F, typename T1
+    >
+struct apply< F,T1,na,na,na,na >
+    : apply1< F,T1 >
+{
+};
+
+template<
+      typename F, typename T1, typename T2
+    >
+struct apply2
+
+    : apply_wrap2<
+          typename lambda<F>::type
+        , T1, T2
+        >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(
+          3
+        , apply2
+        , (F, T1, T2)
+        )
+};
+
+template<
+      typename F, typename T1, typename T2
+    >
+struct apply< F,T1,T2,na,na,na >
+    : apply2< F,T1,T2 >
+{
+};
+
+template<
+      typename F, typename T1, typename T2, typename T3
+    >
+struct apply3
+
+    : apply_wrap3<
+          typename lambda<F>::type
+        , T1, T2, T3
+        >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(
+          4
+        , apply3
+        , (F, T1, T2, T3)
+        )
+};
+
+template<
+      typename F, typename T1, typename T2, typename T3
+    >
+struct apply< F,T1,T2,T3,na,na >
+    : apply3< F,T1,T2,T3 >
+{
+};
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    >
+struct apply4
+
+    : apply_wrap4<
+          typename lambda<F>::type
+        , T1, T2, T3, T4
+        >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(
+          5
+        , apply4
+        , (F, T1, T2, T3, T4)
+        )
+};
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    >
+struct apply< F,T1,T2,T3,T4,na >
+    : apply4< F,T1,T2,T3,T4 >
+{
+};
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    , typename T5
+    >
+struct apply5
+
+    : apply_wrap5<
+          typename lambda<F>::type
+        , T1, T2, T3, T4, T5
+        >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(
+          6
+        , apply5
+        , (F, T1, T2, T3, T4, T5)
+        )
+};
+
+/// primary template (not a specialization!)
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    , typename T5
+    >
+struct apply
+    : apply5< F,T1,T2,T3,T4,T5 >
+{
+};
+
+}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/apply_fwd.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/apply_fwd.hpp
new file mode 100644
index 0000000..5f1c7de
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/apply_fwd.hpp
@@ -0,0 +1,51 @@
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/apply_fwd.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl {
+
+template<
+      typename F, typename T1 = na, typename T2 = na, typename T3 = na
+    , typename T4 = na, typename T5 = na
+    >
+struct apply;
+
+template<
+      typename F
+    >
+struct apply0;
+
+template<
+      typename F, typename T1
+    >
+struct apply1;
+
+template<
+      typename F, typename T1, typename T2
+    >
+struct apply2;
+
+template<
+      typename F, typename T1, typename T2, typename T3
+    >
+struct apply3;
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    >
+struct apply4;
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    , typename T5
+    >
+struct apply5;
+
+}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp
new file mode 100644
index 0000000..94ca5d7
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp
@@ -0,0 +1,83 @@
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/apply_wrap.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl {
+
+template<
+      typename F
+
+    , typename has_apply_ = typename aux::has_apply<F>::type
+
+    >
+struct apply_wrap0
+
+    : F::template apply<  >
+{
+};
+
+template< typename F >
+struct apply_wrap0< F,true_ >
+    : F::apply
+{
+};
+
+template<
+      typename F, typename T1
+
+    >
+struct apply_wrap1
+
+    : F::template apply<T1>
+{
+};
+
+template<
+      typename F, typename T1, typename T2
+
+    >
+struct apply_wrap2
+
+    : F::template apply< T1,T2 >
+{
+};
+
+template<
+      typename F, typename T1, typename T2, typename T3
+
+    >
+struct apply_wrap3
+
+    : F::template apply< T1,T2,T3 >
+{
+};
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+
+    >
+struct apply_wrap4
+
+    : F::template apply< T1,T2,T3,T4 >
+{
+};
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    , typename T5
+
+    >
+struct apply_wrap5
+
+    : F::template apply< T1,T2,T3,T4,T5 >
+{
+};
+
+}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/arg.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/arg.hpp
new file mode 100644
index 0000000..dd64011
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/arg.hpp
@@ -0,0 +1,123 @@
+
+// Copyright Peter Dimov 2001-2002
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/arg.hpp" header
+// -- DO NOT modify by hand!
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+template<> struct arg< -1 >
+{
+    BOOST_STATIC_CONSTANT(int, value  = -1);
+    BOOST_MPL_AUX_ARG_TYPEDEF(na, tag)
+    BOOST_MPL_AUX_ARG_TYPEDEF(na, type)
+
+    template<
+          typename U1 = na, typename U2 = na, typename U3 = na
+        , typename U4 = na, typename U5 = na
+        >
+    struct apply
+    {
+        typedef U1 type;
+        BOOST_MPL_AUX_ASSERT_NOT_NA(type);
+    };
+};
+
+template<> struct arg<1>
+{
+    BOOST_STATIC_CONSTANT(int, value  = 1);
+    typedef arg<2> next;
+    BOOST_MPL_AUX_ARG_TYPEDEF(na, tag)
+    BOOST_MPL_AUX_ARG_TYPEDEF(na, type)
+
+    template<
+          typename U1 = na, typename U2 = na, typename U3 = na
+        , typename U4 = na, typename U5 = na
+        >
+    struct apply
+    {
+        typedef U1 type;
+        BOOST_MPL_AUX_ASSERT_NOT_NA(type);
+    };
+};
+
+template<> struct arg<2>
+{
+    BOOST_STATIC_CONSTANT(int, value  = 2);
+    typedef arg<3> next;
+    BOOST_MPL_AUX_ARG_TYPEDEF(na, tag)
+    BOOST_MPL_AUX_ARG_TYPEDEF(na, type)
+
+    template<
+          typename U1 = na, typename U2 = na, typename U3 = na
+        , typename U4 = na, typename U5 = na
+        >
+    struct apply
+    {
+        typedef U2 type;
+        BOOST_MPL_AUX_ASSERT_NOT_NA(type);
+    };
+};
+
+template<> struct arg<3>
+{
+    BOOST_STATIC_CONSTANT(int, value  = 3);
+    typedef arg<4> next;
+    BOOST_MPL_AUX_ARG_TYPEDEF(na, tag)
+    BOOST_MPL_AUX_ARG_TYPEDEF(na, type)
+
+    template<
+          typename U1 = na, typename U2 = na, typename U3 = na
+        , typename U4 = na, typename U5 = na
+        >
+    struct apply
+    {
+        typedef U3 type;
+        BOOST_MPL_AUX_ASSERT_NOT_NA(type);
+    };
+};
+
+template<> struct arg<4>
+{
+    BOOST_STATIC_CONSTANT(int, value  = 4);
+    typedef arg<5> next;
+    BOOST_MPL_AUX_ARG_TYPEDEF(na, tag)
+    BOOST_MPL_AUX_ARG_TYPEDEF(na, type)
+
+    template<
+          typename U1 = na, typename U2 = na, typename U3 = na
+        , typename U4 = na, typename U5 = na
+        >
+    struct apply
+    {
+        typedef U4 type;
+        BOOST_MPL_AUX_ASSERT_NOT_NA(type);
+    };
+};
+
+template<> struct arg<5>
+{
+    BOOST_STATIC_CONSTANT(int, value  = 5);
+    typedef arg<6> next;
+    BOOST_MPL_AUX_ARG_TYPEDEF(na, tag)
+    BOOST_MPL_AUX_ARG_TYPEDEF(na, type)
+
+    template<
+          typename U1 = na, typename U2 = na, typename U3 = na
+        , typename U4 = na, typename U5 = na
+        >
+    struct apply
+    {
+        typedef U5 type;
+        BOOST_MPL_AUX_ASSERT_NOT_NA(type);
+    };
+};
+
+BOOST_MPL_AUX_NONTYPE_ARITY_SPEC(1,int, arg)
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/bind.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/bind.hpp
new file mode 100644
index 0000000..65c61b5
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/bind.hpp
@@ -0,0 +1,560 @@
+
+// Copyright Peter Dimov 2001
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/bind.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl {
+
+namespace aux {
+
+template<
+      typename T, typename U1, typename U2, typename U3, typename U4
+    , typename U5
+    >
+struct resolve_bind_arg
+{
+    typedef T type;
+};
+
+template<
+      typename T
+    , typename Arg
+    >
+struct replace_unnamed_arg
+{
+    typedef Arg next;
+    typedef T type;
+};
+
+template<
+      typename Arg
+    >
+struct replace_unnamed_arg< arg< -1 >, Arg >
+{
+    typedef typename Arg::next next;
+    typedef Arg type;
+};
+
+template<
+      int N, typename U1, typename U2, typename U3, typename U4, typename U5
+    >
+struct resolve_bind_arg< arg<N>, U1, U2, U3, U4, U5 >
+{
+    typedef typename apply_wrap5<mpl::arg<N>, U1, U2, U3, U4, U5>::type type;
+};
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename U1, typename U2, typename U3, typename U4
+    , typename U5
+    >
+struct resolve_bind_arg< bind< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5 >
+{
+    typedef bind< F,T1,T2,T3,T4,T5 > f_;
+    typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type;
+};
+
+} // namespace aux
+
+template<
+      typename F
+    >
+struct bind0
+{
+    template<
+          typename U1 = na, typename U2 = na, typename U3 = na
+        , typename U4 = na, typename U5 = na
+        >
+    struct apply
+    {
+     private:
+        typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0;
+        typedef typename r0::type a0;
+        typedef typename r0::next n1;
+        typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_;
+        ///
+     public:
+        typedef typename apply_wrap0<
+              f_
+            >::type type;
+
+    };
+};
+
+namespace aux {
+
+template<
+      typename F, typename U1, typename U2, typename U3, typename U4
+    , typename U5
+    >
+struct resolve_bind_arg<
+      bind0<F>, U1, U2, U3, U4, U5
+    >
+{
+    typedef bind0<F> f_;
+    typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type;
+};
+
+} // namespace aux
+
+BOOST_MPL_AUX_ARITY_SPEC(1, bind0)
+BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(1, bind0)
+
+template<
+      typename F
+    >
+struct bind< F,na,na,na,na,na >
+    : bind0<F>
+{
+};
+
+template<
+      typename F, typename T1
+    >
+struct bind1
+{
+    template<
+          typename U1 = na, typename U2 = na, typename U3 = na
+        , typename U4 = na, typename U5 = na
+        >
+    struct apply
+    {
+     private:
+        typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0;
+        typedef typename r0::type a0;
+        typedef typename r0::next n1;
+        typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_;
+        ///
+        typedef aux::replace_unnamed_arg< T1,n1 > r1;
+        typedef typename r1::type a1;
+        typedef typename r1::next n2;
+        typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1;
+        ///
+     public:
+        typedef typename apply_wrap1<
+              f_
+            , typename t1::type
+            >::type type;
+
+    };
+};
+
+namespace aux {
+
+template<
+      typename F, typename T1, typename U1, typename U2, typename U3
+    , typename U4, typename U5
+    >
+struct resolve_bind_arg<
+      bind1< F,T1 >, U1, U2, U3, U4, U5
+    >
+{
+    typedef bind1< F,T1 > f_;
+    typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type;
+};
+
+} // namespace aux
+
+BOOST_MPL_AUX_ARITY_SPEC(2, bind1)
+BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(2, bind1)
+
+template<
+      typename F, typename T1
+    >
+struct bind< F,T1,na,na,na,na >
+    : bind1< F,T1 >
+{
+};
+
+template<
+      typename F, typename T1, typename T2
+    >
+struct bind2
+{
+    template<
+          typename U1 = na, typename U2 = na, typename U3 = na
+        , typename U4 = na, typename U5 = na
+        >
+    struct apply
+    {
+     private:
+        typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0;
+        typedef typename r0::type a0;
+        typedef typename r0::next n1;
+        typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_;
+        ///
+        typedef aux::replace_unnamed_arg< T1,n1 > r1;
+        typedef typename r1::type a1;
+        typedef typename r1::next n2;
+        typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1;
+        ///
+        typedef aux::replace_unnamed_arg< T2,n2 > r2;
+        typedef typename r2::type a2;
+        typedef typename r2::next n3;
+        typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2;
+        ///
+     public:
+        typedef typename apply_wrap2<
+              f_
+            , typename t1::type, typename t2::type
+            >::type type;
+
+    };
+};
+
+namespace aux {
+
+template<
+      typename F, typename T1, typename T2, typename U1, typename U2
+    , typename U3, typename U4, typename U5
+    >
+struct resolve_bind_arg<
+      bind2< F,T1,T2 >, U1, U2, U3, U4, U5
+    >
+{
+    typedef bind2< F,T1,T2 > f_;
+    typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type;
+};
+
+} // namespace aux
+
+BOOST_MPL_AUX_ARITY_SPEC(3, bind2)
+BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(3, bind2)
+
+template<
+      typename F, typename T1, typename T2
+    >
+struct bind< F,T1,T2,na,na,na >
+    : bind2< F,T1,T2 >
+{
+};
+
+template<
+      typename F, typename T1, typename T2, typename T3
+    >
+struct bind3
+{
+    template<
+          typename U1 = na, typename U2 = na, typename U3 = na
+        , typename U4 = na, typename U5 = na
+        >
+    struct apply
+    {
+     private:
+        typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0;
+        typedef typename r0::type a0;
+        typedef typename r0::next n1;
+        typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_;
+        ///
+        typedef aux::replace_unnamed_arg< T1,n1 > r1;
+        typedef typename r1::type a1;
+        typedef typename r1::next n2;
+        typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1;
+        ///
+        typedef aux::replace_unnamed_arg< T2,n2 > r2;
+        typedef typename r2::type a2;
+        typedef typename r2::next n3;
+        typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2;
+        ///
+        typedef aux::replace_unnamed_arg< T3,n3 > r3;
+        typedef typename r3::type a3;
+        typedef typename r3::next n4;
+        typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3;
+        ///
+     public:
+        typedef typename apply_wrap3<
+              f_
+            , typename t1::type, typename t2::type, typename t3::type
+            >::type type;
+
+    };
+};
+
+namespace aux {
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename U1
+    , typename U2, typename U3, typename U4, typename U5
+    >
+struct resolve_bind_arg<
+      bind3< F,T1,T2,T3 >, U1, U2, U3, U4, U5
+    >
+{
+    typedef bind3< F,T1,T2,T3 > f_;
+    typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type;
+};
+
+} // namespace aux
+
+BOOST_MPL_AUX_ARITY_SPEC(4, bind3)
+BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(4, bind3)
+
+template<
+      typename F, typename T1, typename T2, typename T3
+    >
+struct bind< F,T1,T2,T3,na,na >
+    : bind3< F,T1,T2,T3 >
+{
+};
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    >
+struct bind4
+{
+    template<
+          typename U1 = na, typename U2 = na, typename U3 = na
+        , typename U4 = na, typename U5 = na
+        >
+    struct apply
+    {
+     private:
+        typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0;
+        typedef typename r0::type a0;
+        typedef typename r0::next n1;
+        typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_;
+        ///
+        typedef aux::replace_unnamed_arg< T1,n1 > r1;
+        typedef typename r1::type a1;
+        typedef typename r1::next n2;
+        typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1;
+        ///
+        typedef aux::replace_unnamed_arg< T2,n2 > r2;
+        typedef typename r2::type a2;
+        typedef typename r2::next n3;
+        typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2;
+        ///
+        typedef aux::replace_unnamed_arg< T3,n3 > r3;
+        typedef typename r3::type a3;
+        typedef typename r3::next n4;
+        typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3;
+        ///
+        typedef aux::replace_unnamed_arg< T4,n4 > r4;
+        typedef typename r4::type a4;
+        typedef typename r4::next n5;
+        typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4;
+        ///
+     public:
+        typedef typename apply_wrap4<
+              f_
+            , typename t1::type, typename t2::type, typename t3::type
+            , typename t4::type
+            >::type type;
+
+    };
+};
+
+namespace aux {
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    , typename U1, typename U2, typename U3, typename U4, typename U5
+    >
+struct resolve_bind_arg<
+      bind4< F,T1,T2,T3,T4 >, U1, U2, U3, U4, U5
+    >
+{
+    typedef bind4< F,T1,T2,T3,T4 > f_;
+    typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type;
+};
+
+} // namespace aux
+
+BOOST_MPL_AUX_ARITY_SPEC(5, bind4)
+BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(5, bind4)
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    >
+struct bind< F,T1,T2,T3,T4,na >
+    : bind4< F,T1,T2,T3,T4 >
+{
+};
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    , typename T5
+    >
+struct bind5
+{
+    template<
+          typename U1 = na, typename U2 = na, typename U3 = na
+        , typename U4 = na, typename U5 = na
+        >
+    struct apply
+    {
+     private:
+        typedef aux::replace_unnamed_arg< F, mpl::arg<1> > r0;
+        typedef typename r0::type a0;
+        typedef typename r0::next n1;
+        typedef typename aux::resolve_bind_arg< a0,U1,U2,U3,U4,U5 >::type f_;
+        ///
+        typedef aux::replace_unnamed_arg< T1,n1 > r1;
+        typedef typename r1::type a1;
+        typedef typename r1::next n2;
+        typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1;
+        ///
+        typedef aux::replace_unnamed_arg< T2,n2 > r2;
+        typedef typename r2::type a2;
+        typedef typename r2::next n3;
+        typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2;
+        ///
+        typedef aux::replace_unnamed_arg< T3,n3 > r3;
+        typedef typename r3::type a3;
+        typedef typename r3::next n4;
+        typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3;
+        ///
+        typedef aux::replace_unnamed_arg< T4,n4 > r4;
+        typedef typename r4::type a4;
+        typedef typename r4::next n5;
+        typedef aux::resolve_bind_arg< a4,U1,U2,U3,U4,U5 > t4;
+        ///
+        typedef aux::replace_unnamed_arg< T5,n5 > r5;
+        typedef typename r5::type a5;
+        typedef typename r5::next n6;
+        typedef aux::resolve_bind_arg< a5,U1,U2,U3,U4,U5 > t5;
+        ///
+     public:
+        typedef typename apply_wrap5<
+              f_
+            , typename t1::type, typename t2::type, typename t3::type
+            , typename t4::type, typename t5::type
+            >::type type;
+
+    };
+};
+
+namespace aux {
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename U1, typename U2, typename U3, typename U4
+    , typename U5
+    >
+struct resolve_bind_arg<
+      bind5< F,T1,T2,T3,T4,T5 >, U1, U2, U3, U4, U5
+    >
+{
+    typedef bind5< F,T1,T2,T3,T4,T5 > f_;
+    typedef typename apply_wrap5< f_,U1,U2,U3,U4,U5 >::type type;
+};
+
+} // namespace aux
+
+BOOST_MPL_AUX_ARITY_SPEC(6, bind5)
+BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(6, bind5)
+
+/// primary template (not a specialization!)
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    , typename T5
+    >
+struct bind
+    : bind5< F,T1,T2,T3,T4,T5 >
+{
+};
+
+/// if_/eval_if specializations
+template< template< typename T1, typename T2, typename T3 > class F, typename Tag >
+struct quote3;
+
+template< typename T1, typename T2, typename T3 > struct if_;
+
+template<
+      typename Tag, typename T1, typename T2, typename T3
+    >
+struct bind3<
+      quote3< if_,Tag >
+    , T1, T2, T3
+    >
+{
+    template<
+          typename U1 = na, typename U2 = na, typename U3 = na
+        , typename U4 = na, typename U5 = na
+        >
+    struct apply
+    {
+     private:
+        typedef mpl::arg<1> n1;
+        typedef aux::replace_unnamed_arg< T1,n1 > r1;
+        typedef typename r1::type a1;
+        typedef typename r1::next n2;
+        typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1;
+        ///
+        typedef aux::replace_unnamed_arg< T2,n2 > r2;
+        typedef typename r2::type a2;
+        typedef typename r2::next n3;
+        typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2;
+        ///
+        typedef aux::replace_unnamed_arg< T3,n3 > r3;
+        typedef typename r3::type a3;
+        typedef typename r3::next n4;
+        typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3;
+        ///
+        typedef typename if_<
+              typename t1::type
+            , t2, t3
+            >::type f_;
+
+     public:
+        typedef typename f_::type type;
+    };
+};
+
+template<
+      template< typename T1, typename T2, typename T3 > class F, typename Tag
+    >
+struct quote3;
+
+template< typename T1, typename T2, typename T3 > struct eval_if;
+
+template<
+      typename Tag, typename T1, typename T2, typename T3
+    >
+struct bind3<
+      quote3< eval_if,Tag >
+    , T1, T2, T3
+    >
+{
+    template<
+          typename U1 = na, typename U2 = na, typename U3 = na
+        , typename U4 = na, typename U5 = na
+        >
+    struct apply
+    {
+     private:
+        typedef mpl::arg<1> n1;
+        typedef aux::replace_unnamed_arg< T1,n1 > r1;
+        typedef typename r1::type a1;
+        typedef typename r1::next n2;
+        typedef aux::resolve_bind_arg< a1,U1,U2,U3,U4,U5 > t1;
+        ///
+        typedef aux::replace_unnamed_arg< T2,n2 > r2;
+        typedef typename r2::type a2;
+        typedef typename r2::next n3;
+        typedef aux::resolve_bind_arg< a2,U1,U2,U3,U4,U5 > t2;
+        ///
+        typedef aux::replace_unnamed_arg< T3,n3 > r3;
+        typedef typename r3::type a3;
+        typedef typename r3::next n4;
+        typedef aux::resolve_bind_arg< a3,U1,U2,U3,U4,U5 > t3;
+        ///
+        typedef typename eval_if<
+              typename t1::type
+            , t2, t3
+            >::type f_;
+
+     public:
+        typedef typename f_::type type;
+    };
+};
+
+}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/bind_fwd.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/bind_fwd.hpp
new file mode 100644
index 0000000..480e181
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/bind_fwd.hpp
@@ -0,0 +1,51 @@
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/bind_fwd.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl {
+
+template<
+      typename F, typename T1 = na, typename T2 = na, typename T3 = na
+    , typename T4 = na, typename T5 = na
+    >
+struct bind;
+
+template<
+      typename F
+    >
+struct bind0;
+
+template<
+      typename F, typename T1
+    >
+struct bind1;
+
+template<
+      typename F, typename T1, typename T2
+    >
+struct bind2;
+
+template<
+      typename F, typename T1, typename T2, typename T3
+    >
+struct bind3;
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    >
+struct bind4;
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    , typename T5
+    >
+struct bind5;
+
+}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp
new file mode 100644
index 0000000..8bc6ab7
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp
@@ -0,0 +1,180 @@
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/aux_/fold_impl.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl { namespace aux {
+
+/// forward declaration
+
+template<
+      int N
+    , typename First
+    , typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct fold_impl;
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct fold_impl< 0,First,Last,State,ForwardOp >
+{
+    typedef First iter0;
+    typedef State state0;
+    typedef state0 state;
+    typedef iter0 iterator;
+};
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct fold_impl< 1,First,Last,State,ForwardOp >
+{
+    typedef First iter0;
+    typedef State state0;
+    typedef typename apply2< ForwardOp, state0, typename deref<iter0>::type >::type state1;
+    typedef typename mpl::next<iter0>::type iter1;
+
+
+    typedef state1 state;
+    typedef iter1 iterator;
+};
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct fold_impl< 2,First,Last,State,ForwardOp >
+{
+    typedef First iter0;
+    typedef State state0;
+    typedef typename apply2< ForwardOp, state0, typename deref<iter0>::type >::type state1;
+    typedef typename mpl::next<iter0>::type iter1;
+    typedef typename apply2< ForwardOp, state1, typename deref<iter1>::type >::type state2;
+    typedef typename mpl::next<iter1>::type iter2;
+
+
+    typedef state2 state;
+    typedef iter2 iterator;
+};
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct fold_impl< 3,First,Last,State,ForwardOp >
+{
+    typedef First iter0;
+    typedef State state0;
+    typedef typename apply2< ForwardOp, state0, typename deref<iter0>::type >::type state1;
+    typedef typename mpl::next<iter0>::type iter1;
+    typedef typename apply2< ForwardOp, state1, typename deref<iter1>::type >::type state2;
+    typedef typename mpl::next<iter1>::type iter2;
+    typedef typename apply2< ForwardOp, state2, typename deref<iter2>::type >::type state3;
+    typedef typename mpl::next<iter2>::type iter3;
+
+
+    typedef state3 state;
+    typedef iter3 iterator;
+};
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct fold_impl< 4,First,Last,State,ForwardOp >
+{
+    typedef First iter0;
+    typedef State state0;
+    typedef typename apply2< ForwardOp, state0, typename deref<iter0>::type >::type state1;
+    typedef typename mpl::next<iter0>::type iter1;
+    typedef typename apply2< ForwardOp, state1, typename deref<iter1>::type >::type state2;
+    typedef typename mpl::next<iter1>::type iter2;
+    typedef typename apply2< ForwardOp, state2, typename deref<iter2>::type >::type state3;
+    typedef typename mpl::next<iter2>::type iter3;
+    typedef typename apply2< ForwardOp, state3, typename deref<iter3>::type >::type state4;
+    typedef typename mpl::next<iter3>::type iter4;
+
+
+    typedef state4 state;
+    typedef iter4 iterator;
+};
+
+template<
+      int N
+    , typename First
+    , typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct fold_impl
+{
+    typedef fold_impl<
+          4
+        , First
+        , Last
+        , State
+        , ForwardOp
+        > chunk_;
+
+    typedef fold_impl<
+          ( (N - 4) < 0 ? 0 : N - 4 )
+        , typename chunk_::iterator
+        , Last
+        , typename chunk_::state
+        , ForwardOp
+        > res_;
+
+    typedef typename res_::state state;
+    typedef typename res_::iterator iterator;
+};
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct fold_impl< -1,First,Last,State,ForwardOp >
+    : fold_impl<
+          -1
+        , typename mpl::next<First>::type
+        , Last
+        , typename apply2<ForwardOp,State, typename deref<First>::type>::type
+        , ForwardOp
+        >
+{
+};
+
+template<
+      typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct fold_impl< -1,Last,Last,State,ForwardOp >
+{
+    typedef State state;
+    typedef Last iterator;
+};
+
+}}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/full_lambda.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/full_lambda.hpp
new file mode 100644
index 0000000..05c6b75
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/full_lambda.hpp
@@ -0,0 +1,557 @@
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/aux_/full_lambda.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl {
+
+namespace aux {
+
+template<
+      bool C1 = false, bool C2 = false, bool C3 = false, bool C4 = false
+    , bool C5 = false
+    >
+struct lambda_or
+    : true_
+{
+};
+
+template<>
+struct lambda_or< false,false,false,false,false >
+    : false_
+{
+};
+
+} // namespace aux
+
+template<
+      typename T
+    , typename Tag
+    , typename Arity
+    >
+struct lambda
+{
+    typedef false_ is_le;
+    typedef T result_;
+    typedef T type;
+};
+
+template<
+      typename T
+    >
+struct is_lambda_expression
+    : lambda<T>::is_le
+{
+};
+
+template< int N, typename Tag >
+struct lambda< arg<N>,Tag, int_< -1 > >
+{
+    typedef true_ is_le;
+    typedef mpl::arg<N> result_; // qualified for the sake of MIPSpro 7.41
+    typedef mpl::protect<result_> type;
+};
+
+template<
+      typename F
+    , typename Tag
+    >
+struct lambda<
+          bind0<F>
+        , Tag
+        , int_<1>
+        >
+{
+    typedef false_ is_le;
+    typedef bind0<
+          F
+        > result_;
+
+    typedef result_ type;
+};
+
+namespace aux {
+
+template<
+      typename IsLE, typename Tag
+    , template< typename P1 > class F
+    , typename L1
+    >
+struct le_result1
+{
+    typedef F<
+          typename L1::type
+        > result_;
+
+    typedef result_ type;
+};
+
+template<
+      typename Tag
+    , template< typename P1 > class F
+    , typename L1
+    >
+struct le_result1< true_,Tag,F,L1 >
+{
+    typedef bind1<
+          quote1< F,Tag >
+        , typename L1::result_
+        > result_;
+
+    typedef mpl::protect<result_> type;
+};
+
+} // namespace aux
+
+template<
+      template< typename P1 > class F
+    , typename T1
+    , typename Tag
+    >
+struct lambda<
+          F<T1>
+        , Tag
+        , int_<1>
+        >
+{
+    typedef lambda< T1,Tag > l1;
+    typedef typename l1::is_le is_le1;
+    typedef typename aux::lambda_or<
+          is_le1::value
+        >::type is_le;
+
+    typedef aux::le_result1<
+          is_le, Tag, F, l1
+        > le_result_;
+
+    typedef typename le_result_::result_ result_;
+    typedef typename le_result_::type type;
+};
+
+template<
+      typename F, typename T1
+    , typename Tag
+    >
+struct lambda<
+          bind1< F,T1 >
+        , Tag
+        , int_<2>
+        >
+{
+    typedef false_ is_le;
+    typedef bind1<
+          F
+        , T1
+        > result_;
+
+    typedef result_ type;
+};
+
+namespace aux {
+
+template<
+      typename IsLE, typename Tag
+    , template< typename P1, typename P2 > class F
+    , typename L1, typename L2
+    >
+struct le_result2
+{
+    typedef F<
+          typename L1::type, typename L2::type
+        > result_;
+
+    typedef result_ type;
+};
+
+template<
+      typename Tag
+    , template< typename P1, typename P2 > class F
+    , typename L1, typename L2
+    >
+struct le_result2< true_,Tag,F,L1,L2 >
+{
+    typedef bind2<
+          quote2< F,Tag >
+        , typename L1::result_, typename L2::result_
+        > result_;
+
+    typedef mpl::protect<result_> type;
+};
+
+} // namespace aux
+
+template<
+      template< typename P1, typename P2 > class F
+    , typename T1, typename T2
+    , typename Tag
+    >
+struct lambda<
+          F< T1,T2 >
+        , Tag
+        , int_<2>
+        >
+{
+    typedef lambda< T1,Tag > l1;
+    typedef lambda< T2,Tag > l2;
+
+    typedef typename l1::is_le is_le1;
+    typedef typename l2::is_le is_le2;
+
+
+    typedef typename aux::lambda_or<
+          is_le1::value, is_le2::value
+        >::type is_le;
+
+    typedef aux::le_result2<
+          is_le, Tag, F, l1, l2
+        > le_result_;
+
+    typedef typename le_result_::result_ result_;
+    typedef typename le_result_::type type;
+};
+
+template<
+      typename F, typename T1, typename T2
+    , typename Tag
+    >
+struct lambda<
+          bind2< F,T1,T2 >
+        , Tag
+        , int_<3>
+        >
+{
+    typedef false_ is_le;
+    typedef bind2<
+          F
+        , T1, T2
+        > result_;
+
+    typedef result_ type;
+};
+
+namespace aux {
+
+template<
+      typename IsLE, typename Tag
+    , template< typename P1, typename P2, typename P3 > class F
+    , typename L1, typename L2, typename L3
+    >
+struct le_result3
+{
+    typedef F<
+          typename L1::type, typename L2::type, typename L3::type
+        > result_;
+
+    typedef result_ type;
+};
+
+template<
+      typename Tag
+    , template< typename P1, typename P2, typename P3 > class F
+    , typename L1, typename L2, typename L3
+    >
+struct le_result3< true_,Tag,F,L1,L2,L3 >
+{
+    typedef bind3<
+          quote3< F,Tag >
+        , typename L1::result_, typename L2::result_, typename L3::result_
+        > result_;
+
+    typedef mpl::protect<result_> type;
+};
+
+} // namespace aux
+
+template<
+      template< typename P1, typename P2, typename P3 > class F
+    , typename T1, typename T2, typename T3
+    , typename Tag
+    >
+struct lambda<
+          F< T1,T2,T3 >
+        , Tag
+        , int_<3>
+        >
+{
+    typedef lambda< T1,Tag > l1;
+    typedef lambda< T2,Tag > l2;
+    typedef lambda< T3,Tag > l3;
+
+    typedef typename l1::is_le is_le1;
+    typedef typename l2::is_le is_le2;
+    typedef typename l3::is_le is_le3;
+
+
+    typedef typename aux::lambda_or<
+          is_le1::value, is_le2::value, is_le3::value
+        >::type is_le;
+
+    typedef aux::le_result3<
+          is_le, Tag, F, l1, l2, l3
+        > le_result_;
+
+    typedef typename le_result_::result_ result_;
+    typedef typename le_result_::type type;
+};
+
+template<
+      typename F, typename T1, typename T2, typename T3
+    , typename Tag
+    >
+struct lambda<
+          bind3< F,T1,T2,T3 >
+        , Tag
+        , int_<4>
+        >
+{
+    typedef false_ is_le;
+    typedef bind3<
+          F
+        , T1, T2, T3
+        > result_;
+
+    typedef result_ type;
+};
+
+namespace aux {
+
+template<
+      typename IsLE, typename Tag
+    , template< typename P1, typename P2, typename P3, typename P4 > class F
+    , typename L1, typename L2, typename L3, typename L4
+    >
+struct le_result4
+{
+    typedef F<
+          typename L1::type, typename L2::type, typename L3::type
+        , typename L4::type
+        > result_;
+
+    typedef result_ type;
+};
+
+template<
+      typename Tag
+    , template< typename P1, typename P2, typename P3, typename P4 > class F
+    , typename L1, typename L2, typename L3, typename L4
+    >
+struct le_result4< true_,Tag,F,L1,L2,L3,L4 >
+{
+    typedef bind4<
+          quote4< F,Tag >
+        , typename L1::result_, typename L2::result_, typename L3::result_
+        , typename L4::result_
+        > result_;
+
+    typedef mpl::protect<result_> type;
+};
+
+} // namespace aux
+
+template<
+      template< typename P1, typename P2, typename P3, typename P4 > class F
+    , typename T1, typename T2, typename T3, typename T4
+    , typename Tag
+    >
+struct lambda<
+          F< T1,T2,T3,T4 >
+        , Tag
+        , int_<4>
+        >
+{
+    typedef lambda< T1,Tag > l1;
+    typedef lambda< T2,Tag > l2;
+    typedef lambda< T3,Tag > l3;
+    typedef lambda< T4,Tag > l4;
+
+    typedef typename l1::is_le is_le1;
+    typedef typename l2::is_le is_le2;
+    typedef typename l3::is_le is_le3;
+    typedef typename l4::is_le is_le4;
+
+
+    typedef typename aux::lambda_or<
+          is_le1::value, is_le2::value, is_le3::value, is_le4::value
+        >::type is_le;
+
+    typedef aux::le_result4<
+          is_le, Tag, F, l1, l2, l3, l4
+        > le_result_;
+
+    typedef typename le_result_::result_ result_;
+    typedef typename le_result_::type type;
+};
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    , typename Tag
+    >
+struct lambda<
+          bind4< F,T1,T2,T3,T4 >
+        , Tag
+        , int_<5>
+        >
+{
+    typedef false_ is_le;
+    typedef bind4<
+          F
+        , T1, T2, T3, T4
+        > result_;
+
+    typedef result_ type;
+};
+
+namespace aux {
+
+template<
+      typename IsLE, typename Tag
+    , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F
+    , typename L1, typename L2, typename L3, typename L4, typename L5
+    >
+struct le_result5
+{
+    typedef F<
+          typename L1::type, typename L2::type, typename L3::type
+        , typename L4::type, typename L5::type
+        > result_;
+
+    typedef result_ type;
+};
+
+template<
+      typename Tag
+    , template< typename P1, typename P2, typename P3, typename P4, typename P5 > class F
+    , typename L1, typename L2, typename L3, typename L4, typename L5
+    >
+struct le_result5< true_,Tag,F,L1,L2,L3,L4,L5 >
+{
+    typedef bind5<
+          quote5< F,Tag >
+        , typename L1::result_, typename L2::result_, typename L3::result_
+        , typename L4::result_, typename L5::result_
+        > result_;
+
+    typedef mpl::protect<result_> type;
+};
+
+} // namespace aux
+
+template<
+      template<
+          typename P1, typename P2, typename P3, typename P4
+        , typename P5
+        >
+      class F
+    , typename T1, typename T2, typename T3, typename T4, typename T5
+    , typename Tag
+    >
+struct lambda<
+          F< T1,T2,T3,T4,T5 >
+        , Tag
+        , int_<5>
+        >
+{
+    typedef lambda< T1,Tag > l1;
+    typedef lambda< T2,Tag > l2;
+    typedef lambda< T3,Tag > l3;
+    typedef lambda< T4,Tag > l4;
+    typedef lambda< T5,Tag > l5;
+
+    typedef typename l1::is_le is_le1;
+    typedef typename l2::is_le is_le2;
+    typedef typename l3::is_le is_le3;
+    typedef typename l4::is_le is_le4;
+    typedef typename l5::is_le is_le5;
+
+
+    typedef typename aux::lambda_or<
+          is_le1::value, is_le2::value, is_le3::value, is_le4::value
+        , is_le5::value
+        >::type is_le;
+
+    typedef aux::le_result5<
+          is_le, Tag, F, l1, l2, l3, l4, l5
+        > le_result_;
+
+    typedef typename le_result_::result_ result_;
+    typedef typename le_result_::type type;
+};
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    , typename T5
+    , typename Tag
+    >
+struct lambda<
+          bind5< F,T1,T2,T3,T4,T5 >
+        , Tag
+        , int_<6>
+        >
+{
+    typedef false_ is_le;
+    typedef bind5<
+          F
+        , T1, T2, T3, T4, T5
+        > result_;
+
+    typedef result_ type;
+};
+
+/// special case for 'protect'
+template< typename T, typename Tag >
+struct lambda< mpl::protect<T>,Tag, int_<1> >
+{
+    typedef false_ is_le;
+    typedef mpl::protect<T> result_;
+    typedef result_ type;
+};
+
+/// specializations for the main 'bind' form
+
+template<
+      typename F, typename T1, typename T2, typename T3, typename T4
+    , typename T5
+    , typename Tag
+    >
+struct lambda<
+          bind< F,T1,T2,T3,T4,T5 >
+        , Tag
+        , int_<6>
+        >
+{
+    typedef false_ is_le;
+    typedef bind< F,T1,T2,T3,T4,T5 > result_;
+    typedef result_ type;
+};
+
+template<
+      typename F
+    , typename Tag1
+    , typename Tag2
+    , typename Arity
+    >
+struct lambda<
+          lambda< F,Tag1,Arity >
+        , Tag2
+        , int_<3>
+        >
+{
+    typedef lambda< F,Tag2 > l1;
+    typedef lambda< Tag1,Tag2 > l2;
+    typedef typename l1::is_le is_le;
+    typedef bind1< quote1<aux::template_arity>, typename l1::result_ > arity_;
+    typedef lambda< typename if_< is_le,arity_,Arity >::type, Tag2 > l3;
+    typedef aux::le_result3<is_le, Tag2, mpl::lambda, l1, l2, l3> le_result_;
+    typedef typename le_result_::result_ result_;
+    typedef typename le_result_::type type;
+};
+
+BOOST_MPL_AUX_NA_SPEC2(2, 3, lambda)
+
+}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp
new file mode 100644
index 0000000..fba0051
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp
@@ -0,0 +1,133 @@
+
+// Copyright Aleksey Gurtovoy 2001-2004
+// Copyright David Abrahams 2001-2002
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/aux_/iter_fold_if_impl.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl { namespace aux {
+
+template< typename Iterator, typename State >
+struct iter_fold_if_null_step
+{
+    typedef State state;
+    typedef Iterator iterator;
+};
+
+template< bool >
+struct iter_fold_if_step_impl
+{
+    template<
+          typename Iterator
+        , typename State
+        , typename StateOp
+        , typename IteratorOp
+        >
+    struct result_
+    {
+        typedef typename apply2< StateOp,State,Iterator >::type state;
+        typedef typename IteratorOp::type iterator;
+    };
+};
+
+template<>
+struct iter_fold_if_step_impl<false>
+{
+    template<
+          typename Iterator
+        , typename State
+        , typename StateOp
+        , typename IteratorOp
+        >
+    struct result_
+    {
+        typedef State state;
+        typedef Iterator iterator;
+    };
+};
+
+template<
+      typename Iterator
+    , typename State
+    , typename ForwardOp
+    , typename Predicate
+    >
+struct iter_fold_if_forward_step
+{
+    typedef typename apply2< Predicate,State,Iterator >::type not_last;
+    typedef typename iter_fold_if_step_impl<
+          BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value
+        >::template result_< Iterator,State,ForwardOp, mpl::next<Iterator> > impl_;
+
+    typedef typename impl_::state state;
+    typedef typename impl_::iterator iterator;
+};
+
+template<
+      typename Iterator
+    , typename State
+    , typename BackwardOp
+    , typename Predicate
+    >
+struct iter_fold_if_backward_step
+{
+    typedef typename apply2< Predicate,State,Iterator >::type not_last;
+    typedef typename iter_fold_if_step_impl<
+          BOOST_MPL_AUX_MSVC_VALUE_WKND(not_last)::value
+        >::template result_< Iterator,State,BackwardOp, identity<Iterator> > impl_;
+
+    typedef typename impl_::state state;
+    typedef typename impl_::iterator iterator;
+};
+
+template<
+      typename Iterator
+    , typename State
+    , typename ForwardOp
+    , typename ForwardPredicate
+    , typename BackwardOp
+    , typename BackwardPredicate
+    >
+struct iter_fold_if_impl
+{
+ private:
+    typedef iter_fold_if_null_step< Iterator,State > forward_step0;
+    typedef iter_fold_if_forward_step< typename forward_step0::iterator, typename forward_step0::state, ForwardOp, ForwardPredicate > forward_step1;
+    typedef iter_fold_if_forward_step< typename forward_step1::iterator, typename forward_step1::state, ForwardOp, ForwardPredicate > forward_step2;
+    typedef iter_fold_if_forward_step< typename forward_step2::iterator, typename forward_step2::state, ForwardOp, ForwardPredicate > forward_step3;
+    typedef iter_fold_if_forward_step< typename forward_step3::iterator, typename forward_step3::state, ForwardOp, ForwardPredicate > forward_step4;
+
+
+    typedef typename if_<
+          typename forward_step4::not_last
+        , iter_fold_if_impl<
+              typename forward_step4::iterator
+            , typename forward_step4::state
+            , ForwardOp
+            , ForwardPredicate
+            , BackwardOp
+            , BackwardPredicate
+            >
+        , iter_fold_if_null_step<
+              typename forward_step4::iterator
+            , typename forward_step4::state
+            >
+        >::type backward_step4;
+
+    typedef iter_fold_if_backward_step< typename forward_step3::iterator, typename backward_step4::state, BackwardOp, BackwardPredicate > backward_step3;
+    typedef iter_fold_if_backward_step< typename forward_step2::iterator, typename backward_step3::state, BackwardOp, BackwardPredicate > backward_step2;
+    typedef iter_fold_if_backward_step< typename forward_step1::iterator, typename backward_step2::state, BackwardOp, BackwardPredicate > backward_step1;
+    typedef iter_fold_if_backward_step< typename forward_step0::iterator, typename backward_step1::state, BackwardOp, BackwardPredicate > backward_step0;
+
+
+ public:
+    typedef typename backward_step0::state state;
+    typedef typename backward_step4::iterator iterator;
+};
+
+}}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp
new file mode 100644
index 0000000..e4453de
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp
@@ -0,0 +1,180 @@
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/aux_/iter_fold_impl.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl { namespace aux {
+
+/// forward declaration
+
+template<
+      int N
+    , typename First
+    , typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct iter_fold_impl;
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct iter_fold_impl< 0,First,Last,State,ForwardOp >
+{
+    typedef First iter0;
+    typedef State state0;
+    typedef state0 state;
+    typedef iter0 iterator;
+};
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct iter_fold_impl< 1,First,Last,State,ForwardOp >
+{
+    typedef First iter0;
+    typedef State state0;
+    typedef typename apply2< ForwardOp,state0,iter0 >::type state1;
+    typedef typename mpl::next<iter0>::type iter1;
+
+
+    typedef state1 state;
+    typedef iter1 iterator;
+};
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct iter_fold_impl< 2,First,Last,State,ForwardOp >
+{
+    typedef First iter0;
+    typedef State state0;
+    typedef typename apply2< ForwardOp,state0,iter0 >::type state1;
+    typedef typename mpl::next<iter0>::type iter1;
+    typedef typename apply2< ForwardOp,state1,iter1 >::type state2;
+    typedef typename mpl::next<iter1>::type iter2;
+
+
+    typedef state2 state;
+    typedef iter2 iterator;
+};
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct iter_fold_impl< 3,First,Last,State,ForwardOp >
+{
+    typedef First iter0;
+    typedef State state0;
+    typedef typename apply2< ForwardOp,state0,iter0 >::type state1;
+    typedef typename mpl::next<iter0>::type iter1;
+    typedef typename apply2< ForwardOp,state1,iter1 >::type state2;
+    typedef typename mpl::next<iter1>::type iter2;
+    typedef typename apply2< ForwardOp,state2,iter2 >::type state3;
+    typedef typename mpl::next<iter2>::type iter3;
+
+
+    typedef state3 state;
+    typedef iter3 iterator;
+};
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct iter_fold_impl< 4,First,Last,State,ForwardOp >
+{
+    typedef First iter0;
+    typedef State state0;
+    typedef typename apply2< ForwardOp,state0,iter0 >::type state1;
+    typedef typename mpl::next<iter0>::type iter1;
+    typedef typename apply2< ForwardOp,state1,iter1 >::type state2;
+    typedef typename mpl::next<iter1>::type iter2;
+    typedef typename apply2< ForwardOp,state2,iter2 >::type state3;
+    typedef typename mpl::next<iter2>::type iter3;
+    typedef typename apply2< ForwardOp,state3,iter3 >::type state4;
+    typedef typename mpl::next<iter3>::type iter4;
+
+
+    typedef state4 state;
+    typedef iter4 iterator;
+};
+
+template<
+      int N
+    , typename First
+    , typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct iter_fold_impl
+{
+    typedef iter_fold_impl<
+          4
+        , First
+        , Last
+        , State
+        , ForwardOp
+        > chunk_;
+
+    typedef iter_fold_impl<
+          ( (N - 4) < 0 ? 0 : N - 4 )
+        , typename chunk_::iterator
+        , Last
+        , typename chunk_::state
+        , ForwardOp
+        > res_;
+
+    typedef typename res_::state state;
+    typedef typename res_::iterator iterator;
+};
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct iter_fold_impl< -1,First,Last,State,ForwardOp >
+    : iter_fold_impl<
+          -1
+        , typename mpl::next<First>::type
+        , Last
+        , typename apply2< ForwardOp,State,First >::type
+        , ForwardOp
+        >
+{
+};
+
+template<
+      typename Last
+    , typename State
+    , typename ForwardOp
+    >
+struct iter_fold_impl< -1,Last,Last,State,ForwardOp >
+{
+    typedef State state;
+    typedef Last iterator;
+};
+
+}}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/less.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/less.hpp
new file mode 100644
index 0000000..e57fc20
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/less.hpp
@@ -0,0 +1,94 @@
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/less.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl {
+
+template<
+      typename Tag1
+    , typename Tag2
+    >
+struct less_impl
+    : if_c<
+          ( BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag1)
+              > BOOST_MPL_AUX_NESTED_VALUE_WKND(int, Tag2)
+            )
+
+        , aux::cast2nd_impl< less_impl< Tag1,Tag1 >,Tag1, Tag2 >
+        , aux::cast1st_impl< less_impl< Tag2,Tag2 >,Tag1, Tag2 >
+        >::type
+{
+};
+
+/// for Digital Mars C++/compilers with no CTPS/TTP support
+template<> struct less_impl< na,na >
+{
+    template< typename U1, typename U2 > struct apply
+    {
+        typedef apply type;
+        BOOST_STATIC_CONSTANT(int, value  = 0);
+    };
+};
+
+template< typename Tag > struct less_impl< na,Tag >
+{
+    template< typename U1, typename U2 > struct apply
+    {
+        typedef apply type;
+        BOOST_STATIC_CONSTANT(int, value  = 0);
+    };
+};
+
+template< typename Tag > struct less_impl< Tag,na >
+{
+    template< typename U1, typename U2 > struct apply
+    {
+        typedef apply type;
+        BOOST_STATIC_CONSTANT(int, value  = 0);
+    };
+};
+
+template< typename T > struct less_tag
+{
+    typedef typename T::tag type;
+};
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(N1)
+    , typename BOOST_MPL_AUX_NA_PARAM(N2)
+    >
+struct less
+
+    : less_impl<
+          typename less_tag<N1>::type
+        , typename less_tag<N2>::type
+        >::template apply< N1,N2 >::type
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(2, less, (N1, N2))
+
+};
+
+BOOST_MPL_AUX_NA_SPEC2(2, 2, less)
+
+}}
+
+namespace boost { namespace mpl {
+
+template<>
+struct less_impl< integral_c_tag,integral_c_tag >
+{
+    template< typename N1, typename N2 > struct apply
+
+        : bool_< ( BOOST_MPL_AUX_VALUE_WKND(N2)::value > BOOST_MPL_AUX_VALUE_WKND(N1)::value ) >
+    {
+    };
+};
+
+}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/list.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/list.hpp
new file mode 100644
index 0000000..055767c
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/list.hpp
@@ -0,0 +1,322 @@
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/list.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl {
+
+template<
+      typename T0 = na, typename T1 = na, typename T2 = na, typename T3 = na
+    , typename T4 = na, typename T5 = na, typename T6 = na, typename T7 = na
+    , typename T8 = na, typename T9 = na, typename T10 = na, typename T11 = na
+    , typename T12 = na, typename T13 = na, typename T14 = na
+    , typename T15 = na, typename T16 = na, typename T17 = na
+    , typename T18 = na, typename T19 = na
+    >
+struct list;
+
+template<
+
+    >
+struct list<
+          na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na
+        , na, na, na
+        >
+    : list0<  >
+{
+    typedef list0<  >::type type;
+};
+
+template<
+      typename T0
+    >
+struct list<
+          T0, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na
+        , na, na, na
+        >
+    : list1<T0>
+{
+    typedef typename list1<T0>::type type;
+};
+
+template<
+      typename T0, typename T1
+    >
+struct list<
+          T0, T1, na, na, na, na, na, na, na, na, na, na, na, na, na, na, na
+        , na, na, na
+        >
+    : list2< T0,T1 >
+{
+    typedef typename list2< T0,T1 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2
+    >
+struct list<
+          T0, T1, T2, na, na, na, na, na, na, na, na, na, na, na, na, na, na
+        , na, na, na
+        >
+    : list3< T0,T1,T2 >
+{
+    typedef typename list3< T0,T1,T2 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3
+    >
+struct list<
+          T0, T1, T2, T3, na, na, na, na, na, na, na, na, na, na, na, na, na
+        , na, na, na
+        >
+    : list4< T0,T1,T2,T3 >
+{
+    typedef typename list4< T0,T1,T2,T3 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    >
+struct list<
+          T0, T1, T2, T3, T4, na, na, na, na, na, na, na, na, na, na, na, na
+        , na, na, na
+        >
+    : list5< T0,T1,T2,T3,T4 >
+{
+    typedef typename list5< T0,T1,T2,T3,T4 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5
+    >
+struct list<
+          T0, T1, T2, T3, T4, T5, na, na, na, na, na, na, na, na, na, na, na
+        , na, na, na
+        >
+    : list6< T0,T1,T2,T3,T4,T5 >
+{
+    typedef typename list6< T0,T1,T2,T3,T4,T5 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6
+    >
+struct list<
+          T0, T1, T2, T3, T4, T5, T6, na, na, na, na, na, na, na, na, na, na
+        , na, na, na
+        >
+    : list7< T0,T1,T2,T3,T4,T5,T6 >
+{
+    typedef typename list7< T0,T1,T2,T3,T4,T5,T6 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7
+    >
+struct list<
+          T0, T1, T2, T3, T4, T5, T6, T7, na, na, na, na, na, na, na, na, na
+        , na, na, na
+        >
+    : list8< T0,T1,T2,T3,T4,T5,T6,T7 >
+{
+    typedef typename list8< T0,T1,T2,T3,T4,T5,T6,T7 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8
+    >
+struct list<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, na, na, na, na, na, na, na, na
+        , na, na, na
+        >
+    : list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >
+{
+    typedef typename list9< T0,T1,T2,T3,T4,T5,T6,T7,T8 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    >
+struct list<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, na, na, na, na, na, na, na
+        , na, na, na
+        >
+    : list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >
+{
+    typedef typename list10< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10
+    >
+struct list<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, na, na, na, na, na, na
+        , na, na, na
+        >
+    : list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >
+{
+    typedef typename list11< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11
+    >
+struct list<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, na, na, na, na
+        , na, na, na, na
+        >
+    : list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >
+{
+    typedef typename list12< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11, typename T12
+    >
+struct list<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, na, na, na
+        , na, na, na, na
+        >
+    : list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >
+{
+    typedef typename list13< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11, typename T12, typename T13
+    >
+struct list<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, na, na
+        , na, na, na, na
+        >
+    : list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >
+{
+    typedef typename list14< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11, typename T12, typename T13, typename T14
+    >
+struct list<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, na
+        , na, na, na, na
+        >
+    : list15<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
+        >
+{
+    typedef typename list15< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11, typename T12, typename T13, typename T14
+    , typename T15
+    >
+struct list<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
+        , T15, na, na, na, na
+        >
+    : list16<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
+        , T15
+        >
+{
+    typedef typename list16< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11, typename T12, typename T13, typename T14
+    , typename T15, typename T16
+    >
+struct list<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
+        , T15, T16, na, na, na
+        >
+    : list17<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
+        , T15, T16
+        >
+{
+    typedef typename list17< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11, typename T12, typename T13, typename T14
+    , typename T15, typename T16, typename T17
+    >
+struct list<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
+        , T15, T16, T17, na, na
+        >
+    : list18<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
+        , T15, T16, T17
+        >
+{
+    typedef typename list18< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >::type type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11, typename T12, typename T13, typename T14
+    , typename T15, typename T16, typename T17, typename T18
+    >
+struct list<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
+        , T15, T16, T17, T18, na
+        >
+    : list19<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
+        , T15, T16, T17, T18
+        >
+{
+    typedef typename list19< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >::type type;
+};
+
+/// primary template (not a specialization!)
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11, typename T12, typename T13, typename T14
+    , typename T15, typename T16, typename T17, typename T18, typename T19
+    >
+struct list
+    : list20<
+          T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
+        , T15, T16, T17, T18, T19
+        >
+{
+    typedef typename list20< T0,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >::type type;
+};
+
+}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/or.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/or.hpp
new file mode 100644
index 0000000..3a4e9aa
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/or.hpp
@@ -0,0 +1,69 @@
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/or.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl {
+
+namespace aux {
+
+template< bool C_, typename T1, typename T2, typename T3, typename T4 >
+struct or_impl
+    : true_
+{
+};
+
+template< typename T1, typename T2, typename T3, typename T4 >
+struct or_impl< false,T1,T2,T3,T4 >
+    : or_impl<
+          BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value
+        , T2, T3, T4
+        , false_
+        >
+{
+};
+
+template<>
+struct or_impl<
+          false
+        , false_, false_, false_, false_
+        >
+    : false_
+{
+};
+
+} // namespace aux
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(T1)
+    , typename BOOST_MPL_AUX_NA_PARAM(T2)
+    , typename T3 = false_, typename T4 = false_, typename T5 = false_
+    >
+struct or_
+
+    : aux::or_impl<
+          BOOST_MPL_AUX_NESTED_TYPE_WKND(T1)::value
+        , T2, T3, T4, T5
+        >
+
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(
+          5
+        , or_
+        , ( T1, T2, T3, T4, T5)
+        )
+};
+
+BOOST_MPL_AUX_NA_SPEC2(
+      2
+    , 5
+    , or_
+    )
+
+}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/placeholders.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/placeholders.hpp
new file mode 100644
index 0000000..282a36a
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/placeholders.hpp
@@ -0,0 +1,105 @@
+
+// Copyright Aleksey Gurtovoy 2001-2004
+// Copyright Peter Dimov 2001-2003
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/placeholders.hpp" header
+// -- DO NOT modify by hand!
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+typedef arg< -1 > _;
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+namespace boost { namespace mpl {
+
+BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_)
+
+namespace placeholders {
+using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_;
+}
+
+}}
+
+/// agurt, 17/mar/02: one more placeholder for the last 'apply#'
+/// specialization
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+typedef arg<1> _1;
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+namespace boost { namespace mpl {
+
+BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_1)
+
+namespace placeholders {
+using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_1;
+}
+
+}}
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+typedef arg<2> _2;
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+namespace boost { namespace mpl {
+
+BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_2)
+
+namespace placeholders {
+using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_2;
+}
+
+}}
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+typedef arg<3> _3;
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+namespace boost { namespace mpl {
+
+BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_3)
+
+namespace placeholders {
+using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_3;
+}
+
+}}
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+typedef arg<4> _4;
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+namespace boost { namespace mpl {
+
+BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_4)
+
+namespace placeholders {
+using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_4;
+}
+
+}}
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+typedef arg<5> _5;
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+namespace boost { namespace mpl {
+
+BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_5)
+
+namespace placeholders {
+using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_5;
+}
+
+}}
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+typedef arg<6> _6;
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+namespace boost { namespace mpl {
+
+BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_6)
+
+namespace placeholders {
+using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_6;
+}
+
+}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/quote.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/quote.hpp
new file mode 100644
index 0000000..c0c119d
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/quote.hpp
@@ -0,0 +1,122 @@
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/quote.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl {
+
+template< typename T, bool has_type_ >
+struct quote_impl
+{
+    typedef typename T::type type;
+};
+
+template< typename T >
+struct quote_impl< T,false >
+{
+    typedef T type;
+};
+
+template<
+      template< typename P1 > class F
+    , typename Tag = void_
+    >
+struct quote1
+{
+    template< typename U1 > struct apply
+
+        : quote_impl<
+              F<U1>
+            , aux::has_type< F<U1> >::value
+            >
+
+    {
+    };
+};
+
+template<
+      template< typename P1, typename P2 > class F
+    , typename Tag = void_
+    >
+struct quote2
+{
+    template< typename U1, typename U2 > struct apply
+
+        : quote_impl<
+              F< U1,U2 >
+            , aux::has_type< F< U1,U2 > >::value
+            >
+
+    {
+    };
+};
+
+template<
+      template< typename P1, typename P2, typename P3 > class F
+    , typename Tag = void_
+    >
+struct quote3
+{
+    template< typename U1, typename U2, typename U3 > struct apply
+
+        : quote_impl<
+              F< U1,U2,U3 >
+            , aux::has_type< F< U1,U2,U3 > >::value
+            >
+
+    {
+    };
+};
+
+template<
+      template< typename P1, typename P2, typename P3, typename P4 > class F
+    , typename Tag = void_
+    >
+struct quote4
+{
+    template<
+          typename U1, typename U2, typename U3, typename U4
+        >
+    struct apply
+
+        : quote_impl<
+              F< U1,U2,U3,U4 >
+            , aux::has_type< F< U1,U2,U3,U4 > >::value
+            >
+
+    {
+    };
+};
+
+template<
+      template<
+          typename P1, typename P2, typename P3, typename P4
+        , typename P5
+        >
+      class F
+    , typename Tag = void_
+    >
+struct quote5
+{
+    template<
+          typename U1, typename U2, typename U3, typename U4
+        , typename U5
+        >
+    struct apply
+
+        : quote_impl<
+              F< U1,U2,U3,U4,U5 >
+            , aux::has_type< F< U1,U2,U3,U4,U5 > >::value
+            >
+
+    {
+    };
+};
+
+}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp
new file mode 100644
index 0000000..3d43b7a
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp
@@ -0,0 +1,231 @@
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/aux_/reverse_fold_impl.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl { namespace aux {
+
+/// forward declaration
+
+template<
+      long N
+    , typename First
+    , typename Last
+    , typename State
+    , typename BackwardOp
+    , typename ForwardOp
+    >
+struct reverse_fold_impl;
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename BackwardOp
+    , typename ForwardOp
+    >
+struct reverse_fold_impl< 0,First,Last,State,BackwardOp,ForwardOp >
+{
+    typedef First iter0;
+    typedef State fwd_state0;
+    typedef fwd_state0 bkwd_state0;
+    typedef bkwd_state0 state;
+    typedef iter0 iterator;
+};
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename BackwardOp
+    , typename ForwardOp
+    >
+struct reverse_fold_impl< 1,First,Last,State,BackwardOp,ForwardOp >
+{
+    typedef First iter0;
+    typedef State fwd_state0;
+    typedef typename apply2< ForwardOp, fwd_state0, typename deref<iter0>::type >::type fwd_state1;
+    typedef typename mpl::next<iter0>::type iter1;
+
+
+    typedef fwd_state1 bkwd_state1;
+    typedef typename apply2< BackwardOp, bkwd_state1, typename deref<iter0>::type >::type bkwd_state0;
+    typedef bkwd_state0 state;
+    typedef iter1 iterator;
+};
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename BackwardOp
+    , typename ForwardOp
+    >
+struct reverse_fold_impl< 2,First,Last,State,BackwardOp,ForwardOp >
+{
+    typedef First iter0;
+    typedef State fwd_state0;
+    typedef typename apply2< ForwardOp, fwd_state0, typename deref<iter0>::type >::type fwd_state1;
+    typedef typename mpl::next<iter0>::type iter1;
+    typedef typename apply2< ForwardOp, fwd_state1, typename deref<iter1>::type >::type fwd_state2;
+    typedef typename mpl::next<iter1>::type iter2;
+
+
+    typedef fwd_state2 bkwd_state2;
+    typedef typename apply2< BackwardOp, bkwd_state2, typename deref<iter1>::type >::type bkwd_state1;
+    typedef typename apply2< BackwardOp, bkwd_state1, typename deref<iter0>::type >::type bkwd_state0;
+
+
+    typedef bkwd_state0 state;
+    typedef iter2 iterator;
+};
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename BackwardOp
+    , typename ForwardOp
+    >
+struct reverse_fold_impl< 3,First,Last,State,BackwardOp,ForwardOp >
+{
+    typedef First iter0;
+    typedef State fwd_state0;
+    typedef typename apply2< ForwardOp, fwd_state0, typename deref<iter0>::type >::type fwd_state1;
+    typedef typename mpl::next<iter0>::type iter1;
+    typedef typename apply2< ForwardOp, fwd_state1, typename deref<iter1>::type >::type fwd_state2;
+    typedef typename mpl::next<iter1>::type iter2;
+    typedef typename apply2< ForwardOp, fwd_state2, typename deref<iter2>::type >::type fwd_state3;
+    typedef typename mpl::next<iter2>::type iter3;
+
+
+    typedef fwd_state3 bkwd_state3;
+    typedef typename apply2< BackwardOp, bkwd_state3, typename deref<iter2>::type >::type bkwd_state2;
+    typedef typename apply2< BackwardOp, bkwd_state2, typename deref<iter1>::type >::type bkwd_state1;
+    typedef typename apply2< BackwardOp, bkwd_state1, typename deref<iter0>::type >::type bkwd_state0;
+
+
+    typedef bkwd_state0 state;
+    typedef iter3 iterator;
+};
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename BackwardOp
+    , typename ForwardOp
+    >
+struct reverse_fold_impl< 4,First,Last,State,BackwardOp,ForwardOp >
+{
+    typedef First iter0;
+    typedef State fwd_state0;
+    typedef typename apply2< ForwardOp, fwd_state0, typename deref<iter0>::type >::type fwd_state1;
+    typedef typename mpl::next<iter0>::type iter1;
+    typedef typename apply2< ForwardOp, fwd_state1, typename deref<iter1>::type >::type fwd_state2;
+    typedef typename mpl::next<iter1>::type iter2;
+    typedef typename apply2< ForwardOp, fwd_state2, typename deref<iter2>::type >::type fwd_state3;
+    typedef typename mpl::next<iter2>::type iter3;
+    typedef typename apply2< ForwardOp, fwd_state3, typename deref<iter3>::type >::type fwd_state4;
+    typedef typename mpl::next<iter3>::type iter4;
+
+
+    typedef fwd_state4 bkwd_state4;
+    typedef typename apply2< BackwardOp, bkwd_state4, typename deref<iter3>::type >::type bkwd_state3;
+    typedef typename apply2< BackwardOp, bkwd_state3, typename deref<iter2>::type >::type bkwd_state2;
+    typedef typename apply2< BackwardOp, bkwd_state2, typename deref<iter1>::type >::type bkwd_state1;
+    typedef typename apply2< BackwardOp, bkwd_state1, typename deref<iter0>::type >::type bkwd_state0;
+
+
+    typedef bkwd_state0 state;
+    typedef iter4 iterator;
+};
+
+template<
+      long N
+    , typename First
+    , typename Last
+    , typename State
+    , typename BackwardOp
+    , typename ForwardOp
+    >
+struct reverse_fold_impl
+{
+    typedef First iter0;
+    typedef State fwd_state0;
+    typedef typename apply2< ForwardOp, fwd_state0, typename deref<iter0>::type >::type fwd_state1;
+    typedef typename mpl::next<iter0>::type iter1;
+    typedef typename apply2< ForwardOp, fwd_state1, typename deref<iter1>::type >::type fwd_state2;
+    typedef typename mpl::next<iter1>::type iter2;
+    typedef typename apply2< ForwardOp, fwd_state2, typename deref<iter2>::type >::type fwd_state3;
+    typedef typename mpl::next<iter2>::type iter3;
+    typedef typename apply2< ForwardOp, fwd_state3, typename deref<iter3>::type >::type fwd_state4;
+    typedef typename mpl::next<iter3>::type iter4;
+
+
+    typedef reverse_fold_impl<
+          ( (N - 4) < 0 ? 0 : N - 4 )
+        , iter4
+        , Last
+        , fwd_state4
+        , BackwardOp
+        , ForwardOp
+        > nested_chunk;
+
+    typedef typename nested_chunk::state bkwd_state4;
+    typedef typename apply2< BackwardOp, bkwd_state4, typename deref<iter3>::type >::type bkwd_state3;
+    typedef typename apply2< BackwardOp, bkwd_state3, typename deref<iter2>::type >::type bkwd_state2;
+    typedef typename apply2< BackwardOp, bkwd_state2, typename deref<iter1>::type >::type bkwd_state1;
+    typedef typename apply2< BackwardOp, bkwd_state1, typename deref<iter0>::type >::type bkwd_state0;
+
+
+    typedef bkwd_state0 state;
+    typedef typename nested_chunk::iterator iterator;
+};
+
+template<
+      typename First
+    , typename Last
+    , typename State
+    , typename BackwardOp
+    , typename ForwardOp
+    >
+struct reverse_fold_impl< -1,First,Last,State,BackwardOp,ForwardOp >
+{
+    typedef reverse_fold_impl<
+          -1
+        , typename mpl::next<First>::type
+        , Last
+        , typename apply2<ForwardOp,State, typename deref<First>::type>::type
+        , BackwardOp
+        , ForwardOp
+        > nested_step;
+
+    typedef typename apply2<
+          BackwardOp
+        , typename nested_step::state
+        , typename deref<First>::type
+        >::type state;
+
+    typedef typename nested_step::iterator iterator;
+};
+
+template<
+      typename Last
+    , typename State
+    , typename BackwardOp
+    , typename ForwardOp
+    >
+struct reverse_fold_impl< -1,Last,Last,State,BackwardOp,ForwardOp >
+{
+    typedef State state;
+    typedef Last iterator;
+};
+
+}}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp
new file mode 100644
index 0000000..28c8a90
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp
@@ -0,0 +1,97 @@
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// *Preprocessed* version of the main "template_arity.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl { namespace aux {
+template< int N > struct arity_tag
+{
+    typedef char (&type)[N + 1];
+};
+
+template<
+      int C1, int C2, int C3, int C4, int C5, int C6
+    >
+struct max_arity
+{
+    BOOST_STATIC_CONSTANT(int, value =
+          ( C6 > 0 ? C6 : ( C5 > 0 ? C5 : ( C4 > 0 ? C4 : ( C3 > 0 ? C3 : ( C2 > 0 ? C2 : ( C1 > 0 ? C1 : -1 ) ) ) ) ) )
+        );
+};
+
+arity_tag<0>::type arity_helper(...);
+
+template<
+      template< typename P1 > class F
+    , typename T1
+    >
+typename arity_tag<1>::type
+arity_helper(type_wrapper< F<T1> >, arity_tag<1>);
+
+template<
+      template< typename P1, typename P2 > class F
+    , typename T1, typename T2
+    >
+typename arity_tag<2>::type
+arity_helper(type_wrapper< F< T1,T2 > >, arity_tag<2>);
+
+template<
+      template< typename P1, typename P2, typename P3 > class F
+    , typename T1, typename T2, typename T3
+    >
+typename arity_tag<3>::type
+arity_helper(type_wrapper< F< T1,T2,T3 > >, arity_tag<3>);
+
+template<
+      template< typename P1, typename P2, typename P3, typename P4 > class F
+    , typename T1, typename T2, typename T3, typename T4
+    >
+typename arity_tag<4>::type
+arity_helper(type_wrapper< F< T1,T2,T3,T4 > >, arity_tag<4>);
+
+template<
+      template<
+          typename P1, typename P2, typename P3, typename P4
+        , typename P5
+        >
+      class F
+    , typename T1, typename T2, typename T3, typename T4, typename T5
+    >
+typename arity_tag<5>::type
+arity_helper(type_wrapper< F< T1,T2,T3,T4,T5 > >, arity_tag<5>);
+
+template<
+      template<
+          typename P1, typename P2, typename P3, typename P4
+        , typename P5, typename P6
+        >
+      class F
+    , typename T1, typename T2, typename T3, typename T4, typename T5
+    , typename T6
+    >
+typename arity_tag<6>::type
+arity_helper(type_wrapper< F< T1,T2,T3,T4,T5,T6 > >, arity_tag<6>);
+template< typename F, int N >
+struct template_arity_impl
+{
+    BOOST_STATIC_CONSTANT(int, value =
+          sizeof(::boost::mpl::aux::arity_helper(type_wrapper<F>(), arity_tag<N>())) - 1
+        );
+};
+
+template< typename F >
+struct template_arity
+{
+    BOOST_STATIC_CONSTANT(int, value  = (
+          max_arity< template_arity_impl< F,1 >::value, template_arity_impl< F,2 >::value, template_arity_impl< F,3 >::value, template_arity_impl< F,4 >::value, template_arity_impl< F,5 >::value, template_arity_impl< F,6 >::value >::value
+        ));
+    typedef mpl::int_<value> type;
+};
+
+}}}
diff --git a/third_party/boost/boost/mpl/aux_/preprocessor/def_params_tail.hpp b/third_party/boost/boost/mpl/aux_/preprocessor/def_params_tail.hpp
new file mode 100644
index 0000000..7b0188d
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessor/def_params_tail.hpp
@@ -0,0 +1,105 @@
+
+#ifndef BOOST_MPL_AUX_PREPROCESSOR_DEF_PARAMS_TAIL_HPP_INCLUDED
+#define BOOST_MPL_AUX_PREPROCESSOR_DEF_PARAMS_TAIL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/limits/arity.hpp>
+#include <boost/mpl/aux_/config/dtp.hpp>
+#include <boost/mpl/aux_/config/preprocessor.hpp>
+
+#include <boost/preprocessor/comma_if.hpp>
+#include <boost/preprocessor/logical/and.hpp>
+#include <boost/preprocessor/identity.hpp>
+#include <boost/preprocessor/empty.hpp>
+
+// BOOST_MPL_PP_DEF_PARAMS_TAIL(1,T,value): , T1 = value, .., Tn = value
+// BOOST_MPL_PP_DEF_PARAMS_TAIL(2,T,value): , T2 = value, .., Tn = value
+// BOOST_MPL_PP_DEF_PARAMS_TAIL(n,T,value): <nothing>
+
+#if !defined(BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES)
+
+#   include <boost/mpl/aux_/preprocessor/filter_params.hpp>
+#   include <boost/mpl/aux_/preprocessor/sub.hpp>
+
+#   define BOOST_MPL_PP_DEF_PARAMS_TAIL_IMPL(i, param, value_func) \
+    BOOST_MPL_PP_DEF_PARAMS_TAIL_DELAY_1( \
+          i \
+        , BOOST_MPL_PP_SUB(BOOST_MPL_LIMIT_METAFUNCTION_ARITY,i) \
+        , param \
+        , value_func \
+        ) \
+    /**/
+
+#   define BOOST_MPL_PP_DEF_PARAMS_TAIL_DELAY_1(i, n, param, value_func) \
+    BOOST_MPL_PP_DEF_PARAMS_TAIL_DELAY_2(i,n,param,value_func) \
+    /**/
+
+#   define BOOST_MPL_PP_DEF_PARAMS_TAIL_DELAY_2(i, n, param, value_func) \
+    BOOST_PP_COMMA_IF(BOOST_PP_AND(i,n)) \
+    BOOST_MPL_PP_DEF_PARAMS_TAIL_##i(n,param,value_func) \
+    /**/
+
+#   define BOOST_MPL_PP_DEF_PARAMS_TAIL_0(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##1 v(),p##2 v(),p##3 v(),p##4 v(),p##5 v(),p##6 v(),p##7 v(),p##8 v(),p##9 v())
+#   define BOOST_MPL_PP_DEF_PARAMS_TAIL_1(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##2 v(),p##3 v(),p##4 v(),p##5 v(),p##6 v(),p##7 v(),p##8 v(),p##9 v(),p1)
+#   define BOOST_MPL_PP_DEF_PARAMS_TAIL_2(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##3 v(),p##4 v(),p##5 v(),p##6 v(),p##7 v(),p##8 v(),p##9 v(),p1,p2)
+#   define BOOST_MPL_PP_DEF_PARAMS_TAIL_3(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##4 v(),p##5 v(),p##6 v(),p##7 v(),p##8 v(),p##9 v(),p1,p2,p3)
+#   define BOOST_MPL_PP_DEF_PARAMS_TAIL_4(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##5 v(),p##6 v(),p##7 v(),p##8 v(),p##9 v(),p1,p2,p3,p4)
+#   define BOOST_MPL_PP_DEF_PARAMS_TAIL_5(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##6 v(),p##7 v(),p##8 v(),p##9 v(),p1,p2,p3,p4,p5)
+#   define BOOST_MPL_PP_DEF_PARAMS_TAIL_6(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##7 v(),p##8 v(),p##9 v(),p1,p2,p3,p4,p5,p6)
+#   define BOOST_MPL_PP_DEF_PARAMS_TAIL_7(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##8 v(),p##9 v(),p1,p2,p3,p4,p5,p6,p7)
+#   define BOOST_MPL_PP_DEF_PARAMS_TAIL_8(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p##9 v(),p1,p2,p3,p4,p5,p6,p7,p8)
+#   define BOOST_MPL_PP_DEF_PARAMS_TAIL_9(i,p,v) BOOST_MPL_PP_FILTER_PARAMS_##i(p1,p2,p3,p4,p5,p6,p7,p8,p9)
+
+#else
+
+#   include <boost/preprocessor/arithmetic/add.hpp>
+#   include <boost/preprocessor/arithmetic/sub.hpp>
+#   include <boost/preprocessor/inc.hpp>
+#   include <boost/preprocessor/tuple/elem.hpp>
+#   include <boost/preprocessor/repeat.hpp>
+#   include <boost/preprocessor/cat.hpp>
+
+#   define BOOST_MPL_PP_AUX_TAIL_PARAM_FUNC(unused, i, op) \
+    , BOOST_PP_CAT( \
+          BOOST_PP_TUPLE_ELEM(3, 1, op) \
+        , BOOST_PP_ADD_D(1, i, BOOST_PP_INC(BOOST_PP_TUPLE_ELEM(3, 0, op))) \
+        ) BOOST_PP_TUPLE_ELEM(3, 2, op)() \
+    /**/
+
+#   define BOOST_MPL_PP_DEF_PARAMS_TAIL_IMPL(i, param, value_func) \
+    BOOST_PP_REPEAT( \
+          BOOST_PP_SUB_D(1, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, i) \
+        , BOOST_MPL_PP_AUX_TAIL_PARAM_FUNC \
+        , (i, param, value_func) \
+        ) \
+    /**/
+
+
+#endif // BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES
+
+#define BOOST_MPL_PP_DEF_PARAMS_TAIL(i, param, value) \
+    BOOST_MPL_PP_DEF_PARAMS_TAIL_IMPL(i, param, BOOST_PP_IDENTITY(=value)) \
+    /**/
+
+#if !defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES)
+#   define BOOST_MPL_PP_NESTED_DEF_PARAMS_TAIL(i, param, value) \
+    BOOST_MPL_PP_DEF_PARAMS_TAIL_IMPL(i, param, BOOST_PP_IDENTITY(=value)) \
+    /**/
+#else
+#   define BOOST_MPL_PP_NESTED_DEF_PARAMS_TAIL(i, param, value) \
+    BOOST_MPL_PP_DEF_PARAMS_TAIL_IMPL(i, param, BOOST_PP_EMPTY) \
+    /**/
+#endif
+
+#endif // BOOST_MPL_AUX_PREPROCESSOR_DEF_PARAMS_TAIL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/preprocessor/default_params.hpp b/third_party/boost/boost/mpl/aux_/preprocessor/default_params.hpp
new file mode 100644
index 0000000..834d357
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessor/default_params.hpp
@@ -0,0 +1,67 @@
+
+#ifndef BOOST_MPL_AUX_PREPROCESSOR_DEFAULT_PARAMS_HPP_INCLUDED
+#define BOOST_MPL_AUX_PREPROCESSOR_DEFAULT_PARAMS_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/preprocessor.hpp>
+
+// BOOST_MPL_PP_DEFAULT_PARAMS(0,T,int): <nothing>
+// BOOST_MPL_PP_DEFAULT_PARAMS(1,T,int): T1 = int
+// BOOST_MPL_PP_DEFAULT_PARAMS(2,T,int): T1 = int, T2 = int
+// BOOST_MPL_PP_DEFAULT_PARAMS(n,T,int): T1 = int, T2 = int, .., Tn = int
+
+#if !defined(BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES)
+
+#   include <boost/preprocessor/cat.hpp>
+
+#   define BOOST_MPL_PP_DEFAULT_PARAMS(n,p,v) \
+    BOOST_PP_CAT(BOOST_MPL_PP_DEFAULT_PARAMS_,n)(p,v) \
+    /**/
+
+#   define BOOST_MPL_PP_DEFAULT_PARAMS_0(p,v)
+#   define BOOST_MPL_PP_DEFAULT_PARAMS_1(p,v) p##1=v
+#   define BOOST_MPL_PP_DEFAULT_PARAMS_2(p,v) p##1=v,p##2=v
+#   define BOOST_MPL_PP_DEFAULT_PARAMS_3(p,v) p##1=v,p##2=v,p##3=v
+#   define BOOST_MPL_PP_DEFAULT_PARAMS_4(p,v) p##1=v,p##2=v,p##3=v,p##4=v
+#   define BOOST_MPL_PP_DEFAULT_PARAMS_5(p,v) p##1=v,p##2=v,p##3=v,p##4=v,p##5=v
+#   define BOOST_MPL_PP_DEFAULT_PARAMS_6(p,v) p##1=v,p##2=v,p##3=v,p##4=v,p##5=v,p##6=v
+#   define BOOST_MPL_PP_DEFAULT_PARAMS_7(p,v) p##1=v,p##2=v,p##3=v,p##4=v,p##5=v,p##6=v,p##7=v
+#   define BOOST_MPL_PP_DEFAULT_PARAMS_8(p,v) p##1=v,p##2=v,p##3=v,p##4=v,p##5=v,p##6=v,p##7=v,p##8=v
+#   define BOOST_MPL_PP_DEFAULT_PARAMS_9(p,v) p##1=v,p##2=v,p##3=v,p##4=v,p##5=v,p##6=v,p##7=v,p##8=v,p##9=v
+
+#else
+
+#   include <boost/preprocessor/tuple/elem.hpp>
+#   include <boost/preprocessor/comma_if.hpp>
+#   include <boost/preprocessor/repeat.hpp>
+#   include <boost/preprocessor/inc.hpp>
+#   include <boost/preprocessor/cat.hpp>
+
+#   define BOOST_MPL_PP_AUX_DEFAULT_PARAM_FUNC(unused, i, pv) \
+    BOOST_PP_COMMA_IF(i) \
+    BOOST_PP_CAT( BOOST_PP_TUPLE_ELEM(2,0,pv), BOOST_PP_INC(i) ) \
+        = BOOST_PP_TUPLE_ELEM(2,1,pv) \
+    /**/
+
+#   define BOOST_MPL_PP_DEFAULT_PARAMS(n, param, value) \
+    BOOST_PP_REPEAT( \
+          n \
+        , BOOST_MPL_PP_AUX_DEFAULT_PARAM_FUNC \
+        , (param,value) \
+        ) \
+    /**/
+
+#endif
+
+#endif // BOOST_MPL_AUX_PREPROCESSOR_DEFAULT_PARAMS_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/preprocessor/enum.hpp b/third_party/boost/boost/mpl/aux_/preprocessor/enum.hpp
new file mode 100644
index 0000000..b44f6e8
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessor/enum.hpp
@@ -0,0 +1,62 @@
+
+#ifndef BOOST_MPL_AUX_PREPROCESSOR_ENUM_HPP_INCLUDED
+#define BOOST_MPL_AUX_PREPROCESSOR_ENUM_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/preprocessor.hpp>
+
+// BOOST_MPL_PP_ENUM(0,int): <nothing>
+// BOOST_MPL_PP_ENUM(1,int): int
+// BOOST_MPL_PP_ENUM(2,int): int, int
+// BOOST_MPL_PP_ENUM(n,int): int, int, .., int
+
+#if !defined(BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES)
+
+#   include <boost/preprocessor/cat.hpp>
+
+#   define BOOST_MPL_PP_ENUM(n, param) \
+    BOOST_PP_CAT(BOOST_MPL_PP_ENUM_,n)(param) \
+    /**/
+
+#   define BOOST_MPL_PP_ENUM_0(p)
+#   define BOOST_MPL_PP_ENUM_1(p) p
+#   define BOOST_MPL_PP_ENUM_2(p) p,p
+#   define BOOST_MPL_PP_ENUM_3(p) p,p,p
+#   define BOOST_MPL_PP_ENUM_4(p) p,p,p,p
+#   define BOOST_MPL_PP_ENUM_5(p) p,p,p,p,p
+#   define BOOST_MPL_PP_ENUM_6(p) p,p,p,p,p,p
+#   define BOOST_MPL_PP_ENUM_7(p) p,p,p,p,p,p,p
+#   define BOOST_MPL_PP_ENUM_8(p) p,p,p,p,p,p,p,p
+#   define BOOST_MPL_PP_ENUM_9(p) p,p,p,p,p,p,p,p,p
+
+#else
+
+#   include <boost/preprocessor/comma_if.hpp>
+#   include <boost/preprocessor/repeat.hpp>
+
+#   define BOOST_MPL_PP_AUX_ENUM_FUNC(unused, i, param) \
+    BOOST_PP_COMMA_IF(i) param \
+    /**/
+
+#   define BOOST_MPL_PP_ENUM(n, param) \
+    BOOST_PP_REPEAT( \
+          n \
+        , BOOST_MPL_PP_AUX_ENUM_FUNC \
+        , param \
+        ) \
+    /**/
+
+#endif
+
+#endif // BOOST_MPL_AUX_PREPROCESSOR_ENUM_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/preprocessor/params.hpp b/third_party/boost/boost/mpl/aux_/preprocessor/params.hpp
new file mode 100644
index 0000000..2a5e2fe
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/preprocessor/params.hpp
@@ -0,0 +1,65 @@
+
+#ifndef BOOST_MPL_AUX_PREPROCESSOR_PARAMS_HPP_INCLUDED
+#define BOOST_MPL_AUX_PREPROCESSOR_PARAMS_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/preprocessor.hpp>
+
+// BOOST_MPL_PP_PARAMS(0,T): <nothing>
+// BOOST_MPL_PP_PARAMS(1,T): T1
+// BOOST_MPL_PP_PARAMS(2,T): T1, T2
+// BOOST_MPL_PP_PARAMS(n,T): T1, T2, .., Tn
+
+#if !defined(BOOST_MPL_CFG_NO_OWN_PP_PRIMITIVES)
+
+#   include <boost/preprocessor/cat.hpp>
+
+#   define BOOST_MPL_PP_PARAMS(n,p) \
+    BOOST_PP_CAT(BOOST_MPL_PP_PARAMS_,n)(p) \
+    /**/
+
+#   define BOOST_MPL_PP_PARAMS_0(p)
+#   define BOOST_MPL_PP_PARAMS_1(p) p##1
+#   define BOOST_MPL_PP_PARAMS_2(p) p##1,p##2
+#   define BOOST_MPL_PP_PARAMS_3(p) p##1,p##2,p##3
+#   define BOOST_MPL_PP_PARAMS_4(p) p##1,p##2,p##3,p##4
+#   define BOOST_MPL_PP_PARAMS_5(p) p##1,p##2,p##3,p##4,p##5
+#   define BOOST_MPL_PP_PARAMS_6(p) p##1,p##2,p##3,p##4,p##5,p##6
+#   define BOOST_MPL_PP_PARAMS_7(p) p##1,p##2,p##3,p##4,p##5,p##6,p##7
+#   define BOOST_MPL_PP_PARAMS_8(p) p##1,p##2,p##3,p##4,p##5,p##6,p##7,p##8
+#   define BOOST_MPL_PP_PARAMS_9(p) p##1,p##2,p##3,p##4,p##5,p##6,p##7,p##8,p##9
+
+#else
+
+#   include <boost/preprocessor/comma_if.hpp>
+#   include <boost/preprocessor/repeat.hpp>
+#   include <boost/preprocessor/inc.hpp>
+#   include <boost/preprocessor/cat.hpp>
+
+#   define BOOST_MPL_PP_AUX_PARAM_FUNC(unused, i, param) \
+    BOOST_PP_COMMA_IF(i) \
+    BOOST_PP_CAT(param, BOOST_PP_INC(i)) \
+    /**/
+
+#   define BOOST_MPL_PP_PARAMS(n, param) \
+    BOOST_PP_REPEAT( \
+          n \
+        , BOOST_MPL_PP_AUX_PARAM_FUNC \
+        , param \
+        ) \
+    /**/
+
+#endif
+
+#endif // BOOST_MPL_AUX_PREPROCESSOR_PARAMS_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/push_back_impl.hpp b/third_party/boost/boost/mpl/aux_/push_back_impl.hpp
new file mode 100644
index 0000000..cd9f7f2
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/push_back_impl.hpp
@@ -0,0 +1,70 @@
+
+#ifndef BOOST_MPL_AUX_PUSH_BACK_IMPL_HPP_INCLUDED
+#define BOOST_MPL_AUX_PUSH_BACK_IMPL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2008
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/push_back_fwd.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/aux_/has_type.hpp>
+#include <boost/mpl/aux_/traits_lambda_spec.hpp>
+#include <boost/mpl/aux_/config/forwarding.hpp>
+#include <boost/mpl/aux_/config/static_constant.hpp>
+
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace mpl {
+
+struct has_push_back_arg {};
+
+// agurt 05/feb/04: no default implementation; the stub definition is needed
+// to enable the default 'has_push_back' implementation below
+template< typename Tag >
+struct push_back_impl
+{
+    template< typename Sequence, typename T > struct apply
+    {
+        // should be instantiated only in the context of 'has_push_back_impl';
+        // if you've got an assert here, you are requesting a 'push_back'
+        // specialization that doesn't exist.
+        BOOST_MPL_ASSERT_MSG(
+              ( boost::is_same< T, has_push_back_arg >::value )
+            , REQUESTED_PUSH_BACK_SPECIALIZATION_FOR_SEQUENCE_DOES_NOT_EXIST
+            , ( Sequence )
+            );
+    };
+};
+
+template< typename Tag >
+struct has_push_back_impl
+{
+    template< typename Seq > struct apply
+#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING)
+        : aux::has_type< push_back< Seq, has_push_back_arg > >
+    {
+#else
+    {
+        typedef aux::has_type< push_back< Seq, has_push_back_arg > > type;
+        BOOST_STATIC_CONSTANT(bool, value =
+              (aux::has_type< push_back< Seq, has_push_back_arg > >::value)
+            );
+#endif
+    };
+};
+
+BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(2, push_back_impl)
+BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1, has_push_back_impl)
+
+}}
+
+#endif // BOOST_MPL_AUX_PUSH_BACK_IMPL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/push_front_impl.hpp b/third_party/boost/boost/mpl/aux_/push_front_impl.hpp
new file mode 100644
index 0000000..70159a1
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/push_front_impl.hpp
@@ -0,0 +1,71 @@
+
+#ifndef BOOST_MPL_AUX_PUSH_FRONT_IMPL_HPP_INCLUDED
+#define BOOST_MPL_AUX_PUSH_FRONT_IMPL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2008
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/push_front_fwd.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/aux_/has_type.hpp>
+#include <boost/mpl/aux_/traits_lambda_spec.hpp>
+#include <boost/mpl/aux_/config/forwarding.hpp>
+#include <boost/mpl/aux_/config/static_constant.hpp>
+
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace mpl {
+
+struct has_push_front_arg {};
+
+// agurt 05/feb/04: no default implementation; the stub definition is needed
+// to enable the default 'has_push_front' implementation below
+
+template< typename Tag >
+struct push_front_impl
+{
+    template< typename Sequence, typename T > struct apply
+    {
+        // should be instantiated only in the context of 'has_push_front_impl';
+        // if you've got an assert here, you are requesting a 'push_front'
+        // specialization that doesn't exist.
+        BOOST_MPL_ASSERT_MSG(
+              ( boost::is_same< T, has_push_front_arg >::value )
+            , REQUESTED_PUSH_FRONT_SPECIALIZATION_FOR_SEQUENCE_DOES_NOT_EXIST
+            , ( Sequence )
+            );
+    };
+};
+
+template< typename Tag >
+struct has_push_front_impl
+{
+    template< typename Seq > struct apply
+#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING)
+        : aux::has_type< push_front< Seq, has_push_front_arg > >
+    {
+#else
+    {
+        typedef aux::has_type< push_front< Seq, has_push_front_arg > > type;
+        BOOST_STATIC_CONSTANT(bool, value =
+              (aux::has_type< push_front< Seq, has_push_front_arg > >::value)
+            );
+#endif
+    };
+};
+
+BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(2, push_front_impl)
+BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(1, has_push_front_impl)
+
+}}
+
+#endif // BOOST_MPL_AUX_PUSH_FRONT_IMPL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/reverse_fold_impl.hpp b/third_party/boost/boost/mpl/aux_/reverse_fold_impl.hpp
new file mode 100644
index 0000000..26ba383
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/reverse_fold_impl.hpp
@@ -0,0 +1,44 @@
+
+#ifndef BOOST_MPL_AUX_REVERSE_FOLD_IMPL_HPP_INCLUDED
+#define BOOST_MPL_AUX_REVERSE_FOLD_IMPL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/next_prior.hpp>
+#   include <boost/mpl/deref.hpp>
+#   include <boost/mpl/apply.hpp>
+#   include <boost/mpl/aux_/config/ctps.hpp>
+#   if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
+    || defined(BOOST_MPL_CFG_NO_NONTYPE_TEMPLATE_PARTIAL_SPEC)
+#       include <boost/mpl/if.hpp>
+#       include <boost/type_traits/is_same.hpp>
+#   endif
+#endif
+
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER reverse_fold_impl.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   define AUX778076_FOLD_IMPL_OP(iter) typename deref<iter>::type
+#   define AUX778076_FOLD_IMPL_NAME_PREFIX reverse_fold
+#   include <boost/mpl/aux_/reverse_fold_impl_body.hpp>
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_AUX_REVERSE_FOLD_IMPL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/static_cast.hpp b/third_party/boost/boost/mpl/aux_/static_cast.hpp
new file mode 100644
index 0000000..d4dad17
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/static_cast.hpp
@@ -0,0 +1,27 @@
+
+#ifndef BOOST_MPL_AUX_STATIC_CAST_HPP_INCLUDED
+#define BOOST_MPL_AUX_STATIC_CAST_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x561)) \
+ || BOOST_WORKAROUND(__GNUC__, < 3) \
+ || BOOST_WORKAROUND(__MWERKS__, <= 0x3001)
+#   define BOOST_MPL_AUX_STATIC_CAST(T, expr) (T)(expr)
+#else
+#   define BOOST_MPL_AUX_STATIC_CAST(T, expr) static_cast<T>(expr)
+#endif
+
+#endif // BOOST_MPL_AUX_STATIC_CAST_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/template_arity.hpp b/third_party/boost/boost/mpl/aux_/template_arity.hpp
new file mode 100644
index 0000000..0edfba4
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/template_arity.hpp
@@ -0,0 +1,189 @@
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+///// header body
+
+#ifndef BOOST_MPL_AUX_TEMPLATE_ARITY_HPP_INCLUDED
+#define BOOST_MPL_AUX_TEMPLATE_ARITY_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/ttp.hpp>
+#include <boost/mpl/aux_/config/lambda.hpp>
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/aux_/template_arity_fwd.hpp>
+#   include <boost/mpl/int.hpp>
+#   if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT)
+#   if defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING)
+#       include <boost/mpl/aux_/type_wrapper.hpp>
+#   endif
+#   else
+#       include <boost/mpl/aux_/has_rebind.hpp>
+#   endif
+#endif
+
+#include <boost/mpl/aux_/config/static_constant.hpp>
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER template_arity.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT)
+#   if defined(BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING)
+
+#   include <boost/mpl/limits/arity.hpp>
+#   include <boost/mpl/aux_/preprocessor/range.hpp>
+#   include <boost/mpl/aux_/preprocessor/repeat.hpp>
+#   include <boost/mpl/aux_/preprocessor/params.hpp>
+#   include <boost/mpl/aux_/nttp_decl.hpp>
+
+#   include <boost/preprocessor/seq/fold_left.hpp>
+#   include <boost/preprocessor/comma_if.hpp>
+#   include <boost/preprocessor/iterate.hpp>
+#   include <boost/preprocessor/inc.hpp>
+#   include <boost/preprocessor/cat.hpp>
+
+#   define AUX778076_ARITY BOOST_PP_INC(BOOST_MPL_LIMIT_METAFUNCTION_ARITY)
+
+namespace boost { namespace mpl { namespace aux {
+
+template< BOOST_MPL_AUX_NTTP_DECL(int, N) > struct arity_tag
+{
+    typedef char (&type)[N + 1];
+};
+
+#   define AUX778076_MAX_ARITY_OP(unused, state, i_) \
+    ( BOOST_PP_CAT(C,i_) > 0 ? BOOST_PP_CAT(C,i_) : state ) \
+/**/
+
+template<
+      BOOST_MPL_PP_PARAMS(AUX778076_ARITY, BOOST_MPL_AUX_NTTP_DECL(int, C))
+    >
+struct max_arity
+{
+    BOOST_STATIC_CONSTANT(int, value =
+          BOOST_PP_SEQ_FOLD_LEFT(
+              AUX778076_MAX_ARITY_OP
+            , -1
+            , BOOST_MPL_PP_RANGE(1, AUX778076_ARITY)
+            )
+        );
+};
+
+#   undef AUX778076_MAX_ARITY_OP
+
+arity_tag<0>::type arity_helper(...);
+
+#   define BOOST_PP_ITERATION_LIMITS (1, AUX778076_ARITY)
+#   define BOOST_PP_FILENAME_1 <boost/mpl/aux_/template_arity.hpp>
+#   include BOOST_PP_ITERATE()
+
+template< typename F, BOOST_MPL_AUX_NTTP_DECL(int, N) >
+struct template_arity_impl
+{
+    BOOST_STATIC_CONSTANT(int, value =
+          sizeof(::boost::mpl::aux::arity_helper(type_wrapper<F>(),arity_tag<N>())) - 1
+        );
+};
+
+#   define AUX778076_TEMPLATE_ARITY_IMPL_INVOCATION(unused, i_, F) \
+    BOOST_PP_COMMA_IF(i_) template_arity_impl<F,BOOST_PP_INC(i_)>::value \
+/**/
+
+template< typename F >
+struct template_arity
+{
+    BOOST_STATIC_CONSTANT(int, value = (
+          max_arity< BOOST_MPL_PP_REPEAT(
+              AUX778076_ARITY
+            , AUX778076_TEMPLATE_ARITY_IMPL_INVOCATION
+            , F
+            ) >::value
+        ));
+
+    typedef mpl::int_<value> type;
+};
+
+#   undef AUX778076_TEMPLATE_ARITY_IMPL_INVOCATION
+
+#   undef AUX778076_ARITY
+
+}}}
+
+#   endif // BOOST_MPL_CFG_EXTENDED_TEMPLATE_PARAMETERS_MATCHING
+#   else // BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
+
+#   include <boost/mpl/aux_/config/eti.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+
+template< bool >
+struct template_arity_impl
+{
+    template< typename F > struct result_
+        : mpl::int_<-1>
+    {
+    };
+};
+
+template<>
+struct template_arity_impl<true>
+{
+    template< typename F > struct result_
+        : F::arity
+    {
+    };
+};
+
+template< typename F >
+struct template_arity
+    : template_arity_impl< ::boost::mpl::aux::has_rebind<F>::value >
+        ::template result_<F>
+{
+};
+
+#if defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
+template<>
+struct template_arity<int>
+    : mpl::int_<-1>
+{
+};
+#endif
+
+}}}
+
+#   endif // BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_AUX_TEMPLATE_ARITY_HPP_INCLUDED
+
+///// iteration
+
+#else
+#define i_ BOOST_PP_FRAME_ITERATION(1)
+
+template<
+      template< BOOST_MPL_PP_PARAMS(i_, typename P) > class F
+    , BOOST_MPL_PP_PARAMS(i_, typename T)
+    >
+typename arity_tag<i_>::type
+arity_helper(type_wrapper< F<BOOST_MPL_PP_PARAMS(i_, T)> >, arity_tag<i_>);
+
+#undef i_
+#endif // BOOST_PP_IS_ITERATING
diff --git a/third_party/boost/boost/mpl/aux_/template_arity_fwd.hpp b/third_party/boost/boost/mpl/aux_/template_arity_fwd.hpp
new file mode 100644
index 0000000..0db5808
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/template_arity_fwd.hpp
@@ -0,0 +1,23 @@
+
+#ifndef BOOST_MPL_AUX_TEMPLATE_ARITY_FWD_HPP_INCLUDED
+#define BOOST_MPL_AUX_TEMPLATE_ARITY_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+namespace boost { namespace mpl { namespace aux {
+
+template< typename F > struct template_arity;
+
+}}}
+
+#endif // BOOST_MPL_AUX_TEMPLATE_ARITY_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/traits_lambda_spec.hpp b/third_party/boost/boost/mpl/aux_/traits_lambda_spec.hpp
new file mode 100644
index 0000000..8923c7e
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/traits_lambda_spec.hpp
@@ -0,0 +1,63 @@
+
+#ifndef BOOST_MPL_AUX_TRAITS_LAMBDA_SPEC_HPP_INCLUDED
+#define BOOST_MPL_AUX_TRAITS_LAMBDA_SPEC_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2008
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/sequence_tag_fwd.hpp>
+#include <boost/mpl/void.hpp>
+#include <boost/mpl/aux_/preprocessor/params.hpp>
+#include <boost/mpl/aux_/config/lambda.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT)
+
+#   define BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(i, trait) /**/
+
+#elif !defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
+
+#   define BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(i, trait) \
+template<> struct trait<void_> \
+{ \
+    template< BOOST_MPL_PP_PARAMS(i, typename T) > struct apply \
+    { \
+    }; \
+}; \
+/**/
+
+#else
+
+#   define BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(i, trait) \
+template<> struct trait<void_> \
+{ \
+    template< BOOST_MPL_PP_PARAMS(i, typename T) > struct apply \
+    { \
+    }; \
+}; \
+template<> struct trait<int> \
+{ \
+    template< BOOST_MPL_PP_PARAMS(i, typename T) > struct apply \
+    { \
+        typedef int type; \
+    }; \
+}; \
+/**/
+
+#endif // BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
+
+
+#define BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC(i, trait) \
+    BOOST_MPL_ALGORITM_TRAITS_LAMBDA_SPEC_IMPL(i, trait) \
+    template<> struct trait<non_sequence_tag> {}; \
+/**/
+
+#endif // BOOST_MPL_AUX_TRAITS_LAMBDA_SPEC_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/type_wrapper.hpp b/third_party/boost/boost/mpl/aux_/type_wrapper.hpp
new file mode 100644
index 0000000..6d950c5
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/type_wrapper.hpp
@@ -0,0 +1,47 @@
+
+#ifndef BOOST_MPL_AUX_TYPE_WRAPPER_HPP_INCLUDED
+#define BOOST_MPL_AUX_TYPE_WRAPPER_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+// Copyright Peter Dimov 2000-2003
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/ctps.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+
+template< typename T > struct type_wrapper
+{
+    typedef T type;
+};
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+// agurt 08/may/03: a complicated way to extract the wrapped type; need it
+// mostly for the sake of GCC (3.2.x), which ICEs if you try to extract the
+// nested 'type' from 'type_wrapper<T>' when the latter was the result of a
+// 'typeof' expression
+template< typename T > struct wrapped_type;
+
+template< typename T > struct wrapped_type< type_wrapper<T> >
+{
+    typedef T type;
+};
+#else
+template< typename W > struct wrapped_type
+{
+    typedef typename W::type type;
+};
+#endif
+
+}}}
+
+#endif // BOOST_MPL_AUX_TYPE_WRAPPER_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/value_wknd.hpp b/third_party/boost/boost/mpl/aux_/value_wknd.hpp
new file mode 100644
index 0000000..9e1ad65
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/value_wknd.hpp
@@ -0,0 +1,89 @@
+
+#ifndef BOOST_MPL_AUX_VALUE_WKND_HPP_INCLUDED
+#define BOOST_MPL_AUX_VALUE_WKND_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/static_cast.hpp>
+#include <boost/mpl/aux_/config/integral.hpp>
+#include <boost/mpl/aux_/config/eti.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if defined(BOOST_MPL_CFG_BCC_INTEGRAL_CONSTANTS) \
+    || defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
+
+#   include <boost/mpl/int.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+template< typename C_ > struct value_wknd
+    : C_
+{
+};
+
+#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
+template<> struct value_wknd<int>
+    : int_<1>
+{
+    using int_<1>::value;
+};
+#endif
+}}}
+
+
+#if !defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
+#   define BOOST_MPL_AUX_VALUE_WKND(C) \
+    ::BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::aux::value_wknd< C > \
+/**/
+#    define BOOST_MPL_AUX_MSVC_VALUE_WKND(C) BOOST_MPL_AUX_VALUE_WKND(C)
+#else
+#   define BOOST_MPL_AUX_VALUE_WKND(C) C
+#   define BOOST_MPL_AUX_MSVC_VALUE_WKND(C) \
+    ::boost::mpl::aux::value_wknd< C > \
+/**/
+#endif
+
+#else // BOOST_MPL_CFG_BCC_INTEGRAL_CONSTANTS
+
+#   define BOOST_MPL_AUX_VALUE_WKND(C) C
+#   define BOOST_MPL_AUX_MSVC_VALUE_WKND(C) C
+
+#endif
+
+#if BOOST_WORKAROUND(__EDG_VERSION__, <= 238)
+#   define BOOST_MPL_AUX_NESTED_VALUE_WKND(T, C) \
+    BOOST_MPL_AUX_STATIC_CAST(T, C::value) \
+/**/
+#else
+#   define BOOST_MPL_AUX_NESTED_VALUE_WKND(T, C) \
+    BOOST_MPL_AUX_VALUE_WKND(C)::value \
+/**/
+#endif
+
+
+namespace boost { namespace mpl { namespace aux {
+
+template< typename T > struct value_type_wknd
+{
+    typedef typename T::value_type type;
+};
+
+#if defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
+template<> struct value_type_wknd<int>
+{
+    typedef int type;
+};
+#endif
+
+}}}
+
+#endif // BOOST_MPL_AUX_VALUE_WKND_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/aux_/yes_no.hpp b/third_party/boost/boost/mpl/aux_/yes_no.hpp
new file mode 100644
index 0000000..e1b65ed
--- /dev/null
+++ b/third_party/boost/boost/mpl/aux_/yes_no.hpp
@@ -0,0 +1,58 @@
+
+#ifndef BOOST_MPL_AUX_YES_NO_HPP_INCLUDED
+#define BOOST_MPL_AUX_YES_NO_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/nttp_decl.hpp>
+#include <boost/mpl/aux_/config/arrays.hpp>
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+
+namespace boost { namespace mpl { namespace aux {
+
+typedef char (&no_tag)[1];
+typedef char (&yes_tag)[2];
+
+template< bool C_ > struct yes_no_tag
+{
+    typedef no_tag type;
+};
+
+template<> struct yes_no_tag<true>
+{
+    typedef yes_tag type;
+};
+
+
+template< BOOST_MPL_AUX_NTTP_DECL(long, n) > struct weighted_tag
+{
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+    typedef char (&type)[n];
+#else
+    char buf[n];
+    typedef weighted_tag type;
+#endif
+};
+
+#if defined(BOOST_MPL_CFG_NO_DEPENDENT_ARRAY_TYPES)
+template<> struct weighted_tag<0>
+{
+    typedef char (&type)[1];
+};
+#endif
+
+}}}
+
+#endif // BOOST_MPL_AUX_YES_NO_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/back_inserter.hpp b/third_party/boost/boost/mpl/back_inserter.hpp
new file mode 100644
index 0000000..b23b950
--- /dev/null
+++ b/third_party/boost/boost/mpl/back_inserter.hpp
@@ -0,0 +1,34 @@
+
+#ifndef BOOST_MPL_BACK_INSERTER_HPP_INCLUDED
+#define BOOST_MPL_BACK_INSERTER_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2003-2004
+// Copyright David Abrahams 2003-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/push_back.hpp>
+#include <boost/mpl/inserter.hpp>
+
+namespace boost {
+namespace mpl {
+
+template<
+      typename Sequence
+    >
+struct back_inserter
+    : inserter< Sequence,push_back<> >
+{
+};
+
+}}
+
+#endif // BOOST_MPL_BACK_INSERTER_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/begin_end.hpp b/third_party/boost/boost/mpl/begin_end.hpp
new file mode 100644
index 0000000..fe37ef1
--- /dev/null
+++ b/third_party/boost/boost/mpl/begin_end.hpp
@@ -0,0 +1,57 @@
+
+#ifndef BOOST_MPL_BEGIN_END_HPP_INCLUDED
+#define BOOST_MPL_BEGIN_END_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/begin_end_fwd.hpp>
+#include <boost/mpl/aux_/begin_end_impl.hpp>
+#include <boost/mpl/sequence_tag.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost { namespace mpl {
+
+// agurt, 13/sep/02: switched from inheritance to typedef; MSVC is more
+// happy this way (less ETI-related errors), and it doesn't affect
+// anything else
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    >
+struct begin
+{
+    typedef typename sequence_tag<Sequence>::type tag_;
+    typedef typename begin_impl< tag_ >
+        ::template apply< Sequence >::type type;
+
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,begin,(Sequence))
+};
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    >
+struct end
+{
+    typedef typename sequence_tag<Sequence>::type tag_;
+    typedef typename end_impl< tag_ >
+        ::template apply< Sequence >::type type;
+
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,end,(Sequence))
+};
+
+BOOST_MPL_AUX_NA_SPEC(1, begin)
+BOOST_MPL_AUX_NA_SPEC(1, end)
+
+}}
+
+#endif // BOOST_MPL_BEGIN_END_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/begin_end_fwd.hpp b/third_party/boost/boost/mpl/begin_end_fwd.hpp
new file mode 100644
index 0000000..4c16cc2
--- /dev/null
+++ b/third_party/boost/boost/mpl/begin_end_fwd.hpp
@@ -0,0 +1,27 @@
+
+#ifndef BOOST_MPL_BEGIN_END_FWD_HPP_INCLUDED
+#define BOOST_MPL_BEGIN_END_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+namespace boost { namespace mpl {
+
+template< typename Tag > struct begin_impl;
+template< typename Tag > struct end_impl;
+
+template< typename Sequence > struct begin;
+template< typename Sequence > struct end;
+
+}}
+
+#endif // BOOST_MPL_BEGIN_END_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/bind.hpp b/third_party/boost/boost/mpl/bind.hpp
new file mode 100644
index 0000000..5f73601
--- /dev/null
+++ b/third_party/boost/boost/mpl/bind.hpp
@@ -0,0 +1,551 @@
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+///// header body
+
+#ifndef BOOST_MPL_BIND_HPP_INCLUDED
+#define BOOST_MPL_BIND_HPP_INCLUDED
+
+// Copyright Peter Dimov 2001
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/bind_fwd.hpp>
+#   include <boost/mpl/placeholders.hpp>
+#   include <boost/mpl/next.hpp>
+#   include <boost/mpl/protect.hpp>
+#   include <boost/mpl/apply_wrap.hpp>
+#   include <boost/mpl/limits/arity.hpp>
+#   include <boost/mpl/aux_/na.hpp>
+#   include <boost/mpl/aux_/arity_spec.hpp>
+#   include <boost/mpl/aux_/type_wrapper.hpp>
+#   include <boost/mpl/aux_/yes_no.hpp>
+#   if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+#       include <boost/type_traits/is_reference.hpp>
+#   endif
+#endif
+
+#include <boost/mpl/aux_/config/bind.hpp>
+#include <boost/mpl/aux_/config/static_constant.hpp>
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   if defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT)
+#       define BOOST_MPL_PREPROCESSED_HEADER basic_bind.hpp
+#   else
+#       define BOOST_MPL_PREPROCESSED_HEADER bind.hpp
+#   endif
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   include <boost/mpl/aux_/preprocessor/params.hpp>
+#   include <boost/mpl/aux_/preprocessor/default_params.hpp>
+#   include <boost/mpl/aux_/preprocessor/def_params_tail.hpp>
+#   include <boost/mpl/aux_/preprocessor/partial_spec_params.hpp>
+#   include <boost/mpl/aux_/preprocessor/ext_params.hpp>
+#   include <boost/mpl/aux_/preprocessor/repeat.hpp>
+#   include <boost/mpl/aux_/preprocessor/enum.hpp>
+#   include <boost/mpl/aux_/preprocessor/add.hpp>
+#   include <boost/mpl/aux_/config/dmc_ambiguous_ctps.hpp>
+#   include <boost/mpl/aux_/config/ctps.hpp>
+#   include <boost/mpl/aux_/config/ttp.hpp>
+#   include <boost/mpl/aux_/config/dtp.hpp>
+#   include <boost/mpl/aux_/nttp_decl.hpp>
+
+#   include <boost/preprocessor/iterate.hpp>
+#   include <boost/preprocessor/comma_if.hpp>
+#   include <boost/preprocessor/cat.hpp>
+#   include <boost/preprocessor/inc.hpp>
+
+namespace boost { namespace mpl {
+
+// local macros, #undef-ined at the end of the header
+#   define AUX778076_APPLY \
+    BOOST_PP_CAT(apply_wrap,BOOST_MPL_LIMIT_METAFUNCTION_ARITY) \
+    /**/
+
+#   if defined(BOOST_MPL_CFG_DMC_AMBIGUOUS_CTPS)
+#       define AUX778076_DMC_PARAM() , int dummy_
+#   else
+#       define AUX778076_DMC_PARAM()
+#   endif
+
+#   define AUX778076_BIND_PARAMS(param) \
+    BOOST_MPL_PP_PARAMS( \
+          BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
+        , param \
+        ) \
+    /**/
+
+#   define AUX778076_BIND_DEFAULT_PARAMS(param, value) \
+    BOOST_MPL_PP_DEFAULT_PARAMS( \
+          BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
+        , param \
+        , value \
+        ) \
+    /**/
+
+#   define AUX778076_BIND_N_PARAMS(n, param) \
+    BOOST_PP_COMMA_IF(n) BOOST_MPL_PP_PARAMS(n, param) \
+    /**/
+
+#   define AUX778076_BIND_N_SPEC_PARAMS(n, param, def) \
+    BOOST_PP_COMMA_IF(n) \
+    BOOST_MPL_PP_PARTIAL_SPEC_PARAMS(n, param, def) \
+    /**/
+
+#if !defined(BOOST_MPL_CFG_NO_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES)
+#   define AUX778076_BIND_NESTED_DEFAULT_PARAMS(param, value) \
+    AUX778076_BIND_DEFAULT_PARAMS(param, value) \
+    /**/
+#else
+#   define AUX778076_BIND_NESTED_DEFAULT_PARAMS(param, value) \
+    AUX778076_BIND_PARAMS(param) \
+    /**/
+#endif
+
+namespace aux {
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+template<
+      typename T, AUX778076_BIND_PARAMS(typename U)
+    >
+struct resolve_bind_arg
+{
+    typedef T type;
+};
+
+#   if !defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT)
+
+template<
+      typename T
+    , typename Arg
+    >
+struct replace_unnamed_arg
+{
+    typedef Arg next;
+    typedef T type;
+};
+
+template<
+      typename Arg
+    >
+struct replace_unnamed_arg< arg<-1>,Arg >
+{
+    typedef typename Arg::next next;
+    typedef Arg type;
+};
+
+#   endif // BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT
+
+template<
+      BOOST_MPL_AUX_NTTP_DECL(int, N), AUX778076_BIND_PARAMS(typename U)
+    >
+struct resolve_bind_arg< arg<N>,AUX778076_BIND_PARAMS(U) >
+{
+    typedef typename AUX778076_APPLY<mpl::arg<N>, AUX778076_BIND_PARAMS(U)>::type type;
+};
+
+#if !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE)
+template<
+      typename F, AUX778076_BIND_PARAMS(typename T), AUX778076_BIND_PARAMS(typename U)
+    >
+struct resolve_bind_arg< bind<F,AUX778076_BIND_PARAMS(T)>,AUX778076_BIND_PARAMS(U) >
+{
+    typedef bind<F,AUX778076_BIND_PARAMS(T)> f_;
+    typedef typename AUX778076_APPLY<f_, AUX778076_BIND_PARAMS(U)>::type type;
+};
+#endif
+
+#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+// agurt, 15/jan/02: it's not a intended to be used as a function class, and
+// MSVC6.5 has problems with 'apply' name here (the code compiles, but doesn't
+// work), so I went with the 'result_' here, and in all other similar cases
+template< bool >
+struct resolve_arg_impl
+{
+    template< typename T, AUX778076_BIND_PARAMS(typename U) > struct result_
+    {
+        typedef T type;
+    };
+};
+
+template<>
+struct resolve_arg_impl<true>
+{
+    template< typename T, AUX778076_BIND_PARAMS(typename U) > struct result_
+    {
+        typedef typename AUX778076_APPLY<
+              T
+            , AUX778076_BIND_PARAMS(U)
+            >::type type;
+    };
+};
+
+// for 'resolve_bind_arg'
+template< typename T > struct is_bind_template;
+
+template<
+      typename T, AUX778076_BIND_PARAMS(typename U)
+    >
+struct resolve_bind_arg
+    : resolve_arg_impl< is_bind_template<T>::value >
+            ::template result_< T,AUX778076_BIND_PARAMS(U) >
+{
+};
+
+#   if !defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT)
+
+template< typename T >
+struct replace_unnamed_arg_impl
+{
+    template< typename Arg > struct result_
+    {
+        typedef Arg next;
+        typedef T type;
+    };
+};
+
+template<>
+struct replace_unnamed_arg_impl< arg<-1> >
+{
+    template< typename Arg > struct result_
+    {
+        typedef typename next<Arg>::type next;
+        typedef Arg type;
+    };
+};
+
+template< typename T, typename Arg >
+struct replace_unnamed_arg
+    : replace_unnamed_arg_impl<T>::template result_<Arg>
+{
+};
+
+#   endif // BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT
+
+// agurt, 10/mar/02: the forward declaration has to appear before any of
+// 'is_bind_helper' overloads, otherwise MSVC6.5 issues an ICE on it
+template< BOOST_MPL_AUX_NTTP_DECL(int, arity_) > struct bind_chooser;
+
+aux::no_tag is_bind_helper(...);
+template< typename T > aux::no_tag is_bind_helper(protect<T>*);
+
+// overload for "main" form
+// agurt, 15/mar/02: MSVC 6.5 fails to properly resolve the overload
+// in case if we use 'aux::type_wrapper< bind<...> >' here, and all
+// 'bind' instantiations form a complete type anyway
+#if !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE)
+template<
+      typename F, AUX778076_BIND_PARAMS(typename T)
+    >
+aux::yes_tag is_bind_helper(bind<F,AUX778076_BIND_PARAMS(T)>*);
+#endif
+
+template< BOOST_MPL_AUX_NTTP_DECL(int, N) >
+aux::yes_tag is_bind_helper(arg<N>*);
+
+template< bool is_ref_ = true >
+struct is_bind_template_impl
+{
+    template< typename T > struct result_
+    {
+        BOOST_STATIC_CONSTANT(bool, value = false);
+    };
+};
+
+template<>
+struct is_bind_template_impl<false>
+{
+    template< typename T > struct result_
+    {
+        BOOST_STATIC_CONSTANT(bool, value =
+              sizeof(aux::is_bind_helper(static_cast<T*>(0)))
+                == sizeof(aux::yes_tag)
+            );
+    };
+};
+
+template< typename T > struct is_bind_template
+    : is_bind_template_impl< ::boost::detail::is_reference_impl<T>::value >
+        ::template result_<T>
+{
+};
+
+#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+} // namespace aux
+
+
+#define BOOST_PP_ITERATION_PARAMS_1 \
+    (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, <boost/mpl/bind.hpp>))
+#include BOOST_PP_ITERATE()
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
+    && !defined(BOOST_MPL_CFG_NO_TEMPLATE_TEMPLATE_PARAMETERS)
+/// if_/eval_if specializations
+#   define AUX778076_SPEC_NAME if_
+#   define BOOST_PP_ITERATION_PARAMS_1 (3,(3, 3, <boost/mpl/bind.hpp>))
+#   include BOOST_PP_ITERATE()
+
+#if !defined(BOOST_MPL_CFG_DMC_AMBIGUOUS_CTPS)
+#   define AUX778076_SPEC_NAME eval_if
+#   define BOOST_PP_ITERATION_PARAMS_1 (3,(3, 3, <boost/mpl/bind.hpp>))
+#   include BOOST_PP_ITERATE()
+#endif
+#endif
+
+// real C++ version is already taken care of
+#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
+    && !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE)
+
+namespace aux {
+// apply_count_args
+#define AUX778076_COUNT_ARGS_PREFIX bind
+#define AUX778076_COUNT_ARGS_DEFAULT na
+#define AUX778076_COUNT_ARGS_ARITY BOOST_MPL_LIMIT_METAFUNCTION_ARITY
+#include <boost/mpl/aux_/count_args.hpp>
+}
+
+// bind
+template<
+      typename F, AUX778076_BIND_PARAMS(typename T) AUX778076_DMC_PARAM()
+    >
+struct bind
+    : aux::bind_chooser<
+          aux::bind_count_args<AUX778076_BIND_PARAMS(T)>::value
+        >::template result_< F,AUX778076_BIND_PARAMS(T) >::type
+{
+};
+
+BOOST_MPL_AUX_ARITY_SPEC(
+      BOOST_PP_INC(BOOST_MPL_LIMIT_METAFUNCTION_ARITY)
+    , bind
+    )
+
+BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(
+      BOOST_PP_INC(BOOST_MPL_LIMIT_METAFUNCTION_ARITY)
+    , bind
+    )
+
+
+#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+#   undef AUX778076_BIND_NESTED_DEFAULT_PARAMS
+#   undef AUX778076_BIND_N_SPEC_PARAMS
+#   undef AUX778076_BIND_N_PARAMS
+#   undef AUX778076_BIND_DEFAULT_PARAMS
+#   undef AUX778076_BIND_PARAMS
+#   undef AUX778076_DMC_PARAM
+#   undef AUX778076_APPLY
+
+}}
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_BIND_HPP_INCLUDED
+
+///// iteration, depth == 1
+
+// For gcc 4.4 compatability, we must include the
+// BOOST_PP_ITERATION_DEPTH test inside an #else clause.
+#else // BOOST_PP_IS_ITERATING
+#if BOOST_PP_ITERATION_DEPTH() == 1
+
+#   define i_ BOOST_PP_FRAME_ITERATION(1)
+
+#if defined(AUX778076_SPEC_NAME)
+
+// lazy metafunction specialization
+template< template< BOOST_MPL_PP_PARAMS(i_, typename T) > class F, typename Tag >
+struct BOOST_PP_CAT(quote,i_);
+
+template< BOOST_MPL_PP_PARAMS(i_, typename T) > struct AUX778076_SPEC_NAME;
+
+template<
+      typename Tag AUX778076_BIND_N_PARAMS(i_, typename T)
+    >
+struct BOOST_PP_CAT(bind,i_)<
+      BOOST_PP_CAT(quote,i_)<AUX778076_SPEC_NAME,Tag>
+    AUX778076_BIND_N_PARAMS(i_,T)
+    >
+{
+    template<
+          AUX778076_BIND_NESTED_DEFAULT_PARAMS(typename U, na)
+        >
+    struct apply
+    {
+     private:
+        typedef mpl::arg<1> n1;
+#       define BOOST_PP_ITERATION_PARAMS_2 (3,(1, i_, <boost/mpl/bind.hpp>))
+#       include BOOST_PP_ITERATE()
+
+        typedef typename AUX778076_SPEC_NAME<
+              typename t1::type
+            , BOOST_MPL_PP_EXT_PARAMS(2, BOOST_PP_INC(i_), t)
+            >::type f_;
+
+     public:
+        typedef typename f_::type type;
+    };
+};
+
+#undef AUX778076_SPEC_NAME
+
+#else // AUX778076_SPEC_NAME
+
+template<
+      typename F AUX778076_BIND_N_PARAMS(i_, typename T) AUX778076_DMC_PARAM()
+    >
+struct BOOST_PP_CAT(bind,i_)
+{
+    template<
+          AUX778076_BIND_NESTED_DEFAULT_PARAMS(typename U, na)
+        >
+    struct apply
+    {
+     private:
+#   if !defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT)
+
+        typedef aux::replace_unnamed_arg< F,mpl::arg<1> > r0;
+        typedef typename r0::type a0;
+        typedef typename r0::next n1;
+        typedef typename aux::resolve_bind_arg<a0,AUX778076_BIND_PARAMS(U)>::type f_;
+        ///
+#   else
+        typedef typename aux::resolve_bind_arg<F,AUX778076_BIND_PARAMS(U)>::type f_;
+
+#   endif // BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT
+
+#   if i_ > 0
+#       define BOOST_PP_ITERATION_PARAMS_2 (3,(1, i_, <boost/mpl/bind.hpp>))
+#       include BOOST_PP_ITERATE()
+#   endif
+
+     public:
+
+#   define AUX778076_ARG(unused, i_, t) \
+    BOOST_PP_COMMA_IF(i_) \
+    typename BOOST_PP_CAT(t,BOOST_PP_INC(i_))::type \
+/**/
+
+        typedef typename BOOST_PP_CAT(apply_wrap,i_)<
+              f_
+            BOOST_PP_COMMA_IF(i_) BOOST_MPL_PP_REPEAT(i_, AUX778076_ARG, t)
+            >::type type;
+
+#   undef AUX778076_ARG
+    };
+};
+
+namespace aux {
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+template<
+      typename F AUX778076_BIND_N_PARAMS(i_, typename T), AUX778076_BIND_PARAMS(typename U)
+    >
+struct resolve_bind_arg<
+      BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_,T)>,AUX778076_BIND_PARAMS(U)
+    >
+{
+    typedef BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_,T)> f_;
+    typedef typename AUX778076_APPLY<f_, AUX778076_BIND_PARAMS(U)>::type type;
+};
+
+#else
+
+template<
+      typename F AUX778076_BIND_N_PARAMS(i_, typename T)
+    >
+aux::yes_tag
+is_bind_helper(BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_,T)>*);
+
+#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+} // namespace aux
+
+BOOST_MPL_AUX_ARITY_SPEC(BOOST_PP_INC(i_), BOOST_PP_CAT(bind,i_))
+BOOST_MPL_AUX_TEMPLATE_ARITY_SPEC(BOOST_PP_INC(i_), BOOST_PP_CAT(bind,i_))
+
+#   if !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE)
+#   if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+#if i_ == BOOST_MPL_LIMIT_METAFUNCTION_ARITY
+/// primary template (not a specialization!)
+template<
+      typename F AUX778076_BIND_N_PARAMS(i_, typename T) AUX778076_DMC_PARAM()
+    >
+struct bind
+    : BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_,T) >
+{
+};
+#else
+template<
+      typename F AUX778076_BIND_N_PARAMS(i_, typename T) AUX778076_DMC_PARAM()
+    >
+struct bind< F AUX778076_BIND_N_SPEC_PARAMS(i_, T, na) >
+    : BOOST_PP_CAT(bind,i_)<F AUX778076_BIND_N_PARAMS(i_,T) >
+{
+};
+#endif
+
+#   else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+namespace aux {
+
+template<>
+struct bind_chooser<i_>
+{
+    template<
+          typename F, AUX778076_BIND_PARAMS(typename T)
+        >
+    struct result_
+    {
+        typedef BOOST_PP_CAT(bind,i_)< F AUX778076_BIND_N_PARAMS(i_,T) > type;
+    };
+};
+
+} // namespace aux
+
+#   endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+#   endif // BOOST_MPL_CFG_NO_BIND_TEMPLATE
+
+#endif // AUX778076_SPEC_NAME
+
+#   undef i_
+
+///// iteration, depth == 2
+
+#elif BOOST_PP_ITERATION_DEPTH() == 2
+
+#   define j_ BOOST_PP_FRAME_ITERATION(2)
+#   if !defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT)
+
+        typedef aux::replace_unnamed_arg< BOOST_PP_CAT(T,j_),BOOST_PP_CAT(n,j_) > BOOST_PP_CAT(r,j_);
+        typedef typename BOOST_PP_CAT(r,j_)::type BOOST_PP_CAT(a,j_);
+        typedef typename BOOST_PP_CAT(r,j_)::next BOOST_PP_CAT(n,BOOST_PP_INC(j_));
+        typedef aux::resolve_bind_arg<BOOST_PP_CAT(a,j_), AUX778076_BIND_PARAMS(U)> BOOST_PP_CAT(t,j_);
+        ///
+#   else
+        typedef aux::resolve_bind_arg< BOOST_PP_CAT(T,j_),AUX778076_BIND_PARAMS(U)> BOOST_PP_CAT(t,j_);
+
+#   endif
+#   undef j_
+
+#endif // BOOST_PP_ITERATION_DEPTH()
+#endif // BOOST_PP_IS_ITERATING
diff --git a/third_party/boost/boost/mpl/bind_fwd.hpp b/third_party/boost/boost/mpl/bind_fwd.hpp
new file mode 100644
index 0000000..1fa8915
--- /dev/null
+++ b/third_party/boost/boost/mpl/bind_fwd.hpp
@@ -0,0 +1,99 @@
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+///// header body
+
+#ifndef BOOST_MPL_BIND_FWD_HPP_INCLUDED
+#define BOOST_MPL_BIND_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/aux_/na.hpp>
+#endif
+
+#include <boost/mpl/aux_/config/bind.hpp>
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER bind_fwd.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   include <boost/mpl/limits/arity.hpp>
+#   include <boost/mpl/aux_/preprocessor/params.hpp>
+#   include <boost/mpl/aux_/preprocessor/default_params.hpp>
+#   include <boost/mpl/aux_/config/dmc_ambiguous_ctps.hpp>
+
+#   include <boost/preprocessor/comma_if.hpp>
+#   include <boost/preprocessor/iterate.hpp>
+#   include <boost/preprocessor/cat.hpp>
+
+namespace boost { namespace mpl {
+
+// local macros, #undef-ined at the end of the header
+
+#   if defined(BOOST_MPL_CFG_DMC_AMBIGUOUS_CTPS)
+#       define AUX778076_DMC_PARAM() , int dummy_ = 0
+#   else
+#       define AUX778076_DMC_PARAM()
+#   endif
+
+#   define AUX778076_BIND_DEFAULT_PARAMS(param, value) \
+    BOOST_MPL_PP_DEFAULT_PARAMS( \
+          BOOST_MPL_LIMIT_METAFUNCTION_ARITY \
+        , param \
+        , value \
+        ) \
+    AUX778076_DMC_PARAM() \
+    /**/
+
+#   define AUX778076_BIND_N_PARAMS(n, param) \
+    BOOST_PP_COMMA_IF(n) BOOST_MPL_PP_PARAMS(n, param) \
+    AUX778076_DMC_PARAM() \
+    /**/
+
+#if !defined(BOOST_MPL_CFG_NO_BIND_TEMPLATE)
+template<
+      typename F, AUX778076_BIND_DEFAULT_PARAMS(typename T, na)
+    >
+struct bind;
+#endif
+
+#define BOOST_PP_ITERATION_PARAMS_1 \
+    (3,(0, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, <boost/mpl/bind_fwd.hpp>))
+#include BOOST_PP_ITERATE()
+
+#   undef AUX778076_BIND_N_PARAMS
+#   undef AUX778076_BIND_DEFAULT_PARAMS
+#   undef AUX778076_DMC_PARAM
+}}
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_BIND_FWD_HPP_INCLUDED
+
+///// iteration
+
+#else
+#define i_ BOOST_PP_FRAME_ITERATION(1)
+
+template<
+      typename F AUX778076_BIND_N_PARAMS(i_, typename T)
+    >
+struct BOOST_PP_CAT(bind,i_);
+
+#undef i_
+#endif // BOOST_PP_IS_ITERATING
diff --git a/third_party/boost/boost/mpl/bool.hpp b/third_party/boost/boost/mpl/bool.hpp
new file mode 100644
index 0000000..4c336fb
--- /dev/null
+++ b/third_party/boost/boost/mpl/bool.hpp
@@ -0,0 +1,39 @@
+
+#ifndef BOOST_MPL_BOOL_HPP_INCLUDED
+#define BOOST_MPL_BOOL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/bool_fwd.hpp>
+#include <boost/mpl/integral_c_tag.hpp>
+#include <boost/mpl/aux_/config/static_constant.hpp>
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+
+template< bool C_ > struct bool_
+{
+    BOOST_STATIC_CONSTANT(bool, value = C_);
+    typedef integral_c_tag tag;
+    typedef bool_ type;
+    typedef bool value_type;
+    BOOST_CONSTEXPR operator bool() const { return this->value; }
+};
+
+#if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
+template< bool C_ >
+bool const bool_<C_>::value;
+#endif
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+
+#endif // BOOST_MPL_BOOL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/bool_fwd.hpp b/third_party/boost/boost/mpl/bool_fwd.hpp
new file mode 100644
index 0000000..780b280
--- /dev/null
+++ b/third_party/boost/boost/mpl/bool_fwd.hpp
@@ -0,0 +1,33 @@
+
+#ifndef BOOST_MPL_BOOL_FWD_HPP_INCLUDED
+#define BOOST_MPL_BOOL_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/adl_barrier.hpp>
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+
+template< bool C_ > struct bool_;
+
+// shorcuts
+typedef bool_<true> true_;
+typedef bool_<false> false_;
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+
+BOOST_MPL_AUX_ADL_BARRIER_DECL(bool_)
+BOOST_MPL_AUX_ADL_BARRIER_DECL(true_)
+BOOST_MPL_AUX_ADL_BARRIER_DECL(false_)
+
+#endif // BOOST_MPL_BOOL_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/clear.hpp b/third_party/boost/boost/mpl/clear.hpp
new file mode 100644
index 0000000..91b8168
--- /dev/null
+++ b/third_party/boost/boost/mpl/clear.hpp
@@ -0,0 +1,39 @@
+
+#ifndef BOOST_MPL_CLEAR_HPP_INCLUDED
+#define BOOST_MPL_CLEAR_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/clear_fwd.hpp>
+#include <boost/mpl/aux_/clear_impl.hpp>
+#include <boost/mpl/sequence_tag.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    >
+struct clear
+    : clear_impl< typename sequence_tag<Sequence>::type >
+        ::template apply< Sequence >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,clear,(Sequence))
+};
+
+BOOST_MPL_AUX_NA_SPEC(1, clear)
+
+}}
+
+#endif // BOOST_MPL_CLEAR_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/clear_fwd.hpp b/third_party/boost/boost/mpl/clear_fwd.hpp
new file mode 100644
index 0000000..60dfedb
--- /dev/null
+++ b/third_party/boost/boost/mpl/clear_fwd.hpp
@@ -0,0 +1,24 @@
+
+#ifndef BOOST_MPL_CLEAR_FWD_HPP_INCLUDED
+#define BOOST_MPL_CLEAR_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+namespace boost { namespace mpl {
+
+template< typename Tag > struct clear_impl;
+template< typename Sequence > struct clear;
+
+}}
+
+#endif // BOOST_MPL_CLEAR_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/deref.hpp b/third_party/boost/boost/mpl/deref.hpp
new file mode 100644
index 0000000..55f7cde
--- /dev/null
+++ b/third_party/boost/boost/mpl/deref.hpp
@@ -0,0 +1,41 @@
+
+#ifndef BOOST_MPL_DEREF_HPP_INCLUDED
+#define BOOST_MPL_DEREF_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/msvc_type.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+#include <boost/mpl/aux_/config/eti.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Iterator)
+    >
+struct deref
+{
+#if !defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG)
+    typedef typename Iterator::type type;
+#else
+    typedef typename aux::msvc_type<Iterator>::type type;
+#endif
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,deref,(Iterator))
+};
+
+BOOST_MPL_AUX_NA_SPEC(1, deref)
+
+}}
+
+#endif // BOOST_MPL_DEREF_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/distance.hpp b/third_party/boost/boost/mpl/distance.hpp
new file mode 100644
index 0000000..18441a6
--- /dev/null
+++ b/third_party/boost/boost/mpl/distance.hpp
@@ -0,0 +1,78 @@
+
+#ifndef BOOST_MPL_DISTANCE_HPP_INCLUDED
+#define BOOST_MPL_DISTANCE_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/distance_fwd.hpp>
+#include <boost/mpl/iter_fold.hpp>
+#include <boost/mpl/iterator_range.hpp>
+#include <boost/mpl/long.hpp>
+#include <boost/mpl/next.hpp>
+#include <boost/mpl/tag.hpp>
+#include <boost/mpl/apply_wrap.hpp>
+#include <boost/mpl/aux_/msvc_eti_base.hpp>
+#include <boost/mpl/aux_/value_wknd.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/config/forwarding.hpp>
+#include <boost/mpl/aux_/config/static_constant.hpp>
+
+
+namespace boost { namespace mpl {
+
+// default implementation for forward/bidirectional iterators
+template< typename Tag > struct distance_impl
+{
+    template< typename First, typename Last > struct apply
+#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING)
+        : aux::msvc_eti_base< typename iter_fold<
+              iterator_range<First,Last>
+            , mpl::long_<0>
+            , next<>
+            >::type >
+    {
+#else
+    {
+        typedef typename iter_fold<
+              iterator_range<First,Last>
+            , mpl::long_<0>
+            , next<>
+            >::type type;
+
+        BOOST_STATIC_CONSTANT(long, value =
+              (iter_fold<
+                  iterator_range<First,Last>
+                , mpl::long_<0>
+                , next<>
+                >::type::value)
+            );
+#endif
+    };
+};
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(First)
+    , typename BOOST_MPL_AUX_NA_PARAM(Last)
+    >
+struct distance
+    : distance_impl< typename tag<First>::type >
+        ::template apply<First, Last>
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(2, distance, (First, Last))
+};
+
+BOOST_MPL_AUX_NA_SPEC(2, distance)
+
+}}
+
+#endif // BOOST_MPL_DISTANCE_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/distance_fwd.hpp b/third_party/boost/boost/mpl/distance_fwd.hpp
new file mode 100644
index 0000000..efe8d12
--- /dev/null
+++ b/third_party/boost/boost/mpl/distance_fwd.hpp
@@ -0,0 +1,28 @@
+
+#ifndef BOOST_MPL_DISTANCE_FWD_HPP_INCLUDED
+#define BOOST_MPL_DISTANCE_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/common_name_wknd.hpp>
+
+namespace boost { namespace mpl {
+
+BOOST_MPL_AUX_COMMON_NAME_WKND(distance)
+
+template< typename Tag > struct distance_impl;
+template< typename First, typename Last > struct distance;
+
+}}
+
+#endif // BOOST_MPL_DISTANCE_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/empty.hpp b/third_party/boost/boost/mpl/empty.hpp
new file mode 100644
index 0000000..f4f798f
--- /dev/null
+++ b/third_party/boost/boost/mpl/empty.hpp
@@ -0,0 +1,39 @@
+
+#ifndef BOOST_MPL_EMPTY_HPP_INCLUDED
+#define BOOST_MPL_EMPTY_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/empty_fwd.hpp>
+#include <boost/mpl/sequence_tag.hpp>
+#include <boost/mpl/aux_/empty_impl.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    >
+struct empty
+    : empty_impl< typename sequence_tag<Sequence>::type >
+        ::template apply< Sequence >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,empty,(Sequence))
+};
+
+BOOST_MPL_AUX_NA_SPEC(1, empty)
+
+}}
+
+#endif // BOOST_MPL_EMPTY_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/empty_fwd.hpp b/third_party/boost/boost/mpl/empty_fwd.hpp
new file mode 100644
index 0000000..910821b
--- /dev/null
+++ b/third_party/boost/boost/mpl/empty_fwd.hpp
@@ -0,0 +1,24 @@
+
+#ifndef BOOST_MPL_EMPTY_FWD_HPP_INCLUDED
+#define BOOST_MPL_EMPTY_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+namespace boost { namespace mpl {
+
+template< typename Tag > struct empty_impl;
+template< typename Sequence > struct empty;
+
+}}
+
+#endif // BOOST_MPL_EMPTY_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/eval_if.hpp b/third_party/boost/boost/mpl/eval_if.hpp
new file mode 100644
index 0000000..e892703
--- /dev/null
+++ b/third_party/boost/boost/mpl/eval_if.hpp
@@ -0,0 +1,71 @@
+
+#ifndef BOOST_MPL_EVAL_IF_HPP_INCLUDED
+#define BOOST_MPL_EVAL_IF_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/gcc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(C)
+    , typename BOOST_MPL_AUX_NA_PARAM(F1)
+    , typename BOOST_MPL_AUX_NA_PARAM(F2)
+    >
+struct eval_if
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
+     || ( BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, >= 0x0300) \
+        && BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, BOOST_TESTED_AT(0x0304)) \
+        )
+{
+    typedef typename if_<C,F1,F2>::type f_;
+    typedef typename f_::type type;
+#else
+    : if_<C,F1,F2>::type
+{
+#endif
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(3,eval_if,(C,F1,F2))
+};
+
+// (almost) copy & paste in order to save one more
+// recursively nested template instantiation to user
+template<
+      bool C
+    , typename F1
+    , typename F2
+    >
+struct eval_if_c
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \
+     || ( BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, >= 0x0300) \
+        && BOOST_WORKAROUND(BOOST_MPL_CFG_GCC, BOOST_TESTED_AT(0x0304)) \
+        )
+{
+    typedef typename if_c<C,F1,F2>::type f_;
+    typedef typename f_::type type;
+#else
+    : if_c<C,F1,F2>::type
+{
+#endif
+};
+
+BOOST_MPL_AUX_NA_SPEC(3, eval_if)
+
+}}
+
+#endif // BOOST_MPL_EVAL_IF_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/find_if.hpp b/third_party/boost/boost/mpl/find_if.hpp
new file mode 100644
index 0000000..d40da39
--- /dev/null
+++ b/third_party/boost/boost/mpl/find_if.hpp
@@ -0,0 +1,50 @@
+
+#ifndef BOOST_MPL_FIND_IF_HPP_INCLUDED
+#define BOOST_MPL_FIND_IF_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/find_if_pred.hpp>
+#include <boost/mpl/arg.hpp>
+#include <boost/mpl/iter_fold_if.hpp>
+#include <boost/mpl/aux_/common_name_wknd.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost { namespace mpl {
+
+BOOST_MPL_AUX_COMMON_NAME_WKND(find_if)
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    , typename BOOST_MPL_AUX_NA_PARAM(Predicate)
+    >
+struct find_if
+{
+    typedef typename iter_fold_if<
+          Sequence
+        , void
+        , mpl::arg<1> // ignore
+        , protect< aux::find_if_pred<Predicate> >
+        >::type result_;
+
+    typedef typename second<result_>::type type;
+
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(2,find_if,(Sequence,Predicate))
+};
+
+BOOST_MPL_AUX_NA_SPEC(2,find_if)
+
+}}
+
+#endif // BOOST_MPL_FIND_IF_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/fold.hpp b/third_party/boost/boost/mpl/fold.hpp
new file mode 100644
index 0000000..8c06f76
--- /dev/null
+++ b/third_party/boost/boost/mpl/fold.hpp
@@ -0,0 +1,48 @@
+
+#ifndef BOOST_MPL_FOLD_HPP_INCLUDED
+#define BOOST_MPL_FOLD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+// Copyright David Abrahams 2001-2002
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/begin_end.hpp>
+#include <boost/mpl/O1_size.hpp>
+#include <boost/mpl/aux_/fold_impl.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    , typename BOOST_MPL_AUX_NA_PARAM(State)
+    , typename BOOST_MPL_AUX_NA_PARAM(ForwardOp)
+    >
+struct fold
+{
+    typedef typename aux::fold_impl<
+          ::boost::mpl::O1_size<Sequence>::value
+        , typename begin<Sequence>::type
+        , typename end<Sequence>::type
+        , State
+        , ForwardOp
+        >::state type;
+
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(3,fold,(Sequence,State,ForwardOp))
+};
+
+BOOST_MPL_AUX_NA_SPEC(3, fold)
+
+}}
+
+#endif // BOOST_MPL_FOLD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/front.hpp b/third_party/boost/boost/mpl/front.hpp
new file mode 100644
index 0000000..6c30f02
--- /dev/null
+++ b/third_party/boost/boost/mpl/front.hpp
@@ -0,0 +1,39 @@
+
+#ifndef BOOST_MPL_FRONT_HPP_INCLUDED
+#define BOOST_MPL_FRONT_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/front_fwd.hpp>
+#include <boost/mpl/aux_/front_impl.hpp>
+#include <boost/mpl/sequence_tag.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    >
+struct front
+    : front_impl< typename sequence_tag<Sequence>::type >
+        ::template apply< Sequence >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,front,(Sequence))
+};
+
+BOOST_MPL_AUX_NA_SPEC(1, front)
+
+}}
+
+#endif // BOOST_MPL_FRONT_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/front_fwd.hpp b/third_party/boost/boost/mpl/front_fwd.hpp
new file mode 100644
index 0000000..0e181a5
--- /dev/null
+++ b/third_party/boost/boost/mpl/front_fwd.hpp
@@ -0,0 +1,24 @@
+
+#ifndef BOOST_MPL_FRONT_FWD_HPP_INCLUDED
+#define BOOST_MPL_FRONT_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+namespace boost { namespace mpl {
+
+template< typename Tag > struct front_impl;
+template< typename Sequence > struct front;
+
+}}
+
+#endif // BOOST_MPL_FRONT_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/front_inserter.hpp b/third_party/boost/boost/mpl/front_inserter.hpp
new file mode 100644
index 0000000..b047233
--- /dev/null
+++ b/third_party/boost/boost/mpl/front_inserter.hpp
@@ -0,0 +1,33 @@
+
+#ifndef BOOST_MPL_FRONT_INSERTER_HPP_INCLUDED
+#define BOOST_MPL_FRONT_INSERTER_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2003-2004
+// Copyright David Abrahams 2003-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/push_front.hpp>
+#include <boost/mpl/inserter.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename Sequence
+    >
+struct front_inserter
+    : inserter< Sequence,push_front<> >
+{
+};
+
+}}
+
+#endif // BOOST_MPL_FRONT_INSERTER_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/has_xxx.hpp b/third_party/boost/boost/mpl/has_xxx.hpp
new file mode 100644
index 0000000..8df04cd
--- /dev/null
+++ b/third_party/boost/boost/mpl/has_xxx.hpp
@@ -0,0 +1,647 @@
+
+#ifndef BOOST_MPL_HAS_XXX_HPP_INCLUDED
+#define BOOST_MPL_HAS_XXX_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2006
+// Copyright David Abrahams 2002-2003
+// Copyright Daniel Walker 2007
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/type_wrapper.hpp>
+#include <boost/mpl/aux_/yes_no.hpp>
+#include <boost/mpl/aux_/config/gcc.hpp>
+#include <boost/mpl/aux_/config/has_xxx.hpp>
+#include <boost/mpl/aux_/config/msvc_typename.hpp>
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/static_constant.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#include <boost/preprocessor/array/elem.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/control/if.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+
+#if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x590) )
+# include <boost/type_traits/is_class.hpp>
+#endif
+
+#if !defined(BOOST_MPL_CFG_NO_HAS_XXX)
+
+#   if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+
+// agurt, 11/sep/02: MSVC-specific version (< 7.1), based on a USENET
+// newsgroup's posting by John Madsen (comp.lang.c++.moderated,
+// 1999-11-12 19:17:06 GMT); the code is _not_ standard-conforming, but
+// it works way more reliably than the SFINAE-based implementation
+
+// Modified dwa 8/Oct/02 to handle reference types.
+
+#   include <boost/mpl/if.hpp>
+#   include <boost/mpl/bool.hpp>
+
+namespace boost { namespace mpl { namespace aux {
+
+struct has_xxx_tag;
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
+template< typename U > struct msvc_incomplete_array
+{
+    typedef char (&type)[sizeof(U) + 1];
+};
+#endif
+
+template< typename T >
+struct msvc_is_incomplete
+{
+    // MSVC is capable of some kinds of SFINAE.  If U is an incomplete
+    // type, it won't pick the second overload
+    static char tester(...);
+
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
+    template< typename U >
+    static typename msvc_incomplete_array<U>::type tester(type_wrapper<U>);
+#else
+    template< typename U >
+    static char (& tester(type_wrapper<U>) )[sizeof(U)+1];
+#endif
+
+    BOOST_STATIC_CONSTANT(bool, value =
+          sizeof(tester(type_wrapper<T>())) == 1
+        );
+};
+
+template<>
+struct msvc_is_incomplete<int>
+{
+    BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+}}}
+
+#   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, default_) \
+template< typename T, typename name = ::boost::mpl::aux::has_xxx_tag > \
+struct BOOST_PP_CAT(trait,_impl) : T \
+{ \
+    static boost::mpl::aux::no_tag \
+    test(void(*)(::boost::mpl::aux::has_xxx_tag)); \
+    \
+    static boost::mpl::aux::yes_tag test(...); \
+    \
+    BOOST_STATIC_CONSTANT(bool, value = \
+          sizeof(test(static_cast<void(*)(name)>(0))) \
+            != sizeof(boost::mpl::aux::no_tag) \
+        ); \
+    typedef boost::mpl::bool_<value> type; \
+}; \
+\
+template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
+struct trait \
+    : boost::mpl::if_c< \
+          boost::mpl::aux::msvc_is_incomplete<T>::value \
+        , boost::mpl::bool_<false> \
+        , BOOST_PP_CAT(trait,_impl)<T> \
+        >::type \
+{ \
+}; \
+\
+BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, void) \
+BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, bool) \
+BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, char) \
+BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed char) \
+BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned char) \
+BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed short) \
+BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned short) \
+BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed int) \
+BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned int) \
+BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, signed long) \
+BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, unsigned long) \
+BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, float) \
+BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, double) \
+BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, long double) \
+/**/
+
+#   define BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, T) \
+template<> struct trait<T> \
+{ \
+    BOOST_STATIC_CONSTANT(bool, value = false); \
+    typedef boost::mpl::bool_<false> type; \
+}; \
+/**/
+
+#if !defined(BOOST_NO_INTRINSIC_WCHAR_T)
+#   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, unused) \
+    BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, unused) \
+    BOOST_MPL_AUX_HAS_XXX_TRAIT_SPEC(trait, wchar_t) \
+/**/
+#else
+#   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, unused) \
+    BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF_(trait, name, unused) \
+/**/
+#endif
+
+
+// SFINAE-based implementations below are derived from a USENET newsgroup's
+// posting by Rani Sharoni (comp.lang.c++.moderated, 2002-03-17 07:45:09 PST)
+
+#   elif BOOST_WORKAROUND(BOOST_MSVC, <= 1400) \
+      || (BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1800)) && defined(__CUDACC__)) \
+      || BOOST_WORKAROUND(__IBMCPP__, <= 700)
+
+// MSVC 7.1 & MSVC 8.0 & VACPP
+
+// agurt, 15/jun/05: replace overload-based SFINAE implementation with SFINAE
+// applied to partial specialization to fix some apparently random failures
+// (thanks to Daniel Wallin for researching this!)
+
+#   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
+template< typename T > \
+struct BOOST_PP_CAT(trait, _msvc_sfinae_helper) \
+{ \
+    typedef void type; \
+};\
+\
+template< typename T, typename U = void > \
+struct BOOST_PP_CAT(trait,_impl_) \
+{ \
+    BOOST_STATIC_CONSTANT(bool, value = false); \
+    typedef boost::mpl::bool_<value> type; \
+}; \
+\
+template< typename T > \
+struct BOOST_PP_CAT(trait,_impl_)< \
+      T \
+    , typename BOOST_PP_CAT(trait, _msvc_sfinae_helper)< typename T::name >::type \
+    > \
+{ \
+    BOOST_STATIC_CONSTANT(bool, value = true); \
+    typedef boost::mpl::bool_<value> type; \
+}; \
+\
+template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
+struct trait \
+    : BOOST_PP_CAT(trait,_impl_)<T> \
+{ \
+}; \
+/**/
+
+#   elif BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x590) )
+
+#   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_BCB_DEF(trait, trait_tester, name, default_) \
+template< typename T, bool IS_CLASS > \
+struct trait_tester \
+{ \
+    BOOST_STATIC_CONSTANT( bool,  value = false ); \
+}; \
+template< typename T > \
+struct trait_tester< T, true > \
+{ \
+    struct trait_tester_impl \
+    { \
+        template < class U > \
+        static int  resolve( boost::mpl::aux::type_wrapper<U> const volatile * \
+                           , boost::mpl::aux::type_wrapper<typename U::name >* = 0 ); \
+        static char resolve( ... ); \
+    }; \
+    typedef boost::mpl::aux::type_wrapper<T> t_; \
+    BOOST_STATIC_CONSTANT( bool, value = ( sizeof( trait_tester_impl::resolve( static_cast< t_ * >(0) ) ) == sizeof(int) ) ); \
+}; \
+template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
+struct trait           \
+{                      \
+    BOOST_STATIC_CONSTANT( bool, value = (trait_tester< T, boost::is_class< T >::value >::value) );     \
+    typedef boost::mpl::bool_< trait< T, fallback_ >::value > type; \
+};
+
+#   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
+    BOOST_MPL_HAS_XXX_TRAIT_NAMED_BCB_DEF( trait \
+                                         , BOOST_PP_CAT(trait,_tester)      \
+                                         , name       \
+                                         , default_ ) \
+/**/
+
+#   else // other SFINAE-capable compilers
+
+#   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
+template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
+struct trait \
+{ \
+    struct gcc_3_2_wknd \
+    { \
+        template< typename U > \
+        static boost::mpl::aux::yes_tag test( \
+              boost::mpl::aux::type_wrapper<U> const volatile* \
+            , boost::mpl::aux::type_wrapper<BOOST_MSVC_TYPENAME U::name>* = 0 \
+            ); \
+    \
+        static boost::mpl::aux::no_tag test(...); \
+    }; \
+    \
+    typedef boost::mpl::aux::type_wrapper<T> t_; \
+    BOOST_STATIC_CONSTANT(bool, value = \
+          sizeof(gcc_3_2_wknd::test(static_cast<t_*>(0))) \
+            == sizeof(boost::mpl::aux::yes_tag) \
+        ); \
+    typedef boost::mpl::bool_<value> type; \
+}; \
+/**/
+
+#   endif // BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+
+
+#else // BOOST_MPL_CFG_NO_HAS_XXX
+
+// placeholder implementation
+
+#   define BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(trait, name, default_) \
+template< typename T, typename fallback_ = boost::mpl::bool_<default_> > \
+struct trait \
+{ \
+    BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \
+    typedef fallback_ type; \
+}; \
+/**/
+
+#endif
+
+#define BOOST_MPL_HAS_XXX_TRAIT_DEF(name) \
+    BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(BOOST_PP_CAT(has_,name), name, false) \
+/**/
+
+
+#if !defined(BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE)
+
+// Create a boolean Metafunction to detect a nested template
+// member. This implementation is based on a USENET newsgroup's
+// posting by Aleksey Gurtovoy (comp.lang.c++.moderated, 2002-03-19),
+// Rani Sharoni's USENET posting cited above, the non-template has_xxx
+// implementations above, and discussion on the Boost mailing list.
+
+#   if !defined(BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES)
+#     if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
+#       define BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES 1
+#     else
+#       define BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES 0
+#     endif
+#   endif
+
+#   if !defined(BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION)
+#     if (defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS))
+#       define BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION 1
+#     else
+#       define BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION 0
+#     endif
+#   endif
+
+#   if !defined(BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE)
+#     if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
+#       define BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE 1
+#     else
+#       define BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE 0
+#     endif
+#   endif
+
+// NOTE: Many internal implementation macros take a Boost.Preprocessor
+// array argument called args which is of the following form.
+//           ( 4, ( trait, name, max_arity, default_ ) )
+
+#   define BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \
+      BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _introspect) \
+    /**/
+
+#   define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \
+      BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _substitute), n) \
+    /**/
+
+#   define BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) \
+      BOOST_PP_CAT(BOOST_PP_ARRAY_ELEM(0, args) , _test) \
+    /**/
+
+// Thanks to Guillaume Melquiond for pointing out the need for the
+// "substitute" template as an argument to the overloaded test
+// functions to get SFINAE to work for member templates with the
+// correct name but different number of arguments.
+#   define BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE(z, n, args) \
+      template< \
+          template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename V) > class V \
+       > \
+      struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) { \
+      }; \
+    /**/
+
+#   define BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \
+      BOOST_PP_REPEAT( \
+          BOOST_PP_ARRAY_ELEM(2, args) \
+        , BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE \
+        , args \
+      ) \
+    /**/
+
+#   if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION
+#     define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \
+        template< typename V > \
+        static boost::mpl::aux::no_tag \
+        BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \
+      /**/
+#   else
+#     define BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \
+        static boost::mpl::aux::no_tag \
+        BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)(...); \
+      /**/
+#   endif
+
+#   if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES
+#     define BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT(z, n, args) \
+        template< typename V > \
+        static boost::mpl::aux::yes_tag \
+        BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
+            boost::mpl::aux::type_wrapper< V > const volatile* \
+          , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) < \
+                V::template BOOST_PP_ARRAY_ELEM(1, args) \
+            >* = 0 \
+        ); \
+      /**/
+#     define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \
+        BOOST_PP_REPEAT( \
+            BOOST_PP_ARRAY_ELEM(2, args) \
+          , BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT \
+          , args \
+        ) \
+      /**/
+#   else
+#     define BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \
+        template< typename V > \
+        static boost::mpl::aux::yes_tag \
+        BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
+            V const volatile* \
+          , member_macro(args, V, T)* = 0 \
+        ); \
+      /**/
+#   endif
+
+#   if !BOOST_MPL_HAS_XXX_NO_EXPLICIT_TEST_FUNCTION
+#     define BOOST_MPL_HAS_MEMBER_TEST(args) \
+          sizeof(BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U >(0)) \
+              == sizeof(boost::mpl::aux::yes_tag) \
+      /**/
+#   else
+#     if !BOOST_MPL_HAS_XXX_NO_WRAPPED_TYPES
+#       define BOOST_MPL_HAS_MEMBER_TEST(args) \
+          sizeof( \
+              BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
+                  static_cast< boost::mpl::aux::type_wrapper< U >* >(0) \
+              ) \
+          ) == sizeof(boost::mpl::aux::yes_tag) \
+        /**/
+#     else
+#       define BOOST_MPL_HAS_MEMBER_TEST(args) \
+          sizeof( \
+              BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)( \
+                  static_cast< U* >(0) \
+              ) \
+          ) == sizeof(boost::mpl::aux::yes_tag) \
+        /**/
+#     endif
+#   endif
+
+#   define BOOST_MPL_HAS_MEMBER_INTROSPECT( \
+               args, substitute_macro, member_macro \
+           ) \
+      template< typename U > \
+      struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) { \
+          BOOST_MPL_HAS_MEMBER_SUBSTITUTE(args, substitute_macro) \
+          BOOST_MPL_HAS_MEMBER_REJECT(args, member_macro) \
+          BOOST_MPL_HAS_MEMBER_ACCEPT(args, member_macro) \
+          BOOST_STATIC_CONSTANT( \
+              bool, value = BOOST_MPL_HAS_MEMBER_TEST(args) \
+          ); \
+          typedef boost::mpl::bool_< value > type; \
+      }; \
+    /**/
+
+#   define BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \
+               args, introspect_macro, substitute_macro, member_macro \
+           ) \
+      template< \
+          typename T \
+        , typename fallback_ \
+              = boost::mpl::bool_< BOOST_PP_ARRAY_ELEM(3, args) > \
+      > \
+      class BOOST_PP_ARRAY_ELEM(0, args) { \
+          introspect_macro(args, substitute_macro, member_macro) \
+      public: \
+          static const bool value \
+              = BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< T >::value; \
+          typedef typename BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args)< \
+              T \
+          >::type type; \
+      }; \
+    /**/
+
+// BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE expands to the full
+// implementation of the function-based metafunction. Compile with -E
+// to see the preprocessor output for this macro.
+#   define BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \
+               args, substitute_macro, member_macro \
+           ) \
+      BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \
+          args \
+        , BOOST_MPL_HAS_MEMBER_INTROSPECT \
+        , substitute_macro \
+        , member_macro \
+      ) \
+    /**/
+
+#   if BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE
+
+#     if !defined(BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE)
+#       if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
+#         define BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE 1
+#       endif
+#     endif
+
+#     if !BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE
+#       define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
+                   args, n \
+               ) \
+          BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \
+        /**/
+#     else
+#       define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
+                   args, n \
+               ) \
+          BOOST_PP_CAT( \
+              boost_mpl_has_xxx_ \
+            , BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME(args, n) \
+          ) \
+        /**/
+#     endif
+
+#     define BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME( \
+                 args \
+             ) \
+        BOOST_PP_CAT( \
+            BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
+                args, 0 \
+            ) \
+          , _tag \
+        ) \
+      /**/
+
+#     define BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \
+                 z, n, args \
+             ) \
+        template< \
+             template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename U) > class U \
+        > \
+        struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
+                args, n \
+               ) { \
+            typedef \
+                BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \
+                type; \
+        }; \
+      /**/
+
+#     define BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \
+                 args, substitute_macro \
+             ) \
+        typedef void \
+            BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args); \
+        BOOST_PP_REPEAT( \
+            BOOST_PP_ARRAY_ELEM(2, args) \
+          , BOOST_MPL_HAS_MEMBER_MULTI_SUBSTITUTE_WITH_TEMPLATE_SFINAE \
+          , args \
+        ) \
+      /**/
+
+#     define BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE( \
+                 args, member_macro \
+             ) \
+        template< \
+            typename U \
+          , typename V \
+                = BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_TAG_NAME(args) \
+        > \
+        struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args) { \
+            BOOST_STATIC_CONSTANT(bool, value = false); \
+            typedef boost::mpl::bool_< value > type; \
+        }; \
+      /**/
+
+#     define BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT_WITH_TEMPLATE_SFINAE( \
+                 z, n, args \
+             ) \
+        template< typename U > \
+        struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< \
+            U \
+          , typename \
+                BOOST_MPL_HAS_MEMBER_INTROSPECTION_SUBSTITUTE_NAME_WITH_TEMPLATE_SFINAE( \
+                    args, n \
+                )< \
+                    BOOST_MSVC_TYPENAME U::BOOST_PP_ARRAY_ELEM(1, args)< > \
+                >::type \
+        > { \
+            BOOST_STATIC_CONSTANT(bool, value = true); \
+            typedef boost::mpl::bool_< value > type; \
+        }; \
+      /**/
+
+#     define BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE( \
+                 args, member_macro \
+             ) \
+        BOOST_PP_REPEAT( \
+            BOOST_PP_ARRAY_ELEM(2, args) \
+          , BOOST_MPL_HAS_MEMBER_MULTI_ACCEPT_WITH_TEMPLATE_SFINAE \
+          , args \
+        ) \
+      /**/
+
+#     define BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE( \
+                 args, substitute_macro, member_macro \
+             ) \
+        BOOST_MPL_HAS_MEMBER_REJECT_WITH_TEMPLATE_SFINAE(args, member_macro) \
+        BOOST_MPL_HAS_MEMBER_ACCEPT_WITH_TEMPLATE_SFINAE(args, member_macro) \
+        template< typename U > \
+        struct BOOST_MPL_HAS_MEMBER_INTROSPECTION_NAME(args) \
+            : BOOST_MPL_HAS_MEMBER_INTROSPECTION_TEST_NAME(args)< U > { \
+        }; \
+      /**/
+
+// BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE expands to the full
+// implementation of the template-based metafunction. Compile with -E
+// to see the preprocessor output for this macro.
+//
+// Note that if BOOST_MPL_HAS_XXX_NEEDS_NAMESPACE_LEVEL_SUBSTITUTE is
+// defined BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE needs
+// to be expanded at namespace level before
+// BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE can be used.
+#     define BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \
+                 args, substitute_macro, member_macro \
+             ) \
+        BOOST_MPL_HAS_MEMBER_SUBSTITUTE_WITH_TEMPLATE_SFINAE( \
+            args, substitute_macro \
+        ) \
+        BOOST_MPL_HAS_MEMBER_IMPLEMENTATION( \
+            args \
+          , BOOST_MPL_HAS_MEMBER_INTROSPECT_WITH_TEMPLATE_SFINAE \
+          , substitute_macro \
+          , member_macro \
+        ) \
+      /**/
+
+#   endif // BOOST_MPL_HAS_XXX_NEEDS_TEMPLATE_SFINAE
+
+// Note: In the current implementation the parameter and access macros
+// are no longer expanded.
+#   if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
+#     define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \
+        BOOST_MPL_HAS_MEMBER_WITH_FUNCTION_SFINAE( \
+            ( 4, ( trait, name, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, default_ ) ) \
+          , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \
+          , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \
+        ) \
+      /**/
+#   else
+#     define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \
+        BOOST_MPL_HAS_MEMBER_WITH_TEMPLATE_SFINAE( \
+            ( 4, ( trait, name, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, default_ ) ) \
+          , BOOST_MPL_HAS_MEMBER_TEMPLATE_SUBSTITUTE_PARAMETER \
+          , BOOST_MPL_HAS_MEMBER_TEMPLATE_ACCESS \
+        ) \
+      /**/
+#   endif
+
+#else // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
+
+// placeholder implementation
+
+#   define BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(trait, name, default_) \
+      template< typename T \
+              , typename fallback_ = boost::mpl::bool_< default_ > > \
+      struct trait { \
+          BOOST_STATIC_CONSTANT(bool, value = fallback_::value); \
+          typedef fallback_ type; \
+      }; \
+    /**/
+
+#endif // BOOST_MPL_CFG_NO_HAS_XXX_TEMPLATE
+
+#   define BOOST_MPL_HAS_XXX_TEMPLATE_DEF(name) \
+      BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF( \
+          BOOST_PP_CAT(has_, name), name, false \
+      ) \
+    /**/
+
+#endif // BOOST_MPL_HAS_XXX_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/identity.hpp b/third_party/boost/boost/mpl/identity.hpp
new file mode 100644
index 0000000..021cbf4
--- /dev/null
+++ b/third_party/boost/boost/mpl/identity.hpp
@@ -0,0 +1,45 @@
+
+#ifndef BOOST_MPL_IDENTITY_HPP_INCLUDED
+#define BOOST_MPL_IDENTITY_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(T)
+    >
+struct identity
+{
+    typedef T type;
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1, identity, (T))
+};
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(T)
+    >
+struct make_identity
+{
+    typedef identity<T> type;
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1, make_identity, (T))
+};
+
+BOOST_MPL_AUX_NA_SPEC_NO_ETI(1, identity)
+BOOST_MPL_AUX_NA_SPEC_NO_ETI(1, make_identity)
+
+}}
+
+#endif // BOOST_MPL_IDENTITY_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/if.hpp b/third_party/boost/boost/mpl/if.hpp
new file mode 100644
index 0000000..d448c7f
--- /dev/null
+++ b/third_party/boost/boost/mpl/if.hpp
@@ -0,0 +1,135 @@
+
+#ifndef BOOST_MPL_IF_HPP_INCLUDED
+#define BOOST_MPL_IF_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/value_wknd.hpp>
+#include <boost/mpl/aux_/static_cast.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+#include <boost/mpl/aux_/config/integral.hpp>
+#include <boost/mpl/aux_/config/ctps.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+namespace boost { namespace mpl {
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+template<
+      bool C
+    , typename T1
+    , typename T2
+    >
+struct if_c
+{
+    typedef T1 type;
+};
+
+template<
+      typename T1
+    , typename T2
+    >
+struct if_c<false,T1,T2>
+{
+    typedef T2 type;
+};
+
+// agurt, 05/sep/04: nondescriptive parameter names for the sake of DigitalMars
+// (and possibly MWCW < 8.0); see http://article.gmane.org/gmane.comp.lib.boost.devel/108959
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(T1)
+    , typename BOOST_MPL_AUX_NA_PARAM(T2)
+    , typename BOOST_MPL_AUX_NA_PARAM(T3)
+    >
+struct if_
+{
+ private:
+    // agurt, 02/jan/03: two-step 'type' definition for the sake of aCC
+    typedef if_c<
+#if defined(BOOST_MPL_CFG_BCC_INTEGRAL_CONSTANTS)
+          BOOST_MPL_AUX_VALUE_WKND(T1)::value
+#else
+          BOOST_MPL_AUX_STATIC_CAST(bool, BOOST_MPL_AUX_VALUE_WKND(T1)::value)
+#endif
+        , T2
+        , T3
+        > almost_type_;
+
+ public:
+    typedef typename almost_type_::type type;
+
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(3,if_,(T1,T2,T3))
+};
+
+#else
+
+// no partial class template specialization
+
+namespace aux {
+
+template< bool C >
+struct if_impl
+{
+    template< typename T1, typename T2 > struct result_
+    {
+        typedef T1 type;
+    };
+};
+
+template<>
+struct if_impl<false>
+{
+    template< typename T1, typename T2 > struct result_
+    {
+        typedef T2 type;
+    };
+};
+
+} // namespace aux
+
+template<
+      bool C_
+    , typename T1
+    , typename T2
+    >
+struct if_c
+{
+    typedef typename aux::if_impl< C_ >
+        ::template result_<T1,T2>::type type;
+};
+
+// (almost) copy & paste in order to save one more
+// recursively nested template instantiation to user
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(C_)
+    , typename BOOST_MPL_AUX_NA_PARAM(T1)
+    , typename BOOST_MPL_AUX_NA_PARAM(T2)
+    >
+struct if_
+{
+    enum { msvc_wknd_ = BOOST_MPL_AUX_MSVC_VALUE_WKND(C_)::value };
+
+    typedef typename aux::if_impl< BOOST_MPL_AUX_STATIC_CAST(bool, msvc_wknd_) >
+        ::template result_<T1,T2>::type type;
+
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(3,if_,(C_,T1,T2))
+};
+
+#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+BOOST_MPL_AUX_NA_SPEC(3, if_)
+
+}}
+
+#endif // BOOST_MPL_IF_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/inserter.hpp b/third_party/boost/boost/mpl/inserter.hpp
new file mode 100644
index 0000000..44ffea6
--- /dev/null
+++ b/third_party/boost/boost/mpl/inserter.hpp
@@ -0,0 +1,32 @@
+
+#ifndef BOOST_MPL_INSERTER_HPP_INCLUDED
+#define BOOST_MPL_INSERTER_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2003-2004
+// Copyright David Abrahams 2003-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+namespace boost { namespace mpl {
+
+template<
+      typename Sequence
+    , typename Operation
+    >
+struct inserter
+{
+    typedef Sequence    state;
+    typedef Operation   operation;
+};
+
+}}
+
+#endif // BOOST_MPL_INSERTER_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/int.hpp b/third_party/boost/boost/mpl/int.hpp
new file mode 100644
index 0000000..08d6aa1
--- /dev/null
+++ b/third_party/boost/boost/mpl/int.hpp
@@ -0,0 +1,22 @@
+
+#ifndef BOOST_MPL_INT_HPP_INCLUDED
+#define BOOST_MPL_INT_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/int_fwd.hpp>
+
+#define AUX_WRAPPER_VALUE_TYPE int
+#include <boost/mpl/aux_/integral_wrapper.hpp>
+
+#endif // BOOST_MPL_INT_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/int_fwd.hpp b/third_party/boost/boost/mpl/int_fwd.hpp
new file mode 100644
index 0000000..2ae34d6
--- /dev/null
+++ b/third_party/boost/boost/mpl/int_fwd.hpp
@@ -0,0 +1,27 @@
+
+#ifndef BOOST_MPL_INT_FWD_HPP_INCLUDED
+#define BOOST_MPL_INT_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/adl_barrier.hpp>
+#include <boost/mpl/aux_/nttp_decl.hpp>
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+
+template< BOOST_MPL_AUX_NTTP_DECL(int, N) > struct int_;
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+BOOST_MPL_AUX_ADL_BARRIER_DECL(int_)
+
+#endif // BOOST_MPL_INT_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/integral_c.hpp b/third_party/boost/boost/mpl/integral_c.hpp
new file mode 100644
index 0000000..f2a0132
--- /dev/null
+++ b/third_party/boost/boost/mpl/integral_c.hpp
@@ -0,0 +1,51 @@
+
+#ifndef BOOST_MPL_INTEGRAL_C_HPP_INCLUDED
+#define BOOST_MPL_INTEGRAL_C_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2006
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/integral_c_fwd.hpp>
+#include <boost/mpl/aux_/config/ctps.hpp>
+#include <boost/mpl/aux_/config/static_constant.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#if BOOST_WORKAROUND(__HP_aCC, <= 53800)
+// the type of non-type template arguments may not depend on template arguments
+#   define AUX_WRAPPER_PARAMS(N) typename T, long N
+#else
+#   define AUX_WRAPPER_PARAMS(N) typename T, T N
+#endif
+
+#define AUX_WRAPPER_NAME integral_c
+#define AUX_WRAPPER_VALUE_TYPE T
+#define AUX_WRAPPER_INST(value) AUX_WRAPPER_NAME< T, value >
+#include <boost/mpl/aux_/integral_wrapper.hpp>
+
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
+ && !BOOST_WORKAROUND(__BORLANDC__, <= 0x551)
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+// 'bool' constant doesn't have 'next'/'prior' members
+template< bool C >
+struct integral_c<bool, C>
+{
+    BOOST_STATIC_CONSTANT(bool, value = C);
+    typedef integral_c_tag tag;
+    typedef integral_c type;
+    typedef bool value_type;
+    operator bool() const { return this->value; }
+};
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+#endif
+
+#endif // BOOST_MPL_INTEGRAL_C_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/integral_c_fwd.hpp b/third_party/boost/boost/mpl/integral_c_fwd.hpp
new file mode 100644
index 0000000..c0e286f
--- /dev/null
+++ b/third_party/boost/boost/mpl/integral_c_fwd.hpp
@@ -0,0 +1,32 @@
+
+#ifndef BOOST_MPL_INTEGRAL_C_FWD_HPP_INCLUDED
+#define BOOST_MPL_INTEGRAL_C_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2006
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/workaround.hpp>
+#include <boost/mpl/aux_/adl_barrier.hpp>
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+
+#if BOOST_WORKAROUND(__HP_aCC, <= 53800)
+// the type of non-type template arguments may not depend on template arguments
+template< typename T, long N > struct integral_c;
+#else
+template< typename T, T N > struct integral_c;
+#endif
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+BOOST_MPL_AUX_ADL_BARRIER_DECL(integral_c)
+
+#endif // BOOST_MPL_INTEGRAL_C_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/integral_c_tag.hpp b/third_party/boost/boost/mpl/integral_c_tag.hpp
new file mode 100644
index 0000000..afef345
--- /dev/null
+++ b/third_party/boost/boost/mpl/integral_c_tag.hpp
@@ -0,0 +1,26 @@
+
+#ifndef BOOST_MPL_INTEGRAL_C_TAG_HPP_INCLUDED
+#define BOOST_MPL_INTEGRAL_C_TAG_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+
+#include <boost/mpl/aux_/adl_barrier.hpp>
+#include <boost/mpl/aux_/config/static_constant.hpp>
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+struct integral_c_tag { BOOST_STATIC_CONSTANT(int, value = 0); };
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+BOOST_MPL_AUX_ADL_BARRIER_DECL(integral_c_tag)
+
+#endif // BOOST_MPL_INTEGRAL_C_TAG_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/is_sequence.hpp b/third_party/boost/boost/mpl/is_sequence.hpp
new file mode 100644
index 0000000..65f6122
--- /dev/null
+++ b/third_party/boost/boost/mpl/is_sequence.hpp
@@ -0,0 +1,112 @@
+
+#ifndef BOOST_MPL_IS_SEQUENCE_HPP_INCLUDED
+#define BOOST_MPL_IS_SEQUENCE_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/begin_end.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/sequence_tag_fwd.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/void.hpp>
+#include <boost/mpl/aux_/has_tag.hpp>
+#include <boost/mpl/aux_/has_begin.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+#include <boost/mpl/aux_/config/eti.hpp>
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+#   include <boost/mpl/aux_/msvc_is_class.hpp>
+#elif BOOST_WORKAROUND(BOOST_MSVC, == 1300)
+#   include <boost/type_traits/is_class.hpp>
+#endif
+
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace mpl {
+
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+
+namespace aux {
+
+// agurt, 11/jun/03:
+// MSVC 6.5/7.0 fails if 'has_begin' is instantiated on a class type that has a
+// 'begin' member that doesn't name a type; e.g. 'has_begin< std::vector<int> >'
+// would fail; requiring 'T' to have _both_ 'tag' and 'begin' members workarounds
+// the issue for most real-world cases
+template< typename T > struct is_sequence_impl
+    : and_<
+          identity< aux::has_tag<T> >
+        , identity< aux::has_begin<T> >
+        >
+{
+};
+
+} // namespace aux
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(T)
+    >
+struct is_sequence
+    : if_<
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+          aux::msvc_is_class<T>
+#else
+          boost::is_class<T>
+#endif
+        , aux::is_sequence_impl<T>
+        , bool_<false>
+        >::type
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1, is_sequence, (T))
+};
+
+#elif defined(BOOST_MPL_CFG_NO_HAS_XXX)
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(T)
+    >
+struct is_sequence
+    : bool_<false>
+{
+};
+
+#else
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(T)
+    >
+struct is_sequence
+    : not_< is_same< typename begin<T>::type, void_ > >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1, is_sequence, (T))
+};
+
+#endif // BOOST_MSVC
+
+#if defined(BOOST_MPL_CFG_MSVC_60_ETI_BUG)
+template<> struct is_sequence<int>
+    : bool_<false>
+{
+};
+#endif
+
+BOOST_MPL_AUX_NA_SPEC_NO_ETI(1, is_sequence)
+
+}}
+
+#endif // BOOST_MPL_IS_SEQUENCE_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/iter_fold.hpp b/third_party/boost/boost/mpl/iter_fold.hpp
new file mode 100644
index 0000000..f09c00f
--- /dev/null
+++ b/third_party/boost/boost/mpl/iter_fold.hpp
@@ -0,0 +1,49 @@
+
+#ifndef BOOST_MPL_ITER_FOLD_HPP_INCLUDED
+#define BOOST_MPL_ITER_FOLD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+// Copyright David Abrahams 2001-2002
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/begin_end.hpp>
+#include <boost/mpl/O1_size.hpp>
+#include <boost/mpl/lambda.hpp>
+#include <boost/mpl/aux_/iter_fold_impl.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    , typename BOOST_MPL_AUX_NA_PARAM(State)
+    , typename BOOST_MPL_AUX_NA_PARAM(ForwardOp)
+    >
+struct iter_fold
+{
+    typedef typename aux::iter_fold_impl<
+          ::boost::mpl::O1_size<Sequence>::value
+        , typename begin<Sequence>::type
+        , typename end<Sequence>::type
+        , State
+        , typename lambda<ForwardOp>::type
+        >::state type;
+
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(3,iter_fold,(Sequence,State,ForwardOp))
+};
+
+BOOST_MPL_AUX_NA_SPEC(3, iter_fold)
+
+}}
+
+#endif // BOOST_MPL_ITER_FOLD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/iter_fold_if.hpp b/third_party/boost/boost/mpl/iter_fold_if.hpp
new file mode 100644
index 0000000..0fa8165
--- /dev/null
+++ b/third_party/boost/boost/mpl/iter_fold_if.hpp
@@ -0,0 +1,117 @@
+
+#ifndef BOOST_MPL_ITER_FOLD_IF_HPP_INCLUDED
+#define BOOST_MPL_ITER_FOLD_IF_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2003-2004
+// Copyright Eric Friedman 2003
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/begin_end.hpp>
+#include <boost/mpl/logical.hpp>
+#include <boost/mpl/always.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/pair.hpp>
+#include <boost/mpl/apply.hpp>
+#include <boost/mpl/aux_/iter_fold_if_impl.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+#include <boost/mpl/aux_/config/forwarding.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace mpl {
+
+namespace aux {
+
+template< typename Predicate, typename LastIterator >
+struct iter_fold_if_pred
+{
+    template< typename State, typename Iterator > struct apply
+#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING)
+        : and_<
+              not_< is_same<Iterator,LastIterator> >
+            , apply1<Predicate,Iterator>
+            >
+    {
+#else
+    {
+        typedef and_<
+              not_< is_same<Iterator,LastIterator> >
+            , apply1<Predicate,Iterator>
+            > type;
+#endif
+    };
+};
+
+} // namespace aux
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    , typename BOOST_MPL_AUX_NA_PARAM(State)
+    , typename BOOST_MPL_AUX_NA_PARAM(ForwardOp)
+    , typename BOOST_MPL_AUX_NA_PARAM(ForwardPredicate)
+    , typename BOOST_MPL_AUX_NA_PARAM(BackwardOp)
+    , typename BOOST_MPL_AUX_NA_PARAM(BackwardPredicate)
+    >
+struct iter_fold_if
+{
+
+    typedef typename begin<Sequence>::type first_;
+    typedef typename end<Sequence>::type last_;
+
+    typedef typename eval_if<
+          is_na<BackwardPredicate>
+        , if_< is_na<BackwardOp>, always<false_>, always<true_> >
+        , identity<BackwardPredicate>
+        >::type backward_pred_;
+
+// cwpro8 doesn't like 'cut-off' type here (use typedef instead)
+#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) && !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
+    struct result_ :
+#else
+    typedef
+#endif
+        aux::iter_fold_if_impl<
+          first_
+        , State
+        , ForwardOp
+        , protect< aux::iter_fold_if_pred< ForwardPredicate,last_ > >
+        , BackwardOp
+        , backward_pred_
+        >
+#if !BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) && !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
+    { };
+#else
+    result_;
+#endif
+
+public:
+
+    typedef pair<
+          typename result_::state
+        , typename result_::iterator
+        > type;
+
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(
+          6
+        , iter_fold_if
+        , (Sequence,State,ForwardOp,ForwardPredicate,BackwardOp,BackwardPredicate)
+        )
+};
+
+BOOST_MPL_AUX_NA_SPEC(6, iter_fold_if)
+
+}}
+
+#endif // BOOST_MPL_ITER_FOLD_IF_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/iterator_category.hpp b/third_party/boost/boost/mpl/iterator_category.hpp
new file mode 100644
index 0000000..34a7cda
--- /dev/null
+++ b/third_party/boost/boost/mpl/iterator_category.hpp
@@ -0,0 +1,35 @@
+
+#ifndef BOOST_MPL_ITERATOR_CATEGORY_HPP_INCLUDED
+#define BOOST_MPL_ITERATOR_CATEGORY_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost {  namespace mpl {
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Iterator)
+    >
+struct iterator_category
+{
+    typedef typename Iterator::category type;
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,iterator_category,(Iterator))
+};
+
+BOOST_MPL_AUX_NA_SPEC(1, iterator_category)
+
+}}
+
+#endif // BOOST_MPL_ITERATOR_CATEGORY_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/iterator_range.hpp b/third_party/boost/boost/mpl/iterator_range.hpp
new file mode 100644
index 0000000..3ec1ab8
--- /dev/null
+++ b/third_party/boost/boost/mpl/iterator_range.hpp
@@ -0,0 +1,42 @@
+
+#ifndef BOOST_MPL_ITERATOR_RANGE_HPP_INCLUDED
+#define BOOST_MPL_ITERATOR_RANGE_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost { namespace mpl {
+
+struct iterator_range_tag;
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(First)
+    , typename BOOST_MPL_AUX_NA_PARAM(Last)
+    >
+struct iterator_range
+{
+    typedef iterator_range_tag tag;
+    typedef iterator_range type;
+    typedef First begin;
+    typedef Last end;
+
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(2,iterator_range,(First,Last))
+};
+
+BOOST_MPL_AUX_NA_SPEC(2, iterator_range)
+
+}}
+
+#endif // BOOST_MPL_ITERATOR_RANGE_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/iterator_tags.hpp b/third_party/boost/boost/mpl/iterator_tags.hpp
new file mode 100644
index 0000000..a5e2f6b
--- /dev/null
+++ b/third_party/boost/boost/mpl/iterator_tags.hpp
@@ -0,0 +1,27 @@
+
+#ifndef BOOST_MPL_ITERATOR_TAG_HPP_INCLUDED
+#define BOOST_MPL_ITERATOR_TAG_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/int.hpp>
+
+namespace boost { namespace mpl {
+
+struct forward_iterator_tag       : int_<0> { typedef forward_iterator_tag type; };
+struct bidirectional_iterator_tag : int_<1> { typedef bidirectional_iterator_tag type; };
+struct random_access_iterator_tag : int_<2> { typedef random_access_iterator_tag type; };
+
+}}
+
+#endif // BOOST_MPL_ITERATOR_TAG_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/lambda.hpp b/third_party/boost/boost/mpl/lambda.hpp
new file mode 100644
index 0000000..15e51e7
--- /dev/null
+++ b/third_party/boost/boost/mpl/lambda.hpp
@@ -0,0 +1,29 @@
+
+#ifndef BOOST_MPL_LAMBDA_HPP_INCLUDED
+#define BOOST_MPL_LAMBDA_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/lambda_fwd.hpp>
+#include <boost/mpl/bind.hpp>
+#include <boost/mpl/aux_/config/lambda.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT)
+#   include <boost/mpl/aux_/full_lambda.hpp>
+#else
+#   include <boost/mpl/aux_/lambda_no_ctps.hpp>
+#   include <boost/mpl/aux_/lambda_support.hpp>
+#   define BOOST_MPL_CFG_NO_IMPLICIT_METAFUNCTIONS
+#endif
+
+#endif // BOOST_MPL_LAMBDA_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/lambda_fwd.hpp b/third_party/boost/boost/mpl/lambda_fwd.hpp
new file mode 100644
index 0000000..e70d989
--- /dev/null
+++ b/third_party/boost/boost/mpl/lambda_fwd.hpp
@@ -0,0 +1,57 @@
+
+#ifndef BOOST_MPL_LAMBDA_FWD_HPP_INCLUDED
+#define BOOST_MPL_LAMBDA_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/void_fwd.hpp>
+#include <boost/mpl/aux_/na.hpp>
+#include <boost/mpl/aux_/config/lambda.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT)
+
+#   include <boost/mpl/int.hpp>
+#   include <boost/mpl/aux_/lambda_arity_param.hpp>
+#   include <boost/mpl/aux_/template_arity_fwd.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename T = na
+    , typename Tag = void_
+    BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(
+          typename Arity = int_< aux::template_arity<T>::value >
+        )
+    >
+struct lambda;
+
+}}
+
+#else // BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT
+
+#   include <boost/mpl/bool.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename T = na
+    , typename Tag = void_
+    , typename Protect = true_
+    >
+struct lambda;
+
+}}
+
+#endif
+
+#endif // BOOST_MPL_LAMBDA_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/less.hpp b/third_party/boost/boost/mpl/less.hpp
new file mode 100644
index 0000000..3f76a38
--- /dev/null
+++ b/third_party/boost/boost/mpl/less.hpp
@@ -0,0 +1,21 @@
+
+#ifndef BOOST_MPL_LESS_HPP_INCLUDED
+#define BOOST_MPL_LESS_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#define AUX778076_OP_NAME less
+#define AUX778076_OP_TOKEN <
+#include <boost/mpl/aux_/comparison_op.hpp>
+
+#endif // BOOST_MPL_LESS_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/limits/arity.hpp b/third_party/boost/boost/mpl/limits/arity.hpp
new file mode 100644
index 0000000..b4a778e
--- /dev/null
+++ b/third_party/boost/boost/mpl/limits/arity.hpp
@@ -0,0 +1,21 @@
+
+#ifndef BOOST_MPL_LIMITS_ARITY_HPP_INCLUDED
+#define BOOST_MPL_LIMITS_ARITY_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_LIMIT_METAFUNCTION_ARITY)
+#   define BOOST_MPL_LIMIT_METAFUNCTION_ARITY 5
+#endif
+
+#endif // BOOST_MPL_LIMITS_ARITY_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/limits/list.hpp b/third_party/boost/boost/mpl/limits/list.hpp
new file mode 100644
index 0000000..2ce1b34
--- /dev/null
+++ b/third_party/boost/boost/mpl/limits/list.hpp
@@ -0,0 +1,21 @@
+
+#ifndef BOOST_MPL_LIMITS_LIST_HPP_INCLUDED
+#define BOOST_MPL_LIMITS_LIST_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_LIMIT_LIST_SIZE)
+#   define BOOST_MPL_LIMIT_LIST_SIZE 20
+#endif
+
+#endif // BOOST_MPL_LIMITS_LIST_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/list.hpp b/third_party/boost/boost/mpl/list.hpp
new file mode 100644
index 0000000..90940e2
--- /dev/null
+++ b/third_party/boost/boost/mpl/list.hpp
@@ -0,0 +1,57 @@
+
+#ifndef BOOST_MPL_LIST_HPP_INCLUDED
+#define BOOST_MPL_LIST_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/limits/list.hpp>
+#   include <boost/mpl/aux_/na.hpp>
+#   include <boost/mpl/aux_/config/preprocessor.hpp>
+
+#   include <boost/preprocessor/inc.hpp>
+#   include <boost/preprocessor/cat.hpp>
+#   include <boost/preprocessor/stringize.hpp>
+
+#if !defined(BOOST_NEEDS_TOKEN_PASTING_OP_FOR_TOKENS_JUXTAPOSING)
+#   define AUX778076_LIST_HEADER \
+    BOOST_PP_CAT(list,BOOST_MPL_LIMIT_LIST_SIZE).hpp \
+    /**/
+#else
+#   define AUX778076_LIST_HEADER \
+    BOOST_PP_CAT(list,BOOST_MPL_LIMIT_LIST_SIZE)##.hpp \
+    /**/
+#endif
+
+#   include BOOST_PP_STRINGIZE(boost/mpl/list/AUX778076_LIST_HEADER)
+#   undef AUX778076_LIST_HEADER
+#endif
+
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER list.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   include <boost/mpl/limits/list.hpp>
+
+#   define AUX778076_SEQUENCE_NAME list
+#   define AUX778076_SEQUENCE_LIMIT BOOST_MPL_LIMIT_LIST_SIZE
+#   include <boost/mpl/aux_/sequence_wrapper.hpp>
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_LIST_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/list/aux_/O1_size.hpp b/third_party/boost/boost/mpl/list/aux_/O1_size.hpp
new file mode 100644
index 0000000..9924644
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/aux_/O1_size.hpp
@@ -0,0 +1,33 @@
+
+#ifndef BOOST_MPL_LIST_AUX_O1_SIZE_HPP_INCLUDED
+#define BOOST_MPL_LIST_AUX_O1_SIZE_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/O1_size_fwd.hpp>
+#include <boost/mpl/list/aux_/tag.hpp>
+
+namespace boost { namespace mpl {
+
+template<>
+struct O1_size_impl< aux::list_tag >
+{
+    template< typename List > struct apply
+        : List::size
+    {
+    };
+};
+
+}}
+
+#endif // BOOST_MPL_LIST_AUX_O1_SIZE_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/list/aux_/begin_end.hpp b/third_party/boost/boost/mpl/list/aux_/begin_end.hpp
new file mode 100644
index 0000000..9e4a2e7
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/aux_/begin_end.hpp
@@ -0,0 +1,44 @@
+
+#ifndef BOOST_MPL_LIST_AUX_BEGIN_END_HPP_INCLUDED
+#define BOOST_MPL_LIST_AUX_BEGIN_END_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/begin_end_fwd.hpp>
+#include <boost/mpl/list/aux_/iterator.hpp>
+#include <boost/mpl/list/aux_/tag.hpp>
+#include <boost/mpl/list/aux_/item.hpp>
+
+namespace boost { namespace mpl {
+
+template<>
+struct begin_impl< aux::list_tag >
+{
+    template< typename List > struct apply
+    {
+        typedef l_iter<typename List::type> type;
+    };
+};
+
+template<>
+struct end_impl< aux::list_tag >
+{
+    template< typename > struct apply
+    {
+        typedef l_iter<l_end> type;
+    };
+};
+
+}}
+
+#endif // BOOST_MPL_LIST_AUX_BEGIN_END_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/list/aux_/clear.hpp b/third_party/boost/boost/mpl/list/aux_/clear.hpp
new file mode 100644
index 0000000..563621f
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/aux_/clear.hpp
@@ -0,0 +1,34 @@
+
+#ifndef BOOST_MPL_LIST_AUX_CLEAR_HPP_INCLUDED
+#define BOOST_MPL_LIST_AUX_CLEAR_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/clear_fwd.hpp>
+#include <boost/mpl/list/aux_/item.hpp>
+#include <boost/mpl/list/aux_/tag.hpp>
+
+namespace boost { namespace mpl {
+
+template<>
+struct clear_impl< aux::list_tag >
+{
+    template< typename List > struct apply
+    {
+        typedef l_end type;
+    };
+};
+
+}}
+
+#endif // BOOST_MPL_LIST_AUX_CLEAR_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/list/aux_/empty.hpp b/third_party/boost/boost/mpl/list/aux_/empty.hpp
new file mode 100644
index 0000000..4d4ffef
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/aux_/empty.hpp
@@ -0,0 +1,34 @@
+
+#ifndef BOOST_MPL_LIST_AUX_EMPTY_HPP_INCLUDED
+#define BOOST_MPL_LIST_AUX_EMPTY_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/empty_fwd.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/list/aux_/tag.hpp>
+
+namespace boost { namespace mpl {
+
+template<>
+struct empty_impl< aux::list_tag >
+{
+    template< typename List > struct apply
+        : not_<typename List::size>
+    {
+    };
+};
+
+}}
+
+#endif // BOOST_MPL_LIST_AUX_EMPTY_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/list/aux_/front.hpp b/third_party/boost/boost/mpl/list/aux_/front.hpp
new file mode 100644
index 0000000..134a6fa
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/aux_/front.hpp
@@ -0,0 +1,33 @@
+
+#ifndef BOOST_MPL_LIST_AUX_FRONT_HPP_INCLUDED
+#define BOOST_MPL_LIST_AUX_FRONT_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/front_fwd.hpp>
+#include <boost/mpl/list/aux_/tag.hpp>
+
+namespace boost { namespace mpl {
+
+template<>
+struct front_impl< aux::list_tag >
+{
+    template< typename List > struct apply
+    {
+        typedef typename List::item type;
+    };
+};
+
+}}
+
+#endif // BOOST_MPL_LIST_AUX_FRONT_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/list/aux_/include_preprocessed.hpp b/third_party/boost/boost/mpl/list/aux_/include_preprocessed.hpp
new file mode 100644
index 0000000..e95bff2
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/aux_/include_preprocessed.hpp
@@ -0,0 +1,35 @@
+
+// Copyright Aleksey Gurtovoy 2001-2006
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+// NO INCLUDE GUARDS, THE HEADER IS INTENDED FOR MULTIPLE INCLUSION!
+
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/stringize.hpp>
+
+#   define AUX778076_HEADER \
+    aux_/preprocessed/plain/BOOST_MPL_PREPROCESSED_HEADER \
+/**/
+
+#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(700))
+#   define AUX778076_INCLUDE_STRING BOOST_PP_STRINGIZE(boost/mpl/list/AUX778076_HEADER)
+#   include AUX778076_INCLUDE_STRING
+#   undef AUX778076_INCLUDE_STRING
+#else
+#   include BOOST_PP_STRINGIZE(boost/mpl/list/AUX778076_HEADER)
+#endif
+
+#   undef AUX778076_HEADER
+
+#undef BOOST_MPL_PREPROCESSED_HEADER
diff --git a/third_party/boost/boost/mpl/list/aux_/item.hpp b/third_party/boost/boost/mpl/list/aux_/item.hpp
new file mode 100644
index 0000000..68e4295
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/aux_/item.hpp
@@ -0,0 +1,55 @@
+
+#ifndef BOOST_MPL_LIST_AUX_NODE_HPP_INCLUDED
+#define BOOST_MPL_LIST_AUX_NODE_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/long.hpp>
+#include <boost/mpl/list/aux_/tag.hpp>
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename Size
+    , typename T
+    , typename Next
+    >
+struct l_item
+{
+// agurt, 17/jul/03: to facilitate the deficient 'is_sequence' implementation
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+    typedef int begin;
+#endif
+    typedef aux::list_tag tag;
+    typedef l_item type;
+
+    typedef Size size;
+    typedef T item;
+    typedef Next next;
+};
+
+struct l_end
+{
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
+    typedef int begin;
+#endif
+    typedef aux::list_tag tag;
+    typedef l_end type;
+    typedef long_<0> size;
+};
+
+}}
+
+#endif // BOOST_MPL_LIST_AUX_NODE_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/list/aux_/iterator.hpp b/third_party/boost/boost/mpl/list/aux_/iterator.hpp
new file mode 100644
index 0000000..5aaa1a1
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/aux_/iterator.hpp
@@ -0,0 +1,76 @@
+
+#ifndef BOOST_MPL_LIST_AUX_ITERATOR_HPP_INCLUDED
+#define BOOST_MPL_LIST_AUX_ITERATOR_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/iterator_tags.hpp>
+#include <boost/mpl/next_prior.hpp>
+#include <boost/mpl/deref.hpp>
+#include <boost/mpl/list/aux_/item.hpp>
+#include <boost/mpl/aux_/na.hpp>
+#include <boost/mpl/aux_/lambda_spec.hpp>
+#include <boost/mpl/aux_/config/ctps.hpp>
+
+namespace boost { namespace mpl {
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+template< typename Node >
+struct l_iter
+{
+    typedef aux::l_iter_tag tag;
+    typedef forward_iterator_tag category;
+};
+
+template< typename Node >
+struct deref< l_iter<Node> >
+{
+    typedef typename Node::item type;
+};
+
+template< typename Node >
+struct next< l_iter<Node> >
+{
+    typedef l_iter< typename Node::next > type;
+};
+
+#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+template< typename Node >
+struct l_iter
+{
+    typedef aux::l_iter_tag tag;
+    typedef forward_iterator_tag category;
+    typedef typename Node::item type;
+    typedef l_iter< typename mpl::next<Node>::type > next;
+};
+
+#endif
+
+
+template<> struct l_iter<l_end>
+{
+    typedef aux::l_iter_tag tag;
+    typedef forward_iterator_tag category;
+#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+    typedef na type;
+    typedef l_iter next;
+#endif
+};
+
+BOOST_MPL_AUX_PASS_THROUGH_LAMBDA_SPEC(1, l_iter)
+
+}}
+
+#endif // BOOST_MPL_LIST_AUX_ITERATOR_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/list/aux_/pop_front.hpp b/third_party/boost/boost/mpl/list/aux_/pop_front.hpp
new file mode 100644
index 0000000..c01b26c
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/aux_/pop_front.hpp
@@ -0,0 +1,34 @@
+
+#ifndef BOOST_MPL_LIST_AUX_POP_FRONT_HPP_INCLUDED
+#define BOOST_MPL_LIST_AUX_POP_FRONT_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/pop_front_fwd.hpp>
+#include <boost/mpl/next_prior.hpp>
+#include <boost/mpl/list/aux_/tag.hpp>
+
+namespace boost { namespace mpl {
+
+template<>
+struct pop_front_impl< aux::list_tag >
+{
+    template< typename List > struct apply
+    {
+        typedef typename mpl::next<List>::type type;
+    };
+};
+
+}}
+
+#endif // BOOST_MPL_LIST_AUX_POP_FRONT_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/list/aux_/preprocessed/plain/list10.hpp b/third_party/boost/boost/mpl/list/aux_/preprocessed/plain/list10.hpp
new file mode 100644
index 0000000..795a728
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/aux_/preprocessed/plain/list10.hpp
@@ -0,0 +1,149 @@
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/list/list10.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl {
+
+template<
+      typename T0
+    >
+struct list1
+    : l_item<
+          long_<1>
+        , T0
+        , l_end
+        >
+{
+    typedef list1 type;
+};
+
+template<
+      typename T0, typename T1
+    >
+struct list2
+    : l_item<
+          long_<2>
+        , T0
+        , list1<T1>
+        >
+{
+    typedef list2 type;
+};
+
+template<
+      typename T0, typename T1, typename T2
+    >
+struct list3
+    : l_item<
+          long_<3>
+        , T0
+        , list2< T1,T2 >
+        >
+{
+    typedef list3 type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3
+    >
+struct list4
+    : l_item<
+          long_<4>
+        , T0
+        , list3< T1,T2,T3 >
+        >
+{
+    typedef list4 type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    >
+struct list5
+    : l_item<
+          long_<5>
+        , T0
+        , list4< T1,T2,T3,T4 >
+        >
+{
+    typedef list5 type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5
+    >
+struct list6
+    : l_item<
+          long_<6>
+        , T0
+        , list5< T1,T2,T3,T4,T5 >
+        >
+{
+    typedef list6 type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6
+    >
+struct list7
+    : l_item<
+          long_<7>
+        , T0
+        , list6< T1,T2,T3,T4,T5,T6 >
+        >
+{
+    typedef list7 type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7
+    >
+struct list8
+    : l_item<
+          long_<8>
+        , T0
+        , list7< T1,T2,T3,T4,T5,T6,T7 >
+        >
+{
+    typedef list8 type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8
+    >
+struct list9
+    : l_item<
+          long_<9>
+        , T0
+        , list8< T1,T2,T3,T4,T5,T6,T7,T8 >
+        >
+{
+    typedef list9 type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    >
+struct list10
+    : l_item<
+          long_<10>
+        , T0
+        , list9< T1,T2,T3,T4,T5,T6,T7,T8,T9 >
+        >
+{
+    typedef list10 type;
+};
+
+}}
diff --git a/third_party/boost/boost/mpl/list/aux_/preprocessed/plain/list20.hpp b/third_party/boost/boost/mpl/list/aux_/preprocessed/plain/list20.hpp
new file mode 100644
index 0000000..b08ef07
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/aux_/preprocessed/plain/list20.hpp
@@ -0,0 +1,169 @@
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Preprocessed version of "boost/mpl/list/list20.hpp" header
+// -- DO NOT modify by hand!
+
+namespace boost { namespace mpl {
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10
+    >
+struct list11
+    : l_item<
+          long_<11>
+        , T0
+        , list10< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10 >
+        >
+{
+    typedef list11 type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11
+    >
+struct list12
+    : l_item<
+          long_<12>
+        , T0
+        , list11< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11 >
+        >
+{
+    typedef list12 type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11, typename T12
+    >
+struct list13
+    : l_item<
+          long_<13>
+        , T0
+        , list12< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12 >
+        >
+{
+    typedef list13 type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11, typename T12, typename T13
+    >
+struct list14
+    : l_item<
+          long_<14>
+        , T0
+        , list13< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13 >
+        >
+{
+    typedef list14 type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11, typename T12, typename T13, typename T14
+    >
+struct list15
+    : l_item<
+          long_<15>
+        , T0
+        , list14< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14 >
+        >
+{
+    typedef list15 type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11, typename T12, typename T13, typename T14
+    , typename T15
+    >
+struct list16
+    : l_item<
+          long_<16>
+        , T0
+        , list15< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15 >
+        >
+{
+    typedef list16 type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11, typename T12, typename T13, typename T14
+    , typename T15, typename T16
+    >
+struct list17
+    : l_item<
+          long_<17>
+        , T0
+        , list16< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16 >
+        >
+{
+    typedef list17 type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11, typename T12, typename T13, typename T14
+    , typename T15, typename T16, typename T17
+    >
+struct list18
+    : l_item<
+          long_<18>
+        , T0
+        , list17< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17 >
+        >
+{
+    typedef list18 type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11, typename T12, typename T13, typename T14
+    , typename T15, typename T16, typename T17, typename T18
+    >
+struct list19
+    : l_item<
+          long_<19>
+        , T0
+        , list18< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18 >
+        >
+{
+    typedef list19 type;
+};
+
+template<
+      typename T0, typename T1, typename T2, typename T3, typename T4
+    , typename T5, typename T6, typename T7, typename T8, typename T9
+    , typename T10, typename T11, typename T12, typename T13, typename T14
+    , typename T15, typename T16, typename T17, typename T18, typename T19
+    >
+struct list20
+    : l_item<
+          long_<20>
+        , T0
+        , list19< T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11,T12,T13,T14,T15,T16,T17,T18,T19 >
+        >
+{
+    typedef list20 type;
+};
+
+}}
diff --git a/third_party/boost/boost/mpl/list/aux_/push_back.hpp b/third_party/boost/boost/mpl/list/aux_/push_back.hpp
new file mode 100644
index 0000000..89610ca
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/aux_/push_back.hpp
@@ -0,0 +1,36 @@
+
+#ifndef BOOST_MPL_LIST_AUX_PUSH_BACK_HPP_INCLUDED
+#define BOOST_MPL_LIST_AUX_PUSH_BACK_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/push_back_fwd.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/list/aux_/tag.hpp>
+
+namespace boost { namespace mpl {
+
+template< typename Tag > struct has_push_back_impl;
+
+template<>
+struct has_push_back_impl< aux::list_tag >
+{
+    template< typename Seq > struct apply
+        : false_
+    {
+    };
+};
+
+}}
+
+#endif // BOOST_MPL_LIST_AUX_PUSH_BACK_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/list/aux_/push_front.hpp b/third_party/boost/boost/mpl/list/aux_/push_front.hpp
new file mode 100644
index 0000000..f7d5088
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/aux_/push_front.hpp
@@ -0,0 +1,39 @@
+
+#ifndef BOOST_MPL_LIST_AUX_PUSH_FRONT_HPP_INCLUDED
+#define BOOST_MPL_LIST_AUX_PUSH_FRONT_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/push_front_fwd.hpp>
+#include <boost/mpl/next.hpp>
+#include <boost/mpl/list/aux_/item.hpp>
+#include <boost/mpl/list/aux_/tag.hpp>
+
+namespace boost { namespace mpl {
+
+template<>
+struct push_front_impl< aux::list_tag >
+{
+    template< typename List, typename T > struct apply
+    {
+        typedef l_item<
+              typename next<typename List::size>::type
+            , T
+            , typename List::type
+            > type;
+    };
+};
+
+}}
+
+#endif // BOOST_MPL_LIST_AUX_PUSH_FRONT_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/list/aux_/size.hpp b/third_party/boost/boost/mpl/list/aux_/size.hpp
new file mode 100644
index 0000000..6a85379
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/aux_/size.hpp
@@ -0,0 +1,33 @@
+
+#ifndef BOOST_MPL_LIST_AUX_SIZE_HPP_INCLUDED
+#define BOOST_MPL_LIST_AUX_SIZE_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/size_fwd.hpp>
+#include <boost/mpl/list/aux_/tag.hpp>
+
+namespace boost { namespace mpl {
+
+template<>
+struct size_impl< aux::list_tag >
+{
+    template< typename List > struct apply
+        : List::size
+    {
+    };
+};
+
+}}
+
+#endif // BOOST_MPL_LIST_AUX_SIZE_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/list/aux_/tag.hpp b/third_party/boost/boost/mpl/list/aux_/tag.hpp
new file mode 100644
index 0000000..09da2f2
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/aux_/tag.hpp
@@ -0,0 +1,24 @@
+
+#ifndef BOOST_MPL_LIST_AUX_TAG_HPP_INCLUDED
+#define BOOST_MPL_LIST_AUX_TAG_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+namespace boost { namespace mpl { namespace aux {
+
+struct list_tag;
+struct l_iter_tag;
+
+}}}
+
+#endif // BOOST_MPL_LIST_AUX_TAG_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/list/list0.hpp b/third_party/boost/boost/mpl/list/list0.hpp
new file mode 100644
index 0000000..83432c3
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/list0.hpp
@@ -0,0 +1,42 @@
+
+#ifndef BOOST_MPL_LIST_LIST0_HPP_INCLUDED
+#define BOOST_MPL_LIST_LIST0_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/long.hpp>
+#include <boost/mpl/aux_/na.hpp>
+#include <boost/mpl/list/aux_/push_front.hpp>
+#include <boost/mpl/list/aux_/pop_front.hpp>
+#include <boost/mpl/list/aux_/push_back.hpp>
+#include <boost/mpl/list/aux_/front.hpp>
+#include <boost/mpl/list/aux_/clear.hpp>
+#include <boost/mpl/list/aux_/O1_size.hpp>
+#include <boost/mpl/list/aux_/size.hpp>
+#include <boost/mpl/list/aux_/empty.hpp>
+#include <boost/mpl/list/aux_/begin_end.hpp>
+#include <boost/mpl/list/aux_/item.hpp>
+
+namespace boost { namespace mpl {
+
+template< typename Dummy = na > struct list0;
+
+template<> struct list0<na>
+    : l_end
+{
+    typedef l_end type;
+};
+
+}}
+
+#endif // BOOST_MPL_LIST_LIST0_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/list/list10.hpp b/third_party/boost/boost/mpl/list/list10.hpp
new file mode 100644
index 0000000..857a11c
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/list10.hpp
@@ -0,0 +1,43 @@
+
+#ifndef BOOST_MPL_LIST_LIST10_HPP_INCLUDED
+#define BOOST_MPL_LIST_LIST10_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/list/list0.hpp>
+#endif
+
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER list10.hpp
+#   include <boost/mpl/list/aux_/include_preprocessed.hpp>
+
+#else
+
+#   include <boost/preprocessor/iterate.hpp>
+
+namespace boost { namespace mpl {
+
+#   define BOOST_PP_ITERATION_PARAMS_1 \
+    (3,(1, 10, <boost/mpl/list/aux_/numbered.hpp>))
+#   include BOOST_PP_ITERATE()
+
+}}
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+
+#endif // BOOST_MPL_LIST_LIST10_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/list/list20.hpp b/third_party/boost/boost/mpl/list/list20.hpp
new file mode 100644
index 0000000..d8dc6b4
--- /dev/null
+++ b/third_party/boost/boost/mpl/list/list20.hpp
@@ -0,0 +1,43 @@
+
+#ifndef BOOST_MPL_LIST_LIST20_HPP_INCLUDED
+#define BOOST_MPL_LIST_LIST20_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/list/list10.hpp>
+#endif
+
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+ && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER list20.hpp
+#   include <boost/mpl/list/aux_/include_preprocessed.hpp>
+
+#else
+
+#   include <boost/preprocessor/iterate.hpp>
+
+namespace boost { namespace mpl {
+
+#   define BOOST_PP_ITERATION_PARAMS_1 \
+    (3,(11, 20, <boost/mpl/list/aux_/numbered.hpp>))
+#   include BOOST_PP_ITERATE()
+
+}}
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+
+#endif // BOOST_MPL_LIST_LIST20_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/logical.hpp b/third_party/boost/boost/mpl/logical.hpp
new file mode 100644
index 0000000..6b48d41
--- /dev/null
+++ b/third_party/boost/boost/mpl/logical.hpp
@@ -0,0 +1,21 @@
+
+#ifndef BOOST_MPL_LOGICAL_HPP_INCLUDED
+#define BOOST_MPL_LOGICAL_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/not.hpp>
+
+#endif // BOOST_MPL_LOGICAL_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/long.hpp b/third_party/boost/boost/mpl/long.hpp
new file mode 100644
index 0000000..10d72da
--- /dev/null
+++ b/third_party/boost/boost/mpl/long.hpp
@@ -0,0 +1,22 @@
+
+#ifndef BOOST_MPL_LONG_HPP_INCLUDED
+#define BOOST_MPL_LONG_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/long_fwd.hpp>
+
+#define AUX_WRAPPER_VALUE_TYPE long
+#include <boost/mpl/aux_/integral_wrapper.hpp>
+
+#endif // BOOST_MPL_LONG_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/long_fwd.hpp b/third_party/boost/boost/mpl/long_fwd.hpp
new file mode 100644
index 0000000..90285c9
--- /dev/null
+++ b/third_party/boost/boost/mpl/long_fwd.hpp
@@ -0,0 +1,27 @@
+
+#ifndef BOOST_MPL_LONG_FWD_HPP_INCLUDED
+#define BOOST_MPL_LONG_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/adl_barrier.hpp>
+#include <boost/mpl/aux_/nttp_decl.hpp>
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+
+template< BOOST_MPL_AUX_NTTP_DECL(long, N) > struct long_;
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+BOOST_MPL_AUX_ADL_BARRIER_DECL(long_)
+
+#endif // BOOST_MPL_LONG_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/max_element.hpp b/third_party/boost/boost/mpl/max_element.hpp
new file mode 100644
index 0000000..5531c5c
--- /dev/null
+++ b/third_party/boost/boost/mpl/max_element.hpp
@@ -0,0 +1,72 @@
+
+#ifndef BOOST_MPL_MAX_ELEMENT_HPP_INCLUDED
+#define BOOST_MPL_MAX_ELEMENT_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/less.hpp>
+#include <boost/mpl/iter_fold.hpp>
+#include <boost/mpl/begin_end.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/deref.hpp>
+#include <boost/mpl/apply.hpp>
+#include <boost/mpl/aux_/common_name_wknd.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+
+namespace boost { namespace mpl {
+
+BOOST_MPL_AUX_COMMON_NAME_WKND(max_element)
+
+namespace aux {
+
+template< typename Predicate >
+struct select_max
+{
+    template< typename OldIterator, typename Iterator >
+    struct apply
+    {
+        typedef typename apply2<
+              Predicate
+            , typename deref<OldIterator>::type
+            , typename deref<Iterator>::type
+            >::type condition_;
+
+        typedef typename if_<
+              condition_
+            , Iterator
+            , OldIterator
+            >::type type;
+    };
+};
+
+} // namespace aux
+
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    , typename Predicate = less<_,_>
+    >
+struct max_element
+    : iter_fold<
+          Sequence
+        , typename begin<Sequence>::type
+        , protect< aux::select_max<Predicate> >
+        >
+{
+};
+
+BOOST_MPL_AUX_NA_SPEC(1, max_element)
+
+}}
+
+#endif // BOOST_MPL_MAX_ELEMENT_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/min_max.hpp b/third_party/boost/boost/mpl/min_max.hpp
new file mode 100644
index 0000000..7b989da
--- /dev/null
+++ b/third_party/boost/boost/mpl/min_max.hpp
@@ -0,0 +1,46 @@
+
+#ifndef BOOST_MPL_MIN_MAX_HPP_INCLUDED
+#define BOOST_MPL_MIN_MAX_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2008
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/less.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(N1)
+    , typename BOOST_MPL_AUX_NA_PARAM(N2)
+    >
+struct min
+    : if_< less<N1,N2>,N1,N2 >
+{
+};
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(N1)
+    , typename BOOST_MPL_AUX_NA_PARAM(N2)
+    >
+struct max
+    : if_< less<N1,N2>,N2,N1 >
+{
+};
+
+BOOST_MPL_AUX_NA_SPEC(2, min)
+BOOST_MPL_AUX_NA_SPEC(2, max)
+
+}}
+
+#endif // BOOST_MPL_MIN_MAX_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/negate.hpp b/third_party/boost/boost/mpl/negate.hpp
new file mode 100644
index 0000000..319f221
--- /dev/null
+++ b/third_party/boost/boost/mpl/negate.hpp
@@ -0,0 +1,81 @@
+
+#ifndef BOOST_MPL_NEGATE_HPP_INCLUDED
+#define BOOST_MPL_NEGATE_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/integral_c.hpp>
+#include <boost/mpl/aux_/msvc_eti_base.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+#include <boost/mpl/aux_/config/eti.hpp>
+#include <boost/mpl/aux_/config/integral.hpp>
+#include <boost/mpl/aux_/config/static_constant.hpp>
+
+namespace boost { namespace mpl {
+
+template< typename Tag > struct negate_impl;
+
+template< typename T > struct negate_tag
+{
+    typedef typename T::tag type;
+};
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(N)
+    >
+struct negate
+#if !defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
+    : negate_impl<
+          typename negate_tag<N>::type
+        >::template apply<N>::type
+#else
+    : aux::msvc_eti_base< typename apply_wrap1<
+          negate_impl< typename negate_tag<N>::type >
+        , N
+        >::type >::type
+#endif
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1, negate, (N))
+};
+
+BOOST_MPL_AUX_NA_SPEC(1, negate)
+
+
+#if defined(BOOST_MPL_CFG_NO_NESTED_VALUE_ARITHMETIC)
+namespace aux {
+template< typename T, T n > struct negate_wknd
+{
+    BOOST_STATIC_CONSTANT(T, value = -n);
+    typedef integral_c<T,value> type;
+};
+}
+#endif
+
+template<>
+struct negate_impl<integral_c_tag>
+{
+#if defined(BOOST_MPL_CFG_NO_NESTED_VALUE_ARITHMETIC)
+    template< typename N > struct apply
+        : aux::negate_wknd< typename N::value_type, N::value >
+#else
+    template< typename N > struct apply
+        : integral_c< typename N::value_type, (-N::value) >
+#endif
+    {
+    };
+};
+
+}}
+
+#endif // BOOST_MPL_NEGATE_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/next.hpp b/third_party/boost/boost/mpl/next.hpp
new file mode 100644
index 0000000..9f3300d
--- /dev/null
+++ b/third_party/boost/boost/mpl/next.hpp
@@ -0,0 +1,19 @@
+
+#ifndef BOOST_MPL_NEXT_HPP_INCLUDED
+#define BOOST_MPL_NEXT_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/next_prior.hpp>
+
+#endif // BOOST_MPL_NEXT_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/next_prior.hpp b/third_party/boost/boost/mpl/next_prior.hpp
new file mode 100644
index 0000000..552c26c
--- /dev/null
+++ b/third_party/boost/boost/mpl/next_prior.hpp
@@ -0,0 +1,49 @@
+
+#ifndef BOOST_MPL_NEXT_PRIOR_HPP_INCLUDED
+#define BOOST_MPL_NEXT_PRIOR_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/common_name_wknd.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost { namespace mpl {
+
+BOOST_MPL_AUX_COMMON_NAME_WKND(next)
+BOOST_MPL_AUX_COMMON_NAME_WKND(prior)
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(T)
+    >
+struct next
+{
+    typedef typename T::next type;
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,next,(T))
+};
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(T)
+    >
+struct prior
+{
+    typedef typename T::prior type;
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,prior,(T))
+};
+
+BOOST_MPL_AUX_NA_SPEC(1, next)
+BOOST_MPL_AUX_NA_SPEC(1, prior)
+
+}}
+
+#endif // BOOST_MPL_NEXT_PRIOR_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/not.hpp b/third_party/boost/boost/mpl/not.hpp
new file mode 100644
index 0000000..8ef0a9e
--- /dev/null
+++ b/third_party/boost/boost/mpl/not.hpp
@@ -0,0 +1,51 @@
+
+#ifndef BOOST_MPL_NOT_HPP_INCLUDED
+#define BOOST_MPL_NOT_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/aux_/nttp_decl.hpp>
+#include <boost/mpl/aux_/nested_type_wknd.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost { namespace mpl {
+
+namespace aux {
+
+template< BOOST_MPL_AUX_NTTP_DECL(long, C_) > // 'long' is intentional here
+struct not_impl
+    : bool_<!C_>
+{
+};
+
+} // namespace aux
+
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(T)
+    >
+struct not_
+    : aux::not_impl<
+          BOOST_MPL_AUX_NESTED_TYPE_WKND(T)::value
+        >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,not_,(T))
+};
+
+BOOST_MPL_AUX_NA_SPEC(1,not_)
+
+}}
+
+#endif // BOOST_MPL_NOT_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/numeric_cast.hpp b/third_party/boost/boost/mpl/numeric_cast.hpp
new file mode 100644
index 0000000..6541470
--- /dev/null
+++ b/third_party/boost/boost/mpl/numeric_cast.hpp
@@ -0,0 +1,41 @@
+
+#ifndef BOOST_MPL_NUMERIC_CAST_HPP_INCLUDED
+#define BOOST_MPL_NUMERIC_CAST_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2003-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+// agurt 21/sep/04: portability macro for the sake of MSVC 6.x-7.0;
+// resolves conflicts with 'boost::numeric_cast' function template.
+// use it in your own code _only_ if you care about compatibility with
+// these outdated compilers!
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570) )
+#   define BOOST_MPL_AUX_NUMERIC_CAST numeric_cast_
+#else
+#   define BOOST_MPL_AUX_NUMERIC_CAST numeric_cast
+#endif
+
+namespace boost { namespace mpl {
+
+// no default implementation; the definition is needed to make MSVC happy
+
+template< typename SourceTag, typename TargetTag > struct BOOST_MPL_AUX_NUMERIC_CAST
+{
+    template< typename N > struct apply;
+};
+
+}}
+
+#endif // BOOST_MPL_NUMERIC_CAST_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/or.hpp b/third_party/boost/boost/mpl/or.hpp
new file mode 100644
index 0000000..1f1ccba
--- /dev/null
+++ b/third_party/boost/boost/mpl/or.hpp
@@ -0,0 +1,61 @@
+
+#ifndef BOOST_MPL_OR_HPP_INCLUDED
+#define BOOST_MPL_OR_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+    && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   include <boost/mpl/bool.hpp>
+#   include <boost/mpl/aux_/nested_type_wknd.hpp>
+#   include <boost/mpl/aux_/na_spec.hpp>
+#   include <boost/mpl/aux_/lambda_support.hpp>
+#   include <boost/mpl/aux_/config/msvc.hpp>
+
+// agurt, 19/may/04: workaround a conflict with <iso646.h> header's
+// 'or' and 'and' macros, see http://tinyurl.com/3et69; 'defined(or)'
+// has to be checked in a separate condition, otherwise GCC complains
+// about 'or' being an alternative token
+#if defined(_MSC_VER) && !defined(__clang__)
+#ifndef __GCCXML__
+#if defined(or)
+#   pragma push_macro("or")
+#   undef or
+#   define or(x)
+#endif
+#endif
+#endif
+
+#   define BOOST_MPL_PREPROCESSED_HEADER or.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#if defined(_MSC_VER) && !defined(__clang__)
+#ifndef __GCCXML__
+#if defined(or)
+#   pragma pop_macro("or")
+#endif
+#endif
+#endif
+
+#else
+
+#   define AUX778076_OP_NAME or_
+#   define AUX778076_OP_VALUE1 true
+#   define AUX778076_OP_VALUE2 false
+#   include <boost/mpl/aux_/logical_op.hpp>
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_OR_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/pair.hpp b/third_party/boost/boost/mpl/pair.hpp
new file mode 100644
index 0000000..18eca32
--- /dev/null
+++ b/third_party/boost/boost/mpl/pair.hpp
@@ -0,0 +1,70 @@
+
+#ifndef BOOST_MPL_PAIR_HPP_INCLUDED
+#define BOOST_MPL_PAIR_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/msvc_eti_base.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+#include <boost/mpl/aux_/config/eti.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(T1)
+    , typename BOOST_MPL_AUX_NA_PARAM(T2)
+    >
+struct pair
+{
+    typedef pair type;
+    typedef T1 first;
+    typedef T2 second;
+
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(2,pair,(T1,T2))
+};
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(P)
+    >
+struct first
+{
+#if !defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG)
+    typedef typename P::first type;
+#else
+    typedef typename aux::msvc_eti_base<P>::first type;
+#endif
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,first,(P))
+};
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(P)
+    >
+struct second
+{
+#if !defined(BOOST_MPL_CFG_MSVC_70_ETI_BUG)
+    typedef typename P::second type;
+#else
+    typedef typename aux::msvc_eti_base<P>::second type;
+#endif
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,second,(P))
+};
+
+
+BOOST_MPL_AUX_NA_SPEC_NO_ETI(2, pair)
+BOOST_MPL_AUX_NA_SPEC(1, first)
+BOOST_MPL_AUX_NA_SPEC(1, second)
+
+}}
+
+#endif // BOOST_MPL_PAIR_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/pair_view.hpp b/third_party/boost/boost/mpl/pair_view.hpp
new file mode 100644
index 0000000..bf46ca1
--- /dev/null
+++ b/third_party/boost/boost/mpl/pair_view.hpp
@@ -0,0 +1,169 @@
+
+#ifndef BOOST_MPL_PAIR_VIEW_HPP_INCLUDED
+#define BOOST_MPL_PAIR_VIEW_HPP_INCLUDED
+
+// Copyright David Abrahams 2003-2004
+// Copyright Aleksey Gurtovoy 2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/begin_end.hpp>
+#include <boost/mpl/iterator_category.hpp>
+#include <boost/mpl/advance.hpp>
+#include <boost/mpl/distance.hpp>
+#include <boost/mpl/next_prior.hpp>
+#include <boost/mpl/deref.hpp>
+#include <boost/mpl/min_max.hpp>
+#include <boost/mpl/pair.hpp>
+#include <boost/mpl/iterator_tags.hpp>
+#include <boost/mpl/aux_/config/ctps.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+
+namespace boost { namespace mpl {
+
+namespace aux {
+struct pair_iter_tag;
+
+#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+template< typename Iter1, typename Iter2, typename Category >
+struct pair_iter;
+
+template< typename Category > struct prior_pair_iter
+{
+    template< typename Iter1, typename Iter2 > struct apply
+    {
+        typedef typename mpl::prior<Iter1>::type i1_;
+        typedef typename mpl::prior<Iter2>::type i2_;
+        typedef pair_iter<i1_,i2_,Category> type;
+    };
+};
+
+template<> struct prior_pair_iter<forward_iterator_tag>
+{
+    template< typename Iter1, typename Iter2 > struct apply
+    {
+        typedef pair_iter<Iter1,Iter2,forward_iterator_tag> type;
+    };
+};
+
+#endif
+}
+
+template<
+      typename Iter1
+    , typename Iter2
+    , typename Category
+    >
+struct pair_iter
+{
+    typedef aux::pair_iter_tag tag;
+    typedef Category category;
+    typedef Iter1 first;
+    typedef Iter2 second;
+
+#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+    typedef pair<
+          typename deref<Iter1>::type
+        , typename deref<Iter2>::type
+        > type;
+
+    typedef typename mpl::next<Iter1>::type i1_;
+    typedef typename mpl::next<Iter2>::type i2_;
+    typedef pair_iter<i1_,i2_,Category> next;
+
+    typedef apply_wrap2< aux::prior_pair_iter<Category>,Iter1,Iter2 >::type prior;
+#endif
+};
+
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+template< typename Iter1, typename Iter2, typename C >
+struct deref< pair_iter<Iter1,Iter2,C> >
+{
+    typedef pair<
+          typename deref<Iter1>::type
+        , typename deref<Iter2>::type
+        > type;
+};
+
+template< typename Iter1, typename Iter2, typename C >
+struct next< pair_iter<Iter1,Iter2,C> >
+{
+    typedef typename mpl::next<Iter1>::type i1_;
+    typedef typename mpl::next<Iter2>::type i2_;
+    typedef pair_iter<i1_,i2_,C> type;
+};
+
+template< typename Iter1, typename Iter2, typename C >
+struct prior< pair_iter<Iter1,Iter2,C> >
+{
+    typedef typename mpl::prior<Iter1>::type i1_;
+    typedef typename mpl::prior<Iter2>::type i2_;
+    typedef pair_iter<i1_,i2_,C> type;
+};
+
+#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+
+template<> struct advance_impl<aux::pair_iter_tag>
+{
+    template< typename Iter, typename D > struct apply
+    {
+        typedef typename mpl::advance< typename Iter::first,D >::type i1_;
+        typedef typename mpl::advance< typename Iter::second,D >::type i2_;
+        typedef pair_iter<i1_,i2_,typename Iter::category> type;
+    };
+};
+
+template<> struct distance_impl<aux::pair_iter_tag>
+{
+    template< typename Iter1, typename Iter2 > struct apply
+    {
+        // agurt, 10/nov/04: MSVC 6.5 ICE-s on forwarding
+        typedef typename mpl::distance<
+              typename first<Iter1>::type
+            , typename first<Iter2>::type
+            >::type type;
+    };
+};
+
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence1)
+    , typename BOOST_MPL_AUX_NA_PARAM(Sequence2)
+    >
+struct pair_view
+{
+    typedef nested_begin_end_tag tag;
+
+    typedef typename begin<Sequence1>::type iter1_;
+    typedef typename begin<Sequence2>::type iter2_;
+    typedef typename min<
+          typename iterator_category<iter1_>::type
+        , typename iterator_category<iter2_>::type
+        >::type category_;
+
+    typedef pair_iter<iter1_,iter2_,category_> begin;
+
+    typedef pair_iter<
+          typename end<Sequence1>::type
+        , typename end<Sequence2>::type
+        , category_
+        > end;
+};
+
+BOOST_MPL_AUX_NA_SPEC(2, pair_view)
+
+}}
+
+#endif // BOOST_MPL_PAIR_VIEW_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/placeholders.hpp b/third_party/boost/boost/mpl/placeholders.hpp
new file mode 100644
index 0000000..ba4acc0
--- /dev/null
+++ b/third_party/boost/boost/mpl/placeholders.hpp
@@ -0,0 +1,100 @@
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+///// header body
+
+#ifndef BOOST_MPL_PLACEHOLDERS_HPP_INCLUDED
+#define BOOST_MPL_PLACEHOLDERS_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+// Copyright Peter Dimov 2001-2003
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/arg.hpp>
+#   include <boost/mpl/aux_/adl_barrier.hpp>
+
+#   if !defined(BOOST_MPL_CFG_NO_ADL_BARRIER_NAMESPACE)
+#       define BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(type) \
+        using ::BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::type; \
+        /**/
+#   else
+#       define BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(type) /**/
+#   endif
+
+#endif
+
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+ && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER placeholders.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   include <boost/mpl/aux_/nttp_decl.hpp>
+#   include <boost/mpl/limits/arity.hpp>
+#   include <boost/preprocessor/iterate.hpp>
+#   include <boost/preprocessor/cat.hpp>
+
+// watch out for GNU gettext users, who #define _(x)
+#if !defined(_) || defined(BOOST_MPL_CFG_NO_UNNAMED_PLACEHOLDER_SUPPORT)
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+typedef arg<-1> _;
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+
+namespace boost { namespace mpl {
+
+BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(_)
+
+namespace placeholders {
+using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::_;
+}
+
+}}
+#endif
+
+/// agurt, 17/mar/02: one more placeholder for the last 'apply#'
+/// specialization
+#define BOOST_PP_ITERATION_PARAMS_1 \
+    (3,(1, BOOST_MPL_LIMIT_METAFUNCTION_ARITY + 1, <boost/mpl/placeholders.hpp>))
+#include BOOST_PP_ITERATE()
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_PLACEHOLDERS_HPP_INCLUDED
+
+///// iteration
+
+#else
+#define i_ BOOST_PP_FRAME_ITERATION(1)
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+
+typedef arg<i_> BOOST_PP_CAT(_,i_);
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+
+namespace boost { namespace mpl {
+
+BOOST_MPL_AUX_ARG_ADL_BARRIER_DECL(BOOST_PP_CAT(_,i_))
+
+namespace placeholders {
+using BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE::BOOST_PP_CAT(_,i_);
+}
+
+}}
+
+#undef i_
+#endif // BOOST_PP_IS_ITERATING
diff --git a/third_party/boost/boost/mpl/pop_front_fwd.hpp b/third_party/boost/boost/mpl/pop_front_fwd.hpp
new file mode 100644
index 0000000..ae2c518
--- /dev/null
+++ b/third_party/boost/boost/mpl/pop_front_fwd.hpp
@@ -0,0 +1,24 @@
+
+#ifndef BOOST_MPL_POP_FRONT_FWD_HPP_INCLUDED
+#define BOOST_MPL_POP_FRONT_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+namespace boost { namespace mpl {
+
+template< typename Tag > struct pop_front_impl;
+template< typename Sequence > struct pop_front;
+
+}}
+
+#endif // BOOST_MPL_POP_FRONT_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/prior.hpp b/third_party/boost/boost/mpl/prior.hpp
new file mode 100644
index 0000000..16d120e
--- /dev/null
+++ b/third_party/boost/boost/mpl/prior.hpp
@@ -0,0 +1,19 @@
+
+#ifndef BOOST_MPL_PRIOR_HPP_INCLUDED
+#define BOOST_MPL_PRIOR_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/next_prior.hpp>
+
+#endif // BOOST_MPL_PRIOR_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/protect.hpp b/third_party/boost/boost/mpl/protect.hpp
new file mode 100644
index 0000000..ef585d7
--- /dev/null
+++ b/third_party/boost/boost/mpl/protect.hpp
@@ -0,0 +1,55 @@
+
+#ifndef BOOST_MPL_PROTECT_HPP_INCLUDED
+#define BOOST_MPL_PROTECT_HPP_INCLUDED
+
+// Copyright Peter Dimov 2001
+// Copyright Aleksey Gurtovoy 2002-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/arity.hpp>
+#include <boost/mpl/aux_/config/dtp.hpp>
+#include <boost/mpl/aux_/nttp_decl.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(T)
+    , int not_le_ = 0
+    >
+struct protect : T
+{
+#if BOOST_WORKAROUND(__EDG_VERSION__, == 238)
+    typedef mpl::protect type;
+#else
+    typedef protect type;
+#endif
+};
+
+#if defined(BOOST_MPL_CFG_BROKEN_DEFAULT_PARAMETERS_IN_NESTED_TEMPLATES)
+namespace aux {
+template< BOOST_MPL_AUX_NTTP_DECL(int, N), typename T >
+struct arity< protect<T>, N >
+    : arity<T,N>
+{
+};
+} // namespace aux
+#endif
+
+BOOST_MPL_AUX_NA_SPEC_MAIN(1, protect)
+#if !defined(BOOST_MPL_CFG_NO_FULL_LAMBDA_SUPPORT)
+BOOST_MPL_AUX_NA_SPEC_TEMPLATE_ARITY(1, 1, protect)
+#endif
+
+}}
+
+#endif // BOOST_MPL_PROTECT_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/push_back.hpp b/third_party/boost/boost/mpl/push_back.hpp
new file mode 100644
index 0000000..f14bafa
--- /dev/null
+++ b/third_party/boost/boost/mpl/push_back.hpp
@@ -0,0 +1,53 @@
+
+#ifndef BOOST_MPL_PUSH_BACK_HPP_INCLUDED
+#define BOOST_MPL_PUSH_BACK_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/push_back_fwd.hpp>
+#include <boost/mpl/aux_/push_back_impl.hpp>
+#include <boost/mpl/sequence_tag.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    , typename BOOST_MPL_AUX_NA_PARAM(T)
+    >
+struct push_back
+    : push_back_impl< typename sequence_tag<Sequence>::type >
+        ::template apply< Sequence,T >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(2,push_back,(Sequence,T))
+};
+
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    >
+struct has_push_back
+    : has_push_back_impl< typename sequence_tag<Sequence>::type >
+        ::template apply< Sequence >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,has_push_back,(Sequence))
+};
+
+
+BOOST_MPL_AUX_NA_SPEC(2, push_back)
+BOOST_MPL_AUX_NA_SPEC(1, has_push_back)
+
+}}
+
+#endif // BOOST_MPL_PUSH_BACK_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/push_back_fwd.hpp b/third_party/boost/boost/mpl/push_back_fwd.hpp
new file mode 100644
index 0000000..b2f7bcd
--- /dev/null
+++ b/third_party/boost/boost/mpl/push_back_fwd.hpp
@@ -0,0 +1,24 @@
+
+#ifndef BOOST_MPL_PUSH_BACK_FWD_HPP_INCLUDED
+#define BOOST_MPL_PUSH_BACK_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+namespace boost { namespace mpl {
+
+template< typename Tag > struct push_back_impl;
+template< typename Sequence, typename T > struct push_back;
+
+}}
+
+#endif // BOOST_MPL_PUSH_BACK_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/push_front.hpp b/third_party/boost/boost/mpl/push_front.hpp
new file mode 100644
index 0000000..f5d6d44
--- /dev/null
+++ b/third_party/boost/boost/mpl/push_front.hpp
@@ -0,0 +1,52 @@
+
+#ifndef BOOST_MPL_PUSH_FRONT_HPP_INCLUDED
+#define BOOST_MPL_PUSH_FRONT_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/push_front_fwd.hpp>
+#include <boost/mpl/aux_/push_front_impl.hpp>
+#include <boost/mpl/sequence_tag.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    , typename BOOST_MPL_AUX_NA_PARAM(T)
+    >
+struct push_front
+    : push_front_impl< typename sequence_tag<Sequence>::type >
+        ::template apply< Sequence,T >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(2,push_front,(Sequence,T))
+};
+
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    >
+struct has_push_front
+    : has_push_front_impl< typename sequence_tag<Sequence>::type >
+        ::template apply< Sequence >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,has_push_front,(Sequence))
+};
+
+BOOST_MPL_AUX_NA_SPEC(2, push_front)
+BOOST_MPL_AUX_NA_SPEC(1, has_push_front)
+
+}}
+
+#endif // BOOST_MPL_PUSH_FRONT_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/push_front_fwd.hpp b/third_party/boost/boost/mpl/push_front_fwd.hpp
new file mode 100644
index 0000000..ff1b055
--- /dev/null
+++ b/third_party/boost/boost/mpl/push_front_fwd.hpp
@@ -0,0 +1,24 @@
+
+#ifndef BOOST_MPL_PUSH_FRONT_FWD_HPP_INCLUDED
+#define BOOST_MPL_PUSH_FRONT_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+namespace boost { namespace mpl {
+
+template< typename Tag > struct push_front_impl;
+template< typename Sequence, typename T > struct push_front;
+
+}}
+
+#endif // BOOST_MPL_PUSH_FRONT_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/quote.hpp b/third_party/boost/boost/mpl/quote.hpp
new file mode 100644
index 0000000..64e95b7
--- /dev/null
+++ b/third_party/boost/boost/mpl/quote.hpp
@@ -0,0 +1,151 @@
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+///// header body
+
+#ifndef BOOST_MPL_QUOTE_HPP_INCLUDED
+#define BOOST_MPL_QUOTE_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2008
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#if !defined(BOOST_MPL_PREPROCESSING_MODE)
+#   include <boost/mpl/void.hpp>
+#   include <boost/mpl/aux_/has_type.hpp>
+#endif
+
+#include <boost/mpl/aux_/config/bcc.hpp>
+#include <boost/mpl/aux_/config/ttp.hpp>
+
+#if defined(BOOST_MPL_CFG_NO_TEMPLATE_TEMPLATE_PARAMETERS) \
+    && !defined(BOOST_MPL_CFG_BCC590_WORKAROUNDS)
+#   define BOOST_MPL_CFG_NO_QUOTE_TEMPLATE
+#endif
+
+#if !defined(BOOST_MPL_CFG_NO_IMPLICIT_METAFUNCTIONS) \
+    && defined(BOOST_MPL_CFG_NO_HAS_XXX)
+#   define BOOST_MPL_CFG_NO_IMPLICIT_METAFUNCTIONS
+#endif
+
+#include <boost/mpl/aux_/config/use_preprocessed.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS) \
+ && !defined(BOOST_MPL_PREPROCESSING_MODE)
+
+#   define BOOST_MPL_PREPROCESSED_HEADER quote.hpp
+#   include <boost/mpl/aux_/include_preprocessed.hpp>
+
+#else
+
+#   include <boost/mpl/limits/arity.hpp>
+#   include <boost/mpl/aux_/preprocessor/params.hpp>
+#   include <boost/mpl/aux_/config/ctps.hpp>
+#   include <boost/mpl/aux_/config/workaround.hpp>
+
+#   include <boost/preprocessor/iterate.hpp>
+#   include <boost/preprocessor/cat.hpp>
+
+#if !defined(BOOST_MPL_CFG_NO_QUOTE_TEMPLATE)
+
+namespace boost { namespace mpl {
+
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+template< typename T, bool has_type_ >
+struct quote_impl
+// GCC has a problem with metafunction forwarding when T is a
+// specialization of a template called 'type'.
+# if BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4)) \
+    && BOOST_WORKAROUND(__GNUC_MINOR__, BOOST_TESTED_AT(0)) \
+    && BOOST_WORKAROUND(__GNUC_PATCHLEVEL__, BOOST_TESTED_AT(2))
+{
+    typedef typename T::type type;
+};
+# else
+    : T
+{
+};
+# endif
+
+template< typename T >
+struct quote_impl<T,false>
+{
+    typedef T type;
+};
+
+#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+template< bool > struct quote_impl
+{
+    template< typename T > struct result_
+        : T
+    {
+    };
+};
+
+template<> struct quote_impl<false>
+{
+    template< typename T > struct result_
+    {
+        typedef T type;
+    };
+};
+
+#endif
+
+#define BOOST_PP_ITERATION_PARAMS_1 \
+    (3,(1, BOOST_MPL_LIMIT_METAFUNCTION_ARITY, <boost/mpl/quote.hpp>))
+#include BOOST_PP_ITERATE()
+
+}}
+
+#endif // BOOST_MPL_CFG_NO_QUOTE_TEMPLATE
+
+#endif // BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
+#endif // BOOST_MPL_QUOTE_HPP_INCLUDED
+
+///// iteration
+
+#else
+#define i_ BOOST_PP_FRAME_ITERATION(1)
+
+template<
+      template< BOOST_MPL_PP_PARAMS(i_, typename P) > class F
+    , typename Tag = void_
+    >
+struct BOOST_PP_CAT(quote,i_)
+{
+    template< BOOST_MPL_PP_PARAMS(i_, typename U) > struct apply
+#if defined(BOOST_MPL_CFG_BCC590_WORKAROUNDS)
+    {
+        typedef typename quote_impl<
+              F< BOOST_MPL_PP_PARAMS(i_, U) >
+            , aux::has_type< F< BOOST_MPL_PP_PARAMS(i_, U) > >::value
+            >::type type;
+    };
+#elif !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
+        : quote_impl<
+              F< BOOST_MPL_PP_PARAMS(i_, U) >
+            , aux::has_type< F< BOOST_MPL_PP_PARAMS(i_, U) > >::value
+            >
+    {
+    };
+#else
+        : quote_impl< aux::has_type< F< BOOST_MPL_PP_PARAMS(i_, U) > >::value >
+            ::template result_< F< BOOST_MPL_PP_PARAMS(i_, U) > >
+    {
+    };
+#endif
+};
+
+#undef i_
+#endif // BOOST_PP_IS_ITERATING
diff --git a/third_party/boost/boost/mpl/reverse_fold.hpp b/third_party/boost/boost/mpl/reverse_fold.hpp
new file mode 100644
index 0000000..3d54b05
--- /dev/null
+++ b/third_party/boost/boost/mpl/reverse_fold.hpp
@@ -0,0 +1,50 @@
+
+#ifndef BOOST_MPL_REVERSE_FOLD_HPP_INCLUDED
+#define BOOST_MPL_REVERSE_FOLD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+// Copyright David Abrahams 2001-2002
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/begin_end.hpp>
+#include <boost/mpl/O1_size.hpp>
+#include <boost/mpl/arg.hpp>
+#include <boost/mpl/aux_/reverse_fold_impl.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    , typename BOOST_MPL_AUX_NA_PARAM(State)
+    , typename BOOST_MPL_AUX_NA_PARAM(BackwardOp)
+    , typename ForwardOp = arg<1>
+    >
+struct reverse_fold
+{
+    typedef typename aux::reverse_fold_impl<
+          ::boost::mpl::O1_size<Sequence>::value
+        , typename begin<Sequence>::type
+        , typename end<Sequence>::type
+        , State
+        , BackwardOp
+        , ForwardOp
+        >::state type;
+
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(3,reverse_fold,(Sequence,State,BackwardOp))
+};
+
+BOOST_MPL_AUX_NA_SPEC(3, reverse_fold)
+
+}}
+
+#endif // BOOST_MPL_REVERSE_FOLD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/same_as.hpp b/third_party/boost/boost/mpl/same_as.hpp
new file mode 100644
index 0000000..c4b8e9f
--- /dev/null
+++ b/third_party/boost/boost/mpl/same_as.hpp
@@ -0,0 +1,55 @@
+
+#ifndef BOOST_MPL_SAME_AS_HPP_INCLUDED
+#define BOOST_MPL_SAME_AS_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/aux_/lambda_spec.hpp>
+#include <boost/mpl/aux_/config/forwarding.hpp>
+
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost { namespace mpl {
+
+template< typename T1 >
+struct same_as
+{
+    template< typename T2 > struct apply
+#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING)
+        : is_same<T1,T2>
+    {
+#else
+    {
+        typedef typename is_same<T1,T2>::type type;
+#endif
+    };
+};
+
+template< typename T1 >
+struct not_same_as
+{
+    template< typename T2 > struct apply
+#if !defined(BOOST_MPL_CFG_NO_NESTED_FORWARDING)
+        : not_< is_same<T1,T2> >
+    {
+#else
+    {
+        typedef typename not_< is_same<T1,T2> >::type type;
+#endif
+    };
+};
+
+}}
+
+#endif // BOOST_MPL_SAME_AS_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/sequence_tag.hpp b/third_party/boost/boost/mpl/sequence_tag.hpp
new file mode 100644
index 0000000..cda8c87
--- /dev/null
+++ b/third_party/boost/boost/mpl/sequence_tag.hpp
@@ -0,0 +1,124 @@
+
+#ifndef BOOST_MPL_SEQUENCE_TAG_HPP_INCLUDED
+#define BOOST_MPL_SEQUENCE_TAG_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/sequence_tag_fwd.hpp>
+#include <boost/mpl/aux_/has_tag.hpp>
+#include <boost/mpl/aux_/has_begin.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/is_msvc_eti_arg.hpp>
+#include <boost/mpl/aux_/config/eti.hpp>
+#include <boost/mpl/aux_/yes_no.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+namespace boost { namespace mpl {
+
+// agurt, 27/nov/02: have to use a simplistic 'sequence_tag' implementation
+// on MSVC to avoid dreadful "internal structure overflow" error
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
+    || defined(BOOST_MPL_CFG_NO_HAS_XXX)
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    >
+struct sequence_tag
+{
+    typedef typename Sequence::tag type;
+};
+
+#elif BOOST_WORKAROUND(BOOST_MSVC, == 1300)
+
+// agurt, 07/feb/03: workaround for what seems to be MSVC 7.0-specific ETI issue
+
+namespace aux {
+
+template< bool >
+struct sequence_tag_impl
+{
+    template< typename Sequence > struct result_
+    {
+        typedef typename Sequence::tag type;
+    };
+};
+
+template<>
+struct sequence_tag_impl<false>
+{
+    template< typename Sequence > struct result_
+    {
+        typedef int type;
+    };
+};
+
+} // namespace aux
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    >
+struct sequence_tag
+    : aux::sequence_tag_impl< !aux::is_msvc_eti_arg<Sequence>::value >
+        ::template result_<Sequence>
+{
+};
+
+#else
+
+namespace aux {
+
+template< bool has_tag_, bool has_begin_ >
+struct sequence_tag_impl
+{
+    // agurt 24/nov/02: MSVC 6.5 gets confused in 'sequence_tag_impl<true>'
+    // specialization below, if we name it 'result_' here
+    template< typename Sequence > struct result2_;
+};
+
+#   define AUX_CLASS_SEQUENCE_TAG_SPEC(has_tag, has_begin, result_type) \
+template<> struct sequence_tag_impl<has_tag,has_begin> \
+{ \
+    template< typename Sequence > struct result2_ \
+    { \
+        typedef result_type type; \
+    }; \
+}; \
+/**/
+
+AUX_CLASS_SEQUENCE_TAG_SPEC(true, true, typename Sequence::tag)
+AUX_CLASS_SEQUENCE_TAG_SPEC(true, false, typename Sequence::tag)
+AUX_CLASS_SEQUENCE_TAG_SPEC(false, true, nested_begin_end_tag)
+AUX_CLASS_SEQUENCE_TAG_SPEC(false, false, non_sequence_tag)
+
+#   undef AUX_CLASS_SEQUENCE_TAG_SPEC
+
+} // namespace aux
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(Sequence)
+    >
+struct sequence_tag
+    : aux::sequence_tag_impl<
+          ::boost::mpl::aux::has_tag<Sequence>::value
+        , ::boost::mpl::aux::has_begin<Sequence>::value
+        >::template result2_<Sequence>
+{
+};
+
+#endif // BOOST_MSVC
+
+BOOST_MPL_AUX_NA_SPEC(1, sequence_tag)
+
+}}
+
+#endif // BOOST_MPL_SEQUENCE_TAG_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/sequence_tag_fwd.hpp b/third_party/boost/boost/mpl/sequence_tag_fwd.hpp
new file mode 100644
index 0000000..4d4b628
--- /dev/null
+++ b/third_party/boost/boost/mpl/sequence_tag_fwd.hpp
@@ -0,0 +1,26 @@
+
+#ifndef BOOST_MPL_SEQUENCE_TAG_FWD_HPP_INCLUDED
+#define BOOST_MPL_SEQUENCE_TAG_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+namespace boost { namespace mpl {
+
+struct nested_begin_end_tag;
+struct non_sequence_tag;
+
+template< typename Sequence > struct sequence_tag;
+
+}}
+
+#endif // BOOST_MPL_SEQUENCE_TAG_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/size_fwd.hpp b/third_party/boost/boost/mpl/size_fwd.hpp
new file mode 100644
index 0000000..f4d8ba0
--- /dev/null
+++ b/third_party/boost/boost/mpl/size_fwd.hpp
@@ -0,0 +1,24 @@
+
+#ifndef BOOST_MPL_SIZE_FWD_HPP_INCLUDED
+#define BOOST_MPL_SIZE_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+namespace boost { namespace mpl {
+
+template< typename Tag > struct size_impl;
+template< typename Sequence > struct size;
+
+}}
+
+#endif // BOOST_MPL_SIZE_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/size_t.hpp b/third_party/boost/boost/mpl/size_t.hpp
new file mode 100644
index 0000000..d93964c
--- /dev/null
+++ b/third_party/boost/boost/mpl/size_t.hpp
@@ -0,0 +1,25 @@
+
+#ifndef BOOST_MPL_SIZE_T_HPP_INCLUDED
+#define BOOST_MPL_SIZE_T_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/size_t_fwd.hpp>
+
+#define AUX_WRAPPER_VALUE_TYPE std::size_t
+#define AUX_WRAPPER_NAME size_t
+#define AUX_WRAPPER_PARAMS(N) std::size_t N
+
+#include <boost/mpl/aux_/integral_wrapper.hpp>
+
+#endif // BOOST_MPL_SIZE_T_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/size_t_fwd.hpp b/third_party/boost/boost/mpl/size_t_fwd.hpp
new file mode 100644
index 0000000..b368ba2
--- /dev/null
+++ b/third_party/boost/boost/mpl/size_t_fwd.hpp
@@ -0,0 +1,28 @@
+
+#ifndef BOOST_MPL_SIZE_T_FWD_HPP_INCLUDED
+#define BOOST_MPL_SIZE_T_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/adl_barrier.hpp>
+#include <boost/config.hpp> // make sure 'size_t' is placed into 'std'
+#include <cstddef>
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+
+template< std::size_t N > struct size_t;
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+BOOST_MPL_AUX_ADL_BARRIER_DECL(size_t)
+
+#endif // BOOST_MPL_SIZE_T_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/sizeof.hpp b/third_party/boost/boost/mpl/sizeof.hpp
new file mode 100644
index 0000000..21cfce2
--- /dev/null
+++ b/third_party/boost/boost/mpl/sizeof.hpp
@@ -0,0 +1,36 @@
+
+#ifndef BOOST_MPL_SIZEOF_HPP_INCLUDED
+#define BOOST_MPL_SIZEOF_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2003
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/size_t.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost { namespace mpl {
+
+template<
+      typename BOOST_MPL_AUX_NA_PARAM(T)
+    >
+struct sizeof_
+    : mpl::size_t< sizeof(T) >
+{
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,sizeof_,(T))
+};
+
+BOOST_MPL_AUX_NA_SPEC_NO_ETI(1, sizeof_)
+
+}}
+
+#endif // BOOST_MPL_SIZEOF_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/tag.hpp b/third_party/boost/boost/mpl/tag.hpp
new file mode 100644
index 0000000..423d038
--- /dev/null
+++ b/third_party/boost/boost/mpl/tag.hpp
@@ -0,0 +1,52 @@
+
+#ifndef BOOST_MPL_TAG_HPP_INCLUDED
+#define BOOST_MPL_TAG_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/void.hpp>
+#include <boost/mpl/aux_/has_tag.hpp>
+#include <boost/mpl/aux_/config/eti.hpp>
+
+namespace boost { namespace mpl {
+
+namespace aux {
+template< typename T > struct tag_impl
+{
+    typedef typename T::tag type;
+};
+}
+
+template< typename T, typename Default = void_ > struct tag
+#if !defined(BOOST_MPL_CFG_MSVC_ETI_BUG)
+    : if_<
+          aux::has_tag<T>
+        , aux::tag_impl<T>
+        , Default
+        >::type
+{
+#else
+{
+    typedef typename eval_if<
+          aux::has_tag<T>
+        , aux::tag_impl<T>
+        , Default
+        >::type type;
+
+#endif
+};
+
+}}
+
+#endif // BOOST_MPL_TAG_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/transform.hpp b/third_party/boost/boost/mpl/transform.hpp
new file mode 100644
index 0000000..f378cb0
--- /dev/null
+++ b/third_party/boost/boost/mpl/transform.hpp
@@ -0,0 +1,145 @@
+
+#ifndef BOOST_MPL_TRANSFORM_HPP_INCLUDED
+#define BOOST_MPL_TRANSFORM_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2000-2004
+// Copyright David Abrahams 2003-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/fold.hpp>
+#include <boost/mpl/reverse_fold.hpp>
+#include <boost/mpl/pair_view.hpp>
+#include <boost/mpl/is_sequence.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/lambda.hpp>
+#include <boost/mpl/bind.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/aux_/na.hpp>
+#include <boost/mpl/aux_/inserter_algorithm.hpp>
+
+namespace boost { namespace mpl {
+
+namespace aux {
+
+template<
+      typename Seq
+    , typename Op
+    , typename In
+    >
+struct transform1_impl
+    : fold<
+          Seq
+        , typename In::state
+        , bind2< typename lambda< typename In::operation >::type
+            , _1
+            , bind1< typename lambda<Op>::type, _2>
+            >
+        >
+{
+};
+
+template<
+      typename Seq
+    , typename Op
+    , typename In
+    >
+struct reverse_transform1_impl
+    : reverse_fold<
+          Seq
+        , typename In::state
+        , bind2< typename lambda< typename In::operation >::type
+            , _1
+            , bind1< typename lambda<Op>::type, _2>
+            >
+        >
+{
+};
+
+template<
+      typename Seq1
+    , typename Seq2
+    , typename Op
+    , typename In
+    >
+struct transform2_impl
+    : fold<
+          pair_view<Seq1,Seq2>
+        , typename In::state
+        , bind2< typename lambda< typename In::operation >::type
+            , _1
+            , bind2<
+                  typename lambda<Op>::type
+                , bind1<first<>,_2>
+                , bind1<second<>,_2>
+                >
+            >
+        >
+{
+};
+
+template<
+      typename Seq1
+    , typename Seq2
+    , typename Op
+    , typename In
+    >
+struct reverse_transform2_impl
+    : reverse_fold<
+          pair_view<Seq1,Seq2>
+        , typename In::state
+        , bind2< typename lambda< typename In::operation >::type
+            , _1
+            , bind2< typename lambda< Op >::type
+                , bind1<first<>,_2>
+                , bind1<second<>,_2>
+                >
+            >
+        >
+{
+};
+
+} // namespace aux
+
+BOOST_MPL_AUX_INSERTER_ALGORITHM_DEF(3, transform1)
+BOOST_MPL_AUX_INSERTER_ALGORITHM_DEF(4, transform2)
+
+#define AUX778076_TRANSFORM_DEF(name)                                   \
+template<                                                               \
+      typename BOOST_MPL_AUX_NA_PARAM(Seq1)                             \
+    , typename BOOST_MPL_AUX_NA_PARAM(Seq2OrOperation)                  \
+    , typename BOOST_MPL_AUX_NA_PARAM(OperationOrInserter)              \
+    , typename BOOST_MPL_AUX_NA_PARAM(Inserter)                         \
+    >                                                                   \
+struct name                                                             \
+{                                                                       \
+    typedef typename eval_if<                                           \
+          or_<                                                          \
+              is_na<OperationOrInserter>                                \
+            , is_lambda_expression< Seq2OrOperation >                   \
+            , not_< is_sequence<Seq2OrOperation> >                      \
+            >                                                           \
+        , name##1<Seq1,Seq2OrOperation,OperationOrInserter>             \
+        , name##2<Seq1,Seq2OrOperation,OperationOrInserter,Inserter>    \
+        >::type type;                                                   \
+};                                                                      \
+BOOST_MPL_AUX_NA_SPEC(4, name)                                          \
+/**/
+
+AUX778076_TRANSFORM_DEF(transform)
+AUX778076_TRANSFORM_DEF(reverse_transform)
+
+#undef AUX778076_TRANSFORM_DEF
+
+}}
+
+#endif // BOOST_MPL_TRANSFORM_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/void.hpp b/third_party/boost/boost/mpl/void.hpp
new file mode 100644
index 0000000..8ca99e3
--- /dev/null
+++ b/third_party/boost/boost/mpl/void.hpp
@@ -0,0 +1,76 @@
+
+#ifndef BOOST_MPL_VOID_HPP_INCLUDED
+#define BOOST_MPL_VOID_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/void_fwd.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/aux_/na_spec.hpp>
+#include <boost/mpl/aux_/config/msvc.hpp>
+#include <boost/mpl/aux_/config/workaround.hpp>
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+
+//  [JDG Feb-4-2003] made void_ a complete type to allow it to be
+//  instantiated so that it can be passed in as an object that can be
+//  used to select an overloaded function. Possible use includes signaling
+//  a zero arity functor evaluation call.
+struct void_ { typedef void_ type; };
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+
+namespace boost { namespace mpl {
+
+template< typename T >
+struct is_void_
+    : false_
+{
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+    using false_::value;
+#endif
+};
+
+template<>
+struct is_void_<void_>
+    : true_
+{
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+    using true_::value;
+#endif
+};
+
+template< typename T >
+struct is_not_void_
+    : true_
+{
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+    using true_::value;
+#endif
+};
+
+template<>
+struct is_not_void_<void_>
+    : false_
+{
+#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+    using false_::value;
+#endif
+};
+
+BOOST_MPL_AUX_NA_SPEC(1, is_void_)
+BOOST_MPL_AUX_NA_SPEC(1, is_not_void_)
+
+}}
+
+#endif // BOOST_MPL_VOID_HPP_INCLUDED
diff --git a/third_party/boost/boost/mpl/void_fwd.hpp b/third_party/boost/boost/mpl/void_fwd.hpp
new file mode 100644
index 0000000..4838ff0
--- /dev/null
+++ b/third_party/boost/boost/mpl/void_fwd.hpp
@@ -0,0 +1,26 @@
+
+#ifndef BOOST_MPL_VOID_FWD_HPP_INCLUDED
+#define BOOST_MPL_VOID_FWD_HPP_INCLUDED
+
+// Copyright Aleksey Gurtovoy 2001-2004
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/mpl for documentation.
+
+// $Id$
+// $Date$
+// $Revision$
+
+#include <boost/mpl/aux_/adl_barrier.hpp>
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
+
+struct void_;
+
+BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
+BOOST_MPL_AUX_ADL_BARRIER_DECL(void_)
+
+#endif // BOOST_MPL_VOID_FWD_HPP_INCLUDED
diff --git a/third_party/boost/boost/multi_index/detail/scope_guard.hpp b/third_party/boost/boost/multi_index/detail/scope_guard.hpp
new file mode 100644
index 0000000..2371091
--- /dev/null
+++ b/third_party/boost/boost/multi_index/detail/scope_guard.hpp
@@ -0,0 +1,453 @@
+/* Copyright 2003-2013 Joaquin M Lopez Munoz.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * See http://www.boost.org/libs/multi_index for library home page.
+ */
+
+#ifndef BOOST_MULTI_INDEX_DETAIL_SCOPE_GUARD_HPP
+#define BOOST_MULTI_INDEX_DETAIL_SCOPE_GUARD_HPP
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/detail/no_exceptions_support.hpp>
+#include <boost/mpl/if.hpp>
+
+namespace boost{
+
+namespace multi_index{
+
+namespace detail{
+
+/* Until some official version of the ScopeGuard idiom makes it into Boost,
+ * we locally define our own. This is a merely reformated version of
+ * ScopeGuard.h as defined in:
+ *   Alexandrescu, A., Marginean, P.:"Generic<Programming>: Change the Way You
+ *     Write Exception-Safe Code - Forever", C/C++ Users Jornal, Dec 2000,
+ *     http://www.drdobbs.com/184403758
+ * with the following modifications:
+ *   - General pretty formatting (pretty to my taste at least.)
+ *   - Naming style changed to standard C++ library requirements.
+ *   - Added scope_guard_impl4 and obj_scope_guard_impl3, (Boost.MultiIndex
+ *     needs them). A better design would provide guards for many more
+ *     arguments through the Boost Preprocessor Library.
+ *   - Added scope_guard_impl_base::touch (see below.)
+ *   - Removed RefHolder and ByRef, whose functionality is provided
+ *     already by Boost.Ref.
+ *   - Removed static make_guard's and make_obj_guard's, so that the code
+ *     will work even if BOOST_NO_MEMBER_TEMPLATES is defined. This forces
+ *     us to move some private ctors to public, though.
+ *
+ * NB: CodeWarrior Pro 8 seems to have problems looking up safe_execute
+ * without an explicit qualification.
+ *
+ * We also define the following variants of the idiom:
+ *
+ *   - make_guard_if_c<bool>( ... )
+ *   - make_guard_if<IntegralConstant>( ... )
+ *   - make_obj_guard_if_c<bool>( ... )
+ *   - make_obj_guard_if<IntegralConstant>( ... )
+ * which may be used with a compile-time constant to yield
+ * a "null_guard" if the boolean compile-time parameter is false,
+ * or conversely, the guard is only constructed if the constant is true.
+ * This is useful to avoid extra tagging, because the returned
+ * null_guard can be optimzed comlpetely away by the compiler.
+ */
+
+class scope_guard_impl_base
+{
+public:
+  scope_guard_impl_base():dismissed_(false){}
+  void dismiss()const{dismissed_=true;}
+
+  /* This helps prevent some "unused variable" warnings under, for instance,
+   * GCC 3.2.
+   */
+  void touch()const{}
+
+protected:
+  ~scope_guard_impl_base(){}
+
+  scope_guard_impl_base(const scope_guard_impl_base& other):
+    dismissed_(other.dismissed_)
+  {
+    other.dismiss();
+  }
+
+  template<typename J>
+  static void safe_execute(J& j){
+    BOOST_TRY{
+      if(!j.dismissed_)j.execute();
+    }
+    BOOST_CATCH(...){}
+    BOOST_CATCH_END
+  }
+
+  mutable bool dismissed_;
+
+private:
+  scope_guard_impl_base& operator=(const scope_guard_impl_base&);
+};
+
+typedef const scope_guard_impl_base& scope_guard;
+
+struct null_guard : public scope_guard_impl_base
+{
+    template< class T1 >
+    null_guard( const T1& )
+    { }
+
+    template< class T1, class T2 >
+    null_guard( const T1&, const T2& )
+    { }
+
+    template< class T1, class T2, class T3 >
+    null_guard( const T1&, const T2&, const T3& )
+    { }
+
+    template< class T1, class T2, class T3, class T4 >
+    null_guard( const T1&, const T2&, const T3&, const T4& )
+    { }
+
+    template< class T1, class T2, class T3, class T4, class T5 >
+    null_guard( const T1&, const T2&, const T3&, const T4&, const T5& )
+    { }
+};
+
+template< bool cond, class T >
+struct null_guard_return
+{
+    typedef typename boost::mpl::if_c<cond,T,null_guard>::type type;
+};
+
+template<typename F>
+class scope_guard_impl0:public scope_guard_impl_base
+{
+public:
+  scope_guard_impl0(F fun):fun_(fun){}
+  ~scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);}
+  void execute(){fun_();}
+
+protected:
+
+  F fun_;
+};
+
+template<typename F>
+inline scope_guard_impl0<F> make_guard(F fun)
+{
+  return scope_guard_impl0<F>(fun);
+}
+
+template<bool cond, typename F>
+inline typename null_guard_return<cond,scope_guard_impl0<F> >::type
+make_guard_if_c(F fun)
+{
+  return typename null_guard_return<cond,scope_guard_impl0<F> >::type(fun);
+}
+
+template<typename C, typename F>
+inline typename null_guard_return<C::value,scope_guard_impl0<F> >::type
+make_guard_if(F fun)
+{
+  return make_guard_if<C::value>(fun);
+}
+
+template<typename F,typename P1>
+class scope_guard_impl1:public scope_guard_impl_base
+{
+public:
+  scope_guard_impl1(F fun,P1 p1):fun_(fun),p1_(p1){}
+  ~scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);}
+  void execute(){fun_(p1_);}
+
+protected:
+  F        fun_;
+  const P1 p1_;
+};
+
+template<typename F,typename P1>
+inline scope_guard_impl1<F,P1> make_guard(F fun,P1 p1)
+{
+  return scope_guard_impl1<F,P1>(fun,p1);
+}
+
+template<bool cond, typename F,typename P1>
+inline typename null_guard_return<cond,scope_guard_impl1<F,P1> >::type
+make_guard_if_c(F fun,P1 p1)
+{
+  return typename null_guard_return<cond,scope_guard_impl1<F,P1> >::type(fun,p1);
+}
+
+template<typename C, typename F,typename P1>
+inline typename null_guard_return<C::value,scope_guard_impl1<F,P1> >::type
+make_guard_if(F fun,P1 p1)
+{
+  return make_guard_if_c<C::value>(fun,p1);
+}
+
+template<typename F,typename P1,typename P2>
+class scope_guard_impl2:public scope_guard_impl_base
+{
+public:
+  scope_guard_impl2(F fun,P1 p1,P2 p2):fun_(fun),p1_(p1),p2_(p2){}
+  ~scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);}
+  void execute(){fun_(p1_,p2_);}
+
+protected:
+  F        fun_;
+  const P1 p1_;
+  const P2 p2_;
+};
+
+template<typename F,typename P1,typename P2>
+inline scope_guard_impl2<F,P1,P2> make_guard(F fun,P1 p1,P2 p2)
+{
+  return scope_guard_impl2<F,P1,P2>(fun,p1,p2);
+}
+
+template<bool cond, typename F,typename P1,typename P2>
+inline typename null_guard_return<cond,scope_guard_impl2<F,P1,P2> >::type
+make_guard_if_c(F fun,P1 p1,P2 p2)
+{
+  return typename null_guard_return<cond,scope_guard_impl2<F,P1,P2> >::type(fun,p1,p2);
+}
+
+template<typename C, typename F,typename P1,typename P2>
+inline typename null_guard_return<C::value,scope_guard_impl2<F,P1,P2> >::type
+make_guard_if(F fun,P1 p1,P2 p2)
+{
+  return make_guard_if_c<C::value>(fun,p1,p2);
+}
+
+template<typename F,typename P1,typename P2,typename P3>
+class scope_guard_impl3:public scope_guard_impl_base
+{
+public:
+  scope_guard_impl3(F fun,P1 p1,P2 p2,P3 p3):fun_(fun),p1_(p1),p2_(p2),p3_(p3){}
+  ~scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);}
+  void execute(){fun_(p1_,p2_,p3_);}
+
+protected:
+  F        fun_;
+  const P1 p1_;
+  const P2 p2_;
+  const P3 p3_;
+};
+
+template<typename F,typename P1,typename P2,typename P3>
+inline scope_guard_impl3<F,P1,P2,P3> make_guard(F fun,P1 p1,P2 p2,P3 p3)
+{
+  return scope_guard_impl3<F,P1,P2,P3>(fun,p1,p2,p3);
+}
+
+template<bool cond,typename F,typename P1,typename P2,typename P3>
+inline typename null_guard_return<cond,scope_guard_impl3<F,P1,P2,P3> >::type
+make_guard_if_c(F fun,P1 p1,P2 p2,P3 p3)
+{
+  return typename null_guard_return<cond,scope_guard_impl3<F,P1,P2,P3> >::type(fun,p1,p2,p3);
+}
+
+template<typename C,typename F,typename P1,typename P2,typename P3>
+inline typename null_guard_return< C::value,scope_guard_impl3<F,P1,P2,P3> >::type
+make_guard_if(F fun,P1 p1,P2 p2,P3 p3)
+{
+  return make_guard_if_c<C::value>(fun,p1,p2,p3);
+}
+
+template<typename F,typename P1,typename P2,typename P3,typename P4>
+class scope_guard_impl4:public scope_guard_impl_base
+{
+public:
+  scope_guard_impl4(F fun,P1 p1,P2 p2,P3 p3,P4 p4):
+    fun_(fun),p1_(p1),p2_(p2),p3_(p3),p4_(p4){}
+  ~scope_guard_impl4(){scope_guard_impl_base::safe_execute(*this);}
+  void execute(){fun_(p1_,p2_,p3_,p4_);}
+
+protected:
+  F        fun_;
+  const P1 p1_;
+  const P2 p2_;
+  const P3 p3_;
+  const P4 p4_;
+};
+
+template<typename F,typename P1,typename P2,typename P3,typename P4>
+inline scope_guard_impl4<F,P1,P2,P3,P4> make_guard(
+  F fun,P1 p1,P2 p2,P3 p3,P4 p4)
+{
+  return scope_guard_impl4<F,P1,P2,P3,P4>(fun,p1,p2,p3,p4);
+}
+
+template<bool cond, typename F,typename P1,typename P2,typename P3,typename P4>
+inline typename null_guard_return<cond,scope_guard_impl4<F,P1,P2,P3,P4> >::type
+make_guard_if_c(
+  F fun,P1 p1,P2 p2,P3 p3,P4 p4)
+{
+  return typename null_guard_return<cond,scope_guard_impl4<F,P1,P2,P3,P4> >::type(fun,p1,p2,p3,p4);
+}
+
+template<typename C, typename F,typename P1,typename P2,typename P3,typename P4>
+inline typename null_guard_return<C::value,scope_guard_impl4<F,P1,P2,P3,P4> >::type
+make_guard_if(
+  F fun,P1 p1,P2 p2,P3 p3,P4 p4)
+{
+  return make_guard_if_c<C::value>(fun,p1,p2,p3,p4);
+}
+
+template<class Obj,typename MemFun>
+class obj_scope_guard_impl0:public scope_guard_impl_base
+{
+public:
+  obj_scope_guard_impl0(Obj& obj,MemFun mem_fun):obj_(obj),mem_fun_(mem_fun){}
+  ~obj_scope_guard_impl0(){scope_guard_impl_base::safe_execute(*this);}
+  void execute(){(obj_.*mem_fun_)();}
+
+protected:
+  Obj&   obj_;
+  MemFun mem_fun_;
+};
+
+template<class Obj,typename MemFun>
+inline obj_scope_guard_impl0<Obj,MemFun> make_obj_guard(Obj& obj,MemFun mem_fun)
+{
+  return obj_scope_guard_impl0<Obj,MemFun>(obj,mem_fun);
+}
+
+template<bool cond, class Obj,typename MemFun>
+inline typename null_guard_return<cond,obj_scope_guard_impl0<Obj,MemFun> >::type
+make_obj_guard_if_c(Obj& obj,MemFun mem_fun)
+{
+  return typename null_guard_return<cond,obj_scope_guard_impl0<Obj,MemFun> >::type(obj,mem_fun);
+}
+
+template<typename C, class Obj,typename MemFun>
+inline typename null_guard_return<C::value,obj_scope_guard_impl0<Obj,MemFun> >::type
+make_obj_guard_if(Obj& obj,MemFun mem_fun)
+{
+  return make_obj_guard_if_c<C::value>(obj,mem_fun);
+}
+
+template<class Obj,typename MemFun,typename P1>
+class obj_scope_guard_impl1:public scope_guard_impl_base
+{
+public:
+  obj_scope_guard_impl1(Obj& obj,MemFun mem_fun,P1 p1):
+    obj_(obj),mem_fun_(mem_fun),p1_(p1){}
+  ~obj_scope_guard_impl1(){scope_guard_impl_base::safe_execute(*this);}
+  void execute(){(obj_.*mem_fun_)(p1_);}
+
+protected:
+  Obj&     obj_;
+  MemFun   mem_fun_;
+  const P1 p1_;
+};
+
+template<class Obj,typename MemFun,typename P1>
+inline obj_scope_guard_impl1<Obj,MemFun,P1> make_obj_guard(
+  Obj& obj,MemFun mem_fun,P1 p1)
+{
+  return obj_scope_guard_impl1<Obj,MemFun,P1>(obj,mem_fun,p1);
+}
+
+template<bool cond, class Obj,typename MemFun,typename P1>
+inline typename null_guard_return<cond,obj_scope_guard_impl1<Obj,MemFun,P1> >::type
+make_obj_guard_if_c(  Obj& obj,MemFun mem_fun,P1 p1)
+{
+  return typename null_guard_return<cond,obj_scope_guard_impl1<Obj,MemFun,P1> >::type(obj,mem_fun,p1);
+}
+
+template<typename C, class Obj,typename MemFun,typename P1>
+inline typename null_guard_return<C::value,obj_scope_guard_impl1<Obj,MemFun,P1> >::type
+make_obj_guard_if( Obj& obj,MemFun mem_fun,P1 p1)
+{
+  return make_obj_guard_if_c<C::value>(obj,mem_fun,p1);
+}
+
+template<class Obj,typename MemFun,typename P1,typename P2>
+class obj_scope_guard_impl2:public scope_guard_impl_base
+{
+public:
+  obj_scope_guard_impl2(Obj& obj,MemFun mem_fun,P1 p1,P2 p2):
+    obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2)
+  {}
+  ~obj_scope_guard_impl2(){scope_guard_impl_base::safe_execute(*this);}
+  void execute(){(obj_.*mem_fun_)(p1_,p2_);}
+
+protected:
+  Obj&     obj_;
+  MemFun   mem_fun_;
+  const P1 p1_;
+  const P2 p2_;
+};
+
+template<class Obj,typename MemFun,typename P1,typename P2>
+inline obj_scope_guard_impl2<Obj,MemFun,P1,P2>
+make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2)
+{
+  return obj_scope_guard_impl2<Obj,MemFun,P1,P2>(obj,mem_fun,p1,p2);
+}
+
+template<bool cond, class Obj,typename MemFun,typename P1,typename P2>
+inline typename null_guard_return<cond,obj_scope_guard_impl2<Obj,MemFun,P1,P2> >::type
+make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2)
+{
+  return typename null_guard_return<cond,obj_scope_guard_impl2<Obj,MemFun,P1,P2> >::type(obj,mem_fun,p1,p2);
+}
+
+template<typename C, class Obj,typename MemFun,typename P1,typename P2>
+inline typename null_guard_return<C::value,obj_scope_guard_impl2<Obj,MemFun,P1,P2> >::type
+make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2)
+{
+  return make_obj_guard_if_c<C::value>(obj,mem_fun,p1,p2);
+}
+
+template<class Obj,typename MemFun,typename P1,typename P2,typename P3>
+class obj_scope_guard_impl3:public scope_guard_impl_base
+{
+public:
+  obj_scope_guard_impl3(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3):
+    obj_(obj),mem_fun_(mem_fun),p1_(p1),p2_(p2),p3_(p3)
+  {}
+  ~obj_scope_guard_impl3(){scope_guard_impl_base::safe_execute(*this);}
+  void execute(){(obj_.*mem_fun_)(p1_,p2_,p3_);}
+
+protected:
+  Obj&     obj_;
+  MemFun   mem_fun_;
+  const P1 p1_;
+  const P2 p2_;
+  const P3 p3_;
+};
+
+template<class Obj,typename MemFun,typename P1,typename P2,typename P3>
+inline obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3>
+make_obj_guard(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3)
+{
+  return obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3>(obj,mem_fun,p1,p2,p3);
+}
+
+template<bool cond, class Obj,typename MemFun,typename P1,typename P2,typename P3>
+inline typename null_guard_return<cond,obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> >::type
+make_obj_guard_if_c(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3)
+{
+  return typename null_guard_return<cond,obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> >::type(obj,mem_fun,p1,p2,p3);
+}
+
+template<typename C, class Obj,typename MemFun,typename P1,typename P2,typename P3>
+inline typename null_guard_return<C::value,obj_scope_guard_impl3<Obj,MemFun,P1,P2,P3> >::type
+make_obj_guard_if(Obj& obj,MemFun mem_fun,P1 p1,P2 p2,P3 p3)
+{
+  return make_obj_guard_if_c<C::value>(obj,mem_fun,p1,p2,p3);
+}
+
+} /* namespace multi_index::detail */
+
+} /* namespace multi_index */
+
+} /* namespace boost */
+
+#endif
diff --git a/third_party/boost/boost/next_prior.hpp b/third_party/boost/boost/next_prior.hpp
new file mode 100644
index 0000000..7854ec4
--- /dev/null
+++ b/third_party/boost/boost/next_prior.hpp
@@ -0,0 +1,165 @@
+//  Boost next_prior.hpp header file  ---------------------------------------//
+
+//  (C) Copyright Dave Abrahams and Daniel Walker 1999-2003. Distributed under the Boost
+//  Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org/libs/utility for documentation.
+
+//  Revision History
+//  13 Dec 2003  Added next(x, n) and prior(x, n) (Daniel Walker)
+
+#ifndef BOOST_NEXT_PRIOR_HPP_INCLUDED
+#define BOOST_NEXT_PRIOR_HPP_INCLUDED
+
+#include <iterator>
+#if defined(_MSC_VER) && _MSC_VER <= 1310
+#include <boost/mpl/and.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#endif
+#include <boost/type_traits/is_unsigned.hpp>
+#include <boost/type_traits/integral_promotion.hpp>
+#include <boost/type_traits/make_signed.hpp>
+#include <boost/type_traits/has_plus.hpp>
+#include <boost/type_traits/has_plus_assign.hpp>
+#include <boost/type_traits/has_minus.hpp>
+#include <boost/type_traits/has_minus_assign.hpp>
+
+namespace boost {
+
+//  Helper functions for classes like bidirectional iterators not supporting
+//  operator+ and operator-
+//
+//  Usage:
+//    const std::list<T>::iterator p = get_some_iterator();
+//    const std::list<T>::iterator prev = boost::prior(p);
+//    const std::list<T>::iterator next = boost::next(prev, 2);
+
+//  Contributed by Dave Abrahams
+
+namespace next_prior_detail {
+
+template< typename T, typename Distance, bool HasPlus = has_plus< T, Distance >::value >
+struct next_impl2
+{
+    static T call(T x, Distance n)
+    {
+        std::advance(x, n);
+        return x;
+    }
+};
+
+template< typename T, typename Distance >
+struct next_impl2< T, Distance, true >
+{
+    static T call(T x, Distance n)
+    {
+        return x + n;
+    }
+};
+
+
+template< typename T, typename Distance, bool HasPlusAssign = has_plus_assign< T, Distance >::value >
+struct next_impl1 :
+    public next_impl2< T, Distance >
+{
+};
+
+template< typename T, typename Distance >
+struct next_impl1< T, Distance, true >
+{
+    static T call(T x, Distance n)
+    {
+        x += n;
+        return x;
+    }
+};
+
+
+template<
+    typename T,
+    typename Distance,
+    typename PromotedDistance = typename integral_promotion< Distance >::type,
+#if !defined(_MSC_VER) || _MSC_VER > 1310
+    bool IsUInt = is_unsigned< PromotedDistance >::value
+#else
+    // MSVC 7.1 has problems with applying is_unsigned to non-integral types
+    bool IsUInt = mpl::and_< is_integral< PromotedDistance >, is_unsigned< PromotedDistance > >::value
+#endif
+>
+struct prior_impl3
+{
+    static T call(T x, Distance n)
+    {
+        std::advance(x, -n);
+        return x;
+    }
+};
+
+template< typename T, typename Distance, typename PromotedDistance >
+struct prior_impl3< T, Distance, PromotedDistance, true >
+{
+    static T call(T x, Distance n)
+    {
+        typedef typename make_signed< PromotedDistance >::type signed_distance;
+        std::advance(x, -static_cast< signed_distance >(static_cast< PromotedDistance >(n)));
+        return x;
+    }
+};
+
+
+template< typename T, typename Distance, bool HasMinus = has_minus< T, Distance >::value >
+struct prior_impl2 :
+    public prior_impl3< T, Distance >
+{
+};
+
+template< typename T, typename Distance >
+struct prior_impl2< T, Distance, true >
+{
+    static T call(T x, Distance n)
+    {
+        return x - n;
+    }
+};
+
+
+template< typename T, typename Distance, bool HasMinusAssign = has_minus_assign< T, Distance >::value >
+struct prior_impl1 :
+    public prior_impl2< T, Distance >
+{
+};
+
+template< typename T, typename Distance >
+struct prior_impl1< T, Distance, true >
+{
+    static T call(T x, Distance n)
+    {
+        x -= n;
+        return x;
+    }
+};
+
+} // namespace next_prior_detail
+
+template <class T>
+inline T next(T x) { return ++x; }
+
+template <class T, class Distance>
+inline T next(T x, Distance n)
+{
+    return next_prior_detail::next_impl1< T, Distance >::call(x, n);
+}
+
+template <class T>
+inline T prior(T x) { return --x; }
+
+template <class T, class Distance>
+inline T prior(T x, Distance n)
+{
+    return next_prior_detail::prior_impl1< T, Distance >::call(x, n);
+}
+
+} // namespace boost
+
+#endif  // BOOST_NEXT_PRIOR_HPP_INCLUDED
diff --git a/third_party/boost/boost/noncopyable.hpp b/third_party/boost/boost/noncopyable.hpp
new file mode 100644
index 0000000..e998ee8
--- /dev/null
+++ b/third_party/boost/boost/noncopyable.hpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2014 Glen Fernandes
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef BOOST_NONCOPYABLE_HPP
+#define BOOST_NONCOPYABLE_HPP
+
+// The header file at this path is deprecated;
+// use boost/core/noncopyable.hpp instead.
+
+#include <boost/core/noncopyable.hpp>
+
+#endif
diff --git a/third_party/boost/boost/none.hpp b/third_party/boost/boost/none.hpp
new file mode 100644
index 0000000..811d4f2
--- /dev/null
+++ b/third_party/boost/boost/none.hpp
@@ -0,0 +1,58 @@
+// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
+// Copyright (C) 2014 Andrzej Krzemienski.
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/optional for documentation.
+//
+// You are welcome to contact the author at:
+//  fernando_cacciola@hotmail.com
+//
+#ifndef BOOST_NONE_17SEP2003_HPP
+#define BOOST_NONE_17SEP2003_HPP
+
+#include "boost/none_t.hpp"
+
+// NOTE: Borland users have to include this header outside any precompiled headers
+// (bcc<=5.64 cannot include instance data in a precompiled header)
+//  -- * To be verified, now that there's no unnamed namespace
+
+namespace boost {
+
+#ifdef BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE
+
+none_t const none = (static_cast<none_t>(0)) ;
+
+#elif defined BOOST_OPTIONAL_USE_SINGLETON_DEFINITION_OF_NONE
+
+namespace detail { namespace optional_detail {
+
+  // the trick here is to make boost::none defined once as a global but in a header file
+  template <typename T>
+  struct none_instance
+  {
+    static const T instance;
+  };
+
+  template <typename T>
+  const T none_instance<T>::instance = T(); // global, but because 'tis a template, no cpp file required
+
+} } // namespace detail::optional_detail
+
+
+namespace {
+  // TU-local
+  const none_t& none = detail::optional_detail::none_instance<none_t>::instance;
+}
+
+#else
+
+const none_t none ((none_t::init_tag()));
+
+#endif // older definitions
+
+} // namespace boost
+
+#endif // header guard
diff --git a/third_party/boost/boost/none_t.hpp b/third_party/boost/boost/none_t.hpp
new file mode 100644
index 0000000..bc691ee
--- /dev/null
+++ b/third_party/boost/boost/none_t.hpp
@@ -0,0 +1,39 @@
+// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
+// Copyright (C) 2014 Andrzej Krzemienski.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/optional for documentation.
+//
+// You are welcome to contact the author at:
+//  fernando_cacciola@hotmail.com
+//
+#ifndef BOOST_NONE_T_17SEP2003_HPP
+#define BOOST_NONE_T_17SEP2003_HPP
+
+namespace boost {
+
+#ifdef BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE
+
+namespace detail { struct none_helper{}; }
+typedef int detail::none_helper::*none_t ;
+
+#elif defined BOOST_OPTIONAL_USE_SINGLETON_DEFINITION_OF_NONE
+
+class none_t {};
+
+#else
+
+struct none_t
+{
+  struct init_tag{};
+  explicit none_t(init_tag){} // to prevent default constructor
+};
+
+#endif // old implementation workarounds
+
+} // namespace boost
+
+#endif // header guard
diff --git a/third_party/boost/boost/optional.hpp b/third_party/boost/boost/optional.hpp
new file mode 100644
index 0000000..7a8b86f
--- /dev/null
+++ b/third_party/boost/boost/optional.hpp
@@ -0,0 +1,17 @@
+// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/optional for documentation.
+//
+// You are welcome to contact the author at:
+//  fernando_cacciola@hotmail.com
+//
+#ifndef BOOST_OPTIONAL_FLC_19NOV2002_HPP
+#define BOOST_OPTIONAL_FLC_19NOV2002_HPP
+
+#include "boost/optional/optional.hpp"
+
+#endif
diff --git a/third_party/boost/boost/optional/bad_optional_access.hpp b/third_party/boost/boost/optional/bad_optional_access.hpp
new file mode 100644
index 0000000..cabf43f
--- /dev/null
+++ b/third_party/boost/boost/optional/bad_optional_access.hpp
@@ -0,0 +1,32 @@
+// Copyright (C) 2014, Andrzej Krzemienski.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/optional for documentation.
+//
+// You are welcome to contact the author at:
+//  akrzemi1@gmail.com
+//
+#ifndef BOOST_BAD_OPTIONAL_ACCESS_22MAY2014_HPP
+#define BOOST_BAD_OPTIONAL_ACCESS_22MAY2014_HPP
+
+#include <stdexcept>
+#if __cplusplus < 201103L
+#include <string> // to make converting-ctor std::string(char const*) visible
+#endif
+
+namespace boost {
+
+class bad_optional_access : public std::logic_error
+{
+public:
+  bad_optional_access()
+    : std::logic_error("Attempted to access the value of an uninitialized optional object.")
+    {}
+};
+
+} // namespace boost
+
+#endif
diff --git a/third_party/boost/boost/optional/optional.hpp b/third_party/boost/boost/optional/optional.hpp
new file mode 100644
index 0000000..8b0a9a6
--- /dev/null
+++ b/third_party/boost/boost/optional/optional.hpp
@@ -0,0 +1,1567 @@
+// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
+// Copyright (C) 2014, 2015 Andrzej Krzemienski.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/optional for documentation.
+//
+// You are welcome to contact the author at:
+//  fernando_cacciola@hotmail.com
+//
+// Revisions:
+// 27 Apr 2008 (improved swap) Fernando Cacciola, Niels Dekker, Thorsten Ottosen
+// 05 May 2014 (Added move semantics) Andrzej Krzemienski
+//
+#ifndef BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
+#define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
+
+#include <new>
+#include <iosfwd>
+
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+#include <boost/core/addressof.hpp>
+#include <boost/core/enable_if.hpp>
+#include <boost/core/explicit_operator_bool.hpp>
+#include <boost/core/swap.hpp>
+#include <boost/optional/bad_optional_access.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/type.hpp>
+#include <boost/type_traits/alignment_of.hpp>
+#include <boost/type_traits/has_nothrow_constructor.hpp>
+#include <boost/type_traits/type_with_alignment.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/decay.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+#include <boost/type_traits/is_lvalue_reference.hpp>
+#include <boost/type_traits/is_nothrow_move_assignable.hpp>
+#include <boost/type_traits/is_nothrow_move_constructible.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/is_rvalue_reference.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/detail/reference_content.hpp>
+#include <boost/move/utility.hpp>
+#include <boost/none.hpp>
+#include <boost/utility/compare_pointees.hpp>
+
+#include <boost/optional/optional_fwd.hpp>
+
+#if (defined BOOST_NO_CXX11_RVALUE_REFERENCES) || (defined BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES)
+#define BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+#endif
+
+#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION,<=700)
+// AFAICT only Intel 7 correctly resolves the overload set
+// that includes the in-place factory taking functions,
+// so for the other icc versions, in-place factory support
+// is disabled
+#define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+#endif
+
+#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551)
+// BCB (5.5.1) cannot parse the nested template struct in an inplace factory.
+#define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+#endif
+
+#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) \
+    && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581) )
+// BCB (up to 5.64) has the following bug:
+//   If there is a member function/operator template of the form
+//     template<class Expr> mfunc( Expr expr ) ;
+//   some calls are resolved to this even if there are other better matches.
+//   The effect of this bug is that calls to converting ctors and assignments
+//   are incrorrectly sink to this general catch-all member function template as shown above.
+#define BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
+#endif
+
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+// GCC since 3.3 has may_alias attribute that helps to alleviate optimizer issues with
+// regard to violation of the strict aliasing rules. The optional< T > storage type is marked
+// with this attribute in order to let the compiler know that it will alias objects of type T
+// and silence compilation warnings.
+#define BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS
+#endif
+
+// Daniel Wallin discovered that bind/apply.hpp badly interacts with the apply<>
+// member template of a factory as used in the optional<> implementation.
+// He proposed this simple fix which is to move the call to apply<> outside
+// namespace boost.
+namespace boost_optional_detail
+{
+  template <class T, class Factory>
+  inline void construct(Factory const& factory, void* address)
+  {
+    factory.BOOST_NESTED_TEMPLATE apply<T>(address);
+  }
+}
+
+
+namespace boost {
+
+class in_place_factory_base ;
+class typed_in_place_factory_base ;
+
+// This forward is needed to refer to namespace scope swap from the member swap
+template<class T> void swap ( optional<T>& x, optional<T>& y );
+
+namespace optional_detail {
+// This local class is used instead of that in "aligned_storage.hpp"
+// because I've found the 'official' class to ICE BCB5.5
+// when some types are used with optional<>
+// (due to sizeof() passed down as a non-type template parameter)
+template <class T>
+class aligned_storage
+{
+    // Borland ICEs if unnamed unions are used for this!
+    union
+    // This works around GCC warnings about breaking strict aliasing rules when casting storage address to T*
+#if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS)
+    __attribute__((__may_alias__))
+#endif
+    dummy_u
+    {
+        char data[ sizeof(T) ];
+        BOOST_DEDUCED_TYPENAME type_with_alignment<
+          ::boost::alignment_of<T>::value >::type aligner_;
+    } dummy_ ;
+
+  public:
+
+#if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS)
+    void const* address() const { return &dummy_; }
+    void      * address()       { return &dummy_; }
+#else
+    void const* address() const { return dummy_.data; }
+    void      * address()       { return dummy_.data; }
+#endif
+} ;
+
+template<class T>
+struct types_when_isnt_ref
+{
+  typedef T const& reference_const_type ;
+  typedef T &      reference_type ;
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+  typedef T &&     rval_reference_type ;
+  typedef T &&     reference_type_of_temporary_wrapper;
+#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
+  // GCC 4.4 has support for an early draft of rvalue references. The conforming version below
+  // causes warnings about returning references to a temporary.
+  static T&& move(T&& r) { return r; }
+#else
+  static rval_reference_type move(reference_type r) { return boost::move(r); }
+#endif
+#endif
+  typedef T const* pointer_const_type ;
+  typedef T *      pointer_type ;
+  typedef T const& argument_type ;
+} ;
+
+template<class T>
+struct types_when_is_ref
+{
+  typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type raw_type ;
+
+  typedef raw_type&  reference_const_type ;
+  typedef raw_type&  reference_type ;
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+  typedef BOOST_DEDUCED_TYPENAME remove_const<raw_type>::type&& rval_reference_type ;
+  typedef raw_type&  reference_type_of_temporary_wrapper;
+  static reference_type move(reference_type r) { return r; }
+#endif
+  typedef raw_type*  pointer_const_type ;
+  typedef raw_type*  pointer_type ;
+  typedef raw_type&  argument_type ;
+} ;
+
+template <class To, class From>
+void prevent_binding_rvalue_ref_to_optional_lvalue_ref()
+{
+#ifndef BOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES
+  BOOST_STATIC_ASSERT_MSG(
+    !boost::is_lvalue_reference<To>::value || !boost::is_rvalue_reference<From>::value,
+    "binding rvalue references to optional lvalue references is disallowed");
+#endif
+}
+
+struct optional_tag {} ;
+
+template<class T>
+class optional_base : public optional_tag
+{
+  private :
+
+    typedef
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+    BOOST_DEDUCED_TYPENAME
+#endif
+    ::boost::detail::make_reference_content<T>::type internal_type ;
+
+    typedef aligned_storage<internal_type> storage_type ;
+
+    typedef types_when_isnt_ref<T> types_when_not_ref ;
+    typedef types_when_is_ref<T>   types_when_ref   ;
+
+    typedef optional_base<T> this_type ;
+
+  protected :
+
+    typedef T value_type ;
+
+    typedef mpl::true_  is_reference_tag ;
+    typedef mpl::false_ is_not_reference_tag ;
+
+    typedef BOOST_DEDUCED_TYPENAME is_reference<T>::type is_reference_predicate ;
+
+  public:
+    typedef BOOST_DEDUCED_TYPENAME mpl::if_<is_reference_predicate,types_when_ref,types_when_not_ref>::type types ;
+
+  protected:
+    typedef BOOST_DEDUCED_TYPENAME types::reference_type       reference_type ;
+    typedef BOOST_DEDUCED_TYPENAME types::reference_const_type reference_const_type ;
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    typedef BOOST_DEDUCED_TYPENAME types::rval_reference_type  rval_reference_type ;
+    typedef BOOST_DEDUCED_TYPENAME types::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
+#endif
+    typedef BOOST_DEDUCED_TYPENAME types::pointer_type         pointer_type ;
+    typedef BOOST_DEDUCED_TYPENAME types::pointer_const_type   pointer_const_type ;
+    typedef BOOST_DEDUCED_TYPENAME types::argument_type        argument_type ;
+
+    // Creates an optional<T> uninitialized.
+    // No-throw
+    optional_base()
+      :
+      m_initialized(false) {}
+
+    // Creates an optional<T> uninitialized.
+    // No-throw
+    optional_base ( none_t )
+      :
+      m_initialized(false) {}
+
+    // Creates an optional<T> initialized with 'val'.
+    // Can throw if T::T(T const&) does
+    optional_base ( argument_type val )
+      :
+      m_initialized(false)
+    {
+      construct(val);
+    }
+
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    // move-construct an optional<T> initialized from an rvalue-ref to 'val'.
+    // Can throw if T::T(T&&) does
+    optional_base ( rval_reference_type val )
+      :
+      m_initialized(false)
+    {
+      construct( boost::move(val) );
+    }
+#endif
+
+    // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialzed optional<T>.
+    // Can throw if T::T(T const&) does
+    optional_base ( bool cond, argument_type val )
+      :
+      m_initialized(false)
+    {
+      if ( cond )
+        construct(val);
+    }
+
+    // Creates a deep copy of another optional<T>
+    // Can throw if T::T(T const&) does
+    optional_base ( optional_base const& rhs )
+      :
+      m_initialized(false)
+    {
+      if ( rhs.is_initialized() )
+        construct(rhs.get_impl());
+    }
+
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    // Creates a deep move of another optional<T>
+    // Can throw if T::T(T&&) does
+    optional_base ( optional_base&& rhs )
+      :
+      m_initialized(false)
+    {
+      if ( rhs.is_initialized() )
+        construct( boost::move(rhs.get_impl()) );
+    }
+#endif
+
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+
+    template<class Expr, class PtrExpr>
+    explicit optional_base ( Expr&& expr, PtrExpr const* tag )
+      :
+      m_initialized(false)
+    {
+      construct(boost::forward<Expr>(expr),tag);
+    }
+
+#else
+    // This is used for both converting and in-place constructions.
+    // Derived classes use the 'tag' to select the appropriate
+    // implementation (the correct 'construct()' overload)
+    template<class Expr>
+    explicit optional_base ( Expr const& expr, Expr const* tag )
+      :
+      m_initialized(false)
+    {
+      construct(expr,tag);
+    }
+
+#endif
+
+
+    // No-throw (assuming T::~T() doesn't)
+    ~optional_base() { destroy() ; }
+
+    // Assigns from another optional<T> (deep-copies the rhs value)
+    void assign ( optional_base const& rhs )
+    {
+      if (is_initialized())
+      {
+        if ( rhs.is_initialized() )
+             assign_value(rhs.get_impl(), is_reference_predicate() );
+        else destroy();
+      }
+      else
+      {
+        if ( rhs.is_initialized() )
+          construct(rhs.get_impl());
+      }
+    }
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    // Assigns from another optional<T> (deep-moves the rhs value)
+    void assign ( optional_base&& rhs )
+    {
+      if (is_initialized())
+      {
+        if ( rhs.is_initialized() )
+             assign_value(boost::move(rhs.get_impl()), is_reference_predicate() );
+        else destroy();
+      }
+      else
+      {
+        if ( rhs.is_initialized() )
+          construct(boost::move(rhs.get_impl()));
+      }
+    }
+#endif
+
+    // Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
+    template<class U>
+    void assign ( optional<U> const& rhs )
+    {
+      if (is_initialized())
+      {
+        if ( rhs.is_initialized() )
+#ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
+          assign_value(rhs.get(), is_reference_predicate() );
+#else
+          assign_value(static_cast<value_type>(rhs.get()), is_reference_predicate() );
+#endif
+
+        else destroy();
+      }
+      else
+      {
+        if ( rhs.is_initialized() )
+#ifndef BOOST_OPTIONAL_CONFIG_RESTORE_ASSIGNMENT_OF_NONCONVERTIBLE_TYPES
+          construct(rhs.get());
+#else
+          construct(static_cast<value_type>(rhs.get()));
+#endif
+      }
+    }
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    // move-assigns from another _convertible_ optional<U> (deep-moves from the rhs value)
+    template<class U>
+    void assign ( optional<U>&& rhs )
+    {
+      typedef BOOST_DEDUCED_TYPENAME optional<U>::rval_reference_type ref_type;
+      if (is_initialized())
+      {
+        if ( rhs.is_initialized() )
+             assign_value(static_cast<ref_type>(rhs.get()), is_reference_predicate() );
+        else destroy();
+      }
+      else
+      {
+        if ( rhs.is_initialized() )
+          construct(static_cast<ref_type>(rhs.get()));
+      }
+    }
+#endif
+
+    // Assigns from a T (deep-copies the rhs value)
+    void assign ( argument_type val )
+    {
+      if (is_initialized())
+           assign_value(val, is_reference_predicate() );
+      else construct(val);
+    }
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    // Assigns from a T (deep-moves the rhs value)
+    void assign ( rval_reference_type val )
+    {
+      if (is_initialized())
+           assign_value( boost::move(val), is_reference_predicate() );
+      else construct( boost::move(val) );
+    }
+#endif
+
+    // Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED
+    // No-throw (assuming T::~T() doesn't)
+    void assign ( none_t ) BOOST_NOEXCEPT { destroy(); }
+
+#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    template<class Expr, class ExprPtr>
+    void assign_expr ( Expr&& expr, ExprPtr const* tag )
+    {
+      if (is_initialized())
+        assign_expr_to_initialized(boost::forward<Expr>(expr),tag);
+      else construct(boost::forward<Expr>(expr),tag);
+    }
+#else
+    template<class Expr>
+    void assign_expr ( Expr const& expr, Expr const* tag )
+    {
+      if (is_initialized())
+        assign_expr_to_initialized(expr,tag);
+      else construct(expr,tag);
+    }
+#endif
+
+#endif
+
+  public :
+
+    // **DEPPRECATED** Destroys the current value, if any, leaving this UNINITIALIZED
+    // No-throw (assuming T::~T() doesn't)
+    void reset() BOOST_NOEXCEPT { destroy(); }
+
+    // **DEPPRECATED** Replaces the current value -if any- with 'val'
+    void reset ( argument_type val ) { assign(val); }
+
+    // Returns a pointer to the value if this is initialized, otherwise,
+    // returns NULL.
+    // No-throw
+    pointer_const_type get_ptr() const { return m_initialized ? get_ptr_impl() : 0 ; }
+    pointer_type       get_ptr()       { return m_initialized ? get_ptr_impl() : 0 ; }
+
+    bool is_initialized() const { return m_initialized ; }
+
+  protected :
+
+    void construct ( argument_type val )
+     {
+       ::new (m_storage.address()) internal_type(val) ;
+       m_initialized = true ;
+     }
+
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    void construct ( rval_reference_type val )
+     {
+       ::new (m_storage.address()) internal_type( types::move(val) ) ;
+       m_initialized = true ;
+     }
+#endif
+
+
+#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+    // Constructs in-place
+    // upon exception *this is always uninitialized
+    template<class... Args>
+    void emplace_assign ( Args&&... args )
+     {
+       destroy();
+       ::new (m_storage.address()) internal_type( boost::forward<Args>(args)... );
+       m_initialized = true ;
+     }
+#elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
+    template<class Arg>
+    void emplace_assign ( Arg&& arg )
+     {
+       destroy();
+       ::new (m_storage.address()) internal_type( boost::forward<Arg>(arg) );
+       m_initialized = true ;
+     }
+
+    void emplace_assign ()
+     {
+       destroy();
+       ::new (m_storage.address()) internal_type();
+       m_initialized = true ;
+     }
+#else
+    template<class Arg>
+    void emplace_assign ( const Arg& arg )
+     {
+       destroy();
+       ::new (m_storage.address()) internal_type( arg );
+       m_initialized = true ;
+     }
+
+    template<class Arg>
+    void emplace_assign ( Arg& arg )
+     {
+       destroy();
+       ::new (m_storage.address()) internal_type( arg );
+       m_initialized = true ;
+     }
+
+    void emplace_assign ()
+     {
+       destroy();
+       ::new (m_storage.address()) internal_type();
+       m_initialized = true ;
+     }
+#endif
+
+#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    // Constructs in-place using the given factory
+    template<class Expr>
+    void construct ( Expr&& factory, in_place_factory_base const* )
+     {
+       BOOST_STATIC_ASSERT ( ::boost::mpl::not_<is_reference_predicate>::value ) ;
+       boost_optional_detail::construct<value_type>(factory, m_storage.address());
+       m_initialized = true ;
+     }
+
+    // Constructs in-place using the given typed factory
+    template<class Expr>
+    void construct ( Expr&& factory, typed_in_place_factory_base const* )
+     {
+       BOOST_STATIC_ASSERT ( ::boost::mpl::not_<is_reference_predicate>::value ) ;
+       factory.apply(m_storage.address()) ;
+       m_initialized = true ;
+     }
+
+    template<class Expr>
+    void assign_expr_to_initialized ( Expr&& factory, in_place_factory_base const* tag )
+     {
+       destroy();
+       construct(factory,tag);
+     }
+
+    // Constructs in-place using the given typed factory
+    template<class Expr>
+    void assign_expr_to_initialized ( Expr&& factory, typed_in_place_factory_base const* tag )
+     {
+       destroy();
+       construct(factory,tag);
+     }
+
+#else
+    // Constructs in-place using the given factory
+    template<class Expr>
+    void construct ( Expr const& factory, in_place_factory_base const* )
+     {
+       BOOST_STATIC_ASSERT ( ::boost::mpl::not_<is_reference_predicate>::value ) ;
+       boost_optional_detail::construct<value_type>(factory, m_storage.address());
+       m_initialized = true ;
+     }
+
+    // Constructs in-place using the given typed factory
+    template<class Expr>
+    void construct ( Expr const& factory, typed_in_place_factory_base const* )
+     {
+       BOOST_STATIC_ASSERT ( ::boost::mpl::not_<is_reference_predicate>::value ) ;
+       factory.apply(m_storage.address()) ;
+       m_initialized = true ;
+     }
+
+    template<class Expr>
+    void assign_expr_to_initialized ( Expr const& factory, in_place_factory_base const* tag )
+     {
+       destroy();
+       construct(factory,tag);
+     }
+
+    // Constructs in-place using the given typed factory
+    template<class Expr>
+    void assign_expr_to_initialized ( Expr const& factory, typed_in_place_factory_base const* tag )
+     {
+       destroy();
+       construct(factory,tag);
+     }
+#endif
+
+#endif
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    // Constructs using any expression implicitly convertible to the single argument
+    // of a one-argument T constructor.
+    // Converting constructions of optional<T> from optional<U> uses this function with
+    // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
+    template<class Expr>
+    void construct ( Expr&& expr, void const* )
+    {
+      new (m_storage.address()) internal_type(boost::forward<Expr>(expr)) ;
+      m_initialized = true ;
+    }
+
+    // Assigns using a form any expression implicitly convertible to the single argument
+    // of a T's assignment operator.
+    // Converting assignments of optional<T> from optional<U> uses this function with
+    // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
+    template<class Expr>
+    void assign_expr_to_initialized ( Expr&& expr, void const* )
+    {
+      assign_value(boost::forward<Expr>(expr), is_reference_predicate());
+    }
+#else
+    // Constructs using any expression implicitly convertible to the single argument
+    // of a one-argument T constructor.
+    // Converting constructions of optional<T> from optional<U> uses this function with
+    // 'Expr' being of type 'U' and relying on a converting constructor of T from U.
+    template<class Expr>
+    void construct ( Expr const& expr, void const* )
+     {
+       new (m_storage.address()) internal_type(expr) ;
+       m_initialized = true ;
+     }
+
+    // Assigns using a form any expression implicitly convertible to the single argument
+    // of a T's assignment operator.
+    // Converting assignments of optional<T> from optional<U> uses this function with
+    // 'Expr' being of type 'U' and relying on a converting assignment of T from U.
+    template<class Expr>
+    void assign_expr_to_initialized ( Expr const& expr, void const* )
+     {
+       assign_value(expr, is_reference_predicate());
+     }
+
+#endif
+
+#ifdef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
+    // BCB5.64 (and probably lower versions) workaround.
+    //   The in-place factories are supported by means of catch-all constructors
+    //   and assignment operators (the functions are parameterized in terms of
+    //   an arbitrary 'Expr' type)
+    //   This compiler incorrectly resolves the overload set and sinks optional<T> and optional<U>
+    //   to the 'Expr'-taking functions even though explicit overloads are present for them.
+    //   Thus, the following overload is needed to properly handle the case when the 'lhs'
+    //   is another optional.
+    //
+    // For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error
+    // instead of choosing the wrong overload
+    //
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    // Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
+    template<class Expr>
+    void construct ( Expr&& expr, optional_tag const* )
+     {
+       if ( expr.is_initialized() )
+       {
+         // An exception can be thrown here.
+         // It it happens, THIS will be left uninitialized.
+         new (m_storage.address()) internal_type(types::move(expr.get())) ;
+         m_initialized = true ;
+       }
+     }
+#else
+    // Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
+    template<class Expr>
+    void construct ( Expr const& expr, optional_tag const* )
+     {
+       if ( expr.is_initialized() )
+       {
+         // An exception can be thrown here.
+         // It it happens, THIS will be left uninitialized.
+         new (m_storage.address()) internal_type(expr.get()) ;
+         m_initialized = true ;
+       }
+     }
+#endif
+#endif // defined BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
+
+    void assign_value ( argument_type val, is_not_reference_tag ) { get_impl() = val; }
+    void assign_value ( argument_type val, is_reference_tag     ) { construct(val); }
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    void assign_value ( rval_reference_type val, is_not_reference_tag ) { get_impl() = static_cast<rval_reference_type>(val); }
+    void assign_value ( rval_reference_type val, is_reference_tag     ) { construct( static_cast<rval_reference_type>(val) ); }
+#endif
+
+    void destroy()
+    {
+      if ( m_initialized )
+        destroy_impl(is_reference_predicate()) ;
+    }
+
+    reference_const_type get_impl() const { return dereference(get_object(), is_reference_predicate() ) ; }
+    reference_type       get_impl()       { return dereference(get_object(), is_reference_predicate() ) ; }
+
+    pointer_const_type get_ptr_impl() const { return cast_ptr(get_object(), is_reference_predicate() ) ; }
+    pointer_type       get_ptr_impl()       { return cast_ptr(get_object(), is_reference_predicate() ) ; }
+
+  private :
+
+    // internal_type can be either T or reference_content<T>
+#if defined(BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS)
+    // This workaround is supposed to silence GCC warnings about broken strict aliasing rules
+    internal_type const* get_object() const
+    {
+        union { void const* ap_pvoid; internal_type const* as_ptype; } caster = { m_storage.address() };
+        return caster.as_ptype;
+    }
+    internal_type *      get_object()
+    {
+        union { void* ap_pvoid; internal_type* as_ptype; } caster = { m_storage.address() };
+        return caster.as_ptype;
+    }
+#else
+    internal_type const* get_object() const { return static_cast<internal_type const*>(m_storage.address()); }
+    internal_type *      get_object()       { return static_cast<internal_type *>     (m_storage.address()); }
+#endif
+
+    // reference_content<T> lacks an implicit conversion to T&, so the following is needed to obtain a proper reference.
+    reference_const_type dereference( internal_type const* p, is_not_reference_tag ) const { return *p ; }
+    reference_type       dereference( internal_type*       p, is_not_reference_tag )       { return *p ; }
+    reference_const_type dereference( internal_type const* p, is_reference_tag     ) const { return p->get() ; }
+    reference_type       dereference( internal_type*       p, is_reference_tag     )       { return p->get() ; }
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))
+    void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->internal_type::~internal_type() ; m_initialized = false ; }
+#else
+    void destroy_impl ( is_not_reference_tag ) { get_ptr_impl()->~T() ; m_initialized = false ; }
+#endif
+
+    void destroy_impl ( is_reference_tag     ) { m_initialized = false ; }
+
+    // If T is of reference type, trying to get a pointer to the held value must result in a compile-time error.
+    // Decent compilers should disallow conversions from reference_content<T>* to T*, but just in case,
+    // the following olverloads are used to filter out the case and guarantee an error in case of T being a reference.
+    pointer_const_type cast_ptr( internal_type const* p, is_not_reference_tag ) const { return p ; }
+    pointer_type       cast_ptr( internal_type *      p, is_not_reference_tag )       { return p ; }
+    pointer_const_type cast_ptr( internal_type const* p, is_reference_tag     ) const { return &p->get() ; }
+    pointer_type       cast_ptr( internal_type *      p, is_reference_tag     )       { return &p->get() ; }
+
+    bool m_initialized ;
+    storage_type m_storage ;
+} ;
+
+} // namespace optional_detail
+
+template<class T>
+class optional : public optional_detail::optional_base<T>
+{
+    typedef optional_detail::optional_base<T> base ;
+
+  public :
+
+    typedef optional<T> this_type ;
+
+    typedef BOOST_DEDUCED_TYPENAME base::value_type           value_type ;
+    typedef BOOST_DEDUCED_TYPENAME base::reference_type       reference_type ;
+    typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ;
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    typedef BOOST_DEDUCED_TYPENAME base::rval_reference_type  rval_reference_type ;
+    typedef BOOST_DEDUCED_TYPENAME base::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
+#endif
+    typedef BOOST_DEDUCED_TYPENAME base::pointer_type         pointer_type ;
+    typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type   pointer_const_type ;
+    typedef BOOST_DEDUCED_TYPENAME base::argument_type        argument_type ;
+
+    // Creates an optional<T> uninitialized.
+    // No-throw
+    optional() BOOST_NOEXCEPT : base() {}
+
+    // Creates an optional<T> uninitialized.
+    // No-throw
+    optional( none_t none_ ) BOOST_NOEXCEPT : base(none_) {}
+
+    // Creates an optional<T> initialized with 'val'.
+    // Can throw if T::T(T const&) does
+    optional ( argument_type val ) : base(val) {}
+
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    // Creates an optional<T> initialized with 'move(val)'.
+    // Can throw if T::T(T &&) does
+    optional ( rval_reference_type val ) : base( boost::forward<T>(val) )
+      {optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, rval_reference_type>();}
+#endif
+
+    // Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional.
+    // Can throw if T::T(T const&) does
+    optional ( bool cond, argument_type val ) : base(cond,val) {}
+
+    // NOTE: MSVC needs templated versions first
+
+    // Creates a deep copy of another convertible optional<U>
+    // Requires a valid conversion from U to T.
+    // Can throw if T::T(U const&) does
+    template<class U>
+    explicit optional ( optional<U> const& rhs )
+      :
+      base()
+    {
+      if ( rhs.is_initialized() )
+        this->construct(rhs.get());
+    }
+
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    // Creates a deep move of another convertible optional<U>
+    // Requires a valid conversion from U to T.
+    // Can throw if T::T(U&&) does
+    template<class U>
+    explicit optional ( optional<U> && rhs )
+      :
+      base()
+    {
+      if ( rhs.is_initialized() )
+        this->construct( boost::move(rhs.get()) );
+    }
+#endif
+
+#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+    // Creates an optional<T> with an expression which can be either
+    //  (a) An instance of InPlaceFactory (i.e. in_place(a,b,...,n);
+    //  (b) An instance of TypedInPlaceFactory ( i.e. in_place<T>(a,b,...,n);
+    //  (c) Any expression implicitly convertible to the single type
+    //      of a one-argument T's constructor.
+    //  (d*) Weak compilers (BCB) might also resolved Expr as optional<T> and optional<U>
+    //       even though explicit overloads are present for these.
+    // Depending on the above some T ctor is called.
+    // Can throw if the resolved T ctor throws.
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+
+
+  template<class Expr>
+  explicit optional ( Expr&& expr,
+                      BOOST_DEDUCED_TYPENAME boost::disable_if_c<
+                        (boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type>::value) ||
+                        boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type, none_t>::value >::type* = 0
+  )
+    : base(boost::forward<Expr>(expr),boost::addressof(expr))
+    {optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, Expr&&>();}
+
+#else
+    template<class Expr>
+    explicit optional ( Expr const& expr ) : base(expr,boost::addressof(expr)) {}
+#endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+#endif // !defined BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+
+    // Creates a deep copy of another optional<T>
+    // Can throw if T::T(T const&) does
+    optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {}
+
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+	// Creates a deep move of another optional<T>
+	// Can throw if T::T(T&&) does
+	optional ( optional && rhs )
+	  BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value)
+	  : base( boost::move(rhs) )
+	{}
+
+#endif
+   // No-throw (assuming T::~T() doesn't)
+    ~optional() {}
+
+#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
+    // Assigns from an expression. See corresponding constructor.
+    // Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+
+    template<class Expr>
+    BOOST_DEDUCED_TYPENAME boost::disable_if_c<
+      boost::is_base_of<optional_detail::optional_tag, BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type>::value ||
+        boost::is_same<BOOST_DEDUCED_TYPENAME boost::decay<Expr>::type, none_t>::value,
+      optional&
+    >::type
+    operator= ( Expr&& expr )
+      {
+        optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, Expr&&>();
+        this->assign_expr(boost::forward<Expr>(expr),boost::addressof(expr));
+        return *this ;
+      }
+
+#else
+    template<class Expr>
+    optional& operator= ( Expr const& expr )
+      {
+        this->assign_expr(expr,boost::addressof(expr));
+        return *this ;
+      }
+#endif // !defined  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+#endif // !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
+
+    // Copy-assigns from another convertible optional<U> (converts && deep-copies the rhs value)
+    // Requires a valid conversion from U to T.
+    // Basic Guarantee: If T::T( U const& ) throws, this is left UNINITIALIZED
+    template<class U>
+    optional& operator= ( optional<U> const& rhs )
+      {
+        this->assign(rhs);
+        return *this ;
+      }
+
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    // Move-assigns from another convertible optional<U> (converts && deep-moves the rhs value)
+    // Requires a valid conversion from U to T.
+    // Basic Guarantee: If T::T( U && ) throws, this is left UNINITIALIZED
+    template<class U>
+    optional& operator= ( optional<U> && rhs )
+      {
+        this->assign(boost::move(rhs));
+        return *this ;
+      }
+#endif
+
+    // Assigns from another optional<T> (deep-copies the rhs value)
+    // Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED
+    //  (NOTE: On BCB, this operator is not actually called and left is left UNMODIFIED in case of a throw)
+    optional& operator= ( optional const& rhs )
+      {
+        this->assign( static_cast<base const&>(rhs) ) ;
+        return *this ;
+      }
+
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    // Assigns from another optional<T> (deep-moves the rhs value)
+    optional& operator= ( optional && rhs )
+	  BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
+      {
+        this->assign( static_cast<base &&>(rhs) ) ;
+        return *this ;
+      }
+#endif
+
+    // Assigns from a T (deep-copies the rhs value)
+    // Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED
+    optional& operator= ( argument_type val )
+      {
+        this->assign( val ) ;
+        return *this ;
+      }
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    // Assigns from a T (deep-moves the rhs value)
+    optional& operator= ( rval_reference_type val )
+      {
+        optional_detail::prevent_binding_rvalue_ref_to_optional_lvalue_ref<T, rval_reference_type>();
+        this->assign( boost::move(val) ) ;
+        return *this ;
+      }
+#endif
+
+    // Assigns from a "none"
+    // Which destroys the current value, if any, leaving this UNINITIALIZED
+    // No-throw (assuming T::~T() doesn't)
+    optional& operator= ( none_t none_ ) BOOST_NOEXCEPT
+      {
+        this->assign( none_ ) ;
+        return *this ;
+      }
+
+#if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+    // Constructs in-place
+    // upon exception *this is always uninitialized
+    template<class... Args>
+    void emplace ( Args&&... args )
+     {
+       this->emplace_assign( boost::forward<Args>(args)... );
+     }
+#elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
+    template<class Arg>
+    void emplace ( Arg&& arg )
+     {
+       this->emplace_assign( boost::forward<Arg>(arg) );
+     }
+
+    void emplace ()
+     {
+       this->emplace_assign();
+     }
+#else
+    template<class Arg>
+    void emplace ( const Arg& arg )
+     {
+       this->emplace_assign( arg );
+     }
+
+    template<class Arg>
+    void emplace ( Arg& arg )
+     {
+       this->emplace_assign( arg );
+     }
+
+    void emplace ()
+     {
+       this->emplace_assign();
+     }
+#endif
+
+    void swap( optional & arg )
+	  BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
+      {
+        // allow for Koenig lookup
+        boost::swap(*this, arg);
+      }
+
+
+    // Returns a reference to the value if this is initialized, otherwise,
+    // the behaviour is UNDEFINED
+    // No-throw
+    reference_const_type get() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
+    reference_type       get()       { BOOST_ASSERT(this->is_initialized()) ; return this->get_impl(); }
+
+    // Returns a copy of the value if this is initialized, 'v' otherwise
+    reference_const_type get_value_or ( reference_const_type v ) const { return this->is_initialized() ? get() : v ; }
+    reference_type       get_value_or ( reference_type       v )       { return this->is_initialized() ? get() : v ; }
+
+    // Returns a pointer to the value if this is initialized, otherwise,
+    // the behaviour is UNDEFINED
+    // No-throw
+    pointer_const_type operator->() const { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
+    pointer_type       operator->()       { BOOST_ASSERT(this->is_initialized()) ; return this->get_ptr_impl() ; }
+
+    // Returns a reference to the value if this is initialized, otherwise,
+    // the behaviour is UNDEFINED
+    // No-throw
+#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
+    reference_const_type operator *() const& { return this->get() ; }
+    reference_type       operator *() &      { return this->get() ; }
+    reference_type_of_temporary_wrapper operator *() && { return base::types::move(this->get()) ; }
+#else
+    reference_const_type operator *() const { return this->get() ; }
+    reference_type       operator *()       { return this->get() ; }
+#endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS
+
+#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
+    reference_const_type value() const&
+      {
+        if (this->is_initialized())
+          return this->get() ;
+        else
+          throw_exception(bad_optional_access());
+      }
+
+    reference_type value() &
+      {
+        if (this->is_initialized())
+          return this->get() ;
+        else
+          throw_exception(bad_optional_access());
+      }
+
+    reference_type_of_temporary_wrapper value() &&
+      {
+        if (this->is_initialized())
+          return base::types::move(this->get()) ;
+        else
+          throw_exception(bad_optional_access());
+      }
+
+#else
+    reference_const_type value() const
+      {
+        if (this->is_initialized())
+          return this->get() ;
+        else
+          throw_exception(bad_optional_access());
+      }
+
+    reference_type value()
+      {
+        if (this->is_initialized())
+          return this->get() ;
+        else
+          throw_exception(bad_optional_access());
+      }
+#endif
+
+
+#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
+    template <class U>
+    value_type value_or ( U&& v ) const&
+      {
+        if (this->is_initialized())
+          return get();
+        else
+          return boost::forward<U>(v);
+      }
+
+    template <class U>
+    value_type value_or ( U&& v ) &&
+      {
+        if (this->is_initialized())
+          return base::types::move(get());
+        else
+          return boost::forward<U>(v);
+      }
+#elif !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+    template <class U>
+    value_type value_or ( U&& v ) const
+      {
+        if (this->is_initialized())
+          return get();
+        else
+          return boost::forward<U>(v);
+      }
+#else
+    template <class U>
+    value_type value_or ( U const& v ) const
+      {
+        if (this->is_initialized())
+          return get();
+        else
+          return v;
+      }
+
+    template <class U>
+    value_type value_or ( U& v ) const
+      {
+        if (this->is_initialized())
+          return get();
+        else
+          return v;
+      }
+#endif
+
+
+#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
+    template <typename F>
+    value_type value_or_eval ( F f ) const&
+      {
+        if (this->is_initialized())
+          return get();
+        else
+          return f();
+      }
+
+    template <typename F>
+    value_type value_or_eval ( F f ) &&
+      {
+        if (this->is_initialized())
+          return base::types::move(get());
+        else
+          return f();
+      }
+#else
+    template <typename F>
+    value_type value_or_eval ( F f ) const
+      {
+        if (this->is_initialized())
+          return get();
+        else
+          return f();
+      }
+#endif
+
+    bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; }
+
+    BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
+} ;
+
+#ifndef  BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+template<class T>
+class optional<T&&>
+{
+  BOOST_STATIC_ASSERT_MSG(sizeof(T) == 0, "Optional rvalue references are illegal.");
+} ;
+#endif
+
+// Returns optional<T>(v)
+template<class T>
+inline
+optional<T> make_optional ( T const& v  )
+{
+  return optional<T>(v);
+}
+
+// Returns optional<T>(cond,v)
+template<class T>
+inline
+optional<T> make_optional ( bool cond, T const& v )
+{
+  return optional<T>(cond,v);
+}
+
+// Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
+// No-throw
+template<class T>
+inline
+BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
+get ( optional<T> const& opt )
+{
+  return opt.get() ;
+}
+
+template<class T>
+inline
+BOOST_DEDUCED_TYPENAME optional<T>::reference_type
+get ( optional<T>& opt )
+{
+  return opt.get() ;
+}
+
+// Returns a pointer to the value if this is initialized, otherwise, returns NULL.
+// No-throw
+template<class T>
+inline
+BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
+get ( optional<T> const* opt )
+{
+  return opt->get_ptr() ;
+}
+
+template<class T>
+inline
+BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
+get ( optional<T>* opt )
+{
+  return opt->get_ptr() ;
+}
+
+// Returns a reference to the value if this is initialized, otherwise, the behaviour is UNDEFINED.
+// No-throw
+template<class T>
+inline
+BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type
+get_optional_value_or ( optional<T> const& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_const_type v )
+{
+  return opt.get_value_or(v) ;
+}
+
+template<class T>
+inline
+BOOST_DEDUCED_TYPENAME optional<T>::reference_type
+get_optional_value_or ( optional<T>& opt, BOOST_DEDUCED_TYPENAME optional<T>::reference_type v )
+{
+  return opt.get_value_or(v) ;
+}
+
+// Returns a pointer to the value if this is initialized, otherwise, returns NULL.
+// No-throw
+template<class T>
+inline
+BOOST_DEDUCED_TYPENAME optional<T>::pointer_const_type
+get_pointer ( optional<T> const& opt )
+{
+  return opt.get_ptr() ;
+}
+
+template<class T>
+inline
+BOOST_DEDUCED_TYPENAME optional<T>::pointer_type
+get_pointer ( optional<T>& opt )
+{
+  return opt.get_ptr() ;
+}
+
+// The following declaration prevents a bug where operator safe-bool is used upon streaming optional object if you forget the IO header.
+template<class CharType, class CharTrait>
+std::basic_ostream<CharType, CharTrait>&
+operator<<(std::basic_ostream<CharType, CharTrait>& os, optional_detail::optional_tag const&)
+{
+  BOOST_STATIC_ASSERT_MSG(sizeof(CharType) == 0, "If you want to output boost::optional, include header <boost/optional/optional_io.hpp>");
+  return os;
+}
+
+// optional's relational operators ( ==, !=, <, >, <=, >= ) have deep-semantics (compare values).
+// WARNING: This is UNLIKE pointers. Use equal_pointees()/less_pointess() in generic code instead.
+
+
+//
+// optional<T> vs optional<T> cases
+//
+
+template<class T>
+inline
+bool operator == ( optional<T> const& x, optional<T> const& y )
+{ return equal_pointees(x,y); }
+
+template<class T>
+inline
+bool operator < ( optional<T> const& x, optional<T> const& y )
+{ return less_pointees(x,y); }
+
+template<class T>
+inline
+bool operator != ( optional<T> const& x, optional<T> const& y )
+{ return !( x == y ) ; }
+
+template<class T>
+inline
+bool operator > ( optional<T> const& x, optional<T> const& y )
+{ return y < x ; }
+
+template<class T>
+inline
+bool operator <= ( optional<T> const& x, optional<T> const& y )
+{ return !( y < x ) ; }
+
+template<class T>
+inline
+bool operator >= ( optional<T> const& x, optional<T> const& y )
+{ return !( x < y ) ; }
+
+
+//
+// optional<T> vs T cases
+//
+template<class T>
+inline
+bool operator == ( optional<T> const& x, T const& y )
+{ return equal_pointees(x, optional<T>(y)); }
+
+template<class T>
+inline
+bool operator < ( optional<T> const& x, T const& y )
+{ return less_pointees(x, optional<T>(y)); }
+
+template<class T>
+inline
+bool operator != ( optional<T> const& x, T const& y )
+{ return !( x == y ) ; }
+
+template<class T>
+inline
+bool operator > ( optional<T> const& x, T const& y )
+{ return y < x ; }
+
+template<class T>
+inline
+bool operator <= ( optional<T> const& x, T const& y )
+{ return !( y < x ) ; }
+
+template<class T>
+inline
+bool operator >= ( optional<T> const& x, T const& y )
+{ return !( x < y ) ; }
+
+//
+// T vs optional<T> cases
+//
+
+template<class T>
+inline
+bool operator == ( T const& x, optional<T> const& y )
+{ return equal_pointees( optional<T>(x), y ); }
+
+template<class T>
+inline
+bool operator < ( T const& x, optional<T> const& y )
+{ return less_pointees( optional<T>(x), y ); }
+
+template<class T>
+inline
+bool operator != ( T const& x, optional<T> const& y )
+{ return !( x == y ) ; }
+
+template<class T>
+inline
+bool operator > ( T const& x, optional<T> const& y )
+{ return y < x ; }
+
+template<class T>
+inline
+bool operator <= ( T const& x, optional<T> const& y )
+{ return !( y < x ) ; }
+
+template<class T>
+inline
+bool operator >= ( T const& x, optional<T> const& y )
+{ return !( x < y ) ; }
+
+
+//
+// optional<T> vs none cases
+//
+
+template<class T>
+inline
+bool operator == ( optional<T> const& x, none_t ) BOOST_NOEXCEPT
+{ return !x; }
+
+template<class T>
+inline
+bool operator < ( optional<T> const& x, none_t )
+{ return less_pointees(x,optional<T>() ); }
+
+template<class T>
+inline
+bool operator != ( optional<T> const& x, none_t ) BOOST_NOEXCEPT
+{ return bool(x); }
+
+template<class T>
+inline
+bool operator > ( optional<T> const& x, none_t y )
+{ return y < x ; }
+
+template<class T>
+inline
+bool operator <= ( optional<T> const& x, none_t y )
+{ return !( y < x ) ; }
+
+template<class T>
+inline
+bool operator >= ( optional<T> const& x, none_t y )
+{ return !( x < y ) ; }
+
+//
+// none vs optional<T> cases
+//
+
+template<class T>
+inline
+bool operator == ( none_t , optional<T> const& y ) BOOST_NOEXCEPT
+{ return !y; }
+
+template<class T>
+inline
+bool operator < ( none_t , optional<T> const& y )
+{ return less_pointees(optional<T>() ,y); }
+
+template<class T>
+inline
+bool operator != ( none_t, optional<T> const& y ) BOOST_NOEXCEPT
+{ return bool(y); }
+
+template<class T>
+inline
+bool operator > ( none_t x, optional<T> const& y )
+{ return y < x ; }
+
+template<class T>
+inline
+bool operator <= ( none_t x, optional<T> const& y )
+{ return !( y < x ) ; }
+
+template<class T>
+inline
+bool operator >= ( none_t x, optional<T> const& y )
+{ return !( x < y ) ; }
+
+namespace optional_detail {
+
+template<bool use_default_constructor> struct swap_selector;
+
+template<>
+struct swap_selector<true>
+{
+    template<class T>
+    static void optional_swap ( optional<T>& x, optional<T>& y )
+    {
+        const bool hasX = !!x;
+        const bool hasY = !!y;
+
+        if ( !hasX && !hasY )
+            return;
+
+        if( !hasX )
+            x.emplace();
+        else if ( !hasY )
+            y.emplace();
+
+        // Boost.Utility.Swap will take care of ADL and workarounds for broken compilers
+        boost::swap(x.get(),y.get());
+
+        if( !hasX )
+            y = boost::none ;
+        else if( !hasY )
+            x = boost::none ;
+    }
+};
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+template<>
+struct swap_selector<false>
+{
+    template<class T>
+    static void optional_swap ( optional<T>& x, optional<T>& y )
+    //BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y)))
+    {
+        if(x)
+        {
+            if (y)
+            {
+                boost::swap(*x, *y);
+            }
+            else
+            {
+                y = boost::move(*x);
+                x = boost::none;
+            }
+        }
+        else
+        {
+            if (y)
+            {
+                x = boost::move(*y);
+                y = boost::none;
+            }
+        }
+    }
+};
+#else
+template<>
+struct swap_selector<false>
+{
+    template<class T>
+    static void optional_swap ( optional<T>& x, optional<T>& y )
+    {
+        const bool hasX = !!x;
+        const bool hasY = !!y;
+
+        if ( !hasX && hasY )
+        {
+            x = y.get();
+            y = boost::none ;
+        }
+        else if ( hasX && !hasY )
+        {
+            y = x.get();
+            x = boost::none ;
+        }
+        else if ( hasX && hasY )
+        {
+            // Boost.Utility.Swap will take care of ADL and workarounds for broken compilers
+            boost::swap(x.get(),y.get());
+        }
+    }
+};
+#endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+
+} // namespace optional_detail
+
+#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_CONFIG_RESTORE_OBSOLETE_SWAP_IMPLEMENTATION)
+
+template<class T>
+struct optional_swap_should_use_default_constructor : boost::false_type {} ;
+
+#else
+
+template<class T>
+struct optional_swap_should_use_default_constructor : has_nothrow_default_constructor<T> {} ;
+
+#endif //BOOST_NO_CXX11_RVALUE_REFERENCES
+
+template<class T> inline void swap ( optional<T>& x, optional<T>& y )
+  //BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y)))
+{
+    optional_detail::swap_selector<optional_swap_should_use_default_constructor<T>::value>::optional_swap(x, y);
+}
+
+} // namespace boost
+
+#endif
diff --git a/third_party/boost/boost/optional/optional_fwd.hpp b/third_party/boost/boost/optional/optional_fwd.hpp
new file mode 100644
index 0000000..162779a
--- /dev/null
+++ b/third_party/boost/boost/optional/optional_fwd.hpp
@@ -0,0 +1,29 @@
+// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/optional for documentation.
+//
+// You are welcome to contact the author at:
+//  fernando_cacciola@hotmail.com
+//
+// Revisions:
+// 10 May 2008 (added swap related forward declaration) Niels Dekker
+//
+#ifndef BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
+#define BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
+
+
+namespace boost {
+
+template<class T> class optional ;
+
+template<class T> void swap ( optional<T>& , optional<T>& );
+
+template<class T> struct optional_swap_should_use_default_constructor ;
+
+} // namespace boost
+
+#endif
diff --git a/third_party/boost/boost/predef.h b/third_party/boost/boost/predef.h
new file mode 100644
index 0000000..4965337
--- /dev/null
+++ b/third_party/boost/boost/predef.h
@@ -0,0 +1,24 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#if !defined(BOOST_PREDEF_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
+#ifndef BOOST_PREDEF_H
+#define BOOST_PREDEF_H
+#endif
+
+#include <boost/predef/language.h>
+#include <boost/predef/architecture.h>
+#include <boost/predef/compiler.h>
+#include <boost/predef/library.h>
+#include <boost/predef/os.h>
+#include <boost/predef/other.h>
+#include <boost/predef/platform.h>
+#include <boost/predef/hardware.h>
+
+#include <boost/predef/version.h>
+
+#endif
diff --git a/third_party/boost/boost/predef/architecture.h b/third_party/boost/boost/predef/architecture.h
new file mode 100644
index 0000000..c433d43
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture.h
@@ -0,0 +1,32 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#if !defined(BOOST_PREDEF_ARCHITECTURE_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
+#ifndef BOOST_PREDEF_ARCHITECTURE_H
+#define BOOST_PREDEF_ARCHITECTURE_H
+#endif
+
+#include <boost/predef/architecture/alpha.h>
+#include <boost/predef/architecture/arm.h>
+#include <boost/predef/architecture/blackfin.h>
+#include <boost/predef/architecture/convex.h>
+#include <boost/predef/architecture/ia64.h>
+#include <boost/predef/architecture/m68k.h>
+#include <boost/predef/architecture/mips.h>
+#include <boost/predef/architecture/parisc.h>
+#include <boost/predef/architecture/ppc.h>
+#include <boost/predef/architecture/pyramid.h>
+#include <boost/predef/architecture/rs6k.h>
+#include <boost/predef/architecture/sparc.h>
+#include <boost/predef/architecture/superh.h>
+#include <boost/predef/architecture/sys370.h>
+#include <boost/predef/architecture/sys390.h>
+#include <boost/predef/architecture/x86.h>
+#include <boost/predef/architecture/z.h>
+/*#include <boost/predef/architecture/.h>*/
+
+#endif
diff --git a/third_party/boost/boost/predef/architecture/alpha.h b/third_party/boost/boost/predef/architecture/alpha.h
new file mode 100644
index 0000000..5bcade1
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/alpha.h
@@ -0,0 +1,59 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_ALPHA_H
+#define BOOST_PREDEF_ARCHITECTURE_ALPHA_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_ALPHA`]
+
+[@http://en.wikipedia.org/wiki/DEC_Alpha DEC Alpha] architecture.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+    [[`__alpha__`] [__predef_detection__]]
+    [[`__alpha`] [__predef_detection__]]
+    [[`_M_ALPHA`] [__predef_detection__]]
+
+    [[`__alpha_ev4__`] [4.0.0]]
+    [[`__alpha_ev5__`] [5.0.0]]
+    [[`__alpha_ev6__`] [6.0.0]]
+    ]
+ */
+
+#define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__alpha__) || defined(__alpha) || \
+    defined(_M_ALPHA)
+#   undef BOOST_ARCH_ALPHA
+#   if !defined(BOOST_ARCH_ALPHA) && defined(__alpha_ev4__)
+#       define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER(4,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_ALPHA) && defined(__alpha_ev5__)
+#       define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER(5,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_ALPHA) && defined(__alpha_ev6__)
+#       define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER(6,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_ALPHA)
+#       define BOOST_ARCH_ALPHA BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_ARCH_ALPHA
+#   define BOOST_ARCH_ALPHA_AVAILABLE
+#endif
+
+#define BOOST_ARCH_ALPHA_NAME "DEC Alpha"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_ALPHA,BOOST_ARCH_ALPHA_NAME)
diff --git a/third_party/boost/boost/predef/architecture/arm.h b/third_party/boost/boost/predef/architecture/arm.h
new file mode 100644
index 0000000..b200c62
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/arm.h
@@ -0,0 +1,70 @@
+/*
+Copyright Rene Rivera 2008-2015
+Copyright Franz Detro 2014
+Copyright (c) Microsoft Corporation 2014
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_ARM_H
+#define BOOST_PREDEF_ARCHITECTURE_ARM_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_ARM`]
+
+[@http://en.wikipedia.org/wiki/ARM_architecture ARM] architecture.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__arm__`] [__predef_detection__]]
+    [[`__arm64`] [__predef_detection__]]
+    [[`__thumb__`] [__predef_detection__]]
+    [[`__TARGET_ARCH_ARM`] [__predef_detection__]]
+    [[`__TARGET_ARCH_THUMB`] [__predef_detection__]]
+    [[`_M_ARM`] [__predef_detection__]]
+
+    [[`__arm64`] [8.0.0]]
+    [[`__TARGET_ARCH_ARM`] [V.0.0]]
+    [[`__TARGET_ARCH_THUMB`] [V.0.0]]
+    [[`_M_ARM`] [V.0.0]]
+    ]
+ */
+
+#define BOOST_ARCH_ARM BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__arm__) || defined(__arm64) || defined(__thumb__) || \
+    defined(__TARGET_ARCH_ARM) || defined(__TARGET_ARCH_THUMB) || \
+    defined(_M_ARM)
+#   undef BOOST_ARCH_ARM
+#   if !defined(BOOST_ARCH_ARM) && defined(__arm64)
+#       define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(8,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_ARM) && defined(__TARGET_ARCH_ARM)
+#       define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(__TARGET_ARCH_ARM,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_ARM) && defined(__TARGET_ARCH_THUMB)
+#       define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(__TARGET_ARCH_THUMB,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_ARM) && defined(_M_ARM)
+#       define BOOST_ARCH_ARM BOOST_VERSION_NUMBER(_M_ARM,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_ARM)
+#       define BOOST_ARCH_ARM BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_ARCH_ARM
+#   define BOOST_ARCH_ARM_AVAILABLE
+#endif
+
+#define BOOST_ARCH_ARM_NAME "ARM"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_ARM,BOOST_ARCH_ARM_NAME)
diff --git a/third_party/boost/boost/predef/architecture/blackfin.h b/third_party/boost/boost/predef/architecture/blackfin.h
new file mode 100644
index 0000000..84c58a2
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/blackfin.h
@@ -0,0 +1,46 @@
+/*
+Copyright Rene Rivera 2013-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_BLACKFIN_H
+#define BOOST_PREDEF_ARCHITECTURE_BLACKFIN_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_BLACKFIN`]
+
+Blackfin Processors from Analog Devices.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__bfin__`] [__predef_detection__]]
+    [[`__BFIN__`] [__predef_detection__]]
+    [[`bfin`] [__predef_detection__]]
+    [[`BFIN`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_ARCH_BLACKFIN BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__bfin__) || defined(__BFIN__) || \
+    defined(bfin) || defined(BFIN)
+#   undef BOOST_ARCH_BLACKFIN
+#   define BOOST_ARCH_BLACKFIN BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_ARCH_BLACKFIN
+#   define BOOST_ARCH_BLACKFIN_AVAILABLE
+#endif
+
+#define BOOST_ARCH_BLACKFIN_NAME "Blackfin"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_BLACKFIN,BOOST_ARCH_BLACKFIN_NAME)
diff --git a/third_party/boost/boost/predef/architecture/convex.h b/third_party/boost/boost/predef/architecture/convex.h
new file mode 100644
index 0000000..ac783a9
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/convex.h
@@ -0,0 +1,65 @@
+/*
+Copyright Rene Rivera 2011-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_CONVEX_H
+#define BOOST_PREDEF_ARCHITECTURE_CONVEX_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_CONVEX`]
+
+[@http://en.wikipedia.org/wiki/Convex_Computer Convex Computer] architecture.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__convex__`] [__predef_detection__]]
+
+    [[`__convex_c1__`] [1.0.0]]
+    [[`__convex_c2__`] [2.0.0]]
+    [[`__convex_c32__`] [3.2.0]]
+    [[`__convex_c34__`] [3.4.0]]
+    [[`__convex_c38__`] [3.8.0]]
+    ]
+ */
+
+#define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__convex__)
+#   undef BOOST_ARCH_CONVEX
+#   if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c1__)
+#       define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(1,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c2__)
+#       define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(2,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c32__)
+#       define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(3,2,0)
+#   endif
+#   if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c34__)
+#       define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(3,4,0)
+#   endif
+#   if !defined(BOOST_ARCH_CONVEX) && defined(__convex_c38__)
+#       define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER(3,8,0)
+#   endif
+#   if !defined(BOOST_ARCH_CONVEX)
+#       define BOOST_ARCH_CONVEX BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_ARCH_CONVEX
+#   define BOOST_ARCH_CONVEX_AVAILABLE
+#endif
+
+#define BOOST_ARCH_CONVEX_NAME "Convex Computer"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_CONVEX,BOOST_ARCH_CONVEX_NAME)
diff --git a/third_party/boost/boost/predef/architecture/ia64.h b/third_party/boost/boost/predef/architecture/ia64.h
new file mode 100644
index 0000000..9b1972b
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/ia64.h
@@ -0,0 +1,49 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_IA64_H
+#define BOOST_PREDEF_ARCHITECTURE_IA64_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_IA64`]
+
+[@http://en.wikipedia.org/wiki/Ia64 Intel Itanium 64] architecture.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__ia64__`] [__predef_detection__]]
+    [[`_IA64`] [__predef_detection__]]
+    [[`__IA64__`] [__predef_detection__]]
+    [[`__ia64`] [__predef_detection__]]
+    [[`_M_IA64`] [__predef_detection__]]
+    [[`__itanium__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_ARCH_IA64 BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__ia64__) || defined(_IA64) || \
+    defined(__IA64__) || defined(__ia64) || \
+    defined(_M_IA64) || defined(__itanium__)
+#   undef BOOST_ARCH_IA64
+#   define BOOST_ARCH_IA64 BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_ARCH_IA64
+#   define BOOST_ARCH_IA64_AVAILABLE
+#endif
+
+#define BOOST_ARCH_IA64_NAME "Intel Itanium 64"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_IA64,BOOST_ARCH_IA64_NAME)
diff --git a/third_party/boost/boost/predef/architecture/m68k.h b/third_party/boost/boost/predef/architecture/m68k.h
new file mode 100644
index 0000000..63ed5f8
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/m68k.h
@@ -0,0 +1,82 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_M68K_H
+#define BOOST_PREDEF_ARCHITECTURE_M68K_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_M68K`]
+
+[@http://en.wikipedia.org/wiki/M68k Motorola 68k] architecture.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__m68k__`] [__predef_detection__]]
+    [[`M68000`] [__predef_detection__]]
+
+    [[`__mc68060__`] [6.0.0]]
+    [[`mc68060`] [6.0.0]]
+    [[`__mc68060`] [6.0.0]]
+    [[`__mc68040__`] [4.0.0]]
+    [[`mc68040`] [4.0.0]]
+    [[`__mc68040`] [4.0.0]]
+    [[`__mc68030__`] [3.0.0]]
+    [[`mc68030`] [3.0.0]]
+    [[`__mc68030`] [3.0.0]]
+    [[`__mc68020__`] [2.0.0]]
+    [[`mc68020`] [2.0.0]]
+    [[`__mc68020`] [2.0.0]]
+    [[`__mc68010__`] [1.0.0]]
+    [[`mc68010`] [1.0.0]]
+    [[`__mc68010`] [1.0.0]]
+    [[`__mc68000__`] [0.0.1]]
+    [[`mc68000`] [0.0.1]]
+    [[`__mc68000`] [0.0.1]]
+    ]
+ */
+
+#define BOOST_ARCH_M68K BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__m68k__) || defined(M68000)
+#   undef BOOST_ARCH_M68K
+#   if !defined(BOOST_ARCH_M68K) && (defined(__mc68060__) || defined(mc68060) || defined(__mc68060))
+#       define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(6,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_M68K) && (defined(__mc68040__) || defined(mc68040) || defined(__mc68040))
+#       define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(4,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_M68K) && (defined(__mc68030__) || defined(mc68030) || defined(__mc68030))
+#       define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(3,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_M68K) && (defined(__mc68020__) || defined(mc68020) || defined(__mc68020))
+#       define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(2,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_M68K) && (defined(__mc68010__) || defined(mc68010) || defined(__mc68010))
+#       define BOOST_ARCH_M68K BOOST_VERSION_NUMBER(1,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_M68K) && (defined(__mc68000__) || defined(mc68000) || defined(__mc68000))
+#       define BOOST_ARCH_M68K BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#   if !defined(BOOST_ARCH_M68K)
+#       define BOOST_ARCH_M68K BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_ARCH_M68K
+#   define BOOST_ARCH_M68K_AVAILABLE
+#endif
+
+#define BOOST_ARCH_M68K_NAME "Motorola 68k"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_M68K,BOOST_ARCH_M68K_NAME)
diff --git a/third_party/boost/boost/predef/architecture/mips.h b/third_party/boost/boost/predef/architecture/mips.h
new file mode 100644
index 0000000..0189d7d
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/mips.h
@@ -0,0 +1,73 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_MIPS_H
+#define BOOST_PREDEF_ARCHITECTURE_MIPS_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_MIPS`]
+
+[@http://en.wikipedia.org/wiki/MIPS_architecture MIPS] architecture.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__mips__`] [__predef_detection__]]
+    [[`__mips`] [__predef_detection__]]
+    [[`__MIPS__`] [__predef_detection__]]
+
+    [[`__mips`] [V.0.0]]
+    [[`_MIPS_ISA_MIPS1`] [1.0.0]]
+    [[`_R3000`] [1.0.0]]
+    [[`_MIPS_ISA_MIPS2`] [2.0.0]]
+    [[`__MIPS_ISA2__`] [2.0.0]]
+    [[`_R4000`] [2.0.0]]
+    [[`_MIPS_ISA_MIPS3`] [3.0.0]]
+    [[`__MIPS_ISA3__`] [3.0.0]]
+    [[`_MIPS_ISA_MIPS4`] [4.0.0]]
+    [[`__MIPS_ISA4__`] [4.0.0]]
+    ]
+ */
+
+#define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__mips__) || defined(__mips) || \
+    defined(__MIPS__)
+#   undef BOOST_ARCH_MIPS
+#   if !defined(BOOST_ARCH_MIPS) && (defined(__mips))
+#       define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(__mips,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_MIPS) && (defined(_MIPS_ISA_MIPS1) || defined(_R3000))
+#       define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(1,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_MIPS) && (defined(_MIPS_ISA_MIPS2) || defined(__MIPS_ISA2__) || defined(_R4000))
+#       define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(2,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_MIPS) && (defined(_MIPS_ISA_MIPS3) || defined(__MIPS_ISA3__))
+#       define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(3,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_MIPS) && (defined(_MIPS_ISA_MIPS4) || defined(__MIPS_ISA4__))
+#       define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER(4,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_MIPS)
+#       define BOOST_ARCH_MIPS BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_ARCH_MIPS
+#   define BOOST_ARCH_MIPS_AVAILABLE
+#endif
+
+#define BOOST_ARCH_MIPS_NAME "MIPS"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_MIPS,BOOST_ARCH_MIPS_NAME)
diff --git a/third_party/boost/boost/predef/architecture/parisc.h b/third_party/boost/boost/predef/architecture/parisc.h
new file mode 100644
index 0000000..7c7625f
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/parisc.h
@@ -0,0 +1,64 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_PARISC_H
+#define BOOST_PREDEF_ARCHITECTURE_PARISC_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_PARISK`]
+
+[@http://en.wikipedia.org/wiki/PA-RISC_family HP/PA RISC] architecture.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__hppa__`] [__predef_detection__]]
+    [[`__hppa`] [__predef_detection__]]
+    [[`__HPPA__`] [__predef_detection__]]
+
+    [[`_PA_RISC1_0`] [1.0.0]]
+    [[`_PA_RISC1_1`] [1.1.0]]
+    [[`__HPPA11__`] [1.1.0]]
+    [[`__PA7100__`] [1.1.0]]
+    [[`_PA_RISC2_0`] [2.0.0]]
+    [[`__RISC2_0__`] [2.0.0]]
+    [[`__HPPA20__`] [2.0.0]]
+    [[`__PA8000__`] [2.0.0]]
+    ]
+ */
+
+#define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__hppa__) || defined(__hppa) || defined(__HPPA__)
+#   undef BOOST_ARCH_PARISC
+#   if !defined(BOOST_ARCH_PARISC) && (defined(_PA_RISC1_0))
+#       define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER(1,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_PARISC) && (defined(_PA_RISC1_1) || defined(__HPPA11__) || defined(__PA7100__))
+#       define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER(1,1,0)
+#   endif
+#   if !defined(BOOST_ARCH_PARISC) && (defined(_PA_RISC2_0) || defined(__RISC2_0__) || defined(__HPPA20__) || defined(__PA8000__))
+#       define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER(2,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_PARISC)
+#       define BOOST_ARCH_PARISC BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_ARCH_PARISC
+#   define BOOST_ARCH_PARISC_AVAILABLE
+#endif
+
+#define BOOST_ARCH_PARISC_NAME "HP/PA RISC"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PARISC,BOOST_ARCH_PARISC_NAME)
diff --git a/third_party/boost/boost/predef/architecture/ppc.h b/third_party/boost/boost/predef/architecture/ppc.h
new file mode 100644
index 0000000..e8c57c9
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/ppc.h
@@ -0,0 +1,72 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_PPC_H
+#define BOOST_PREDEF_ARCHITECTURE_PPC_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_PPC`]
+
+[@http://en.wikipedia.org/wiki/PowerPC PowerPC] architecture.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__powerpc`] [__predef_detection__]]
+    [[`__powerpc__`] [__predef_detection__]]
+    [[`__POWERPC__`] [__predef_detection__]]
+    [[`__ppc__`] [__predef_detection__]]
+    [[`_M_PPC`] [__predef_detection__]]
+    [[`_ARCH_PPC`] [__predef_detection__]]
+    [[`__PPCGECKO__`] [__predef_detection__]]
+    [[`__PPCBROADWAY__`] [__predef_detection__]]
+    [[`_XENON`] [__predef_detection__]]
+
+    [[`__ppc601__`] [6.1.0]]
+    [[`_ARCH_601`] [6.1.0]]
+    [[`__ppc603__`] [6.3.0]]
+    [[`_ARCH_603`] [6.3.0]]
+    [[`__ppc604__`] [6.4.0]]
+    [[`__ppc604__`] [6.4.0]]
+    ]
+ */
+
+#define BOOST_ARCH_PPC BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__powerpc) || defined(__powerpc__) || \
+    defined(__POWERPC__) || defined(__ppc__) || \
+    defined(_M_PPC) || defined(_ARCH_PPC) || \
+    defined(__PPCGECKO__) || defined(__PPCBROADWAY__) || \
+    defined(_XENON)
+#   undef BOOST_ARCH_PPC
+#   if !defined (BOOST_ARCH_PPC) && (defined(__ppc601__) || defined(_ARCH_601))
+#       define BOOST_ARCH_PPC BOOST_VERSION_NUMBER(6,1,0)
+#   endif
+#   if !defined (BOOST_ARCH_PPC) && (defined(__ppc603__) || defined(_ARCH_603))
+#       define BOOST_ARCH_PPC BOOST_VERSION_NUMBER(6,3,0)
+#   endif
+#   if !defined (BOOST_ARCH_PPC) && (defined(__ppc604__) || defined(__ppc604__))
+#       define BOOST_ARCH_PPC BOOST_VERSION_NUMBER(6,4,0)
+#   endif
+#   if !defined (BOOST_ARCH_PPC)
+#       define BOOST_ARCH_PPC BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_ARCH_PPC
+#   define BOOST_ARCH_PPC_AVAILABLE
+#endif
+
+#define BOOST_ARCH_PPC_NAME "PowerPC"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PPC,BOOST_ARCH_PPC_NAME)
diff --git a/third_party/boost/boost/predef/architecture/pyramid.h b/third_party/boost/boost/predef/architecture/pyramid.h
new file mode 100644
index 0000000..4f13253
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/pyramid.h
@@ -0,0 +1,42 @@
+/*
+Copyright Rene Rivera 2011-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_PYRAMID_H
+#define BOOST_PREDEF_ARCHITECTURE_PYRAMID_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_PYRAMID`]
+
+Pyramid 9810 architecture.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`pyr`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_ARCH_PYRAMID BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(pyr)
+#   undef BOOST_ARCH_PYRAMID
+#   define BOOST_ARCH_PYRAMID BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_ARCH_PYRAMID
+#   define BOOST_ARCH_PYRAMID_AVAILABLE
+#endif
+
+#define BOOST_ARCH_PYRAMID_NAME "Pyramid 9810"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_PYRAMID,BOOST_ARCH_PYRAMID_NAME)
diff --git a/third_party/boost/boost/predef/architecture/rs6k.h b/third_party/boost/boost/predef/architecture/rs6k.h
new file mode 100644
index 0000000..8a6e9b6
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/rs6k.h
@@ -0,0 +1,56 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_RS6K_H
+#define BOOST_PREDEF_ARCHITECTURE_RS6K_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_RS6000`]
+
+[@http://en.wikipedia.org/wiki/RS/6000 RS/6000] architecture.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__THW_RS6000`] [__predef_detection__]]
+    [[`_IBMR2`] [__predef_detection__]]
+    [[`_POWER`] [__predef_detection__]]
+    [[`_ARCH_PWR`] [__predef_detection__]]
+    [[`_ARCH_PWR2`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_ARCH_RS6000 BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__THW_RS6000) || defined(_IBMR2) || \
+    defined(_POWER) || defined(_ARCH_PWR) || \
+    defined(_ARCH_PWR2)
+#   undef BOOST_ARCH_RS6000
+#   define BOOST_ARCH_RS6000 BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_ARCH_RS6000
+#   define BOOST_ARCH_RS6000_AVAILABLE
+#endif
+
+#define BOOST_ARCH_RS6000_NAME "RS/6000"
+
+#define BOOST_ARCH_PWR BOOST_ARCH_RS6000
+
+#if BOOST_ARCH_PWR
+#   define BOOST_ARCH_PWR_AVAILABLE
+#endif
+
+#define BOOST_ARCH_PWR_NAME BOOST_ARCH_RS6000_NAME
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_RS6000,BOOST_ARCH_RS6000_NAME)
diff --git a/third_party/boost/boost/predef/architecture/sparc.h b/third_party/boost/boost/predef/architecture/sparc.h
new file mode 100644
index 0000000..a89a510
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/sparc.h
@@ -0,0 +1,54 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_SPARC_H
+#define BOOST_PREDEF_ARCHITECTURE_SPARC_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_SPARC`]
+
+[@http://en.wikipedia.org/wiki/SPARC SPARC] architecture.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__sparc__`] [__predef_detection__]]
+    [[`__sparc`] [__predef_detection__]]
+
+    [[`__sparcv9`] [9.0.0]]
+    [[`__sparcv8`] [8.0.0]]
+    ]
+ */
+
+#define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__sparc__) || defined(__sparc)
+#   undef BOOST_ARCH_SPARC
+#   if !defined(BOOST_ARCH_SPARC) && defined(__sparcv9)
+#       define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER(9,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_SPARC) && defined(__sparcv8)
+#       define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER(8,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_SPARC)
+#       define BOOST_ARCH_SPARC BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_ARCH_SPARC
+#   define BOOST_ARCH_SPARC_AVAILABLE
+#endif
+
+#define BOOST_ARCH_SPARC_NAME "SPARC"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SPARC,BOOST_ARCH_SPARC_NAME)
diff --git a/third_party/boost/boost/predef/architecture/superh.h b/third_party/boost/boost/predef/architecture/superh.h
new file mode 100644
index 0000000..da0529e
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/superh.h
@@ -0,0 +1,67 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_SUPERH_H
+#define BOOST_PREDEF_ARCHITECTURE_SUPERH_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_SH`]
+
+[@http://en.wikipedia.org/wiki/SuperH SuperH] architecture:
+If available versions \[1-5\] are specifically detected.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__sh__`] [__predef_detection__]]
+
+    [[`__SH5__`] [5.0.0]]
+    [[`__SH4__`] [4.0.0]]
+    [[`__sh3__`] [3.0.0]]
+    [[`__SH3__`] [3.0.0]]
+    [[`__sh2__`] [2.0.0]]
+    [[`__sh1__`] [1.0.0]]
+    ]
+ */
+
+#define BOOST_ARCH_SH BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__sh__)
+#   undef BOOST_ARCH_SH
+#   if !defined(BOOST_ARCH_SH) && (defined(__SH5__))
+#       define BOOST_ARCH_SH BOOST_VERSION_NUMBER(5,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_SH) && (defined(__SH4__))
+#       define BOOST_ARCH_SH BOOST_VERSION_NUMBER(4,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_SH) && (defined(__sh3__) || defined(__SH3__))
+#       define BOOST_ARCH_SH BOOST_VERSION_NUMBER(3,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_SH) && (defined(__sh2__))
+#       define BOOST_ARCH_SH BOOST_VERSION_NUMBER(2,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_SH) && (defined(__sh1__))
+#       define BOOST_ARCH_SH BOOST_VERSION_NUMBER(1,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_SH)
+#       define BOOST_ARCH_SH BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_ARCH_SH
+#   define BOOST_ARCH_SH_AVAILABLE
+#endif
+
+#define BOOST_ARCH_SH_NAME "SuperH"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SH,BOOST_ARCH_SH_NAME)
diff --git a/third_party/boost/boost/predef/architecture/sys370.h b/third_party/boost/boost/predef/architecture/sys370.h
new file mode 100644
index 0000000..cfd85dc
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/sys370.h
@@ -0,0 +1,43 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_SYS370_H
+#define BOOST_PREDEF_ARCHITECTURE_SYS370_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_SYS370`]
+
+[@http://en.wikipedia.org/wiki/System/370 System/370] architecture.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__370__`] [__predef_detection__]]
+    [[`__THW_370__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_ARCH_SYS370 BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__370__) || defined(__THW_370__)
+#   undef BOOST_ARCH_SYS370
+#   define BOOST_ARCH_SYS370 BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_ARCH_SYS370
+#   define BOOST_ARCH_SYS370_AVAILABLE
+#endif
+
+#define BOOST_ARCH_SYS370_NAME "System/370"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SYS370,BOOST_ARCH_SYS370_NAME)
diff --git a/third_party/boost/boost/predef/architecture/sys390.h b/third_party/boost/boost/predef/architecture/sys390.h
new file mode 100644
index 0000000..47aff6a
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/sys390.h
@@ -0,0 +1,43 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_SYS390_H
+#define BOOST_PREDEF_ARCHITECTURE_SYS390_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_SYS390`]
+
+[@http://en.wikipedia.org/wiki/System/390 System/390] architecture.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__s390__`] [__predef_detection__]]
+    [[`__s390x__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_ARCH_SYS390 BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__s390__) || defined(__s390x__)
+#   undef BOOST_ARCH_SYS390
+#   define BOOST_ARCH_SYS390 BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_ARCH_SYS390
+#   define BOOST_ARCH_SYS390_AVAILABLE
+#endif
+
+#define BOOST_ARCH_SYS390_NAME "System/390"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_SYS390,BOOST_ARCH_SYS390_NAME)
diff --git a/third_party/boost/boost/predef/architecture/x86.h b/third_party/boost/boost/predef/architecture/x86.h
new file mode 100644
index 0000000..0ef3ef4
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/x86.h
@@ -0,0 +1,38 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#include <boost/predef/architecture/x86/32.h>
+#include <boost/predef/architecture/x86/64.h>
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_X86_H
+#define BOOST_PREDEF_ARCHITECTURE_X86_H
+
+/*`
+[heading `BOOST_ARCH_X86`]
+
+[@http://en.wikipedia.org/wiki/X86 Intel x86] architecture. This is
+a category to indicate that either `BOOST_ARCH_X86_32` or
+`BOOST_ARCH_X86_64` is detected.
+ */
+
+#define BOOST_ARCH_X86 BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if BOOST_ARCH_X86_32 || BOOST_ARCH_X86_64
+#   undef BOOST_ARCH_X86
+#   define BOOST_ARCH_X86 BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_ARCH_X86
+#   define BOOST_ARCH_X86_AVAILABLE
+#endif
+
+#define BOOST_ARCH_X86_NAME "Intel x86"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86,BOOST_ARCH_X86_NAME)
diff --git a/third_party/boost/boost/predef/architecture/x86/32.h b/third_party/boost/boost/predef/architecture/x86/32.h
new file mode 100644
index 0000000..17fbff5
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/x86/32.h
@@ -0,0 +1,87 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_X86_32_H
+#define BOOST_PREDEF_ARCHITECTURE_X86_32_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_X86_32`]
+
+[@http://en.wikipedia.org/wiki/X86 Intel x86] architecture:
+If available versions \[3-6\] are specifically detected.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`i386`] [__predef_detection__]]
+    [[`__i386__`] [__predef_detection__]]
+    [[`__i486__`] [__predef_detection__]]
+    [[`__i586__`] [__predef_detection__]]
+    [[`__i686__`] [__predef_detection__]]
+    [[`__i386`] [__predef_detection__]]
+    [[`_M_IX86`] [__predef_detection__]]
+    [[`_X86_`] [__predef_detection__]]
+    [[`__THW_INTEL__`] [__predef_detection__]]
+    [[`__I86__`] [__predef_detection__]]
+    [[`__INTEL__`] [__predef_detection__]]
+
+    [[`__I86__`] [V.0.0]]
+    [[`_M_IX86`] [V.0.0]]
+    [[`__i686__`] [6.0.0]]
+    [[`__i586__`] [5.0.0]]
+    [[`__i486__`] [4.0.0]]
+    [[`__i386__`] [3.0.0]]
+    ]
+ */
+
+#define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(i386) || defined(__i386__) || \
+    defined(__i486__) || defined(__i586__) || \
+    defined(__i686__) || defined(__i386) || \
+    defined(_M_IX86) || defined(_X86_) || \
+    defined(__THW_INTEL__) || defined(__I86__) || \
+    defined(__INTEL__)
+#   undef BOOST_ARCH_X86_32
+#   if !defined(BOOST_ARCH_X86_32) && defined(__I86__)
+#       define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(__I86__,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_X86_32) && defined(_M_IX86)
+#       define BOOST_ARCH_X86_32 BOOST_PREDEF_MAKE_10_VV00(_M_IX86)
+#   endif
+#   if !defined(BOOST_ARCH_X86_32) && defined(__i686__)
+#       define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(6,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_X86_32) && defined(__i586__)
+#       define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(5,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_X86_32) && defined(__i486__)
+#       define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(4,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_X86_32) && defined(__i386__)
+#       define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER(3,0,0)
+#   endif
+#   if !defined(BOOST_ARCH_X86_32)
+#       define BOOST_ARCH_X86_32 BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_ARCH_X86_32
+#   define BOOST_ARCH_X86_32_AVAILABLE
+#endif
+
+#define BOOST_ARCH_X86_32_NAME "Intel x86-32"
+
+#include <boost/predef/architecture/x86.h>
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86_32,BOOST_ARCH_X86_32_NAME)
diff --git a/third_party/boost/boost/predef/architecture/x86/64.h b/third_party/boost/boost/predef/architecture/x86/64.h
new file mode 100644
index 0000000..f761c92
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/x86/64.h
@@ -0,0 +1,50 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_X86_64_H
+#define BOOST_PREDEF_ARCHITECTURE_X86_64_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_X86_64`]
+
+[@http://en.wikipedia.org/wiki/Ia64 Intel IA-64] architecture.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__x86_64`] [__predef_detection__]]
+    [[`__x86_64__`] [__predef_detection__]]
+    [[`__amd64__`] [__predef_detection__]]
+    [[`__amd64`] [__predef_detection__]]
+    [[`_M_X64`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_ARCH_X86_64 BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__x86_64) || defined(__x86_64__) || \
+    defined(__amd64__) || defined(__amd64) || \
+    defined(_M_X64)
+#   undef BOOST_ARCH_X86_64
+#   define BOOST_ARCH_X86_64 BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_ARCH_X86_64
+#   define BOOST_ARCH_X86_64_AVAILABLE
+#endif
+
+#define BOOST_ARCH_X86_64_NAME "Intel x86-64"
+
+#include <boost/predef/architecture/x86.h>
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_X86_64,BOOST_ARCH_X86_64_NAME)
diff --git a/third_party/boost/boost/predef/architecture/z.h b/third_party/boost/boost/predef/architecture/z.h
new file mode 100644
index 0000000..3d218aa
--- /dev/null
+++ b/third_party/boost/boost/predef/architecture/z.h
@@ -0,0 +1,42 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ARCHITECTURE_Z_H
+#define BOOST_PREDEF_ARCHITECTURE_Z_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_ARCH_Z`]
+
+[@http://en.wikipedia.org/wiki/Z/Architecture z/Architecture] architecture.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__SYSC_ZARCH__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_ARCH_Z BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__SYSC_ZARCH__)
+#   undef BOOST_ARCH_Z
+#   define BOOST_ARCH_Z BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_ARCH_Z
+#   define BOOST_ARCH_Z_AVAILABLE
+#endif
+
+#define BOOST_ARCH_Z_NAME "z/Architecture"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ARCH_Z,BOOST_ARCH_Z_NAME)
diff --git a/third_party/boost/boost/predef/compiler.h b/third_party/boost/boost/predef/compiler.h
new file mode 100644
index 0000000..61a4c52
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler.h
@@ -0,0 +1,43 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#if !defined(BOOST_PREDEF_COMPILER_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
+#ifndef BOOST_PREDEF_COMPILER_H
+#define BOOST_PREDEF_COMPILER_H
+#endif
+
+#include <boost/predef/compiler/borland.h>
+#include <boost/predef/compiler/clang.h>
+#include <boost/predef/compiler/comeau.h>
+#include <boost/predef/compiler/compaq.h>
+#include <boost/predef/compiler/diab.h>
+#include <boost/predef/compiler/digitalmars.h>
+#include <boost/predef/compiler/dignus.h>
+#include <boost/predef/compiler/edg.h>
+#include <boost/predef/compiler/ekopath.h>
+#include <boost/predef/compiler/gcc_xml.h>
+#include <boost/predef/compiler/gcc.h>
+#include <boost/predef/compiler/greenhills.h>
+#include <boost/predef/compiler/hp_acc.h>
+#include <boost/predef/compiler/iar.h>
+#include <boost/predef/compiler/ibm.h>
+#include <boost/predef/compiler/intel.h>
+#include <boost/predef/compiler/kai.h>
+#include <boost/predef/compiler/llvm.h>
+#include <boost/predef/compiler/metaware.h>
+#include <boost/predef/compiler/metrowerks.h>
+#include <boost/predef/compiler/microtec.h>
+#include <boost/predef/compiler/mpw.h>
+#include <boost/predef/compiler/palm.h>
+#include <boost/predef/compiler/pgi.h>
+#include <boost/predef/compiler/sgi_mipspro.h>
+#include <boost/predef/compiler/sunpro.h>
+#include <boost/predef/compiler/tendra.h>
+#include <boost/predef/compiler/visualc.h>
+#include <boost/predef/compiler/watcom.h>
+
+#endif
diff --git a/third_party/boost/boost/predef/compiler/borland.h b/third_party/boost/boost/predef/compiler/borland.h
new file mode 100644
index 0000000..3677cca
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/borland.h
@@ -0,0 +1,63 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_BORLAND_H
+#define BOOST_PREDEF_COMPILER_BORLAND_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_BORLAND`]
+
+[@http://en.wikipedia.org/wiki/C_plus_plus_builder Borland C++] compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__BORLANDC__`] [__predef_detection__]]
+    [[`__CODEGEARC__`] [__predef_detection__]]
+
+    [[`__BORLANDC__`] [V.R.P]]
+    [[`__CODEGEARC__`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_BORLAND BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__BORLANDC__) || defined(__CODEGEARC__)
+#   if !defined(BOOST_COMP_BORLAND_DETECTION) && (defined(__CODEGEARC__))
+#       define BOOST_COMP_BORLAND_DETECTION BOOST_PREDEF_MAKE_0X_VVRP(__CODEGEARC__)
+#   endif
+#   if !defined(BOOST_COMP_BORLAND_DETECTION)
+#       define BOOST_COMP_BORLAND_DETECTION BOOST_PREDEF_MAKE_0X_VVRP(__BORLANDC__)
+#   endif
+#endif
+
+#ifdef BOOST_COMP_BORLAND_DETECTION
+#   define BOOST_COMP_BORLAND_AVAILABLE
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_BORLAND_EMULATED BOOST_COMP_BORLAND_DETECTION
+#   else
+#       undef BOOST_COMP_BORLAND
+#       define BOOST_COMP_BORLAND BOOST_COMP_BORLAND_DETECTION
+#   endif
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_BORLAND_NAME "Borland C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_BORLAND,BOOST_COMP_BORLAND_NAME)
+
+#ifdef BOOST_COMP_BORLAND_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_BORLAND_EMULATED,BOOST_COMP_BORLAND_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/clang.h b/third_party/boost/boost/predef/compiler/clang.h
new file mode 100644
index 0000000..56678fe
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/clang.h
@@ -0,0 +1,56 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_CLANG_H
+#define BOOST_PREDEF_COMPILER_CLANG_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_CLANG`]
+
+[@http://en.wikipedia.org/wiki/Clang Clang] compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__clang__`] [__predef_detection__]]
+
+    [[`__clang_major__`, `__clang_minor__`, `__clang_patchlevel__`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_CLANG BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__clang__)
+#   define BOOST_COMP_CLANG_DETECTION BOOST_VERSION_NUMBER(__clang_major__,__clang_minor__,__clang_patchlevel__)
+#endif
+
+#ifdef BOOST_COMP_CLANG_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_CLANG_EMULATED BOOST_COMP_CLANG_DETECTION
+#   else
+#       undef BOOST_COMP_CLANG
+#       define BOOST_COMP_CLANG BOOST_COMP_CLANG_DETECTION
+#   endif
+#   define BOOST_COMP_CLANG_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_CLANG_NAME "Clang"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_CLANG,BOOST_COMP_CLANG_NAME)
+
+#ifdef BOOST_COMP_CLANG_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_CLANG_EMULATED,BOOST_COMP_CLANG_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/comeau.h b/third_party/boost/boost/predef/compiler/comeau.h
new file mode 100644
index 0000000..15a4564
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/comeau.h
@@ -0,0 +1,61 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_COMEAU_H
+#define BOOST_PREDEF_COMPILER_COMEAU_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+#define BOOST_COMP_COMO BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+/*`
+[heading `BOOST_COMP_COMO`]
+
+[@http://en.wikipedia.org/wiki/Comeau_C/C%2B%2B Comeau C++] compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__COMO__`] [__predef_detection__]]
+
+    [[`__COMO_VERSION__`] [V.R.P]]
+    ]
+ */
+
+#if defined(__COMO__)
+#   if !defined(BOOST_COMP_COMO_DETECTION) && defined(__COMO_VERSION__)
+#       define BOOST_COMP_COMO_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__COMO_VERSION__)
+#   endif
+#   if !defined(BOOST_COMP_COMO_DETECTION)
+#       define BOOST_COMP_COMO_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#ifdef BOOST_COMP_COMO_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_COMO_EMULATED BOOST_COMP_COMO_DETECTION
+#   else
+#       undef BOOST_COMP_COMO
+#       define BOOST_COMP_COMO BOOST_COMP_COMO_DETECTION
+#   endif
+#   define BOOST_COMP_COMO_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_COMO_NAME "Comeau C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_COMO,BOOST_COMP_COMO_NAME)
+
+#ifdef BOOST_COMP_COMO_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_COMO_EMULATED,BOOST_COMP_COMO_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/compaq.h b/third_party/boost/boost/predef/compiler/compaq.h
new file mode 100644
index 0000000..96a79e6
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/compaq.h
@@ -0,0 +1,66 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_COMPAQ_H
+#define BOOST_PREDEF_COMPILER_COMPAQ_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_DEC`]
+
+[@http://www.openvms.compaq.com/openvms/brochures/deccplus/ Compaq C/C++] compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__DECCXX`] [__predef_detection__]]
+    [[`__DECC`] [__predef_detection__]]
+
+    [[`__DECCXX_VER`] [V.R.P]]
+    [[`__DECC_VER`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_DEC BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__DECC) || defined(__DECCXX)
+#   if !defined(BOOST_COMP_DEC_DETECTION) && defined(__DECCXX_VER)
+#       define BOOST_COMP_DEC_DETECTION BOOST_PREDEF_MAKE_10_VVRR0PP00(__DECCXX_VER)
+#   endif
+#   if !defined(BOOST_COMP_DEC_DETECTION) && defined(__DECC_VER)
+#       define BOOST_COMP_DEC_DETECTION BOOST_PREDEF_MAKE_10_VVRR0PP00(__DECC_VER)
+#   endif
+#   if !defined(BOOST_COMP_DEC_DETECTION)
+#       define BOOST_COM_DEC_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#ifdef BOOST_COMP_DEC_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_DEC_EMULATED BOOST_COMP_DEC_DETECTION
+#   else
+#       undef BOOST_COMP_DEC
+#       define BOOST_COMP_DEC BOOST_COMP_DEC_DETECTION
+#   endif
+#   define BOOST_COMP_DEC_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_DEC_NAME "Compaq C/C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DEC,BOOST_COMP_DEC_NAME)
+
+#ifdef BOOST_COMP_DEC_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DEC_EMULATED,BOOST_COMP_DEC_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/diab.h b/third_party/boost/boost/predef/compiler/diab.h
new file mode 100644
index 0000000..f5a37de
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/diab.h
@@ -0,0 +1,56 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_DIAB_H
+#define BOOST_PREDEF_COMPILER_DIAB_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_DIAB`]
+
+[@http://www.windriver.com/products/development_suite/wind_river_compiler/ Diab C/C++] compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__DCC__`] [__predef_detection__]]
+
+    [[`__VERSION_NUMBER__`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_DIAB BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__DCC__)
+#   define BOOST_COMP_DIAB_DETECTION BOOST_PREDEF_MAKE_10_VRPP(__VERSION_NUMBER__)
+#endif
+
+#ifdef BOOST_COMP_DIAB_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_DIAB_EMULATED BOOST_COMP_DIAB_DETECTION
+#   else
+#       undef BOOST_COMP_DIAB
+#       define BOOST_COMP_DIAB BOOST_COMP_DIAB_DETECTION
+#   endif
+#   define BOOST_COMP_DIAB_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_DIAB_NAME "Diab C/C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DIAB,BOOST_COMP_DIAB_NAME)
+
+#ifdef BOOST_COMP_DIAB_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DIAB_EMULATED,BOOST_COMP_DIAB_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/digitalmars.h b/third_party/boost/boost/predef/compiler/digitalmars.h
new file mode 100644
index 0000000..9bd5850
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/digitalmars.h
@@ -0,0 +1,56 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_DIGITALMARS_H
+#define BOOST_PREDEF_COMPILER_DIGITALMARS_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_DMC`]
+
+[@http://en.wikipedia.org/wiki/Digital_Mars Digital Mars] compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__DMC__`] [__predef_detection__]]
+
+    [[`__DMC__`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_DMC BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__DMC__)
+#   define BOOST_COMP_DMC_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__DMC__)
+#endif
+
+#ifdef BOOST_COMP_DMC_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_DMC_EMULATED BOOST_COMP_DMC_DETECTION
+#   else
+#       undef BOOST_COMP_DMC
+#       define BOOST_COMP_DMC BOOST_COMP_DMC_DETECTION
+#   endif
+#   define BOOST_COMP_DMC_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_DMC_NAME "Digital Mars"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DMC,BOOST_COMP_DMC_NAME)
+
+#ifdef BOOST_COMP_DMC_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_DMC_EMULATED,BOOST_COMP_DMC_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/dignus.h b/third_party/boost/boost/predef/compiler/dignus.h
new file mode 100644
index 0000000..c65d3dc
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/dignus.h
@@ -0,0 +1,56 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_DIGNUS_H
+#define BOOST_PREDEF_COMPILER_DIGNUS_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_SYSC`]
+
+[@http://www.dignus.com/dcxx/ Dignus Systems/C++] compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__SYSC__`] [__predef_detection__]]
+
+    [[`__SYSC_VER__`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_SYSC BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__SYSC__)
+#   define BOOST_COMP_SYSC_DETECTION BOOST_PREDEF_MAKE_10_VRRPP(__SYSC_VER__)
+#endif
+
+#ifdef BOOST_COMP_SYSC_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_SYSC_EMULATED BOOST_COMP_SYSC_DETECTION
+#   else
+#       undef BOOST_COMP_SYSC
+#       define BOOST_COMP_SYSC BOOST_COMP_SYSC_DETECTION
+#   endif
+#   define BOOST_COMP_SYSC_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_SYSC_NAME "Dignus Systems/C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SYSC,BOOST_COMP_SYSC_NAME)
+
+#ifdef BOOST_COMP_SYSC_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SYSC_EMULATED,BOOST_COMP_SYSC_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/edg.h b/third_party/boost/boost/predef/compiler/edg.h
new file mode 100644
index 0000000..2ffb9b0
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/edg.h
@@ -0,0 +1,56 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_EDG_H
+#define BOOST_PREDEF_COMPILER_EDG_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_EDG`]
+
+[@http://en.wikipedia.org/wiki/Edison_Design_Group EDG C++ Frontend] compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__EDG__`] [__predef_detection__]]
+
+    [[`__EDG_VERSION__`] [V.R.0]]
+    ]
+ */
+
+#define BOOST_COMP_EDG BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__EDG__)
+#   define BOOST_COMP_EDG_DETECTION BOOST_PREDEF_MAKE_10_VRR(__EDG_VERSION__)
+#endif
+
+#ifdef BOOST_COMP_EDG_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_EDG_EMULATED BOOST_COMP_EDG_DETECTION
+#   else
+#       undef BOOST_COMP_EDG
+#       define BOOST_COMP_EDG BOOST_COMP_EDG_DETECTION
+#   endif
+#   define BOOST_COMP_EDG_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_EDG_NAME "EDG C++ Frontend"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_EDG,BOOST_COMP_EDG_NAME)
+
+#ifdef BOOST_COMP_EDG_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_EDG_EMULATED,BOOST_COMP_EDG_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/ekopath.h b/third_party/boost/boost/predef/compiler/ekopath.h
new file mode 100644
index 0000000..e5cde36
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/ekopath.h
@@ -0,0 +1,57 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_EKOPATH_H
+#define BOOST_PREDEF_COMPILER_EKOPATH_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_PATH`]
+
+[@http://en.wikipedia.org/wiki/PathScale EKOpath] compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__PATHCC__`] [__predef_detection__]]
+
+    [[`__PATHCC__`, `__PATHCC_MINOR__`, `__PATHCC_PATCHLEVEL__`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_PATH BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__PATHCC__)
+#   define BOOST_COMP_PATH_DETECTION \
+        BOOST_VERSION_NUMBER(__PATHCC__,__PATHCC_MINOR__,__PATHCC_PATCHLEVEL__)
+#endif
+
+#ifdef BOOST_COMP_PATH_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_PATH_EMULATED BOOST_COMP_PATH_DETECTION
+#   else
+#       undef BOOST_COMP_PATH
+#       define BOOST_COMP_PATH BOOST_COMP_PATH_DETECTION
+#   endif
+#   define BOOST_COMP_PATH_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_PATH_NAME "EKOpath"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PATH,BOOST_COMP_PATH_NAME)
+
+#ifdef BOOST_COMP_PATH_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PATH_EMULATED,BOOST_COMP_PATH_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/gcc.h b/third_party/boost/boost/predef/compiler/gcc.h
new file mode 100644
index 0000000..c2d7fff
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/gcc.h
@@ -0,0 +1,68 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_GCC_H
+#define BOOST_PREDEF_COMPILER_GCC_H
+
+/* Other compilers that emulate this one need to be detected first. */
+
+#include <boost/predef/compiler/clang.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_GNUC`]
+
+[@http://en.wikipedia.org/wiki/GNU_Compiler_Collection Gnu GCC C/C++] compiler.
+Version number available as major, minor, and patch (if available).
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__GNUC__`] [__predef_detection__]]
+
+    [[`__GNUC__`, `__GNUC_MINOR__`, `__GNUC_PATCHLEVEL__`] [V.R.P]]
+    [[`__GNUC__`, `__GNUC_MINOR__`] [V.R.0]]
+    ]
+ */
+
+#define BOOST_COMP_GNUC BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__GNUC__)
+#   if !defined(BOOST_COMP_GNUC_DETECTION) && defined(__GNUC_PATCHLEVEL__)
+#       define BOOST_COMP_GNUC_DETECTION \
+            BOOST_VERSION_NUMBER(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__)
+#   endif
+#   if !defined(BOOST_COMP_GNUC_DETECTION)
+#       define BOOST_COMP_GNUC_DETECTION \
+            BOOST_VERSION_NUMBER(__GNUC__,__GNUC_MINOR__,0)
+#   endif
+#endif
+
+#ifdef BOOST_COMP_GNUC_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_GNUC_EMULATED BOOST_COMP_GNUC_DETECTION
+#   else
+#       undef BOOST_COMP_GNUC
+#       define BOOST_COMP_GNUC BOOST_COMP_GNUC_DETECTION
+#   endif
+#   define BOOST_COMP_GNUC_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_GNUC_NAME "Gnu GCC C/C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GNUC,BOOST_COMP_GNUC_NAME)
+
+#ifdef BOOST_COMP_GNUC_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GNUC_EMULATED,BOOST_COMP_GNUC_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/gcc_xml.h b/third_party/boost/boost/predef/compiler/gcc_xml.h
new file mode 100644
index 0000000..acae600
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/gcc_xml.h
@@ -0,0 +1,53 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_GCC_XML_H
+#define BOOST_PREDEF_COMPILER_GCC_XML_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_GCCXML`]
+
+[@http://www.gccxml.org/ GCC XML] compiler.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__GCCXML__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_COMP_GCCXML BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__GCCXML__)
+#   define BOOST_COMP_GCCXML_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#ifdef BOOST_COMP_GCCXML_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_GCCXML_EMULATED BOOST_COMP_GCCXML_DETECTION
+#   else
+#       undef BOOST_COMP_GCCXML
+#       define BOOST_COMP_GCCXML BOOST_COMP_GCCXML_DETECTION
+#   endif
+#   define BOOST_COMP_GCCXML_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_GCCXML_NAME "GCC XML"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GCCXML,BOOST_COMP_GCCXML_NAME)
+
+#ifdef BOOST_COMP_GCCXML_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GCCXML_EMULATED,BOOST_COMP_GCCXML_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/greenhills.h b/third_party/boost/boost/predef/compiler/greenhills.h
new file mode 100644
index 0000000..23b8f01
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/greenhills.h
@@ -0,0 +1,66 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_GREENHILLS_H
+#define BOOST_PREDEF_COMPILER_GREENHILLS_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_GHS`]
+
+[@http://en.wikipedia.org/wiki/Green_Hills_Software Green Hills C/C++] compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__ghs`] [__predef_detection__]]
+    [[`__ghs__`] [__predef_detection__]]
+
+    [[`__GHS_VERSION_NUMBER__`] [V.R.P]]
+    [[`__ghs`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_GHS BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__ghs) || defined(__ghs__)
+#   if !defined(BOOST_COMP_GHS_DETECTION) && defined(__GHS_VERSION_NUMBER__)
+#       define BOOST_COMP_GHS_DETECTION BOOST_PREDEF_MAKE_10_VRP(__GHS_VERSION_NUMBER__)
+#   endif
+#   if !defined(BOOST_COMP_GHS_DETECTION) && defined(__ghs)
+#       define BOOST_COMP_GHS_DETECTION BOOST_PREDEF_MAKE_10_VRP(__ghs)
+#   endif
+#   if !defined(BOOST_COMP_GHS_DETECTION)
+#       define BOOST_COMP_GHS_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#ifdef BOOST_COMP_GHS_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_GHS_EMULATED BOOST_COMP_GHS_DETECTION
+#   else
+#       undef BOOST_COMP_GHS
+#       define BOOST_COMP_GHS BOOST_COMP_GHS_DETECTION
+#   endif
+#   define BOOST_COMP_GHS_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_GHS_NAME "Green Hills C/C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GHS,BOOST_COMP_GHS_NAME)
+
+#ifdef BOOST_COMP_GHS_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_GHS_EMULATED,BOOST_COMP_GHS_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/hp_acc.h b/third_party/boost/boost/predef/compiler/hp_acc.h
new file mode 100644
index 0000000..7b3ffe9
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/hp_acc.h
@@ -0,0 +1,61 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_HP_ACC_H
+#define BOOST_PREDEF_COMPILER_HP_ACC_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_HPACC`]
+
+HP aC++ compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__HP_aCC`] [__predef_detection__]]
+
+    [[`__HP_aCC`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_HPACC BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__HP_aCC)
+#   if !defined(BOOST_COMP_HPACC_DETECTION) && (__HP_aCC > 1)
+#       define BOOST_COMP_HPACC_DETECTION BOOST_PREDEF_MAKE_10_VVRRPP(__HP_aCC)
+#   endif
+#   if !defined(BOOST_COMP_HPACC_DETECTION)
+#       define BOOST_COMP_HPACC_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#ifdef BOOST_COMP_HPACC_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_HPACC_EMULATED BOOST_COMP_HPACC_DETECTION
+#   else
+#       undef BOOST_COMP_HPACC
+#       define BOOST_COMP_HPACC BOOST_COMP_HPACC_DETECTION
+#   endif
+#   define BOOST_COMP_HPACC_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_HPACC_NAME "HP aC++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HPACC,BOOST_COMP_HPACC_NAME)
+
+#ifdef BOOST_COMP_HPACC_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HPACC_EMULATED,BOOST_COMP_HPACC_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/iar.h b/third_party/boost/boost/predef/compiler/iar.h
new file mode 100644
index 0000000..237f492
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/iar.h
@@ -0,0 +1,56 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_IAR_H
+#define BOOST_PREDEF_COMPILER_IAR_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_IAR`]
+
+IAR C/C++ compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__IAR_SYSTEMS_ICC__`] [__predef_detection__]]
+
+    [[`__VER__`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_IAR BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__IAR_SYSTEMS_ICC__)
+#   define BOOST_COMP_IAR_DETECTION BOOST_PREDEF_MAKE_10_VVRR(__VER__)
+#endif
+
+#ifdef BOOST_COMP_IAR_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_IAR_EMULATED BOOST_COMP_IAR_DETECTION
+#   else
+#       undef BOOST_COMP_IAR
+#       define BOOST_COMP_IAR BOOST_COMP_IAR_DETECTION
+#   endif
+#   define BOOST_COMP_IAR_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_IAR_NAME "IAR C/C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IAR,BOOST_COMP_IAR_NAME)
+
+#ifdef BOOST_COMP_IAR_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IAR_EMULATED,BOOST_COMP_IAR_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/ibm.h b/third_party/boost/boost/predef/compiler/ibm.h
new file mode 100644
index 0000000..6931ebd
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/ibm.h
@@ -0,0 +1,72 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_IBM_H
+#define BOOST_PREDEF_COMPILER_IBM_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_IBM`]
+
+[@http://en.wikipedia.org/wiki/VisualAge IBM XL C/C++] compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__IBMCPP__`] [__predef_detection__]]
+    [[`__xlC__`] [__predef_detection__]]
+    [[`__xlc__`] [__predef_detection__]]
+
+    [[`__COMPILER_VER__`] [V.R.P]]
+    [[`__xlC__`] [V.R.P]]
+    [[`__xlc__`] [V.R.P]]
+    [[`__IBMCPP__`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_IBM BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__IBMCPP__) || defined(__xlC__) || defined(__xlc__)
+#   if !defined(BOOST_COMP_IBM_DETECTION) && defined(__COMPILER_VER__)
+#       define BOOST_COMP_IBM_DETECTION BOOST_PREDEF_MAKE_0X_VRRPPPP(__COMPILER_VER__)
+#   endif
+#   if !defined(BOOST_COMP_IBM_DETECTION) && defined(__xlC__)
+#       define BOOST_COMP_IBM_DETECTION BOOST_PREDEF_MAKE_0X_VVRR(__xlC__)
+#   endif
+#   if !defined(BOOST_COMP_IBM_DETECTION) && defined(__xlc__)
+#       define BOOST_COMP_IBM_DETECTION BOOST_PREDEF_MAKE_0X_VVRR(__xlc__)
+#   endif
+#   if !defined(BOOST_COMP_IBM_DETECTION)
+#       define BOOST_COMP_IBM_DETECTION BOOST_PREDEF_MAKE_10_VRP(__IBMCPP__)
+#   endif
+#endif
+
+#ifdef BOOST_COMP_IBM_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_IBM_EMULATED BOOST_COMP_IBM_DETECTION
+#   else
+#       undef BOOST_COMP_IBM
+#       define BOOST_COMP_IBM BOOST_COMP_IBM_DETECTION
+#   endif
+#   define BOOST_COMP_IBM_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_IBM_NAME "IBM XL C/C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IBM,BOOST_COMP_IBM_NAME)
+
+#ifdef BOOST_COMP_IBM_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_IBM_EMULATED,BOOST_COMP_IBM_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/intel.h b/third_party/boost/boost/predef/compiler/intel.h
new file mode 100644
index 0000000..65bde67
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/intel.h
@@ -0,0 +1,65 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_INTEL_H
+#define BOOST_PREDEF_COMPILER_INTEL_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_INTEL`]
+
+[@http://en.wikipedia.org/wiki/Intel_C%2B%2B Intel C/C++] compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__INTEL_COMPILER`] [__predef_detection__]]
+    [[`__ICL`] [__predef_detection__]]
+    [[`__ICC`] [__predef_detection__]]
+    [[`__ECC`] [__predef_detection__]]
+
+    [[`__INTEL_COMPILER`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_INTEL BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || \
+    defined(__ECC)
+#   if !defined(BOOST_COMP_INTEL_DETECTION) && defined(__INTEL_COMPILER)
+#       define BOOST_COMP_INTEL_DETECTION BOOST_PREDEF_MAKE_10_VRP(__INTEL_COMPILER)
+#   endif
+#   if !defined(BOOST_COMP_INTEL_DETECTION)
+#       define BOOST_COMP_INTEL_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#ifdef BOOST_COMP_INTEL_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_INTEL_EMULATED BOOST_COMP_INTEL_DETECTION
+#   else
+#       undef BOOST_COMP_INTEL
+#       define BOOST_COMP_INTEL BOOST_COMP_INTEL_DETECTION
+#   endif
+#   define BOOST_COMP_INTEL_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_INTEL_NAME "Intel C/C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_INTEL,BOOST_COMP_INTEL_NAME)
+
+#ifdef BOOST_COMP_INTEL_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_INTEL_EMULATED,BOOST_COMP_INTEL_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/kai.h b/third_party/boost/boost/predef/compiler/kai.h
new file mode 100644
index 0000000..68ce84e
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/kai.h
@@ -0,0 +1,56 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_KAI_H
+#define BOOST_PREDEF_COMPILER_KAI_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_KCC`]
+
+Kai C++ compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__KCC`] [__predef_detection__]]
+
+    [[`__KCC_VERSION`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_KCC BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__KCC)
+#   define BOOST_COMP_KCC_DETECTION BOOST_PREDEF_MAKE_0X_VRPP(__KCC_VERSION)
+#endif
+
+#ifdef BOOST_COMP_KCC_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_KCC_EMULATED BOOST_COMP_KCC_DETECTION
+#   else
+#       undef BOOST_COMP_KCC
+#       define BOOST_COMP_KCC BOOST_COMP_KCC_DETECTION
+#   endif
+#   define BOOST_COMP_KCC_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_KCC_NAME "Kai C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_KCC,BOOST_COMP_KCC_NAME)
+
+#ifdef BOOST_COMP_KCC_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_KCC_EMULATED,BOOST_COMP_KCC_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/llvm.h b/third_party/boost/boost/predef/compiler/llvm.h
new file mode 100644
index 0000000..de654eb
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/llvm.h
@@ -0,0 +1,57 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_LLVM_H
+#define BOOST_PREDEF_COMPILER_LLVM_H
+
+/* Other compilers that emulate this one need to be detected first. */
+
+#include <boost/predef/compiler/clang.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_LLVM`]
+
+[@http://en.wikipedia.org/wiki/LLVM LLVM] compiler.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__llvm__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_COMP_LLVM BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__llvm__)
+#   define BOOST_COMP_LLVM_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#ifdef BOOST_COMP_LLVM_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_LLVM_EMULATED BOOST_COMP_LLVM_DETECTION
+#   else
+#       undef BOOST_COMP_LLVM
+#       define BOOST_COMP_LLVM BOOST_COMP_LLVM_DETECTION
+#   endif
+#   define BOOST_COMP_LLVM_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_LLVM_NAME "LLVM"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_LLVM,BOOST_COMP_LLVM_NAME)
+
+#ifdef BOOST_COMP_LLVM_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_LLVM_EMULATED,BOOST_COMP_LLVM_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/metaware.h b/third_party/boost/boost/predef/compiler/metaware.h
new file mode 100644
index 0000000..1a32039
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/metaware.h
@@ -0,0 +1,53 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_METAWARE_H
+#define BOOST_PREDEF_COMPILER_METAWARE_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_HIGHC`]
+
+MetaWare High C/C++ compiler.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__HIGHC__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_COMP_HIGHC BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__HIGHC__)
+#   define BOOST_COMP_HIGHC_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#ifdef BOOST_COMP_HIGHC_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_HIGHC_EMULATED BOOST_COMP_HIGHC_DETECTION
+#   else
+#       undef BOOST_COMP_HIGHC
+#       define BOOST_COMP_HIGHC BOOST_COMP_HIGHC_DETECTION
+#   endif
+#   define BOOST_COMP_HIGHC_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_HIGHC_NAME "MetaWare High C/C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HIGHC,BOOST_COMP_HIGHC_NAME)
+
+#ifdef BOOST_COMP_HIGHC_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_HIGHC_EMULATED,BOOST_COMP_HIGHC_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/metrowerks.h b/third_party/boost/boost/predef/compiler/metrowerks.h
new file mode 100644
index 0000000..f2d739b
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/metrowerks.h
@@ -0,0 +1,77 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_METROWERKS_H
+#define BOOST_PREDEF_COMPILER_METROWERKS_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_MWERKS`]
+
+[@http://en.wikipedia.org/wiki/CodeWarrior Metrowerks CodeWarrior] compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__MWERKS__`] [__predef_detection__]]
+    [[`__CWCC__`] [__predef_detection__]]
+
+    [[`__CWCC__`] [V.R.P]]
+    [[`__MWERKS__`] [V.R.P >= 4.2.0]]
+    [[`__MWERKS__`] [9.R.0]]
+    [[`__MWERKS__`] [8.R.0]]
+    ]
+ */
+
+#define BOOST_COMP_MWERKS BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__MWERKS__) || defined(__CWCC__)
+#   if !defined(BOOST_COMP_MWERKS_DETECTION) && defined(__CWCC__)
+#       define BOOST_COMP_MWERKS_DETECTION BOOST_PREDEF_MAKE_0X_VRPP(__CWCC__)
+#   endif
+#   if !defined(BOOST_COMP_MWERKS_DETECTION) && (__MWERKS__ >= 0x4200)
+#       define BOOST_COMP_MWERKS_DETECTION BOOST_PREDEF_MAKE_0X_VRPP(__MWERKS__)
+#   endif
+#   if !defined(BOOST_COMP_MWERKS_DETECTION) && (__MWERKS__ >= 0x3204) // note the "skip": 04->9.3
+#       define BOOST_COMP_MWERKS_DETECTION BOOST_VERSION_NUMBER(9,(__MWERKS__)%100-1,0)
+#   endif
+#   if !defined(BOOST_COMP_MWERKS_DETECTION) && (__MWERKS__ >= 0x3200)
+#       define BOOST_COMP_MWERKS_DETECTION BOOST_VERSION_NUMBER(9,(__MWERKS__)%100,0)
+#   endif
+#   if !defined(BOOST_COMP_MWERKS_DETECTION) && (__MWERKS__ >= 0x3000)
+#       define BOOST_COMP_MWERKS_DETECTION BOOST_VERSION_NUMBER(8,(__MWERKS__)%100,0)
+#   endif
+#   if !defined(BOOST_COMP_MWERKS_DETECTION)
+#       define BOOST_COMP_MWERKS_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#ifdef BOOST_COMP_MWERKS_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_MWERKS_EMULATED BOOST_COMP_MWERKS_DETECTION
+#   else
+#       undef BOOST_COMP_MWERKS
+#       define BOOST_COMP_MWERKS BOOST_COMP_MWERKS_DETECTION
+#   endif
+#   define BOOST_COMP_MWERKS_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_MWERKS_NAME "Metrowerks CodeWarrior"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MWERKS,BOOST_COMP_MWERKS_NAME)
+
+#ifdef BOOST_COMP_MWERKS_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MWERKS_EMULATED,BOOST_COMP_MWERKS_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/microtec.h b/third_party/boost/boost/predef/compiler/microtec.h
new file mode 100644
index 0000000..066a6d2
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/microtec.h
@@ -0,0 +1,53 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_MICROTEC_H
+#define BOOST_PREDEF_COMPILER_MICROTEC_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_MRI`]
+
+[@http://www.mentor.com/microtec/ Microtec C/C++] compiler.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`_MRI`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_COMP_MRI BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(_MRI)
+#   define BOOST_COMP_MRI_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#ifdef BOOST_COMP_MRI_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_MRI_EMULATED BOOST_COMP_MRI_DETECTION
+#   else
+#       undef BOOST_COMP_MRI
+#       define BOOST_COMP_MRI BOOST_COMP_MRI_DETECTION
+#   endif
+#   define BOOST_COMP_MRI_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_MRI_NAME "Microtec C/C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MRI,BOOST_COMP_MRI_NAME)
+
+#ifdef BOOST_COMP_MRI_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MRI_EMULATED,BOOST_COMP_MRI_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/mpw.h b/third_party/boost/boost/predef/compiler/mpw.h
new file mode 100644
index 0000000..1183306
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/mpw.h
@@ -0,0 +1,63 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_MPW_H
+#define BOOST_PREDEF_COMPILER_MPW_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_MPW`]
+
+[@http://en.wikipedia.org/wiki/Macintosh_Programmer%27s_Workshop MPW C++] compiler.
+Version number available as major, and minor.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__MRC__`] [__predef_detection__]]
+    [[`MPW_C`] [__predef_detection__]]
+    [[`MPW_CPLUS`] [__predef_detection__]]
+
+    [[`__MRC__`] [V.R.0]]
+    ]
+ */
+
+#define BOOST_COMP_MPW BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__MRC__) || defined(MPW_C) || defined(MPW_CPLUS)
+#   if !defined(BOOST_COMP_MPW_DETECTION) && defined(__MRC__)
+#       define BOOST_COMP_MPW_DETECTION BOOST_PREDEF_MAKE_0X_VVRR(__MRC__)
+#   endif
+#   if !defined(BOOST_COMP_MPW_DETECTION)
+#       define BOOST_COMP_MPW_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#ifdef BOOST_COMP_MPW_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_MPW_EMULATED BOOST_COMP_MPW_DETECTION
+#   else
+#       undef BOOST_COMP_MPW
+#       define BOOST_COMP_MPW BOOST_COMP_MPW_DETECTION
+#   endif
+#   define BOOST_COMP_MPW_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_MPW_NAME "MPW C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MPW,BOOST_COMP_MPW_NAME)
+
+#ifdef BOOST_COMP_MPW_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MPW_EMULATED,BOOST_COMP_MPW_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/palm.h b/third_party/boost/boost/predef/compiler/palm.h
new file mode 100644
index 0000000..707925a
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/palm.h
@@ -0,0 +1,56 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_PALM_H
+#define BOOST_PREDEF_COMPILER_PALM_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_PALM`]
+
+Palm C/C++ compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`_PACC_VER`] [__predef_detection__]]
+
+    [[`_PACC_VER`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_PALM BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(_PACC_VER)
+#   define BOOST_COMP_PALM_DETECTION BOOST_PREDEF_MAKE_0X_VRRPP000(_PACC_VER)
+#endif
+
+#ifdef BOOST_COMP_PALM_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_PALM_EMULATED BOOST_COMP_PALM_DETECTION
+#   else
+#       undef BOOST_COMP_PALM
+#       define BOOST_COMP_PALM BOOST_COMP_PALM_DETECTION
+#   endif
+#   define BOOST_COMP_PALM_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_PALM_NAME "Palm C/C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PALM,BOOST_COMP_PALM_NAME)
+
+#ifdef BOOST_COMP_PALM_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PALM_EMULATED,BOOST_COMP_PALM_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/pgi.h b/third_party/boost/boost/predef/compiler/pgi.h
new file mode 100644
index 0000000..e016aeb
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/pgi.h
@@ -0,0 +1,60 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_PGI_H
+#define BOOST_PREDEF_COMPILER_PGI_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_PGI`]
+
+[@http://en.wikipedia.org/wiki/The_Portland_Group Portland Group C/C++] compiler.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__PGI`] [__predef_detection__]]
+
+    [[`__PGIC__`, `__PGIC_MINOR__`, `__PGIC_PATCHLEVEL__`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_PGI BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__PGI)
+#   if !defined(BOOST_COMP_PGI_DETECTION) && (defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__))
+#       define BOOST_COMP_PGI_DETECTION BOOST_VERSION_NUMBER(__PGIC__,__PGIC_MINOR__,__PGIC_PATCHLEVEL__)
+#   endif
+#   if !defined(BOOST_COMP_PGI_DETECTION)
+#       define BOOST_COMP_PGI_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#ifdef BOOST_COMP_PGI_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_PGI_EMULATED BOOST_COMP_PGI_DETECTION
+#   else
+#       undef BOOST_COMP_PGI
+#       define BOOST_COMP_PGI BOOST_COMP_PGI_DETECTION
+#   endif
+#   define BOOST_COMP_PGI_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_PGI_NAME "Portland Group C/C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PGI,BOOST_COMP_PGI_NAME)
+
+#ifdef BOOST_COMP_PGI_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_PGI_EMULATED,BOOST_COMP_PGI_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/sgi_mipspro.h b/third_party/boost/boost/predef/compiler/sgi_mipspro.h
new file mode 100644
index 0000000..00739f0
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/sgi_mipspro.h
@@ -0,0 +1,66 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_SGI_MIPSPRO_H
+#define BOOST_PREDEF_COMPILER_SGI_MIPSPRO_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_SGI`]
+
+[@http://en.wikipedia.org/wiki/MIPSpro SGI MIPSpro] compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__sgi`] [__predef_detection__]]
+    [[`sgi`] [__predef_detection__]]
+
+    [[`_SGI_COMPILER_VERSION`] [V.R.P]]
+    [[`_COMPILER_VERSION`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_SGI BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__sgi) || defined(sgi)
+#   if !defined(BOOST_COMP_SGI_DETECTION) && defined(_SGI_COMPILER_VERSION)
+#       define BOOST_COMP_SGI_DETECTION BOOST_PREDEF_MAKE_10_VRP(_SGI_COMPILER_VERSION)
+#   endif
+#   if !defined(BOOST_COMP_SGI_DETECTION) && defined(_COMPILER_VERSION)
+#       define BOOST_COMP_SGI_DETECTION BOOST_PREDEF_MAKE_10_VRP(_COMPILER_VERSION)
+#   endif
+#   if !defined(BOOST_COMP_SGI_DETECTION)
+#       define BOOST_COMP_SGI_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#ifdef BOOST_COMP_SGI_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_SGI_EMULATED BOOST_COMP_SGI_DETECTION
+#   else
+#       undef BOOST_COMP_SGI
+#       define BOOST_COMP_SGI BOOST_COMP_SGI_DETECTION
+#   endif
+#   define BOOST_COMP_SGI_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_SGI_NAME "SGI MIPSpro"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SGI,BOOST_COMP_SGI_NAME)
+
+#ifdef BOOST_COMP_SGI_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SGI_EMULATED,BOOST_COMP_SGI_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/sunpro.h b/third_party/boost/boost/predef/compiler/sunpro.h
new file mode 100644
index 0000000..92c3926
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/sunpro.h
@@ -0,0 +1,76 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_SUNPRO_H
+#define BOOST_PREDEF_COMPILER_SUNPRO_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_SUNPRO`]
+
+[@http://en.wikipedia.org/wiki/Oracle_Solaris_Studio Oracle Solaris Studio] compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__SUNPRO_CC`] [__predef_detection__]]
+    [[`__SUNPRO_C`] [__predef_detection__]]
+
+    [[`__SUNPRO_CC`] [V.R.P]]
+    [[`__SUNPRO_C`] [V.R.P]]
+    [[`__SUNPRO_CC`] [VV.RR.P]]
+    [[`__SUNPRO_C`] [VV.RR.P]]
+    ]
+ */
+
+#define BOOST_COMP_SUNPRO BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__SUNPRO_CC) || defined(__SUNPRO_C)
+#   if !defined(BOOST_COMP_SUNPRO_DETECTION) && defined(__SUNPRO_CC)
+#       if (__SUNPRO_CC < 0x5100)
+#           define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__SUNPRO_CC)
+#       else
+#           define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VVRRP(__SUNPRO_CC)
+#       endif
+#   endif
+#   if !defined(BOOST_COMP_SUNPRO_DETECTION) && defined(__SUNPRO_C)
+#       if (__SUNPRO_C < 0x5100)
+#           define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VRP(__SUNPRO_C)
+#       else
+#           define BOOST_COMP_SUNPRO_DETECTION BOOST_PREDEF_MAKE_0X_VVRRP(__SUNPRO_C)
+#       endif
+#   endif
+#   if !defined(BOOST_COMP_SUNPRO_DETECTION)
+#       define BOOST_COMP_SUNPRO_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#ifdef BOOST_COMP_SUNPRO_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_SUNPRO_EMULATED BOOST_COMP_SUNPRO_DETECTION
+#   else
+#       undef BOOST_COMP_SUNPRO
+#       define BOOST_COMP_SUNPRO BOOST_COMP_SUNPRO_DETECTION
+#   endif
+#   define BOOST_COMP_SUNPRO_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_SUNPRO_NAME "Oracle Solaris Studio"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SUNPRO,BOOST_COMP_SUNPRO_NAME)
+
+#ifdef BOOST_COMP_SUNPRO_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_SUNPRO_EMULATED,BOOST_COMP_SUNPRO_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/tendra.h b/third_party/boost/boost/predef/compiler/tendra.h
new file mode 100644
index 0000000..c2bc5e4
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/tendra.h
@@ -0,0 +1,53 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_TENDRA_H
+#define BOOST_PREDEF_COMPILER_TENDRA_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_TENDRA`]
+
+[@http://en.wikipedia.org/wiki/TenDRA_Compiler TenDRA C/C++] compiler.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__TenDRA__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_COMP_TENDRA BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__TenDRA__)
+#   define BOOST_COMP_TENDRA_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#ifdef BOOST_COMP_TENDRA_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_TENDRA_EMULATED BOOST_COMP_TENDRA_DETECTION
+#   else
+#       undef BOOST_COMP_TENDRA
+#       define BOOST_COMP_TENDRA BOOST_COMP_TENDRA_DETECTION
+#   endif
+#   define BOOST_COMP_TENDRA_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_TENDRA_NAME "TenDRA C/C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_TENDRA,BOOST_COMP_TENDRA_NAME)
+
+#ifdef BOOST_COMP_TENDRA_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_TENDRA_EMULATED,BOOST_COMP_TENDRA_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/visualc.h b/third_party/boost/boost/predef/compiler/visualc.h
new file mode 100644
index 0000000..9481d9d
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/visualc.h
@@ -0,0 +1,91 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_VISUALC_H
+#define BOOST_PREDEF_COMPILER_VISUALC_H
+
+/* Other compilers that emulate this one need to be detected first. */
+
+#include <boost/predef/compiler/clang.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_MSVC`]
+
+[@http://en.wikipedia.org/wiki/Visual_studio Microsoft Visual C/C++] compiler.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`_MSC_VER`] [__predef_detection__]]
+
+    [[`_MSC_FULL_VER`] [V.R.P]]
+    [[`_MSC_VER`] [V.R.0]]
+    ]
+ */
+
+#define BOOST_COMP_MSVC BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(_MSC_VER)
+#   if !defined (_MSC_FULL_VER)
+#       define BOOST_COMP_MSVC_BUILD 0
+#   else
+        /* how many digits does the build number have? */
+#       if _MSC_FULL_VER / 10000 == _MSC_VER
+            /* four digits */
+#           define BOOST_COMP_MSVC_BUILD (_MSC_FULL_VER % 10000)
+#       elif _MSC_FULL_VER / 100000 == _MSC_VER
+            /* five digits */
+#           define BOOST_COMP_MSVC_BUILD (_MSC_FULL_VER % 100000)
+#       else
+#           error "Cannot determine build number from _MSC_FULL_VER"
+#       endif
+#   endif
+    /*
+    VS2014 was skipped in the release sequence for MS. Which
+    means that the compiler and VS product versions are no longer
+    in sync. Hence we need to use different formulas for
+    mapping from MSC version to VS product version.
+    */
+#   if (_MSC_VER >= 1900)
+#       define BOOST_COMP_MSVC_DETECTION BOOST_VERSION_NUMBER(\
+            _MSC_VER/100-5,\
+            _MSC_VER%100,\
+            BOOST_COMP_MSVC_BUILD)
+#   else
+#       define BOOST_COMP_MSVC_DETECTION BOOST_VERSION_NUMBER(\
+            _MSC_VER/100-6,\
+            _MSC_VER%100,\
+            BOOST_COMP_MSVC_BUILD)
+#   endif
+#endif
+
+#ifdef BOOST_COMP_MSVC_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_MSVC_EMULATED BOOST_COMP_MSVC_DETECTION
+#   else
+#       undef BOOST_COMP_MSVC
+#       define BOOST_COMP_MSVC BOOST_COMP_MSVC_DETECTION
+#   endif
+#   define BOOST_COMP_MSVC_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_MSVC_NAME "Microsoft Visual C/C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MSVC,BOOST_COMP_MSVC_NAME)
+
+#ifdef BOOST_COMP_MSVC_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_MSVC_EMULATED,BOOST_COMP_MSVC_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/compiler/watcom.h b/third_party/boost/boost/predef/compiler/watcom.h
new file mode 100644
index 0000000..b0e7776
--- /dev/null
+++ b/third_party/boost/boost/predef/compiler/watcom.h
@@ -0,0 +1,56 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_WATCOM_H
+#define BOOST_PREDEF_COMPILER_WATCOM_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_COMP_WATCOM`]
+
+[@http://en.wikipedia.org/wiki/Watcom Watcom C++] compiler.
+Version number available as major, and minor.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__WATCOMC__`] [__predef_detection__]]
+
+    [[`__WATCOMC__`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_COMP_WATCOM BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__WATCOMC__)
+#   define BOOST_COMP_WATCOM_DETECTION BOOST_PREDEF_MAKE_10_VVRR(__WATCOMC__)
+#endif
+
+#ifdef BOOST_COMP_WATCOM_DETECTION
+#   if defined(BOOST_PREDEF_DETAIL_COMP_DETECTED)
+#       define BOOST_COMP_WATCOM_EMULATED BOOST_COMP_WATCOM_DETECTION
+#   else
+#       undef BOOST_COMP_WATCOM
+#       define BOOST_COMP_WATCOM BOOST_COMP_WATCOM_DETECTION
+#   endif
+#   define BOOST_COMP_WATCOM_AVAILABLE
+#   include <boost/predef/detail/comp_detected.h>
+#endif
+
+#define BOOST_COMP_WATCOM_NAME "Watcom C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_WATCOM,BOOST_COMP_WATCOM_NAME)
+
+#ifdef BOOST_COMP_WATCOM_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_COMP_WATCOM_EMULATED,BOOST_COMP_WATCOM_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/detail/_cassert.h b/third_party/boost/boost/predef/detail/_cassert.h
new file mode 100644
index 0000000..940e944
--- /dev/null
+++ b/third_party/boost/boost/predef/detail/_cassert.h
@@ -0,0 +1,17 @@
+/*
+Copyright Rene Rivera 2011-2012
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_DETAIL__CASSERT_H
+#define BOOST_PREDEF_DETAIL__CASSERT_H
+
+#if defined(__cplusplus)
+#include <cassert>
+#else
+#include <assert.h>
+#endif
+
+#endif
diff --git a/third_party/boost/boost/predef/detail/_exception.h b/third_party/boost/boost/predef/detail/_exception.h
new file mode 100644
index 0000000..f5a6687
--- /dev/null
+++ b/third_party/boost/boost/predef/detail/_exception.h
@@ -0,0 +1,15 @@
+/*
+Copyright Rene Rivera 2011-2012
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_DETAIL__EXCEPTION_H
+#define BOOST_PREDEF_DETAIL__EXCEPTION_H
+
+#if defined(__cplusplus)
+#include <exception>
+#endif
+
+#endif
diff --git a/third_party/boost/boost/predef/detail/comp_detected.h b/third_party/boost/boost/predef/detail/comp_detected.h
new file mode 100644
index 0000000..fda1801
--- /dev/null
+++ b/third_party/boost/boost/predef/detail/comp_detected.h
@@ -0,0 +1,10 @@
+/*
+Copyright Rene Rivera 2014
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_DETAIL_COMP_DETECTED
+#define BOOST_PREDEF_DETAIL_COMP_DETECTED 1
+#endif
diff --git a/third_party/boost/boost/predef/detail/os_detected.h b/third_party/boost/boost/predef/detail/os_detected.h
new file mode 100644
index 0000000..08e10f9
--- /dev/null
+++ b/third_party/boost/boost/predef/detail/os_detected.h
@@ -0,0 +1,10 @@
+/*
+Copyright Rene Rivera 2013
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_DETAIL_OS_DETECTED
+#define BOOST_PREDEF_DETAIL_OS_DETECTED 1
+#endif
diff --git a/third_party/boost/boost/predef/detail/test.h b/third_party/boost/boost/predef/detail/test.h
new file mode 100644
index 0000000..546a9e4
--- /dev/null
+++ b/third_party/boost/boost/predef/detail/test.h
@@ -0,0 +1,17 @@
+/*
+Copyright Rene Rivera 2011-2012
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_DETAIL_TEST_H
+#define BOOST_PREDEF_DETAIL_TEST_H
+
+#if !defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
+
+#define BOOST_PREDEF_DECLARE_TEST(x,s)
+
+#endif
+
+#endif
diff --git a/third_party/boost/boost/predef/hardware.h b/third_party/boost/boost/predef/hardware.h
new file mode 100644
index 0000000..972b73a
--- /dev/null
+++ b/third_party/boost/boost/predef/hardware.h
@@ -0,0 +1,16 @@
+/*
+Copyright Charly Chevalier 2015
+Copyright Joel Falcou 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#if !defined(BOOST_PREDEF_HARDWARE_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
+#ifndef BOOST_PREDEF_HARDWARE_H
+#define BOOST_PREDEF_HARDWARE_H
+#endif
+
+#include <boost/predef/hardware/simd.h>
+
+#endif
diff --git a/third_party/boost/boost/predef/hardware/simd.h b/third_party/boost/boost/predef/hardware/simd.h
new file mode 100644
index 0000000..4de1e70
--- /dev/null
+++ b/third_party/boost/boost/predef/hardware/simd.h
@@ -0,0 +1,107 @@
+/*
+Copyright Charly Chevalier 2015
+Copyright Joel Falcou 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#include <boost/predef/hardware/simd/x86.h>
+#include <boost/predef/hardware/simd/x86_amd.h>
+#include <boost/predef/hardware/simd/arm.h>
+#include <boost/predef/hardware/simd/ppc.h>
+
+#ifndef BOOST_PREDEF_HARDWARE_SIMD_H
+#define BOOST_PREDEF_HARDWARE_SIMD_H
+
+#include <boost/predef/version_number.h>
+
+/*`
+ [section Using the `BOOST_HW_SIMD_*` predefs]
+ [include ../doc/hardware_simd.qbk]
+ [endsect]
+
+ [/ --------------------------- ]
+
+ [section `BOOST_HW_SIMD_*`]
+
+ [heading `BOOST_HW_SIMD`]
+
+ The SIMD extension detected for a specific architectures.
+ Version number depends on the detected extension.
+
+ [table
+     [[__predef_symbol__] [__predef_version__]]
+
+     [[`BOOST_HW_SIMD_X86_AVAILABLE`] [__predef_detection__]]
+     [[`BOOST_HW_SIMD_X86_AMD_AVAILABLE`] [__predef_detection__]]
+     [[`BOOST_HW_SIMD_ARM_AVAILABLE`] [__predef_detection__]]
+     [[`BOOST_HW_SIMD_PPC_AVAILABLE`] [__predef_detection__]]
+     ]
+
+ [include ../include/boost/predef/hardware/simd/x86.h]
+ [include ../include/boost/predef/hardware/simd/x86_amd.h]
+ [include ../include/boost/predef/hardware/simd/arm.h]
+ [include ../include/boost/predef/hardware/simd/ppc.h]
+
+ [endsect]
+
+ [/ --------------------------- ]
+
+ [section `BOOST_HW_SIMD_X86_*_VERSION`]
+ [include ../include/boost/predef/hardware/simd/x86/versions.h]
+ [endsect]
+
+ [section `BOOST_HW_SIMD_X86_AMD_*_VERSION`]
+ [include ../include/boost/predef/hardware/simd/x86_amd/versions.h]
+ [endsect]
+
+ [section `BOOST_HW_SIMD_ARM_*_VERSION`]
+ [include ../include/boost/predef/hardware/simd/arm/versions.h]
+ [endsect]
+
+ [section `BOOST_HW_SIMD_PPC_*_VERSION`]
+ [include ../include/boost/predef/hardware/simd/ppc/versions.h]
+ [endsect]
+
+ */
+
+// We check if SIMD extension of multiples architectures have been detected,
+// if yes, then this is an error!
+//
+// NOTE: _X86_AMD implies _X86, so there is no need to check for it here!
+//
+#if defined(BOOST_HW_SIMD_ARM_AVAILABLE) && defined(BOOST_HW_SIMD_PPC_AVAILABLE) ||\
+    defined(BOOST_HW_SIMD_ARM_AVAILABLE) && defined(BOOST_HW_SIMD_X86_AVAILABLE) ||\
+    defined(BOOST_HW_SIMD_PPC_AVAILABLE) && defined(BOOST_HW_SIMD_X86_AVAILABLE)
+#   error "Multiple SIMD architectures detected, this cannot happen!"
+#endif
+
+#if defined(BOOST_HW_SIMD_X86_AVAILABLE)
+#   define BOOST_HW_SIMD BOOST_HW_SIMD_X86
+#endif
+
+#if defined(BOOST_HW_SIMD_X86_AMD_AVAILABLE)
+#   define BOOST_HW_SIMD BOOST_HW_SIMD_X86_AMD
+#endif
+
+#if defined(BOOST_HW_SIMD_ARM_AVAILABLE)
+#   define BOOST_HW_SIMD BOOST_HW_SIMD_ARM
+#endif
+
+#if defined(BOOST_HW_SIMD_PPC_AVAILABLE)
+#   define BOOST_HW_SIMD BOOST_HW_SIMD_PPC
+#endif
+
+#if defined(BOOST_HW_SIMD)
+#   define BOOST_HW_SIMD_AVAILABLE
+#else
+#   define BOOST_HW_SIMD BOOST_VERSION_NUMBER_NOT_AVAILABLE
+#endif
+
+#define BOOST_HW_SIMD_NAME "Hardware SIMD"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD, BOOST_HW_SIMD_NAME)
diff --git a/third_party/boost/boost/predef/hardware/simd/arm.h b/third_party/boost/boost/predef/hardware/simd/arm.h
new file mode 100644
index 0000000..d067c93
--- /dev/null
+++ b/third_party/boost/boost/predef/hardware/simd/arm.h
@@ -0,0 +1,57 @@
+/*
+Copyright Charly Chevalier 2015
+Copyright Joel Falcou 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_HARDWARE_SIMD_ARM_H
+#define BOOST_PREDEF_HARDWARE_SIMD_ARM_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/hardware/simd/arm/versions.h>
+
+/*`
+ [heading `BOOST_HW_SIMD_ARM`]
+
+ The SIMD extension for ARM (*if detected*).
+ Version number depends on the most recent detected extension.
+
+ [table
+     [[__predef_symbol__] [__predef_version__]]
+
+     [[`__ARM_NEON__`] [__predef_detection__]]
+     [[`__aarch64__`] [__predef_detection__]]
+     [[`_M_ARM`] [__predef_detection__]]
+     ]
+
+ [table
+     [[__predef_symbol__] [__predef_version__]]
+
+     [[`__ARM_NEON__`] [BOOST_HW_SIMD_ARM_NEON_VERSION]]
+     [[`__aarch64__`] [BOOST_HW_SIMD_ARM_NEON_VERSION]]
+     [[`_M_ARM`] [BOOST_HW_SIMD_ARM_NEON_VERSION]]
+     ]
+
+ */
+
+#define BOOST_HW_SIMD_ARM BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#undef BOOST_HW_SIMD_ARM
+#if !defined(BOOST_HW_SIMD_ARM) && (defined(__ARM_NEON__) || defined(__aarch64__) || defined (_M_ARM))
+#   define BOOST_HW_SIMD_ARM BOOST_HW_SIMD_ARM_NEON_VERSION
+#endif
+
+#if !defined(BOOST_HW_SIMD_ARM)
+#   define BOOST_HW_SIMD_ARM BOOST_VERSION_NUMBER_NOT_AVAILABLE
+#else
+#   define BOOST_HW_SIMD_ARM_AVAILABLE
+#endif
+
+#define BOOST_HW_SIMD_ARM_NAME "ARM SIMD"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD_ARM, BOOST_HW_SIMD_ARM_NAME)
diff --git a/third_party/boost/boost/predef/hardware/simd/arm/versions.h b/third_party/boost/boost/predef/hardware/simd/arm/versions.h
new file mode 100644
index 0000000..8425b31
--- /dev/null
+++ b/third_party/boost/boost/predef/hardware/simd/arm/versions.h
@@ -0,0 +1,32 @@
+/*
+Copyright Charly Chevalier 2015
+Copyright Joel Falcou 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_HARDWARE_SIMD_ARM_VERSIONS_H
+#define BOOST_PREDEF_HARDWARE_SIMD_ARM_VERSIONS_H
+
+#include <boost/predef/version_number.h>
+
+/*`
+ Those defines represent ARM SIMD extensions versions.
+
+ [note You *MUST* compare them with the predef `BOOST_HW_SIMD_ARM`.]
+ */
+
+// ---------------------------------
+
+/*`
+ [heading `BOOST_HW_SIMD_ARM_NEON_VERSION`]
+
+ The [@https://en.wikipedia.org/wiki/ARM_architecture#Advanced_SIMD_.28NEON.29 NEON]
+ ARM extension version number.
+
+ Version number is: *1.0.0*.
+ */
+#define BOOST_HW_SIMD_ARM_NEON_VERSION BOOST_VERSION_NUMBER(1, 0, 0)
+
+#endif
diff --git a/third_party/boost/boost/predef/hardware/simd/ppc.h b/third_party/boost/boost/predef/hardware/simd/ppc.h
new file mode 100644
index 0000000..eef25c2
--- /dev/null
+++ b/third_party/boost/boost/predef/hardware/simd/ppc.h
@@ -0,0 +1,69 @@
+/*
+Copyright Charly Chevalier 2015
+Copyright Joel Falcou 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_HARDWARE_SIMD_PPC_H
+#define BOOST_PREDEF_HARDWARE_SIMD_PPC_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/hardware/simd/ppc/versions.h>
+
+/*`
+ [heading `BOOST_HW_SIMD_PPC`]
+
+ The SIMD extension for PowerPC (*if detected*).
+ Version number depends on the most recent detected extension.
+
+ [table
+     [[__predef_symbol__] [__predef_version__]]
+
+     [[`__VECTOR4DOUBLE__`] [__predef_detection__]]
+
+     [[`__ALTIVEC__`] [__predef_detection__]]
+     [[`__VEC__`] [__predef_detection__]]
+
+     [[`__VSX__`] [__predef_detection__]]
+     ]
+
+ [table
+     [[__predef_symbol__] [__predef_version__]]
+
+     [[`__VECTOR4DOUBLE__`] [BOOST_HW_SIMD_PPC_QPX_VERSION]]
+
+     [[`__ALTIVEC__`] [BOOST_HW_SIMD_PPC_VMX_VERSION]]
+     [[`__VEC__`] [BOOST_HW_SIMD_PPC_VMX_VERSION]]
+
+     [[`__VSX__`] [BOOST_HW_SIMD_PPC_VSX_VERSION]]
+     ]
+
+ */
+
+#define BOOST_HW_SIMD_PPC BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#undef BOOST_HW_SIMD_PPC
+#if !defined(BOOST_HW_SIMD_PPC) && defined(__VECTOR4DOUBLE__)
+#   define BOOST_HW_SIMD_PPC BOOST_HW_SIMD_PPC_QPX_VERSION
+#endif
+#if !defined(BOOST_HW_SIMD_PPC) && defined(__VSX__)
+#   define BOOST_HW_SIMD_PPC BOOST_HW_SIMD_PPC_VSX_VERSION
+#endif
+#if !defined(BOOST_HW_SIMD_PPC) && (defined(__ALTIVEC__) || defined(__VEC__))
+#   define BOOST_HW_SIMD_PPC BOOST_HW_SIMD_PPC_VMX_VERSION
+#endif
+
+#if !defined(BOOST_HW_SIMD_PPC)
+#   define BOOST_HW_SIMD_PPC BOOST_VERSION_NUMBER_NOT_AVAILABLE
+#else
+#   define BOOST_HW_SIMD_PPC_AVAILABLE
+#endif
+
+#define BOOST_HW_SIMD_PPC_NAME "PPC SIMD"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD_PPC, BOOST_HW_SIMD_PPC_NAME)
diff --git a/third_party/boost/boost/predef/hardware/simd/ppc/versions.h b/third_party/boost/boost/predef/hardware/simd/ppc/versions.h
new file mode 100644
index 0000000..ffe3f0b
--- /dev/null
+++ b/third_party/boost/boost/predef/hardware/simd/ppc/versions.h
@@ -0,0 +1,51 @@
+/*
+Copyright Charly Chevalier 2015
+Copyright Joel Falcou 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_HARDWARE_SIMD_PPC_VERSIONS_H
+#define BOOST_PREDEF_HARDWARE_SIMD_PPC_VERSIONS_H
+
+#include <boost/predef/version_number.h>
+
+/*`
+ Those defines represent Power PC SIMD extensions versions.
+
+ [note You *MUST* compare them with the predef `BOOST_HW_SIMD_PPC`.]
+ */
+
+// ---------------------------------
+
+/*`
+ [heading `BOOST_HW_SIMD_PPC_VMX_VERSION`]
+
+ The [@https://en.wikipedia.org/wiki/AltiVec#VMX128 VMX] powerpc extension
+ version number.
+
+ Version number is: *1.0.0*.
+ */
+#define BOOST_HW_SIMD_PPC_VMX_VERSION BOOST_VERSION_NUMBER(1, 0, 0)
+
+/*`
+ [heading `BOOST_HW_SIMD_PPC_VSX_VERSION`]
+
+ The [@https://en.wikipedia.org/wiki/AltiVec#VSX VSX] powerpc extension version
+ number.
+
+ Version number is: *1.1.0*.
+ */
+#define BOOST_HW_SIMD_PPC_VSX_VERSION BOOST_VERSION_NUMBER(1, 1, 0)
+
+/*`
+ [heading `BOOST_HW_SIMD_PPC_QPX_VERSION`]
+
+ The QPX powerpc extension version number.
+
+ Version number is: *2.0.0*.
+ */
+#define BOOST_HW_SIMD_PPC_QPX_VERSION BOOST_VERSION_NUMBER(2, 0, 0)
+
+#endif
diff --git a/third_party/boost/boost/predef/hardware/simd/x86.h b/third_party/boost/boost/predef/hardware/simd/x86.h
new file mode 100644
index 0000000..0874bc4
--- /dev/null
+++ b/third_party/boost/boost/predef/hardware/simd/x86.h
@@ -0,0 +1,123 @@
+/*
+Copyright Charly Chevalier 2015
+Copyright Joel Falcou 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_HARDWARE_SIMD_X86_H
+#define BOOST_PREDEF_HARDWARE_SIMD_X86_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/hardware/simd/x86/versions.h>
+
+/*`
+ [heading `BOOST_HW_SIMD_X86`]
+
+ The SIMD extension for x86 (*if detected*).
+ Version number depends on the most recent detected extension.
+
+ [table
+     [[__predef_symbol__] [__predef_version__]]
+
+     [[`__SSE__`] [__predef_detection__]]
+     [[`_M_X64`] [__predef_detection__]]
+     [[`_M_IX86_FP >= 1`] [__predef_detection__]]
+
+     [[`__SSE2__`] [__predef_detection__]]
+     [[`_M_X64`] [__predef_detection__]]
+     [[`_M_IX86_FP >= 2`] [__predef_detection__]]
+
+     [[`__SSE3__`] [__predef_detection__]]
+
+     [[`__SSSE3__`] [__predef_detection__]]
+
+     [[`__SSE4_1__`] [__predef_detection__]]
+
+     [[`__SSE4_2__`] [__predef_detection__]]
+
+     [[`__AVX__`] [__predef_detection__]]
+
+     [[`__FMA__`] [__predef_detection__]]
+
+     [[`__AVX2__`] [__predef_detection__]]
+     ]
+
+ [table
+     [[__predef_symbol__] [__predef_version__]]
+
+     [[`__SSE__`] [BOOST_HW_SIMD_X86_SSE_VERSION]]
+     [[`_M_X64`] [BOOST_HW_SIMD_X86_SSE_VERSION]]
+     [[`_M_IX86_FP >= 1`] [BOOST_HW_SIMD_X86_SSE_VERSION]]
+
+     [[`__SSE2__`] [BOOST_HW_SIMD_X86_SSE2_VERSION]]
+     [[`_M_X64`] [BOOST_HW_SIMD_X86_SSE2_VERSION]]
+     [[`_M_IX86_FP >= 2`] [BOOST_HW_SIMD_X86_SSE2_VERSION]]
+
+     [[`__SSE3__`] [BOOST_HW_SIMD_X86_SSE3_VERSION]]
+
+     [[`__SSSE3__`] [BOOST_HW_SIMD_X86_SSSE3_VERSION]]
+
+     [[`__SSE4_1__`] [BOOST_HW_SIMD_X86_SSE4_1_VERSION]]
+
+     [[`__SSE4_2__`] [BOOST_HW_SIMD_X86_SSE4_2_VERSION]]
+
+     [[`__AVX__`] [BOOST_HW_SIMD_X86_AVX_VERSION]]
+
+     [[`__FMA__`] [BOOST_HW_SIMD_X86_FMA3_VERSION]]
+
+     [[`__AVX2__`] [BOOST_HW_SIMD_x86_AVX2_VERSION]]
+     ]
+
+ */
+
+#define BOOST_HW_SIMD_X86 BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#undef BOOST_HW_SIMD_X86
+#if !defined(BOOST_HW_SIMD_X86) && defined(__MIC__)
+#   define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_MIC_VERSION
+#endif
+#if !defined(BOOST_HW_SIMD_X86) && defined(__AVX2__)
+#   define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_AVX2_VERSION
+#endif
+#if !defined(BOOST_HW_SIMD_X86) && defined(__AVX__)
+#   define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_AVX_VERSION
+#endif
+#if !defined(BOOST_HW_SIMD_X86) && defined(__FMA__)
+#   define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_FMA_VERSION
+#endif
+#if !defined(BOOST_HW_SIMD_X86) && defined(__SSE4_2__)
+#   define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSE4_2_VERSION
+#endif
+#if !defined(BOOST_HW_SIMD_X86) && defined(__SSE4_1__)
+#   define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSE4_1_VERSION
+#endif
+#if !defined(BOOST_HW_SIMD_X86) && defined(__SSSE3__)
+#   define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSSE3_VERSION
+#endif
+#if !defined(BOOST_HW_SIMD_X86) && defined(__SSE3__)
+#   define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSE3_VERSION
+#endif
+#if !defined(BOOST_HW_SIMD_X86) && (defined(__SSE2__) || defined(_M_X64) || _M_IX86_FP >= 2)
+#   define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSE2_VERSION
+#endif
+#if !defined(BOOST_HW_SIMD_X86) && (defined(__SSE__) || defined(_M_X64) || _M_IX86_FP >= 1)
+#   define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_SSE_VERSION
+#endif
+#if !defined(BOOST_HW_SIMD_X86) && defined(__MMX__)
+#   define BOOST_HW_SIMD_X86 BOOST_HW_SIMD_X86_MMX_VERSION
+#endif
+
+#if !defined(BOOST_HW_SIMD_X86)
+#   define BOOST_HW_SIMD_X86 BOOST_VERSION_NUMBER_NOT_AVAILABLE
+#else
+#   define BOOST_HW_SIMD_X86_AVAILABLE
+#endif
+
+#define BOOST_HW_SIMD_X86_NAME "x86 SIMD"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD_X86, BOOST_HW_SIMD_X86_NAME)
diff --git a/third_party/boost/boost/predef/hardware/simd/x86/versions.h b/third_party/boost/boost/predef/hardware/simd/x86/versions.h
new file mode 100644
index 0000000..0c7a4d3
--- /dev/null
+++ b/third_party/boost/boost/predef/hardware/simd/x86/versions.h
@@ -0,0 +1,129 @@
+/*
+Copyright Charly Chevalier 2015
+Copyright Joel Falcou 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_HARDWARE_SIMD_X86_VERSIONS_H
+#define BOOST_PREDEF_HARDWARE_SIMD_X86_VERSIONS_H
+
+#include <boost/predef/version_number.h>
+
+/*`
+ Those defines represent x86 SIMD extensions versions.
+
+ [note You *MUST* compare them with the predef `BOOST_HW_SIMD_X86`.]
+ */
+
+// ---------------------------------
+
+/*`
+ [heading `BOOST_HW_SIMD_X86_MMX_VERSION`]
+
+ The [@https://en.wikipedia.org/wiki/MMX_(instruction_set) MMX] x86 extension
+ version number.
+
+ Version number is: *0.99.0*.
+ */
+#define BOOST_HW_SIMD_X86_MMX_VERSION BOOST_VERSION_NUMBER(0, 99, 0)
+
+/*`
+ [heading `BOOST_HW_SIMD_X86_SSE_VERSION`]
+
+ The [@https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions SSE] x86 extension
+ version number.
+
+ Version number is: *1.0.0*.
+ */
+#define BOOST_HW_SIMD_X86_SSE_VERSION BOOST_VERSION_NUMBER(1, 0, 0)
+
+/*`
+ [heading `BOOST_HW_SIMD_X86_SSE2_VERSION`]
+
+ The [@https://en.wikipedia.org/wiki/SSE2 SSE2] x86 extension version number.
+
+ Version number is: *2.0.0*.
+ */
+#define BOOST_HW_SIMD_X86_SSE2_VERSION BOOST_VERSION_NUMBER(2, 0, 0)
+
+/*`
+ [heading `BOOST_HW_SIMD_X86_SSE3_VERSION`]
+
+ The [@https://en.wikipedia.org/wiki/SSE3 SSE3] x86 extension version number.
+
+ Version number is: *3.0.0*.
+ */
+#define BOOST_HW_SIMD_X86_SSE3_VERSION BOOST_VERSION_NUMBER(3, 0, 0)
+
+/*`
+ [heading `BOOST_HW_SIMD_X86_SSSE3_VERSION`]
+
+ The [@https://en.wikipedia.org/wiki/SSSE3 SSSE3] x86 extension version number.
+
+ Version number is: *3.1.0*.
+ */
+#define BOOST_HW_SIMD_X86_SSSE3_VERSION BOOST_VERSION_NUMBER(3, 1, 0)
+
+/*`
+ [heading `BOOST_HW_SIMD_X86_SSE4_1_VERSION`]
+
+ The [@https://en.wikipedia.org/wiki/SSE4#SSE4.1 SSE4_1] x86 extension version
+ number.
+
+ Version number is: *4.1.0*.
+ */
+#define BOOST_HW_SIMD_X86_SSE4_1_VERSION BOOST_VERSION_NUMBER(4, 1, 0)
+
+/*`
+ [heading `BOOST_HW_SIMD_X86_SSE4_2_VERSION`]
+
+ The [@https://en.wikipedia.org/wiki/SSE4##SSE4.2 SSE4_2] x86 extension version
+ number.
+
+ Version number is: *4.2.0*.
+ */
+#define BOOST_HW_SIMD_X86_SSE4_2_VERSION BOOST_VERSION_NUMBER(4, 2, 0)
+
+/*`
+ [heading `BOOST_HW_SIMD_X86_AVX_VERSION`]
+
+ The [@https://en.wikipedia.org/wiki/Advanced_Vector_Extensions AVX] x86
+ extension version number.
+
+ Version number is: *5.0.0*.
+ */
+#define BOOST_HW_SIMD_X86_AVX_VERSION BOOST_VERSION_NUMBER(5, 0, 0)
+
+/*`
+ [heading `BOOST_HW_SIMD_X86_FMA3_VERSION`]
+
+ The [@https://en.wikipedia.org/wiki/FMA_instruction_set FMA3] x86 extension
+ version number.
+
+ Version number is: *5.2.0*.
+ */
+#define BOOST_HW_SIMD_X86_FMA3_VERSION BOOST_VERSION_NUMBER(5, 2, 0)
+
+/*`
+ [heading `BOOST_HW_SIMD_X86_AVX2_VERSION`]
+
+ The [@https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#Advanced_Vector_Extensions_2 AVX2]
+ x86 extension version number.
+
+ Version number is: *5.3.0*.
+ */
+#define BOOST_HW_SIMD_X86_AVX2_VERSION BOOST_VERSION_NUMBER(5, 3, 0)
+
+/*`
+ [heading `BOOST_HW_SIMD_X86_MIC_VERSION`]
+
+ The [@https://en.wikipedia.org/wiki/Xeon_Phi MIC] (Xeon Phi) x86 extension
+ version number.
+
+ Version number is: *9.0.0*.
+ */
+#define BOOST_HW_SIMD_X86_MIC_VERSION BOOST_VERSION_NUMBER(9, 0, 0)
+
+#endif
diff --git a/third_party/boost/boost/predef/hardware/simd/x86_amd.h b/third_party/boost/boost/predef/hardware/simd/x86_amd.h
new file mode 100644
index 0000000..60fd448
--- /dev/null
+++ b/third_party/boost/boost/predef/hardware/simd/x86_amd.h
@@ -0,0 +1,87 @@
+/*
+Copyright Charly Chevalier 2015
+Copyright Joel Falcou 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_HARDWARE_SIMD_X86_AMD_H
+#define BOOST_PREDEF_HARDWARE_SIMD_X86_AMD_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/hardware/simd/x86_amd/versions.h>
+
+/*`
+ [heading `BOOST_HW_SIMD_X86_AMD`]
+
+ The SIMD extension for x86 (AMD) (*if detected*).
+ Version number depends on the most recent detected extension.
+
+ [table
+     [[__predef_symbol__] [__predef_version__]]
+
+     [[`__SSE4A__`] [__predef_detection__]]
+
+     [[`__FMA4__`] [__predef_detection__]]
+
+     [[`__XOP__`] [__predef_detection__]]
+
+     [[`BOOST_HW_SIMD_X86`] [__predef_detection__]]
+     ]
+
+ [table
+     [[__predef_symbol__] [__predef_version__]]
+
+     [[`__SSE4A__`] [BOOST_HW_SIMD_x86_SSE4A_VERSION]]
+
+     [[`__FMA4__`] [BOOST_HW_SIMD_x86_FMA4_VERSION]]
+
+     [[`__XOP__`] [BOOST_HW_SIMD_x86_XOP_VERSION]]
+
+     [[`BOOST_HW_SIMD_X86`] [BOOST_HW_SIMD_x86]]
+     ]
+
+ [note This predef includes every other x86 SIMD extensions and also has other
+ more specific extensions (FMA4, XOP, SSE4a). You should use this predef
+ instead of `BOOST_HW_SIMD_X86` to test if those specific extensions have
+ been detected.]
+
+ */
+
+#define BOOST_HW_SIMD_X86_AMD BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+// AMD CPUs also use x86 architecture. We first try to detect if any AMD
+// specific extension are detected, if yes, then try to detect more recent x86
+// common extensions.
+
+#undef BOOST_HW_SIMD_X86_AMD
+#if !defined(BOOST_HW_SIMD_X86_AMD) && defined(__XOP__)
+#   define BOOST_HW_SIMD_X86_AMD BOOST_HW_SIMD_X86_AMD_XOP_VERSION
+#endif
+#if !defined(BOOST_HW_SIMD_X86_AMD) && defined(__FMA4__)
+#   define BOOST_HW_SIMD_X86_AMD BOOST_HW_SIMD_X86_AMD_FMA4_VERSION
+#endif
+#if !defined(BOOST_HW_SIMD_X86_AMD) && defined(__SSE4A__)
+#   define BOOST_HW_SIMD_X86_AMD BOOST_HW_SIMD_X86_AMD_SSE4A_VERSION
+#endif
+
+#if !defined(BOOST_HW_SIMD_X86_AMD)
+#   define BOOST_HW_SIMD_X86_AMD BOOST_VERSION_NUMBER_NOT_AVAILABLE
+#else
+    // At this point, we know that we have an AMD CPU, we do need to check for
+    // other x86 extensions to determine the final version number.
+#   include <boost/predef/hardware/simd/x86.h>
+#   if BOOST_HW_SIMD_X86 > BOOST_HW_SIMD_X86_AMD
+#      undef BOOST_HW_SIMD_X86_AMD
+#      define BOOST_HW_SIMD_X86_AMD BOOST_HW_SIMD_X86
+#   endif
+#   define BOOST_HW_SIMD_X86_AMD_AVAILABLE
+#endif
+
+#define BOOST_HW_SIMD_X86_AMD_NAME "x86 (AMD) SIMD"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD_X86_AMD, BOOST_HW_SIMD_X86_AMD_NAME)
diff --git a/third_party/boost/boost/predef/hardware/simd/x86_amd/versions.h b/third_party/boost/boost/predef/hardware/simd/x86_amd/versions.h
new file mode 100644
index 0000000..a0a9e91
--- /dev/null
+++ b/third_party/boost/boost/predef/hardware/simd/x86_amd/versions.h
@@ -0,0 +1,51 @@
+/*
+Copyright Charly Chevalier 2015
+Copyright Joel Falcou 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_HARDWARE_SIMD_X86_AMD_VERSIONS_H
+#define BOOST_PREDEF_HARDWARE_SIMD_X86_AMD_VERSIONS_H
+
+#include <boost/predef/version_number.h>
+
+/*`
+ Those defines represent x86 (AMD specific) SIMD extensions versions.
+
+ [note You *MUST* compare them with the predef `BOOST_HW_SIMD_X86_AMD`.]
+ */
+
+
+// ---------------------------------
+
+/*`
+ [heading `BOOST_HW_SIMD_X86_SSE4A_VERSION`]
+
+ [@https://en.wikipedia.org/wiki/SSE4##SSE4A SSE4A] x86 extension (AMD specific).
+
+ Version number is: *4.0.0*.
+ */
+#define BOOST_HW_SIMD_X86_AMD_SSE4A_VERSION BOOST_VERSION_NUMBER(4, 0, 0)
+
+/*`
+ [heading `BOOST_HW_SIMD_X86_XOP_VERSION`]
+
+ [@https://en.wikipedia.org/wiki/XOP_instruction_set XOP] x86 extension (AMD specific).
+
+ Version number is: *5.1.0*.
+ */
+#define BOOST_HW_SIMD_X86_AMD_FMA4_VERSION BOOST_VERSION_NUMBER(5, 1, 0)
+
+/*`
+ [heading `BOOST_HW_SIMD_X86_XOP_VERSION`]
+
+ [@https://en.wikipedia.org/wiki/XOP_instruction_set XOP] x86 extension (AMD specific).
+
+ Version number is: *5.1.1*.
+ */
+#define BOOST_HW_SIMD_X86_AMD_XOP_VERSION BOOST_VERSION_NUMBER(5, 1, 1)
+
+
+#endif
diff --git a/third_party/boost/boost/predef/language.h b/third_party/boost/boost/predef/language.h
new file mode 100644
index 0000000..0a317d5
--- /dev/null
+++ b/third_party/boost/boost/predef/language.h
@@ -0,0 +1,17 @@
+/*
+Copyright Rene Rivera 2011-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#if !defined(BOOST_PREDEF_LANGUAGE_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
+#ifndef BOOST_PREDEF_LANGUAGE_H
+#define BOOST_PREDEF_LANGUAGE_H
+#endif
+
+#include <boost/predef/language/stdc.h>
+#include <boost/predef/language/stdcpp.h>
+#include <boost/predef/language/objc.h>
+
+#endif
diff --git a/third_party/boost/boost/predef/language/objc.h b/third_party/boost/boost/predef/language/objc.h
new file mode 100644
index 0000000..24e3ad3
--- /dev/null
+++ b/third_party/boost/boost/predef/language/objc.h
@@ -0,0 +1,42 @@
+/*
+Copyright Rene Rivera 2011-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LANGUAGE_OBJC_H
+#define BOOST_PREDEF_LANGUAGE_OBJC_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_LANG_OBJC`]
+
+[@http://en.wikipedia.org/wiki/Objective-C Objective-C] language.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__OBJC__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_LANG_OBJC BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__OBJC__)
+#   undef BOOST_LANG_OBJC
+#   define BOOST_LANG_OBJC BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_LANG_OBJC
+#   define BOOST_LANG_OBJC_AVAILABLE
+#endif
+
+#define BOOST_LANG_OBJC_NAME "Objective-C"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_OBJC,BOOST_LANG_OBJC_NAME)
diff --git a/third_party/boost/boost/predef/language/stdc.h b/third_party/boost/boost/predef/language/stdc.h
new file mode 100644
index 0000000..db25c12
--- /dev/null
+++ b/third_party/boost/boost/predef/language/stdc.h
@@ -0,0 +1,53 @@
+/*
+Copyright Rene Rivera 2011-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LANGUAGE_STDC_H
+#define BOOST_PREDEF_LANGUAGE_STDC_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_LANG_STDC`]
+
+[@http://en.wikipedia.org/wiki/C_(programming_language) Standard C] language.
+If available, the year of the standard is detected as YYYY.MM.1 from the Epoc date.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__STDC__`] [__predef_detection__]]
+
+    [[`__STDC_VERSION__`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_LANG_STDC BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__STDC__)
+#   undef BOOST_LANG_STDC
+#   if defined(__STDC_VERSION__)
+#       if (__STDC_VERSION__ > 100)
+#           define BOOST_LANG_STDC BOOST_PREDEF_MAKE_YYYYMM(__STDC_VERSION__)
+#       else
+#           define BOOST_LANG_STDC BOOST_VERSION_NUMBER_AVAILABLE
+#       endif
+#   else
+#       define BOOST_LANG_STDC BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_LANG_STDC
+#   define BOOST_LANG_STDC_AVAILABLE
+#endif
+
+#define BOOST_LANG_STDC_NAME "Standard C"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDC,BOOST_LANG_STDC_NAME)
diff --git a/third_party/boost/boost/predef/language/stdcpp.h b/third_party/boost/boost/predef/language/stdcpp.h
new file mode 100644
index 0000000..34dc8c7
--- /dev/null
+++ b/third_party/boost/boost/predef/language/stdcpp.h
@@ -0,0 +1,121 @@
+/*
+Copyright Rene Rivera 2011-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LANGUAGE_STDCPP_H
+#define BOOST_PREDEF_LANGUAGE_STDCPP_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_LANG_STDCPP`]
+
+[@http://en.wikipedia.org/wiki/C%2B%2B Standard C++] language.
+If available, the year of the standard is detected as YYYY.MM.1 from the Epoc date.
+Because of the way the C++ standardization process works the
+defined version year will not be the commonly known year of the standard.
+Specifically the defined versions are:
+
+[table Detected Version Number vs. C++ Standard Year
+  [[Detected Version Number] [Standard Year] [C++ Standard]]
+  [[27.11.1] [1998] [ISO/IEC 14882:1998]]
+  [[41.12.1] [2011] [ISO/IEC 14882:2011]]
+]
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__cplusplus`] [__predef_detection__]]
+
+    [[`__cplusplus`] [YYYY.MM.1]]
+    ]
+ */
+
+#define BOOST_LANG_STDCPP BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__cplusplus)
+#   undef BOOST_LANG_STDCPP
+#   if (__cplusplus > 100)
+#       define BOOST_LANG_STDCPP BOOST_PREDEF_MAKE_YYYYMM(__cplusplus)
+#   else
+#       define BOOST_LANG_STDCPP BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_LANG_STDCPP
+#   define BOOST_LANG_STDCPP_AVAILABLE
+#endif
+
+#define BOOST_LANG_STDCPP_NAME "Standard C++"
+
+/*`
+[heading `BOOST_LANG_STDCPPCLI`]
+
+[@http://en.wikipedia.org/wiki/C%2B%2B/CLI Standard C++/CLI] language.
+If available, the year of the standard is detected as YYYY.MM.1 from the Epoc date.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__cplusplus_cli`] [__predef_detection__]]
+
+    [[`__cplusplus_cli`] [YYYY.MM.1]]
+    ]
+ */
+
+#define BOOST_LANG_STDCPPCLI BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__cplusplus_cli)
+#   undef BOOST_LANG_STDCPPCLI
+#   if (__cplusplus_cli > 100)
+#       define BOOST_LANG_STDCPPCLI BOOST_PREDEF_MAKE_YYYYMM(__cplusplus_cli)
+#   else
+#       define BOOST_LANG_STDCPPCLI BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_LANG_STDCPPCLI
+#   define BOOST_LANG_STDCPPCLI_AVAILABLE
+#endif
+
+#define BOOST_LANG_STDCPPCLI_NAME "Standard C++/CLI"
+
+/*`
+[heading `BOOST_LANG_STDECPP`]
+
+[@http://en.wikipedia.org/wiki/Embedded_C%2B%2B Standard Embedded C++] language.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__embedded_cplusplus`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_LANG_STDECPP BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__embedded_cplusplus)
+#   undef BOOST_LANG_STDECPP
+#   define BOOST_LANG_STDECPP BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_LANG_STDECPP
+#   define BOOST_LANG_STDECPP_AVAILABLE
+#endif
+
+#define BOOST_LANG_STDECPP_NAME "Standard Embedded C++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDCPP,BOOST_LANG_STDCPP_NAME)
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDCPPCLI,BOOST_LANG_STDCPPCLI_NAME)
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LANG_STDECPP,BOOST_LANG_STDECPP_NAME)
diff --git a/third_party/boost/boost/predef/library.h b/third_party/boost/boost/predef/library.h
new file mode 100644
index 0000000..40518a9
--- /dev/null
+++ b/third_party/boost/boost/predef/library.h
@@ -0,0 +1,16 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#if !defined(BOOST_PREDEF_LIBRARY_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
+#ifndef BOOST_PREDEF_LIBRARY_H
+#define BOOST_PREDEF_LIBRARY_H
+#endif
+
+#include <boost/predef/library/c.h>
+#include <boost/predef/library/std.h>
+
+#endif
diff --git a/third_party/boost/boost/predef/library/c.h b/third_party/boost/boost/predef/library/c.h
new file mode 100644
index 0000000..fa8841e
--- /dev/null
+++ b/third_party/boost/boost/predef/library/c.h
@@ -0,0 +1,20 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#if !defined(BOOST_PREDEF_LIBRARY_C_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
+#ifndef BOOST_PREDEF_LIBRARY_C_H
+#define BOOST_PREDEF_LIBRARY_C_H
+#endif
+
+#include <boost/predef/library/c/_prefix.h>
+
+#include <boost/predef/library/c/gnu.h>
+#include <boost/predef/library/c/uc.h>
+#include <boost/predef/library/c/vms.h>
+#include <boost/predef/library/c/zos.h>
+
+#endif
diff --git a/third_party/boost/boost/predef/library/c/_prefix.h b/third_party/boost/boost/predef/library/c/_prefix.h
new file mode 100644
index 0000000..12bcb0f
--- /dev/null
+++ b/third_party/boost/boost/predef/library/c/_prefix.h
@@ -0,0 +1,13 @@
+/*
+Copyright Rene Rivera 2008-2013
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LIBRARY_C__PREFIX_H
+#define BOOST_PREDEF_LIBRARY_C__PREFIX_H
+
+#include <boost/predef/detail/_cassert.h>
+
+#endif
diff --git a/third_party/boost/boost/predef/library/c/gnu.h b/third_party/boost/boost/predef/library/c/gnu.h
new file mode 100644
index 0000000..9e4ca89
--- /dev/null
+++ b/third_party/boost/boost/predef/library/c/gnu.h
@@ -0,0 +1,61 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LIBRARY_C_GNU_H
+#define BOOST_PREDEF_LIBRARY_C_GNU_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+#include <boost/predef/library/c/_prefix.h>
+
+#if defined(__STDC__)
+#include <stddef.h>
+#elif defined(__cplusplus)
+#include <cstddef>
+#endif
+
+/*`
+[heading `BOOST_LIB_C_GNU`]
+
+[@http://en.wikipedia.org/wiki/Glibc GNU glibc] Standard C library.
+Version number available as major, and minor.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__GLIBC__`] [__predef_detection__]]
+    [[`__GNU_LIBRARY__`] [__predef_detection__]]
+
+    [[`__GLIBC__`, `__GLIBC_MINOR__`] [V.R.0]]
+    [[`__GNU_LIBRARY__`, `__GNU_LIBRARY_MINOR__`] [V.R.0]]
+    ]
+ */
+
+#define BOOST_LIB_C_GNU BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__GLIBC__) || defined(__GNU_LIBRARY__)
+#   undef BOOST_LIB_C_GNU
+#   if defined(__GLIBC__)
+#       define BOOST_LIB_C_GNU \
+            BOOST_VERSION_NUMBER(__GLIBC__,__GLIBC_MINOR__,0)
+#   else
+#       define BOOST_LIB_C_GNU \
+            BOOST_VERSION_NUMBER(__GNU_LIBRARY__,__GNU_LIBRARY_MINOR__,0)
+#   endif
+#endif
+
+#if BOOST_LIB_C_GNU
+#   define BOOST_LIB_C_GNU_AVAILABLE
+#endif
+
+#define BOOST_LIB_C_GNU_NAME "GNU"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_GNU,BOOST_LIB_C_GNU_NAME)
diff --git a/third_party/boost/boost/predef/library/c/uc.h b/third_party/boost/boost/predef/library/c/uc.h
new file mode 100644
index 0000000..03081e9
--- /dev/null
+++ b/third_party/boost/boost/predef/library/c/uc.h
@@ -0,0 +1,47 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LIBRARY_C_UC_H
+#define BOOST_PREDEF_LIBRARY_C_UC_H
+
+#include <boost/predef/library/c/_prefix.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_LIB_C_UC`]
+
+[@http://en.wikipedia.org/wiki/Uclibc uClibc] Standard C library.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__UCLIBC__`] [__predef_detection__]]
+
+    [[`__UCLIBC_MAJOR__`, `__UCLIBC_MINOR__`, `__UCLIBC_SUBLEVEL__`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_LIB_C_UC BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__UCLIBC__)
+#   undef BOOST_LIB_C_UC
+#   define BOOST_LIB_C_UC BOOST_VERSION_NUMBER(\
+        __UCLIBC_MAJOR__,__UCLIBC_MINOR__,__UCLIBC_SUBLEVEL__)
+#endif
+
+#if BOOST_LIB_C_UC
+#   define BOOST_LIB_C_UC_AVAILABLE
+#endif
+
+#define BOOST_LIB_C_UC_NAME "uClibc"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_UC,BOOST_LIB_C_UC_NAME)
diff --git a/third_party/boost/boost/predef/library/c/vms.h b/third_party/boost/boost/predef/library/c/vms.h
new file mode 100644
index 0000000..685f1a7
--- /dev/null
+++ b/third_party/boost/boost/predef/library/c/vms.h
@@ -0,0 +1,47 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LIBRARY_C_VMS_H
+#define BOOST_PREDEF_LIBRARY_C_VMS_H
+
+#include <boost/predef/library/c/_prefix.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_LIB_C_VMS`]
+
+VMS libc Standard C library.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__CRTL_VER`] [__predef_detection__]]
+
+    [[`__CRTL_VER`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_LIB_C_VMS BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__CRTL_VER)
+#   undef BOOST_LIB_C_VMS
+#   define BOOST_LIB_C_VMS BOOST_PREDEF_MAKE_10_VVRR0PP00(__CRTL_VER)
+#endif
+
+#if BOOST_LIB_C_VMS
+#   define BOOST_LIB_C_VMS_AVAILABLE
+#endif
+
+#define BOOST_LIB_C_VMS_NAME "VMS"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_VMS,BOOST_LIB_C_VMS_NAME)
diff --git a/third_party/boost/boost/predef/library/c/zos.h b/third_party/boost/boost/predef/library/c/zos.h
new file mode 100644
index 0000000..222d355
--- /dev/null
+++ b/third_party/boost/boost/predef/library/c/zos.h
@@ -0,0 +1,56 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LIBRARY_C_ZOS_H
+#define BOOST_PREDEF_LIBRARY_C_ZOS_H
+
+#include <boost/predef/library/c/_prefix.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_LIB_C_ZOS`]
+
+z/OS libc Standard C library.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__LIBREL__`] [__predef_detection__]]
+
+    [[`__LIBREL__`] [V.R.P]]
+    [[`__TARGET_LIB__`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_LIB_C_ZOS BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__LIBREL__)
+#   undef BOOST_LIB_C_ZOS
+#   if !defined(BOOST_LIB_C_ZOS) && defined(__LIBREL__)
+#       define BOOST_LIB_C_ZOS BOOST_PREDEF_MAKE_0X_VRRPPPP(__LIBREL__)
+#   endif
+#   if !defined(BOOST_LIB_C_ZOS) && defined(__TARGET_LIB__)
+#       define BOOST_LIB_C_ZOS BOOST_PREDEF_MAKE_0X_VRRPPPP(__TARGET_LIB__)
+#   endif
+#   if !defined(BOOST_LIB_C_ZOS)
+#       define BOOST_LIB_C_ZOS BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_LIB_C_ZOS
+#   define BOOST_LIB_C_ZOS_AVAILABLE
+#endif
+
+#define BOOST_LIB_C_ZOS_NAME "z/OS"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_C_ZOS,BOOST_LIB_C_ZOS_NAME)
diff --git a/third_party/boost/boost/predef/library/std.h b/third_party/boost/boost/predef/library/std.h
new file mode 100644
index 0000000..403b6ff
--- /dev/null
+++ b/third_party/boost/boost/predef/library/std.h
@@ -0,0 +1,25 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+#if !defined(BOOST_PREDEF_LIBRARY_STD_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
+#ifndef BOOST_PREDEF_LIBRARY_STD_H
+#define BOOST_PREDEF_LIBRARY_STD_H
+#endif
+
+#include <boost/predef/library/std/_prefix.h>
+
+#include <boost/predef/library/std/cxx.h>
+#include <boost/predef/library/std/dinkumware.h>
+#include <boost/predef/library/std/libcomo.h>
+#include <boost/predef/library/std/modena.h>
+#include <boost/predef/library/std/msl.h>
+#include <boost/predef/library/std/roguewave.h>
+#include <boost/predef/library/std/sgi.h>
+#include <boost/predef/library/std/stdcpp3.h>
+#include <boost/predef/library/std/stlport.h>
+#include <boost/predef/library/std/vacpp.h>
+
+#endif
diff --git a/third_party/boost/boost/predef/library/std/_prefix.h b/third_party/boost/boost/predef/library/std/_prefix.h
new file mode 100644
index 0000000..932b855
--- /dev/null
+++ b/third_party/boost/boost/predef/library/std/_prefix.h
@@ -0,0 +1,23 @@
+/*
+Copyright Rene Rivera 2008-2013
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+#ifndef BOOST_PREDEF_LIBRARY_STD__PREFIX_H
+#define BOOST_PREDEF_LIBRARY_STD__PREFIX_H
+
+/*
+We need to include an STD header to gives us the context
+of which library we are using. The "smallest" code-wise header
+seems to be <exception>. Boost uses <utility> but as far
+as I can tell (RR) it's not a stand-alone header in most
+implementations. Using <exception> also has the benefit of
+being available in EC++, so we get a chance to make this work
+for embedded users. And since it's not a header impacted by TR1
+there's no magic needed for inclusion in the face of the
+Boost.TR1 library.
+*/
+#include <boost/predef/detail/_exception.h>
+
+#endif
diff --git a/third_party/boost/boost/predef/library/std/cxx.h b/third_party/boost/boost/predef/library/std/cxx.h
new file mode 100644
index 0000000..07b52cd
--- /dev/null
+++ b/third_party/boost/boost/predef/library/std/cxx.h
@@ -0,0 +1,46 @@
+/*
+Copyright Rene Rivera 2011-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LIBRARY_STD_CXX_H
+#define BOOST_PREDEF_LIBRARY_STD_CXX_H
+
+#include <boost/predef/library/std/_prefix.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_LIB_STD_CXX`]
+
+[@http://libcxx.llvm.org/ libc++] C++ Standard Library.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`_LIBCPP_VERSION`] [__predef_detection__]]
+
+    [[`_LIBCPP_VERSION`] [V.0.P]]
+    ]
+ */
+
+#define BOOST_LIB_STD_CXX BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(_LIBCPP_VERSION)
+#   undef BOOST_LIB_STD_CXX
+#   define BOOST_LIB_STD_CXX BOOST_PREDEF_MAKE_10_VPPP(_LIBCPP_VERSION)
+#endif
+
+#if BOOST_LIB_STD_CXX
+#   define BOOST_LIB_STD_CXX_AVAILABLE
+#endif
+
+#define BOOST_LIB_STD_CXX_NAME "libc++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_CXX,BOOST_LIB_STD_CXX_NAME)
diff --git a/third_party/boost/boost/predef/library/std/dinkumware.h b/third_party/boost/boost/predef/library/std/dinkumware.h
new file mode 100644
index 0000000..0fc0776
--- /dev/null
+++ b/third_party/boost/boost/predef/library/std/dinkumware.h
@@ -0,0 +1,52 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LIBRARY_STD_DINKUMWARE_H
+#define BOOST_PREDEF_LIBRARY_STD_DINKUMWARE_H
+
+#include <boost/predef/library/std/_prefix.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_LIB_STD_DINKUMWARE`]
+
+[@http://en.wikipedia.org/wiki/Dinkumware Dinkumware] Standard C++ Library.
+If available version number as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`_YVALS`, `__IBMCPP__`] [__predef_detection__]]
+    [[`_CPPLIB_VER`] [__predef_detection__]]
+
+    [[`_CPPLIB_VER`] [V.R.0]]
+    ]
+ */
+
+#define BOOST_LIB_STD_DINKUMWARE BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER)
+#   undef BOOST_LIB_STD_DINKUMWARE
+#   if defined(_CPPLIB_VER)
+#       define BOOST_LIB_STD_DINKUMWARE BOOST_PREDEF_MAKE_10_VVRR(_CPPLIB_VER)
+#   else
+#       define BOOST_LIB_STD_DINKUMWARE BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_LIB_STD_DINKUMWARE
+#   define BOOST_LIB_STD_DINKUMWARE_AVAILABLE
+#endif
+
+#define BOOST_LIB_STD_DINKUMWARE_NAME "Dinkumware"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_DINKUMWARE,BOOST_LIB_STD_DINKUMWARE_NAME)
diff --git a/third_party/boost/boost/predef/library/std/libcomo.h b/third_party/boost/boost/predef/library/std/libcomo.h
new file mode 100644
index 0000000..97d4a53
--- /dev/null
+++ b/third_party/boost/boost/predef/library/std/libcomo.h
@@ -0,0 +1,47 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LIBRARY_STD_LIBCOMO_H
+#define BOOST_PREDEF_LIBRARY_STD_LIBCOMO_H
+
+#include <boost/predef/library/std/_prefix.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_LIB_STD_COMO`]
+
+[@http://www.comeaucomputing.com/libcomo/ Comeau Computing] Standard C++ Library.
+Version number available as major.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__LIBCOMO__`] [__predef_detection__]]
+
+    [[`__LIBCOMO_VERSION__`] [V.0.0]]
+    ]
+ */
+
+#define BOOST_LIB_STD_COMO BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__LIBCOMO__)
+#   undef BOOST_LIB_STD_COMO
+#   define BOOST_LIB_STD_COMO BOOST_VERSION_NUMBER(__LIBCOMO_VERSION__,0,0)
+#endif
+
+#if BOOST_LIB_STD_COMO
+#   define BOOST_LIB_STD_COMO_AVAILABLE
+#endif
+
+#define BOOST_LIB_STD_COMO_NAME "Comeau Computing"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_COMO,BOOST_LIB_STD_COMO_NAME)
diff --git a/third_party/boost/boost/predef/library/std/modena.h b/third_party/boost/boost/predef/library/std/modena.h
new file mode 100644
index 0000000..b67ac62
--- /dev/null
+++ b/third_party/boost/boost/predef/library/std/modena.h
@@ -0,0 +1,45 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LIBRARY_STD_MODENA_H
+#define BOOST_PREDEF_LIBRARY_STD_MODENA_H
+
+#include <boost/predef/library/std/_prefix.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_LIB_STD_MSIPL`]
+
+[@http://modena.us/ Modena Software Lib++] Standard C++ Library.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`MSIPL_COMPILE_H`] [__predef_detection__]]
+    [[`__MSIPL_COMPILE_H`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_LIB_STD_MSIPL BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(MSIPL_COMPILE_H) || defined(__MSIPL_COMPILE_H)
+#   undef BOOST_LIB_STD_MSIPL
+#   define BOOST_LIB_STD_MSIPL BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_LIB_STD_MSIPL
+#   define BOOST_LIB_STD_MSIPL_AVAILABLE
+#endif
+
+#define BOOST_LIB_STD_MSIPL_NAME "Modena Software Lib++"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_MSIPL,BOOST_LIB_STD_MSIPL_NAME)
diff --git a/third_party/boost/boost/predef/library/std/msl.h b/third_party/boost/boost/predef/library/std/msl.h
new file mode 100644
index 0000000..d73c74c
--- /dev/null
+++ b/third_party/boost/boost/predef/library/std/msl.h
@@ -0,0 +1,53 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LIBRARY_STD_MSL_H
+#define BOOST_PREDEF_LIBRARY_STD_MSL_H
+
+#include <boost/predef/library/std/_prefix.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_LIB_STD_MSL`]
+
+[@http://www.freescale.com/ Metrowerks] Standard C++ Library.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__MSL_CPP__`] [__predef_detection__]]
+    [[`__MSL__`] [__predef_detection__]]
+
+    [[`__MSL_CPP__`] [V.R.P]]
+    [[`__MSL__`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_LIB_STD_MSL BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__MSL_CPP__) || defined(__MSL__)
+#   undef BOOST_LIB_STD_MSL
+#   if defined(__MSL_CPP__)
+#       define BOOST_LIB_STD_MSL BOOST_PREDEF_MAKE_0X_VRPP(__MSL_CPP__)
+#   else
+#       define BOOST_LIB_STD_MSL BOOST_PREDEF_MAKE_0X_VRPP(__MSL__)
+#   endif
+#endif
+
+#if BOOST_LIB_STD_MSL
+#   define BOOST_LIB_STD_MSL_AVAILABLE
+#endif
+
+#define BOOST_LIB_STD_MSL_NAME "Metrowerks"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_MSL,BOOST_LIB_STD_MSL_NAME)
diff --git a/third_party/boost/boost/predef/library/std/roguewave.h b/third_party/boost/boost/predef/library/std/roguewave.h
new file mode 100644
index 0000000..9c3f288
--- /dev/null
+++ b/third_party/boost/boost/predef/library/std/roguewave.h
@@ -0,0 +1,56 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LIBRARY_STD_ROGUEWAVE_H
+#define BOOST_PREDEF_LIBRARY_STD_ROGUEWAVE_H
+
+#include <boost/predef/library/std/_prefix.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_LIB_STD_RW`]
+
+[@http://stdcxx.apache.org/ Roguewave] Standard C++ library.
+If available version number as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__STD_RWCOMPILER_H__`] [__predef_detection__]]
+    [[`_RWSTD_VER`] [__predef_detection__]]
+
+    [[`_RWSTD_VER`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_LIB_STD_RW BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER)
+#   undef BOOST_LIB_STD_RW
+#   if defined(_RWSTD_VER)
+#       if _RWSTD_VER < 0x010000
+#           define BOOST_LIB_STD_RW BOOST_PREDEF_MAKE_0X_VVRRP(_RWSTD_VER)
+#       else
+#           define BOOST_LIB_STD_RW BOOST_PREDEF_MAKE_0X_VVRRPP(_RWSTD_VER)
+#       endif
+#   else
+#       define BOOST_LIB_STD_RW BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_LIB_STD_RW
+#   define BOOST_LIB_STD_RW_AVAILABLE
+#endif
+
+#define BOOST_LIB_STD_RW_NAME "Roguewave"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_RW,BOOST_LIB_STD_RW_NAME)
diff --git a/third_party/boost/boost/predef/library/std/sgi.h b/third_party/boost/boost/predef/library/std/sgi.h
new file mode 100644
index 0000000..5d19bba
--- /dev/null
+++ b/third_party/boost/boost/predef/library/std/sgi.h
@@ -0,0 +1,51 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LIBRARY_STD_SGI_H
+#define BOOST_PREDEF_LIBRARY_STD_SGI_H
+
+#include <boost/predef/library/std/_prefix.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_LIB_STD_SGI`]
+
+[@http://www.sgi.com/tech/stl/ SGI] Standard C++ library.
+If available version number as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__STL_CONFIG_H`] [__predef_detection__]]
+
+    [[`__SGI_STL`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_LIB_STD_SGI BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__STL_CONFIG_H)
+#   undef BOOST_LIB_STD_SGI
+#   if defined(__SGI_STL)
+#       define BOOST_LIB_STD_SGI BOOST_PREDEF_MAKE_0X_VRP(__SGI_STL)
+#   else
+#       define BOOST_LIB_STD_SGI BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_LIB_STD_SGI
+#   define BOOST_LIB_STD_SGI_AVAILABLE
+#endif
+
+#define BOOST_LIB_STD_SGI_NAME "SGI"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_SGI,BOOST_LIB_STD_SGI_NAME)
diff --git a/third_party/boost/boost/predef/library/std/stdcpp3.h b/third_party/boost/boost/predef/library/std/stdcpp3.h
new file mode 100644
index 0000000..c980292
--- /dev/null
+++ b/third_party/boost/boost/predef/library/std/stdcpp3.h
@@ -0,0 +1,53 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LIBRARY_STD_STDCPP3_H
+#define BOOST_PREDEF_LIBRARY_STD_STDCPP3_H
+
+#include <boost/predef/library/std/_prefix.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_LIB_STD_GNU`]
+
+[@http://gcc.gnu.org/libstdc++/ GNU libstdc++] Standard C++ library.
+Version number available as year (from 1970), month, and day.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__GLIBCXX__`] [__predef_detection__]]
+    [[`__GLIBCPP__`] [__predef_detection__]]
+
+    [[`__GLIBCXX__`] [V.R.P]]
+    [[`__GLIBCPP__`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_LIB_STD_GNU BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__GLIBCPP__) || defined(__GLIBCXX__)
+#   undef BOOST_LIB_STD_GNU
+#   if defined(__GLIBCXX__)
+#       define BOOST_LIB_STD_GNU BOOST_PREDEF_MAKE_YYYYMMDD(__GLIBCXX__)
+#   else
+#       define BOOST_LIB_STD_GNU BOOST_PREDEF_MAKE_YYYYMMDD(__GLIBCPP__)
+#   endif
+#endif
+
+#if BOOST_LIB_STD_GNU
+#   define BOOST_LIB_STD_GNU_AVAILABLE
+#endif
+
+#define BOOST_LIB_STD_GNU_NAME "GNU"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_GNU,BOOST_LIB_STD_GNU_NAME)
diff --git a/third_party/boost/boost/predef/library/std/stlport.h b/third_party/boost/boost/predef/library/std/stlport.h
new file mode 100644
index 0000000..c09483b
--- /dev/null
+++ b/third_party/boost/boost/predef/library/std/stlport.h
@@ -0,0 +1,59 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LIBRARY_STD_STLPORT_H
+#define BOOST_PREDEF_LIBRARY_STD_STLPORT_H
+
+#include <boost/predef/library/std/_prefix.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_LIB_STD_STLPORT`]
+
+[@http://sourceforge.net/projects/stlport/ STLport Standard C++] library.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__SGI_STL_PORT`] [__predef_detection__]]
+    [[`_STLPORT_VERSION`] [__predef_detection__]]
+
+    [[`_STLPORT_MAJOR`, `_STLPORT_MINOR`, `_STLPORT_PATCHLEVEL`] [V.R.P]]
+    [[`_STLPORT_VERSION`] [V.R.P]]
+    [[`__SGI_STL_PORT`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_LIB_STD_STLPORT BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
+#   undef BOOST_LIB_STD_STLPORT
+#   if !defined(BOOST_LIB_STD_STLPORT) && defined(_STLPORT_MAJOR)
+#       define BOOST_LIB_STD_STLPORT \
+            BOOST_VERSION_NUMBER(_STLPORT_MAJOR,_STLPORT_MINOR,_STLPORT_PATCHLEVEL)
+#   endif
+#   if !defined(BOOST_LIB_STD_STLPORT) && defined(_STLPORT_VERSION)
+#       define BOOST_LIB_STD_STLPORT BOOST_PREDEF_MAKE_0X_VRP(_STLPORT_VERSION)
+#   endif
+#   if !defined(BOOST_LIB_STD_STLPORT)
+#       define BOOST_LIB_STD_STLPORT BOOST_PREDEF_MAKE_0X_VRP(__SGI_STL_PORT)
+#   endif
+#endif
+
+#if BOOST_LIB_STD_STLPORT
+#   define BOOST_LIB_STD_STLPORT_AVAILABLE
+#endif
+
+#define BOOST_LIB_STD_STLPORT_NAME "STLport"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_STLPORT,BOOST_LIB_STD_STLPORT_NAME)
diff --git a/third_party/boost/boost/predef/library/std/vacpp.h b/third_party/boost/boost/predef/library/std/vacpp.h
new file mode 100644
index 0000000..632f846
--- /dev/null
+++ b/third_party/boost/boost/predef/library/std/vacpp.h
@@ -0,0 +1,44 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_LIBRARY_STD_VACPP_H
+#define BOOST_PREDEF_LIBRARY_STD_VACPP_H
+
+#include <boost/predef/library/std/_prefix.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_LIB_STD_IBM`]
+
+[@http://www.ibm.com/software/awdtools/xlcpp/ IBM VACPP Standard C++] library.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__IBMCPP__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_LIB_STD_IBM BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__IBMCPP__)
+#   undef BOOST_LIB_STD_IBM
+#   define BOOST_LIB_STD_IBM BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_LIB_STD_IBM
+#   define BOOST_LIB_STD_IBM_AVAILABLE
+#endif
+
+#define BOOST_LIB_STD_IBM_NAME "IBM VACPP"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_LIB_STD_IBM,BOOST_LIB_STD_IBM_NAME)
diff --git a/third_party/boost/boost/predef/make.h b/third_party/boost/boost/predef/make.h
new file mode 100644
index 0000000..4f2f9ee
--- /dev/null
+++ b/third_party/boost/boost/predef/make.h
@@ -0,0 +1,89 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+#include <boost/predef/detail/test.h>
+
+#ifndef BOOST_PREDEF_MAKE_H
+#define BOOST_PREDEF_MAKE_H
+
+/*
+Shorthands for the common version number formats used by vendors...
+*/
+
+/*`
+[heading `BOOST_PREDEF_MAKE_..` macros]
+
+These set of macros decompose common vendor version number
+macros which are composed version, revision, and patch digits.
+The naming convention indicates:
+
+* The base of the specified version number. "`BOOST_PREDEF_MAKE_0X`" for
+  hexadecimal digits, and "`BOOST_PREDEF_MAKE_10`" for decimal digits.
+* The format of the vendor version number. Where "`V`" indicates the version digits,
+  "`R`" indicates the revision digits, "`P`" indicates the patch digits, and "`0`"
+  indicates an ignored digit.
+
+Macros are:
+*/
+/*` `BOOST_PREDEF_MAKE_0X_VRP(V)` */
+#define BOOST_PREDEF_MAKE_0X_VRP(V) BOOST_VERSION_NUMBER((V&0xF00)>>8,(V&0xF0)>>4,(V&0xF))
+/*` `BOOST_PREDEF_MAKE_0X_VVRP(V)` */
+#define BOOST_PREDEF_MAKE_0X_VVRP(V) BOOST_VERSION_NUMBER((V&0xFF00)>>8,(V&0xF0)>>4,(V&0xF))
+/*` `BOOST_PREDEF_MAKE_0X_VRPP(V)` */
+#define BOOST_PREDEF_MAKE_0X_VRPP(V) BOOST_VERSION_NUMBER((V&0xF000)>>12,(V&0xF00)>>8,(V&0xFF))
+/*` `BOOST_PREDEF_MAKE_0X_VVRR(V)` */
+#define BOOST_PREDEF_MAKE_0X_VVRR(V) BOOST_VERSION_NUMBER((V&0xFF00)>>8,(V&0xFF),0)
+/*` `BOOST_PREDEF_MAKE_0X_VRRPPPP(V)` */
+#define BOOST_PREDEF_MAKE_0X_VRRPPPP(V) BOOST_VERSION_NUMBER((V&0xF000000)>>24,(V&0xFF0000)>>16,(V&0xFFFF))
+/*` `BOOST_PREDEF_MAKE_0X_VVRRP(V)` */
+#define BOOST_PREDEF_MAKE_0X_VVRRP(V) BOOST_VERSION_NUMBER((V&0xFF000)>>12,(V&0xFF0)>>4,(V&0xF))
+/*` `BOOST_PREDEF_MAKE_0X_VRRPP000(V)` */
+#define BOOST_PREDEF_MAKE_0X_VRRPP000(V) BOOST_VERSION_NUMBER((V&0xF0000000)>>28,(V&0xFF00000)>>20,(V&0xFF000)>>12)
+/*` `BOOST_PREDEF_MAKE_0X_VVRRPP(V)` */
+#define BOOST_PREDEF_MAKE_0X_VVRRPP(V) BOOST_VERSION_NUMBER((V&0xFF0000)>>16,(V&0xFF00)>>8,(V&0xFF))
+/*` `BOOST_PREDEF_MAKE_10_VPPP(V)` */
+#define BOOST_PREDEF_MAKE_10_VPPP(V) BOOST_VERSION_NUMBER(((V)/1000)%10,0,(V)%1000)
+/*` `BOOST_PREDEF_MAKE_10_VRP(V)` */
+#define BOOST_PREDEF_MAKE_10_VRP(V) BOOST_VERSION_NUMBER(((V)/100)%10,((V)/10)%10,(V)%10)
+/*` `BOOST_PREDEF_MAKE_10_VRP000(V)` */
+#define BOOST_PREDEF_MAKE_10_VRP000(V) BOOST_VERSION_NUMBER(((V)/100000)%10,((V)/10000)%10,((V)/1000)%10)
+/*` `BOOST_PREDEF_MAKE_10_VRPP(V)` */
+#define BOOST_PREDEF_MAKE_10_VRPP(V) BOOST_VERSION_NUMBER(((V)/1000)%10,((V)/100)%10,(V)%100)
+/*` `BOOST_PREDEF_MAKE_10_VRR(V)` */
+#define BOOST_PREDEF_MAKE_10_VRR(V) BOOST_VERSION_NUMBER(((V)/100)%10,(V)%100,0)
+/*` `BOOST_PREDEF_MAKE_10_VRRPP(V)` */
+#define BOOST_PREDEF_MAKE_10_VRRPP(V) BOOST_VERSION_NUMBER(((V)/10000)%10,((V)/100)%100,(V)%100)
+/*` `BOOST_PREDEF_MAKE_10_VRR000(V)` */
+#define BOOST_PREDEF_MAKE_10_VRR000(V) BOOST_VERSION_NUMBER(((V)/100000)%10,((V)/1000)%100,0)
+/*` `BOOST_PREDEF_MAKE_10_VV00(V)` */
+#define BOOST_PREDEF_MAKE_10_VV00(V) BOOST_VERSION_NUMBER(((V)/100)%100,0,0)
+/*` `BOOST_PREDEF_MAKE_10_VVRR(V)` */
+#define BOOST_PREDEF_MAKE_10_VVRR(V) BOOST_VERSION_NUMBER(((V)/100)%100,(V)%100,0)
+/*` `BOOST_PREDEF_MAKE_10_VVRRPP(V)` */
+#define BOOST_PREDEF_MAKE_10_VVRRPP(V) BOOST_VERSION_NUMBER(((V)/10000)%100,((V)/100)%100,(V)%100)
+/*` `BOOST_PREDEF_MAKE_10_VVRR0PP00(V)` */
+#define BOOST_PREDEF_MAKE_10_VVRR0PP00(V) BOOST_VERSION_NUMBER(((V)/10000000)%100,((V)/100000)%100,((V)/100)%100)
+/*` `BOOST_PREDEF_MAKE_10_VVRR0PPPP(V)` */
+#define BOOST_PREDEF_MAKE_10_VVRR0PPPP(V) BOOST_VERSION_NUMBER(((V)/10000000)%100,((V)/100000)%100,(V)%10000)
+/*` `BOOST_PREDEF_MAKE_10_VVRR00PP00(V)` */
+#define BOOST_PREDEF_MAKE_10_VVRR00PP00(V) BOOST_VERSION_NUMBER(((V)/100000000)%100,((V)/1000000)%100,((V)/100)%100)
+/*`
+[heading `BOOST_PREDEF_MAKE_*..` date macros]
+
+Date decomposition macros return a date in the relative to the 1970
+Epoch date. If the month is not available, January 1st is used as the month and day.
+If the day is not available, but the month is, the 1st of the month is used as the day.
+*/
+/*` `BOOST_PREDEF_MAKE_DATE(Y,M,D)` */
+#define BOOST_PREDEF_MAKE_DATE(Y,M,D) BOOST_VERSION_NUMBER((Y)%10000-1970,(M)%100,(D)%100)
+/*` `BOOST_PREDEF_MAKE_YYYYMMDD(V)` */
+#define BOOST_PREDEF_MAKE_YYYYMMDD(V) BOOST_PREDEF_MAKE_DATE(((V)/10000)%10000,((V)/100)%100,(V)%100)
+/*` `BOOST_PREDEF_MAKE_YYYY(V)` */
+#define BOOST_PREDEF_MAKE_YYYY(V) BOOST_PREDEF_MAKE_DATE(V,1,1)
+/*` `BOOST_PREDEF_MAKE_YYYYMM(V)` */
+#define BOOST_PREDEF_MAKE_YYYYMM(V) BOOST_PREDEF_MAKE_DATE((V)/100,(V)%100,1)
+
+#endif
diff --git a/third_party/boost/boost/predef/os.h b/third_party/boost/boost/predef/os.h
new file mode 100644
index 0000000..bedf99e
--- /dev/null
+++ b/third_party/boost/boost/predef/os.h
@@ -0,0 +1,33 @@
+/*
+Copyright Rene Rivera 2008-2015
+Copyright Franz Detro 2014
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#if !defined(BOOST_PREDEF_OS_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
+#ifndef BOOST_PREDEF_OS_H
+#define BOOST_PREDEF_OS_H
+#endif
+
+#include <boost/predef/os/aix.h>
+#include <boost/predef/os/amigaos.h>
+#include <boost/predef/os/android.h>
+#include <boost/predef/os/beos.h>
+#include <boost/predef/os/bsd.h>
+#include <boost/predef/os/cygwin.h>
+#include <boost/predef/os/haiku.h>
+#include <boost/predef/os/hpux.h>
+#include <boost/predef/os/irix.h>
+#include <boost/predef/os/ios.h>
+#include <boost/predef/os/linux.h>
+#include <boost/predef/os/macos.h>
+#include <boost/predef/os/os400.h>
+#include <boost/predef/os/qnxnto.h>
+#include <boost/predef/os/solaris.h>
+#include <boost/predef/os/unix.h>
+#include <boost/predef/os/vms.h>
+#include <boost/predef/os/windows.h>
+
+#endif
diff --git a/third_party/boost/boost/predef/os/aix.h b/third_party/boost/boost/predef/os/aix.h
new file mode 100644
index 0000000..3e5a953
--- /dev/null
+++ b/third_party/boost/boost/predef/os/aix.h
@@ -0,0 +1,66 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_AIX_H
+#define BOOST_PREDEF_OS_AIX_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_AIX`]
+
+[@http://en.wikipedia.org/wiki/AIX_operating_system IBM AIX] operating system.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`_AIX`] [__predef_detection__]]
+    [[`__TOS_AIX__`] [__predef_detection__]]
+
+    [[`_AIX43`] [4.3.0]]
+    [[`_AIX41`] [4.1.0]]
+    [[`_AIX32`] [3.2.0]]
+    [[`_AIX3`] [3.0.0]]
+    ]
+ */
+
+#define BOOST_OS_AIX BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(_AIX) || defined(__TOS_AIX__) \
+    )
+#   undef BOOST_OS_AIX
+#   if !defined(BOOST_OS_AIX) && defined(_AIX43)
+#       define BOOST_OS_AIX BOOST_VERSION_NUMBER(4,3,0)
+#   endif
+#   if !defined(BOOST_OS_AIX) && defined(_AIX41)
+#       define BOOST_OS_AIX BOOST_VERSION_NUMBER(4,1,0)
+#   endif
+#   if !defined(BOOST_OS_AIX) && defined(_AIX32)
+#       define BOOST_OS_AIX BOOST_VERSION_NUMBER(3,2,0)
+#   endif
+#   if !defined(BOOST_OS_AIX) && defined(_AIX3)
+#       define BOOST_OS_AIX BOOST_VERSION_NUMBER(3,0,0)
+#   endif
+#   if !defined(BOOST_OS_AIX)
+#       define BOOST_OS_AIX BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_OS_AIX
+#   define BOOST_OS_AIX_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_AIX_NAME "IBM AIX"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_AIX,BOOST_OS_AIX_NAME)
diff --git a/third_party/boost/boost/predef/os/amigaos.h b/third_party/boost/boost/predef/os/amigaos.h
new file mode 100644
index 0000000..7b32ddf
--- /dev/null
+++ b/third_party/boost/boost/predef/os/amigaos.h
@@ -0,0 +1,46 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_AMIGAOS_H
+#define BOOST_PREDEF_OS_AMIGAOS_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_AMIGAOS`]
+
+[@http://en.wikipedia.org/wiki/AmigaOS AmigaOS] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`AMIGA`] [__predef_detection__]]
+    [[`__amigaos__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_OS_AMIGAOS BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(AMIGA) || defined(__amigaos__) \
+    )
+#   undef BOOST_OS_AMIGAOS
+#   define BOOST_OS_AMIGAOS BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_OS_AMIGAOS
+#   define BOOST_OS_AMIGAOS_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_AMIGAOS_NAME "AmigaOS"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_AMIGAOS,BOOST_OS_AMIGAOS_NAME)
diff --git a/third_party/boost/boost/predef/os/android.h b/third_party/boost/boost/predef/os/android.h
new file mode 100644
index 0000000..00836e7
--- /dev/null
+++ b/third_party/boost/boost/predef/os/android.h
@@ -0,0 +1,45 @@
+/*
+Copyright Rene Rivera 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_ADROID_H
+#define BOOST_PREDEF_OS_ADROID_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_ANDROID`]
+
+[@http://en.wikipedia.org/wiki/Android_%28operating_system%29 Android] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__ANDROID__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_OS_ANDROID BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(__ANDROID__) \
+    )
+#   undef BOOST_OS_ANDROID
+#   define BOOST_OS_ANDROID BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_OS_ANDROID
+#   define BOOST_OS_ANDROID_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_ANDROID_NAME "Android"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_ANDROID,BOOST_OS_ANDROID_NAME)
diff --git a/third_party/boost/boost/predef/os/beos.h b/third_party/boost/boost/predef/os/beos.h
new file mode 100644
index 0000000..19f4cb7
--- /dev/null
+++ b/third_party/boost/boost/predef/os/beos.h
@@ -0,0 +1,45 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_BEOS_H
+#define BOOST_PREDEF_OS_BEOS_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_BEOS`]
+
+[@http://en.wikipedia.org/wiki/BeOS BeOS] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__BEOS__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_OS_BEOS BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(__BEOS__) \
+    )
+#   undef BOOST_OS_BEOS
+#   define BOOST_OS_BEOS BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_OS_BEOS
+#   define BOOST_OS_BEOS_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_BEOS_NAME "BeOS"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BEOS,BOOST_OS_BEOS_NAME)
diff --git a/third_party/boost/boost/predef/os/bsd.h b/third_party/boost/boost/predef/os/bsd.h
new file mode 100644
index 0000000..fad9aed
--- /dev/null
+++ b/third_party/boost/boost/predef/os/bsd.h
@@ -0,0 +1,103 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_BSD_H
+#define BOOST_PREDEF_OS_BSD_H
+
+/* Special case: OSX will define BSD predefs if the sys/param.h
+ * header is included. We can guard against that, but only if we
+ * detect OSX first. Hence we will force include OSX detection
+ * before doing any BSD detection.
+ */
+#include <boost/predef/os/macos.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_BSD`]
+
+[@http://en.wikipedia.org/wiki/Berkeley_Software_Distribution BSD] operating system.
+
+BSD has various branch operating systems possible and each detected
+individually. This detects the following variations and sets a specific
+version number macro to match:
+
+* `BOOST_OS_BSD_DRAGONFLY` [@http://en.wikipedia.org/wiki/DragonFly_BSD DragonFly BSD]
+* `BOOST_OS_BSD_FREE` [@http://en.wikipedia.org/wiki/Freebsd FreeBSD]
+* `BOOST_OS_BSD_BSDI` [@http://en.wikipedia.org/wiki/BSD/OS BSDi BSD/OS]
+* `BOOST_OS_BSD_NET` [@http://en.wikipedia.org/wiki/Netbsd NetBSD]
+* `BOOST_OS_BSD_OPEN` [@http://en.wikipedia.org/wiki/Openbsd OpenBSD]
+
+[note The general `BOOST_OS_BSD` is set in all cases to indicate some form
+of BSD. If the above variants is detected the corresponding macro is also set.]
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`BSD`] [__predef_detection__]]
+    [[`_SYSTYPE_BSD`] [__predef_detection__]]
+
+    [[`BSD4_2`] [4.2.0]]
+    [[`BSD4_3`] [4.3.0]]
+    [[`BSD4_4`] [4.4.0]]
+    [[`BSD`] [V.R.0]]
+    ]
+ */
+
+#include <boost/predef/os/bsd/bsdi.h>
+#include <boost/predef/os/bsd/dragonfly.h>
+#include <boost/predef/os/bsd/free.h>
+#include <boost/predef/os/bsd/open.h>
+#include <boost/predef/os/bsd/net.h>
+
+#ifndef BOOST_OS_BSD
+#define BOOST_OS_BSD BOOST_VERSION_NUMBER_NOT_AVAILABLE
+#endif
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(BSD) || \
+    defined(_SYSTYPE_BSD) \
+    )
+#   undef BOOST_OS_BSD
+#   include <sys/param.h>
+#   if !defined(BOOST_OS_BSD) && defined(BSD4_4)
+#       define BOOST_OS_BSD BOOST_VERSION_NUMBER(4,4,0)
+#   endif
+#   if !defined(BOOST_OS_BSD) && defined(BSD4_3)
+#       define BOOST_OS_BSD BOOST_VERSION_NUMBER(4,3,0)
+#   endif
+#   if !defined(BOOST_OS_BSD) && defined(BSD4_2)
+#       define BOOST_OS_BSD BOOST_VERSION_NUMBER(4,2,0)
+#   endif
+#   if !defined(BOOST_OS_BSD) && defined(BSD)
+#       define BOOST_OS_BSD BOOST_PREDEF_MAKE_10_VVRR(BSD)
+#   endif
+#   if !defined(BOOST_OS_BSD)
+#       define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_OS_BSD
+#   define BOOST_OS_BSD_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_BSD_NAME "BSD"
+
+#else
+
+#include <boost/predef/os/bsd/bsdi.h>
+#include <boost/predef/os/bsd/dragonfly.h>
+#include <boost/predef/os/bsd/free.h>
+#include <boost/predef/os/bsd/open.h>
+#include <boost/predef/os/bsd/net.h>
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD,BOOST_OS_BSD_NAME)
diff --git a/third_party/boost/boost/predef/os/bsd/bsdi.h b/third_party/boost/boost/predef/os/bsd/bsdi.h
new file mode 100644
index 0000000..afdcd3e
--- /dev/null
+++ b/third_party/boost/boost/predef/os/bsd/bsdi.h
@@ -0,0 +1,48 @@
+/*
+Copyright Rene Rivera 2012-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_BSD_BSDI_H
+#define BOOST_PREDEF_OS_BSD_BSDI_H
+
+#include <boost/predef/os/bsd.h>
+
+/*`
+[heading `BOOST_OS_BSD_BSDI`]
+
+[@http://en.wikipedia.org/wiki/BSD/OS BSDi BSD/OS] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__bsdi__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_OS_BSD_BSDI BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(__bsdi__) \
+    )
+#   ifndef BOOST_OS_BSD_AVAILABLE
+#       define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE
+#       define BOOST_OS_BSD_AVAILABLE
+#   endif
+#   undef BOOST_OS_BSD_BSDI
+#   define BOOST_OS_BSD_BSDI BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_OS_BSD_BSDI
+#   define BOOST_OS_BSD_BSDI_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_BSD_BSDI_NAME "BSDi BSD/OS"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_BSDI,BOOST_OS_BSD_BSDI_NAME)
diff --git a/third_party/boost/boost/predef/os/bsd/dragonfly.h b/third_party/boost/boost/predef/os/bsd/dragonfly.h
new file mode 100644
index 0000000..1d07579
--- /dev/null
+++ b/third_party/boost/boost/predef/os/bsd/dragonfly.h
@@ -0,0 +1,50 @@
+/*
+Copyright Rene Rivera 2012-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_BSD_DRAGONFLY_H
+#define BOOST_PREDEF_OS_BSD_DRAGONFLY_H
+
+#include <boost/predef/os/bsd.h>
+
+/*`
+[heading `BOOST_OS_BSD_DRAGONFLY`]
+
+[@http://en.wikipedia.org/wiki/DragonFly_BSD DragonFly BSD] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__DragonFly__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_OS_BSD_DRAGONFLY BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(__DragonFly__) \
+    )
+#   ifndef BOOST_OS_BSD_AVAILABLE
+#       define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE
+#       define BOOST_OS_BSD_AVAILABLE
+#   endif
+#   undef BOOST_OS_BSD_DRAGONFLY
+#   if defined(__DragonFly__)
+#       define BOOST_OS_DRAGONFLY_BSD BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_OS_BSD_DRAGONFLY
+#   define BOOST_OS_BSD_DRAGONFLY_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_BSD_DRAGONFLY_NAME "DragonFly BSD"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_DRAGONFLY,BOOST_OS_BSD_DRAGONFLY_NAME)
diff --git a/third_party/boost/boost/predef/os/bsd/free.h b/third_party/boost/boost/predef/os/bsd/free.h
new file mode 100644
index 0000000..248011a
--- /dev/null
+++ b/third_party/boost/boost/predef/os/bsd/free.h
@@ -0,0 +1,60 @@
+/*
+Copyright Rene Rivera 2012-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_BSD_FREE_H
+#define BOOST_PREDEF_OS_BSD_FREE_H
+
+#include <boost/predef/os/bsd.h>
+
+/*`
+[heading `BOOST_OS_BSD_FREE`]
+
+[@http://en.wikipedia.org/wiki/Freebsd FreeBSD] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__FreeBSD__`] [__predef_detection__]]
+
+    [[`__FreeBSD_version`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_OS_BSD_FREE BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(__FreeBSD__) \
+    )
+#   ifndef BOOST_OS_BSD_AVAILABLE
+#       define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE
+#       define BOOST_OS_BSD_AVAILABLE
+#   endif
+#   undef BOOST_OS_BSD_FREE
+#   if defined(__FreeBSD_version)
+#       if __FreeBSD_version < 500000
+#           define BOOST_OS_BSD_FREE \
+                BOOST_PREDEF_MAKE_10_VRP000(__FreeBSD_version)
+#       else
+#           define BOOST_OS_BSD_FREE \
+                BOOST_PREDEF_MAKE_10_VRR000(__FreeBSD_version)
+#       endif
+#   else
+#       define BOOST_OS_BSD_FREE BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_OS_BSD_FREE
+#   define BOOST_OS_BSD_FREE_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_BSD_FREE_NAME "Free BSD"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_FREE,BOOST_OS_BSD_FREE_NAME)
diff --git a/third_party/boost/boost/predef/os/bsd/net.h b/third_party/boost/boost/predef/os/bsd/net.h
new file mode 100644
index 0000000..387cbde
--- /dev/null
+++ b/third_party/boost/boost/predef/os/bsd/net.h
@@ -0,0 +1,84 @@
+/*
+Copyright Rene Rivera 2012-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_BSD_NET_H
+#define BOOST_PREDEF_OS_BSD_NET_H
+
+#include <boost/predef/os/bsd.h>
+
+/*`
+[heading `BOOST_OS_BSD_NET`]
+
+[@http://en.wikipedia.org/wiki/Netbsd NetBSD] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__NETBSD__`] [__predef_detection__]]
+    [[`__NetBSD__`] [__predef_detection__]]
+
+    [[`__NETBSD_version`] [V.R.P]]
+    [[`NetBSD0_8`] [0.8.0]]
+    [[`NetBSD0_9`] [0.9.0]]
+    [[`NetBSD1_0`] [1.0.0]]
+    [[`__NetBSD_Version`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(__NETBSD__) || defined(__NetBSD__) \
+    )
+#   ifndef BOOST_OS_BSD_AVAILABLE
+#       define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE
+#       define BOOST_OS_BSD_AVAILABLE
+#   endif
+#   undef BOOST_OS_BSD_NET
+#   if defined(__NETBSD__)
+#       if defined(__NETBSD_version)
+#           if __NETBSD_version < 500000
+#               define BOOST_OS_BSD_NET \
+                    BOOST_PREDEF_MAKE_10_VRP000(__NETBSD_version)
+#           else
+#               define BOOST_OS_BSD_NET \
+                    BOOST_PREDEF_MAKE_10_VRR000(__NETBSD_version)
+#           endif
+#       else
+#           define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER_AVAILABLE
+#       endif
+#   elif defined(__NetBSD__)
+#       if !defined(BOOST_OS_BSD_NET) && defined(NetBSD0_8)
+#           define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER(0,8,0)
+#       endif
+#       if !defined(BOOST_OS_BSD_NET) && defined(NetBSD0_9)
+#           define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER(0,9,0)
+#       endif
+#       if !defined(BOOST_OS_BSD_NET) && defined(NetBSD1_0)
+#           define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER(1,0,0)
+#       endif
+#       if !defined(BOOST_OS_BSD_NET) && defined(__NetBSD_Version)
+#           define BOOST_OS_BSD_NET \
+                BOOST_PREDEF_MAKE_10_VVRR00PP00(__NetBSD_Version)
+#       endif
+#       if !defined(BOOST_OS_BSD_NET)
+#           define BOOST_OS_BSD_NET BOOST_VERSION_NUMBER_AVAILABLE
+#       endif
+#   endif
+#endif
+
+#if BOOST_OS_BSD_NET
+#   define BOOST_OS_BSD_NET_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_BSD_NET_NAME "DragonFly BSD"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_NET,BOOST_OS_BSD_NET_NAME)
diff --git a/third_party/boost/boost/predef/os/bsd/open.h b/third_party/boost/boost/predef/os/bsd/open.h
new file mode 100644
index 0000000..423103a
--- /dev/null
+++ b/third_party/boost/boost/predef/os/bsd/open.h
@@ -0,0 +1,171 @@
+/*
+Copyright Rene Rivera 2012-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_BSD_OPEN_H
+#define BOOST_PREDEF_OS_BSD_OPEN_H
+
+#include <boost/predef/os/bsd.h>
+
+/*`
+[heading `BOOST_OS_BSD_OPEN`]
+
+[@http://en.wikipedia.org/wiki/Openbsd OpenBSD] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__OpenBSD__`] [__predef_detection__]]
+
+    [[`OpenBSD2_0`] [2.0.0]]
+    [[`OpenBSD2_1`] [2.1.0]]
+    [[`OpenBSD2_2`] [2.2.0]]
+    [[`OpenBSD2_3`] [2.3.0]]
+    [[`OpenBSD2_4`] [2.4.0]]
+    [[`OpenBSD2_5`] [2.5.0]]
+    [[`OpenBSD2_6`] [2.6.0]]
+    [[`OpenBSD2_7`] [2.7.0]]
+    [[`OpenBSD2_8`] [2.8.0]]
+    [[`OpenBSD2_9`] [2.9.0]]
+    [[`OpenBSD3_0`] [3.0.0]]
+    [[`OpenBSD3_1`] [3.1.0]]
+    [[`OpenBSD3_2`] [3.2.0]]
+    [[`OpenBSD3_3`] [3.3.0]]
+    [[`OpenBSD3_4`] [3.4.0]]
+    [[`OpenBSD3_5`] [3.5.0]]
+    [[`OpenBSD3_6`] [3.6.0]]
+    [[`OpenBSD3_7`] [3.7.0]]
+    [[`OpenBSD3_8`] [3.8.0]]
+    [[`OpenBSD3_9`] [3.9.0]]
+    [[`OpenBSD4_0`] [4.0.0]]
+    [[`OpenBSD4_1`] [4.1.0]]
+    [[`OpenBSD4_2`] [4.2.0]]
+    [[`OpenBSD4_3`] [4.3.0]]
+    [[`OpenBSD4_4`] [4.4.0]]
+    [[`OpenBSD4_5`] [4.5.0]]
+    [[`OpenBSD4_6`] [4.6.0]]
+    [[`OpenBSD4_7`] [4.7.0]]
+    [[`OpenBSD4_8`] [4.8.0]]
+    [[`OpenBSD4_9`] [4.9.0]]
+    ]
+ */
+
+#define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(__OpenBSD__) \
+    )
+#   ifndef BOOST_OS_BSD_AVAILABLE
+#       define BOOST_OS_BSD BOOST_VERSION_NUMBER_AVAILABLE
+#       define BOOST_OS_BSD_AVAILABLE
+#   endif
+#   undef BOOST_OS_BSD_OPEN
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_0)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,0,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_1)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,1,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_2)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,2,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_3)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,3,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_4)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,4,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_5)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,5,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_6)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,6,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_7)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,7,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_8)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,8,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD2_9)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(2,9,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_0)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,0,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_1)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,1,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_2)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,2,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_3)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,3,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_4)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,4,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_5)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,5,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_6)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,6,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_7)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,7,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_8)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,8,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD3_9)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(3,9,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_0)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,0,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_1)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,1,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_2)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,2,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_3)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,3,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_4)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,4,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_5)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,5,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_6)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,6,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_7)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,7,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_8)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,8,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN) && defined(OpenBSD4_9)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER(4,9,0)
+#   endif
+#   if !defined(BOOST_OS_BSD_OPEN)
+#       define BOOST_OS_BSD_OPEN BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_OS_BSD_OPEN
+#   define BOOST_OS_BSD_OPEN_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_BSD_OPEN_NAME "OpenBSD"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_BSD_OPEN,BOOST_OS_BSD_OPEN_NAME)
diff --git a/third_party/boost/boost/predef/os/cygwin.h b/third_party/boost/boost/predef/os/cygwin.h
new file mode 100644
index 0000000..1985c97
--- /dev/null
+++ b/third_party/boost/boost/predef/os/cygwin.h
@@ -0,0 +1,45 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_CYGWIN_H
+#define BOOST_PREDEF_OS_CYGWIN_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_CYGWIN`]
+
+[@http://en.wikipedia.org/wiki/Cygwin Cygwin] evironment.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__CYGWIN__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_OS_CYGWIN BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(__CYGWIN__) \
+    )
+#   undef BOOST_OS_CYGWIN
+#   define BOOST_OS_CGYWIN BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_OS_CYGWIN
+#   define BOOST_OS_CYGWIN_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_CYGWIN_NAME "Cygwin"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_CYGWIN,BOOST_OS_CYGWIN_NAME)
diff --git a/third_party/boost/boost/predef/os/haiku.h b/third_party/boost/boost/predef/os/haiku.h
new file mode 100644
index 0000000..d79dbea
--- /dev/null
+++ b/third_party/boost/boost/predef/os/haiku.h
@@ -0,0 +1,46 @@
+/*
+Copyright Jessica Hamilton 2014
+Copyright Rene Rivera 2014-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_HAIKU_H
+#define BOOST_PREDEF_OS_HAIKU_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_HAIKU`]
+
+[@http://en.wikipedia.org/wiki/Haiku_(operating_system) Haiku] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__HAIKU__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_OS_HAIKU BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(__HAIKU__) \
+    )
+#   undef BOOST_OS_HAIKU
+#   define BOOST_OS_HAIKU BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_OS_HAIKU
+#   define BOOST_OS_HAIKU_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_HAIKU_NAME "Haiku"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_HAIKU,BOOST_OS_HAIKU_NAME)
diff --git a/third_party/boost/boost/predef/os/hpux.h b/third_party/boost/boost/predef/os/hpux.h
new file mode 100644
index 0000000..29243f4
--- /dev/null
+++ b/third_party/boost/boost/predef/os/hpux.h
@@ -0,0 +1,47 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_HPUX_H
+#define BOOST_PREDEF_OS_HPUX_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_HPUX`]
+
+[@http://en.wikipedia.org/wiki/HP-UX HP-UX] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`hpux`] [__predef_detection__]]
+    [[`_hpux`] [__predef_detection__]]
+    [[`__hpux`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_OS_HPUX BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(hpux) || defined(_hpux) || defined(__hpux) \
+    )
+#   undef BOOST_OS_HPUX
+#   define BOOST_OS_HPUX BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_OS_HPUX
+#   define BOOST_OS_HPUX_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_HPUX_NAME "HP-UX"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_HPUX,BOOST_OS_HPUX_NAME)
diff --git a/third_party/boost/boost/predef/os/ios.h b/third_party/boost/boost/predef/os/ios.h
new file mode 100644
index 0000000..f853815
--- /dev/null
+++ b/third_party/boost/boost/predef/os/ios.h
@@ -0,0 +1,51 @@
+/*
+Copyright Franz Detro 2014
+Copyright Rene Rivera 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_IOS_H
+#define BOOST_PREDEF_OS_IOS_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_IOS`]
+
+[@http://en.wikipedia.org/wiki/iOS iOS] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__APPLE__`] [__predef_detection__]]
+    [[`__MACH__`] [__predef_detection__]]
+    [[`__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__`] [__predef_detection__]]
+
+    [[`__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__`] [__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__*1000]]
+    ]
+ */
+
+#define BOOST_OS_IOS BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(__APPLE__) && defined(__MACH__) && \
+    defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) \
+    )
+#   undef BOOST_OS_IOS
+#   define BOOST_OS_IOS (__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__*1000)
+#endif
+
+#if BOOST_OS_IOS
+#   define BOOST_OS_IOS_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_IOS_NAME "iOS"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_IOS,BOOST_OS_IOS_NAME)
diff --git a/third_party/boost/boost/predef/os/irix.h b/third_party/boost/boost/predef/os/irix.h
new file mode 100644
index 0000000..fa6ac41
--- /dev/null
+++ b/third_party/boost/boost/predef/os/irix.h
@@ -0,0 +1,46 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_IRIX_H
+#define BOOST_PREDEF_OS_IRIX_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_IRIX`]
+
+[@http://en.wikipedia.org/wiki/Irix IRIX] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`sgi`] [__predef_detection__]]
+    [[`__sgi`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_OS_IRIX BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(sgi) || defined(__sgi) \
+    )
+#   undef BOOST_OS_IRIX
+#   define BOOST_OS_IRIX BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_OS_IRIX
+#   define BOOST_OS_IRIX_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_IRIX_NAME "IRIX"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_IRIX,BOOST_OS_IRIX_NAME)
diff --git a/third_party/boost/boost/predef/os/linux.h b/third_party/boost/boost/predef/os/linux.h
new file mode 100644
index 0000000..a297d08
--- /dev/null
+++ b/third_party/boost/boost/predef/os/linux.h
@@ -0,0 +1,46 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_LINUX_H
+#define BOOST_PREDEF_OS_LINUX_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_LINUX`]
+
+[@http://en.wikipedia.org/wiki/Linux Linux] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`linux`] [__predef_detection__]]
+    [[`__linux`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_OS_LINUX BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(linux) || defined(__linux) \
+    )
+#   undef BOOST_OS_LINUX
+#   define BOOST_OS_LINUX BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_OS_LINUX
+#   define BOOST_OS_LINUX_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_LINUX_NAME "Linux"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_LINUX,BOOST_OS_LINUX_NAME)
diff --git a/third_party/boost/boost/predef/os/macos.h b/third_party/boost/boost/predef/os/macos.h
new file mode 100644
index 0000000..4afb30d
--- /dev/null
+++ b/third_party/boost/boost/predef/os/macos.h
@@ -0,0 +1,65 @@
+/*
+Copyright Rene Rivera 2008-2015
+Copyright Franz Detro 2014
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_MACOS_H
+#define BOOST_PREDEF_OS_MACOS_H
+
+/* Special case: iOS will define the same predefs as MacOS, and additionally
+ '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__'. We can guard against that,
+ but only if we detect iOS first. Hence we will force include iOS detection
+ * before doing any MacOS detection.
+ */
+#include <boost/predef/os/ios.h>
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_MACOS`]
+
+[@http://en.wikipedia.org/wiki/Mac_OS Mac OS] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`macintosh`] [__predef_detection__]]
+    [[`Macintosh`] [__predef_detection__]]
+    [[`__APPLE__`] [__predef_detection__]]
+    [[`__MACH__`] [__predef_detection__]]
+
+    [[`__APPLE__`, `__MACH__`] [10.0.0]]
+    [[ /otherwise/ ] [9.0.0]]
+    ]
+ */
+
+#define BOOST_OS_MACOS BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(macintosh) || defined(Macintosh) || \
+    (defined(__APPLE__) && defined(__MACH__)) \
+    )
+#   undef BOOST_OS_MACOS
+#   if !defined(BOOST_OS_MACOS) && defined(__APPLE__) && defined(__MACH__)
+#       define BOOST_OS_MACOS BOOST_VERSION_NUMBER(10,0,0)
+#   endif
+#   if !defined(BOOST_OS_MACOS)
+#       define BOOST_OS_MACOS BOOST_VERSION_NUMBER(9,0,0)
+#   endif
+#endif
+
+#if BOOST_OS_MACOS
+#   define BOOST_OS_MACOS_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_MACOS_NAME "Mac OS"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_MACOS,BOOST_OS_MACOS_NAME)
diff --git a/third_party/boost/boost/predef/os/os400.h b/third_party/boost/boost/predef/os/os400.h
new file mode 100644
index 0000000..b3446c2
--- /dev/null
+++ b/third_party/boost/boost/predef/os/os400.h
@@ -0,0 +1,45 @@
+/*
+Copyright Rene Rivera 2011-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_OS400_H
+#define BOOST_PREDEF_OS_OS400_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_OS400`]
+
+[@http://en.wikipedia.org/wiki/IBM_i IBM OS/400] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__OS400__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_OS_OS400 BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(__OS400__) \
+    )
+#   undef BOOST_OS_OS400
+#   define BOOST_OS_OS400 BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_OS_OS400
+#   define BOOST_OS_OS400_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_OS400_NAME "IBM OS/400"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_OS400,BOOST_OS_OS400_NAME)
diff --git a/third_party/boost/boost/predef/os/qnxnto.h b/third_party/boost/boost/predef/os/qnxnto.h
new file mode 100644
index 0000000..e76fbf2
--- /dev/null
+++ b/third_party/boost/boost/predef/os/qnxnto.h
@@ -0,0 +1,59 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_QNXNTO_H
+#define BOOST_PREDEF_OS_QNXNTO_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_QNX`]
+
+[@http://en.wikipedia.org/wiki/QNX QNX] operating system.
+Version number available as major, and minor if possible. And
+version 4 is specifically detected.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__QNX__`] [__predef_detection__]]
+    [[`__QNXNTO__`] [__predef_detection__]]
+
+    [[`_NTO_VERSION`] [V.R.0]]
+    [[`__QNX__`] [4.0.0]]
+    ]
+ */
+
+#define BOOST_OS_QNX BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(__QNX__) || defined(__QNXNTO__) \
+    )
+#   undef BOOST_OS_QNX
+#   if !defined(BOOST_OS_QNX) && defined(_NTO_VERSION)
+#       define BOOST_OS_QNX BOOST_PREDEF_MAKE_10_VVRR(_NTO_VERSION)
+#   endif
+#   if !defined(BOOST_OS_QNX) && defined(__QNX__)
+#       define BOOST_OS_QNX BOOST_VERSION_NUMBER(4,0,0)
+#   endif
+#   if !defined(BOOST_OS_QNX)
+#       define BOOST_OS_QNX BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_OS_QNX
+#   define BOOST_OS_QNX_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_QNX_NAME "QNX"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_QNX,BOOST_OS_QNX_NAME)
diff --git a/third_party/boost/boost/predef/os/solaris.h b/third_party/boost/boost/predef/os/solaris.h
new file mode 100644
index 0000000..75ddc91
--- /dev/null
+++ b/third_party/boost/boost/predef/os/solaris.h
@@ -0,0 +1,46 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_SOLARIS_H
+#define BOOST_PREDEF_OS_SOLARIS_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_SOLARIS`]
+
+[@http://en.wikipedia.org/wiki/Solaris_Operating_Environment Solaris] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`sun`] [__predef_detection__]]
+    [[`__sun`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_OS_SOLARIS BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(sun) || defined(__sun) \
+    )
+#   undef BOOST_OS_SOLARIS
+#   define BOOST_OS_SOLARIS BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_OS_SOLARIS
+#   define BOOST_OS_SOLARIS_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_SOLARIS_NAME "Solaris"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_SOLARIS,BOOST_OS_SOLARIS_NAME)
diff --git a/third_party/boost/boost/predef/os/unix.h b/third_party/boost/boost/predef/os/unix.h
new file mode 100644
index 0000000..a607104
--- /dev/null
+++ b/third_party/boost/boost/predef/os/unix.h
@@ -0,0 +1,76 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_UNIX_H
+#define BOOST_PREDEF_OS_UNIX_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_UNIX`]
+
+[@http://en.wikipedia.org/wiki/Unix Unix Environment] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`unix`] [__predef_detection__]]
+    [[`__unix`] [__predef_detection__]]
+    [[`_XOPEN_SOURCE`] [__predef_detection__]]
+    [[`_POSIX_SOURCE`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_OS_UNIX BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(unix) || defined(__unix) || \
+    defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE)
+#   undef BOOST_OS_UNIX
+#   define BOOST_OS_UNIX BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_OS_UNIX
+#   define BOOST_OS_UNIX_AVAILABLE
+#endif
+
+#define BOOST_OS_UNIX_NAME "Unix Environment"
+
+/*`
+[heading `BOOST_OS_SVR4`]
+
+[@http://en.wikipedia.org/wiki/UNIX_System_V SVR4 Environment] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__sysv__`] [__predef_detection__]]
+    [[`__SVR4`] [__predef_detection__]]
+    [[`__svr4__`] [__predef_detection__]]
+    [[`_SYSTYPE_SVR4`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_OS_SVR4 BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__sysv__) || defined(__SVR4) || \
+    defined(__svr4__) || defined(_SYSTYPE_SVR4)
+#   undef BOOST_OS_SVR4
+#   define BOOST_OS_SVR4 BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_OS_SVR4
+#   define BOOST_OS_SVR4_AVAILABLE
+#endif
+
+#define BOOST_OS_SVR4_NAME "SVR4 Environment"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_UNIX,BOOST_OS_UNIX_NAME)
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_SVR4,BOOST_OS_SVR4_NAME)
diff --git a/third_party/boost/boost/predef/os/vms.h b/third_party/boost/boost/predef/os/vms.h
new file mode 100644
index 0000000..2f8f786
--- /dev/null
+++ b/third_party/boost/boost/predef/os/vms.h
@@ -0,0 +1,52 @@
+/*
+Copyright Rene Rivera 2011-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_VMS_H
+#define BOOST_PREDEF_OS_VMS_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_VMS`]
+
+[@http://en.wikipedia.org/wiki/Vms VMS] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`VMS`] [__predef_detection__]]
+    [[`__VMS`] [__predef_detection__]]
+
+    [[`__VMS_VER`] [V.R.P]]
+    ]
+ */
+
+#define BOOST_OS_VMS BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(VMS) || defined(__VMS) \
+    )
+#   undef BOOST_OS_VMS
+#   if defined(__VMS_VER)
+#       define BOOST_OS_VMS BOOST_PREDEF_MAKE_10_VVRR00PP00(__VMS_VER)
+#   else
+#       define BOOST_OS_VMS BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#if BOOST_OS_VMS
+#   define BOOST_OS_VMS_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_VMS_NAME "VMS"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_VMS,BOOST_OS_VMS_NAME)
diff --git a/third_party/boost/boost/predef/os/windows.h b/third_party/boost/boost/predef/os/windows.h
new file mode 100644
index 0000000..9db4390
--- /dev/null
+++ b/third_party/boost/boost/predef/os/windows.h
@@ -0,0 +1,51 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_OS_WINDOWS_H
+#define BOOST_PREDEF_OS_WINDOWS_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_OS_WINDOWS`]
+
+[@http://en.wikipedia.org/wiki/Category:Microsoft_Windows Microsoft Windows] operating system.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`_WIN32`] [__predef_detection__]]
+    [[`_WIN64`] [__predef_detection__]]
+    [[`__WIN32__`] [__predef_detection__]]
+    [[`__TOS_WIN__`] [__predef_detection__]]
+    [[`__WINDOWS__`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_OS_WINDOWS BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if !defined(BOOST_PREDEF_DETAIL_OS_DETECTED) && ( \
+    defined(_WIN32) || defined(_WIN64) || \
+    defined(__WIN32__) || defined(__TOS_WIN__) || \
+    defined(__WINDOWS__) \
+    )
+#   undef BOOST_OS_WINDOWS
+#   define BOOST_OS_WINDOWS BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_OS_WINDOWS
+#   define BOOST_OS_WINDOWS_AVAILABLE
+#   include <boost/predef/detail/os_detected.h>
+#endif
+
+#define BOOST_OS_WINDOWS_NAME "Microsoft Windows"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_OS_WINDOWS,BOOST_OS_WINDOWS_NAME)
diff --git a/third_party/boost/boost/predef/other.h b/third_party/boost/boost/predef/other.h
new file mode 100644
index 0000000..c09ad49
--- /dev/null
+++ b/third_party/boost/boost/predef/other.h
@@ -0,0 +1,16 @@
+/*
+Copyright Rene Rivera 2013-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#if !defined(BOOST_PREDEF_OTHER_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
+#ifndef BOOST_PREDEF_OTHER_H
+#define BOOST_PREDEF_OTHER_H
+#endif
+
+#include <boost/predef/other/endian.h>
+/*#include <boost/predef/other/.h>*/
+
+#endif
diff --git a/third_party/boost/boost/predef/other/endian.h b/third_party/boost/boost/predef/other/endian.h
new file mode 100644
index 0000000..6d1f43f
--- /dev/null
+++ b/third_party/boost/boost/predef/other/endian.h
@@ -0,0 +1,204 @@
+/*
+Copyright Rene Rivera 2013-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_ENDIAN_H
+#define BOOST_PREDEF_ENDIAN_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+#include <boost/predef/library/c/gnu.h>
+#include <boost/predef/os/macos.h>
+#include <boost/predef/os/bsd.h>
+#include <boost/predef/os/android.h>
+
+/*`
+[heading `BOOST_ENDIAN_*`]
+
+Detection of endian memory ordering. There are four defined macros
+in this header that define the various generally possible endian
+memory orderings:
+
+* `BOOST_ENDIAN_BIG_BYTE`, byte-swapped big-endian.
+* `BOOST_ENDIAN_BIG_WORD`, word-swapped big-endian.
+* `BOOST_ENDIAN_LITTLE_BYTE`, byte-swapped little-endian.
+* `BOOST_ENDIAN_LITTLE_WORD`, word-swapped little-endian.
+
+The detection is conservative in that it only identifies endianness
+that it knows for certain. In particular bi-endianness is not
+indicated as is it not practically possible to determine the
+endianness from anything but an operating system provided
+header. And the currently known headers do not define that
+programatic bi-endianness is available.
+
+This implementation is a compilation of various publicly available
+information and acquired knowledge:
+
+# The indispensable documentation of "Pre-defined Compiler Macros"
+  [@http://sourceforge.net/p/predef/wiki/Endianness Endianness].
+# The various endian specifications available in the
+  [@http://wikipedia.org/ Wikipedia] computer architecture pages.
+# Generally available searches for headers that define endianness.
+ */
+
+#define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_NOT_AVAILABLE
+#define BOOST_ENDIAN_BIG_WORD BOOST_VERSION_NUMBER_NOT_AVAILABLE
+#define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_NOT_AVAILABLE
+#define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+/* GNU libc provides a header defining __BYTE_ORDER, or _BYTE_ORDER.
+ * And some OSs provide some for of endian header also.
+ */
+#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
+    !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
+#   if BOOST_LIB_C_GNU || BOOST_OS_ANDROID
+#       include <endian.h>
+#   else
+#       if BOOST_OS_MACOS
+#           include <machine/endian.h>
+#       else
+#           if BOOST_OS_BSD
+#               if BOOST_OS_BSD_OPEN
+#                   include <machine/endian.h>
+#               else
+#                   include <sys/endian.h>
+#               endif
+#           endif
+#       endif
+#   endif
+#   if defined(__BYTE_ORDER)
+#       if defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN)
+#           undef BOOST_ENDIAN_BIG_BYTE
+#           define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE
+#       endif
+#       if defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN)
+#           undef BOOST_ENDIAN_LITTLE_BYTE
+#           define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
+#       endif
+#       if defined(__PDP_ENDIAN) && (__BYTE_ORDER == __PDP_ENDIAN)
+#           undef BOOST_ENDIAN_LITTLE_WORD
+#           define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_AVAILABLE
+#       endif
+#   endif
+#   if !defined(__BYTE_ORDER) && defined(_BYTE_ORDER)
+#       if defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN)
+#           undef BOOST_ENDIAN_BIG_BYTE
+#           define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE
+#       endif
+#       if defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN)
+#           undef BOOST_ENDIAN_LITTLE_BYTE
+#           define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
+#       endif
+#       if defined(_PDP_ENDIAN) && (_BYTE_ORDER == _PDP_ENDIAN)
+#           undef BOOST_ENDIAN_LITTLE_WORD
+#           define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_AVAILABLE
+#       endif
+#   endif
+#endif
+
+/* Built-in byte-swpped big-endian macros.
+ */
+#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
+    !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
+#   if (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) || \
+       (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)) || \
+        defined(__ARMEB__) || \
+        defined(__THUMBEB__) || \
+        defined(__AARCH64EB__) || \
+        defined(_MIPSEB) || \
+        defined(__MIPSEB) || \
+        defined(__MIPSEB__)
+#       undef BOOST_ENDIAN_BIG_BYTE
+#       define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+/* Built-in byte-swpped little-endian macros.
+ */
+#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
+    !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
+#   if (defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \
+       (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)) || \
+        defined(__ARMEL__) || \
+        defined(__THUMBEL__) || \
+        defined(__AARCH64EL__) || \
+        defined(_MIPSEL) || \
+        defined(__MIPSEL) || \
+        defined(__MIPSEL__)
+#       undef BOOST_ENDIAN_LITTLE_BYTE
+#       define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+/* Some architectures are strictly one endianess (as opposed
+ * the current common bi-endianess).
+ */
+#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
+    !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
+#   include <boost/predef/architecture.h>
+#   if BOOST_ARCH_M68K || \
+        BOOST_ARCH_PARISC || \
+        BOOST_ARCH_SPARC || \
+        BOOST_ARCH_SYS370 || \
+        BOOST_ARCH_SYS390 || \
+        BOOST_ARCH_Z
+#       undef BOOST_ENDIAN_BIG_BYTE
+#       define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#   if BOOST_ARCH_AMD64 || \
+        BOOST_ARCH_IA64 || \
+        BOOST_ARCH_X86 || \
+        BOOST_ARCH_BLACKFIN
+#       undef BOOST_ENDIAN_LITTLE_BYTE
+#       define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+/* Windows on ARM, if not otherwise detected/specified, is always
+ * byte-swaped little-endian.
+ */
+#if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
+    !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
+#   if BOOST_ARCH_ARM
+#       include <boost/predef/os/windows.h>
+#       if BOOST_OS_WINDOWS
+#           undef BOOST_ENDIAN_LITTLE_BYTE
+#           define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
+#       endif
+#   endif
+#endif
+
+#if BOOST_ENDIAN_BIG_BYTE
+#   define BOOST_ENDIAN_BIG_BYTE_AVAILABLE
+#endif
+#if BOOST_ENDIAN_BIG_WORD
+#   define BOOST_ENDIAN_BIG_WORD_BYTE_AVAILABLE
+#endif
+#if BOOST_ENDIAN_LITTLE_BYTE
+#   define BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE
+#endif
+#if BOOST_ENDIAN_LITTLE_WORD
+#   define BOOST_ENDIAN_LITTLE_WORD_BYTE_AVAILABLE
+#endif
+
+#define BOOST_ENDIAN_BIG_BYTE_NAME "Byte-Swapped Big-Endian"
+#define BOOST_ENDIAN_BIG_WORD_NAME "Word-Swapped Big-Endian"
+#define BOOST_ENDIAN_LITTLE_BYTE_NAME "Byte-Swapped Little-Endian"
+#define BOOST_ENDIAN_LITTLE_WORD_NAME "Word-Swapped Little-Endian"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_BYTE,BOOST_ENDIAN_BIG_BYTE_NAME)
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_WORD,BOOST_ENDIAN_BIG_WORD_NAME)
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_BYTE,BOOST_ENDIAN_LITTLE_BYTE_NAME)
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_WORD,BOOST_ENDIAN_LITTLE_WORD_NAME)
diff --git a/third_party/boost/boost/predef/platform.h b/third_party/boost/boost/predef/platform.h
new file mode 100644
index 0000000..c0c8706
--- /dev/null
+++ b/third_party/boost/boost/predef/platform.h
@@ -0,0 +1,21 @@
+/*
+Copyright Rene Rivera 2013-2015
+Copyright (c) Microsoft Corporation 2014
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#if !defined(BOOST_PREDEF_PLATFORM_H) || defined(BOOST_PREDEF_INTERNAL_GENERATE_TESTS)
+#ifndef BOOST_PREDEF_PLATFORM_H
+#define BOOST_PREDEF_PLATFORM_H
+#endif
+
+#include <boost/predef/platform/mingw.h>
+#include <boost/predef/platform/windows_desktop.h>
+#include <boost/predef/platform/windows_store.h>
+#include <boost/predef/platform/windows_phone.h>
+#include <boost/predef/platform/windows_runtime.h>
+/*#include <boost/predef/platform/.h>*/
+
+#endif
diff --git a/third_party/boost/boost/predef/platform/mingw.h b/third_party/boost/boost/predef/platform/mingw.h
new file mode 100644
index 0000000..64c5837
--- /dev/null
+++ b/third_party/boost/boost/predef/platform/mingw.h
@@ -0,0 +1,69 @@
+/*
+Copyright Rene Rivera 2008-2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_COMPILER_MINGW_H
+#define BOOST_PREDEF_COMPILER_MINGW_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+
+/*`
+[heading `BOOST_PLAT_MINGW`]
+
+[@http://en.wikipedia.org/wiki/MinGW MinGW] platform.
+Version number available as major, minor, and patch.
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`__MINGW32__`] [__predef_detection__]]
+    [[`__MINGW64__`] [__predef_detection__]]
+
+    [[`__MINGW64_VERSION_MAJOR`, `__MINGW64_VERSION_MINOR`] [V.R.0]]
+    [[`__MINGW32_VERSION_MAJOR`, `__MINGW32_VERSION_MINOR`] [V.R.0]]
+    ]
+ */
+
+#define BOOST_PLAT_MINGW BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if defined(__MINGW32__) || defined(__MINGW64__)
+#   include <_mingw.h>
+#   if !defined(BOOST_PLAT_MINGW_DETECTION) && (defined(__MINGW64_VERSION_MAJOR) && defined(__MINGW64_VERSION_MINOR))
+#       define BOOST_PLAT_MINGW_DETECTION \
+            BOOST_VERSION_NUMBER(__MINGW64_VERSION_MAJOR,__MINGW64_VERSION_MINOR,0)
+#   endif
+#   if !defined(BOOST_PLAT_MINGW_DETECTION) && (defined(__MINGW32_VERSION_MAJOR) && defined(__MINGW32_VERSION_MINOR))
+#       define BOOST_PLAT_MINGW_DETECTION \
+            BOOST_VERSION_NUMBER(__MINGW32_MAJOR_VERSION,__MINGW32_MINOR_VERSION,0)
+#   endif
+#   if !defined(BOOST_PLAT_MINGW_DETECTION)
+#       define BOOST_PLAT_MINGW_DETECTION BOOST_VERSION_NUMBER_AVAILABLE
+#   endif
+#endif
+
+#ifdef BOOST_PLAT_MINGW_DETECTION
+#   define BOOST_PLAT_MINGW_AVAILABLE
+#   if defined(BOOST_PREDEF_DETAIL_PLAT_DETECTED)
+#       define BOOST_PLAT_MINGW_EMULATED BOOST_PLAT_MINGW_DETECTION
+#   else
+#       undef BOOST_PLAT_MINGW
+#       define BOOST_PLAT_MINGW BOOST_PLAT_MINGW_DETECTION
+#   endif
+#   include <boost/predef/detail/platform_detected.h>
+#endif
+
+#define BOOST_PLAT_MINGW_NAME "MinGW"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_MINGW,BOOST_PLAT_MINGW_NAME)
+
+#ifdef BOOST_PLAT_MINGW_EMULATED
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_MINGW_EMULATED,BOOST_PLAT_MINGW_NAME)
+#endif
diff --git a/third_party/boost/boost/predef/platform/windows_desktop.h b/third_party/boost/boost/predef/platform/windows_desktop.h
new file mode 100644
index 0000000..41485e9
--- /dev/null
+++ b/third_party/boost/boost/predef/platform/windows_desktop.h
@@ -0,0 +1,45 @@
+/*
+Copyright (c) Microsoft Corporation 2014
+Copyright Rene Rivera 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_PLAT_WINDOWS_DESKTOP_H
+#define BOOST_PREDEF_PLAT_WINDOWS_DESKTOP_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+#include <boost/predef/os/windows.h>
+
+/*`
+[heading `BOOST_PLAT_WINDOWS_DESKTOP`]
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`!WINAPI_FAMILY`] [__predef_detection__]]
+    [[`WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_PLAT_WINDOWS_DESKTOP BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if BOOST_OS_WINDOWS && \
+    ( !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) )
+#   undef BOOST_PLAT_WINDOWS_DESKTOP
+#   define BOOST_PLAT_WINDOWS_DESKTOP BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_PLAT_WINDOWS_DESKTOP
+#   define BOOST_PLAT_WINDOWS_DESKTOP_AVAILABLE
+#   include <boost/predef/detail/platform_detected.h>
+#endif
+
+#define BOOST_PLAT_WINDOWS_DESKTOP_NAME "Windows Desktop"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_DESKTOP,BOOST_PLAT_WINDOWS_DESKTOP_NAME)
diff --git a/third_party/boost/boost/predef/platform/windows_phone.h b/third_party/boost/boost/predef/platform/windows_phone.h
new file mode 100644
index 0000000..5ed6410
--- /dev/null
+++ b/third_party/boost/boost/predef/platform/windows_phone.h
@@ -0,0 +1,43 @@
+/*
+Copyright (c) Microsoft Corporation 2014
+Copyright Rene Rivera 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_PLAT_WINDOWS_PHONE_H
+#define BOOST_PREDEF_PLAT_WINDOWS_PHONE_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+#include <boost/predef/os/windows.h>
+
+/*`
+[heading `BOOST_PLAT_WINDOWS_PHONE`]
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_PLAT_WINDOWS_PHONE BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if BOOST_OS_WINDOWS && defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
+#   undef BOOST_PLAT_WINDOWS_PHONE
+#   define BOOST_PLAT_WINDOWS_PHONE BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_PLAT_WINDOWS_PHONE
+#   define BOOST_PLAT_WINDOWS_PHONE_AVAILABLE
+#   include <boost/predef/detail/platform_detected.h>
+#endif
+
+#define BOOST_PLAT_WINDOWS_PHONE_NAME "Windows Phone"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_PHONE,BOOST_PLAT_WINDOWS_PHONE_NAME)
diff --git a/third_party/boost/boost/predef/platform/windows_runtime.h b/third_party/boost/boost/predef/platform/windows_runtime.h
new file mode 100644
index 0000000..bffab75
--- /dev/null
+++ b/third_party/boost/boost/predef/platform/windows_runtime.h
@@ -0,0 +1,45 @@
+/*
+Copyright (c) Microsoft Corporation 2014
+Copyright Rene Rivera 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_PLAT_WINDOWS_RUNTIME_H
+#define BOOST_PREDEF_PLAT_WINDOWS_RUNTIME_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+#include <boost/predef/os/windows.h>
+
+/*`
+[heading `BOOST_PLAT_WINDOWS_RUNTIME`]
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`WINAPI_FAMILY == WINAPI_FAMILY_APP`] [__predef_detection__]]
+    [[`WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_PLAT_WINDOWS_RUNTIME BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if BOOST_OS_WINDOWS && defined(WINAPI_FAMILY) && \
+    ( WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP )
+#   undef BOOST_PLAT_WINDOWS_RUNTIME
+#   define BOOST_PLAT_WINDOWS_RUNTIME BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_PLAT_WINDOWS_RUNTIME
+#   define BOOST_PLAT_WINDOWS_RUNTIME_AVAILABLE
+#   include <boost/predef/detail/platform_detected.h>
+#endif
+
+#define BOOST_PLAT_WINDOWS_RUNTIME_NAME "Windows Runtime"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_RUNTIME,BOOST_PLAT_WINDOWS_RUNTIME_NAME)
diff --git a/third_party/boost/boost/predef/platform/windows_store.h b/third_party/boost/boost/predef/platform/windows_store.h
new file mode 100644
index 0000000..86e7116
--- /dev/null
+++ b/third_party/boost/boost/predef/platform/windows_store.h
@@ -0,0 +1,43 @@
+/*
+Copyright (c) Microsoft Corporation 2014
+Copyright Rene Rivera 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_PLAT_WINDOWS_STORE_H
+#define BOOST_PREDEF_PLAT_WINDOWS_STORE_H
+
+#include <boost/predef/version_number.h>
+#include <boost/predef/make.h>
+#include <boost/predef/os/windows.h>
+
+/*`
+[heading `BOOST_PLAT_WINDOWS_STORE`]
+
+[table
+    [[__predef_symbol__] [__predef_version__]]
+
+    [[`WINAPI_FAMILY == WINAPI_FAMILY_APP`] [__predef_detection__]]
+    ]
+ */
+
+#define BOOST_PLAT_WINDOWS_STORE BOOST_VERSION_NUMBER_NOT_AVAILABLE
+
+#if BOOST_OS_WINDOWS && defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP
+#   undef BOOST_PLAT_WINDOWS_STORE
+#   define BOOST_PLAT_WINDOWS_STORE BOOST_VERSION_NUMBER_AVAILABLE
+#endif
+
+#if BOOST_PLAT_WINDOWS_STORE
+#   define BOOST_PLAT_WINDOWS_STORE_AVAILABLE
+#   include <boost/predef/detail/platform_detected.h>
+#endif
+
+#define BOOST_PLAT_WINDOWS_STORE_NAME "Windows Store"
+
+#endif
+
+#include <boost/predef/detail/test.h>
+BOOST_PREDEF_DECLARE_TEST(BOOST_PLAT_WINDOWS_STORE,BOOST_PLAT_WINDOWS_STORE_NAME)
diff --git a/third_party/boost/boost/predef/version.h b/third_party/boost/boost/predef/version.h
new file mode 100644
index 0000000..2fcdefa
--- /dev/null
+++ b/third_party/boost/boost/predef/version.h
@@ -0,0 +1,15 @@
+/*
+Copyright Rene Rivera 2015
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_VERSION_H
+#define BOOST_PREDEF_VERSION_H
+
+#include <boost/predef/version_number.h>
+
+#define BOOST_PREDEF_VERSION BOOST_VERSION_NUMBER(1,4,0)
+
+#endif
diff --git a/third_party/boost/boost/predef/version_number.h b/third_party/boost/boost/predef/version_number.h
new file mode 100644
index 0000000..3903a36
--- /dev/null
+++ b/third_party/boost/boost/predef/version_number.h
@@ -0,0 +1,53 @@
+/*
+Copyright Rene Rivera 2005, 2008-2013
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_PREDEF_VERSION_NUMBER_H
+#define BOOST_PREDEF_VERSION_NUMBER_H
+
+/*`
+[heading `BOOST_VERSION_NUMBER`]
+
+``
+BOOST_VERSION_NUMBER(major,minor,patch)
+``
+
+Defines standard version numbers, with these properties:
+
+* Decimal base whole numbers in the range \[0,1000000000).
+  The number range is designed to allow for a (2,2,5) triplet.
+  Which fits within a 32 bit value.
+* The `major` number can be in the \[0,99\] range.
+* The `minor` number can be in the \[0,99\] range.
+* The `patch` number can be in the \[0,99999\] range.
+* Values can be specified in any base. As the defined value
+  is an constant expression.
+* Value can be directly used in both preprocessor and compiler
+  expressions for comparison to other similarly defined values.
+* The implementation enforces the individual ranges for the
+  major, minor, and patch numbers. And values over the ranges
+  are truncated (modulo).
+
+*/
+#define BOOST_VERSION_NUMBER(major,minor,patch) \
+    ( (((major)%100)*10000000) + (((minor)%100)*100000) + ((patch)%100000) )
+
+#define BOOST_VERSION_NUMBER_MAX \
+    BOOST_VERSION_NUMBER(99,99,99999)
+
+#define BOOST_VERSION_NUMBER_ZERO \
+    BOOST_VERSION_NUMBER(0,0,0)
+
+#define BOOST_VERSION_NUMBER_MIN \
+    BOOST_VERSION_NUMBER(0,0,1)
+
+#define BOOST_VERSION_NUMBER_AVAILABLE \
+    BOOST_VERSION_NUMBER_MIN
+
+#define BOOST_VERSION_NUMBER_NOT_AVAILABLE \
+    BOOST_VERSION_NUMBER_ZERO
+
+#endif
diff --git a/third_party/boost/boost/preprocessor/arithmetic.hpp b/third_party/boost/boost/preprocessor/arithmetic.hpp
new file mode 100644
index 0000000..b1be781
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/arithmetic.hpp
@@ -0,0 +1,25 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ARITHMETIC_HPP
+# define BOOST_PREPROCESSOR_ARITHMETIC_HPP
+#
+# include <boost/preprocessor/arithmetic/add.hpp>
+# include <boost/preprocessor/arithmetic/dec.hpp>
+# include <boost/preprocessor/arithmetic/div.hpp>
+# include <boost/preprocessor/arithmetic/inc.hpp>
+# include <boost/preprocessor/arithmetic/mod.hpp>
+# include <boost/preprocessor/arithmetic/mul.hpp>
+# include <boost/preprocessor/arithmetic/sub.hpp>
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/arithmetic/add.hpp b/third_party/boost/boost/preprocessor/arithmetic/add.hpp
new file mode 100644
index 0000000..5a29f55
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/arithmetic/add.hpp
@@ -0,0 +1,51 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ARITHMETIC_ADD_HPP
+# define BOOST_PREPROCESSOR_ARITHMETIC_ADD_HPP
+#
+# include <boost/preprocessor/arithmetic/dec.hpp>
+# include <boost/preprocessor/arithmetic/inc.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/control/while.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+#
+# /* BOOST_PP_ADD */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ADD(x, y) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_WHILE(BOOST_PP_ADD_P, BOOST_PP_ADD_O, (x, y)))
+# else
+#    define BOOST_PP_ADD(x, y) BOOST_PP_ADD_I(x, y)
+#    define BOOST_PP_ADD_I(x, y) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_WHILE(BOOST_PP_ADD_P, BOOST_PP_ADD_O, (x, y)))
+# endif
+#
+# define BOOST_PP_ADD_P(d, xy) BOOST_PP_TUPLE_ELEM(2, 1, xy)
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#    define BOOST_PP_ADD_O(d, xy) BOOST_PP_ADD_O_I xy
+# else
+#    define BOOST_PP_ADD_O(d, xy) BOOST_PP_ADD_O_I(BOOST_PP_TUPLE_ELEM(2, 0, xy), BOOST_PP_TUPLE_ELEM(2, 1, xy))
+# endif
+#
+# define BOOST_PP_ADD_O_I(x, y) (BOOST_PP_INC(x), BOOST_PP_DEC(y))
+#
+# /* BOOST_PP_ADD_D */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ADD_D(d, x, y) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_WHILE_ ## d(BOOST_PP_ADD_P, BOOST_PP_ADD_O, (x, y)))
+# else
+#    define BOOST_PP_ADD_D(d, x, y) BOOST_PP_ADD_D_I(d, x, y)
+#    define BOOST_PP_ADD_D_I(d, x, y) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_WHILE_ ## d(BOOST_PP_ADD_P, BOOST_PP_ADD_O, (x, y)))
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/arithmetic/dec.hpp b/third_party/boost/boost/preprocessor/arithmetic/dec.hpp
new file mode 100644
index 0000000..23dd0a3
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/arithmetic/dec.hpp
@@ -0,0 +1,289 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ARITHMETIC_DEC_HPP
+# define BOOST_PREPROCESSOR_ARITHMETIC_DEC_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+#
+# /* BOOST_PP_DEC */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#    define BOOST_PP_DEC(x) BOOST_PP_DEC_I(x)
+# else
+#    define BOOST_PP_DEC(x) BOOST_PP_DEC_OO((x))
+#    define BOOST_PP_DEC_OO(par) BOOST_PP_DEC_I ## par
+# endif
+#
+# define BOOST_PP_DEC_I(x) BOOST_PP_DEC_ ## x
+#
+# define BOOST_PP_DEC_0 0
+# define BOOST_PP_DEC_1 0
+# define BOOST_PP_DEC_2 1
+# define BOOST_PP_DEC_3 2
+# define BOOST_PP_DEC_4 3
+# define BOOST_PP_DEC_5 4
+# define BOOST_PP_DEC_6 5
+# define BOOST_PP_DEC_7 6
+# define BOOST_PP_DEC_8 7
+# define BOOST_PP_DEC_9 8
+# define BOOST_PP_DEC_10 9
+# define BOOST_PP_DEC_11 10
+# define BOOST_PP_DEC_12 11
+# define BOOST_PP_DEC_13 12
+# define BOOST_PP_DEC_14 13
+# define BOOST_PP_DEC_15 14
+# define BOOST_PP_DEC_16 15
+# define BOOST_PP_DEC_17 16
+# define BOOST_PP_DEC_18 17
+# define BOOST_PP_DEC_19 18
+# define BOOST_PP_DEC_20 19
+# define BOOST_PP_DEC_21 20
+# define BOOST_PP_DEC_22 21
+# define BOOST_PP_DEC_23 22
+# define BOOST_PP_DEC_24 23
+# define BOOST_PP_DEC_25 24
+# define BOOST_PP_DEC_26 25
+# define BOOST_PP_DEC_27 26
+# define BOOST_PP_DEC_28 27
+# define BOOST_PP_DEC_29 28
+# define BOOST_PP_DEC_30 29
+# define BOOST_PP_DEC_31 30
+# define BOOST_PP_DEC_32 31
+# define BOOST_PP_DEC_33 32
+# define BOOST_PP_DEC_34 33
+# define BOOST_PP_DEC_35 34
+# define BOOST_PP_DEC_36 35
+# define BOOST_PP_DEC_37 36
+# define BOOST_PP_DEC_38 37
+# define BOOST_PP_DEC_39 38
+# define BOOST_PP_DEC_40 39
+# define BOOST_PP_DEC_41 40
+# define BOOST_PP_DEC_42 41
+# define BOOST_PP_DEC_43 42
+# define BOOST_PP_DEC_44 43
+# define BOOST_PP_DEC_45 44
+# define BOOST_PP_DEC_46 45
+# define BOOST_PP_DEC_47 46
+# define BOOST_PP_DEC_48 47
+# define BOOST_PP_DEC_49 48
+# define BOOST_PP_DEC_50 49
+# define BOOST_PP_DEC_51 50
+# define BOOST_PP_DEC_52 51
+# define BOOST_PP_DEC_53 52
+# define BOOST_PP_DEC_54 53
+# define BOOST_PP_DEC_55 54
+# define BOOST_PP_DEC_56 55
+# define BOOST_PP_DEC_57 56
+# define BOOST_PP_DEC_58 57
+# define BOOST_PP_DEC_59 58
+# define BOOST_PP_DEC_60 59
+# define BOOST_PP_DEC_61 60
+# define BOOST_PP_DEC_62 61
+# define BOOST_PP_DEC_63 62
+# define BOOST_PP_DEC_64 63
+# define BOOST_PP_DEC_65 64
+# define BOOST_PP_DEC_66 65
+# define BOOST_PP_DEC_67 66
+# define BOOST_PP_DEC_68 67
+# define BOOST_PP_DEC_69 68
+# define BOOST_PP_DEC_70 69
+# define BOOST_PP_DEC_71 70
+# define BOOST_PP_DEC_72 71
+# define BOOST_PP_DEC_73 72
+# define BOOST_PP_DEC_74 73
+# define BOOST_PP_DEC_75 74
+# define BOOST_PP_DEC_76 75
+# define BOOST_PP_DEC_77 76
+# define BOOST_PP_DEC_78 77
+# define BOOST_PP_DEC_79 78
+# define BOOST_PP_DEC_80 79
+# define BOOST_PP_DEC_81 80
+# define BOOST_PP_DEC_82 81
+# define BOOST_PP_DEC_83 82
+# define BOOST_PP_DEC_84 83
+# define BOOST_PP_DEC_85 84
+# define BOOST_PP_DEC_86 85
+# define BOOST_PP_DEC_87 86
+# define BOOST_PP_DEC_88 87
+# define BOOST_PP_DEC_89 88
+# define BOOST_PP_DEC_90 89
+# define BOOST_PP_DEC_91 90
+# define BOOST_PP_DEC_92 91
+# define BOOST_PP_DEC_93 92
+# define BOOST_PP_DEC_94 93
+# define BOOST_PP_DEC_95 94
+# define BOOST_PP_DEC_96 95
+# define BOOST_PP_DEC_97 96
+# define BOOST_PP_DEC_98 97
+# define BOOST_PP_DEC_99 98
+# define BOOST_PP_DEC_100 99
+# define BOOST_PP_DEC_101 100
+# define BOOST_PP_DEC_102 101
+# define BOOST_PP_DEC_103 102
+# define BOOST_PP_DEC_104 103
+# define BOOST_PP_DEC_105 104
+# define BOOST_PP_DEC_106 105
+# define BOOST_PP_DEC_107 106
+# define BOOST_PP_DEC_108 107
+# define BOOST_PP_DEC_109 108
+# define BOOST_PP_DEC_110 109
+# define BOOST_PP_DEC_111 110
+# define BOOST_PP_DEC_112 111
+# define BOOST_PP_DEC_113 112
+# define BOOST_PP_DEC_114 113
+# define BOOST_PP_DEC_115 114
+# define BOOST_PP_DEC_116 115
+# define BOOST_PP_DEC_117 116
+# define BOOST_PP_DEC_118 117
+# define BOOST_PP_DEC_119 118
+# define BOOST_PP_DEC_120 119
+# define BOOST_PP_DEC_121 120
+# define BOOST_PP_DEC_122 121
+# define BOOST_PP_DEC_123 122
+# define BOOST_PP_DEC_124 123
+# define BOOST_PP_DEC_125 124
+# define BOOST_PP_DEC_126 125
+# define BOOST_PP_DEC_127 126
+# define BOOST_PP_DEC_128 127
+# define BOOST_PP_DEC_129 128
+# define BOOST_PP_DEC_130 129
+# define BOOST_PP_DEC_131 130
+# define BOOST_PP_DEC_132 131
+# define BOOST_PP_DEC_133 132
+# define BOOST_PP_DEC_134 133
+# define BOOST_PP_DEC_135 134
+# define BOOST_PP_DEC_136 135
+# define BOOST_PP_DEC_137 136
+# define BOOST_PP_DEC_138 137
+# define BOOST_PP_DEC_139 138
+# define BOOST_PP_DEC_140 139
+# define BOOST_PP_DEC_141 140
+# define BOOST_PP_DEC_142 141
+# define BOOST_PP_DEC_143 142
+# define BOOST_PP_DEC_144 143
+# define BOOST_PP_DEC_145 144
+# define BOOST_PP_DEC_146 145
+# define BOOST_PP_DEC_147 146
+# define BOOST_PP_DEC_148 147
+# define BOOST_PP_DEC_149 148
+# define BOOST_PP_DEC_150 149
+# define BOOST_PP_DEC_151 150
+# define BOOST_PP_DEC_152 151
+# define BOOST_PP_DEC_153 152
+# define BOOST_PP_DEC_154 153
+# define BOOST_PP_DEC_155 154
+# define BOOST_PP_DEC_156 155
+# define BOOST_PP_DEC_157 156
+# define BOOST_PP_DEC_158 157
+# define BOOST_PP_DEC_159 158
+# define BOOST_PP_DEC_160 159
+# define BOOST_PP_DEC_161 160
+# define BOOST_PP_DEC_162 161
+# define BOOST_PP_DEC_163 162
+# define BOOST_PP_DEC_164 163
+# define BOOST_PP_DEC_165 164
+# define BOOST_PP_DEC_166 165
+# define BOOST_PP_DEC_167 166
+# define BOOST_PP_DEC_168 167
+# define BOOST_PP_DEC_169 168
+# define BOOST_PP_DEC_170 169
+# define BOOST_PP_DEC_171 170
+# define BOOST_PP_DEC_172 171
+# define BOOST_PP_DEC_173 172
+# define BOOST_PP_DEC_174 173
+# define BOOST_PP_DEC_175 174
+# define BOOST_PP_DEC_176 175
+# define BOOST_PP_DEC_177 176
+# define BOOST_PP_DEC_178 177
+# define BOOST_PP_DEC_179 178
+# define BOOST_PP_DEC_180 179
+# define BOOST_PP_DEC_181 180
+# define BOOST_PP_DEC_182 181
+# define BOOST_PP_DEC_183 182
+# define BOOST_PP_DEC_184 183
+# define BOOST_PP_DEC_185 184
+# define BOOST_PP_DEC_186 185
+# define BOOST_PP_DEC_187 186
+# define BOOST_PP_DEC_188 187
+# define BOOST_PP_DEC_189 188
+# define BOOST_PP_DEC_190 189
+# define BOOST_PP_DEC_191 190
+# define BOOST_PP_DEC_192 191
+# define BOOST_PP_DEC_193 192
+# define BOOST_PP_DEC_194 193
+# define BOOST_PP_DEC_195 194
+# define BOOST_PP_DEC_196 195
+# define BOOST_PP_DEC_197 196
+# define BOOST_PP_DEC_198 197
+# define BOOST_PP_DEC_199 198
+# define BOOST_PP_DEC_200 199
+# define BOOST_PP_DEC_201 200
+# define BOOST_PP_DEC_202 201
+# define BOOST_PP_DEC_203 202
+# define BOOST_PP_DEC_204 203
+# define BOOST_PP_DEC_205 204
+# define BOOST_PP_DEC_206 205
+# define BOOST_PP_DEC_207 206
+# define BOOST_PP_DEC_208 207
+# define BOOST_PP_DEC_209 208
+# define BOOST_PP_DEC_210 209
+# define BOOST_PP_DEC_211 210
+# define BOOST_PP_DEC_212 211
+# define BOOST_PP_DEC_213 212
+# define BOOST_PP_DEC_214 213
+# define BOOST_PP_DEC_215 214
+# define BOOST_PP_DEC_216 215
+# define BOOST_PP_DEC_217 216
+# define BOOST_PP_DEC_218 217
+# define BOOST_PP_DEC_219 218
+# define BOOST_PP_DEC_220 219
+# define BOOST_PP_DEC_221 220
+# define BOOST_PP_DEC_222 221
+# define BOOST_PP_DEC_223 222
+# define BOOST_PP_DEC_224 223
+# define BOOST_PP_DEC_225 224
+# define BOOST_PP_DEC_226 225
+# define BOOST_PP_DEC_227 226
+# define BOOST_PP_DEC_228 227
+# define BOOST_PP_DEC_229 228
+# define BOOST_PP_DEC_230 229
+# define BOOST_PP_DEC_231 230
+# define BOOST_PP_DEC_232 231
+# define BOOST_PP_DEC_233 232
+# define BOOST_PP_DEC_234 233
+# define BOOST_PP_DEC_235 234
+# define BOOST_PP_DEC_236 235
+# define BOOST_PP_DEC_237 236
+# define BOOST_PP_DEC_238 237
+# define BOOST_PP_DEC_239 238
+# define BOOST_PP_DEC_240 239
+# define BOOST_PP_DEC_241 240
+# define BOOST_PP_DEC_242 241
+# define BOOST_PP_DEC_243 242
+# define BOOST_PP_DEC_244 243
+# define BOOST_PP_DEC_245 244
+# define BOOST_PP_DEC_246 245
+# define BOOST_PP_DEC_247 246
+# define BOOST_PP_DEC_248 247
+# define BOOST_PP_DEC_249 248
+# define BOOST_PP_DEC_250 249
+# define BOOST_PP_DEC_251 250
+# define BOOST_PP_DEC_252 251
+# define BOOST_PP_DEC_253 252
+# define BOOST_PP_DEC_254 253
+# define BOOST_PP_DEC_255 254
+# define BOOST_PP_DEC_256 255
+# define BOOST_PP_DEC_257 256
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/arithmetic/detail/div_base.hpp b/third_party/boost/boost/preprocessor/arithmetic/detail/div_base.hpp
new file mode 100644
index 0000000..106632a
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/arithmetic/detail/div_base.hpp
@@ -0,0 +1,61 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ARITHMETIC_DETAIL_DIV_BASE_HPP
+# define BOOST_PREPROCESSOR_ARITHMETIC_DETAIL_DIV_BASE_HPP
+#
+# include <boost/preprocessor/arithmetic/inc.hpp>
+# include <boost/preprocessor/arithmetic/sub.hpp>
+# include <boost/preprocessor/comparison/less_equal.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/control/while.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+# include <boost/preprocessor/tuple/rem.hpp>
+#
+# /* BOOST_PP_DIV_BASE */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_DIV_BASE(x, y) BOOST_PP_WHILE(BOOST_PP_DIV_BASE_P, BOOST_PP_DIV_BASE_O, (0, x, y))
+# else
+#    define BOOST_PP_DIV_BASE(x, y) BOOST_PP_DIV_BASE_I(x, y)
+#    define BOOST_PP_DIV_BASE_I(x, y) BOOST_PP_WHILE(BOOST_PP_DIV_BASE_P, BOOST_PP_DIV_BASE_O, (0, x, y))
+# endif
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
+#    define BOOST_PP_DIV_BASE_P(d, rxy) BOOST_PP_DIV_BASE_P_IM(d, BOOST_PP_TUPLE_REM_3 rxy)
+#    define BOOST_PP_DIV_BASE_P_IM(d, im) BOOST_PP_DIV_BASE_P_I(d, im)
+# else
+#    define BOOST_PP_DIV_BASE_P(d, rxy) BOOST_PP_DIV_BASE_P_I(d, BOOST_PP_TUPLE_ELEM(3, 0, rxy), BOOST_PP_TUPLE_ELEM(3, 1, rxy), BOOST_PP_TUPLE_ELEM(3, 2, rxy))
+# endif
+#
+# define BOOST_PP_DIV_BASE_P_I(d, r, x, y) BOOST_PP_LESS_EQUAL_D(d, y, x)
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
+#    define BOOST_PP_DIV_BASE_O(d, rxy) BOOST_PP_DIV_BASE_O_IM(d, BOOST_PP_TUPLE_REM_3 rxy)
+#    define BOOST_PP_DIV_BASE_O_IM(d, im) BOOST_PP_DIV_BASE_O_I(d, im)
+# else
+#    define BOOST_PP_DIV_BASE_O(d, rxy) BOOST_PP_DIV_BASE_O_I(d, BOOST_PP_TUPLE_ELEM(3, 0, rxy), BOOST_PP_TUPLE_ELEM(3, 1, rxy), BOOST_PP_TUPLE_ELEM(3, 2, rxy))
+# endif
+#
+# define BOOST_PP_DIV_BASE_O_I(d, r, x, y) (BOOST_PP_INC(r), BOOST_PP_SUB_D(d, x, y), y)
+#
+# /* BOOST_PP_DIV_BASE_D */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_DIV_BASE_D(d, x, y) BOOST_PP_WHILE_ ## d(BOOST_PP_DIV_BASE_P, BOOST_PP_DIV_BASE_O, (0, x, y))
+# else
+#    define BOOST_PP_DIV_BASE_D(d, x, y) BOOST_PP_DIV_BASE_D_I(d, x, y)
+#    define BOOST_PP_DIV_BASE_D_I(d, x, y) BOOST_PP_WHILE_ ## d(BOOST_PP_DIV_BASE_P, BOOST_PP_DIV_BASE_O, (0, x, y))
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/arithmetic/div.hpp b/third_party/boost/boost/preprocessor/arithmetic/div.hpp
new file mode 100644
index 0000000..277596c
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/arithmetic/div.hpp
@@ -0,0 +1,39 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ARITHMETIC_DIV_HPP
+# define BOOST_PREPROCESSOR_ARITHMETIC_DIV_HPP
+#
+# include <boost/preprocessor/arithmetic/detail/div_base.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+#
+# /* BOOST_PP_DIV */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_DIV(x, y) BOOST_PP_TUPLE_ELEM(3, 0, BOOST_PP_DIV_BASE(x, y))
+# else
+#    define BOOST_PP_DIV(x, y) BOOST_PP_DIV_I(x, y)
+#    define BOOST_PP_DIV_I(x, y) BOOST_PP_TUPLE_ELEM(3, 0, BOOST_PP_DIV_BASE(x, y))
+# endif
+#
+# /* BOOST_PP_DIV_D */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_DIV_D(d, x, y) BOOST_PP_TUPLE_ELEM(3, 0, BOOST_PP_DIV_BASE_D(d, x, y))
+# else
+#    define BOOST_PP_DIV_D(d, x, y) BOOST_PP_DIV_D_I(d, x, y)
+#    define BOOST_PP_DIV_D_I(d, x, y) BOOST_PP_TUPLE_ELEM(3, 0, BOOST_PP_DIV_BASE_D(d, x, y))
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/arithmetic/inc.hpp b/third_party/boost/boost/preprocessor/arithmetic/inc.hpp
new file mode 100644
index 0000000..1597ab8
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/arithmetic/inc.hpp
@@ -0,0 +1,288 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ARITHMETIC_INC_HPP
+# define BOOST_PREPROCESSOR_ARITHMETIC_INC_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+#
+# /* BOOST_PP_INC */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#    define BOOST_PP_INC(x) BOOST_PP_INC_I(x)
+# else
+#    define BOOST_PP_INC(x) BOOST_PP_INC_OO((x))
+#    define BOOST_PP_INC_OO(par) BOOST_PP_INC_I ## par
+# endif
+#
+# define BOOST_PP_INC_I(x) BOOST_PP_INC_ ## x
+#
+# define BOOST_PP_INC_0 1
+# define BOOST_PP_INC_1 2
+# define BOOST_PP_INC_2 3
+# define BOOST_PP_INC_3 4
+# define BOOST_PP_INC_4 5
+# define BOOST_PP_INC_5 6
+# define BOOST_PP_INC_6 7
+# define BOOST_PP_INC_7 8
+# define BOOST_PP_INC_8 9
+# define BOOST_PP_INC_9 10
+# define BOOST_PP_INC_10 11
+# define BOOST_PP_INC_11 12
+# define BOOST_PP_INC_12 13
+# define BOOST_PP_INC_13 14
+# define BOOST_PP_INC_14 15
+# define BOOST_PP_INC_15 16
+# define BOOST_PP_INC_16 17
+# define BOOST_PP_INC_17 18
+# define BOOST_PP_INC_18 19
+# define BOOST_PP_INC_19 20
+# define BOOST_PP_INC_20 21
+# define BOOST_PP_INC_21 22
+# define BOOST_PP_INC_22 23
+# define BOOST_PP_INC_23 24
+# define BOOST_PP_INC_24 25
+# define BOOST_PP_INC_25 26
+# define BOOST_PP_INC_26 27
+# define BOOST_PP_INC_27 28
+# define BOOST_PP_INC_28 29
+# define BOOST_PP_INC_29 30
+# define BOOST_PP_INC_30 31
+# define BOOST_PP_INC_31 32
+# define BOOST_PP_INC_32 33
+# define BOOST_PP_INC_33 34
+# define BOOST_PP_INC_34 35
+# define BOOST_PP_INC_35 36
+# define BOOST_PP_INC_36 37
+# define BOOST_PP_INC_37 38
+# define BOOST_PP_INC_38 39
+# define BOOST_PP_INC_39 40
+# define BOOST_PP_INC_40 41
+# define BOOST_PP_INC_41 42
+# define BOOST_PP_INC_42 43
+# define BOOST_PP_INC_43 44
+# define BOOST_PP_INC_44 45
+# define BOOST_PP_INC_45 46
+# define BOOST_PP_INC_46 47
+# define BOOST_PP_INC_47 48
+# define BOOST_PP_INC_48 49
+# define BOOST_PP_INC_49 50
+# define BOOST_PP_INC_50 51
+# define BOOST_PP_INC_51 52
+# define BOOST_PP_INC_52 53
+# define BOOST_PP_INC_53 54
+# define BOOST_PP_INC_54 55
+# define BOOST_PP_INC_55 56
+# define BOOST_PP_INC_56 57
+# define BOOST_PP_INC_57 58
+# define BOOST_PP_INC_58 59
+# define BOOST_PP_INC_59 60
+# define BOOST_PP_INC_60 61
+# define BOOST_PP_INC_61 62
+# define BOOST_PP_INC_62 63
+# define BOOST_PP_INC_63 64
+# define BOOST_PP_INC_64 65
+# define BOOST_PP_INC_65 66
+# define BOOST_PP_INC_66 67
+# define BOOST_PP_INC_67 68
+# define BOOST_PP_INC_68 69
+# define BOOST_PP_INC_69 70
+# define BOOST_PP_INC_70 71
+# define BOOST_PP_INC_71 72
+# define BOOST_PP_INC_72 73
+# define BOOST_PP_INC_73 74
+# define BOOST_PP_INC_74 75
+# define BOOST_PP_INC_75 76
+# define BOOST_PP_INC_76 77
+# define BOOST_PP_INC_77 78
+# define BOOST_PP_INC_78 79
+# define BOOST_PP_INC_79 80
+# define BOOST_PP_INC_80 81
+# define BOOST_PP_INC_81 82
+# define BOOST_PP_INC_82 83
+# define BOOST_PP_INC_83 84
+# define BOOST_PP_INC_84 85
+# define BOOST_PP_INC_85 86
+# define BOOST_PP_INC_86 87
+# define BOOST_PP_INC_87 88
+# define BOOST_PP_INC_88 89
+# define BOOST_PP_INC_89 90
+# define BOOST_PP_INC_90 91
+# define BOOST_PP_INC_91 92
+# define BOOST_PP_INC_92 93
+# define BOOST_PP_INC_93 94
+# define BOOST_PP_INC_94 95
+# define BOOST_PP_INC_95 96
+# define BOOST_PP_INC_96 97
+# define BOOST_PP_INC_97 98
+# define BOOST_PP_INC_98 99
+# define BOOST_PP_INC_99 100
+# define BOOST_PP_INC_100 101
+# define BOOST_PP_INC_101 102
+# define BOOST_PP_INC_102 103
+# define BOOST_PP_INC_103 104
+# define BOOST_PP_INC_104 105
+# define BOOST_PP_INC_105 106
+# define BOOST_PP_INC_106 107
+# define BOOST_PP_INC_107 108
+# define BOOST_PP_INC_108 109
+# define BOOST_PP_INC_109 110
+# define BOOST_PP_INC_110 111
+# define BOOST_PP_INC_111 112
+# define BOOST_PP_INC_112 113
+# define BOOST_PP_INC_113 114
+# define BOOST_PP_INC_114 115
+# define BOOST_PP_INC_115 116
+# define BOOST_PP_INC_116 117
+# define BOOST_PP_INC_117 118
+# define BOOST_PP_INC_118 119
+# define BOOST_PP_INC_119 120
+# define BOOST_PP_INC_120 121
+# define BOOST_PP_INC_121 122
+# define BOOST_PP_INC_122 123
+# define BOOST_PP_INC_123 124
+# define BOOST_PP_INC_124 125
+# define BOOST_PP_INC_125 126
+# define BOOST_PP_INC_126 127
+# define BOOST_PP_INC_127 128
+# define BOOST_PP_INC_128 129
+# define BOOST_PP_INC_129 130
+# define BOOST_PP_INC_130 131
+# define BOOST_PP_INC_131 132
+# define BOOST_PP_INC_132 133
+# define BOOST_PP_INC_133 134
+# define BOOST_PP_INC_134 135
+# define BOOST_PP_INC_135 136
+# define BOOST_PP_INC_136 137
+# define BOOST_PP_INC_137 138
+# define BOOST_PP_INC_138 139
+# define BOOST_PP_INC_139 140
+# define BOOST_PP_INC_140 141
+# define BOOST_PP_INC_141 142
+# define BOOST_PP_INC_142 143
+# define BOOST_PP_INC_143 144
+# define BOOST_PP_INC_144 145
+# define BOOST_PP_INC_145 146
+# define BOOST_PP_INC_146 147
+# define BOOST_PP_INC_147 148
+# define BOOST_PP_INC_148 149
+# define BOOST_PP_INC_149 150
+# define BOOST_PP_INC_150 151
+# define BOOST_PP_INC_151 152
+# define BOOST_PP_INC_152 153
+# define BOOST_PP_INC_153 154
+# define BOOST_PP_INC_154 155
+# define BOOST_PP_INC_155 156
+# define BOOST_PP_INC_156 157
+# define BOOST_PP_INC_157 158
+# define BOOST_PP_INC_158 159
+# define BOOST_PP_INC_159 160
+# define BOOST_PP_INC_160 161
+# define BOOST_PP_INC_161 162
+# define BOOST_PP_INC_162 163
+# define BOOST_PP_INC_163 164
+# define BOOST_PP_INC_164 165
+# define BOOST_PP_INC_165 166
+# define BOOST_PP_INC_166 167
+# define BOOST_PP_INC_167 168
+# define BOOST_PP_INC_168 169
+# define BOOST_PP_INC_169 170
+# define BOOST_PP_INC_170 171
+# define BOOST_PP_INC_171 172
+# define BOOST_PP_INC_172 173
+# define BOOST_PP_INC_173 174
+# define BOOST_PP_INC_174 175
+# define BOOST_PP_INC_175 176
+# define BOOST_PP_INC_176 177
+# define BOOST_PP_INC_177 178
+# define BOOST_PP_INC_178 179
+# define BOOST_PP_INC_179 180
+# define BOOST_PP_INC_180 181
+# define BOOST_PP_INC_181 182
+# define BOOST_PP_INC_182 183
+# define BOOST_PP_INC_183 184
+# define BOOST_PP_INC_184 185
+# define BOOST_PP_INC_185 186
+# define BOOST_PP_INC_186 187
+# define BOOST_PP_INC_187 188
+# define BOOST_PP_INC_188 189
+# define BOOST_PP_INC_189 190
+# define BOOST_PP_INC_190 191
+# define BOOST_PP_INC_191 192
+# define BOOST_PP_INC_192 193
+# define BOOST_PP_INC_193 194
+# define BOOST_PP_INC_194 195
+# define BOOST_PP_INC_195 196
+# define BOOST_PP_INC_196 197
+# define BOOST_PP_INC_197 198
+# define BOOST_PP_INC_198 199
+# define BOOST_PP_INC_199 200
+# define BOOST_PP_INC_200 201
+# define BOOST_PP_INC_201 202
+# define BOOST_PP_INC_202 203
+# define BOOST_PP_INC_203 204
+# define BOOST_PP_INC_204 205
+# define BOOST_PP_INC_205 206
+# define BOOST_PP_INC_206 207
+# define BOOST_PP_INC_207 208
+# define BOOST_PP_INC_208 209
+# define BOOST_PP_INC_209 210
+# define BOOST_PP_INC_210 211
+# define BOOST_PP_INC_211 212
+# define BOOST_PP_INC_212 213
+# define BOOST_PP_INC_213 214
+# define BOOST_PP_INC_214 215
+# define BOOST_PP_INC_215 216
+# define BOOST_PP_INC_216 217
+# define BOOST_PP_INC_217 218
+# define BOOST_PP_INC_218 219
+# define BOOST_PP_INC_219 220
+# define BOOST_PP_INC_220 221
+# define BOOST_PP_INC_221 222
+# define BOOST_PP_INC_222 223
+# define BOOST_PP_INC_223 224
+# define BOOST_PP_INC_224 225
+# define BOOST_PP_INC_225 226
+# define BOOST_PP_INC_226 227
+# define BOOST_PP_INC_227 228
+# define BOOST_PP_INC_228 229
+# define BOOST_PP_INC_229 230
+# define BOOST_PP_INC_230 231
+# define BOOST_PP_INC_231 232
+# define BOOST_PP_INC_232 233
+# define BOOST_PP_INC_233 234
+# define BOOST_PP_INC_234 235
+# define BOOST_PP_INC_235 236
+# define BOOST_PP_INC_236 237
+# define BOOST_PP_INC_237 238
+# define BOOST_PP_INC_238 239
+# define BOOST_PP_INC_239 240
+# define BOOST_PP_INC_240 241
+# define BOOST_PP_INC_241 242
+# define BOOST_PP_INC_242 243
+# define BOOST_PP_INC_243 244
+# define BOOST_PP_INC_244 245
+# define BOOST_PP_INC_245 246
+# define BOOST_PP_INC_246 247
+# define BOOST_PP_INC_247 248
+# define BOOST_PP_INC_248 249
+# define BOOST_PP_INC_249 250
+# define BOOST_PP_INC_250 251
+# define BOOST_PP_INC_251 252
+# define BOOST_PP_INC_252 253
+# define BOOST_PP_INC_253 254
+# define BOOST_PP_INC_254 255
+# define BOOST_PP_INC_255 256
+# define BOOST_PP_INC_256 256
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/arithmetic/mod.hpp b/third_party/boost/boost/preprocessor/arithmetic/mod.hpp
new file mode 100644
index 0000000..62489d1
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/arithmetic/mod.hpp
@@ -0,0 +1,39 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ARITHMETIC_MOD_HPP
+# define BOOST_PREPROCESSOR_ARITHMETIC_MOD_HPP
+#
+# include <boost/preprocessor/arithmetic/detail/div_base.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+#
+# /* BOOST_PP_MOD */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_MOD(x, y) BOOST_PP_TUPLE_ELEM(3, 1, BOOST_PP_DIV_BASE(x, y))
+# else
+#    define BOOST_PP_MOD(x, y) BOOST_PP_MOD_I(x, y)
+#    define BOOST_PP_MOD_I(x, y) BOOST_PP_TUPLE_ELEM(3, 1, BOOST_PP_DIV_BASE(x, y))
+# endif
+#
+# /* BOOST_PP_MOD_D */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_MOD_D(d, x, y) BOOST_PP_TUPLE_ELEM(3, 1, BOOST_PP_DIV_BASE_D(d, x, y))
+# else
+#    define BOOST_PP_MOD_D(d, x, y) BOOST_PP_MOD_D_I(d, x, y)
+#    define BOOST_PP_MOD_D_I(d, x, y) BOOST_PP_TUPLE_ELEM(3, 1, BOOST_PP_DIV_BASE_D(d, x, y))
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/arithmetic/mul.hpp b/third_party/boost/boost/preprocessor/arithmetic/mul.hpp
new file mode 100644
index 0000000..f3d9ffc
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/arithmetic/mul.hpp
@@ -0,0 +1,53 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ARITHMETIC_MUL_HPP
+# define BOOST_PREPROCESSOR_ARITHMETIC_MUL_HPP
+#
+# include <boost/preprocessor/arithmetic/add.hpp>
+# include <boost/preprocessor/arithmetic/dec.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/control/while.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+# include <boost/preprocessor/tuple/rem.hpp>
+#
+# /* BOOST_PP_MUL */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_MUL(x, y) BOOST_PP_TUPLE_ELEM(3, 0, BOOST_PP_WHILE(BOOST_PP_MUL_P, BOOST_PP_MUL_O, (0, x, y)))
+# else
+#    define BOOST_PP_MUL(x, y) BOOST_PP_MUL_I(x, y)
+#    define BOOST_PP_MUL_I(x, y) BOOST_PP_TUPLE_ELEM(3, 0, BOOST_PP_WHILE(BOOST_PP_MUL_P, BOOST_PP_MUL_O, (0, x, y)))
+# endif
+#
+# define BOOST_PP_MUL_P(d, rxy) BOOST_PP_TUPLE_ELEM(3, 2, rxy)
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
+#    define BOOST_PP_MUL_O(d, rxy) BOOST_PP_MUL_O_IM(d, BOOST_PP_TUPLE_REM_3 rxy)
+#    define BOOST_PP_MUL_O_IM(d, im) BOOST_PP_MUL_O_I(d, im)
+# else
+#    define BOOST_PP_MUL_O(d, rxy) BOOST_PP_MUL_O_I(d, BOOST_PP_TUPLE_ELEM(3, 0, rxy), BOOST_PP_TUPLE_ELEM(3, 1, rxy), BOOST_PP_TUPLE_ELEM(3, 2, rxy))
+# endif
+#
+# define BOOST_PP_MUL_O_I(d, r, x, y) (BOOST_PP_ADD_D(d, r, x), x, BOOST_PP_DEC(y))
+#
+# /* BOOST_PP_MUL_D */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_MUL_D(d, x, y) BOOST_PP_TUPLE_ELEM(3, 0, BOOST_PP_WHILE_ ## d(BOOST_PP_MUL_P, BOOST_PP_MUL_O, (0, x, y)))
+# else
+#    define BOOST_PP_MUL_D(d, x, y) BOOST_PP_MUL_D_I(d, x, y)
+#    define BOOST_PP_MUL_D_I(d, x, y) BOOST_PP_TUPLE_ELEM(3, 0, BOOST_PP_WHILE_ ## d(BOOST_PP_MUL_P, BOOST_PP_MUL_O, (0, x, y)))
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/arithmetic/sub.hpp b/third_party/boost/boost/preprocessor/arithmetic/sub.hpp
new file mode 100644
index 0000000..5262cda
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/arithmetic/sub.hpp
@@ -0,0 +1,50 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ARITHMETIC_SUB_HPP
+# define BOOST_PREPROCESSOR_ARITHMETIC_SUB_HPP
+#
+# include <boost/preprocessor/arithmetic/dec.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/control/while.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+#
+# /* BOOST_PP_SUB */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_SUB(x, y) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_WHILE(BOOST_PP_SUB_P, BOOST_PP_SUB_O, (x, y)))
+# else
+#    define BOOST_PP_SUB(x, y) BOOST_PP_SUB_I(x, y)
+#    define BOOST_PP_SUB_I(x, y) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_WHILE(BOOST_PP_SUB_P, BOOST_PP_SUB_O, (x, y)))
+# endif
+#
+# define BOOST_PP_SUB_P(d, xy) BOOST_PP_TUPLE_ELEM(2, 1, xy)
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#    define BOOST_PP_SUB_O(d, xy) BOOST_PP_SUB_O_I xy
+# else
+#    define BOOST_PP_SUB_O(d, xy) BOOST_PP_SUB_O_I(BOOST_PP_TUPLE_ELEM(2, 0, xy), BOOST_PP_TUPLE_ELEM(2, 1, xy))
+# endif
+#
+# define BOOST_PP_SUB_O_I(x, y) (BOOST_PP_DEC(x), BOOST_PP_DEC(y))
+#
+# /* BOOST_PP_SUB_D */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_SUB_D(d, x, y) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_WHILE_ ## d(BOOST_PP_SUB_P, BOOST_PP_SUB_O, (x, y)))
+# else
+#    define BOOST_PP_SUB_D(d, x, y) BOOST_PP_SUB_D_I(d, x, y)
+#    define BOOST_PP_SUB_D_I(d, x, y) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_WHILE_ ## d(BOOST_PP_SUB_P, BOOST_PP_SUB_O, (x, y)))
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/array/data.hpp b/third_party/boost/boost/preprocessor/array/data.hpp
new file mode 100644
index 0000000..10c926a
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/array/data.hpp
@@ -0,0 +1,28 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ARRAY_DATA_HPP
+# define BOOST_PREPROCESSOR_ARRAY_DATA_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+#
+# /* BOOST_PP_ARRAY_DATA */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ARRAY_DATA(array) BOOST_PP_TUPLE_ELEM(2, 1, array)
+# else
+#    define BOOST_PP_ARRAY_DATA(array) BOOST_PP_ARRAY_DATA_I(array)
+#    define BOOST_PP_ARRAY_DATA_I(array) BOOST_PP_ARRAY_DATA_II array
+#    define BOOST_PP_ARRAY_DATA_II(size, data) data
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/array/elem.hpp b/third_party/boost/boost/preprocessor/array/elem.hpp
new file mode 100644
index 0000000..105ba24
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/array/elem.hpp
@@ -0,0 +1,29 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ARRAY_ELEM_HPP
+# define BOOST_PREPROCESSOR_ARRAY_ELEM_HPP
+#
+# include <boost/preprocessor/array/data.hpp>
+# include <boost/preprocessor/array/size.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+#
+# /* BOOST_PP_ARRAY_ELEM */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ARRAY_ELEM(i, array) BOOST_PP_TUPLE_ELEM(BOOST_PP_ARRAY_SIZE(array), i, BOOST_PP_ARRAY_DATA(array))
+# else
+#    define BOOST_PP_ARRAY_ELEM(i, array) BOOST_PP_ARRAY_ELEM_I(i, array)
+#    define BOOST_PP_ARRAY_ELEM_I(i, array) BOOST_PP_TUPLE_ELEM(BOOST_PP_ARRAY_SIZE(array), i, BOOST_PP_ARRAY_DATA(array))
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/array/size.hpp b/third_party/boost/boost/preprocessor/array/size.hpp
new file mode 100644
index 0000000..3f370ee
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/array/size.hpp
@@ -0,0 +1,28 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ARRAY_SIZE_HPP
+# define BOOST_PREPROCESSOR_ARRAY_SIZE_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+#
+# /* BOOST_PP_ARRAY_SIZE */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ARRAY_SIZE(array) BOOST_PP_TUPLE_ELEM(2, 0, array)
+# else
+#    define BOOST_PP_ARRAY_SIZE(array) BOOST_PP_ARRAY_SIZE_I(array)
+#    define BOOST_PP_ARRAY_SIZE_I(array) BOOST_PP_ARRAY_SIZE_II array
+#    define BOOST_PP_ARRAY_SIZE_II(size, data) size
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/cat.hpp b/third_party/boost/boost/preprocessor/cat.hpp
new file mode 100644
index 0000000..5e52850
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/cat.hpp
@@ -0,0 +1,35 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_CAT_HPP
+# define BOOST_PREPROCESSOR_CAT_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+#
+# /* BOOST_PP_CAT */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#    define BOOST_PP_CAT(a, b) BOOST_PP_CAT_I(a, b)
+# else
+#    define BOOST_PP_CAT(a, b) BOOST_PP_CAT_OO((a, b))
+#    define BOOST_PP_CAT_OO(par) BOOST_PP_CAT_I ## par
+# endif
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC()
+#    define BOOST_PP_CAT_I(a, b) a ## b
+# else
+#    define BOOST_PP_CAT_I(a, b) BOOST_PP_CAT_II(~, a ## b)
+#    define BOOST_PP_CAT_II(p, res) res
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/comma_if.hpp b/third_party/boost/boost/preprocessor/comma_if.hpp
new file mode 100644
index 0000000..9ceb079
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/comma_if.hpp
@@ -0,0 +1,17 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_COMMA_IF_HPP
+# define BOOST_PREPROCESSOR_COMMA_IF_HPP
+#
+# include <boost/preprocessor/punctuation/comma_if.hpp>
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/comparison/less_equal.hpp b/third_party/boost/boost/preprocessor/comparison/less_equal.hpp
new file mode 100644
index 0000000..1302d54
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/comparison/less_equal.hpp
@@ -0,0 +1,39 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_COMPARISON_LESS_EQUAL_HPP
+# define BOOST_PREPROCESSOR_COMPARISON_LESS_EQUAL_HPP
+#
+# include <boost/preprocessor/arithmetic/sub.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/logical/not.hpp>
+#
+# /* BOOST_PP_LESS_EQUAL */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_LESS_EQUAL(x, y) BOOST_PP_NOT(BOOST_PP_SUB(x, y))
+# else
+#    define BOOST_PP_LESS_EQUAL(x, y) BOOST_PP_LESS_EQUAL_I(x, y)
+#    define BOOST_PP_LESS_EQUAL_I(x, y) BOOST_PP_NOT(BOOST_PP_SUB(x, y))
+# endif
+#
+# /* BOOST_PP_LESS_EQUAL_D */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_LESS_EQUAL_D(d, x, y) BOOST_PP_NOT(BOOST_PP_SUB_D(d, x, y))
+# else
+#    define BOOST_PP_LESS_EQUAL_D(d, x, y) BOOST_PP_LESS_EQUAL_D_I(d, x, y)
+#    define BOOST_PP_LESS_EQUAL_D_I(d, x, y) BOOST_PP_NOT(BOOST_PP_SUB_D(d, x, y))
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/config/config.hpp b/third_party/boost/boost/preprocessor/config/config.hpp
new file mode 100644
index 0000000..835b283
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/config/config.hpp
@@ -0,0 +1,104 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002-2011.                             *
+#  *     (C) Copyright Edward Diener 2011.                                    *
+#  *     Distributed under the Boost Software License, Version 1.0. (See      *
+#  *     accompanying file LICENSE_1_0.txt or copy at                         *
+#  *     http://www.boost.org/LICENSE_1_0.txt)                                *
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_CONFIG_CONFIG_HPP
+# define BOOST_PREPROCESSOR_CONFIG_CONFIG_HPP
+#
+# /* BOOST_PP_CONFIG_FLAGS */
+#
+# define BOOST_PP_CONFIG_STRICT() 0x0001
+# define BOOST_PP_CONFIG_IDEAL() 0x0002
+#
+# define BOOST_PP_CONFIG_MSVC() 0x0004
+# define BOOST_PP_CONFIG_MWCC() 0x0008
+# define BOOST_PP_CONFIG_BCC() 0x0010
+# define BOOST_PP_CONFIG_EDG() 0x0020
+# define BOOST_PP_CONFIG_DMC() 0x0040
+#
+# ifndef BOOST_PP_CONFIG_FLAGS
+#    if defined(__GCCXML__)
+#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT())
+#    elif defined(__WAVE__)
+#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT())
+#    elif defined(__MWERKS__) && __MWERKS__ >= 0x3200
+#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT())
+#    elif defined(__EDG__) || defined(__EDG_VERSION__)
+#        if defined(_MSC_VER) && (defined(__INTELLISENSE__) || __EDG_VERSION__ >= 308)
+#            define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_MSVC())
+#        else
+#            define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_EDG() | BOOST_PP_CONFIG_STRICT())
+#        endif
+#    elif defined(__MWERKS__)
+#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_MWCC())
+#    elif defined(__DMC__)
+#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_DMC())
+#    elif defined(__BORLANDC__) && __BORLANDC__ >= 0x581
+#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT())
+#    elif defined(__BORLANDC__) || defined(__IBMC__) || defined(__IBMCPP__) || defined(__SUNPRO_CC)
+#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_BCC())
+#    elif defined(_MSC_VER) && !defined(__clang__)
+#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_MSVC())
+#    else
+#        define BOOST_PP_CONFIG_FLAGS() (BOOST_PP_CONFIG_STRICT())
+#    endif
+# endif
+#
+# /* BOOST_PP_CONFIG_EXTENDED_LINE_INFO */
+#
+# ifndef BOOST_PP_CONFIG_EXTENDED_LINE_INFO
+#    define BOOST_PP_CONFIG_EXTENDED_LINE_INFO 0
+# endif
+#
+# /* BOOST_PP_CONFIG_ERRORS */
+#
+# ifndef BOOST_PP_CONFIG_ERRORS
+#    ifdef NDEBUG
+#        define BOOST_PP_CONFIG_ERRORS 0
+#    else
+#        define BOOST_PP_CONFIG_ERRORS 1
+#    endif
+# endif
+#
+# /* BOOST_PP_VARIADICS */
+#
+# define BOOST_PP_VARIADICS_MSVC 0
+# if !defined BOOST_PP_VARIADICS
+#    /* variadic support explicitly disabled for all untested compilers */
+#    if defined __GCCXML__ || defined __CUDACC__ || defined __PATHSCALE__ || defined __DMC__ || defined __CODEGEARC__ || defined __BORLANDC__ || defined __MWERKS__ || ( defined __SUNPRO_CC && __SUNPRO_CC < 0x5130 ) || defined __HP_aCC && !defined __EDG__ || defined __MRC__ || defined __SC__ || defined __IBMCPP__ || defined __PGI
+#        define BOOST_PP_VARIADICS 0
+#    /* VC++ (C/C++) */
+#    elif defined _MSC_VER && _MSC_VER >= 1400 && (!defined __EDG__ || defined(__INTELLISENSE__)) && !defined __clang__
+#        define BOOST_PP_VARIADICS 1
+#        undef BOOST_PP_VARIADICS_MSVC
+#        define BOOST_PP_VARIADICS_MSVC 1
+#    /* Wave (C/C++), GCC (C++) */
+#    elif defined __WAVE__ && __WAVE_HAS_VARIADICS__ || defined __GNUC__ && defined __GXX_EXPERIMENTAL_CXX0X__ && __GXX_EXPERIMENTAL_CXX0X__
+#        define BOOST_PP_VARIADICS 1
+#    /* EDG-based (C/C++), GCC (C), and unknown (C/C++) */
+#    elif !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L
+#        define BOOST_PP_VARIADICS 1
+#    else
+#        define BOOST_PP_VARIADICS 0
+#    endif
+# elif !BOOST_PP_VARIADICS + 1 < 2
+#    undef BOOST_PP_VARIADICS
+#    define BOOST_PP_VARIADICS 1
+#    if defined _MSC_VER && _MSC_VER >= 1400 && (defined(__INTELLISENSE__) || !(defined __EDG__ || defined __GCCXML__ || defined __CUDACC__ || defined __PATHSCALE__ || defined __clang__ || defined __DMC__ || defined __CODEGEARC__ || defined __BORLANDC__ || defined __MWERKS__ || defined __SUNPRO_CC || defined __HP_aCC || defined __MRC__ || defined __SC__ || defined __IBMCPP__ || defined __PGI))
+#        undef BOOST_PP_VARIADICS_MSVC
+#        define BOOST_PP_VARIADICS_MSVC 1
+#    endif
+# else
+#    undef BOOST_PP_VARIADICS
+#    define BOOST_PP_VARIADICS 0
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/control/detail/while.hpp b/third_party/boost/boost/preprocessor/control/detail/while.hpp
new file mode 100644
index 0000000..7315e1d
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/control/detail/while.hpp
@@ -0,0 +1,536 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_CONTROL_DETAIL_WHILE_HPP
+# define BOOST_PREPROCESSOR_CONTROL_DETAIL_WHILE_HPP
+#
+# include <boost/preprocessor/control/iif.hpp>
+# include <boost/preprocessor/logical/bool.hpp>
+# include <boost/preprocessor/tuple/eat.hpp>
+#
+# define BOOST_PP_WHILE_1(p, o, s) BOOST_PP_WHILE_1_C(BOOST_PP_BOOL(p(2, s)), p, o, s)
+# define BOOST_PP_WHILE_2(p, o, s) BOOST_PP_WHILE_2_C(BOOST_PP_BOOL(p(3, s)), p, o, s)
+# define BOOST_PP_WHILE_3(p, o, s) BOOST_PP_WHILE_3_C(BOOST_PP_BOOL(p(4, s)), p, o, s)
+# define BOOST_PP_WHILE_4(p, o, s) BOOST_PP_WHILE_4_C(BOOST_PP_BOOL(p(5, s)), p, o, s)
+# define BOOST_PP_WHILE_5(p, o, s) BOOST_PP_WHILE_5_C(BOOST_PP_BOOL(p(6, s)), p, o, s)
+# define BOOST_PP_WHILE_6(p, o, s) BOOST_PP_WHILE_6_C(BOOST_PP_BOOL(p(7, s)), p, o, s)
+# define BOOST_PP_WHILE_7(p, o, s) BOOST_PP_WHILE_7_C(BOOST_PP_BOOL(p(8, s)), p, o, s)
+# define BOOST_PP_WHILE_8(p, o, s) BOOST_PP_WHILE_8_C(BOOST_PP_BOOL(p(9, s)), p, o, s)
+# define BOOST_PP_WHILE_9(p, o, s) BOOST_PP_WHILE_9_C(BOOST_PP_BOOL(p(10, s)), p, o, s)
+# define BOOST_PP_WHILE_10(p, o, s) BOOST_PP_WHILE_10_C(BOOST_PP_BOOL(p(11, s)), p, o, s)
+# define BOOST_PP_WHILE_11(p, o, s) BOOST_PP_WHILE_11_C(BOOST_PP_BOOL(p(12, s)), p, o, s)
+# define BOOST_PP_WHILE_12(p, o, s) BOOST_PP_WHILE_12_C(BOOST_PP_BOOL(p(13, s)), p, o, s)
+# define BOOST_PP_WHILE_13(p, o, s) BOOST_PP_WHILE_13_C(BOOST_PP_BOOL(p(14, s)), p, o, s)
+# define BOOST_PP_WHILE_14(p, o, s) BOOST_PP_WHILE_14_C(BOOST_PP_BOOL(p(15, s)), p, o, s)
+# define BOOST_PP_WHILE_15(p, o, s) BOOST_PP_WHILE_15_C(BOOST_PP_BOOL(p(16, s)), p, o, s)
+# define BOOST_PP_WHILE_16(p, o, s) BOOST_PP_WHILE_16_C(BOOST_PP_BOOL(p(17, s)), p, o, s)
+# define BOOST_PP_WHILE_17(p, o, s) BOOST_PP_WHILE_17_C(BOOST_PP_BOOL(p(18, s)), p, o, s)
+# define BOOST_PP_WHILE_18(p, o, s) BOOST_PP_WHILE_18_C(BOOST_PP_BOOL(p(19, s)), p, o, s)
+# define BOOST_PP_WHILE_19(p, o, s) BOOST_PP_WHILE_19_C(BOOST_PP_BOOL(p(20, s)), p, o, s)
+# define BOOST_PP_WHILE_20(p, o, s) BOOST_PP_WHILE_20_C(BOOST_PP_BOOL(p(21, s)), p, o, s)
+# define BOOST_PP_WHILE_21(p, o, s) BOOST_PP_WHILE_21_C(BOOST_PP_BOOL(p(22, s)), p, o, s)
+# define BOOST_PP_WHILE_22(p, o, s) BOOST_PP_WHILE_22_C(BOOST_PP_BOOL(p(23, s)), p, o, s)
+# define BOOST_PP_WHILE_23(p, o, s) BOOST_PP_WHILE_23_C(BOOST_PP_BOOL(p(24, s)), p, o, s)
+# define BOOST_PP_WHILE_24(p, o, s) BOOST_PP_WHILE_24_C(BOOST_PP_BOOL(p(25, s)), p, o, s)
+# define BOOST_PP_WHILE_25(p, o, s) BOOST_PP_WHILE_25_C(BOOST_PP_BOOL(p(26, s)), p, o, s)
+# define BOOST_PP_WHILE_26(p, o, s) BOOST_PP_WHILE_26_C(BOOST_PP_BOOL(p(27, s)), p, o, s)
+# define BOOST_PP_WHILE_27(p, o, s) BOOST_PP_WHILE_27_C(BOOST_PP_BOOL(p(28, s)), p, o, s)
+# define BOOST_PP_WHILE_28(p, o, s) BOOST_PP_WHILE_28_C(BOOST_PP_BOOL(p(29, s)), p, o, s)
+# define BOOST_PP_WHILE_29(p, o, s) BOOST_PP_WHILE_29_C(BOOST_PP_BOOL(p(30, s)), p, o, s)
+# define BOOST_PP_WHILE_30(p, o, s) BOOST_PP_WHILE_30_C(BOOST_PP_BOOL(p(31, s)), p, o, s)
+# define BOOST_PP_WHILE_31(p, o, s) BOOST_PP_WHILE_31_C(BOOST_PP_BOOL(p(32, s)), p, o, s)
+# define BOOST_PP_WHILE_32(p, o, s) BOOST_PP_WHILE_32_C(BOOST_PP_BOOL(p(33, s)), p, o, s)
+# define BOOST_PP_WHILE_33(p, o, s) BOOST_PP_WHILE_33_C(BOOST_PP_BOOL(p(34, s)), p, o, s)
+# define BOOST_PP_WHILE_34(p, o, s) BOOST_PP_WHILE_34_C(BOOST_PP_BOOL(p(35, s)), p, o, s)
+# define BOOST_PP_WHILE_35(p, o, s) BOOST_PP_WHILE_35_C(BOOST_PP_BOOL(p(36, s)), p, o, s)
+# define BOOST_PP_WHILE_36(p, o, s) BOOST_PP_WHILE_36_C(BOOST_PP_BOOL(p(37, s)), p, o, s)
+# define BOOST_PP_WHILE_37(p, o, s) BOOST_PP_WHILE_37_C(BOOST_PP_BOOL(p(38, s)), p, o, s)
+# define BOOST_PP_WHILE_38(p, o, s) BOOST_PP_WHILE_38_C(BOOST_PP_BOOL(p(39, s)), p, o, s)
+# define BOOST_PP_WHILE_39(p, o, s) BOOST_PP_WHILE_39_C(BOOST_PP_BOOL(p(40, s)), p, o, s)
+# define BOOST_PP_WHILE_40(p, o, s) BOOST_PP_WHILE_40_C(BOOST_PP_BOOL(p(41, s)), p, o, s)
+# define BOOST_PP_WHILE_41(p, o, s) BOOST_PP_WHILE_41_C(BOOST_PP_BOOL(p(42, s)), p, o, s)
+# define BOOST_PP_WHILE_42(p, o, s) BOOST_PP_WHILE_42_C(BOOST_PP_BOOL(p(43, s)), p, o, s)
+# define BOOST_PP_WHILE_43(p, o, s) BOOST_PP_WHILE_43_C(BOOST_PP_BOOL(p(44, s)), p, o, s)
+# define BOOST_PP_WHILE_44(p, o, s) BOOST_PP_WHILE_44_C(BOOST_PP_BOOL(p(45, s)), p, o, s)
+# define BOOST_PP_WHILE_45(p, o, s) BOOST_PP_WHILE_45_C(BOOST_PP_BOOL(p(46, s)), p, o, s)
+# define BOOST_PP_WHILE_46(p, o, s) BOOST_PP_WHILE_46_C(BOOST_PP_BOOL(p(47, s)), p, o, s)
+# define BOOST_PP_WHILE_47(p, o, s) BOOST_PP_WHILE_47_C(BOOST_PP_BOOL(p(48, s)), p, o, s)
+# define BOOST_PP_WHILE_48(p, o, s) BOOST_PP_WHILE_48_C(BOOST_PP_BOOL(p(49, s)), p, o, s)
+# define BOOST_PP_WHILE_49(p, o, s) BOOST_PP_WHILE_49_C(BOOST_PP_BOOL(p(50, s)), p, o, s)
+# define BOOST_PP_WHILE_50(p, o, s) BOOST_PP_WHILE_50_C(BOOST_PP_BOOL(p(51, s)), p, o, s)
+# define BOOST_PP_WHILE_51(p, o, s) BOOST_PP_WHILE_51_C(BOOST_PP_BOOL(p(52, s)), p, o, s)
+# define BOOST_PP_WHILE_52(p, o, s) BOOST_PP_WHILE_52_C(BOOST_PP_BOOL(p(53, s)), p, o, s)
+# define BOOST_PP_WHILE_53(p, o, s) BOOST_PP_WHILE_53_C(BOOST_PP_BOOL(p(54, s)), p, o, s)
+# define BOOST_PP_WHILE_54(p, o, s) BOOST_PP_WHILE_54_C(BOOST_PP_BOOL(p(55, s)), p, o, s)
+# define BOOST_PP_WHILE_55(p, o, s) BOOST_PP_WHILE_55_C(BOOST_PP_BOOL(p(56, s)), p, o, s)
+# define BOOST_PP_WHILE_56(p, o, s) BOOST_PP_WHILE_56_C(BOOST_PP_BOOL(p(57, s)), p, o, s)
+# define BOOST_PP_WHILE_57(p, o, s) BOOST_PP_WHILE_57_C(BOOST_PP_BOOL(p(58, s)), p, o, s)
+# define BOOST_PP_WHILE_58(p, o, s) BOOST_PP_WHILE_58_C(BOOST_PP_BOOL(p(59, s)), p, o, s)
+# define BOOST_PP_WHILE_59(p, o, s) BOOST_PP_WHILE_59_C(BOOST_PP_BOOL(p(60, s)), p, o, s)
+# define BOOST_PP_WHILE_60(p, o, s) BOOST_PP_WHILE_60_C(BOOST_PP_BOOL(p(61, s)), p, o, s)
+# define BOOST_PP_WHILE_61(p, o, s) BOOST_PP_WHILE_61_C(BOOST_PP_BOOL(p(62, s)), p, o, s)
+# define BOOST_PP_WHILE_62(p, o, s) BOOST_PP_WHILE_62_C(BOOST_PP_BOOL(p(63, s)), p, o, s)
+# define BOOST_PP_WHILE_63(p, o, s) BOOST_PP_WHILE_63_C(BOOST_PP_BOOL(p(64, s)), p, o, s)
+# define BOOST_PP_WHILE_64(p, o, s) BOOST_PP_WHILE_64_C(BOOST_PP_BOOL(p(65, s)), p, o, s)
+# define BOOST_PP_WHILE_65(p, o, s) BOOST_PP_WHILE_65_C(BOOST_PP_BOOL(p(66, s)), p, o, s)
+# define BOOST_PP_WHILE_66(p, o, s) BOOST_PP_WHILE_66_C(BOOST_PP_BOOL(p(67, s)), p, o, s)
+# define BOOST_PP_WHILE_67(p, o, s) BOOST_PP_WHILE_67_C(BOOST_PP_BOOL(p(68, s)), p, o, s)
+# define BOOST_PP_WHILE_68(p, o, s) BOOST_PP_WHILE_68_C(BOOST_PP_BOOL(p(69, s)), p, o, s)
+# define BOOST_PP_WHILE_69(p, o, s) BOOST_PP_WHILE_69_C(BOOST_PP_BOOL(p(70, s)), p, o, s)
+# define BOOST_PP_WHILE_70(p, o, s) BOOST_PP_WHILE_70_C(BOOST_PP_BOOL(p(71, s)), p, o, s)
+# define BOOST_PP_WHILE_71(p, o, s) BOOST_PP_WHILE_71_C(BOOST_PP_BOOL(p(72, s)), p, o, s)
+# define BOOST_PP_WHILE_72(p, o, s) BOOST_PP_WHILE_72_C(BOOST_PP_BOOL(p(73, s)), p, o, s)
+# define BOOST_PP_WHILE_73(p, o, s) BOOST_PP_WHILE_73_C(BOOST_PP_BOOL(p(74, s)), p, o, s)
+# define BOOST_PP_WHILE_74(p, o, s) BOOST_PP_WHILE_74_C(BOOST_PP_BOOL(p(75, s)), p, o, s)
+# define BOOST_PP_WHILE_75(p, o, s) BOOST_PP_WHILE_75_C(BOOST_PP_BOOL(p(76, s)), p, o, s)
+# define BOOST_PP_WHILE_76(p, o, s) BOOST_PP_WHILE_76_C(BOOST_PP_BOOL(p(77, s)), p, o, s)
+# define BOOST_PP_WHILE_77(p, o, s) BOOST_PP_WHILE_77_C(BOOST_PP_BOOL(p(78, s)), p, o, s)
+# define BOOST_PP_WHILE_78(p, o, s) BOOST_PP_WHILE_78_C(BOOST_PP_BOOL(p(79, s)), p, o, s)
+# define BOOST_PP_WHILE_79(p, o, s) BOOST_PP_WHILE_79_C(BOOST_PP_BOOL(p(80, s)), p, o, s)
+# define BOOST_PP_WHILE_80(p, o, s) BOOST_PP_WHILE_80_C(BOOST_PP_BOOL(p(81, s)), p, o, s)
+# define BOOST_PP_WHILE_81(p, o, s) BOOST_PP_WHILE_81_C(BOOST_PP_BOOL(p(82, s)), p, o, s)
+# define BOOST_PP_WHILE_82(p, o, s) BOOST_PP_WHILE_82_C(BOOST_PP_BOOL(p(83, s)), p, o, s)
+# define BOOST_PP_WHILE_83(p, o, s) BOOST_PP_WHILE_83_C(BOOST_PP_BOOL(p(84, s)), p, o, s)
+# define BOOST_PP_WHILE_84(p, o, s) BOOST_PP_WHILE_84_C(BOOST_PP_BOOL(p(85, s)), p, o, s)
+# define BOOST_PP_WHILE_85(p, o, s) BOOST_PP_WHILE_85_C(BOOST_PP_BOOL(p(86, s)), p, o, s)
+# define BOOST_PP_WHILE_86(p, o, s) BOOST_PP_WHILE_86_C(BOOST_PP_BOOL(p(87, s)), p, o, s)
+# define BOOST_PP_WHILE_87(p, o, s) BOOST_PP_WHILE_87_C(BOOST_PP_BOOL(p(88, s)), p, o, s)
+# define BOOST_PP_WHILE_88(p, o, s) BOOST_PP_WHILE_88_C(BOOST_PP_BOOL(p(89, s)), p, o, s)
+# define BOOST_PP_WHILE_89(p, o, s) BOOST_PP_WHILE_89_C(BOOST_PP_BOOL(p(90, s)), p, o, s)
+# define BOOST_PP_WHILE_90(p, o, s) BOOST_PP_WHILE_90_C(BOOST_PP_BOOL(p(91, s)), p, o, s)
+# define BOOST_PP_WHILE_91(p, o, s) BOOST_PP_WHILE_91_C(BOOST_PP_BOOL(p(92, s)), p, o, s)
+# define BOOST_PP_WHILE_92(p, o, s) BOOST_PP_WHILE_92_C(BOOST_PP_BOOL(p(93, s)), p, o, s)
+# define BOOST_PP_WHILE_93(p, o, s) BOOST_PP_WHILE_93_C(BOOST_PP_BOOL(p(94, s)), p, o, s)
+# define BOOST_PP_WHILE_94(p, o, s) BOOST_PP_WHILE_94_C(BOOST_PP_BOOL(p(95, s)), p, o, s)
+# define BOOST_PP_WHILE_95(p, o, s) BOOST_PP_WHILE_95_C(BOOST_PP_BOOL(p(96, s)), p, o, s)
+# define BOOST_PP_WHILE_96(p, o, s) BOOST_PP_WHILE_96_C(BOOST_PP_BOOL(p(97, s)), p, o, s)
+# define BOOST_PP_WHILE_97(p, o, s) BOOST_PP_WHILE_97_C(BOOST_PP_BOOL(p(98, s)), p, o, s)
+# define BOOST_PP_WHILE_98(p, o, s) BOOST_PP_WHILE_98_C(BOOST_PP_BOOL(p(99, s)), p, o, s)
+# define BOOST_PP_WHILE_99(p, o, s) BOOST_PP_WHILE_99_C(BOOST_PP_BOOL(p(100, s)), p, o, s)
+# define BOOST_PP_WHILE_100(p, o, s) BOOST_PP_WHILE_100_C(BOOST_PP_BOOL(p(101, s)), p, o, s)
+# define BOOST_PP_WHILE_101(p, o, s) BOOST_PP_WHILE_101_C(BOOST_PP_BOOL(p(102, s)), p, o, s)
+# define BOOST_PP_WHILE_102(p, o, s) BOOST_PP_WHILE_102_C(BOOST_PP_BOOL(p(103, s)), p, o, s)
+# define BOOST_PP_WHILE_103(p, o, s) BOOST_PP_WHILE_103_C(BOOST_PP_BOOL(p(104, s)), p, o, s)
+# define BOOST_PP_WHILE_104(p, o, s) BOOST_PP_WHILE_104_C(BOOST_PP_BOOL(p(105, s)), p, o, s)
+# define BOOST_PP_WHILE_105(p, o, s) BOOST_PP_WHILE_105_C(BOOST_PP_BOOL(p(106, s)), p, o, s)
+# define BOOST_PP_WHILE_106(p, o, s) BOOST_PP_WHILE_106_C(BOOST_PP_BOOL(p(107, s)), p, o, s)
+# define BOOST_PP_WHILE_107(p, o, s) BOOST_PP_WHILE_107_C(BOOST_PP_BOOL(p(108, s)), p, o, s)
+# define BOOST_PP_WHILE_108(p, o, s) BOOST_PP_WHILE_108_C(BOOST_PP_BOOL(p(109, s)), p, o, s)
+# define BOOST_PP_WHILE_109(p, o, s) BOOST_PP_WHILE_109_C(BOOST_PP_BOOL(p(110, s)), p, o, s)
+# define BOOST_PP_WHILE_110(p, o, s) BOOST_PP_WHILE_110_C(BOOST_PP_BOOL(p(111, s)), p, o, s)
+# define BOOST_PP_WHILE_111(p, o, s) BOOST_PP_WHILE_111_C(BOOST_PP_BOOL(p(112, s)), p, o, s)
+# define BOOST_PP_WHILE_112(p, o, s) BOOST_PP_WHILE_112_C(BOOST_PP_BOOL(p(113, s)), p, o, s)
+# define BOOST_PP_WHILE_113(p, o, s) BOOST_PP_WHILE_113_C(BOOST_PP_BOOL(p(114, s)), p, o, s)
+# define BOOST_PP_WHILE_114(p, o, s) BOOST_PP_WHILE_114_C(BOOST_PP_BOOL(p(115, s)), p, o, s)
+# define BOOST_PP_WHILE_115(p, o, s) BOOST_PP_WHILE_115_C(BOOST_PP_BOOL(p(116, s)), p, o, s)
+# define BOOST_PP_WHILE_116(p, o, s) BOOST_PP_WHILE_116_C(BOOST_PP_BOOL(p(117, s)), p, o, s)
+# define BOOST_PP_WHILE_117(p, o, s) BOOST_PP_WHILE_117_C(BOOST_PP_BOOL(p(118, s)), p, o, s)
+# define BOOST_PP_WHILE_118(p, o, s) BOOST_PP_WHILE_118_C(BOOST_PP_BOOL(p(119, s)), p, o, s)
+# define BOOST_PP_WHILE_119(p, o, s) BOOST_PP_WHILE_119_C(BOOST_PP_BOOL(p(120, s)), p, o, s)
+# define BOOST_PP_WHILE_120(p, o, s) BOOST_PP_WHILE_120_C(BOOST_PP_BOOL(p(121, s)), p, o, s)
+# define BOOST_PP_WHILE_121(p, o, s) BOOST_PP_WHILE_121_C(BOOST_PP_BOOL(p(122, s)), p, o, s)
+# define BOOST_PP_WHILE_122(p, o, s) BOOST_PP_WHILE_122_C(BOOST_PP_BOOL(p(123, s)), p, o, s)
+# define BOOST_PP_WHILE_123(p, o, s) BOOST_PP_WHILE_123_C(BOOST_PP_BOOL(p(124, s)), p, o, s)
+# define BOOST_PP_WHILE_124(p, o, s) BOOST_PP_WHILE_124_C(BOOST_PP_BOOL(p(125, s)), p, o, s)
+# define BOOST_PP_WHILE_125(p, o, s) BOOST_PP_WHILE_125_C(BOOST_PP_BOOL(p(126, s)), p, o, s)
+# define BOOST_PP_WHILE_126(p, o, s) BOOST_PP_WHILE_126_C(BOOST_PP_BOOL(p(127, s)), p, o, s)
+# define BOOST_PP_WHILE_127(p, o, s) BOOST_PP_WHILE_127_C(BOOST_PP_BOOL(p(128, s)), p, o, s)
+# define BOOST_PP_WHILE_128(p, o, s) BOOST_PP_WHILE_128_C(BOOST_PP_BOOL(p(129, s)), p, o, s)
+# define BOOST_PP_WHILE_129(p, o, s) BOOST_PP_WHILE_129_C(BOOST_PP_BOOL(p(130, s)), p, o, s)
+# define BOOST_PP_WHILE_130(p, o, s) BOOST_PP_WHILE_130_C(BOOST_PP_BOOL(p(131, s)), p, o, s)
+# define BOOST_PP_WHILE_131(p, o, s) BOOST_PP_WHILE_131_C(BOOST_PP_BOOL(p(132, s)), p, o, s)
+# define BOOST_PP_WHILE_132(p, o, s) BOOST_PP_WHILE_132_C(BOOST_PP_BOOL(p(133, s)), p, o, s)
+# define BOOST_PP_WHILE_133(p, o, s) BOOST_PP_WHILE_133_C(BOOST_PP_BOOL(p(134, s)), p, o, s)
+# define BOOST_PP_WHILE_134(p, o, s) BOOST_PP_WHILE_134_C(BOOST_PP_BOOL(p(135, s)), p, o, s)
+# define BOOST_PP_WHILE_135(p, o, s) BOOST_PP_WHILE_135_C(BOOST_PP_BOOL(p(136, s)), p, o, s)
+# define BOOST_PP_WHILE_136(p, o, s) BOOST_PP_WHILE_136_C(BOOST_PP_BOOL(p(137, s)), p, o, s)
+# define BOOST_PP_WHILE_137(p, o, s) BOOST_PP_WHILE_137_C(BOOST_PP_BOOL(p(138, s)), p, o, s)
+# define BOOST_PP_WHILE_138(p, o, s) BOOST_PP_WHILE_138_C(BOOST_PP_BOOL(p(139, s)), p, o, s)
+# define BOOST_PP_WHILE_139(p, o, s) BOOST_PP_WHILE_139_C(BOOST_PP_BOOL(p(140, s)), p, o, s)
+# define BOOST_PP_WHILE_140(p, o, s) BOOST_PP_WHILE_140_C(BOOST_PP_BOOL(p(141, s)), p, o, s)
+# define BOOST_PP_WHILE_141(p, o, s) BOOST_PP_WHILE_141_C(BOOST_PP_BOOL(p(142, s)), p, o, s)
+# define BOOST_PP_WHILE_142(p, o, s) BOOST_PP_WHILE_142_C(BOOST_PP_BOOL(p(143, s)), p, o, s)
+# define BOOST_PP_WHILE_143(p, o, s) BOOST_PP_WHILE_143_C(BOOST_PP_BOOL(p(144, s)), p, o, s)
+# define BOOST_PP_WHILE_144(p, o, s) BOOST_PP_WHILE_144_C(BOOST_PP_BOOL(p(145, s)), p, o, s)
+# define BOOST_PP_WHILE_145(p, o, s) BOOST_PP_WHILE_145_C(BOOST_PP_BOOL(p(146, s)), p, o, s)
+# define BOOST_PP_WHILE_146(p, o, s) BOOST_PP_WHILE_146_C(BOOST_PP_BOOL(p(147, s)), p, o, s)
+# define BOOST_PP_WHILE_147(p, o, s) BOOST_PP_WHILE_147_C(BOOST_PP_BOOL(p(148, s)), p, o, s)
+# define BOOST_PP_WHILE_148(p, o, s) BOOST_PP_WHILE_148_C(BOOST_PP_BOOL(p(149, s)), p, o, s)
+# define BOOST_PP_WHILE_149(p, o, s) BOOST_PP_WHILE_149_C(BOOST_PP_BOOL(p(150, s)), p, o, s)
+# define BOOST_PP_WHILE_150(p, o, s) BOOST_PP_WHILE_150_C(BOOST_PP_BOOL(p(151, s)), p, o, s)
+# define BOOST_PP_WHILE_151(p, o, s) BOOST_PP_WHILE_151_C(BOOST_PP_BOOL(p(152, s)), p, o, s)
+# define BOOST_PP_WHILE_152(p, o, s) BOOST_PP_WHILE_152_C(BOOST_PP_BOOL(p(153, s)), p, o, s)
+# define BOOST_PP_WHILE_153(p, o, s) BOOST_PP_WHILE_153_C(BOOST_PP_BOOL(p(154, s)), p, o, s)
+# define BOOST_PP_WHILE_154(p, o, s) BOOST_PP_WHILE_154_C(BOOST_PP_BOOL(p(155, s)), p, o, s)
+# define BOOST_PP_WHILE_155(p, o, s) BOOST_PP_WHILE_155_C(BOOST_PP_BOOL(p(156, s)), p, o, s)
+# define BOOST_PP_WHILE_156(p, o, s) BOOST_PP_WHILE_156_C(BOOST_PP_BOOL(p(157, s)), p, o, s)
+# define BOOST_PP_WHILE_157(p, o, s) BOOST_PP_WHILE_157_C(BOOST_PP_BOOL(p(158, s)), p, o, s)
+# define BOOST_PP_WHILE_158(p, o, s) BOOST_PP_WHILE_158_C(BOOST_PP_BOOL(p(159, s)), p, o, s)
+# define BOOST_PP_WHILE_159(p, o, s) BOOST_PP_WHILE_159_C(BOOST_PP_BOOL(p(160, s)), p, o, s)
+# define BOOST_PP_WHILE_160(p, o, s) BOOST_PP_WHILE_160_C(BOOST_PP_BOOL(p(161, s)), p, o, s)
+# define BOOST_PP_WHILE_161(p, o, s) BOOST_PP_WHILE_161_C(BOOST_PP_BOOL(p(162, s)), p, o, s)
+# define BOOST_PP_WHILE_162(p, o, s) BOOST_PP_WHILE_162_C(BOOST_PP_BOOL(p(163, s)), p, o, s)
+# define BOOST_PP_WHILE_163(p, o, s) BOOST_PP_WHILE_163_C(BOOST_PP_BOOL(p(164, s)), p, o, s)
+# define BOOST_PP_WHILE_164(p, o, s) BOOST_PP_WHILE_164_C(BOOST_PP_BOOL(p(165, s)), p, o, s)
+# define BOOST_PP_WHILE_165(p, o, s) BOOST_PP_WHILE_165_C(BOOST_PP_BOOL(p(166, s)), p, o, s)
+# define BOOST_PP_WHILE_166(p, o, s) BOOST_PP_WHILE_166_C(BOOST_PP_BOOL(p(167, s)), p, o, s)
+# define BOOST_PP_WHILE_167(p, o, s) BOOST_PP_WHILE_167_C(BOOST_PP_BOOL(p(168, s)), p, o, s)
+# define BOOST_PP_WHILE_168(p, o, s) BOOST_PP_WHILE_168_C(BOOST_PP_BOOL(p(169, s)), p, o, s)
+# define BOOST_PP_WHILE_169(p, o, s) BOOST_PP_WHILE_169_C(BOOST_PP_BOOL(p(170, s)), p, o, s)
+# define BOOST_PP_WHILE_170(p, o, s) BOOST_PP_WHILE_170_C(BOOST_PP_BOOL(p(171, s)), p, o, s)
+# define BOOST_PP_WHILE_171(p, o, s) BOOST_PP_WHILE_171_C(BOOST_PP_BOOL(p(172, s)), p, o, s)
+# define BOOST_PP_WHILE_172(p, o, s) BOOST_PP_WHILE_172_C(BOOST_PP_BOOL(p(173, s)), p, o, s)
+# define BOOST_PP_WHILE_173(p, o, s) BOOST_PP_WHILE_173_C(BOOST_PP_BOOL(p(174, s)), p, o, s)
+# define BOOST_PP_WHILE_174(p, o, s) BOOST_PP_WHILE_174_C(BOOST_PP_BOOL(p(175, s)), p, o, s)
+# define BOOST_PP_WHILE_175(p, o, s) BOOST_PP_WHILE_175_C(BOOST_PP_BOOL(p(176, s)), p, o, s)
+# define BOOST_PP_WHILE_176(p, o, s) BOOST_PP_WHILE_176_C(BOOST_PP_BOOL(p(177, s)), p, o, s)
+# define BOOST_PP_WHILE_177(p, o, s) BOOST_PP_WHILE_177_C(BOOST_PP_BOOL(p(178, s)), p, o, s)
+# define BOOST_PP_WHILE_178(p, o, s) BOOST_PP_WHILE_178_C(BOOST_PP_BOOL(p(179, s)), p, o, s)
+# define BOOST_PP_WHILE_179(p, o, s) BOOST_PP_WHILE_179_C(BOOST_PP_BOOL(p(180, s)), p, o, s)
+# define BOOST_PP_WHILE_180(p, o, s) BOOST_PP_WHILE_180_C(BOOST_PP_BOOL(p(181, s)), p, o, s)
+# define BOOST_PP_WHILE_181(p, o, s) BOOST_PP_WHILE_181_C(BOOST_PP_BOOL(p(182, s)), p, o, s)
+# define BOOST_PP_WHILE_182(p, o, s) BOOST_PP_WHILE_182_C(BOOST_PP_BOOL(p(183, s)), p, o, s)
+# define BOOST_PP_WHILE_183(p, o, s) BOOST_PP_WHILE_183_C(BOOST_PP_BOOL(p(184, s)), p, o, s)
+# define BOOST_PP_WHILE_184(p, o, s) BOOST_PP_WHILE_184_C(BOOST_PP_BOOL(p(185, s)), p, o, s)
+# define BOOST_PP_WHILE_185(p, o, s) BOOST_PP_WHILE_185_C(BOOST_PP_BOOL(p(186, s)), p, o, s)
+# define BOOST_PP_WHILE_186(p, o, s) BOOST_PP_WHILE_186_C(BOOST_PP_BOOL(p(187, s)), p, o, s)
+# define BOOST_PP_WHILE_187(p, o, s) BOOST_PP_WHILE_187_C(BOOST_PP_BOOL(p(188, s)), p, o, s)
+# define BOOST_PP_WHILE_188(p, o, s) BOOST_PP_WHILE_188_C(BOOST_PP_BOOL(p(189, s)), p, o, s)
+# define BOOST_PP_WHILE_189(p, o, s) BOOST_PP_WHILE_189_C(BOOST_PP_BOOL(p(190, s)), p, o, s)
+# define BOOST_PP_WHILE_190(p, o, s) BOOST_PP_WHILE_190_C(BOOST_PP_BOOL(p(191, s)), p, o, s)
+# define BOOST_PP_WHILE_191(p, o, s) BOOST_PP_WHILE_191_C(BOOST_PP_BOOL(p(192, s)), p, o, s)
+# define BOOST_PP_WHILE_192(p, o, s) BOOST_PP_WHILE_192_C(BOOST_PP_BOOL(p(193, s)), p, o, s)
+# define BOOST_PP_WHILE_193(p, o, s) BOOST_PP_WHILE_193_C(BOOST_PP_BOOL(p(194, s)), p, o, s)
+# define BOOST_PP_WHILE_194(p, o, s) BOOST_PP_WHILE_194_C(BOOST_PP_BOOL(p(195, s)), p, o, s)
+# define BOOST_PP_WHILE_195(p, o, s) BOOST_PP_WHILE_195_C(BOOST_PP_BOOL(p(196, s)), p, o, s)
+# define BOOST_PP_WHILE_196(p, o, s) BOOST_PP_WHILE_196_C(BOOST_PP_BOOL(p(197, s)), p, o, s)
+# define BOOST_PP_WHILE_197(p, o, s) BOOST_PP_WHILE_197_C(BOOST_PP_BOOL(p(198, s)), p, o, s)
+# define BOOST_PP_WHILE_198(p, o, s) BOOST_PP_WHILE_198_C(BOOST_PP_BOOL(p(199, s)), p, o, s)
+# define BOOST_PP_WHILE_199(p, o, s) BOOST_PP_WHILE_199_C(BOOST_PP_BOOL(p(200, s)), p, o, s)
+# define BOOST_PP_WHILE_200(p, o, s) BOOST_PP_WHILE_200_C(BOOST_PP_BOOL(p(201, s)), p, o, s)
+# define BOOST_PP_WHILE_201(p, o, s) BOOST_PP_WHILE_201_C(BOOST_PP_BOOL(p(202, s)), p, o, s)
+# define BOOST_PP_WHILE_202(p, o, s) BOOST_PP_WHILE_202_C(BOOST_PP_BOOL(p(203, s)), p, o, s)
+# define BOOST_PP_WHILE_203(p, o, s) BOOST_PP_WHILE_203_C(BOOST_PP_BOOL(p(204, s)), p, o, s)
+# define BOOST_PP_WHILE_204(p, o, s) BOOST_PP_WHILE_204_C(BOOST_PP_BOOL(p(205, s)), p, o, s)
+# define BOOST_PP_WHILE_205(p, o, s) BOOST_PP_WHILE_205_C(BOOST_PP_BOOL(p(206, s)), p, o, s)
+# define BOOST_PP_WHILE_206(p, o, s) BOOST_PP_WHILE_206_C(BOOST_PP_BOOL(p(207, s)), p, o, s)
+# define BOOST_PP_WHILE_207(p, o, s) BOOST_PP_WHILE_207_C(BOOST_PP_BOOL(p(208, s)), p, o, s)
+# define BOOST_PP_WHILE_208(p, o, s) BOOST_PP_WHILE_208_C(BOOST_PP_BOOL(p(209, s)), p, o, s)
+# define BOOST_PP_WHILE_209(p, o, s) BOOST_PP_WHILE_209_C(BOOST_PP_BOOL(p(210, s)), p, o, s)
+# define BOOST_PP_WHILE_210(p, o, s) BOOST_PP_WHILE_210_C(BOOST_PP_BOOL(p(211, s)), p, o, s)
+# define BOOST_PP_WHILE_211(p, o, s) BOOST_PP_WHILE_211_C(BOOST_PP_BOOL(p(212, s)), p, o, s)
+# define BOOST_PP_WHILE_212(p, o, s) BOOST_PP_WHILE_212_C(BOOST_PP_BOOL(p(213, s)), p, o, s)
+# define BOOST_PP_WHILE_213(p, o, s) BOOST_PP_WHILE_213_C(BOOST_PP_BOOL(p(214, s)), p, o, s)
+# define BOOST_PP_WHILE_214(p, o, s) BOOST_PP_WHILE_214_C(BOOST_PP_BOOL(p(215, s)), p, o, s)
+# define BOOST_PP_WHILE_215(p, o, s) BOOST_PP_WHILE_215_C(BOOST_PP_BOOL(p(216, s)), p, o, s)
+# define BOOST_PP_WHILE_216(p, o, s) BOOST_PP_WHILE_216_C(BOOST_PP_BOOL(p(217, s)), p, o, s)
+# define BOOST_PP_WHILE_217(p, o, s) BOOST_PP_WHILE_217_C(BOOST_PP_BOOL(p(218, s)), p, o, s)
+# define BOOST_PP_WHILE_218(p, o, s) BOOST_PP_WHILE_218_C(BOOST_PP_BOOL(p(219, s)), p, o, s)
+# define BOOST_PP_WHILE_219(p, o, s) BOOST_PP_WHILE_219_C(BOOST_PP_BOOL(p(220, s)), p, o, s)
+# define BOOST_PP_WHILE_220(p, o, s) BOOST_PP_WHILE_220_C(BOOST_PP_BOOL(p(221, s)), p, o, s)
+# define BOOST_PP_WHILE_221(p, o, s) BOOST_PP_WHILE_221_C(BOOST_PP_BOOL(p(222, s)), p, o, s)
+# define BOOST_PP_WHILE_222(p, o, s) BOOST_PP_WHILE_222_C(BOOST_PP_BOOL(p(223, s)), p, o, s)
+# define BOOST_PP_WHILE_223(p, o, s) BOOST_PP_WHILE_223_C(BOOST_PP_BOOL(p(224, s)), p, o, s)
+# define BOOST_PP_WHILE_224(p, o, s) BOOST_PP_WHILE_224_C(BOOST_PP_BOOL(p(225, s)), p, o, s)
+# define BOOST_PP_WHILE_225(p, o, s) BOOST_PP_WHILE_225_C(BOOST_PP_BOOL(p(226, s)), p, o, s)
+# define BOOST_PP_WHILE_226(p, o, s) BOOST_PP_WHILE_226_C(BOOST_PP_BOOL(p(227, s)), p, o, s)
+# define BOOST_PP_WHILE_227(p, o, s) BOOST_PP_WHILE_227_C(BOOST_PP_BOOL(p(228, s)), p, o, s)
+# define BOOST_PP_WHILE_228(p, o, s) BOOST_PP_WHILE_228_C(BOOST_PP_BOOL(p(229, s)), p, o, s)
+# define BOOST_PP_WHILE_229(p, o, s) BOOST_PP_WHILE_229_C(BOOST_PP_BOOL(p(230, s)), p, o, s)
+# define BOOST_PP_WHILE_230(p, o, s) BOOST_PP_WHILE_230_C(BOOST_PP_BOOL(p(231, s)), p, o, s)
+# define BOOST_PP_WHILE_231(p, o, s) BOOST_PP_WHILE_231_C(BOOST_PP_BOOL(p(232, s)), p, o, s)
+# define BOOST_PP_WHILE_232(p, o, s) BOOST_PP_WHILE_232_C(BOOST_PP_BOOL(p(233, s)), p, o, s)
+# define BOOST_PP_WHILE_233(p, o, s) BOOST_PP_WHILE_233_C(BOOST_PP_BOOL(p(234, s)), p, o, s)
+# define BOOST_PP_WHILE_234(p, o, s) BOOST_PP_WHILE_234_C(BOOST_PP_BOOL(p(235, s)), p, o, s)
+# define BOOST_PP_WHILE_235(p, o, s) BOOST_PP_WHILE_235_C(BOOST_PP_BOOL(p(236, s)), p, o, s)
+# define BOOST_PP_WHILE_236(p, o, s) BOOST_PP_WHILE_236_C(BOOST_PP_BOOL(p(237, s)), p, o, s)
+# define BOOST_PP_WHILE_237(p, o, s) BOOST_PP_WHILE_237_C(BOOST_PP_BOOL(p(238, s)), p, o, s)
+# define BOOST_PP_WHILE_238(p, o, s) BOOST_PP_WHILE_238_C(BOOST_PP_BOOL(p(239, s)), p, o, s)
+# define BOOST_PP_WHILE_239(p, o, s) BOOST_PP_WHILE_239_C(BOOST_PP_BOOL(p(240, s)), p, o, s)
+# define BOOST_PP_WHILE_240(p, o, s) BOOST_PP_WHILE_240_C(BOOST_PP_BOOL(p(241, s)), p, o, s)
+# define BOOST_PP_WHILE_241(p, o, s) BOOST_PP_WHILE_241_C(BOOST_PP_BOOL(p(242, s)), p, o, s)
+# define BOOST_PP_WHILE_242(p, o, s) BOOST_PP_WHILE_242_C(BOOST_PP_BOOL(p(243, s)), p, o, s)
+# define BOOST_PP_WHILE_243(p, o, s) BOOST_PP_WHILE_243_C(BOOST_PP_BOOL(p(244, s)), p, o, s)
+# define BOOST_PP_WHILE_244(p, o, s) BOOST_PP_WHILE_244_C(BOOST_PP_BOOL(p(245, s)), p, o, s)
+# define BOOST_PP_WHILE_245(p, o, s) BOOST_PP_WHILE_245_C(BOOST_PP_BOOL(p(246, s)), p, o, s)
+# define BOOST_PP_WHILE_246(p, o, s) BOOST_PP_WHILE_246_C(BOOST_PP_BOOL(p(247, s)), p, o, s)
+# define BOOST_PP_WHILE_247(p, o, s) BOOST_PP_WHILE_247_C(BOOST_PP_BOOL(p(248, s)), p, o, s)
+# define BOOST_PP_WHILE_248(p, o, s) BOOST_PP_WHILE_248_C(BOOST_PP_BOOL(p(249, s)), p, o, s)
+# define BOOST_PP_WHILE_249(p, o, s) BOOST_PP_WHILE_249_C(BOOST_PP_BOOL(p(250, s)), p, o, s)
+# define BOOST_PP_WHILE_250(p, o, s) BOOST_PP_WHILE_250_C(BOOST_PP_BOOL(p(251, s)), p, o, s)
+# define BOOST_PP_WHILE_251(p, o, s) BOOST_PP_WHILE_251_C(BOOST_PP_BOOL(p(252, s)), p, o, s)
+# define BOOST_PP_WHILE_252(p, o, s) BOOST_PP_WHILE_252_C(BOOST_PP_BOOL(p(253, s)), p, o, s)
+# define BOOST_PP_WHILE_253(p, o, s) BOOST_PP_WHILE_253_C(BOOST_PP_BOOL(p(254, s)), p, o, s)
+# define BOOST_PP_WHILE_254(p, o, s) BOOST_PP_WHILE_254_C(BOOST_PP_BOOL(p(255, s)), p, o, s)
+# define BOOST_PP_WHILE_255(p, o, s) BOOST_PP_WHILE_255_C(BOOST_PP_BOOL(p(256, s)), p, o, s)
+# define BOOST_PP_WHILE_256(p, o, s) BOOST_PP_WHILE_256_C(BOOST_PP_BOOL(p(257, s)), p, o, s)
+#
+# define BOOST_PP_WHILE_1_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_2, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(2, s))
+# define BOOST_PP_WHILE_2_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_3, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(3, s))
+# define BOOST_PP_WHILE_3_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_4, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(4, s))
+# define BOOST_PP_WHILE_4_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_5, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(5, s))
+# define BOOST_PP_WHILE_5_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_6, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(6, s))
+# define BOOST_PP_WHILE_6_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_7, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(7, s))
+# define BOOST_PP_WHILE_7_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_8, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(8, s))
+# define BOOST_PP_WHILE_8_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_9, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(9, s))
+# define BOOST_PP_WHILE_9_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_10, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(10, s))
+# define BOOST_PP_WHILE_10_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_11, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(11, s))
+# define BOOST_PP_WHILE_11_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_12, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(12, s))
+# define BOOST_PP_WHILE_12_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_13, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(13, s))
+# define BOOST_PP_WHILE_13_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_14, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(14, s))
+# define BOOST_PP_WHILE_14_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_15, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(15, s))
+# define BOOST_PP_WHILE_15_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_16, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(16, s))
+# define BOOST_PP_WHILE_16_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_17, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(17, s))
+# define BOOST_PP_WHILE_17_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_18, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(18, s))
+# define BOOST_PP_WHILE_18_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_19, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(19, s))
+# define BOOST_PP_WHILE_19_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_20, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(20, s))
+# define BOOST_PP_WHILE_20_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_21, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(21, s))
+# define BOOST_PP_WHILE_21_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_22, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(22, s))
+# define BOOST_PP_WHILE_22_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_23, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(23, s))
+# define BOOST_PP_WHILE_23_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_24, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(24, s))
+# define BOOST_PP_WHILE_24_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_25, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(25, s))
+# define BOOST_PP_WHILE_25_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_26, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(26, s))
+# define BOOST_PP_WHILE_26_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_27, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(27, s))
+# define BOOST_PP_WHILE_27_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_28, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(28, s))
+# define BOOST_PP_WHILE_28_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_29, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(29, s))
+# define BOOST_PP_WHILE_29_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_30, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(30, s))
+# define BOOST_PP_WHILE_30_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_31, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(31, s))
+# define BOOST_PP_WHILE_31_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_32, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(32, s))
+# define BOOST_PP_WHILE_32_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_33, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(33, s))
+# define BOOST_PP_WHILE_33_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_34, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(34, s))
+# define BOOST_PP_WHILE_34_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_35, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(35, s))
+# define BOOST_PP_WHILE_35_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_36, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(36, s))
+# define BOOST_PP_WHILE_36_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_37, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(37, s))
+# define BOOST_PP_WHILE_37_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_38, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(38, s))
+# define BOOST_PP_WHILE_38_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_39, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(39, s))
+# define BOOST_PP_WHILE_39_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_40, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(40, s))
+# define BOOST_PP_WHILE_40_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_41, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(41, s))
+# define BOOST_PP_WHILE_41_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_42, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(42, s))
+# define BOOST_PP_WHILE_42_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_43, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(43, s))
+# define BOOST_PP_WHILE_43_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_44, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(44, s))
+# define BOOST_PP_WHILE_44_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_45, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(45, s))
+# define BOOST_PP_WHILE_45_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_46, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(46, s))
+# define BOOST_PP_WHILE_46_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_47, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(47, s))
+# define BOOST_PP_WHILE_47_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_48, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(48, s))
+# define BOOST_PP_WHILE_48_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_49, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(49, s))
+# define BOOST_PP_WHILE_49_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_50, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(50, s))
+# define BOOST_PP_WHILE_50_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_51, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(51, s))
+# define BOOST_PP_WHILE_51_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_52, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(52, s))
+# define BOOST_PP_WHILE_52_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_53, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(53, s))
+# define BOOST_PP_WHILE_53_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_54, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(54, s))
+# define BOOST_PP_WHILE_54_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_55, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(55, s))
+# define BOOST_PP_WHILE_55_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_56, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(56, s))
+# define BOOST_PP_WHILE_56_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_57, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(57, s))
+# define BOOST_PP_WHILE_57_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_58, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(58, s))
+# define BOOST_PP_WHILE_58_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_59, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(59, s))
+# define BOOST_PP_WHILE_59_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_60, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(60, s))
+# define BOOST_PP_WHILE_60_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_61, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(61, s))
+# define BOOST_PP_WHILE_61_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_62, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(62, s))
+# define BOOST_PP_WHILE_62_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_63, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(63, s))
+# define BOOST_PP_WHILE_63_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_64, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(64, s))
+# define BOOST_PP_WHILE_64_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_65, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(65, s))
+# define BOOST_PP_WHILE_65_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_66, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(66, s))
+# define BOOST_PP_WHILE_66_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_67, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(67, s))
+# define BOOST_PP_WHILE_67_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_68, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(68, s))
+# define BOOST_PP_WHILE_68_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_69, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(69, s))
+# define BOOST_PP_WHILE_69_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_70, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(70, s))
+# define BOOST_PP_WHILE_70_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_71, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(71, s))
+# define BOOST_PP_WHILE_71_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_72, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(72, s))
+# define BOOST_PP_WHILE_72_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_73, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(73, s))
+# define BOOST_PP_WHILE_73_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_74, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(74, s))
+# define BOOST_PP_WHILE_74_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_75, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(75, s))
+# define BOOST_PP_WHILE_75_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_76, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(76, s))
+# define BOOST_PP_WHILE_76_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_77, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(77, s))
+# define BOOST_PP_WHILE_77_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_78, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(78, s))
+# define BOOST_PP_WHILE_78_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_79, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(79, s))
+# define BOOST_PP_WHILE_79_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_80, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(80, s))
+# define BOOST_PP_WHILE_80_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_81, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(81, s))
+# define BOOST_PP_WHILE_81_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_82, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(82, s))
+# define BOOST_PP_WHILE_82_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_83, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(83, s))
+# define BOOST_PP_WHILE_83_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_84, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(84, s))
+# define BOOST_PP_WHILE_84_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_85, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(85, s))
+# define BOOST_PP_WHILE_85_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_86, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(86, s))
+# define BOOST_PP_WHILE_86_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_87, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(87, s))
+# define BOOST_PP_WHILE_87_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_88, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(88, s))
+# define BOOST_PP_WHILE_88_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_89, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(89, s))
+# define BOOST_PP_WHILE_89_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_90, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(90, s))
+# define BOOST_PP_WHILE_90_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_91, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(91, s))
+# define BOOST_PP_WHILE_91_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_92, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(92, s))
+# define BOOST_PP_WHILE_92_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_93, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(93, s))
+# define BOOST_PP_WHILE_93_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_94, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(94, s))
+# define BOOST_PP_WHILE_94_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_95, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(95, s))
+# define BOOST_PP_WHILE_95_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_96, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(96, s))
+# define BOOST_PP_WHILE_96_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_97, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(97, s))
+# define BOOST_PP_WHILE_97_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_98, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(98, s))
+# define BOOST_PP_WHILE_98_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_99, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(99, s))
+# define BOOST_PP_WHILE_99_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_100, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(100, s))
+# define BOOST_PP_WHILE_100_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_101, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(101, s))
+# define BOOST_PP_WHILE_101_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_102, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(102, s))
+# define BOOST_PP_WHILE_102_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_103, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(103, s))
+# define BOOST_PP_WHILE_103_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_104, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(104, s))
+# define BOOST_PP_WHILE_104_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_105, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(105, s))
+# define BOOST_PP_WHILE_105_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_106, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(106, s))
+# define BOOST_PP_WHILE_106_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_107, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(107, s))
+# define BOOST_PP_WHILE_107_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_108, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(108, s))
+# define BOOST_PP_WHILE_108_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_109, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(109, s))
+# define BOOST_PP_WHILE_109_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_110, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(110, s))
+# define BOOST_PP_WHILE_110_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_111, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(111, s))
+# define BOOST_PP_WHILE_111_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_112, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(112, s))
+# define BOOST_PP_WHILE_112_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_113, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(113, s))
+# define BOOST_PP_WHILE_113_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_114, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(114, s))
+# define BOOST_PP_WHILE_114_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_115, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(115, s))
+# define BOOST_PP_WHILE_115_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_116, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(116, s))
+# define BOOST_PP_WHILE_116_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_117, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(117, s))
+# define BOOST_PP_WHILE_117_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_118, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(118, s))
+# define BOOST_PP_WHILE_118_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_119, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(119, s))
+# define BOOST_PP_WHILE_119_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_120, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(120, s))
+# define BOOST_PP_WHILE_120_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_121, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(121, s))
+# define BOOST_PP_WHILE_121_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_122, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(122, s))
+# define BOOST_PP_WHILE_122_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_123, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(123, s))
+# define BOOST_PP_WHILE_123_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_124, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(124, s))
+# define BOOST_PP_WHILE_124_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_125, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(125, s))
+# define BOOST_PP_WHILE_125_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_126, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(126, s))
+# define BOOST_PP_WHILE_126_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_127, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(127, s))
+# define BOOST_PP_WHILE_127_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_128, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(128, s))
+# define BOOST_PP_WHILE_128_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_129, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(129, s))
+# define BOOST_PP_WHILE_129_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_130, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(130, s))
+# define BOOST_PP_WHILE_130_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_131, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(131, s))
+# define BOOST_PP_WHILE_131_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_132, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(132, s))
+# define BOOST_PP_WHILE_132_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_133, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(133, s))
+# define BOOST_PP_WHILE_133_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_134, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(134, s))
+# define BOOST_PP_WHILE_134_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_135, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(135, s))
+# define BOOST_PP_WHILE_135_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_136, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(136, s))
+# define BOOST_PP_WHILE_136_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_137, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(137, s))
+# define BOOST_PP_WHILE_137_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_138, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(138, s))
+# define BOOST_PP_WHILE_138_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_139, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(139, s))
+# define BOOST_PP_WHILE_139_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_140, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(140, s))
+# define BOOST_PP_WHILE_140_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_141, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(141, s))
+# define BOOST_PP_WHILE_141_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_142, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(142, s))
+# define BOOST_PP_WHILE_142_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_143, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(143, s))
+# define BOOST_PP_WHILE_143_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_144, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(144, s))
+# define BOOST_PP_WHILE_144_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_145, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(145, s))
+# define BOOST_PP_WHILE_145_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_146, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(146, s))
+# define BOOST_PP_WHILE_146_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_147, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(147, s))
+# define BOOST_PP_WHILE_147_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_148, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(148, s))
+# define BOOST_PP_WHILE_148_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_149, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(149, s))
+# define BOOST_PP_WHILE_149_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_150, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(150, s))
+# define BOOST_PP_WHILE_150_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_151, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(151, s))
+# define BOOST_PP_WHILE_151_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_152, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(152, s))
+# define BOOST_PP_WHILE_152_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_153, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(153, s))
+# define BOOST_PP_WHILE_153_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_154, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(154, s))
+# define BOOST_PP_WHILE_154_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_155, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(155, s))
+# define BOOST_PP_WHILE_155_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_156, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(156, s))
+# define BOOST_PP_WHILE_156_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_157, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(157, s))
+# define BOOST_PP_WHILE_157_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_158, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(158, s))
+# define BOOST_PP_WHILE_158_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_159, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(159, s))
+# define BOOST_PP_WHILE_159_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_160, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(160, s))
+# define BOOST_PP_WHILE_160_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_161, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(161, s))
+# define BOOST_PP_WHILE_161_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_162, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(162, s))
+# define BOOST_PP_WHILE_162_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_163, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(163, s))
+# define BOOST_PP_WHILE_163_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_164, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(164, s))
+# define BOOST_PP_WHILE_164_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_165, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(165, s))
+# define BOOST_PP_WHILE_165_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_166, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(166, s))
+# define BOOST_PP_WHILE_166_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_167, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(167, s))
+# define BOOST_PP_WHILE_167_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_168, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(168, s))
+# define BOOST_PP_WHILE_168_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_169, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(169, s))
+# define BOOST_PP_WHILE_169_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_170, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(170, s))
+# define BOOST_PP_WHILE_170_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_171, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(171, s))
+# define BOOST_PP_WHILE_171_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_172, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(172, s))
+# define BOOST_PP_WHILE_172_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_173, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(173, s))
+# define BOOST_PP_WHILE_173_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_174, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(174, s))
+# define BOOST_PP_WHILE_174_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_175, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(175, s))
+# define BOOST_PP_WHILE_175_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_176, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(176, s))
+# define BOOST_PP_WHILE_176_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_177, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(177, s))
+# define BOOST_PP_WHILE_177_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_178, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(178, s))
+# define BOOST_PP_WHILE_178_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_179, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(179, s))
+# define BOOST_PP_WHILE_179_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_180, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(180, s))
+# define BOOST_PP_WHILE_180_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_181, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(181, s))
+# define BOOST_PP_WHILE_181_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_182, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(182, s))
+# define BOOST_PP_WHILE_182_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_183, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(183, s))
+# define BOOST_PP_WHILE_183_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_184, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(184, s))
+# define BOOST_PP_WHILE_184_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_185, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(185, s))
+# define BOOST_PP_WHILE_185_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_186, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(186, s))
+# define BOOST_PP_WHILE_186_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_187, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(187, s))
+# define BOOST_PP_WHILE_187_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_188, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(188, s))
+# define BOOST_PP_WHILE_188_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_189, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(189, s))
+# define BOOST_PP_WHILE_189_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_190, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(190, s))
+# define BOOST_PP_WHILE_190_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_191, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(191, s))
+# define BOOST_PP_WHILE_191_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_192, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(192, s))
+# define BOOST_PP_WHILE_192_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_193, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(193, s))
+# define BOOST_PP_WHILE_193_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_194, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(194, s))
+# define BOOST_PP_WHILE_194_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_195, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(195, s))
+# define BOOST_PP_WHILE_195_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_196, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(196, s))
+# define BOOST_PP_WHILE_196_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_197, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(197, s))
+# define BOOST_PP_WHILE_197_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_198, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(198, s))
+# define BOOST_PP_WHILE_198_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_199, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(199, s))
+# define BOOST_PP_WHILE_199_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_200, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(200, s))
+# define BOOST_PP_WHILE_200_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_201, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(201, s))
+# define BOOST_PP_WHILE_201_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_202, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(202, s))
+# define BOOST_PP_WHILE_202_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_203, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(203, s))
+# define BOOST_PP_WHILE_203_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_204, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(204, s))
+# define BOOST_PP_WHILE_204_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_205, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(205, s))
+# define BOOST_PP_WHILE_205_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_206, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(206, s))
+# define BOOST_PP_WHILE_206_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_207, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(207, s))
+# define BOOST_PP_WHILE_207_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_208, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(208, s))
+# define BOOST_PP_WHILE_208_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_209, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(209, s))
+# define BOOST_PP_WHILE_209_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_210, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(210, s))
+# define BOOST_PP_WHILE_210_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_211, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(211, s))
+# define BOOST_PP_WHILE_211_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_212, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(212, s))
+# define BOOST_PP_WHILE_212_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_213, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(213, s))
+# define BOOST_PP_WHILE_213_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_214, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(214, s))
+# define BOOST_PP_WHILE_214_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_215, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(215, s))
+# define BOOST_PP_WHILE_215_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_216, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(216, s))
+# define BOOST_PP_WHILE_216_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_217, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(217, s))
+# define BOOST_PP_WHILE_217_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_218, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(218, s))
+# define BOOST_PP_WHILE_218_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_219, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(219, s))
+# define BOOST_PP_WHILE_219_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_220, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(220, s))
+# define BOOST_PP_WHILE_220_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_221, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(221, s))
+# define BOOST_PP_WHILE_221_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_222, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(222, s))
+# define BOOST_PP_WHILE_222_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_223, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(223, s))
+# define BOOST_PP_WHILE_223_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_224, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(224, s))
+# define BOOST_PP_WHILE_224_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_225, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(225, s))
+# define BOOST_PP_WHILE_225_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_226, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(226, s))
+# define BOOST_PP_WHILE_226_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_227, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(227, s))
+# define BOOST_PP_WHILE_227_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_228, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(228, s))
+# define BOOST_PP_WHILE_228_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_229, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(229, s))
+# define BOOST_PP_WHILE_229_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_230, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(230, s))
+# define BOOST_PP_WHILE_230_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_231, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(231, s))
+# define BOOST_PP_WHILE_231_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_232, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(232, s))
+# define BOOST_PP_WHILE_232_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_233, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(233, s))
+# define BOOST_PP_WHILE_233_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_234, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(234, s))
+# define BOOST_PP_WHILE_234_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_235, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(235, s))
+# define BOOST_PP_WHILE_235_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_236, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(236, s))
+# define BOOST_PP_WHILE_236_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_237, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(237, s))
+# define BOOST_PP_WHILE_237_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_238, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(238, s))
+# define BOOST_PP_WHILE_238_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_239, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(239, s))
+# define BOOST_PP_WHILE_239_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_240, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(240, s))
+# define BOOST_PP_WHILE_240_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_241, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(241, s))
+# define BOOST_PP_WHILE_241_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_242, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(242, s))
+# define BOOST_PP_WHILE_242_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_243, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(243, s))
+# define BOOST_PP_WHILE_243_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_244, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(244, s))
+# define BOOST_PP_WHILE_244_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_245, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(245, s))
+# define BOOST_PP_WHILE_245_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_246, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(246, s))
+# define BOOST_PP_WHILE_246_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_247, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(247, s))
+# define BOOST_PP_WHILE_247_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_248, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(248, s))
+# define BOOST_PP_WHILE_248_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_249, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(249, s))
+# define BOOST_PP_WHILE_249_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_250, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(250, s))
+# define BOOST_PP_WHILE_250_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_251, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(251, s))
+# define BOOST_PP_WHILE_251_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_252, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(252, s))
+# define BOOST_PP_WHILE_252_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_253, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(253, s))
+# define BOOST_PP_WHILE_253_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_254, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(254, s))
+# define BOOST_PP_WHILE_254_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_255, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(255, s))
+# define BOOST_PP_WHILE_255_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_256, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(256, s))
+# define BOOST_PP_WHILE_256_C(c, p, o, s) BOOST_PP_IIF(c, BOOST_PP_WHILE_257, s BOOST_PP_TUPLE_EAT_3)(p, o, BOOST_PP_IIF(c, o, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_2)(257, s))
+#
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/control/expr_if.hpp b/third_party/boost/boost/preprocessor/control/expr_if.hpp
new file mode 100644
index 0000000..0e1ab51
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/control/expr_if.hpp
@@ -0,0 +1,30 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_CONTROL_EXPR_IF_HPP
+# define BOOST_PREPROCESSOR_CONTROL_EXPR_IF_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/control/expr_iif.hpp>
+# include <boost/preprocessor/logical/bool.hpp>
+#
+# /* BOOST_PP_EXPR_IF */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_EXPR_IF(cond, expr) BOOST_PP_EXPR_IIF(BOOST_PP_BOOL(cond), expr)
+# else
+#    define BOOST_PP_EXPR_IF(cond, expr) BOOST_PP_EXPR_IF_I(cond, expr)
+#    define BOOST_PP_EXPR_IF_I(cond, expr) BOOST_PP_EXPR_IIF(BOOST_PP_BOOL(cond), expr)
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/control/expr_iif.hpp b/third_party/boost/boost/preprocessor/control/expr_iif.hpp
new file mode 100644
index 0000000..58f45a4
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/control/expr_iif.hpp
@@ -0,0 +1,31 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_CONTROL_EXPR_IIF_HPP
+# define BOOST_PREPROCESSOR_CONTROL_EXPR_IIF_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+#
+# /* BOOST_PP_EXPR_IIF */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#    define BOOST_PP_EXPR_IIF(bit, expr) BOOST_PP_EXPR_IIF_I(bit, expr)
+# else
+#    define BOOST_PP_EXPR_IIF(bit, expr) BOOST_PP_EXPR_IIF_OO((bit, expr))
+#    define BOOST_PP_EXPR_IIF_OO(par) BOOST_PP_EXPR_IIF_I ## par
+# endif
+#
+# define BOOST_PP_EXPR_IIF_I(bit, expr) BOOST_PP_EXPR_IIF_ ## bit(expr)
+#
+# define BOOST_PP_EXPR_IIF_0(expr)
+# define BOOST_PP_EXPR_IIF_1(expr) expr
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/control/if.hpp b/third_party/boost/boost/preprocessor/control/if.hpp
new file mode 100644
index 0000000..52cfc3d
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/control/if.hpp
@@ -0,0 +1,30 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_CONTROL_IF_HPP
+# define BOOST_PREPROCESSOR_CONTROL_IF_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/control/iif.hpp>
+# include <boost/preprocessor/logical/bool.hpp>
+#
+# /* BOOST_PP_IF */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_IF(cond, t, f) BOOST_PP_IIF(BOOST_PP_BOOL(cond), t, f)
+# else
+#    define BOOST_PP_IF(cond, t, f) BOOST_PP_IF_I(cond, t, f)
+#    define BOOST_PP_IF_I(cond, t, f) BOOST_PP_IIF(BOOST_PP_BOOL(cond), t, f)
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/control/iif.hpp b/third_party/boost/boost/preprocessor/control/iif.hpp
new file mode 100644
index 0000000..fd07817
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/control/iif.hpp
@@ -0,0 +1,34 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_CONTROL_IIF_HPP
+# define BOOST_PREPROCESSOR_CONTROL_IIF_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#    define BOOST_PP_IIF(bit, t, f) BOOST_PP_IIF_I(bit, t, f)
+# else
+#    define BOOST_PP_IIF(bit, t, f) BOOST_PP_IIF_OO((bit, t, f))
+#    define BOOST_PP_IIF_OO(par) BOOST_PP_IIF_I ## par
+# endif
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC()
+#    define BOOST_PP_IIF_I(bit, t, f) BOOST_PP_IIF_ ## bit(t, f)
+# else
+#    define BOOST_PP_IIF_I(bit, t, f) BOOST_PP_IIF_II(BOOST_PP_IIF_ ## bit(t, f))
+#    define BOOST_PP_IIF_II(id) id
+# endif
+#
+# define BOOST_PP_IIF_0(t, f) f
+# define BOOST_PP_IIF_1(t, f) t
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/control/while.hpp b/third_party/boost/boost/preprocessor/control/while.hpp
new file mode 100644
index 0000000..e8a65ff
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/control/while.hpp
@@ -0,0 +1,312 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_CONTROL_WHILE_HPP
+# define BOOST_PREPROCESSOR_CONTROL_WHILE_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/debug/error.hpp>
+# include <boost/preprocessor/detail/auto_rec.hpp>
+# include <boost/preprocessor/list/fold_left.hpp>
+# include <boost/preprocessor/list/fold_right.hpp>
+# include <boost/preprocessor/logical/bitand.hpp>
+#
+# /* BOOST_PP_WHILE */
+#
+# if 0
+#    define BOOST_PP_WHILE(pred, op, state)
+# endif
+#
+# define BOOST_PP_WHILE BOOST_PP_CAT(BOOST_PP_WHILE_, BOOST_PP_AUTO_REC(BOOST_PP_WHILE_P, 256))
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_WHILE_P(n) BOOST_PP_BITAND(BOOST_PP_CAT(BOOST_PP_WHILE_CHECK_, BOOST_PP_WHILE_ ## n(BOOST_PP_WHILE_F, BOOST_PP_NIL, BOOST_PP_NIL)), BOOST_PP_BITAND(BOOST_PP_CAT(BOOST_PP_LIST_FOLD_LEFT_CHECK_, BOOST_PP_LIST_FOLD_LEFT_ ## n(BOOST_PP_NIL, BOOST_PP_NIL, BOOST_PP_NIL)), BOOST_PP_CAT(BOOST_PP_LIST_FOLD_RIGHT_CHECK_, BOOST_PP_LIST_FOLD_RIGHT_ ## n(BOOST_PP_NIL, BOOST_PP_NIL, BOOST_PP_NIL))))
+# else
+#    define BOOST_PP_WHILE_P(n) BOOST_PP_BITAND(BOOST_PP_CAT(BOOST_PP_WHILE_CHECK_, BOOST_PP_WHILE_ ## n(BOOST_PP_WHILE_F, BOOST_PP_NIL, BOOST_PP_NIL)), BOOST_PP_CAT(BOOST_PP_LIST_FOLD_LEFT_CHECK_, BOOST_PP_LIST_FOLD_LEFT_ ## n(BOOST_PP_NIL, BOOST_PP_NIL, BOOST_PP_NIL)))
+# endif
+#
+# define BOOST_PP_WHILE_F(d, _) 0
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    include <boost/preprocessor/control/detail/edg/while.hpp>
+# elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC()
+#    include <boost/preprocessor/control/detail/msvc/while.hpp>
+# elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC()
+#    include <boost/preprocessor/control/detail/dmc/while.hpp>
+# else
+#    include <boost/preprocessor/control/detail/while.hpp>
+# endif
+#
+# define BOOST_PP_WHILE_257(p, o, s) BOOST_PP_ERROR(0x0001)
+#
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_NIL 1
+#
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_1(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_2(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_3(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_4(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_5(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_6(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_7(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_8(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_9(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_10(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_11(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_12(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_13(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_14(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_15(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_16(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_17(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_18(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_19(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_20(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_21(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_22(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_23(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_24(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_25(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_26(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_27(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_28(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_29(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_30(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_31(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_32(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_33(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_34(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_35(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_36(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_37(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_38(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_39(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_40(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_41(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_42(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_43(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_44(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_45(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_46(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_47(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_48(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_49(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_50(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_51(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_52(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_53(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_54(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_55(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_56(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_57(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_58(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_59(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_60(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_61(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_62(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_63(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_64(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_65(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_66(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_67(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_68(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_69(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_70(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_71(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_72(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_73(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_74(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_75(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_76(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_77(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_78(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_79(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_80(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_81(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_82(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_83(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_84(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_85(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_86(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_87(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_88(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_89(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_90(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_91(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_92(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_93(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_94(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_95(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_96(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_97(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_98(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_99(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_100(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_101(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_102(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_103(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_104(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_105(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_106(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_107(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_108(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_109(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_110(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_111(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_112(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_113(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_114(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_115(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_116(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_117(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_118(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_119(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_120(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_121(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_122(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_123(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_124(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_125(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_126(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_127(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_128(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_129(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_130(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_131(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_132(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_133(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_134(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_135(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_136(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_137(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_138(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_139(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_140(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_141(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_142(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_143(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_144(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_145(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_146(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_147(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_148(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_149(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_150(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_151(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_152(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_153(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_154(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_155(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_156(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_157(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_158(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_159(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_160(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_161(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_162(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_163(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_164(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_165(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_166(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_167(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_168(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_169(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_170(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_171(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_172(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_173(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_174(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_175(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_176(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_177(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_178(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_179(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_180(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_181(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_182(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_183(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_184(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_185(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_186(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_187(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_188(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_189(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_190(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_191(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_192(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_193(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_194(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_195(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_196(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_197(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_198(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_199(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_200(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_201(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_202(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_203(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_204(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_205(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_206(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_207(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_208(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_209(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_210(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_211(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_212(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_213(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_214(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_215(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_216(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_217(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_218(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_219(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_220(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_221(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_222(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_223(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_224(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_225(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_226(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_227(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_228(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_229(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_230(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_231(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_232(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_233(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_234(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_235(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_236(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_237(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_238(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_239(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_240(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_241(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_242(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_243(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_244(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_245(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_246(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_247(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_248(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_249(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_250(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_251(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_252(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_253(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_254(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_255(p, o, s) 0
+# define BOOST_PP_WHILE_CHECK_BOOST_PP_WHILE_256(p, o, s) 0
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/debug/error.hpp b/third_party/boost/boost/preprocessor/debug/error.hpp
new file mode 100644
index 0000000..c8ae5e7
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/debug/error.hpp
@@ -0,0 +1,33 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_DEBUG_ERROR_HPP
+# define BOOST_PREPROCESSOR_DEBUG_ERROR_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/config/config.hpp>
+#
+# /* BOOST_PP_ERROR */
+#
+# if BOOST_PP_CONFIG_ERRORS
+#    define BOOST_PP_ERROR(code) BOOST_PP_CAT(BOOST_PP_ERROR_, code)
+# endif
+#
+# define BOOST_PP_ERROR_0x0000 BOOST_PP_ERROR(0x0000, BOOST_PP_INDEX_OUT_OF_BOUNDS)
+# define BOOST_PP_ERROR_0x0001 BOOST_PP_ERROR(0x0001, BOOST_PP_WHILE_OVERFLOW)
+# define BOOST_PP_ERROR_0x0002 BOOST_PP_ERROR(0x0002, BOOST_PP_FOR_OVERFLOW)
+# define BOOST_PP_ERROR_0x0003 BOOST_PP_ERROR(0x0003, BOOST_PP_REPEAT_OVERFLOW)
+# define BOOST_PP_ERROR_0x0004 BOOST_PP_ERROR(0x0004, BOOST_PP_LIST_FOLD_OVERFLOW)
+# define BOOST_PP_ERROR_0x0005 BOOST_PP_ERROR(0x0005, BOOST_PP_SEQ_FOLD_OVERFLOW)
+# define BOOST_PP_ERROR_0x0006 BOOST_PP_ERROR(0x0006, BOOST_PP_ARITHMETIC_OVERFLOW)
+# define BOOST_PP_ERROR_0x0007 BOOST_PP_ERROR(0x0007, BOOST_PP_DIVISION_BY_ZERO)
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/detail/auto_rec.hpp b/third_party/boost/boost/preprocessor/detail/auto_rec.hpp
new file mode 100644
index 0000000..39de1d0
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/detail/auto_rec.hpp
@@ -0,0 +1,293 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# include <boost/preprocessor/config/config.hpp>
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC()
+#     include <boost/preprocessor/detail/dmc/auto_rec.hpp>
+# else
+#
+# ifndef BOOST_PREPROCESSOR_DETAIL_AUTO_REC_HPP
+# define BOOST_PREPROCESSOR_DETAIL_AUTO_REC_HPP
+#
+# include <boost/preprocessor/control/iif.hpp>
+#
+# /* BOOST_PP_AUTO_REC */
+#
+# define BOOST_PP_AUTO_REC(pred, n) BOOST_PP_NODE_ENTRY_ ## n(pred)
+#
+# define BOOST_PP_NODE_ENTRY_256(p) BOOST_PP_NODE_128(p)(p)(p)(p)(p)(p)(p)(p)
+# define BOOST_PP_NODE_ENTRY_128(p) BOOST_PP_NODE_64(p)(p)(p)(p)(p)(p)(p)
+# define BOOST_PP_NODE_ENTRY_64(p) BOOST_PP_NODE_32(p)(p)(p)(p)(p)(p)
+# define BOOST_PP_NODE_ENTRY_32(p) BOOST_PP_NODE_16(p)(p)(p)(p)(p)
+# define BOOST_PP_NODE_ENTRY_16(p) BOOST_PP_NODE_8(p)(p)(p)(p)
+# define BOOST_PP_NODE_ENTRY_8(p) BOOST_PP_NODE_4(p)(p)(p)
+# define BOOST_PP_NODE_ENTRY_4(p) BOOST_PP_NODE_2(p)(p)
+# define BOOST_PP_NODE_ENTRY_2(p) BOOST_PP_NODE_1(p)
+#
+# define BOOST_PP_NODE_128(p) BOOST_PP_IIF(p(128), BOOST_PP_NODE_64, BOOST_PP_NODE_192)
+#    define BOOST_PP_NODE_64(p) BOOST_PP_IIF(p(64), BOOST_PP_NODE_32, BOOST_PP_NODE_96)
+#        define BOOST_PP_NODE_32(p) BOOST_PP_IIF(p(32), BOOST_PP_NODE_16, BOOST_PP_NODE_48)
+#            define BOOST_PP_NODE_16(p) BOOST_PP_IIF(p(16), BOOST_PP_NODE_8, BOOST_PP_NODE_24)
+#                define BOOST_PP_NODE_8(p) BOOST_PP_IIF(p(8), BOOST_PP_NODE_4, BOOST_PP_NODE_12)
+#                    define BOOST_PP_NODE_4(p) BOOST_PP_IIF(p(4), BOOST_PP_NODE_2, BOOST_PP_NODE_6)
+#                        define BOOST_PP_NODE_2(p) BOOST_PP_IIF(p(2), BOOST_PP_NODE_1, BOOST_PP_NODE_3)
+#                            define BOOST_PP_NODE_1(p) BOOST_PP_IIF(p(1), 1, 2)
+#                            define BOOST_PP_NODE_3(p) BOOST_PP_IIF(p(3), 3, 4)
+#                        define BOOST_PP_NODE_6(p) BOOST_PP_IIF(p(6), BOOST_PP_NODE_5, BOOST_PP_NODE_7)
+#                            define BOOST_PP_NODE_5(p) BOOST_PP_IIF(p(5), 5, 6)
+#                            define BOOST_PP_NODE_7(p) BOOST_PP_IIF(p(7), 7, 8)
+#                    define BOOST_PP_NODE_12(p) BOOST_PP_IIF(p(12), BOOST_PP_NODE_10, BOOST_PP_NODE_14)
+#                        define BOOST_PP_NODE_10(p) BOOST_PP_IIF(p(10), BOOST_PP_NODE_9, BOOST_PP_NODE_11)
+#                            define BOOST_PP_NODE_9(p) BOOST_PP_IIF(p(9), 9, 10)
+#                            define BOOST_PP_NODE_11(p) BOOST_PP_IIF(p(11), 11, 12)
+#                        define BOOST_PP_NODE_14(p) BOOST_PP_IIF(p(14), BOOST_PP_NODE_13, BOOST_PP_NODE_15)
+#                            define BOOST_PP_NODE_13(p) BOOST_PP_IIF(p(13), 13, 14)
+#                            define BOOST_PP_NODE_15(p) BOOST_PP_IIF(p(15), 15, 16)
+#                define BOOST_PP_NODE_24(p) BOOST_PP_IIF(p(24), BOOST_PP_NODE_20, BOOST_PP_NODE_28)
+#                    define BOOST_PP_NODE_20(p) BOOST_PP_IIF(p(20), BOOST_PP_NODE_18, BOOST_PP_NODE_22)
+#                        define BOOST_PP_NODE_18(p) BOOST_PP_IIF(p(18), BOOST_PP_NODE_17, BOOST_PP_NODE_19)
+#                            define BOOST_PP_NODE_17(p) BOOST_PP_IIF(p(17), 17, 18)
+#                            define BOOST_PP_NODE_19(p) BOOST_PP_IIF(p(19), 19, 20)
+#                        define BOOST_PP_NODE_22(p) BOOST_PP_IIF(p(22), BOOST_PP_NODE_21, BOOST_PP_NODE_23)
+#                            define BOOST_PP_NODE_21(p) BOOST_PP_IIF(p(21), 21, 22)
+#                            define BOOST_PP_NODE_23(p) BOOST_PP_IIF(p(23), 23, 24)
+#                    define BOOST_PP_NODE_28(p) BOOST_PP_IIF(p(28), BOOST_PP_NODE_26, BOOST_PP_NODE_30)
+#                        define BOOST_PP_NODE_26(p) BOOST_PP_IIF(p(26), BOOST_PP_NODE_25, BOOST_PP_NODE_27)
+#                            define BOOST_PP_NODE_25(p) BOOST_PP_IIF(p(25), 25, 26)
+#                            define BOOST_PP_NODE_27(p) BOOST_PP_IIF(p(27), 27, 28)
+#                        define BOOST_PP_NODE_30(p) BOOST_PP_IIF(p(30), BOOST_PP_NODE_29, BOOST_PP_NODE_31)
+#                            define BOOST_PP_NODE_29(p) BOOST_PP_IIF(p(29), 29, 30)
+#                            define BOOST_PP_NODE_31(p) BOOST_PP_IIF(p(31), 31, 32)
+#            define BOOST_PP_NODE_48(p) BOOST_PP_IIF(p(48), BOOST_PP_NODE_40, BOOST_PP_NODE_56)
+#                define BOOST_PP_NODE_40(p) BOOST_PP_IIF(p(40), BOOST_PP_NODE_36, BOOST_PP_NODE_44)
+#                    define BOOST_PP_NODE_36(p) BOOST_PP_IIF(p(36), BOOST_PP_NODE_34, BOOST_PP_NODE_38)
+#                        define BOOST_PP_NODE_34(p) BOOST_PP_IIF(p(34), BOOST_PP_NODE_33, BOOST_PP_NODE_35)
+#                            define BOOST_PP_NODE_33(p) BOOST_PP_IIF(p(33), 33, 34)
+#                            define BOOST_PP_NODE_35(p) BOOST_PP_IIF(p(35), 35, 36)
+#                        define BOOST_PP_NODE_38(p) BOOST_PP_IIF(p(38), BOOST_PP_NODE_37, BOOST_PP_NODE_39)
+#                            define BOOST_PP_NODE_37(p) BOOST_PP_IIF(p(37), 37, 38)
+#                            define BOOST_PP_NODE_39(p) BOOST_PP_IIF(p(39), 39, 40)
+#                    define BOOST_PP_NODE_44(p) BOOST_PP_IIF(p(44), BOOST_PP_NODE_42, BOOST_PP_NODE_46)
+#                        define BOOST_PP_NODE_42(p) BOOST_PP_IIF(p(42), BOOST_PP_NODE_41, BOOST_PP_NODE_43)
+#                            define BOOST_PP_NODE_41(p) BOOST_PP_IIF(p(41), 41, 42)
+#                            define BOOST_PP_NODE_43(p) BOOST_PP_IIF(p(43), 43, 44)
+#                        define BOOST_PP_NODE_46(p) BOOST_PP_IIF(p(46), BOOST_PP_NODE_45, BOOST_PP_NODE_47)
+#                            define BOOST_PP_NODE_45(p) BOOST_PP_IIF(p(45), 45, 46)
+#                            define BOOST_PP_NODE_47(p) BOOST_PP_IIF(p(47), 47, 48)
+#                define BOOST_PP_NODE_56(p) BOOST_PP_IIF(p(56), BOOST_PP_NODE_52, BOOST_PP_NODE_60)
+#                    define BOOST_PP_NODE_52(p) BOOST_PP_IIF(p(52), BOOST_PP_NODE_50, BOOST_PP_NODE_54)
+#                        define BOOST_PP_NODE_50(p) BOOST_PP_IIF(p(50), BOOST_PP_NODE_49, BOOST_PP_NODE_51)
+#                            define BOOST_PP_NODE_49(p) BOOST_PP_IIF(p(49), 49, 50)
+#                            define BOOST_PP_NODE_51(p) BOOST_PP_IIF(p(51), 51, 52)
+#                        define BOOST_PP_NODE_54(p) BOOST_PP_IIF(p(54), BOOST_PP_NODE_53, BOOST_PP_NODE_55)
+#                            define BOOST_PP_NODE_53(p) BOOST_PP_IIF(p(53), 53, 54)
+#                            define BOOST_PP_NODE_55(p) BOOST_PP_IIF(p(55), 55, 56)
+#                    define BOOST_PP_NODE_60(p) BOOST_PP_IIF(p(60), BOOST_PP_NODE_58, BOOST_PP_NODE_62)
+#                        define BOOST_PP_NODE_58(p) BOOST_PP_IIF(p(58), BOOST_PP_NODE_57, BOOST_PP_NODE_59)
+#                            define BOOST_PP_NODE_57(p) BOOST_PP_IIF(p(57), 57, 58)
+#                            define BOOST_PP_NODE_59(p) BOOST_PP_IIF(p(59), 59, 60)
+#                        define BOOST_PP_NODE_62(p) BOOST_PP_IIF(p(62), BOOST_PP_NODE_61, BOOST_PP_NODE_63)
+#                            define BOOST_PP_NODE_61(p) BOOST_PP_IIF(p(61), 61, 62)
+#                            define BOOST_PP_NODE_63(p) BOOST_PP_IIF(p(63), 63, 64)
+#        define BOOST_PP_NODE_96(p) BOOST_PP_IIF(p(96), BOOST_PP_NODE_80, BOOST_PP_NODE_112)
+#            define BOOST_PP_NODE_80(p) BOOST_PP_IIF(p(80), BOOST_PP_NODE_72, BOOST_PP_NODE_88)
+#                define BOOST_PP_NODE_72(p) BOOST_PP_IIF(p(72), BOOST_PP_NODE_68, BOOST_PP_NODE_76)
+#                    define BOOST_PP_NODE_68(p) BOOST_PP_IIF(p(68), BOOST_PP_NODE_66, BOOST_PP_NODE_70)
+#                        define BOOST_PP_NODE_66(p) BOOST_PP_IIF(p(66), BOOST_PP_NODE_65, BOOST_PP_NODE_67)
+#                            define BOOST_PP_NODE_65(p) BOOST_PP_IIF(p(65), 65, 66)
+#                            define BOOST_PP_NODE_67(p) BOOST_PP_IIF(p(67), 67, 68)
+#                        define BOOST_PP_NODE_70(p) BOOST_PP_IIF(p(70), BOOST_PP_NODE_69, BOOST_PP_NODE_71)
+#                            define BOOST_PP_NODE_69(p) BOOST_PP_IIF(p(69), 69, 70)
+#                            define BOOST_PP_NODE_71(p) BOOST_PP_IIF(p(71), 71, 72)
+#                    define BOOST_PP_NODE_76(p) BOOST_PP_IIF(p(76), BOOST_PP_NODE_74, BOOST_PP_NODE_78)
+#                        define BOOST_PP_NODE_74(p) BOOST_PP_IIF(p(74), BOOST_PP_NODE_73, BOOST_PP_NODE_75)
+#                            define BOOST_PP_NODE_73(p) BOOST_PP_IIF(p(73), 73, 74)
+#                            define BOOST_PP_NODE_75(p) BOOST_PP_IIF(p(75), 75, 76)
+#                        define BOOST_PP_NODE_78(p) BOOST_PP_IIF(p(78), BOOST_PP_NODE_77, BOOST_PP_NODE_79)
+#                            define BOOST_PP_NODE_77(p) BOOST_PP_IIF(p(77), 77, 78)
+#                            define BOOST_PP_NODE_79(p) BOOST_PP_IIF(p(79), 79, 80)
+#                define BOOST_PP_NODE_88(p) BOOST_PP_IIF(p(88), BOOST_PP_NODE_84, BOOST_PP_NODE_92)
+#                    define BOOST_PP_NODE_84(p) BOOST_PP_IIF(p(84), BOOST_PP_NODE_82, BOOST_PP_NODE_86)
+#                        define BOOST_PP_NODE_82(p) BOOST_PP_IIF(p(82), BOOST_PP_NODE_81, BOOST_PP_NODE_83)
+#                            define BOOST_PP_NODE_81(p) BOOST_PP_IIF(p(81), 81, 82)
+#                            define BOOST_PP_NODE_83(p) BOOST_PP_IIF(p(83), 83, 84)
+#                        define BOOST_PP_NODE_86(p) BOOST_PP_IIF(p(86), BOOST_PP_NODE_85, BOOST_PP_NODE_87)
+#                            define BOOST_PP_NODE_85(p) BOOST_PP_IIF(p(85), 85, 86)
+#                            define BOOST_PP_NODE_87(p) BOOST_PP_IIF(p(87), 87, 88)
+#                    define BOOST_PP_NODE_92(p) BOOST_PP_IIF(p(92), BOOST_PP_NODE_90, BOOST_PP_NODE_94)
+#                        define BOOST_PP_NODE_90(p) BOOST_PP_IIF(p(90), BOOST_PP_NODE_89, BOOST_PP_NODE_91)
+#                            define BOOST_PP_NODE_89(p) BOOST_PP_IIF(p(89), 89, 90)
+#                            define BOOST_PP_NODE_91(p) BOOST_PP_IIF(p(91), 91, 92)
+#                        define BOOST_PP_NODE_94(p) BOOST_PP_IIF(p(94), BOOST_PP_NODE_93, BOOST_PP_NODE_95)
+#                            define BOOST_PP_NODE_93(p) BOOST_PP_IIF(p(93), 93, 94)
+#                            define BOOST_PP_NODE_95(p) BOOST_PP_IIF(p(95), 95, 96)
+#            define BOOST_PP_NODE_112(p) BOOST_PP_IIF(p(112), BOOST_PP_NODE_104, BOOST_PP_NODE_120)
+#                define BOOST_PP_NODE_104(p) BOOST_PP_IIF(p(104), BOOST_PP_NODE_100, BOOST_PP_NODE_108)
+#                    define BOOST_PP_NODE_100(p) BOOST_PP_IIF(p(100), BOOST_PP_NODE_98, BOOST_PP_NODE_102)
+#                        define BOOST_PP_NODE_98(p) BOOST_PP_IIF(p(98), BOOST_PP_NODE_97, BOOST_PP_NODE_99)
+#                            define BOOST_PP_NODE_97(p) BOOST_PP_IIF(p(97), 97, 98)
+#                            define BOOST_PP_NODE_99(p) BOOST_PP_IIF(p(99), 99, 100)
+#                        define BOOST_PP_NODE_102(p) BOOST_PP_IIF(p(102), BOOST_PP_NODE_101, BOOST_PP_NODE_103)
+#                            define BOOST_PP_NODE_101(p) BOOST_PP_IIF(p(101), 101, 102)
+#                            define BOOST_PP_NODE_103(p) BOOST_PP_IIF(p(103), 103, 104)
+#                    define BOOST_PP_NODE_108(p) BOOST_PP_IIF(p(108), BOOST_PP_NODE_106, BOOST_PP_NODE_110)
+#                        define BOOST_PP_NODE_106(p) BOOST_PP_IIF(p(106), BOOST_PP_NODE_105, BOOST_PP_NODE_107)
+#                            define BOOST_PP_NODE_105(p) BOOST_PP_IIF(p(105), 105, 106)
+#                            define BOOST_PP_NODE_107(p) BOOST_PP_IIF(p(107), 107, 108)
+#                        define BOOST_PP_NODE_110(p) BOOST_PP_IIF(p(110), BOOST_PP_NODE_109, BOOST_PP_NODE_111)
+#                            define BOOST_PP_NODE_109(p) BOOST_PP_IIF(p(109), 109, 110)
+#                            define BOOST_PP_NODE_111(p) BOOST_PP_IIF(p(111), 111, 112)
+#                define BOOST_PP_NODE_120(p) BOOST_PP_IIF(p(120), BOOST_PP_NODE_116, BOOST_PP_NODE_124)
+#                    define BOOST_PP_NODE_116(p) BOOST_PP_IIF(p(116), BOOST_PP_NODE_114, BOOST_PP_NODE_118)
+#                        define BOOST_PP_NODE_114(p) BOOST_PP_IIF(p(114), BOOST_PP_NODE_113, BOOST_PP_NODE_115)
+#                            define BOOST_PP_NODE_113(p) BOOST_PP_IIF(p(113), 113, 114)
+#                            define BOOST_PP_NODE_115(p) BOOST_PP_IIF(p(115), 115, 116)
+#                        define BOOST_PP_NODE_118(p) BOOST_PP_IIF(p(118), BOOST_PP_NODE_117, BOOST_PP_NODE_119)
+#                            define BOOST_PP_NODE_117(p) BOOST_PP_IIF(p(117), 117, 118)
+#                            define BOOST_PP_NODE_119(p) BOOST_PP_IIF(p(119), 119, 120)
+#                    define BOOST_PP_NODE_124(p) BOOST_PP_IIF(p(124), BOOST_PP_NODE_122, BOOST_PP_NODE_126)
+#                        define BOOST_PP_NODE_122(p) BOOST_PP_IIF(p(122), BOOST_PP_NODE_121, BOOST_PP_NODE_123)
+#                            define BOOST_PP_NODE_121(p) BOOST_PP_IIF(p(121), 121, 122)
+#                            define BOOST_PP_NODE_123(p) BOOST_PP_IIF(p(123), 123, 124)
+#                        define BOOST_PP_NODE_126(p) BOOST_PP_IIF(p(126), BOOST_PP_NODE_125, BOOST_PP_NODE_127)
+#                            define BOOST_PP_NODE_125(p) BOOST_PP_IIF(p(125), 125, 126)
+#                            define BOOST_PP_NODE_127(p) BOOST_PP_IIF(p(127), 127, 128)
+#    define BOOST_PP_NODE_192(p) BOOST_PP_IIF(p(192), BOOST_PP_NODE_160, BOOST_PP_NODE_224)
+#        define BOOST_PP_NODE_160(p) BOOST_PP_IIF(p(160), BOOST_PP_NODE_144, BOOST_PP_NODE_176)
+#            define BOOST_PP_NODE_144(p) BOOST_PP_IIF(p(144), BOOST_PP_NODE_136, BOOST_PP_NODE_152)
+#                define BOOST_PP_NODE_136(p) BOOST_PP_IIF(p(136), BOOST_PP_NODE_132, BOOST_PP_NODE_140)
+#                    define BOOST_PP_NODE_132(p) BOOST_PP_IIF(p(132), BOOST_PP_NODE_130, BOOST_PP_NODE_134)
+#                        define BOOST_PP_NODE_130(p) BOOST_PP_IIF(p(130), BOOST_PP_NODE_129, BOOST_PP_NODE_131)
+#                            define BOOST_PP_NODE_129(p) BOOST_PP_IIF(p(129), 129, 130)
+#                            define BOOST_PP_NODE_131(p) BOOST_PP_IIF(p(131), 131, 132)
+#                        define BOOST_PP_NODE_134(p) BOOST_PP_IIF(p(134), BOOST_PP_NODE_133, BOOST_PP_NODE_135)
+#                            define BOOST_PP_NODE_133(p) BOOST_PP_IIF(p(133), 133, 134)
+#                            define BOOST_PP_NODE_135(p) BOOST_PP_IIF(p(135), 135, 136)
+#                    define BOOST_PP_NODE_140(p) BOOST_PP_IIF(p(140), BOOST_PP_NODE_138, BOOST_PP_NODE_142)
+#                        define BOOST_PP_NODE_138(p) BOOST_PP_IIF(p(138), BOOST_PP_NODE_137, BOOST_PP_NODE_139)
+#                            define BOOST_PP_NODE_137(p) BOOST_PP_IIF(p(137), 137, 138)
+#                            define BOOST_PP_NODE_139(p) BOOST_PP_IIF(p(139), 139, 140)
+#                        define BOOST_PP_NODE_142(p) BOOST_PP_IIF(p(142), BOOST_PP_NODE_141, BOOST_PP_NODE_143)
+#                            define BOOST_PP_NODE_141(p) BOOST_PP_IIF(p(141), 141, 142)
+#                            define BOOST_PP_NODE_143(p) BOOST_PP_IIF(p(143), 143, 144)
+#                define BOOST_PP_NODE_152(p) BOOST_PP_IIF(p(152), BOOST_PP_NODE_148, BOOST_PP_NODE_156)
+#                    define BOOST_PP_NODE_148(p) BOOST_PP_IIF(p(148), BOOST_PP_NODE_146, BOOST_PP_NODE_150)
+#                        define BOOST_PP_NODE_146(p) BOOST_PP_IIF(p(146), BOOST_PP_NODE_145, BOOST_PP_NODE_147)
+#                            define BOOST_PP_NODE_145(p) BOOST_PP_IIF(p(145), 145, 146)
+#                            define BOOST_PP_NODE_147(p) BOOST_PP_IIF(p(147), 147, 148)
+#                        define BOOST_PP_NODE_150(p) BOOST_PP_IIF(p(150), BOOST_PP_NODE_149, BOOST_PP_NODE_151)
+#                            define BOOST_PP_NODE_149(p) BOOST_PP_IIF(p(149), 149, 150)
+#                            define BOOST_PP_NODE_151(p) BOOST_PP_IIF(p(151), 151, 152)
+#                    define BOOST_PP_NODE_156(p) BOOST_PP_IIF(p(156), BOOST_PP_NODE_154, BOOST_PP_NODE_158)
+#                        define BOOST_PP_NODE_154(p) BOOST_PP_IIF(p(154), BOOST_PP_NODE_153, BOOST_PP_NODE_155)
+#                            define BOOST_PP_NODE_153(p) BOOST_PP_IIF(p(153), 153, 154)
+#                            define BOOST_PP_NODE_155(p) BOOST_PP_IIF(p(155), 155, 156)
+#                        define BOOST_PP_NODE_158(p) BOOST_PP_IIF(p(158), BOOST_PP_NODE_157, BOOST_PP_NODE_159)
+#                            define BOOST_PP_NODE_157(p) BOOST_PP_IIF(p(157), 157, 158)
+#                            define BOOST_PP_NODE_159(p) BOOST_PP_IIF(p(159), 159, 160)
+#            define BOOST_PP_NODE_176(p) BOOST_PP_IIF(p(176), BOOST_PP_NODE_168, BOOST_PP_NODE_184)
+#                define BOOST_PP_NODE_168(p) BOOST_PP_IIF(p(168), BOOST_PP_NODE_164, BOOST_PP_NODE_172)
+#                    define BOOST_PP_NODE_164(p) BOOST_PP_IIF(p(164), BOOST_PP_NODE_162, BOOST_PP_NODE_166)
+#                        define BOOST_PP_NODE_162(p) BOOST_PP_IIF(p(162), BOOST_PP_NODE_161, BOOST_PP_NODE_163)
+#                            define BOOST_PP_NODE_161(p) BOOST_PP_IIF(p(161), 161, 162)
+#                            define BOOST_PP_NODE_163(p) BOOST_PP_IIF(p(163), 163, 164)
+#                        define BOOST_PP_NODE_166(p) BOOST_PP_IIF(p(166), BOOST_PP_NODE_165, BOOST_PP_NODE_167)
+#                            define BOOST_PP_NODE_165(p) BOOST_PP_IIF(p(165), 165, 166)
+#                            define BOOST_PP_NODE_167(p) BOOST_PP_IIF(p(167), 167, 168)
+#                    define BOOST_PP_NODE_172(p) BOOST_PP_IIF(p(172), BOOST_PP_NODE_170, BOOST_PP_NODE_174)
+#                        define BOOST_PP_NODE_170(p) BOOST_PP_IIF(p(170), BOOST_PP_NODE_169, BOOST_PP_NODE_171)
+#                            define BOOST_PP_NODE_169(p) BOOST_PP_IIF(p(169), 169, 170)
+#                            define BOOST_PP_NODE_171(p) BOOST_PP_IIF(p(171), 171, 172)
+#                        define BOOST_PP_NODE_174(p) BOOST_PP_IIF(p(174), BOOST_PP_NODE_173, BOOST_PP_NODE_175)
+#                            define BOOST_PP_NODE_173(p) BOOST_PP_IIF(p(173), 173, 174)
+#                            define BOOST_PP_NODE_175(p) BOOST_PP_IIF(p(175), 175, 176)
+#                define BOOST_PP_NODE_184(p) BOOST_PP_IIF(p(184), BOOST_PP_NODE_180, BOOST_PP_NODE_188)
+#                    define BOOST_PP_NODE_180(p) BOOST_PP_IIF(p(180), BOOST_PP_NODE_178, BOOST_PP_NODE_182)
+#                        define BOOST_PP_NODE_178(p) BOOST_PP_IIF(p(178), BOOST_PP_NODE_177, BOOST_PP_NODE_179)
+#                            define BOOST_PP_NODE_177(p) BOOST_PP_IIF(p(177), 177, 178)
+#                            define BOOST_PP_NODE_179(p) BOOST_PP_IIF(p(179), 179, 180)
+#                        define BOOST_PP_NODE_182(p) BOOST_PP_IIF(p(182), BOOST_PP_NODE_181, BOOST_PP_NODE_183)
+#                            define BOOST_PP_NODE_181(p) BOOST_PP_IIF(p(181), 181, 182)
+#                            define BOOST_PP_NODE_183(p) BOOST_PP_IIF(p(183), 183, 184)
+#                    define BOOST_PP_NODE_188(p) BOOST_PP_IIF(p(188), BOOST_PP_NODE_186, BOOST_PP_NODE_190)
+#                        define BOOST_PP_NODE_186(p) BOOST_PP_IIF(p(186), BOOST_PP_NODE_185, BOOST_PP_NODE_187)
+#                            define BOOST_PP_NODE_185(p) BOOST_PP_IIF(p(185), 185, 186)
+#                            define BOOST_PP_NODE_187(p) BOOST_PP_IIF(p(187), 187, 188)
+#                        define BOOST_PP_NODE_190(p) BOOST_PP_IIF(p(190), BOOST_PP_NODE_189, BOOST_PP_NODE_191)
+#                            define BOOST_PP_NODE_189(p) BOOST_PP_IIF(p(189), 189, 190)
+#                            define BOOST_PP_NODE_191(p) BOOST_PP_IIF(p(191), 191, 192)
+#        define BOOST_PP_NODE_224(p) BOOST_PP_IIF(p(224), BOOST_PP_NODE_208, BOOST_PP_NODE_240)
+#            define BOOST_PP_NODE_208(p) BOOST_PP_IIF(p(208), BOOST_PP_NODE_200, BOOST_PP_NODE_216)
+#                define BOOST_PP_NODE_200(p) BOOST_PP_IIF(p(200), BOOST_PP_NODE_196, BOOST_PP_NODE_204)
+#                    define BOOST_PP_NODE_196(p) BOOST_PP_IIF(p(196), BOOST_PP_NODE_194, BOOST_PP_NODE_198)
+#                        define BOOST_PP_NODE_194(p) BOOST_PP_IIF(p(194), BOOST_PP_NODE_193, BOOST_PP_NODE_195)
+#                            define BOOST_PP_NODE_193(p) BOOST_PP_IIF(p(193), 193, 194)
+#                            define BOOST_PP_NODE_195(p) BOOST_PP_IIF(p(195), 195, 196)
+#                        define BOOST_PP_NODE_198(p) BOOST_PP_IIF(p(198), BOOST_PP_NODE_197, BOOST_PP_NODE_199)
+#                            define BOOST_PP_NODE_197(p) BOOST_PP_IIF(p(197), 197, 198)
+#                            define BOOST_PP_NODE_199(p) BOOST_PP_IIF(p(199), 199, 200)
+#                    define BOOST_PP_NODE_204(p) BOOST_PP_IIF(p(204), BOOST_PP_NODE_202, BOOST_PP_NODE_206)
+#                        define BOOST_PP_NODE_202(p) BOOST_PP_IIF(p(202), BOOST_PP_NODE_201, BOOST_PP_NODE_203)
+#                            define BOOST_PP_NODE_201(p) BOOST_PP_IIF(p(201), 201, 202)
+#                            define BOOST_PP_NODE_203(p) BOOST_PP_IIF(p(203), 203, 204)
+#                        define BOOST_PP_NODE_206(p) BOOST_PP_IIF(p(206), BOOST_PP_NODE_205, BOOST_PP_NODE_207)
+#                            define BOOST_PP_NODE_205(p) BOOST_PP_IIF(p(205), 205, 206)
+#                            define BOOST_PP_NODE_207(p) BOOST_PP_IIF(p(207), 207, 208)
+#                define BOOST_PP_NODE_216(p) BOOST_PP_IIF(p(216), BOOST_PP_NODE_212, BOOST_PP_NODE_220)
+#                    define BOOST_PP_NODE_212(p) BOOST_PP_IIF(p(212), BOOST_PP_NODE_210, BOOST_PP_NODE_214)
+#                        define BOOST_PP_NODE_210(p) BOOST_PP_IIF(p(210), BOOST_PP_NODE_209, BOOST_PP_NODE_211)
+#                            define BOOST_PP_NODE_209(p) BOOST_PP_IIF(p(209), 209, 210)
+#                            define BOOST_PP_NODE_211(p) BOOST_PP_IIF(p(211), 211, 212)
+#                        define BOOST_PP_NODE_214(p) BOOST_PP_IIF(p(214), BOOST_PP_NODE_213, BOOST_PP_NODE_215)
+#                            define BOOST_PP_NODE_213(p) BOOST_PP_IIF(p(213), 213, 214)
+#                            define BOOST_PP_NODE_215(p) BOOST_PP_IIF(p(215), 215, 216)
+#                    define BOOST_PP_NODE_220(p) BOOST_PP_IIF(p(220), BOOST_PP_NODE_218, BOOST_PP_NODE_222)
+#                        define BOOST_PP_NODE_218(p) BOOST_PP_IIF(p(218), BOOST_PP_NODE_217, BOOST_PP_NODE_219)
+#                            define BOOST_PP_NODE_217(p) BOOST_PP_IIF(p(217), 217, 218)
+#                            define BOOST_PP_NODE_219(p) BOOST_PP_IIF(p(219), 219, 220)
+#                        define BOOST_PP_NODE_222(p) BOOST_PP_IIF(p(222), BOOST_PP_NODE_221, BOOST_PP_NODE_223)
+#                            define BOOST_PP_NODE_221(p) BOOST_PP_IIF(p(221), 221, 222)
+#                            define BOOST_PP_NODE_223(p) BOOST_PP_IIF(p(223), 223, 224)
+#            define BOOST_PP_NODE_240(p) BOOST_PP_IIF(p(240), BOOST_PP_NODE_232, BOOST_PP_NODE_248)
+#                define BOOST_PP_NODE_232(p) BOOST_PP_IIF(p(232), BOOST_PP_NODE_228, BOOST_PP_NODE_236)
+#                    define BOOST_PP_NODE_228(p) BOOST_PP_IIF(p(228), BOOST_PP_NODE_226, BOOST_PP_NODE_230)
+#                        define BOOST_PP_NODE_226(p) BOOST_PP_IIF(p(226), BOOST_PP_NODE_225, BOOST_PP_NODE_227)
+#                            define BOOST_PP_NODE_225(p) BOOST_PP_IIF(p(225), 225, 226)
+#                            define BOOST_PP_NODE_227(p) BOOST_PP_IIF(p(227), 227, 228)
+#                        define BOOST_PP_NODE_230(p) BOOST_PP_IIF(p(230), BOOST_PP_NODE_229, BOOST_PP_NODE_231)
+#                            define BOOST_PP_NODE_229(p) BOOST_PP_IIF(p(229), 229, 230)
+#                            define BOOST_PP_NODE_231(p) BOOST_PP_IIF(p(231), 231, 232)
+#                    define BOOST_PP_NODE_236(p) BOOST_PP_IIF(p(236), BOOST_PP_NODE_234, BOOST_PP_NODE_238)
+#                        define BOOST_PP_NODE_234(p) BOOST_PP_IIF(p(234), BOOST_PP_NODE_233, BOOST_PP_NODE_235)
+#                            define BOOST_PP_NODE_233(p) BOOST_PP_IIF(p(233), 233, 234)
+#                            define BOOST_PP_NODE_235(p) BOOST_PP_IIF(p(235), 235, 236)
+#                        define BOOST_PP_NODE_238(p) BOOST_PP_IIF(p(238), BOOST_PP_NODE_237, BOOST_PP_NODE_239)
+#                            define BOOST_PP_NODE_237(p) BOOST_PP_IIF(p(237), 237, 238)
+#                            define BOOST_PP_NODE_239(p) BOOST_PP_IIF(p(239), 239, 240)
+#                define BOOST_PP_NODE_248(p) BOOST_PP_IIF(p(248), BOOST_PP_NODE_244, BOOST_PP_NODE_252)
+#                    define BOOST_PP_NODE_244(p) BOOST_PP_IIF(p(244), BOOST_PP_NODE_242, BOOST_PP_NODE_246)
+#                        define BOOST_PP_NODE_242(p) BOOST_PP_IIF(p(242), BOOST_PP_NODE_241, BOOST_PP_NODE_243)
+#                            define BOOST_PP_NODE_241(p) BOOST_PP_IIF(p(241), 241, 242)
+#                            define BOOST_PP_NODE_243(p) BOOST_PP_IIF(p(243), 243, 244)
+#                        define BOOST_PP_NODE_246(p) BOOST_PP_IIF(p(246), BOOST_PP_NODE_245, BOOST_PP_NODE_247)
+#                            define BOOST_PP_NODE_245(p) BOOST_PP_IIF(p(245), 245, 246)
+#                            define BOOST_PP_NODE_247(p) BOOST_PP_IIF(p(247), 247, 248)
+#                    define BOOST_PP_NODE_252(p) BOOST_PP_IIF(p(252), BOOST_PP_NODE_250, BOOST_PP_NODE_254)
+#                        define BOOST_PP_NODE_250(p) BOOST_PP_IIF(p(250), BOOST_PP_NODE_249, BOOST_PP_NODE_251)
+#                            define BOOST_PP_NODE_249(p) BOOST_PP_IIF(p(249), 249, 250)
+#                            define BOOST_PP_NODE_251(p) BOOST_PP_IIF(p(251), 251, 252)
+#                        define BOOST_PP_NODE_254(p) BOOST_PP_IIF(p(254), BOOST_PP_NODE_253, BOOST_PP_NODE_255)
+#                            define BOOST_PP_NODE_253(p) BOOST_PP_IIF(p(253), 253, 254)
+#                            define BOOST_PP_NODE_255(p) BOOST_PP_IIF(p(255), 255, 256)
+#
+# endif
+# endif
diff --git a/third_party/boost/boost/preprocessor/detail/check.hpp b/third_party/boost/boost/preprocessor/detail/check.hpp
new file mode 100644
index 0000000..63f8ff9
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/detail/check.hpp
@@ -0,0 +1,48 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_DETAIL_CHECK_HPP
+# define BOOST_PREPROCESSOR_DETAIL_CHECK_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/config/config.hpp>
+#
+# /* BOOST_PP_CHECK */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#    define BOOST_PP_CHECK(x, type) BOOST_PP_CHECK_D(x, type)
+# else
+#    define BOOST_PP_CHECK(x, type) BOOST_PP_CHECK_OO((x, type))
+#    define BOOST_PP_CHECK_OO(par) BOOST_PP_CHECK_D ## par
+# endif
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC() && ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC()
+#    define BOOST_PP_CHECK_D(x, type) BOOST_PP_CHECK_1(BOOST_PP_CAT(BOOST_PP_CHECK_RESULT_, type x))
+#    define BOOST_PP_CHECK_1(chk) BOOST_PP_CHECK_2(chk)
+#    define BOOST_PP_CHECK_2(res, _) res
+# elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC()
+#    define BOOST_PP_CHECK_D(x, type) BOOST_PP_CHECK_1(type x)
+#    define BOOST_PP_CHECK_1(chk) BOOST_PP_CHECK_2(chk)
+#    define BOOST_PP_CHECK_2(chk) BOOST_PP_CHECK_3((BOOST_PP_CHECK_RESULT_ ## chk))
+#    define BOOST_PP_CHECK_3(im) BOOST_PP_CHECK_5(BOOST_PP_CHECK_4 im)
+#    define BOOST_PP_CHECK_4(res, _) res
+#    define BOOST_PP_CHECK_5(res) res
+# else /* DMC */
+#    define BOOST_PP_CHECK_D(x, type) BOOST_PP_CHECK_OO((type x))
+#    define BOOST_PP_CHECK_OO(par) BOOST_PP_CHECK_0 ## par
+#    define BOOST_PP_CHECK_0(chk) BOOST_PP_CHECK_1(BOOST_PP_CAT(BOOST_PP_CHECK_RESULT_, chk))
+#    define BOOST_PP_CHECK_1(chk) BOOST_PP_CHECK_2(chk)
+#    define BOOST_PP_CHECK_2(res, _) res
+# endif
+#
+# define BOOST_PP_CHECK_RESULT_1 1, BOOST_PP_NIL
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/detail/is_binary.hpp b/third_party/boost/boost/preprocessor/detail/is_binary.hpp
new file mode 100644
index 0000000..3428833
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/detail/is_binary.hpp
@@ -0,0 +1,30 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_DETAIL_IS_BINARY_HPP
+# define BOOST_PREPROCESSOR_DETAIL_IS_BINARY_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/detail/check.hpp>
+#
+# /* BOOST_PP_IS_BINARY */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_IS_BINARY(x) BOOST_PP_CHECK(x, BOOST_PP_IS_BINARY_CHECK)
+# else
+#    define BOOST_PP_IS_BINARY(x) BOOST_PP_IS_BINARY_I(x)
+#    define BOOST_PP_IS_BINARY_I(x) BOOST_PP_CHECK(x, BOOST_PP_IS_BINARY_CHECK)
+# endif
+#
+# define BOOST_PP_IS_BINARY_CHECK(a, b) 1
+# define BOOST_PP_CHECK_RESULT_BOOST_PP_IS_BINARY_CHECK 0, BOOST_PP_NIL
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/empty.hpp b/third_party/boost/boost/preprocessor/empty.hpp
new file mode 100644
index 0000000..116ef74
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/empty.hpp
@@ -0,0 +1,17 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_EMPTY_HPP
+# define BOOST_PREPROCESSOR_EMPTY_HPP
+#
+# include <boost/preprocessor/facilities/empty.hpp>
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/enum.hpp b/third_party/boost/boost/preprocessor/enum.hpp
new file mode 100644
index 0000000..ae05bb0
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/enum.hpp
@@ -0,0 +1,17 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ENUM_HPP
+# define BOOST_PREPROCESSOR_ENUM_HPP
+#
+# include <boost/preprocessor/repetition/enum.hpp>
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/enum_params.hpp b/third_party/boost/boost/preprocessor/enum_params.hpp
new file mode 100644
index 0000000..414f8aa
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/enum_params.hpp
@@ -0,0 +1,17 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ENUM_PARAMS_HPP
+# define BOOST_PREPROCESSOR_ENUM_PARAMS_HPP
+#
+# include <boost/preprocessor/repetition/enum_params.hpp>
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/enum_shifted_params.hpp b/third_party/boost/boost/preprocessor/enum_shifted_params.hpp
new file mode 100644
index 0000000..462c642
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/enum_shifted_params.hpp
@@ -0,0 +1,17 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ENUM_SHIFTED_PARAMS_HPP
+# define BOOST_PREPROCESSOR_ENUM_SHIFTED_PARAMS_HPP
+#
+# include <boost/preprocessor/repetition/enum_shifted_params.hpp>
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/facilities/empty.hpp b/third_party/boost/boost/preprocessor/facilities/empty.hpp
new file mode 100644
index 0000000..6f215dc
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/facilities/empty.hpp
@@ -0,0 +1,23 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_FACILITIES_EMPTY_HPP
+# define BOOST_PREPROCESSOR_FACILITIES_EMPTY_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+#
+# /* BOOST_PP_EMPTY */
+#
+# define BOOST_PP_EMPTY()
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/facilities/expand.hpp b/third_party/boost/boost/preprocessor/facilities/expand.hpp
new file mode 100644
index 0000000..c8661a1
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/facilities/expand.hpp
@@ -0,0 +1,28 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_FACILITIES_EXPAND_HPP
+# define BOOST_PREPROCESSOR_FACILITIES_EXPAND_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC() && ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC()
+#    define BOOST_PP_EXPAND(x) BOOST_PP_EXPAND_I(x)
+# else
+#    define BOOST_PP_EXPAND(x) BOOST_PP_EXPAND_OO((x))
+#    define BOOST_PP_EXPAND_OO(par) BOOST_PP_EXPAND_I ## par
+# endif
+#
+# define BOOST_PP_EXPAND_I(x) x
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/facilities/identity.hpp b/third_party/boost/boost/preprocessor/facilities/identity.hpp
new file mode 100644
index 0000000..8a7834d
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/facilities/identity.hpp
@@ -0,0 +1,27 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+# /* Revised by Edward Diener (2015) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_FACILITIES_IDENTITY_HPP
+# define BOOST_PREPROCESSOR_FACILITIES_IDENTITY_HPP
+#
+# include <boost/preprocessor/facilities/empty.hpp>
+# include <boost/preprocessor/tuple/eat.hpp>
+#
+# /* BOOST_PP_IDENTITY */
+#
+# define BOOST_PP_IDENTITY(item) item BOOST_PP_EMPTY
+#
+# define BOOST_PP_IDENTITY_N(item,n) item BOOST_PP_TUPLE_EAT_N(n)
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/facilities/intercept.hpp b/third_party/boost/boost/preprocessor/facilities/intercept.hpp
new file mode 100644
index 0000000..41dcc6a
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/facilities/intercept.hpp
@@ -0,0 +1,277 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_FACILITIES_INTERCEPT_HPP
+# define BOOST_PREPROCESSOR_FACILITIES_INTERCEPT_HPP
+#
+# /* BOOST_PP_INTERCEPT */
+#
+# define BOOST_PP_INTERCEPT BOOST_PP_INTERCEPT_
+#
+# define BOOST_PP_INTERCEPT_0
+# define BOOST_PP_INTERCEPT_1
+# define BOOST_PP_INTERCEPT_2
+# define BOOST_PP_INTERCEPT_3
+# define BOOST_PP_INTERCEPT_4
+# define BOOST_PP_INTERCEPT_5
+# define BOOST_PP_INTERCEPT_6
+# define BOOST_PP_INTERCEPT_7
+# define BOOST_PP_INTERCEPT_8
+# define BOOST_PP_INTERCEPT_9
+# define BOOST_PP_INTERCEPT_10
+# define BOOST_PP_INTERCEPT_11
+# define BOOST_PP_INTERCEPT_12
+# define BOOST_PP_INTERCEPT_13
+# define BOOST_PP_INTERCEPT_14
+# define BOOST_PP_INTERCEPT_15
+# define BOOST_PP_INTERCEPT_16
+# define BOOST_PP_INTERCEPT_17
+# define BOOST_PP_INTERCEPT_18
+# define BOOST_PP_INTERCEPT_19
+# define BOOST_PP_INTERCEPT_20
+# define BOOST_PP_INTERCEPT_21
+# define BOOST_PP_INTERCEPT_22
+# define BOOST_PP_INTERCEPT_23
+# define BOOST_PP_INTERCEPT_24
+# define BOOST_PP_INTERCEPT_25
+# define BOOST_PP_INTERCEPT_26
+# define BOOST_PP_INTERCEPT_27
+# define BOOST_PP_INTERCEPT_28
+# define BOOST_PP_INTERCEPT_29
+# define BOOST_PP_INTERCEPT_30
+# define BOOST_PP_INTERCEPT_31
+# define BOOST_PP_INTERCEPT_32
+# define BOOST_PP_INTERCEPT_33
+# define BOOST_PP_INTERCEPT_34
+# define BOOST_PP_INTERCEPT_35
+# define BOOST_PP_INTERCEPT_36
+# define BOOST_PP_INTERCEPT_37
+# define BOOST_PP_INTERCEPT_38
+# define BOOST_PP_INTERCEPT_39
+# define BOOST_PP_INTERCEPT_40
+# define BOOST_PP_INTERCEPT_41
+# define BOOST_PP_INTERCEPT_42
+# define BOOST_PP_INTERCEPT_43
+# define BOOST_PP_INTERCEPT_44
+# define BOOST_PP_INTERCEPT_45
+# define BOOST_PP_INTERCEPT_46
+# define BOOST_PP_INTERCEPT_47
+# define BOOST_PP_INTERCEPT_48
+# define BOOST_PP_INTERCEPT_49
+# define BOOST_PP_INTERCEPT_50
+# define BOOST_PP_INTERCEPT_51
+# define BOOST_PP_INTERCEPT_52
+# define BOOST_PP_INTERCEPT_53
+# define BOOST_PP_INTERCEPT_54
+# define BOOST_PP_INTERCEPT_55
+# define BOOST_PP_INTERCEPT_56
+# define BOOST_PP_INTERCEPT_57
+# define BOOST_PP_INTERCEPT_58
+# define BOOST_PP_INTERCEPT_59
+# define BOOST_PP_INTERCEPT_60
+# define BOOST_PP_INTERCEPT_61
+# define BOOST_PP_INTERCEPT_62
+# define BOOST_PP_INTERCEPT_63
+# define BOOST_PP_INTERCEPT_64
+# define BOOST_PP_INTERCEPT_65
+# define BOOST_PP_INTERCEPT_66
+# define BOOST_PP_INTERCEPT_67
+# define BOOST_PP_INTERCEPT_68
+# define BOOST_PP_INTERCEPT_69
+# define BOOST_PP_INTERCEPT_70
+# define BOOST_PP_INTERCEPT_71
+# define BOOST_PP_INTERCEPT_72
+# define BOOST_PP_INTERCEPT_73
+# define BOOST_PP_INTERCEPT_74
+# define BOOST_PP_INTERCEPT_75
+# define BOOST_PP_INTERCEPT_76
+# define BOOST_PP_INTERCEPT_77
+# define BOOST_PP_INTERCEPT_78
+# define BOOST_PP_INTERCEPT_79
+# define BOOST_PP_INTERCEPT_80
+# define BOOST_PP_INTERCEPT_81
+# define BOOST_PP_INTERCEPT_82
+# define BOOST_PP_INTERCEPT_83
+# define BOOST_PP_INTERCEPT_84
+# define BOOST_PP_INTERCEPT_85
+# define BOOST_PP_INTERCEPT_86
+# define BOOST_PP_INTERCEPT_87
+# define BOOST_PP_INTERCEPT_88
+# define BOOST_PP_INTERCEPT_89
+# define BOOST_PP_INTERCEPT_90
+# define BOOST_PP_INTERCEPT_91
+# define BOOST_PP_INTERCEPT_92
+# define BOOST_PP_INTERCEPT_93
+# define BOOST_PP_INTERCEPT_94
+# define BOOST_PP_INTERCEPT_95
+# define BOOST_PP_INTERCEPT_96
+# define BOOST_PP_INTERCEPT_97
+# define BOOST_PP_INTERCEPT_98
+# define BOOST_PP_INTERCEPT_99
+# define BOOST_PP_INTERCEPT_100
+# define BOOST_PP_INTERCEPT_101
+# define BOOST_PP_INTERCEPT_102
+# define BOOST_PP_INTERCEPT_103
+# define BOOST_PP_INTERCEPT_104
+# define BOOST_PP_INTERCEPT_105
+# define BOOST_PP_INTERCEPT_106
+# define BOOST_PP_INTERCEPT_107
+# define BOOST_PP_INTERCEPT_108
+# define BOOST_PP_INTERCEPT_109
+# define BOOST_PP_INTERCEPT_110
+# define BOOST_PP_INTERCEPT_111
+# define BOOST_PP_INTERCEPT_112
+# define BOOST_PP_INTERCEPT_113
+# define BOOST_PP_INTERCEPT_114
+# define BOOST_PP_INTERCEPT_115
+# define BOOST_PP_INTERCEPT_116
+# define BOOST_PP_INTERCEPT_117
+# define BOOST_PP_INTERCEPT_118
+# define BOOST_PP_INTERCEPT_119
+# define BOOST_PP_INTERCEPT_120
+# define BOOST_PP_INTERCEPT_121
+# define BOOST_PP_INTERCEPT_122
+# define BOOST_PP_INTERCEPT_123
+# define BOOST_PP_INTERCEPT_124
+# define BOOST_PP_INTERCEPT_125
+# define BOOST_PP_INTERCEPT_126
+# define BOOST_PP_INTERCEPT_127
+# define BOOST_PP_INTERCEPT_128
+# define BOOST_PP_INTERCEPT_129
+# define BOOST_PP_INTERCEPT_130
+# define BOOST_PP_INTERCEPT_131
+# define BOOST_PP_INTERCEPT_132
+# define BOOST_PP_INTERCEPT_133
+# define BOOST_PP_INTERCEPT_134
+# define BOOST_PP_INTERCEPT_135
+# define BOOST_PP_INTERCEPT_136
+# define BOOST_PP_INTERCEPT_137
+# define BOOST_PP_INTERCEPT_138
+# define BOOST_PP_INTERCEPT_139
+# define BOOST_PP_INTERCEPT_140
+# define BOOST_PP_INTERCEPT_141
+# define BOOST_PP_INTERCEPT_142
+# define BOOST_PP_INTERCEPT_143
+# define BOOST_PP_INTERCEPT_144
+# define BOOST_PP_INTERCEPT_145
+# define BOOST_PP_INTERCEPT_146
+# define BOOST_PP_INTERCEPT_147
+# define BOOST_PP_INTERCEPT_148
+# define BOOST_PP_INTERCEPT_149
+# define BOOST_PP_INTERCEPT_150
+# define BOOST_PP_INTERCEPT_151
+# define BOOST_PP_INTERCEPT_152
+# define BOOST_PP_INTERCEPT_153
+# define BOOST_PP_INTERCEPT_154
+# define BOOST_PP_INTERCEPT_155
+# define BOOST_PP_INTERCEPT_156
+# define BOOST_PP_INTERCEPT_157
+# define BOOST_PP_INTERCEPT_158
+# define BOOST_PP_INTERCEPT_159
+# define BOOST_PP_INTERCEPT_160
+# define BOOST_PP_INTERCEPT_161
+# define BOOST_PP_INTERCEPT_162
+# define BOOST_PP_INTERCEPT_163
+# define BOOST_PP_INTERCEPT_164
+# define BOOST_PP_INTERCEPT_165
+# define BOOST_PP_INTERCEPT_166
+# define BOOST_PP_INTERCEPT_167
+# define BOOST_PP_INTERCEPT_168
+# define BOOST_PP_INTERCEPT_169
+# define BOOST_PP_INTERCEPT_170
+# define BOOST_PP_INTERCEPT_171
+# define BOOST_PP_INTERCEPT_172
+# define BOOST_PP_INTERCEPT_173
+# define BOOST_PP_INTERCEPT_174
+# define BOOST_PP_INTERCEPT_175
+# define BOOST_PP_INTERCEPT_176
+# define BOOST_PP_INTERCEPT_177
+# define BOOST_PP_INTERCEPT_178
+# define BOOST_PP_INTERCEPT_179
+# define BOOST_PP_INTERCEPT_180
+# define BOOST_PP_INTERCEPT_181
+# define BOOST_PP_INTERCEPT_182
+# define BOOST_PP_INTERCEPT_183
+# define BOOST_PP_INTERCEPT_184
+# define BOOST_PP_INTERCEPT_185
+# define BOOST_PP_INTERCEPT_186
+# define BOOST_PP_INTERCEPT_187
+# define BOOST_PP_INTERCEPT_188
+# define BOOST_PP_INTERCEPT_189
+# define BOOST_PP_INTERCEPT_190
+# define BOOST_PP_INTERCEPT_191
+# define BOOST_PP_INTERCEPT_192
+# define BOOST_PP_INTERCEPT_193
+# define BOOST_PP_INTERCEPT_194
+# define BOOST_PP_INTERCEPT_195
+# define BOOST_PP_INTERCEPT_196
+# define BOOST_PP_INTERCEPT_197
+# define BOOST_PP_INTERCEPT_198
+# define BOOST_PP_INTERCEPT_199
+# define BOOST_PP_INTERCEPT_200
+# define BOOST_PP_INTERCEPT_201
+# define BOOST_PP_INTERCEPT_202
+# define BOOST_PP_INTERCEPT_203
+# define BOOST_PP_INTERCEPT_204
+# define BOOST_PP_INTERCEPT_205
+# define BOOST_PP_INTERCEPT_206
+# define BOOST_PP_INTERCEPT_207
+# define BOOST_PP_INTERCEPT_208
+# define BOOST_PP_INTERCEPT_209
+# define BOOST_PP_INTERCEPT_210
+# define BOOST_PP_INTERCEPT_211
+# define BOOST_PP_INTERCEPT_212
+# define BOOST_PP_INTERCEPT_213
+# define BOOST_PP_INTERCEPT_214
+# define BOOST_PP_INTERCEPT_215
+# define BOOST_PP_INTERCEPT_216
+# define BOOST_PP_INTERCEPT_217
+# define BOOST_PP_INTERCEPT_218
+# define BOOST_PP_INTERCEPT_219
+# define BOOST_PP_INTERCEPT_220
+# define BOOST_PP_INTERCEPT_221
+# define BOOST_PP_INTERCEPT_222
+# define BOOST_PP_INTERCEPT_223
+# define BOOST_PP_INTERCEPT_224
+# define BOOST_PP_INTERCEPT_225
+# define BOOST_PP_INTERCEPT_226
+# define BOOST_PP_INTERCEPT_227
+# define BOOST_PP_INTERCEPT_228
+# define BOOST_PP_INTERCEPT_229
+# define BOOST_PP_INTERCEPT_230
+# define BOOST_PP_INTERCEPT_231
+# define BOOST_PP_INTERCEPT_232
+# define BOOST_PP_INTERCEPT_233
+# define BOOST_PP_INTERCEPT_234
+# define BOOST_PP_INTERCEPT_235
+# define BOOST_PP_INTERCEPT_236
+# define BOOST_PP_INTERCEPT_237
+# define BOOST_PP_INTERCEPT_238
+# define BOOST_PP_INTERCEPT_239
+# define BOOST_PP_INTERCEPT_240
+# define BOOST_PP_INTERCEPT_241
+# define BOOST_PP_INTERCEPT_242
+# define BOOST_PP_INTERCEPT_243
+# define BOOST_PP_INTERCEPT_244
+# define BOOST_PP_INTERCEPT_245
+# define BOOST_PP_INTERCEPT_246
+# define BOOST_PP_INTERCEPT_247
+# define BOOST_PP_INTERCEPT_248
+# define BOOST_PP_INTERCEPT_249
+# define BOOST_PP_INTERCEPT_250
+# define BOOST_PP_INTERCEPT_251
+# define BOOST_PP_INTERCEPT_252
+# define BOOST_PP_INTERCEPT_253
+# define BOOST_PP_INTERCEPT_254
+# define BOOST_PP_INTERCEPT_255
+# define BOOST_PP_INTERCEPT_256
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/facilities/overload.hpp b/third_party/boost/boost/preprocessor/facilities/overload.hpp
new file mode 100644
index 0000000..1576316
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/facilities/overload.hpp
@@ -0,0 +1,25 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2011.                                  *
+#  *     (C) Copyright Edward Diener 2011.                                    *
+#  *     Distributed under the Boost Software License, Version 1.0. (See      *
+#  *     accompanying file LICENSE_1_0.txt or copy at                         *
+#  *     http://www.boost.org/LICENSE_1_0.txt)                                *
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_FACILITIES_OVERLOAD_HPP
+# define BOOST_PREPROCESSOR_FACILITIES_OVERLOAD_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/variadic/size.hpp>
+#
+# /* BOOST_PP_OVERLOAD */
+#
+# if BOOST_PP_VARIADICS
+#    define BOOST_PP_OVERLOAD(prefix, ...) BOOST_PP_CAT(prefix, BOOST_PP_VARIADIC_SIZE(__VA_ARGS__))
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/identity.hpp b/third_party/boost/boost/preprocessor/identity.hpp
new file mode 100644
index 0000000..847dd13
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/identity.hpp
@@ -0,0 +1,17 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_IDENTITY_HPP
+# define BOOST_PREPROCESSOR_IDENTITY_HPP
+#
+# include <boost/preprocessor/facilities/identity.hpp>
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/inc.hpp b/third_party/boost/boost/preprocessor/inc.hpp
new file mode 100644
index 0000000..b98d3a6
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/inc.hpp
@@ -0,0 +1,17 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_INC_HPP
+# define BOOST_PREPROCESSOR_INC_HPP
+#
+# include <boost/preprocessor/arithmetic/inc.hpp>
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/iterate.hpp b/third_party/boost/boost/preprocessor/iterate.hpp
new file mode 100644
index 0000000..e720ec8
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/iterate.hpp
@@ -0,0 +1,17 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ITERATE_HPP
+# define BOOST_PREPROCESSOR_ITERATE_HPP
+#
+# include <boost/preprocessor/iteration/iterate.hpp>
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/iteration.hpp b/third_party/boost/boost/preprocessor/iteration.hpp
new file mode 100644
index 0000000..1055ac0
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/iteration.hpp
@@ -0,0 +1,19 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ITERATION_HPP
+# define BOOST_PREPROCESSOR_ITERATION_HPP
+#
+# include <boost/preprocessor/iteration/iterate.hpp>
+# include <boost/preprocessor/iteration/local.hpp>
+# include <boost/preprocessor/iteration/self.hpp>
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/iteration/detail/bounds/lower1.hpp b/third_party/boost/boost/preprocessor/iteration/detail/bounds/lower1.hpp
new file mode 100644
index 0000000..6694d0b
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/iteration/detail/bounds/lower1.hpp
@@ -0,0 +1,99 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# include <boost/preprocessor/slot/detail/shared.hpp>
+#
+# undef BOOST_PP_ITERATION_START_1
+#
+# undef BOOST_PP_ITERATION_START_1_DIGIT_1
+# undef BOOST_PP_ITERATION_START_1_DIGIT_2
+# undef BOOST_PP_ITERATION_START_1_DIGIT_3
+# undef BOOST_PP_ITERATION_START_1_DIGIT_4
+# undef BOOST_PP_ITERATION_START_1_DIGIT_5
+# undef BOOST_PP_ITERATION_START_1_DIGIT_6
+# undef BOOST_PP_ITERATION_START_1_DIGIT_7
+# undef BOOST_PP_ITERATION_START_1_DIGIT_8
+# undef BOOST_PP_ITERATION_START_1_DIGIT_9
+# undef BOOST_PP_ITERATION_START_1_DIGIT_10
+#
+# if BOOST_PP_SLOT_TEMP_3 == 0
+#    define BOOST_PP_ITERATION_START_1_DIGIT_3 0
+# elif BOOST_PP_SLOT_TEMP_3 == 1
+#    define BOOST_PP_ITERATION_START_1_DIGIT_3 1
+# elif BOOST_PP_SLOT_TEMP_3 == 2
+#    define BOOST_PP_ITERATION_START_1_DIGIT_3 2
+# elif BOOST_PP_SLOT_TEMP_3 == 3
+#    define BOOST_PP_ITERATION_START_1_DIGIT_3 3
+# elif BOOST_PP_SLOT_TEMP_3 == 4
+#    define BOOST_PP_ITERATION_START_1_DIGIT_3 4
+# elif BOOST_PP_SLOT_TEMP_3 == 5
+#    define BOOST_PP_ITERATION_START_1_DIGIT_3 5
+# elif BOOST_PP_SLOT_TEMP_3 == 6
+#    define BOOST_PP_ITERATION_START_1_DIGIT_3 6
+# elif BOOST_PP_SLOT_TEMP_3 == 7
+#    define BOOST_PP_ITERATION_START_1_DIGIT_3 7
+# elif BOOST_PP_SLOT_TEMP_3 == 8
+#    define BOOST_PP_ITERATION_START_1_DIGIT_3 8
+# elif BOOST_PP_SLOT_TEMP_3 == 9
+#    define BOOST_PP_ITERATION_START_1_DIGIT_3 9
+# endif
+#
+# if BOOST_PP_SLOT_TEMP_2 == 0
+#    define BOOST_PP_ITERATION_START_1_DIGIT_2 0
+# elif BOOST_PP_SLOT_TEMP_2 == 1
+#    define BOOST_PP_ITERATION_START_1_DIGIT_2 1
+# elif BOOST_PP_SLOT_TEMP_2 == 2
+#    define BOOST_PP_ITERATION_START_1_DIGIT_2 2
+# elif BOOST_PP_SLOT_TEMP_2 == 3
+#    define BOOST_PP_ITERATION_START_1_DIGIT_2 3
+# elif BOOST_PP_SLOT_TEMP_2 == 4
+#    define BOOST_PP_ITERATION_START_1_DIGIT_2 4
+# elif BOOST_PP_SLOT_TEMP_2 == 5
+#    define BOOST_PP_ITERATION_START_1_DIGIT_2 5
+# elif BOOST_PP_SLOT_TEMP_2 == 6
+#    define BOOST_PP_ITERATION_START_1_DIGIT_2 6
+# elif BOOST_PP_SLOT_TEMP_2 == 7
+#    define BOOST_PP_ITERATION_START_1_DIGIT_2 7
+# elif BOOST_PP_SLOT_TEMP_2 == 8
+#    define BOOST_PP_ITERATION_START_1_DIGIT_2 8
+# elif BOOST_PP_SLOT_TEMP_2 == 9
+#    define BOOST_PP_ITERATION_START_1_DIGIT_2 9
+# endif
+#
+# if BOOST_PP_SLOT_TEMP_1 == 0
+#    define BOOST_PP_ITERATION_START_1_DIGIT_1 0
+# elif BOOST_PP_SLOT_TEMP_1 == 1
+#    define BOOST_PP_ITERATION_START_1_DIGIT_1 1
+# elif BOOST_PP_SLOT_TEMP_1 == 2
+#    define BOOST_PP_ITERATION_START_1_DIGIT_1 2
+# elif BOOST_PP_SLOT_TEMP_1 == 3
+#    define BOOST_PP_ITERATION_START_1_DIGIT_1 3
+# elif BOOST_PP_SLOT_TEMP_1 == 4
+#    define BOOST_PP_ITERATION_START_1_DIGIT_1 4
+# elif BOOST_PP_SLOT_TEMP_1 == 5
+#    define BOOST_PP_ITERATION_START_1_DIGIT_1 5
+# elif BOOST_PP_SLOT_TEMP_1 == 6
+#    define BOOST_PP_ITERATION_START_1_DIGIT_1 6
+# elif BOOST_PP_SLOT_TEMP_1 == 7
+#    define BOOST_PP_ITERATION_START_1_DIGIT_1 7
+# elif BOOST_PP_SLOT_TEMP_1 == 8
+#    define BOOST_PP_ITERATION_START_1_DIGIT_1 8
+# elif BOOST_PP_SLOT_TEMP_1 == 9
+#    define BOOST_PP_ITERATION_START_1_DIGIT_1 9
+# endif
+#
+# if BOOST_PP_ITERATION_START_1_DIGIT_3
+#    define BOOST_PP_ITERATION_START_1 BOOST_PP_SLOT_CC_3(BOOST_PP_ITERATION_START_1_DIGIT_3, BOOST_PP_ITERATION_START_1_DIGIT_2, BOOST_PP_ITERATION_START_1_DIGIT_1)
+# elif BOOST_PP_ITERATION_START_1_DIGIT_2
+#    define BOOST_PP_ITERATION_START_1 BOOST_PP_SLOT_CC_2(BOOST_PP_ITERATION_START_1_DIGIT_2, BOOST_PP_ITERATION_START_1_DIGIT_1)
+# else
+#    define BOOST_PP_ITERATION_START_1 BOOST_PP_ITERATION_START_1_DIGIT_1
+# endif
diff --git a/third_party/boost/boost/preprocessor/iteration/detail/bounds/upper1.hpp b/third_party/boost/boost/preprocessor/iteration/detail/bounds/upper1.hpp
new file mode 100644
index 0000000..50d0fcf
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/iteration/detail/bounds/upper1.hpp
@@ -0,0 +1,99 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# include <boost/preprocessor/slot/detail/shared.hpp>
+#
+# undef BOOST_PP_ITERATION_FINISH_1
+#
+# undef BOOST_PP_ITERATION_FINISH_1_DIGIT_1
+# undef BOOST_PP_ITERATION_FINISH_1_DIGIT_2
+# undef BOOST_PP_ITERATION_FINISH_1_DIGIT_3
+# undef BOOST_PP_ITERATION_FINISH_1_DIGIT_4
+# undef BOOST_PP_ITERATION_FINISH_1_DIGIT_5
+# undef BOOST_PP_ITERATION_FINISH_1_DIGIT_6
+# undef BOOST_PP_ITERATION_FINISH_1_DIGIT_7
+# undef BOOST_PP_ITERATION_FINISH_1_DIGIT_8
+# undef BOOST_PP_ITERATION_FINISH_1_DIGIT_9
+# undef BOOST_PP_ITERATION_FINISH_1_DIGIT_10
+#
+# if BOOST_PP_SLOT_TEMP_3 == 0
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 0
+# elif BOOST_PP_SLOT_TEMP_3 == 1
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 1
+# elif BOOST_PP_SLOT_TEMP_3 == 2
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 2
+# elif BOOST_PP_SLOT_TEMP_3 == 3
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 3
+# elif BOOST_PP_SLOT_TEMP_3 == 4
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 4
+# elif BOOST_PP_SLOT_TEMP_3 == 5
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 5
+# elif BOOST_PP_SLOT_TEMP_3 == 6
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 6
+# elif BOOST_PP_SLOT_TEMP_3 == 7
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 7
+# elif BOOST_PP_SLOT_TEMP_3 == 8
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 8
+# elif BOOST_PP_SLOT_TEMP_3 == 9
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_3 9
+# endif
+#
+# if BOOST_PP_SLOT_TEMP_2 == 0
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 0
+# elif BOOST_PP_SLOT_TEMP_2 == 1
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 1
+# elif BOOST_PP_SLOT_TEMP_2 == 2
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 2
+# elif BOOST_PP_SLOT_TEMP_2 == 3
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 3
+# elif BOOST_PP_SLOT_TEMP_2 == 4
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 4
+# elif BOOST_PP_SLOT_TEMP_2 == 5
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 5
+# elif BOOST_PP_SLOT_TEMP_2 == 6
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 6
+# elif BOOST_PP_SLOT_TEMP_2 == 7
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 7
+# elif BOOST_PP_SLOT_TEMP_2 == 8
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 8
+# elif BOOST_PP_SLOT_TEMP_2 == 9
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_2 9
+# endif
+#
+# if BOOST_PP_SLOT_TEMP_1 == 0
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 0
+# elif BOOST_PP_SLOT_TEMP_1 == 1
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 1
+# elif BOOST_PP_SLOT_TEMP_1 == 2
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 2
+# elif BOOST_PP_SLOT_TEMP_1 == 3
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 3
+# elif BOOST_PP_SLOT_TEMP_1 == 4
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 4
+# elif BOOST_PP_SLOT_TEMP_1 == 5
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 5
+# elif BOOST_PP_SLOT_TEMP_1 == 6
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 6
+# elif BOOST_PP_SLOT_TEMP_1 == 7
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 7
+# elif BOOST_PP_SLOT_TEMP_1 == 8
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 8
+# elif BOOST_PP_SLOT_TEMP_1 == 9
+#    define BOOST_PP_ITERATION_FINISH_1_DIGIT_1 9
+# endif
+#
+# if BOOST_PP_ITERATION_FINISH_1_DIGIT_3
+#    define BOOST_PP_ITERATION_FINISH_1 BOOST_PP_SLOT_CC_3(BOOST_PP_ITERATION_FINISH_1_DIGIT_3, BOOST_PP_ITERATION_FINISH_1_DIGIT_2, BOOST_PP_ITERATION_FINISH_1_DIGIT_1)
+# elif BOOST_PP_ITERATION_FINISH_1_DIGIT_2
+#    define BOOST_PP_ITERATION_FINISH_1 BOOST_PP_SLOT_CC_2(BOOST_PP_ITERATION_FINISH_1_DIGIT_2, BOOST_PP_ITERATION_FINISH_1_DIGIT_1)
+# else
+#    define BOOST_PP_ITERATION_FINISH_1 BOOST_PP_ITERATION_FINISH_1_DIGIT_1
+# endif
diff --git a/third_party/boost/boost/preprocessor/iteration/detail/iter/forward1.hpp b/third_party/boost/boost/preprocessor/iteration/detail/iter/forward1.hpp
new file mode 100644
index 0000000..3c6a458
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/iteration/detail/iter/forward1.hpp
@@ -0,0 +1,1342 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# if defined(BOOST_PP_ITERATION_LIMITS)
+#    if !defined(BOOST_PP_FILENAME_1)
+#        error BOOST_PP_ERROR:  depth #1 filename is not defined
+#    endif
+#    define BOOST_PP_VALUE BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_ITERATION_LIMITS)
+#    include <boost/preprocessor/iteration/detail/bounds/lower1.hpp>
+#    define BOOST_PP_VALUE BOOST_PP_TUPLE_ELEM(2, 1, BOOST_PP_ITERATION_LIMITS)
+#    include <boost/preprocessor/iteration/detail/bounds/upper1.hpp>
+#    define BOOST_PP_ITERATION_FLAGS_1() 0
+#    undef BOOST_PP_ITERATION_LIMITS
+# elif defined(BOOST_PP_ITERATION_PARAMS_1)
+#    define BOOST_PP_VALUE BOOST_PP_ARRAY_ELEM(0, BOOST_PP_ITERATION_PARAMS_1)
+#    include <boost/preprocessor/iteration/detail/bounds/lower1.hpp>
+#    define BOOST_PP_VALUE BOOST_PP_ARRAY_ELEM(1, BOOST_PP_ITERATION_PARAMS_1)
+#    include <boost/preprocessor/iteration/detail/bounds/upper1.hpp>
+#    define BOOST_PP_FILENAME_1 BOOST_PP_ARRAY_ELEM(2, BOOST_PP_ITERATION_PARAMS_1)
+#    if BOOST_PP_ARRAY_SIZE(BOOST_PP_ITERATION_PARAMS_1) >= 4
+#        define BOOST_PP_ITERATION_FLAGS_1() BOOST_PP_ARRAY_ELEM(3, BOOST_PP_ITERATION_PARAMS_1)
+#    else
+#        define BOOST_PP_ITERATION_FLAGS_1() 0
+#    endif
+# else
+#    error BOOST_PP_ERROR:  depth #1 iteration boundaries or filename not defined
+# endif
+#
+# undef BOOST_PP_ITERATION_DEPTH
+# define BOOST_PP_ITERATION_DEPTH() 1
+#
+# define BOOST_PP_IS_ITERATING 1
+#
+# if (BOOST_PP_ITERATION_START_1) > (BOOST_PP_ITERATION_FINISH_1)
+#    include <boost/preprocessor/iteration/detail/iter/reverse1.hpp>
+# else
+#    if BOOST_PP_ITERATION_START_1 <= 0 && BOOST_PP_ITERATION_FINISH_1 >= 0
+#        define BOOST_PP_ITERATION_1 0
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 1 && BOOST_PP_ITERATION_FINISH_1 >= 1
+#        define BOOST_PP_ITERATION_1 1
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 2 && BOOST_PP_ITERATION_FINISH_1 >= 2
+#        define BOOST_PP_ITERATION_1 2
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 3 && BOOST_PP_ITERATION_FINISH_1 >= 3
+#        define BOOST_PP_ITERATION_1 3
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 4 && BOOST_PP_ITERATION_FINISH_1 >= 4
+#        define BOOST_PP_ITERATION_1 4
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 5 && BOOST_PP_ITERATION_FINISH_1 >= 5
+#        define BOOST_PP_ITERATION_1 5
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 6 && BOOST_PP_ITERATION_FINISH_1 >= 6
+#        define BOOST_PP_ITERATION_1 6
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 7 && BOOST_PP_ITERATION_FINISH_1 >= 7
+#        define BOOST_PP_ITERATION_1 7
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 8 && BOOST_PP_ITERATION_FINISH_1 >= 8
+#        define BOOST_PP_ITERATION_1 8
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 9 && BOOST_PP_ITERATION_FINISH_1 >= 9
+#        define BOOST_PP_ITERATION_1 9
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 10 && BOOST_PP_ITERATION_FINISH_1 >= 10
+#        define BOOST_PP_ITERATION_1 10
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 11 && BOOST_PP_ITERATION_FINISH_1 >= 11
+#        define BOOST_PP_ITERATION_1 11
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 12 && BOOST_PP_ITERATION_FINISH_1 >= 12
+#        define BOOST_PP_ITERATION_1 12
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 13 && BOOST_PP_ITERATION_FINISH_1 >= 13
+#        define BOOST_PP_ITERATION_1 13
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 14 && BOOST_PP_ITERATION_FINISH_1 >= 14
+#        define BOOST_PP_ITERATION_1 14
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 15 && BOOST_PP_ITERATION_FINISH_1 >= 15
+#        define BOOST_PP_ITERATION_1 15
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 16 && BOOST_PP_ITERATION_FINISH_1 >= 16
+#        define BOOST_PP_ITERATION_1 16
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 17 && BOOST_PP_ITERATION_FINISH_1 >= 17
+#        define BOOST_PP_ITERATION_1 17
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 18 && BOOST_PP_ITERATION_FINISH_1 >= 18
+#        define BOOST_PP_ITERATION_1 18
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 19 && BOOST_PP_ITERATION_FINISH_1 >= 19
+#        define BOOST_PP_ITERATION_1 19
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 20 && BOOST_PP_ITERATION_FINISH_1 >= 20
+#        define BOOST_PP_ITERATION_1 20
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 21 && BOOST_PP_ITERATION_FINISH_1 >= 21
+#        define BOOST_PP_ITERATION_1 21
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 22 && BOOST_PP_ITERATION_FINISH_1 >= 22
+#        define BOOST_PP_ITERATION_1 22
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 23 && BOOST_PP_ITERATION_FINISH_1 >= 23
+#        define BOOST_PP_ITERATION_1 23
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 24 && BOOST_PP_ITERATION_FINISH_1 >= 24
+#        define BOOST_PP_ITERATION_1 24
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 25 && BOOST_PP_ITERATION_FINISH_1 >= 25
+#        define BOOST_PP_ITERATION_1 25
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 26 && BOOST_PP_ITERATION_FINISH_1 >= 26
+#        define BOOST_PP_ITERATION_1 26
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 27 && BOOST_PP_ITERATION_FINISH_1 >= 27
+#        define BOOST_PP_ITERATION_1 27
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 28 && BOOST_PP_ITERATION_FINISH_1 >= 28
+#        define BOOST_PP_ITERATION_1 28
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 29 && BOOST_PP_ITERATION_FINISH_1 >= 29
+#        define BOOST_PP_ITERATION_1 29
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 30 && BOOST_PP_ITERATION_FINISH_1 >= 30
+#        define BOOST_PP_ITERATION_1 30
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 31 && BOOST_PP_ITERATION_FINISH_1 >= 31
+#        define BOOST_PP_ITERATION_1 31
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 32 && BOOST_PP_ITERATION_FINISH_1 >= 32
+#        define BOOST_PP_ITERATION_1 32
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 33 && BOOST_PP_ITERATION_FINISH_1 >= 33
+#        define BOOST_PP_ITERATION_1 33
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 34 && BOOST_PP_ITERATION_FINISH_1 >= 34
+#        define BOOST_PP_ITERATION_1 34
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 35 && BOOST_PP_ITERATION_FINISH_1 >= 35
+#        define BOOST_PP_ITERATION_1 35
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 36 && BOOST_PP_ITERATION_FINISH_1 >= 36
+#        define BOOST_PP_ITERATION_1 36
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 37 && BOOST_PP_ITERATION_FINISH_1 >= 37
+#        define BOOST_PP_ITERATION_1 37
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 38 && BOOST_PP_ITERATION_FINISH_1 >= 38
+#        define BOOST_PP_ITERATION_1 38
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 39 && BOOST_PP_ITERATION_FINISH_1 >= 39
+#        define BOOST_PP_ITERATION_1 39
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 40 && BOOST_PP_ITERATION_FINISH_1 >= 40
+#        define BOOST_PP_ITERATION_1 40
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 41 && BOOST_PP_ITERATION_FINISH_1 >= 41
+#        define BOOST_PP_ITERATION_1 41
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 42 && BOOST_PP_ITERATION_FINISH_1 >= 42
+#        define BOOST_PP_ITERATION_1 42
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 43 && BOOST_PP_ITERATION_FINISH_1 >= 43
+#        define BOOST_PP_ITERATION_1 43
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 44 && BOOST_PP_ITERATION_FINISH_1 >= 44
+#        define BOOST_PP_ITERATION_1 44
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 45 && BOOST_PP_ITERATION_FINISH_1 >= 45
+#        define BOOST_PP_ITERATION_1 45
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 46 && BOOST_PP_ITERATION_FINISH_1 >= 46
+#        define BOOST_PP_ITERATION_1 46
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 47 && BOOST_PP_ITERATION_FINISH_1 >= 47
+#        define BOOST_PP_ITERATION_1 47
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 48 && BOOST_PP_ITERATION_FINISH_1 >= 48
+#        define BOOST_PP_ITERATION_1 48
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 49 && BOOST_PP_ITERATION_FINISH_1 >= 49
+#        define BOOST_PP_ITERATION_1 49
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 50 && BOOST_PP_ITERATION_FINISH_1 >= 50
+#        define BOOST_PP_ITERATION_1 50
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 51 && BOOST_PP_ITERATION_FINISH_1 >= 51
+#        define BOOST_PP_ITERATION_1 51
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 52 && BOOST_PP_ITERATION_FINISH_1 >= 52
+#        define BOOST_PP_ITERATION_1 52
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 53 && BOOST_PP_ITERATION_FINISH_1 >= 53
+#        define BOOST_PP_ITERATION_1 53
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 54 && BOOST_PP_ITERATION_FINISH_1 >= 54
+#        define BOOST_PP_ITERATION_1 54
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 55 && BOOST_PP_ITERATION_FINISH_1 >= 55
+#        define BOOST_PP_ITERATION_1 55
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 56 && BOOST_PP_ITERATION_FINISH_1 >= 56
+#        define BOOST_PP_ITERATION_1 56
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 57 && BOOST_PP_ITERATION_FINISH_1 >= 57
+#        define BOOST_PP_ITERATION_1 57
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 58 && BOOST_PP_ITERATION_FINISH_1 >= 58
+#        define BOOST_PP_ITERATION_1 58
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 59 && BOOST_PP_ITERATION_FINISH_1 >= 59
+#        define BOOST_PP_ITERATION_1 59
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 60 && BOOST_PP_ITERATION_FINISH_1 >= 60
+#        define BOOST_PP_ITERATION_1 60
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 61 && BOOST_PP_ITERATION_FINISH_1 >= 61
+#        define BOOST_PP_ITERATION_1 61
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 62 && BOOST_PP_ITERATION_FINISH_1 >= 62
+#        define BOOST_PP_ITERATION_1 62
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 63 && BOOST_PP_ITERATION_FINISH_1 >= 63
+#        define BOOST_PP_ITERATION_1 63
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 64 && BOOST_PP_ITERATION_FINISH_1 >= 64
+#        define BOOST_PP_ITERATION_1 64
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 65 && BOOST_PP_ITERATION_FINISH_1 >= 65
+#        define BOOST_PP_ITERATION_1 65
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 66 && BOOST_PP_ITERATION_FINISH_1 >= 66
+#        define BOOST_PP_ITERATION_1 66
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 67 && BOOST_PP_ITERATION_FINISH_1 >= 67
+#        define BOOST_PP_ITERATION_1 67
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 68 && BOOST_PP_ITERATION_FINISH_1 >= 68
+#        define BOOST_PP_ITERATION_1 68
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 69 && BOOST_PP_ITERATION_FINISH_1 >= 69
+#        define BOOST_PP_ITERATION_1 69
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 70 && BOOST_PP_ITERATION_FINISH_1 >= 70
+#        define BOOST_PP_ITERATION_1 70
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 71 && BOOST_PP_ITERATION_FINISH_1 >= 71
+#        define BOOST_PP_ITERATION_1 71
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 72 && BOOST_PP_ITERATION_FINISH_1 >= 72
+#        define BOOST_PP_ITERATION_1 72
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 73 && BOOST_PP_ITERATION_FINISH_1 >= 73
+#        define BOOST_PP_ITERATION_1 73
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 74 && BOOST_PP_ITERATION_FINISH_1 >= 74
+#        define BOOST_PP_ITERATION_1 74
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 75 && BOOST_PP_ITERATION_FINISH_1 >= 75
+#        define BOOST_PP_ITERATION_1 75
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 76 && BOOST_PP_ITERATION_FINISH_1 >= 76
+#        define BOOST_PP_ITERATION_1 76
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 77 && BOOST_PP_ITERATION_FINISH_1 >= 77
+#        define BOOST_PP_ITERATION_1 77
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 78 && BOOST_PP_ITERATION_FINISH_1 >= 78
+#        define BOOST_PP_ITERATION_1 78
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 79 && BOOST_PP_ITERATION_FINISH_1 >= 79
+#        define BOOST_PP_ITERATION_1 79
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 80 && BOOST_PP_ITERATION_FINISH_1 >= 80
+#        define BOOST_PP_ITERATION_1 80
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 81 && BOOST_PP_ITERATION_FINISH_1 >= 81
+#        define BOOST_PP_ITERATION_1 81
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 82 && BOOST_PP_ITERATION_FINISH_1 >= 82
+#        define BOOST_PP_ITERATION_1 82
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 83 && BOOST_PP_ITERATION_FINISH_1 >= 83
+#        define BOOST_PP_ITERATION_1 83
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 84 && BOOST_PP_ITERATION_FINISH_1 >= 84
+#        define BOOST_PP_ITERATION_1 84
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 85 && BOOST_PP_ITERATION_FINISH_1 >= 85
+#        define BOOST_PP_ITERATION_1 85
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 86 && BOOST_PP_ITERATION_FINISH_1 >= 86
+#        define BOOST_PP_ITERATION_1 86
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 87 && BOOST_PP_ITERATION_FINISH_1 >= 87
+#        define BOOST_PP_ITERATION_1 87
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 88 && BOOST_PP_ITERATION_FINISH_1 >= 88
+#        define BOOST_PP_ITERATION_1 88
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 89 && BOOST_PP_ITERATION_FINISH_1 >= 89
+#        define BOOST_PP_ITERATION_1 89
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 90 && BOOST_PP_ITERATION_FINISH_1 >= 90
+#        define BOOST_PP_ITERATION_1 90
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 91 && BOOST_PP_ITERATION_FINISH_1 >= 91
+#        define BOOST_PP_ITERATION_1 91
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 92 && BOOST_PP_ITERATION_FINISH_1 >= 92
+#        define BOOST_PP_ITERATION_1 92
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 93 && BOOST_PP_ITERATION_FINISH_1 >= 93
+#        define BOOST_PP_ITERATION_1 93
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 94 && BOOST_PP_ITERATION_FINISH_1 >= 94
+#        define BOOST_PP_ITERATION_1 94
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 95 && BOOST_PP_ITERATION_FINISH_1 >= 95
+#        define BOOST_PP_ITERATION_1 95
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 96 && BOOST_PP_ITERATION_FINISH_1 >= 96
+#        define BOOST_PP_ITERATION_1 96
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 97 && BOOST_PP_ITERATION_FINISH_1 >= 97
+#        define BOOST_PP_ITERATION_1 97
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 98 && BOOST_PP_ITERATION_FINISH_1 >= 98
+#        define BOOST_PP_ITERATION_1 98
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 99 && BOOST_PP_ITERATION_FINISH_1 >= 99
+#        define BOOST_PP_ITERATION_1 99
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 100 && BOOST_PP_ITERATION_FINISH_1 >= 100
+#        define BOOST_PP_ITERATION_1 100
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 101 && BOOST_PP_ITERATION_FINISH_1 >= 101
+#        define BOOST_PP_ITERATION_1 101
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 102 && BOOST_PP_ITERATION_FINISH_1 >= 102
+#        define BOOST_PP_ITERATION_1 102
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 103 && BOOST_PP_ITERATION_FINISH_1 >= 103
+#        define BOOST_PP_ITERATION_1 103
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 104 && BOOST_PP_ITERATION_FINISH_1 >= 104
+#        define BOOST_PP_ITERATION_1 104
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 105 && BOOST_PP_ITERATION_FINISH_1 >= 105
+#        define BOOST_PP_ITERATION_1 105
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 106 && BOOST_PP_ITERATION_FINISH_1 >= 106
+#        define BOOST_PP_ITERATION_1 106
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 107 && BOOST_PP_ITERATION_FINISH_1 >= 107
+#        define BOOST_PP_ITERATION_1 107
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 108 && BOOST_PP_ITERATION_FINISH_1 >= 108
+#        define BOOST_PP_ITERATION_1 108
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 109 && BOOST_PP_ITERATION_FINISH_1 >= 109
+#        define BOOST_PP_ITERATION_1 109
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 110 && BOOST_PP_ITERATION_FINISH_1 >= 110
+#        define BOOST_PP_ITERATION_1 110
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 111 && BOOST_PP_ITERATION_FINISH_1 >= 111
+#        define BOOST_PP_ITERATION_1 111
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 112 && BOOST_PP_ITERATION_FINISH_1 >= 112
+#        define BOOST_PP_ITERATION_1 112
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 113 && BOOST_PP_ITERATION_FINISH_1 >= 113
+#        define BOOST_PP_ITERATION_1 113
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 114 && BOOST_PP_ITERATION_FINISH_1 >= 114
+#        define BOOST_PP_ITERATION_1 114
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 115 && BOOST_PP_ITERATION_FINISH_1 >= 115
+#        define BOOST_PP_ITERATION_1 115
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 116 && BOOST_PP_ITERATION_FINISH_1 >= 116
+#        define BOOST_PP_ITERATION_1 116
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 117 && BOOST_PP_ITERATION_FINISH_1 >= 117
+#        define BOOST_PP_ITERATION_1 117
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 118 && BOOST_PP_ITERATION_FINISH_1 >= 118
+#        define BOOST_PP_ITERATION_1 118
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 119 && BOOST_PP_ITERATION_FINISH_1 >= 119
+#        define BOOST_PP_ITERATION_1 119
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 120 && BOOST_PP_ITERATION_FINISH_1 >= 120
+#        define BOOST_PP_ITERATION_1 120
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 121 && BOOST_PP_ITERATION_FINISH_1 >= 121
+#        define BOOST_PP_ITERATION_1 121
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 122 && BOOST_PP_ITERATION_FINISH_1 >= 122
+#        define BOOST_PP_ITERATION_1 122
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 123 && BOOST_PP_ITERATION_FINISH_1 >= 123
+#        define BOOST_PP_ITERATION_1 123
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 124 && BOOST_PP_ITERATION_FINISH_1 >= 124
+#        define BOOST_PP_ITERATION_1 124
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 125 && BOOST_PP_ITERATION_FINISH_1 >= 125
+#        define BOOST_PP_ITERATION_1 125
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 126 && BOOST_PP_ITERATION_FINISH_1 >= 126
+#        define BOOST_PP_ITERATION_1 126
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 127 && BOOST_PP_ITERATION_FINISH_1 >= 127
+#        define BOOST_PP_ITERATION_1 127
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 128 && BOOST_PP_ITERATION_FINISH_1 >= 128
+#        define BOOST_PP_ITERATION_1 128
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 129 && BOOST_PP_ITERATION_FINISH_1 >= 129
+#        define BOOST_PP_ITERATION_1 129
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 130 && BOOST_PP_ITERATION_FINISH_1 >= 130
+#        define BOOST_PP_ITERATION_1 130
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 131 && BOOST_PP_ITERATION_FINISH_1 >= 131
+#        define BOOST_PP_ITERATION_1 131
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 132 && BOOST_PP_ITERATION_FINISH_1 >= 132
+#        define BOOST_PP_ITERATION_1 132
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 133 && BOOST_PP_ITERATION_FINISH_1 >= 133
+#        define BOOST_PP_ITERATION_1 133
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 134 && BOOST_PP_ITERATION_FINISH_1 >= 134
+#        define BOOST_PP_ITERATION_1 134
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 135 && BOOST_PP_ITERATION_FINISH_1 >= 135
+#        define BOOST_PP_ITERATION_1 135
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 136 && BOOST_PP_ITERATION_FINISH_1 >= 136
+#        define BOOST_PP_ITERATION_1 136
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 137 && BOOST_PP_ITERATION_FINISH_1 >= 137
+#        define BOOST_PP_ITERATION_1 137
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 138 && BOOST_PP_ITERATION_FINISH_1 >= 138
+#        define BOOST_PP_ITERATION_1 138
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 139 && BOOST_PP_ITERATION_FINISH_1 >= 139
+#        define BOOST_PP_ITERATION_1 139
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 140 && BOOST_PP_ITERATION_FINISH_1 >= 140
+#        define BOOST_PP_ITERATION_1 140
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 141 && BOOST_PP_ITERATION_FINISH_1 >= 141
+#        define BOOST_PP_ITERATION_1 141
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 142 && BOOST_PP_ITERATION_FINISH_1 >= 142
+#        define BOOST_PP_ITERATION_1 142
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 143 && BOOST_PP_ITERATION_FINISH_1 >= 143
+#        define BOOST_PP_ITERATION_1 143
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 144 && BOOST_PP_ITERATION_FINISH_1 >= 144
+#        define BOOST_PP_ITERATION_1 144
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 145 && BOOST_PP_ITERATION_FINISH_1 >= 145
+#        define BOOST_PP_ITERATION_1 145
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 146 && BOOST_PP_ITERATION_FINISH_1 >= 146
+#        define BOOST_PP_ITERATION_1 146
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 147 && BOOST_PP_ITERATION_FINISH_1 >= 147
+#        define BOOST_PP_ITERATION_1 147
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 148 && BOOST_PP_ITERATION_FINISH_1 >= 148
+#        define BOOST_PP_ITERATION_1 148
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 149 && BOOST_PP_ITERATION_FINISH_1 >= 149
+#        define BOOST_PP_ITERATION_1 149
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 150 && BOOST_PP_ITERATION_FINISH_1 >= 150
+#        define BOOST_PP_ITERATION_1 150
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 151 && BOOST_PP_ITERATION_FINISH_1 >= 151
+#        define BOOST_PP_ITERATION_1 151
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 152 && BOOST_PP_ITERATION_FINISH_1 >= 152
+#        define BOOST_PP_ITERATION_1 152
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 153 && BOOST_PP_ITERATION_FINISH_1 >= 153
+#        define BOOST_PP_ITERATION_1 153
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 154 && BOOST_PP_ITERATION_FINISH_1 >= 154
+#        define BOOST_PP_ITERATION_1 154
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 155 && BOOST_PP_ITERATION_FINISH_1 >= 155
+#        define BOOST_PP_ITERATION_1 155
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 156 && BOOST_PP_ITERATION_FINISH_1 >= 156
+#        define BOOST_PP_ITERATION_1 156
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 157 && BOOST_PP_ITERATION_FINISH_1 >= 157
+#        define BOOST_PP_ITERATION_1 157
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 158 && BOOST_PP_ITERATION_FINISH_1 >= 158
+#        define BOOST_PP_ITERATION_1 158
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 159 && BOOST_PP_ITERATION_FINISH_1 >= 159
+#        define BOOST_PP_ITERATION_1 159
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 160 && BOOST_PP_ITERATION_FINISH_1 >= 160
+#        define BOOST_PP_ITERATION_1 160
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 161 && BOOST_PP_ITERATION_FINISH_1 >= 161
+#        define BOOST_PP_ITERATION_1 161
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 162 && BOOST_PP_ITERATION_FINISH_1 >= 162
+#        define BOOST_PP_ITERATION_1 162
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 163 && BOOST_PP_ITERATION_FINISH_1 >= 163
+#        define BOOST_PP_ITERATION_1 163
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 164 && BOOST_PP_ITERATION_FINISH_1 >= 164
+#        define BOOST_PP_ITERATION_1 164
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 165 && BOOST_PP_ITERATION_FINISH_1 >= 165
+#        define BOOST_PP_ITERATION_1 165
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 166 && BOOST_PP_ITERATION_FINISH_1 >= 166
+#        define BOOST_PP_ITERATION_1 166
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 167 && BOOST_PP_ITERATION_FINISH_1 >= 167
+#        define BOOST_PP_ITERATION_1 167
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 168 && BOOST_PP_ITERATION_FINISH_1 >= 168
+#        define BOOST_PP_ITERATION_1 168
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 169 && BOOST_PP_ITERATION_FINISH_1 >= 169
+#        define BOOST_PP_ITERATION_1 169
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 170 && BOOST_PP_ITERATION_FINISH_1 >= 170
+#        define BOOST_PP_ITERATION_1 170
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 171 && BOOST_PP_ITERATION_FINISH_1 >= 171
+#        define BOOST_PP_ITERATION_1 171
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 172 && BOOST_PP_ITERATION_FINISH_1 >= 172
+#        define BOOST_PP_ITERATION_1 172
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 173 && BOOST_PP_ITERATION_FINISH_1 >= 173
+#        define BOOST_PP_ITERATION_1 173
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 174 && BOOST_PP_ITERATION_FINISH_1 >= 174
+#        define BOOST_PP_ITERATION_1 174
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 175 && BOOST_PP_ITERATION_FINISH_1 >= 175
+#        define BOOST_PP_ITERATION_1 175
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 176 && BOOST_PP_ITERATION_FINISH_1 >= 176
+#        define BOOST_PP_ITERATION_1 176
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 177 && BOOST_PP_ITERATION_FINISH_1 >= 177
+#        define BOOST_PP_ITERATION_1 177
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 178 && BOOST_PP_ITERATION_FINISH_1 >= 178
+#        define BOOST_PP_ITERATION_1 178
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 179 && BOOST_PP_ITERATION_FINISH_1 >= 179
+#        define BOOST_PP_ITERATION_1 179
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 180 && BOOST_PP_ITERATION_FINISH_1 >= 180
+#        define BOOST_PP_ITERATION_1 180
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 181 && BOOST_PP_ITERATION_FINISH_1 >= 181
+#        define BOOST_PP_ITERATION_1 181
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 182 && BOOST_PP_ITERATION_FINISH_1 >= 182
+#        define BOOST_PP_ITERATION_1 182
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 183 && BOOST_PP_ITERATION_FINISH_1 >= 183
+#        define BOOST_PP_ITERATION_1 183
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 184 && BOOST_PP_ITERATION_FINISH_1 >= 184
+#        define BOOST_PP_ITERATION_1 184
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 185 && BOOST_PP_ITERATION_FINISH_1 >= 185
+#        define BOOST_PP_ITERATION_1 185
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 186 && BOOST_PP_ITERATION_FINISH_1 >= 186
+#        define BOOST_PP_ITERATION_1 186
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 187 && BOOST_PP_ITERATION_FINISH_1 >= 187
+#        define BOOST_PP_ITERATION_1 187
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 188 && BOOST_PP_ITERATION_FINISH_1 >= 188
+#        define BOOST_PP_ITERATION_1 188
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 189 && BOOST_PP_ITERATION_FINISH_1 >= 189
+#        define BOOST_PP_ITERATION_1 189
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 190 && BOOST_PP_ITERATION_FINISH_1 >= 190
+#        define BOOST_PP_ITERATION_1 190
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 191 && BOOST_PP_ITERATION_FINISH_1 >= 191
+#        define BOOST_PP_ITERATION_1 191
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 192 && BOOST_PP_ITERATION_FINISH_1 >= 192
+#        define BOOST_PP_ITERATION_1 192
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 193 && BOOST_PP_ITERATION_FINISH_1 >= 193
+#        define BOOST_PP_ITERATION_1 193
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 194 && BOOST_PP_ITERATION_FINISH_1 >= 194
+#        define BOOST_PP_ITERATION_1 194
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 195 && BOOST_PP_ITERATION_FINISH_1 >= 195
+#        define BOOST_PP_ITERATION_1 195
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 196 && BOOST_PP_ITERATION_FINISH_1 >= 196
+#        define BOOST_PP_ITERATION_1 196
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 197 && BOOST_PP_ITERATION_FINISH_1 >= 197
+#        define BOOST_PP_ITERATION_1 197
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 198 && BOOST_PP_ITERATION_FINISH_1 >= 198
+#        define BOOST_PP_ITERATION_1 198
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 199 && BOOST_PP_ITERATION_FINISH_1 >= 199
+#        define BOOST_PP_ITERATION_1 199
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 200 && BOOST_PP_ITERATION_FINISH_1 >= 200
+#        define BOOST_PP_ITERATION_1 200
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 201 && BOOST_PP_ITERATION_FINISH_1 >= 201
+#        define BOOST_PP_ITERATION_1 201
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 202 && BOOST_PP_ITERATION_FINISH_1 >= 202
+#        define BOOST_PP_ITERATION_1 202
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 203 && BOOST_PP_ITERATION_FINISH_1 >= 203
+#        define BOOST_PP_ITERATION_1 203
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 204 && BOOST_PP_ITERATION_FINISH_1 >= 204
+#        define BOOST_PP_ITERATION_1 204
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 205 && BOOST_PP_ITERATION_FINISH_1 >= 205
+#        define BOOST_PP_ITERATION_1 205
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 206 && BOOST_PP_ITERATION_FINISH_1 >= 206
+#        define BOOST_PP_ITERATION_1 206
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 207 && BOOST_PP_ITERATION_FINISH_1 >= 207
+#        define BOOST_PP_ITERATION_1 207
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 208 && BOOST_PP_ITERATION_FINISH_1 >= 208
+#        define BOOST_PP_ITERATION_1 208
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 209 && BOOST_PP_ITERATION_FINISH_1 >= 209
+#        define BOOST_PP_ITERATION_1 209
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 210 && BOOST_PP_ITERATION_FINISH_1 >= 210
+#        define BOOST_PP_ITERATION_1 210
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 211 && BOOST_PP_ITERATION_FINISH_1 >= 211
+#        define BOOST_PP_ITERATION_1 211
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 212 && BOOST_PP_ITERATION_FINISH_1 >= 212
+#        define BOOST_PP_ITERATION_1 212
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 213 && BOOST_PP_ITERATION_FINISH_1 >= 213
+#        define BOOST_PP_ITERATION_1 213
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 214 && BOOST_PP_ITERATION_FINISH_1 >= 214
+#        define BOOST_PP_ITERATION_1 214
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 215 && BOOST_PP_ITERATION_FINISH_1 >= 215
+#        define BOOST_PP_ITERATION_1 215
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 216 && BOOST_PP_ITERATION_FINISH_1 >= 216
+#        define BOOST_PP_ITERATION_1 216
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 217 && BOOST_PP_ITERATION_FINISH_1 >= 217
+#        define BOOST_PP_ITERATION_1 217
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 218 && BOOST_PP_ITERATION_FINISH_1 >= 218
+#        define BOOST_PP_ITERATION_1 218
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 219 && BOOST_PP_ITERATION_FINISH_1 >= 219
+#        define BOOST_PP_ITERATION_1 219
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 220 && BOOST_PP_ITERATION_FINISH_1 >= 220
+#        define BOOST_PP_ITERATION_1 220
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 221 && BOOST_PP_ITERATION_FINISH_1 >= 221
+#        define BOOST_PP_ITERATION_1 221
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 222 && BOOST_PP_ITERATION_FINISH_1 >= 222
+#        define BOOST_PP_ITERATION_1 222
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 223 && BOOST_PP_ITERATION_FINISH_1 >= 223
+#        define BOOST_PP_ITERATION_1 223
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 224 && BOOST_PP_ITERATION_FINISH_1 >= 224
+#        define BOOST_PP_ITERATION_1 224
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 225 && BOOST_PP_ITERATION_FINISH_1 >= 225
+#        define BOOST_PP_ITERATION_1 225
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 226 && BOOST_PP_ITERATION_FINISH_1 >= 226
+#        define BOOST_PP_ITERATION_1 226
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 227 && BOOST_PP_ITERATION_FINISH_1 >= 227
+#        define BOOST_PP_ITERATION_1 227
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 228 && BOOST_PP_ITERATION_FINISH_1 >= 228
+#        define BOOST_PP_ITERATION_1 228
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 229 && BOOST_PP_ITERATION_FINISH_1 >= 229
+#        define BOOST_PP_ITERATION_1 229
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 230 && BOOST_PP_ITERATION_FINISH_1 >= 230
+#        define BOOST_PP_ITERATION_1 230
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 231 && BOOST_PP_ITERATION_FINISH_1 >= 231
+#        define BOOST_PP_ITERATION_1 231
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 232 && BOOST_PP_ITERATION_FINISH_1 >= 232
+#        define BOOST_PP_ITERATION_1 232
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 233 && BOOST_PP_ITERATION_FINISH_1 >= 233
+#        define BOOST_PP_ITERATION_1 233
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 234 && BOOST_PP_ITERATION_FINISH_1 >= 234
+#        define BOOST_PP_ITERATION_1 234
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 235 && BOOST_PP_ITERATION_FINISH_1 >= 235
+#        define BOOST_PP_ITERATION_1 235
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 236 && BOOST_PP_ITERATION_FINISH_1 >= 236
+#        define BOOST_PP_ITERATION_1 236
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 237 && BOOST_PP_ITERATION_FINISH_1 >= 237
+#        define BOOST_PP_ITERATION_1 237
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 238 && BOOST_PP_ITERATION_FINISH_1 >= 238
+#        define BOOST_PP_ITERATION_1 238
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 239 && BOOST_PP_ITERATION_FINISH_1 >= 239
+#        define BOOST_PP_ITERATION_1 239
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 240 && BOOST_PP_ITERATION_FINISH_1 >= 240
+#        define BOOST_PP_ITERATION_1 240
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 241 && BOOST_PP_ITERATION_FINISH_1 >= 241
+#        define BOOST_PP_ITERATION_1 241
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 242 && BOOST_PP_ITERATION_FINISH_1 >= 242
+#        define BOOST_PP_ITERATION_1 242
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 243 && BOOST_PP_ITERATION_FINISH_1 >= 243
+#        define BOOST_PP_ITERATION_1 243
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 244 && BOOST_PP_ITERATION_FINISH_1 >= 244
+#        define BOOST_PP_ITERATION_1 244
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 245 && BOOST_PP_ITERATION_FINISH_1 >= 245
+#        define BOOST_PP_ITERATION_1 245
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 246 && BOOST_PP_ITERATION_FINISH_1 >= 246
+#        define BOOST_PP_ITERATION_1 246
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 247 && BOOST_PP_ITERATION_FINISH_1 >= 247
+#        define BOOST_PP_ITERATION_1 247
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 248 && BOOST_PP_ITERATION_FINISH_1 >= 248
+#        define BOOST_PP_ITERATION_1 248
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 249 && BOOST_PP_ITERATION_FINISH_1 >= 249
+#        define BOOST_PP_ITERATION_1 249
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 250 && BOOST_PP_ITERATION_FINISH_1 >= 250
+#        define BOOST_PP_ITERATION_1 250
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 251 && BOOST_PP_ITERATION_FINISH_1 >= 251
+#        define BOOST_PP_ITERATION_1 251
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 252 && BOOST_PP_ITERATION_FINISH_1 >= 252
+#        define BOOST_PP_ITERATION_1 252
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 253 && BOOST_PP_ITERATION_FINISH_1 >= 253
+#        define BOOST_PP_ITERATION_1 253
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 254 && BOOST_PP_ITERATION_FINISH_1 >= 254
+#        define BOOST_PP_ITERATION_1 254
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 255 && BOOST_PP_ITERATION_FINISH_1 >= 255
+#        define BOOST_PP_ITERATION_1 255
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+#    if BOOST_PP_ITERATION_START_1 <= 256 && BOOST_PP_ITERATION_FINISH_1 >= 256
+#        define BOOST_PP_ITERATION_1 256
+#        include BOOST_PP_FILENAME_1
+#        undef BOOST_PP_ITERATION_1
+#    endif
+# endif
+#
+# undef BOOST_PP_IS_ITERATING
+#
+# undef BOOST_PP_ITERATION_DEPTH
+# define BOOST_PP_ITERATION_DEPTH() 0
+#
+# undef BOOST_PP_ITERATION_START_1
+# undef BOOST_PP_ITERATION_FINISH_1
+# undef BOOST_PP_FILENAME_1
+#
+# undef BOOST_PP_ITERATION_FLAGS_1
+# undef BOOST_PP_ITERATION_PARAMS_1
diff --git a/third_party/boost/boost/preprocessor/iteration/iterate.hpp b/third_party/boost/boost/preprocessor/iteration/iterate.hpp
new file mode 100644
index 0000000..8f861e7
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/iteration/iterate.hpp
@@ -0,0 +1,82 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ITERATION_ITERATE_HPP
+# define BOOST_PREPROCESSOR_ITERATION_ITERATE_HPP
+#
+# include <boost/preprocessor/arithmetic/dec.hpp>
+# include <boost/preprocessor/arithmetic/inc.hpp>
+# include <boost/preprocessor/array/elem.hpp>
+# include <boost/preprocessor/array/size.hpp>
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/slot/slot.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+#
+# /* BOOST_PP_ITERATION_DEPTH */
+#
+# define BOOST_PP_ITERATION_DEPTH() 0
+#
+# /* BOOST_PP_ITERATION */
+#
+# define BOOST_PP_ITERATION() BOOST_PP_CAT(BOOST_PP_ITERATION_, BOOST_PP_ITERATION_DEPTH())
+#
+# /* BOOST_PP_ITERATION_START && BOOST_PP_ITERATION_FINISH */
+#
+# define BOOST_PP_ITERATION_START() BOOST_PP_CAT(BOOST_PP_ITERATION_START_, BOOST_PP_ITERATION_DEPTH())
+# define BOOST_PP_ITERATION_FINISH() BOOST_PP_CAT(BOOST_PP_ITERATION_FINISH_, BOOST_PP_ITERATION_DEPTH())
+#
+# /* BOOST_PP_ITERATION_FLAGS */
+#
+# define BOOST_PP_ITERATION_FLAGS() (BOOST_PP_CAT(BOOST_PP_ITERATION_FLAGS_, BOOST_PP_ITERATION_DEPTH())())
+#
+# /* BOOST_PP_FRAME_ITERATION */
+#
+# define BOOST_PP_FRAME_ITERATION(i) BOOST_PP_CAT(BOOST_PP_ITERATION_, i)
+#
+# /* BOOST_PP_FRAME_START && BOOST_PP_FRAME_FINISH */
+#
+# define BOOST_PP_FRAME_START(i) BOOST_PP_CAT(BOOST_PP_ITERATION_START_, i)
+# define BOOST_PP_FRAME_FINISH(i) BOOST_PP_CAT(BOOST_PP_ITERATION_FINISH_, i)
+#
+# /* BOOST_PP_FRAME_FLAGS */
+#
+# define BOOST_PP_FRAME_FLAGS(i) (BOOST_PP_CAT(BOOST_PP_ITERATION_FLAGS_, i)())
+#
+# /* BOOST_PP_RELATIVE_ITERATION */
+#
+# define BOOST_PP_RELATIVE_ITERATION(i) BOOST_PP_CAT(BOOST_PP_RELATIVE_, i)(BOOST_PP_ITERATION_)
+#
+# define BOOST_PP_RELATIVE_0(m) BOOST_PP_CAT(m, BOOST_PP_ITERATION_DEPTH())
+# define BOOST_PP_RELATIVE_1(m) BOOST_PP_CAT(m, BOOST_PP_DEC(BOOST_PP_ITERATION_DEPTH()))
+# define BOOST_PP_RELATIVE_2(m) BOOST_PP_CAT(m, BOOST_PP_DEC(BOOST_PP_DEC(BOOST_PP_ITERATION_DEPTH())))
+# define BOOST_PP_RELATIVE_3(m) BOOST_PP_CAT(m, BOOST_PP_DEC(BOOST_PP_DEC(BOOST_PP_DEC(BOOST_PP_ITERATION_DEPTH()))))
+# define BOOST_PP_RELATIVE_4(m) BOOST_PP_CAT(m, BOOST_PP_DEC(BOOST_PP_DEC(BOOST_PP_DEC(BOOST_PP_DEC(BOOST_PP_ITERATION_DEPTH())))))
+#
+# /* BOOST_PP_RELATIVE_START && BOOST_PP_RELATIVE_FINISH */
+#
+# define BOOST_PP_RELATIVE_START(i) BOOST_PP_CAT(BOOST_PP_RELATIVE_, i)(BOOST_PP_ITERATION_START_)
+# define BOOST_PP_RELATIVE_FINISH(i) BOOST_PP_CAT(BOOST_PP_RELATIVE_, i)(BOOST_PP_ITERATION_FINISH_)
+#
+# /* BOOST_PP_RELATIVE_FLAGS */
+#
+# define BOOST_PP_RELATIVE_FLAGS(i) (BOOST_PP_CAT(BOOST_PP_RELATIVE_, i)(BOOST_PP_ITERATION_FLAGS_)())
+#
+# /* BOOST_PP_ITERATE */
+#
+# define BOOST_PP_ITERATE() BOOST_PP_CAT(BOOST_PP_ITERATE_, BOOST_PP_INC(BOOST_PP_ITERATION_DEPTH()))
+#
+# define BOOST_PP_ITERATE_1 <boost/preprocessor/iteration/detail/iter/forward1.hpp>
+# define BOOST_PP_ITERATE_2 <boost/preprocessor/iteration/detail/iter/forward2.hpp>
+# define BOOST_PP_ITERATE_3 <boost/preprocessor/iteration/detail/iter/forward3.hpp>
+# define BOOST_PP_ITERATE_4 <boost/preprocessor/iteration/detail/iter/forward4.hpp>
+# define BOOST_PP_ITERATE_5 <boost/preprocessor/iteration/detail/iter/forward5.hpp>
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/iteration/local.hpp b/third_party/boost/boost/preprocessor/iteration/local.hpp
new file mode 100644
index 0000000..289fb1a
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/iteration/local.hpp
@@ -0,0 +1,26 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ITERATION_LOCAL_HPP
+# define BOOST_PREPROCESSOR_ITERATION_LOCAL_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/slot/slot.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+#
+# /* BOOST_PP_LOCAL_ITERATE */
+#
+# define BOOST_PP_LOCAL_ITERATE() <boost/preprocessor/iteration/detail/local.hpp>
+#
+# define BOOST_PP_LOCAL_C(n) (BOOST_PP_LOCAL_S) <= n && (BOOST_PP_LOCAL_F) >= n
+# define BOOST_PP_LOCAL_R(n) (BOOST_PP_LOCAL_F) <= n && (BOOST_PP_LOCAL_S) >= n
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/iteration/self.hpp b/third_party/boost/boost/preprocessor/iteration/self.hpp
new file mode 100644
index 0000000..6e0464c
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/iteration/self.hpp
@@ -0,0 +1,19 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_ITERATION_SELF_HPP
+# define BOOST_PREPROCESSOR_ITERATION_SELF_HPP
+#
+# /* BOOST_PP_INCLUDE_SELF */
+#
+# define BOOST_PP_INCLUDE_SELF() <boost/preprocessor/iteration/detail/self.hpp>
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/list/adt.hpp b/third_party/boost/boost/preprocessor/list/adt.hpp
new file mode 100644
index 0000000..b4f12ba
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/list/adt.hpp
@@ -0,0 +1,73 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  *
+#  * See http://www.boost.org for most recent version.
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# ifndef BOOST_PREPROCESSOR_LIST_ADT_HPP
+# define BOOST_PREPROCESSOR_LIST_ADT_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/detail/is_binary.hpp>
+# include <boost/preprocessor/logical/compl.hpp>
+# include <boost/preprocessor/tuple/eat.hpp>
+#
+# /* BOOST_PP_LIST_CONS */
+#
+# define BOOST_PP_LIST_CONS(head, tail) (head, tail)
+#
+# /* BOOST_PP_LIST_NIL */
+#
+# define BOOST_PP_LIST_NIL BOOST_PP_NIL
+#
+# /* BOOST_PP_LIST_FIRST */
+#
+# define BOOST_PP_LIST_FIRST(list) BOOST_PP_LIST_FIRST_D(list)
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#    define BOOST_PP_LIST_FIRST_D(list) BOOST_PP_LIST_FIRST_I list
+# else
+#    define BOOST_PP_LIST_FIRST_D(list) BOOST_PP_LIST_FIRST_I ## list
+# endif
+#
+# define BOOST_PP_LIST_FIRST_I(head, tail) head
+#
+# /* BOOST_PP_LIST_REST */
+#
+# define BOOST_PP_LIST_REST(list) BOOST_PP_LIST_REST_D(list)
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#    define BOOST_PP_LIST_REST_D(list) BOOST_PP_LIST_REST_I list
+# else
+#    define BOOST_PP_LIST_REST_D(list) BOOST_PP_LIST_REST_I ## list
+# endif
+#
+# define BOOST_PP_LIST_REST_I(head, tail) tail
+#
+# /* BOOST_PP_LIST_IS_CONS */
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_BCC()
+#    define BOOST_PP_LIST_IS_CONS(list) BOOST_PP_LIST_IS_CONS_D(list)
+#    define BOOST_PP_LIST_IS_CONS_D(list) BOOST_PP_LIST_IS_CONS_ ## list
+#    define BOOST_PP_LIST_IS_CONS_(head, tail) 1
+#    define BOOST_PP_LIST_IS_CONS_BOOST_PP_NIL 0
+# else
+#    define BOOST_PP_LIST_IS_CONS(list) BOOST_PP_IS_BINARY(list)
+# endif
+#
+# /* BOOST_PP_LIST_IS_NIL */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_BCC()
+#    define BOOST_PP_LIST_IS_NIL(list) BOOST_PP_COMPL(BOOST_PP_IS_BINARY(list))
+# else
+#    define BOOST_PP_LIST_IS_NIL(list) BOOST_PP_COMPL(BOOST_PP_LIST_IS_CONS(list))
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/list/detail/fold_left.hpp b/third_party/boost/boost/preprocessor/list/detail/fold_left.hpp
new file mode 100644
index 0000000..f5fcab7
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/list/detail/fold_left.hpp
@@ -0,0 +1,279 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_LIST_DETAIL_FOLD_LEFT_HPP
+# define BOOST_PREPROCESSOR_LIST_DETAIL_FOLD_LEFT_HPP
+#
+# include <boost/preprocessor/control/expr_iif.hpp>
+# include <boost/preprocessor/control/iif.hpp>
+# include <boost/preprocessor/list/adt.hpp>
+# include <boost/preprocessor/tuple/eat.hpp>
+#
+# define BOOST_PP_LIST_FOLD_LEFT_1(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_2, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(2, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_2(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_3, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(3, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_3(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_4, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(4, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_4(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_5, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(5, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_5(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_6, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(6, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_6(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_7, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(7, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_7(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_8, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(8, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_8(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_9, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(9, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_9(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_10, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(10, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_10(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_11, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(11, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_11(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_12, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(12, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_12(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_13, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(13, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_13(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_14, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(14, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_14(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_15, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(15, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_15(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_16, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(16, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_16(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_17, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(17, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_17(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_18, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(18, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_18(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_19, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(19, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_19(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_20, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(20, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_20(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_21, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(21, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_21(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_22, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(22, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_22(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_23, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(23, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_23(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_24, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(24, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_24(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_25, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(25, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_25(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_26, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(26, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_26(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_27, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(27, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_27(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_28, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(28, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_28(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_29, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(29, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_29(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_30, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(30, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_30(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_31, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(31, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_31(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_32, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(32, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_32(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_33, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(33, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_33(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_34, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(34, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_34(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_35, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(35, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_35(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_36, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(36, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_36(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_37, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(37, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_37(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_38, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(38, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_38(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_39, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(39, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_39(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_40, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(40, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_40(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_41, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(41, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_41(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_42, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(42, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_42(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_43, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(43, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_43(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_44, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(44, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_44(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_45, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(45, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_45(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_46, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(46, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_46(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_47, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(47, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_47(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_48, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(48, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_48(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_49, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(49, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_49(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_50, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(50, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_50(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_51, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(51, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_51(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_52, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(52, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_52(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_53, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(53, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_53(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_54, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(54, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_54(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_55, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(55, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_55(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_56, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(56, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_56(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_57, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(57, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_57(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_58, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(58, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_58(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_59, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(59, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_59(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_60, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(60, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_60(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_61, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(61, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_61(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_62, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(62, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_62(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_63, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(63, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_63(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_64, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(64, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_64(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_65, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(65, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_65(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_66, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(66, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_66(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_67, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(67, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_67(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_68, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(68, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_68(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_69, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(69, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_69(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_70, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(70, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_70(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_71, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(71, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_71(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_72, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(72, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_72(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_73, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(73, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_73(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_74, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(74, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_74(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_75, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(75, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_75(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_76, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(76, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_76(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_77, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(77, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_77(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_78, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(78, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_78(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_79, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(79, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_79(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_80, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(80, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_80(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_81, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(81, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_81(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_82, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(82, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_82(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_83, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(83, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_83(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_84, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(84, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_84(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_85, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(85, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_85(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_86, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(86, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_86(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_87, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(87, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_87(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_88, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(88, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_88(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_89, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(89, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_89(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_90, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(90, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_90(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_91, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(91, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_91(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_92, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(92, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_92(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_93, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(93, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_93(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_94, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(94, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_94(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_95, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(95, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_95(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_96, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(96, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_96(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_97, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(97, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_97(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_98, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(98, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_98(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_99, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(99, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_99(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_100, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(100, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_100(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_101, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(101, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_101(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_102, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(102, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_102(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_103, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(103, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_103(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_104, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(104, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_104(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_105, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(105, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_105(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_106, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(106, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_106(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_107, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(107, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_107(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_108, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(108, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_108(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_109, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(109, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_109(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_110, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(110, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_110(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_111, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(111, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_111(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_112, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(112, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_112(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_113, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(113, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_113(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_114, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(114, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_114(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_115, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(115, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_115(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_116, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(116, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_116(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_117, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(117, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_117(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_118, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(118, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_118(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_119, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(119, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_119(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_120, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(120, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_120(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_121, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(121, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_121(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_122, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(122, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_122(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_123, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(123, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_123(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_124, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(124, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_124(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_125, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(125, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_125(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_126, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(126, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_126(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_127, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(127, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_127(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_128, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(128, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_128(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_129, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(129, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_129(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_130, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(130, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_130(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_131, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(131, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_131(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_132, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(132, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_132(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_133, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(133, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_133(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_134, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(134, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_134(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_135, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(135, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_135(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_136, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(136, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_136(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_137, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(137, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_137(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_138, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(138, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_138(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_139, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(139, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_139(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_140, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(140, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_140(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_141, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(141, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_141(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_142, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(142, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_142(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_143, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(143, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_143(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_144, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(144, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_144(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_145, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(145, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_145(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_146, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(146, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_146(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_147, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(147, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_147(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_148, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(148, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_148(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_149, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(149, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_149(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_150, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(150, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_150(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_151, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(151, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_151(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_152, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(152, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_152(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_153, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(153, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_153(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_154, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(154, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_154(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_155, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(155, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_155(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_156, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(156, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_156(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_157, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(157, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_157(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_158, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(158, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_158(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_159, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(159, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_159(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_160, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(160, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_160(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_161, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(161, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_161(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_162, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(162, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_162(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_163, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(163, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_163(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_164, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(164, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_164(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_165, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(165, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_165(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_166, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(166, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_166(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_167, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(167, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_167(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_168, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(168, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_168(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_169, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(169, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_169(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_170, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(170, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_170(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_171, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(171, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_171(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_172, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(172, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_172(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_173, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(173, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_173(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_174, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(174, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_174(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_175, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(175, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_175(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_176, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(176, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_176(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_177, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(177, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_177(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_178, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(178, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_178(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_179, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(179, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_179(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_180, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(180, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_180(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_181, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(181, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_181(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_182, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(182, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_182(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_183, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(183, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_183(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_184, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(184, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_184(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_185, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(185, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_185(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_186, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(186, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_186(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_187, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(187, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_187(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_188, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(188, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_188(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_189, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(189, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_189(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_190, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(190, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_190(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_191, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(191, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_191(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_192, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(192, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_192(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_193, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(193, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_193(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_194, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(194, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_194(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_195, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(195, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_195(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_196, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(196, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_196(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_197, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(197, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_197(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_198, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(198, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_198(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_199, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(199, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_199(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_200, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(200, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_200(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_201, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(201, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_201(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_202, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(202, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_202(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_203, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(203, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_203(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_204, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(204, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_204(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_205, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(205, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_205(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_206, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(206, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_206(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_207, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(207, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_207(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_208, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(208, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_208(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_209, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(209, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_209(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_210, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(210, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_210(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_211, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(211, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_211(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_212, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(212, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_212(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_213, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(213, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_213(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_214, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(214, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_214(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_215, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(215, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_215(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_216, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(216, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_216(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_217, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(217, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_217(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_218, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(218, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_218(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_219, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(219, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_219(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_220, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(220, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_220(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_221, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(221, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_221(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_222, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(222, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_222(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_223, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(223, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_223(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_224, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(224, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_224(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_225, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(225, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_225(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_226, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(226, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_226(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_227, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(227, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_227(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_228, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(228, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_228(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_229, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(229, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_229(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_230, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(230, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_230(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_231, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(231, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_231(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_232, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(232, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_232(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_233, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(233, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_233(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_234, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(234, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_234(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_235, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(235, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_235(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_236, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(236, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_236(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_237, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(237, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_237(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_238, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(238, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_238(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_239, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(239, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_239(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_240, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(240, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_240(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_241, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(241, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_241(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_242, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(242, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_242(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_243, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(243, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_243(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_244, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(244, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_244(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_245, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(245, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_245(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_246, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(246, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_246(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_247, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(247, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_247(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_248, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(248, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_248(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_249, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(249, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_249(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_250, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(250, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_250(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_251, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(251, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_251(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_252, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(252, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_252(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_253, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(253, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_253(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_254, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(254, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_254(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_255, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(255, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_255(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_256, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(256, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+# define BOOST_PP_LIST_FOLD_LEFT_256(o, s, l) BOOST_PP_IIF(BOOST_PP_LIST_IS_CONS(l), BOOST_PP_LIST_FOLD_LEFT_257, s BOOST_PP_TUPLE_EAT_3)(o, BOOST_PP_EXPR_IIF(BOOST_PP_LIST_IS_CONS(l), o)(257, s, BOOST_PP_LIST_FIRST(l)), BOOST_PP_LIST_REST(l))
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/list/detail/fold_right.hpp b/third_party/boost/boost/preprocessor/list/detail/fold_right.hpp
new file mode 100644
index 0000000..29146d5
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/list/detail/fold_right.hpp
@@ -0,0 +1,277 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_LIST_DETAIL_FOLD_RIGHT_HPP
+# define BOOST_PREPROCESSOR_LIST_DETAIL_FOLD_RIGHT_HPP
+#
+# include <boost/preprocessor/list/fold_left.hpp>
+# include <boost/preprocessor/list/reverse.hpp>
+#
+# define BOOST_PP_LIST_FOLD_RIGHT_1(o, s, l) BOOST_PP_LIST_FOLD_LEFT_1(o, s, BOOST_PP_LIST_REVERSE_D(1, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_2(o, s, l) BOOST_PP_LIST_FOLD_LEFT_2(o, s, BOOST_PP_LIST_REVERSE_D(2, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_3(o, s, l) BOOST_PP_LIST_FOLD_LEFT_3(o, s, BOOST_PP_LIST_REVERSE_D(3, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_4(o, s, l) BOOST_PP_LIST_FOLD_LEFT_4(o, s, BOOST_PP_LIST_REVERSE_D(4, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_5(o, s, l) BOOST_PP_LIST_FOLD_LEFT_5(o, s, BOOST_PP_LIST_REVERSE_D(5, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_6(o, s, l) BOOST_PP_LIST_FOLD_LEFT_6(o, s, BOOST_PP_LIST_REVERSE_D(6, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_7(o, s, l) BOOST_PP_LIST_FOLD_LEFT_7(o, s, BOOST_PP_LIST_REVERSE_D(7, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_8(o, s, l) BOOST_PP_LIST_FOLD_LEFT_8(o, s, BOOST_PP_LIST_REVERSE_D(8, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_9(o, s, l) BOOST_PP_LIST_FOLD_LEFT_9(o, s, BOOST_PP_LIST_REVERSE_D(9, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_10(o, s, l) BOOST_PP_LIST_FOLD_LEFT_10(o, s, BOOST_PP_LIST_REVERSE_D(10, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_11(o, s, l) BOOST_PP_LIST_FOLD_LEFT_11(o, s, BOOST_PP_LIST_REVERSE_D(11, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_12(o, s, l) BOOST_PP_LIST_FOLD_LEFT_12(o, s, BOOST_PP_LIST_REVERSE_D(12, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_13(o, s, l) BOOST_PP_LIST_FOLD_LEFT_13(o, s, BOOST_PP_LIST_REVERSE_D(13, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_14(o, s, l) BOOST_PP_LIST_FOLD_LEFT_14(o, s, BOOST_PP_LIST_REVERSE_D(14, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_15(o, s, l) BOOST_PP_LIST_FOLD_LEFT_15(o, s, BOOST_PP_LIST_REVERSE_D(15, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_16(o, s, l) BOOST_PP_LIST_FOLD_LEFT_16(o, s, BOOST_PP_LIST_REVERSE_D(16, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_17(o, s, l) BOOST_PP_LIST_FOLD_LEFT_17(o, s, BOOST_PP_LIST_REVERSE_D(17, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_18(o, s, l) BOOST_PP_LIST_FOLD_LEFT_18(o, s, BOOST_PP_LIST_REVERSE_D(18, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_19(o, s, l) BOOST_PP_LIST_FOLD_LEFT_19(o, s, BOOST_PP_LIST_REVERSE_D(19, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_20(o, s, l) BOOST_PP_LIST_FOLD_LEFT_20(o, s, BOOST_PP_LIST_REVERSE_D(20, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_21(o, s, l) BOOST_PP_LIST_FOLD_LEFT_21(o, s, BOOST_PP_LIST_REVERSE_D(21, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_22(o, s, l) BOOST_PP_LIST_FOLD_LEFT_22(o, s, BOOST_PP_LIST_REVERSE_D(22, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_23(o, s, l) BOOST_PP_LIST_FOLD_LEFT_23(o, s, BOOST_PP_LIST_REVERSE_D(23, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_24(o, s, l) BOOST_PP_LIST_FOLD_LEFT_24(o, s, BOOST_PP_LIST_REVERSE_D(24, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_25(o, s, l) BOOST_PP_LIST_FOLD_LEFT_25(o, s, BOOST_PP_LIST_REVERSE_D(25, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_26(o, s, l) BOOST_PP_LIST_FOLD_LEFT_26(o, s, BOOST_PP_LIST_REVERSE_D(26, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_27(o, s, l) BOOST_PP_LIST_FOLD_LEFT_27(o, s, BOOST_PP_LIST_REVERSE_D(27, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_28(o, s, l) BOOST_PP_LIST_FOLD_LEFT_28(o, s, BOOST_PP_LIST_REVERSE_D(28, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_29(o, s, l) BOOST_PP_LIST_FOLD_LEFT_29(o, s, BOOST_PP_LIST_REVERSE_D(29, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_30(o, s, l) BOOST_PP_LIST_FOLD_LEFT_30(o, s, BOOST_PP_LIST_REVERSE_D(30, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_31(o, s, l) BOOST_PP_LIST_FOLD_LEFT_31(o, s, BOOST_PP_LIST_REVERSE_D(31, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_32(o, s, l) BOOST_PP_LIST_FOLD_LEFT_32(o, s, BOOST_PP_LIST_REVERSE_D(32, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_33(o, s, l) BOOST_PP_LIST_FOLD_LEFT_33(o, s, BOOST_PP_LIST_REVERSE_D(33, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_34(o, s, l) BOOST_PP_LIST_FOLD_LEFT_34(o, s, BOOST_PP_LIST_REVERSE_D(34, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_35(o, s, l) BOOST_PP_LIST_FOLD_LEFT_35(o, s, BOOST_PP_LIST_REVERSE_D(35, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_36(o, s, l) BOOST_PP_LIST_FOLD_LEFT_36(o, s, BOOST_PP_LIST_REVERSE_D(36, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_37(o, s, l) BOOST_PP_LIST_FOLD_LEFT_37(o, s, BOOST_PP_LIST_REVERSE_D(37, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_38(o, s, l) BOOST_PP_LIST_FOLD_LEFT_38(o, s, BOOST_PP_LIST_REVERSE_D(38, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_39(o, s, l) BOOST_PP_LIST_FOLD_LEFT_39(o, s, BOOST_PP_LIST_REVERSE_D(39, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_40(o, s, l) BOOST_PP_LIST_FOLD_LEFT_40(o, s, BOOST_PP_LIST_REVERSE_D(40, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_41(o, s, l) BOOST_PP_LIST_FOLD_LEFT_41(o, s, BOOST_PP_LIST_REVERSE_D(41, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_42(o, s, l) BOOST_PP_LIST_FOLD_LEFT_42(o, s, BOOST_PP_LIST_REVERSE_D(42, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_43(o, s, l) BOOST_PP_LIST_FOLD_LEFT_43(o, s, BOOST_PP_LIST_REVERSE_D(43, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_44(o, s, l) BOOST_PP_LIST_FOLD_LEFT_44(o, s, BOOST_PP_LIST_REVERSE_D(44, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_45(o, s, l) BOOST_PP_LIST_FOLD_LEFT_45(o, s, BOOST_PP_LIST_REVERSE_D(45, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_46(o, s, l) BOOST_PP_LIST_FOLD_LEFT_46(o, s, BOOST_PP_LIST_REVERSE_D(46, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_47(o, s, l) BOOST_PP_LIST_FOLD_LEFT_47(o, s, BOOST_PP_LIST_REVERSE_D(47, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_48(o, s, l) BOOST_PP_LIST_FOLD_LEFT_48(o, s, BOOST_PP_LIST_REVERSE_D(48, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_49(o, s, l) BOOST_PP_LIST_FOLD_LEFT_49(o, s, BOOST_PP_LIST_REVERSE_D(49, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_50(o, s, l) BOOST_PP_LIST_FOLD_LEFT_50(o, s, BOOST_PP_LIST_REVERSE_D(50, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_51(o, s, l) BOOST_PP_LIST_FOLD_LEFT_51(o, s, BOOST_PP_LIST_REVERSE_D(51, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_52(o, s, l) BOOST_PP_LIST_FOLD_LEFT_52(o, s, BOOST_PP_LIST_REVERSE_D(52, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_53(o, s, l) BOOST_PP_LIST_FOLD_LEFT_53(o, s, BOOST_PP_LIST_REVERSE_D(53, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_54(o, s, l) BOOST_PP_LIST_FOLD_LEFT_54(o, s, BOOST_PP_LIST_REVERSE_D(54, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_55(o, s, l) BOOST_PP_LIST_FOLD_LEFT_55(o, s, BOOST_PP_LIST_REVERSE_D(55, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_56(o, s, l) BOOST_PP_LIST_FOLD_LEFT_56(o, s, BOOST_PP_LIST_REVERSE_D(56, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_57(o, s, l) BOOST_PP_LIST_FOLD_LEFT_57(o, s, BOOST_PP_LIST_REVERSE_D(57, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_58(o, s, l) BOOST_PP_LIST_FOLD_LEFT_58(o, s, BOOST_PP_LIST_REVERSE_D(58, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_59(o, s, l) BOOST_PP_LIST_FOLD_LEFT_59(o, s, BOOST_PP_LIST_REVERSE_D(59, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_60(o, s, l) BOOST_PP_LIST_FOLD_LEFT_60(o, s, BOOST_PP_LIST_REVERSE_D(60, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_61(o, s, l) BOOST_PP_LIST_FOLD_LEFT_61(o, s, BOOST_PP_LIST_REVERSE_D(61, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_62(o, s, l) BOOST_PP_LIST_FOLD_LEFT_62(o, s, BOOST_PP_LIST_REVERSE_D(62, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_63(o, s, l) BOOST_PP_LIST_FOLD_LEFT_63(o, s, BOOST_PP_LIST_REVERSE_D(63, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_64(o, s, l) BOOST_PP_LIST_FOLD_LEFT_64(o, s, BOOST_PP_LIST_REVERSE_D(64, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_65(o, s, l) BOOST_PP_LIST_FOLD_LEFT_65(o, s, BOOST_PP_LIST_REVERSE_D(65, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_66(o, s, l) BOOST_PP_LIST_FOLD_LEFT_66(o, s, BOOST_PP_LIST_REVERSE_D(66, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_67(o, s, l) BOOST_PP_LIST_FOLD_LEFT_67(o, s, BOOST_PP_LIST_REVERSE_D(67, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_68(o, s, l) BOOST_PP_LIST_FOLD_LEFT_68(o, s, BOOST_PP_LIST_REVERSE_D(68, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_69(o, s, l) BOOST_PP_LIST_FOLD_LEFT_69(o, s, BOOST_PP_LIST_REVERSE_D(69, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_70(o, s, l) BOOST_PP_LIST_FOLD_LEFT_70(o, s, BOOST_PP_LIST_REVERSE_D(70, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_71(o, s, l) BOOST_PP_LIST_FOLD_LEFT_71(o, s, BOOST_PP_LIST_REVERSE_D(71, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_72(o, s, l) BOOST_PP_LIST_FOLD_LEFT_72(o, s, BOOST_PP_LIST_REVERSE_D(72, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_73(o, s, l) BOOST_PP_LIST_FOLD_LEFT_73(o, s, BOOST_PP_LIST_REVERSE_D(73, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_74(o, s, l) BOOST_PP_LIST_FOLD_LEFT_74(o, s, BOOST_PP_LIST_REVERSE_D(74, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_75(o, s, l) BOOST_PP_LIST_FOLD_LEFT_75(o, s, BOOST_PP_LIST_REVERSE_D(75, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_76(o, s, l) BOOST_PP_LIST_FOLD_LEFT_76(o, s, BOOST_PP_LIST_REVERSE_D(76, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_77(o, s, l) BOOST_PP_LIST_FOLD_LEFT_77(o, s, BOOST_PP_LIST_REVERSE_D(77, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_78(o, s, l) BOOST_PP_LIST_FOLD_LEFT_78(o, s, BOOST_PP_LIST_REVERSE_D(78, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_79(o, s, l) BOOST_PP_LIST_FOLD_LEFT_79(o, s, BOOST_PP_LIST_REVERSE_D(79, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_80(o, s, l) BOOST_PP_LIST_FOLD_LEFT_80(o, s, BOOST_PP_LIST_REVERSE_D(80, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_81(o, s, l) BOOST_PP_LIST_FOLD_LEFT_81(o, s, BOOST_PP_LIST_REVERSE_D(81, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_82(o, s, l) BOOST_PP_LIST_FOLD_LEFT_82(o, s, BOOST_PP_LIST_REVERSE_D(82, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_83(o, s, l) BOOST_PP_LIST_FOLD_LEFT_83(o, s, BOOST_PP_LIST_REVERSE_D(83, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_84(o, s, l) BOOST_PP_LIST_FOLD_LEFT_84(o, s, BOOST_PP_LIST_REVERSE_D(84, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_85(o, s, l) BOOST_PP_LIST_FOLD_LEFT_85(o, s, BOOST_PP_LIST_REVERSE_D(85, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_86(o, s, l) BOOST_PP_LIST_FOLD_LEFT_86(o, s, BOOST_PP_LIST_REVERSE_D(86, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_87(o, s, l) BOOST_PP_LIST_FOLD_LEFT_87(o, s, BOOST_PP_LIST_REVERSE_D(87, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_88(o, s, l) BOOST_PP_LIST_FOLD_LEFT_88(o, s, BOOST_PP_LIST_REVERSE_D(88, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_89(o, s, l) BOOST_PP_LIST_FOLD_LEFT_89(o, s, BOOST_PP_LIST_REVERSE_D(89, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_90(o, s, l) BOOST_PP_LIST_FOLD_LEFT_90(o, s, BOOST_PP_LIST_REVERSE_D(90, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_91(o, s, l) BOOST_PP_LIST_FOLD_LEFT_91(o, s, BOOST_PP_LIST_REVERSE_D(91, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_92(o, s, l) BOOST_PP_LIST_FOLD_LEFT_92(o, s, BOOST_PP_LIST_REVERSE_D(92, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_93(o, s, l) BOOST_PP_LIST_FOLD_LEFT_93(o, s, BOOST_PP_LIST_REVERSE_D(93, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_94(o, s, l) BOOST_PP_LIST_FOLD_LEFT_94(o, s, BOOST_PP_LIST_REVERSE_D(94, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_95(o, s, l) BOOST_PP_LIST_FOLD_LEFT_95(o, s, BOOST_PP_LIST_REVERSE_D(95, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_96(o, s, l) BOOST_PP_LIST_FOLD_LEFT_96(o, s, BOOST_PP_LIST_REVERSE_D(96, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_97(o, s, l) BOOST_PP_LIST_FOLD_LEFT_97(o, s, BOOST_PP_LIST_REVERSE_D(97, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_98(o, s, l) BOOST_PP_LIST_FOLD_LEFT_98(o, s, BOOST_PP_LIST_REVERSE_D(98, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_99(o, s, l) BOOST_PP_LIST_FOLD_LEFT_99(o, s, BOOST_PP_LIST_REVERSE_D(99, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_100(o, s, l) BOOST_PP_LIST_FOLD_LEFT_100(o, s, BOOST_PP_LIST_REVERSE_D(100, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_101(o, s, l) BOOST_PP_LIST_FOLD_LEFT_101(o, s, BOOST_PP_LIST_REVERSE_D(101, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_102(o, s, l) BOOST_PP_LIST_FOLD_LEFT_102(o, s, BOOST_PP_LIST_REVERSE_D(102, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_103(o, s, l) BOOST_PP_LIST_FOLD_LEFT_103(o, s, BOOST_PP_LIST_REVERSE_D(103, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_104(o, s, l) BOOST_PP_LIST_FOLD_LEFT_104(o, s, BOOST_PP_LIST_REVERSE_D(104, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_105(o, s, l) BOOST_PP_LIST_FOLD_LEFT_105(o, s, BOOST_PP_LIST_REVERSE_D(105, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_106(o, s, l) BOOST_PP_LIST_FOLD_LEFT_106(o, s, BOOST_PP_LIST_REVERSE_D(106, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_107(o, s, l) BOOST_PP_LIST_FOLD_LEFT_107(o, s, BOOST_PP_LIST_REVERSE_D(107, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_108(o, s, l) BOOST_PP_LIST_FOLD_LEFT_108(o, s, BOOST_PP_LIST_REVERSE_D(108, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_109(o, s, l) BOOST_PP_LIST_FOLD_LEFT_109(o, s, BOOST_PP_LIST_REVERSE_D(109, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_110(o, s, l) BOOST_PP_LIST_FOLD_LEFT_110(o, s, BOOST_PP_LIST_REVERSE_D(110, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_111(o, s, l) BOOST_PP_LIST_FOLD_LEFT_111(o, s, BOOST_PP_LIST_REVERSE_D(111, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_112(o, s, l) BOOST_PP_LIST_FOLD_LEFT_112(o, s, BOOST_PP_LIST_REVERSE_D(112, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_113(o, s, l) BOOST_PP_LIST_FOLD_LEFT_113(o, s, BOOST_PP_LIST_REVERSE_D(113, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_114(o, s, l) BOOST_PP_LIST_FOLD_LEFT_114(o, s, BOOST_PP_LIST_REVERSE_D(114, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_115(o, s, l) BOOST_PP_LIST_FOLD_LEFT_115(o, s, BOOST_PP_LIST_REVERSE_D(115, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_116(o, s, l) BOOST_PP_LIST_FOLD_LEFT_116(o, s, BOOST_PP_LIST_REVERSE_D(116, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_117(o, s, l) BOOST_PP_LIST_FOLD_LEFT_117(o, s, BOOST_PP_LIST_REVERSE_D(117, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_118(o, s, l) BOOST_PP_LIST_FOLD_LEFT_118(o, s, BOOST_PP_LIST_REVERSE_D(118, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_119(o, s, l) BOOST_PP_LIST_FOLD_LEFT_119(o, s, BOOST_PP_LIST_REVERSE_D(119, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_120(o, s, l) BOOST_PP_LIST_FOLD_LEFT_120(o, s, BOOST_PP_LIST_REVERSE_D(120, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_121(o, s, l) BOOST_PP_LIST_FOLD_LEFT_121(o, s, BOOST_PP_LIST_REVERSE_D(121, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_122(o, s, l) BOOST_PP_LIST_FOLD_LEFT_122(o, s, BOOST_PP_LIST_REVERSE_D(122, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_123(o, s, l) BOOST_PP_LIST_FOLD_LEFT_123(o, s, BOOST_PP_LIST_REVERSE_D(123, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_124(o, s, l) BOOST_PP_LIST_FOLD_LEFT_124(o, s, BOOST_PP_LIST_REVERSE_D(124, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_125(o, s, l) BOOST_PP_LIST_FOLD_LEFT_125(o, s, BOOST_PP_LIST_REVERSE_D(125, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_126(o, s, l) BOOST_PP_LIST_FOLD_LEFT_126(o, s, BOOST_PP_LIST_REVERSE_D(126, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_127(o, s, l) BOOST_PP_LIST_FOLD_LEFT_127(o, s, BOOST_PP_LIST_REVERSE_D(127, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_128(o, s, l) BOOST_PP_LIST_FOLD_LEFT_128(o, s, BOOST_PP_LIST_REVERSE_D(128, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_129(o, s, l) BOOST_PP_LIST_FOLD_LEFT_129(o, s, BOOST_PP_LIST_REVERSE_D(129, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_130(o, s, l) BOOST_PP_LIST_FOLD_LEFT_130(o, s, BOOST_PP_LIST_REVERSE_D(130, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_131(o, s, l) BOOST_PP_LIST_FOLD_LEFT_131(o, s, BOOST_PP_LIST_REVERSE_D(131, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_132(o, s, l) BOOST_PP_LIST_FOLD_LEFT_132(o, s, BOOST_PP_LIST_REVERSE_D(132, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_133(o, s, l) BOOST_PP_LIST_FOLD_LEFT_133(o, s, BOOST_PP_LIST_REVERSE_D(133, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_134(o, s, l) BOOST_PP_LIST_FOLD_LEFT_134(o, s, BOOST_PP_LIST_REVERSE_D(134, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_135(o, s, l) BOOST_PP_LIST_FOLD_LEFT_135(o, s, BOOST_PP_LIST_REVERSE_D(135, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_136(o, s, l) BOOST_PP_LIST_FOLD_LEFT_136(o, s, BOOST_PP_LIST_REVERSE_D(136, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_137(o, s, l) BOOST_PP_LIST_FOLD_LEFT_137(o, s, BOOST_PP_LIST_REVERSE_D(137, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_138(o, s, l) BOOST_PP_LIST_FOLD_LEFT_138(o, s, BOOST_PP_LIST_REVERSE_D(138, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_139(o, s, l) BOOST_PP_LIST_FOLD_LEFT_139(o, s, BOOST_PP_LIST_REVERSE_D(139, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_140(o, s, l) BOOST_PP_LIST_FOLD_LEFT_140(o, s, BOOST_PP_LIST_REVERSE_D(140, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_141(o, s, l) BOOST_PP_LIST_FOLD_LEFT_141(o, s, BOOST_PP_LIST_REVERSE_D(141, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_142(o, s, l) BOOST_PP_LIST_FOLD_LEFT_142(o, s, BOOST_PP_LIST_REVERSE_D(142, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_143(o, s, l) BOOST_PP_LIST_FOLD_LEFT_143(o, s, BOOST_PP_LIST_REVERSE_D(143, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_144(o, s, l) BOOST_PP_LIST_FOLD_LEFT_144(o, s, BOOST_PP_LIST_REVERSE_D(144, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_145(o, s, l) BOOST_PP_LIST_FOLD_LEFT_145(o, s, BOOST_PP_LIST_REVERSE_D(145, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_146(o, s, l) BOOST_PP_LIST_FOLD_LEFT_146(o, s, BOOST_PP_LIST_REVERSE_D(146, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_147(o, s, l) BOOST_PP_LIST_FOLD_LEFT_147(o, s, BOOST_PP_LIST_REVERSE_D(147, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_148(o, s, l) BOOST_PP_LIST_FOLD_LEFT_148(o, s, BOOST_PP_LIST_REVERSE_D(148, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_149(o, s, l) BOOST_PP_LIST_FOLD_LEFT_149(o, s, BOOST_PP_LIST_REVERSE_D(149, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_150(o, s, l) BOOST_PP_LIST_FOLD_LEFT_150(o, s, BOOST_PP_LIST_REVERSE_D(150, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_151(o, s, l) BOOST_PP_LIST_FOLD_LEFT_151(o, s, BOOST_PP_LIST_REVERSE_D(151, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_152(o, s, l) BOOST_PP_LIST_FOLD_LEFT_152(o, s, BOOST_PP_LIST_REVERSE_D(152, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_153(o, s, l) BOOST_PP_LIST_FOLD_LEFT_153(o, s, BOOST_PP_LIST_REVERSE_D(153, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_154(o, s, l) BOOST_PP_LIST_FOLD_LEFT_154(o, s, BOOST_PP_LIST_REVERSE_D(154, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_155(o, s, l) BOOST_PP_LIST_FOLD_LEFT_155(o, s, BOOST_PP_LIST_REVERSE_D(155, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_156(o, s, l) BOOST_PP_LIST_FOLD_LEFT_156(o, s, BOOST_PP_LIST_REVERSE_D(156, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_157(o, s, l) BOOST_PP_LIST_FOLD_LEFT_157(o, s, BOOST_PP_LIST_REVERSE_D(157, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_158(o, s, l) BOOST_PP_LIST_FOLD_LEFT_158(o, s, BOOST_PP_LIST_REVERSE_D(158, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_159(o, s, l) BOOST_PP_LIST_FOLD_LEFT_159(o, s, BOOST_PP_LIST_REVERSE_D(159, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_160(o, s, l) BOOST_PP_LIST_FOLD_LEFT_160(o, s, BOOST_PP_LIST_REVERSE_D(160, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_161(o, s, l) BOOST_PP_LIST_FOLD_LEFT_161(o, s, BOOST_PP_LIST_REVERSE_D(161, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_162(o, s, l) BOOST_PP_LIST_FOLD_LEFT_162(o, s, BOOST_PP_LIST_REVERSE_D(162, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_163(o, s, l) BOOST_PP_LIST_FOLD_LEFT_163(o, s, BOOST_PP_LIST_REVERSE_D(163, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_164(o, s, l) BOOST_PP_LIST_FOLD_LEFT_164(o, s, BOOST_PP_LIST_REVERSE_D(164, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_165(o, s, l) BOOST_PP_LIST_FOLD_LEFT_165(o, s, BOOST_PP_LIST_REVERSE_D(165, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_166(o, s, l) BOOST_PP_LIST_FOLD_LEFT_166(o, s, BOOST_PP_LIST_REVERSE_D(166, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_167(o, s, l) BOOST_PP_LIST_FOLD_LEFT_167(o, s, BOOST_PP_LIST_REVERSE_D(167, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_168(o, s, l) BOOST_PP_LIST_FOLD_LEFT_168(o, s, BOOST_PP_LIST_REVERSE_D(168, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_169(o, s, l) BOOST_PP_LIST_FOLD_LEFT_169(o, s, BOOST_PP_LIST_REVERSE_D(169, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_170(o, s, l) BOOST_PP_LIST_FOLD_LEFT_170(o, s, BOOST_PP_LIST_REVERSE_D(170, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_171(o, s, l) BOOST_PP_LIST_FOLD_LEFT_171(o, s, BOOST_PP_LIST_REVERSE_D(171, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_172(o, s, l) BOOST_PP_LIST_FOLD_LEFT_172(o, s, BOOST_PP_LIST_REVERSE_D(172, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_173(o, s, l) BOOST_PP_LIST_FOLD_LEFT_173(o, s, BOOST_PP_LIST_REVERSE_D(173, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_174(o, s, l) BOOST_PP_LIST_FOLD_LEFT_174(o, s, BOOST_PP_LIST_REVERSE_D(174, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_175(o, s, l) BOOST_PP_LIST_FOLD_LEFT_175(o, s, BOOST_PP_LIST_REVERSE_D(175, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_176(o, s, l) BOOST_PP_LIST_FOLD_LEFT_176(o, s, BOOST_PP_LIST_REVERSE_D(176, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_177(o, s, l) BOOST_PP_LIST_FOLD_LEFT_177(o, s, BOOST_PP_LIST_REVERSE_D(177, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_178(o, s, l) BOOST_PP_LIST_FOLD_LEFT_178(o, s, BOOST_PP_LIST_REVERSE_D(178, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_179(o, s, l) BOOST_PP_LIST_FOLD_LEFT_179(o, s, BOOST_PP_LIST_REVERSE_D(179, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_180(o, s, l) BOOST_PP_LIST_FOLD_LEFT_180(o, s, BOOST_PP_LIST_REVERSE_D(180, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_181(o, s, l) BOOST_PP_LIST_FOLD_LEFT_181(o, s, BOOST_PP_LIST_REVERSE_D(181, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_182(o, s, l) BOOST_PP_LIST_FOLD_LEFT_182(o, s, BOOST_PP_LIST_REVERSE_D(182, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_183(o, s, l) BOOST_PP_LIST_FOLD_LEFT_183(o, s, BOOST_PP_LIST_REVERSE_D(183, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_184(o, s, l) BOOST_PP_LIST_FOLD_LEFT_184(o, s, BOOST_PP_LIST_REVERSE_D(184, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_185(o, s, l) BOOST_PP_LIST_FOLD_LEFT_185(o, s, BOOST_PP_LIST_REVERSE_D(185, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_186(o, s, l) BOOST_PP_LIST_FOLD_LEFT_186(o, s, BOOST_PP_LIST_REVERSE_D(186, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_187(o, s, l) BOOST_PP_LIST_FOLD_LEFT_187(o, s, BOOST_PP_LIST_REVERSE_D(187, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_188(o, s, l) BOOST_PP_LIST_FOLD_LEFT_188(o, s, BOOST_PP_LIST_REVERSE_D(188, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_189(o, s, l) BOOST_PP_LIST_FOLD_LEFT_189(o, s, BOOST_PP_LIST_REVERSE_D(189, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_190(o, s, l) BOOST_PP_LIST_FOLD_LEFT_190(o, s, BOOST_PP_LIST_REVERSE_D(190, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_191(o, s, l) BOOST_PP_LIST_FOLD_LEFT_191(o, s, BOOST_PP_LIST_REVERSE_D(191, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_192(o, s, l) BOOST_PP_LIST_FOLD_LEFT_192(o, s, BOOST_PP_LIST_REVERSE_D(192, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_193(o, s, l) BOOST_PP_LIST_FOLD_LEFT_193(o, s, BOOST_PP_LIST_REVERSE_D(193, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_194(o, s, l) BOOST_PP_LIST_FOLD_LEFT_194(o, s, BOOST_PP_LIST_REVERSE_D(194, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_195(o, s, l) BOOST_PP_LIST_FOLD_LEFT_195(o, s, BOOST_PP_LIST_REVERSE_D(195, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_196(o, s, l) BOOST_PP_LIST_FOLD_LEFT_196(o, s, BOOST_PP_LIST_REVERSE_D(196, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_197(o, s, l) BOOST_PP_LIST_FOLD_LEFT_197(o, s, BOOST_PP_LIST_REVERSE_D(197, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_198(o, s, l) BOOST_PP_LIST_FOLD_LEFT_198(o, s, BOOST_PP_LIST_REVERSE_D(198, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_199(o, s, l) BOOST_PP_LIST_FOLD_LEFT_199(o, s, BOOST_PP_LIST_REVERSE_D(199, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_200(o, s, l) BOOST_PP_LIST_FOLD_LEFT_200(o, s, BOOST_PP_LIST_REVERSE_D(200, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_201(o, s, l) BOOST_PP_LIST_FOLD_LEFT_201(o, s, BOOST_PP_LIST_REVERSE_D(201, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_202(o, s, l) BOOST_PP_LIST_FOLD_LEFT_202(o, s, BOOST_PP_LIST_REVERSE_D(202, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_203(o, s, l) BOOST_PP_LIST_FOLD_LEFT_203(o, s, BOOST_PP_LIST_REVERSE_D(203, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_204(o, s, l) BOOST_PP_LIST_FOLD_LEFT_204(o, s, BOOST_PP_LIST_REVERSE_D(204, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_205(o, s, l) BOOST_PP_LIST_FOLD_LEFT_205(o, s, BOOST_PP_LIST_REVERSE_D(205, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_206(o, s, l) BOOST_PP_LIST_FOLD_LEFT_206(o, s, BOOST_PP_LIST_REVERSE_D(206, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_207(o, s, l) BOOST_PP_LIST_FOLD_LEFT_207(o, s, BOOST_PP_LIST_REVERSE_D(207, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_208(o, s, l) BOOST_PP_LIST_FOLD_LEFT_208(o, s, BOOST_PP_LIST_REVERSE_D(208, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_209(o, s, l) BOOST_PP_LIST_FOLD_LEFT_209(o, s, BOOST_PP_LIST_REVERSE_D(209, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_210(o, s, l) BOOST_PP_LIST_FOLD_LEFT_210(o, s, BOOST_PP_LIST_REVERSE_D(210, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_211(o, s, l) BOOST_PP_LIST_FOLD_LEFT_211(o, s, BOOST_PP_LIST_REVERSE_D(211, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_212(o, s, l) BOOST_PP_LIST_FOLD_LEFT_212(o, s, BOOST_PP_LIST_REVERSE_D(212, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_213(o, s, l) BOOST_PP_LIST_FOLD_LEFT_213(o, s, BOOST_PP_LIST_REVERSE_D(213, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_214(o, s, l) BOOST_PP_LIST_FOLD_LEFT_214(o, s, BOOST_PP_LIST_REVERSE_D(214, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_215(o, s, l) BOOST_PP_LIST_FOLD_LEFT_215(o, s, BOOST_PP_LIST_REVERSE_D(215, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_216(o, s, l) BOOST_PP_LIST_FOLD_LEFT_216(o, s, BOOST_PP_LIST_REVERSE_D(216, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_217(o, s, l) BOOST_PP_LIST_FOLD_LEFT_217(o, s, BOOST_PP_LIST_REVERSE_D(217, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_218(o, s, l) BOOST_PP_LIST_FOLD_LEFT_218(o, s, BOOST_PP_LIST_REVERSE_D(218, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_219(o, s, l) BOOST_PP_LIST_FOLD_LEFT_219(o, s, BOOST_PP_LIST_REVERSE_D(219, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_220(o, s, l) BOOST_PP_LIST_FOLD_LEFT_220(o, s, BOOST_PP_LIST_REVERSE_D(220, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_221(o, s, l) BOOST_PP_LIST_FOLD_LEFT_221(o, s, BOOST_PP_LIST_REVERSE_D(221, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_222(o, s, l) BOOST_PP_LIST_FOLD_LEFT_222(o, s, BOOST_PP_LIST_REVERSE_D(222, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_223(o, s, l) BOOST_PP_LIST_FOLD_LEFT_223(o, s, BOOST_PP_LIST_REVERSE_D(223, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_224(o, s, l) BOOST_PP_LIST_FOLD_LEFT_224(o, s, BOOST_PP_LIST_REVERSE_D(224, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_225(o, s, l) BOOST_PP_LIST_FOLD_LEFT_225(o, s, BOOST_PP_LIST_REVERSE_D(225, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_226(o, s, l) BOOST_PP_LIST_FOLD_LEFT_226(o, s, BOOST_PP_LIST_REVERSE_D(226, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_227(o, s, l) BOOST_PP_LIST_FOLD_LEFT_227(o, s, BOOST_PP_LIST_REVERSE_D(227, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_228(o, s, l) BOOST_PP_LIST_FOLD_LEFT_228(o, s, BOOST_PP_LIST_REVERSE_D(228, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_229(o, s, l) BOOST_PP_LIST_FOLD_LEFT_229(o, s, BOOST_PP_LIST_REVERSE_D(229, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_230(o, s, l) BOOST_PP_LIST_FOLD_LEFT_230(o, s, BOOST_PP_LIST_REVERSE_D(230, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_231(o, s, l) BOOST_PP_LIST_FOLD_LEFT_231(o, s, BOOST_PP_LIST_REVERSE_D(231, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_232(o, s, l) BOOST_PP_LIST_FOLD_LEFT_232(o, s, BOOST_PP_LIST_REVERSE_D(232, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_233(o, s, l) BOOST_PP_LIST_FOLD_LEFT_233(o, s, BOOST_PP_LIST_REVERSE_D(233, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_234(o, s, l) BOOST_PP_LIST_FOLD_LEFT_234(o, s, BOOST_PP_LIST_REVERSE_D(234, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_235(o, s, l) BOOST_PP_LIST_FOLD_LEFT_235(o, s, BOOST_PP_LIST_REVERSE_D(235, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_236(o, s, l) BOOST_PP_LIST_FOLD_LEFT_236(o, s, BOOST_PP_LIST_REVERSE_D(236, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_237(o, s, l) BOOST_PP_LIST_FOLD_LEFT_237(o, s, BOOST_PP_LIST_REVERSE_D(237, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_238(o, s, l) BOOST_PP_LIST_FOLD_LEFT_238(o, s, BOOST_PP_LIST_REVERSE_D(238, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_239(o, s, l) BOOST_PP_LIST_FOLD_LEFT_239(o, s, BOOST_PP_LIST_REVERSE_D(239, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_240(o, s, l) BOOST_PP_LIST_FOLD_LEFT_240(o, s, BOOST_PP_LIST_REVERSE_D(240, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_241(o, s, l) BOOST_PP_LIST_FOLD_LEFT_241(o, s, BOOST_PP_LIST_REVERSE_D(241, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_242(o, s, l) BOOST_PP_LIST_FOLD_LEFT_242(o, s, BOOST_PP_LIST_REVERSE_D(242, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_243(o, s, l) BOOST_PP_LIST_FOLD_LEFT_243(o, s, BOOST_PP_LIST_REVERSE_D(243, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_244(o, s, l) BOOST_PP_LIST_FOLD_LEFT_244(o, s, BOOST_PP_LIST_REVERSE_D(244, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_245(o, s, l) BOOST_PP_LIST_FOLD_LEFT_245(o, s, BOOST_PP_LIST_REVERSE_D(245, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_246(o, s, l) BOOST_PP_LIST_FOLD_LEFT_246(o, s, BOOST_PP_LIST_REVERSE_D(246, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_247(o, s, l) BOOST_PP_LIST_FOLD_LEFT_247(o, s, BOOST_PP_LIST_REVERSE_D(247, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_248(o, s, l) BOOST_PP_LIST_FOLD_LEFT_248(o, s, BOOST_PP_LIST_REVERSE_D(248, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_249(o, s, l) BOOST_PP_LIST_FOLD_LEFT_249(o, s, BOOST_PP_LIST_REVERSE_D(249, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_250(o, s, l) BOOST_PP_LIST_FOLD_LEFT_250(o, s, BOOST_PP_LIST_REVERSE_D(250, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_251(o, s, l) BOOST_PP_LIST_FOLD_LEFT_251(o, s, BOOST_PP_LIST_REVERSE_D(251, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_252(o, s, l) BOOST_PP_LIST_FOLD_LEFT_252(o, s, BOOST_PP_LIST_REVERSE_D(252, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_253(o, s, l) BOOST_PP_LIST_FOLD_LEFT_253(o, s, BOOST_PP_LIST_REVERSE_D(253, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_254(o, s, l) BOOST_PP_LIST_FOLD_LEFT_254(o, s, BOOST_PP_LIST_REVERSE_D(254, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_255(o, s, l) BOOST_PP_LIST_FOLD_LEFT_255(o, s, BOOST_PP_LIST_REVERSE_D(255, l))
+# define BOOST_PP_LIST_FOLD_RIGHT_256(o, s, l) BOOST_PP_LIST_FOLD_LEFT_256(o, s, BOOST_PP_LIST_REVERSE_D(256, l))
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/list/fold_left.hpp b/third_party/boost/boost/preprocessor/list/fold_left.hpp
new file mode 100644
index 0000000..f235aec
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/list/fold_left.hpp
@@ -0,0 +1,303 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_LIST_FOLD_LEFT_HPP
+# define BOOST_PREPROCESSOR_LIST_FOLD_LEFT_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/control/while.hpp>
+# include <boost/preprocessor/debug/error.hpp>
+# include <boost/preprocessor/detail/auto_rec.hpp>
+#
+# /* BOOST_PP_LIST_FOLD_LEFT */
+#
+# if 0
+#    define BOOST_PP_LIST_FOLD_LEFT(op, state, list)
+# endif
+#
+# define BOOST_PP_LIST_FOLD_LEFT BOOST_PP_CAT(BOOST_PP_LIST_FOLD_LEFT_, BOOST_PP_AUTO_REC(BOOST_PP_WHILE_P, 256))
+#
+# define BOOST_PP_LIST_FOLD_LEFT_257(o, s, l) BOOST_PP_ERROR(0x0004)
+#
+# define BOOST_PP_LIST_FOLD_LEFT_D(d, o, s, l) BOOST_PP_LIST_FOLD_LEFT_ ## d(o, s, l)
+# define BOOST_PP_LIST_FOLD_LEFT_2ND BOOST_PP_LIST_FOLD_LEFT
+# define BOOST_PP_LIST_FOLD_LEFT_2ND_D BOOST_PP_LIST_FOLD_LEFT_D
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    include <boost/preprocessor/list/detail/edg/fold_left.hpp>
+# elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC()
+#    include <boost/preprocessor/list/detail/dmc/fold_left.hpp>
+# else
+#    include <boost/preprocessor/list/detail/fold_left.hpp>
+# endif
+#
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_NIL 1
+#
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_1(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_2(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_3(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_4(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_5(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_6(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_7(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_8(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_9(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_10(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_11(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_12(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_13(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_14(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_15(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_16(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_17(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_18(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_19(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_20(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_21(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_22(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_23(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_24(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_25(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_26(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_27(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_28(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_29(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_30(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_31(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_32(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_33(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_34(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_35(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_36(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_37(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_38(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_39(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_40(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_41(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_42(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_43(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_44(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_45(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_46(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_47(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_48(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_49(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_50(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_51(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_52(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_53(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_54(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_55(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_56(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_57(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_58(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_59(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_60(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_61(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_62(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_63(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_64(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_65(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_66(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_67(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_68(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_69(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_70(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_71(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_72(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_73(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_74(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_75(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_76(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_77(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_78(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_79(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_80(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_81(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_82(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_83(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_84(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_85(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_86(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_87(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_88(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_89(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_90(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_91(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_92(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_93(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_94(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_95(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_96(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_97(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_98(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_99(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_100(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_101(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_102(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_103(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_104(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_105(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_106(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_107(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_108(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_109(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_110(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_111(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_112(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_113(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_114(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_115(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_116(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_117(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_118(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_119(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_120(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_121(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_122(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_123(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_124(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_125(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_126(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_127(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_128(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_129(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_130(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_131(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_132(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_133(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_134(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_135(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_136(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_137(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_138(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_139(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_140(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_141(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_142(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_143(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_144(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_145(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_146(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_147(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_148(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_149(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_150(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_151(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_152(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_153(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_154(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_155(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_156(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_157(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_158(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_159(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_160(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_161(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_162(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_163(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_164(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_165(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_166(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_167(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_168(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_169(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_170(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_171(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_172(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_173(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_174(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_175(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_176(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_177(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_178(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_179(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_180(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_181(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_182(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_183(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_184(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_185(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_186(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_187(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_188(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_189(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_190(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_191(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_192(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_193(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_194(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_195(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_196(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_197(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_198(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_199(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_200(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_201(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_202(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_203(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_204(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_205(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_206(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_207(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_208(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_209(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_210(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_211(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_212(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_213(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_214(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_215(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_216(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_217(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_218(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_219(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_220(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_221(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_222(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_223(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_224(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_225(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_226(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_227(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_228(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_229(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_230(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_231(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_232(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_233(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_234(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_235(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_236(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_237(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_238(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_239(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_240(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_241(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_242(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_243(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_244(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_245(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_246(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_247(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_248(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_249(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_250(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_251(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_252(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_253(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_254(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_255(o, s, l) 0
+# define BOOST_PP_LIST_FOLD_LEFT_CHECK_BOOST_PP_LIST_FOLD_LEFT_256(o, s, l) 0
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/list/fold_right.hpp b/third_party/boost/boost/preprocessor/list/fold_right.hpp
new file mode 100644
index 0000000..ce18afe
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/list/fold_right.hpp
@@ -0,0 +1,40 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_LIST_FOLD_RIGHT_HPP
+# define BOOST_PREPROCESSOR_LIST_FOLD_RIGHT_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/control/while.hpp>
+# include <boost/preprocessor/debug/error.hpp>
+# include <boost/preprocessor/detail/auto_rec.hpp>
+#
+# if 0
+#    define BOOST_PP_LIST_FOLD_RIGHT(op, state, list)
+# endif
+#
+# define BOOST_PP_LIST_FOLD_RIGHT BOOST_PP_CAT(BOOST_PP_LIST_FOLD_RIGHT_, BOOST_PP_AUTO_REC(BOOST_PP_WHILE_P, 256))
+#
+# define BOOST_PP_LIST_FOLD_RIGHT_257(o, s, l) BOOST_PP_ERROR(0x0004)
+#
+# define BOOST_PP_LIST_FOLD_RIGHT_D(d, o, s, l) BOOST_PP_LIST_FOLD_RIGHT_ ## d(o, s, l)
+# define BOOST_PP_LIST_FOLD_RIGHT_2ND BOOST_PP_LIST_FOLD_RIGHT
+# define BOOST_PP_LIST_FOLD_RIGHT_2ND_D BOOST_PP_LIST_FOLD_RIGHT_D
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    include <boost/preprocessor/list/detail/edg/fold_right.hpp>
+# else
+#    include <boost/preprocessor/list/detail/fold_right.hpp>
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/list/reverse.hpp b/third_party/boost/boost/preprocessor/list/reverse.hpp
new file mode 100644
index 0000000..651da05
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/list/reverse.hpp
@@ -0,0 +1,40 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_LIST_REVERSE_HPP
+# define BOOST_PREPROCESSOR_LIST_REVERSE_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/list/fold_left.hpp>
+#
+# /* BOOST_PP_LIST_REVERSE */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_LIST_REVERSE(list) BOOST_PP_LIST_FOLD_LEFT(BOOST_PP_LIST_REVERSE_O, BOOST_PP_NIL, list)
+# else
+#    define BOOST_PP_LIST_REVERSE(list) BOOST_PP_LIST_REVERSE_I(list)
+#    define BOOST_PP_LIST_REVERSE_I(list) BOOST_PP_LIST_FOLD_LEFT(BOOST_PP_LIST_REVERSE_O, BOOST_PP_NIL, list)
+# endif
+#
+# define BOOST_PP_LIST_REVERSE_O(d, s, x) (x, s)
+#
+# /* BOOST_PP_LIST_REVERSE_D */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_LIST_REVERSE_D(d, list) BOOST_PP_LIST_FOLD_LEFT_ ## d(BOOST_PP_LIST_REVERSE_O, BOOST_PP_NIL, list)
+# else
+#    define BOOST_PP_LIST_REVERSE_D(d, list) BOOST_PP_LIST_REVERSE_D_I(d, list)
+#    define BOOST_PP_LIST_REVERSE_D_I(d, list) BOOST_PP_LIST_FOLD_LEFT_ ## d(BOOST_PP_LIST_REVERSE_O, BOOST_PP_NIL, list)
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/logical/and.hpp b/third_party/boost/boost/preprocessor/logical/and.hpp
new file mode 100644
index 0000000..8590365
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/logical/and.hpp
@@ -0,0 +1,30 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_LOGICAL_AND_HPP
+# define BOOST_PREPROCESSOR_LOGICAL_AND_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/logical/bool.hpp>
+# include <boost/preprocessor/logical/bitand.hpp>
+#
+# /* BOOST_PP_AND */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_AND(p, q) BOOST_PP_BITAND(BOOST_PP_BOOL(p), BOOST_PP_BOOL(q))
+# else
+#    define BOOST_PP_AND(p, q) BOOST_PP_AND_I(p, q)
+#    define BOOST_PP_AND_I(p, q) BOOST_PP_BITAND(BOOST_PP_BOOL(p), BOOST_PP_BOOL(q))
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/logical/bitand.hpp b/third_party/boost/boost/preprocessor/logical/bitand.hpp
new file mode 100644
index 0000000..74e9527
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/logical/bitand.hpp
@@ -0,0 +1,38 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_LOGICAL_BITAND_HPP
+# define BOOST_PREPROCESSOR_LOGICAL_BITAND_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+#
+# /* BOOST_PP_BITAND */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#    define BOOST_PP_BITAND(x, y) BOOST_PP_BITAND_I(x, y)
+# else
+#    define BOOST_PP_BITAND(x, y) BOOST_PP_BITAND_OO((x, y))
+#    define BOOST_PP_BITAND_OO(par) BOOST_PP_BITAND_I ## par
+# endif
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC()
+#    define BOOST_PP_BITAND_I(x, y) BOOST_PP_BITAND_ ## x ## y
+# else
+#    define BOOST_PP_BITAND_I(x, y) BOOST_PP_BITAND_ID(BOOST_PP_BITAND_ ## x ## y)
+#    define BOOST_PP_BITAND_ID(res) res
+# endif
+#
+# define BOOST_PP_BITAND_00 0
+# define BOOST_PP_BITAND_01 0
+# define BOOST_PP_BITAND_10 0
+# define BOOST_PP_BITAND_11 1
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/logical/bool.hpp b/third_party/boost/boost/preprocessor/logical/bool.hpp
new file mode 100644
index 0000000..fc01b5b
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/logical/bool.hpp
@@ -0,0 +1,288 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_LOGICAL_BOOL_HPP
+# define BOOST_PREPROCESSOR_LOGICAL_BOOL_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+#
+# /* BOOST_PP_BOOL */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#    define BOOST_PP_BOOL(x) BOOST_PP_BOOL_I(x)
+# else
+#    define BOOST_PP_BOOL(x) BOOST_PP_BOOL_OO((x))
+#    define BOOST_PP_BOOL_OO(par) BOOST_PP_BOOL_I ## par
+# endif
+#
+# define BOOST_PP_BOOL_I(x) BOOST_PP_BOOL_ ## x
+#
+# define BOOST_PP_BOOL_0 0
+# define BOOST_PP_BOOL_1 1
+# define BOOST_PP_BOOL_2 1
+# define BOOST_PP_BOOL_3 1
+# define BOOST_PP_BOOL_4 1
+# define BOOST_PP_BOOL_5 1
+# define BOOST_PP_BOOL_6 1
+# define BOOST_PP_BOOL_7 1
+# define BOOST_PP_BOOL_8 1
+# define BOOST_PP_BOOL_9 1
+# define BOOST_PP_BOOL_10 1
+# define BOOST_PP_BOOL_11 1
+# define BOOST_PP_BOOL_12 1
+# define BOOST_PP_BOOL_13 1
+# define BOOST_PP_BOOL_14 1
+# define BOOST_PP_BOOL_15 1
+# define BOOST_PP_BOOL_16 1
+# define BOOST_PP_BOOL_17 1
+# define BOOST_PP_BOOL_18 1
+# define BOOST_PP_BOOL_19 1
+# define BOOST_PP_BOOL_20 1
+# define BOOST_PP_BOOL_21 1
+# define BOOST_PP_BOOL_22 1
+# define BOOST_PP_BOOL_23 1
+# define BOOST_PP_BOOL_24 1
+# define BOOST_PP_BOOL_25 1
+# define BOOST_PP_BOOL_26 1
+# define BOOST_PP_BOOL_27 1
+# define BOOST_PP_BOOL_28 1
+# define BOOST_PP_BOOL_29 1
+# define BOOST_PP_BOOL_30 1
+# define BOOST_PP_BOOL_31 1
+# define BOOST_PP_BOOL_32 1
+# define BOOST_PP_BOOL_33 1
+# define BOOST_PP_BOOL_34 1
+# define BOOST_PP_BOOL_35 1
+# define BOOST_PP_BOOL_36 1
+# define BOOST_PP_BOOL_37 1
+# define BOOST_PP_BOOL_38 1
+# define BOOST_PP_BOOL_39 1
+# define BOOST_PP_BOOL_40 1
+# define BOOST_PP_BOOL_41 1
+# define BOOST_PP_BOOL_42 1
+# define BOOST_PP_BOOL_43 1
+# define BOOST_PP_BOOL_44 1
+# define BOOST_PP_BOOL_45 1
+# define BOOST_PP_BOOL_46 1
+# define BOOST_PP_BOOL_47 1
+# define BOOST_PP_BOOL_48 1
+# define BOOST_PP_BOOL_49 1
+# define BOOST_PP_BOOL_50 1
+# define BOOST_PP_BOOL_51 1
+# define BOOST_PP_BOOL_52 1
+# define BOOST_PP_BOOL_53 1
+# define BOOST_PP_BOOL_54 1
+# define BOOST_PP_BOOL_55 1
+# define BOOST_PP_BOOL_56 1
+# define BOOST_PP_BOOL_57 1
+# define BOOST_PP_BOOL_58 1
+# define BOOST_PP_BOOL_59 1
+# define BOOST_PP_BOOL_60 1
+# define BOOST_PP_BOOL_61 1
+# define BOOST_PP_BOOL_62 1
+# define BOOST_PP_BOOL_63 1
+# define BOOST_PP_BOOL_64 1
+# define BOOST_PP_BOOL_65 1
+# define BOOST_PP_BOOL_66 1
+# define BOOST_PP_BOOL_67 1
+# define BOOST_PP_BOOL_68 1
+# define BOOST_PP_BOOL_69 1
+# define BOOST_PP_BOOL_70 1
+# define BOOST_PP_BOOL_71 1
+# define BOOST_PP_BOOL_72 1
+# define BOOST_PP_BOOL_73 1
+# define BOOST_PP_BOOL_74 1
+# define BOOST_PP_BOOL_75 1
+# define BOOST_PP_BOOL_76 1
+# define BOOST_PP_BOOL_77 1
+# define BOOST_PP_BOOL_78 1
+# define BOOST_PP_BOOL_79 1
+# define BOOST_PP_BOOL_80 1
+# define BOOST_PP_BOOL_81 1
+# define BOOST_PP_BOOL_82 1
+# define BOOST_PP_BOOL_83 1
+# define BOOST_PP_BOOL_84 1
+# define BOOST_PP_BOOL_85 1
+# define BOOST_PP_BOOL_86 1
+# define BOOST_PP_BOOL_87 1
+# define BOOST_PP_BOOL_88 1
+# define BOOST_PP_BOOL_89 1
+# define BOOST_PP_BOOL_90 1
+# define BOOST_PP_BOOL_91 1
+# define BOOST_PP_BOOL_92 1
+# define BOOST_PP_BOOL_93 1
+# define BOOST_PP_BOOL_94 1
+# define BOOST_PP_BOOL_95 1
+# define BOOST_PP_BOOL_96 1
+# define BOOST_PP_BOOL_97 1
+# define BOOST_PP_BOOL_98 1
+# define BOOST_PP_BOOL_99 1
+# define BOOST_PP_BOOL_100 1
+# define BOOST_PP_BOOL_101 1
+# define BOOST_PP_BOOL_102 1
+# define BOOST_PP_BOOL_103 1
+# define BOOST_PP_BOOL_104 1
+# define BOOST_PP_BOOL_105 1
+# define BOOST_PP_BOOL_106 1
+# define BOOST_PP_BOOL_107 1
+# define BOOST_PP_BOOL_108 1
+# define BOOST_PP_BOOL_109 1
+# define BOOST_PP_BOOL_110 1
+# define BOOST_PP_BOOL_111 1
+# define BOOST_PP_BOOL_112 1
+# define BOOST_PP_BOOL_113 1
+# define BOOST_PP_BOOL_114 1
+# define BOOST_PP_BOOL_115 1
+# define BOOST_PP_BOOL_116 1
+# define BOOST_PP_BOOL_117 1
+# define BOOST_PP_BOOL_118 1
+# define BOOST_PP_BOOL_119 1
+# define BOOST_PP_BOOL_120 1
+# define BOOST_PP_BOOL_121 1
+# define BOOST_PP_BOOL_122 1
+# define BOOST_PP_BOOL_123 1
+# define BOOST_PP_BOOL_124 1
+# define BOOST_PP_BOOL_125 1
+# define BOOST_PP_BOOL_126 1
+# define BOOST_PP_BOOL_127 1
+# define BOOST_PP_BOOL_128 1
+# define BOOST_PP_BOOL_129 1
+# define BOOST_PP_BOOL_130 1
+# define BOOST_PP_BOOL_131 1
+# define BOOST_PP_BOOL_132 1
+# define BOOST_PP_BOOL_133 1
+# define BOOST_PP_BOOL_134 1
+# define BOOST_PP_BOOL_135 1
+# define BOOST_PP_BOOL_136 1
+# define BOOST_PP_BOOL_137 1
+# define BOOST_PP_BOOL_138 1
+# define BOOST_PP_BOOL_139 1
+# define BOOST_PP_BOOL_140 1
+# define BOOST_PP_BOOL_141 1
+# define BOOST_PP_BOOL_142 1
+# define BOOST_PP_BOOL_143 1
+# define BOOST_PP_BOOL_144 1
+# define BOOST_PP_BOOL_145 1
+# define BOOST_PP_BOOL_146 1
+# define BOOST_PP_BOOL_147 1
+# define BOOST_PP_BOOL_148 1
+# define BOOST_PP_BOOL_149 1
+# define BOOST_PP_BOOL_150 1
+# define BOOST_PP_BOOL_151 1
+# define BOOST_PP_BOOL_152 1
+# define BOOST_PP_BOOL_153 1
+# define BOOST_PP_BOOL_154 1
+# define BOOST_PP_BOOL_155 1
+# define BOOST_PP_BOOL_156 1
+# define BOOST_PP_BOOL_157 1
+# define BOOST_PP_BOOL_158 1
+# define BOOST_PP_BOOL_159 1
+# define BOOST_PP_BOOL_160 1
+# define BOOST_PP_BOOL_161 1
+# define BOOST_PP_BOOL_162 1
+# define BOOST_PP_BOOL_163 1
+# define BOOST_PP_BOOL_164 1
+# define BOOST_PP_BOOL_165 1
+# define BOOST_PP_BOOL_166 1
+# define BOOST_PP_BOOL_167 1
+# define BOOST_PP_BOOL_168 1
+# define BOOST_PP_BOOL_169 1
+# define BOOST_PP_BOOL_170 1
+# define BOOST_PP_BOOL_171 1
+# define BOOST_PP_BOOL_172 1
+# define BOOST_PP_BOOL_173 1
+# define BOOST_PP_BOOL_174 1
+# define BOOST_PP_BOOL_175 1
+# define BOOST_PP_BOOL_176 1
+# define BOOST_PP_BOOL_177 1
+# define BOOST_PP_BOOL_178 1
+# define BOOST_PP_BOOL_179 1
+# define BOOST_PP_BOOL_180 1
+# define BOOST_PP_BOOL_181 1
+# define BOOST_PP_BOOL_182 1
+# define BOOST_PP_BOOL_183 1
+# define BOOST_PP_BOOL_184 1
+# define BOOST_PP_BOOL_185 1
+# define BOOST_PP_BOOL_186 1
+# define BOOST_PP_BOOL_187 1
+# define BOOST_PP_BOOL_188 1
+# define BOOST_PP_BOOL_189 1
+# define BOOST_PP_BOOL_190 1
+# define BOOST_PP_BOOL_191 1
+# define BOOST_PP_BOOL_192 1
+# define BOOST_PP_BOOL_193 1
+# define BOOST_PP_BOOL_194 1
+# define BOOST_PP_BOOL_195 1
+# define BOOST_PP_BOOL_196 1
+# define BOOST_PP_BOOL_197 1
+# define BOOST_PP_BOOL_198 1
+# define BOOST_PP_BOOL_199 1
+# define BOOST_PP_BOOL_200 1
+# define BOOST_PP_BOOL_201 1
+# define BOOST_PP_BOOL_202 1
+# define BOOST_PP_BOOL_203 1
+# define BOOST_PP_BOOL_204 1
+# define BOOST_PP_BOOL_205 1
+# define BOOST_PP_BOOL_206 1
+# define BOOST_PP_BOOL_207 1
+# define BOOST_PP_BOOL_208 1
+# define BOOST_PP_BOOL_209 1
+# define BOOST_PP_BOOL_210 1
+# define BOOST_PP_BOOL_211 1
+# define BOOST_PP_BOOL_212 1
+# define BOOST_PP_BOOL_213 1
+# define BOOST_PP_BOOL_214 1
+# define BOOST_PP_BOOL_215 1
+# define BOOST_PP_BOOL_216 1
+# define BOOST_PP_BOOL_217 1
+# define BOOST_PP_BOOL_218 1
+# define BOOST_PP_BOOL_219 1
+# define BOOST_PP_BOOL_220 1
+# define BOOST_PP_BOOL_221 1
+# define BOOST_PP_BOOL_222 1
+# define BOOST_PP_BOOL_223 1
+# define BOOST_PP_BOOL_224 1
+# define BOOST_PP_BOOL_225 1
+# define BOOST_PP_BOOL_226 1
+# define BOOST_PP_BOOL_227 1
+# define BOOST_PP_BOOL_228 1
+# define BOOST_PP_BOOL_229 1
+# define BOOST_PP_BOOL_230 1
+# define BOOST_PP_BOOL_231 1
+# define BOOST_PP_BOOL_232 1
+# define BOOST_PP_BOOL_233 1
+# define BOOST_PP_BOOL_234 1
+# define BOOST_PP_BOOL_235 1
+# define BOOST_PP_BOOL_236 1
+# define BOOST_PP_BOOL_237 1
+# define BOOST_PP_BOOL_238 1
+# define BOOST_PP_BOOL_239 1
+# define BOOST_PP_BOOL_240 1
+# define BOOST_PP_BOOL_241 1
+# define BOOST_PP_BOOL_242 1
+# define BOOST_PP_BOOL_243 1
+# define BOOST_PP_BOOL_244 1
+# define BOOST_PP_BOOL_245 1
+# define BOOST_PP_BOOL_246 1
+# define BOOST_PP_BOOL_247 1
+# define BOOST_PP_BOOL_248 1
+# define BOOST_PP_BOOL_249 1
+# define BOOST_PP_BOOL_250 1
+# define BOOST_PP_BOOL_251 1
+# define BOOST_PP_BOOL_252 1
+# define BOOST_PP_BOOL_253 1
+# define BOOST_PP_BOOL_254 1
+# define BOOST_PP_BOOL_255 1
+# define BOOST_PP_BOOL_256 1
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/logical/compl.hpp b/third_party/boost/boost/preprocessor/logical/compl.hpp
new file mode 100644
index 0000000..ad4c7a4
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/logical/compl.hpp
@@ -0,0 +1,36 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_LOGICAL_COMPL_HPP
+# define BOOST_PREPROCESSOR_LOGICAL_COMPL_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+#
+# /* BOOST_PP_COMPL */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#    define BOOST_PP_COMPL(x) BOOST_PP_COMPL_I(x)
+# else
+#    define BOOST_PP_COMPL(x) BOOST_PP_COMPL_OO((x))
+#    define BOOST_PP_COMPL_OO(par) BOOST_PP_COMPL_I ## par
+# endif
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC()
+#    define BOOST_PP_COMPL_I(x) BOOST_PP_COMPL_ ## x
+# else
+#    define BOOST_PP_COMPL_I(x) BOOST_PP_COMPL_ID(BOOST_PP_COMPL_ ## x)
+#    define BOOST_PP_COMPL_ID(id) id
+# endif
+#
+# define BOOST_PP_COMPL_0 1
+# define BOOST_PP_COMPL_1 0
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/logical/not.hpp b/third_party/boost/boost/preprocessor/logical/not.hpp
new file mode 100644
index 0000000..b509d3f
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/logical/not.hpp
@@ -0,0 +1,30 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_LOGICAL_NOT_HPP
+# define BOOST_PREPROCESSOR_LOGICAL_NOT_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/logical/bool.hpp>
+# include <boost/preprocessor/logical/compl.hpp>
+#
+# /* BOOST_PP_NOT */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_NOT(x) BOOST_PP_COMPL(BOOST_PP_BOOL(x))
+# else
+#    define BOOST_PP_NOT(x) BOOST_PP_NOT_I(x)
+#    define BOOST_PP_NOT_I(x) BOOST_PP_COMPL(BOOST_PP_BOOL(x))
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/punctuation/comma.hpp b/third_party/boost/boost/preprocessor/punctuation/comma.hpp
new file mode 100644
index 0000000..38c2e0e
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/punctuation/comma.hpp
@@ -0,0 +1,21 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_PUNCTUATION_COMMA_HPP
+# define BOOST_PREPROCESSOR_PUNCTUATION_COMMA_HPP
+#
+# /* BOOST_PP_COMMA */
+#
+# define BOOST_PP_COMMA() ,
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/punctuation/comma_if.hpp b/third_party/boost/boost/preprocessor/punctuation/comma_if.hpp
new file mode 100644
index 0000000..c711f36
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/punctuation/comma_if.hpp
@@ -0,0 +1,31 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_PUNCTUATION_COMMA_IF_HPP
+# define BOOST_PREPROCESSOR_PUNCTUATION_COMMA_IF_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/control/if.hpp>
+# include <boost/preprocessor/facilities/empty.hpp>
+# include <boost/preprocessor/punctuation/comma.hpp>
+#
+# /* BOOST_PP_COMMA_IF */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_COMMA_IF(cond) BOOST_PP_IF(cond, BOOST_PP_COMMA, BOOST_PP_EMPTY)()
+# else
+#    define BOOST_PP_COMMA_IF(cond) BOOST_PP_COMMA_IF_I(cond)
+#    define BOOST_PP_COMMA_IF_I(cond) BOOST_PP_IF(cond, BOOST_PP_COMMA, BOOST_PP_EMPTY)()
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repeat.hpp b/third_party/boost/boost/preprocessor/repeat.hpp
new file mode 100644
index 0000000..7c47ee8
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repeat.hpp
@@ -0,0 +1,17 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPEAT_HPP
+# define BOOST_PREPROCESSOR_REPEAT_HPP
+#
+# include <boost/preprocessor/repetition/repeat.hpp>
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition.hpp b/third_party/boost/boost/preprocessor/repetition.hpp
new file mode 100644
index 0000000..efcd60a
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition.hpp
@@ -0,0 +1,32 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_HPP
+# define BOOST_PREPROCESSOR_REPETITION_HPP
+#
+# include <boost/preprocessor/repetition/deduce_r.hpp>
+# include <boost/preprocessor/repetition/deduce_z.hpp>
+# include <boost/preprocessor/repetition/enum.hpp>
+# include <boost/preprocessor/repetition/enum_binary_params.hpp>
+# include <boost/preprocessor/repetition/enum_params.hpp>
+# include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+# include <boost/preprocessor/repetition/enum_params_with_defaults.hpp>
+# include <boost/preprocessor/repetition/enum_shifted.hpp>
+# include <boost/preprocessor/repetition/enum_shifted_binary_params.hpp>
+# include <boost/preprocessor/repetition/enum_shifted_params.hpp>
+# include <boost/preprocessor/repetition/enum_trailing.hpp>
+# include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
+# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+# include <boost/preprocessor/repetition/for.hpp>
+# include <boost/preprocessor/repetition/repeat.hpp>
+# include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/deduce_r.hpp b/third_party/boost/boost/preprocessor/repetition/deduce_r.hpp
new file mode 100644
index 0000000..e49296a
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/deduce_r.hpp
@@ -0,0 +1,22 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_DEDUCE_R_HPP
+# define BOOST_PREPROCESSOR_REPETITION_DEDUCE_R_HPP
+#
+# include <boost/preprocessor/detail/auto_rec.hpp>
+# include <boost/preprocessor/repetition/for.hpp>
+#
+# /* BOOST_PP_DEDUCE_R */
+#
+# define BOOST_PP_DEDUCE_R() BOOST_PP_AUTO_REC(BOOST_PP_FOR_P, 256)
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/deduce_z.hpp b/third_party/boost/boost/preprocessor/repetition/deduce_z.hpp
new file mode 100644
index 0000000..14dedc2
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/deduce_z.hpp
@@ -0,0 +1,22 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_DEDUCE_Z_HPP
+# define BOOST_PREPROCESSOR_REPETITION_DEDUCE_Z_HPP
+#
+# include <boost/preprocessor/detail/auto_rec.hpp>
+# include <boost/preprocessor/repetition/repeat.hpp>
+#
+# /* BOOST_PP_DEDUCE_Z */
+#
+# define BOOST_PP_DEDUCE_Z() BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4)
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/detail/for.hpp b/third_party/boost/boost/preprocessor/repetition/detail/for.hpp
new file mode 100644
index 0000000..2770f2c
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/detail/for.hpp
@@ -0,0 +1,536 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_DETAIL_FOR_HPP
+# define BOOST_PREPROCESSOR_REPETITION_DETAIL_FOR_HPP
+#
+# include <boost/preprocessor/control/expr_iif.hpp>
+# include <boost/preprocessor/control/iif.hpp>
+# include <boost/preprocessor/logical/bool.hpp>
+# include <boost/preprocessor/tuple/eat.hpp>
+#
+# define BOOST_PP_FOR_1(s, p, o, m) BOOST_PP_FOR_1_C(BOOST_PP_BOOL(p(2, s)), s, p, o, m)
+# define BOOST_PP_FOR_2(s, p, o, m) BOOST_PP_FOR_2_C(BOOST_PP_BOOL(p(3, s)), s, p, o, m)
+# define BOOST_PP_FOR_3(s, p, o, m) BOOST_PP_FOR_3_C(BOOST_PP_BOOL(p(4, s)), s, p, o, m)
+# define BOOST_PP_FOR_4(s, p, o, m) BOOST_PP_FOR_4_C(BOOST_PP_BOOL(p(5, s)), s, p, o, m)
+# define BOOST_PP_FOR_5(s, p, o, m) BOOST_PP_FOR_5_C(BOOST_PP_BOOL(p(6, s)), s, p, o, m)
+# define BOOST_PP_FOR_6(s, p, o, m) BOOST_PP_FOR_6_C(BOOST_PP_BOOL(p(7, s)), s, p, o, m)
+# define BOOST_PP_FOR_7(s, p, o, m) BOOST_PP_FOR_7_C(BOOST_PP_BOOL(p(8, s)), s, p, o, m)
+# define BOOST_PP_FOR_8(s, p, o, m) BOOST_PP_FOR_8_C(BOOST_PP_BOOL(p(9, s)), s, p, o, m)
+# define BOOST_PP_FOR_9(s, p, o, m) BOOST_PP_FOR_9_C(BOOST_PP_BOOL(p(10, s)), s, p, o, m)
+# define BOOST_PP_FOR_10(s, p, o, m) BOOST_PP_FOR_10_C(BOOST_PP_BOOL(p(11, s)), s, p, o, m)
+# define BOOST_PP_FOR_11(s, p, o, m) BOOST_PP_FOR_11_C(BOOST_PP_BOOL(p(12, s)), s, p, o, m)
+# define BOOST_PP_FOR_12(s, p, o, m) BOOST_PP_FOR_12_C(BOOST_PP_BOOL(p(13, s)), s, p, o, m)
+# define BOOST_PP_FOR_13(s, p, o, m) BOOST_PP_FOR_13_C(BOOST_PP_BOOL(p(14, s)), s, p, o, m)
+# define BOOST_PP_FOR_14(s, p, o, m) BOOST_PP_FOR_14_C(BOOST_PP_BOOL(p(15, s)), s, p, o, m)
+# define BOOST_PP_FOR_15(s, p, o, m) BOOST_PP_FOR_15_C(BOOST_PP_BOOL(p(16, s)), s, p, o, m)
+# define BOOST_PP_FOR_16(s, p, o, m) BOOST_PP_FOR_16_C(BOOST_PP_BOOL(p(17, s)), s, p, o, m)
+# define BOOST_PP_FOR_17(s, p, o, m) BOOST_PP_FOR_17_C(BOOST_PP_BOOL(p(18, s)), s, p, o, m)
+# define BOOST_PP_FOR_18(s, p, o, m) BOOST_PP_FOR_18_C(BOOST_PP_BOOL(p(19, s)), s, p, o, m)
+# define BOOST_PP_FOR_19(s, p, o, m) BOOST_PP_FOR_19_C(BOOST_PP_BOOL(p(20, s)), s, p, o, m)
+# define BOOST_PP_FOR_20(s, p, o, m) BOOST_PP_FOR_20_C(BOOST_PP_BOOL(p(21, s)), s, p, o, m)
+# define BOOST_PP_FOR_21(s, p, o, m) BOOST_PP_FOR_21_C(BOOST_PP_BOOL(p(22, s)), s, p, o, m)
+# define BOOST_PP_FOR_22(s, p, o, m) BOOST_PP_FOR_22_C(BOOST_PP_BOOL(p(23, s)), s, p, o, m)
+# define BOOST_PP_FOR_23(s, p, o, m) BOOST_PP_FOR_23_C(BOOST_PP_BOOL(p(24, s)), s, p, o, m)
+# define BOOST_PP_FOR_24(s, p, o, m) BOOST_PP_FOR_24_C(BOOST_PP_BOOL(p(25, s)), s, p, o, m)
+# define BOOST_PP_FOR_25(s, p, o, m) BOOST_PP_FOR_25_C(BOOST_PP_BOOL(p(26, s)), s, p, o, m)
+# define BOOST_PP_FOR_26(s, p, o, m) BOOST_PP_FOR_26_C(BOOST_PP_BOOL(p(27, s)), s, p, o, m)
+# define BOOST_PP_FOR_27(s, p, o, m) BOOST_PP_FOR_27_C(BOOST_PP_BOOL(p(28, s)), s, p, o, m)
+# define BOOST_PP_FOR_28(s, p, o, m) BOOST_PP_FOR_28_C(BOOST_PP_BOOL(p(29, s)), s, p, o, m)
+# define BOOST_PP_FOR_29(s, p, o, m) BOOST_PP_FOR_29_C(BOOST_PP_BOOL(p(30, s)), s, p, o, m)
+# define BOOST_PP_FOR_30(s, p, o, m) BOOST_PP_FOR_30_C(BOOST_PP_BOOL(p(31, s)), s, p, o, m)
+# define BOOST_PP_FOR_31(s, p, o, m) BOOST_PP_FOR_31_C(BOOST_PP_BOOL(p(32, s)), s, p, o, m)
+# define BOOST_PP_FOR_32(s, p, o, m) BOOST_PP_FOR_32_C(BOOST_PP_BOOL(p(33, s)), s, p, o, m)
+# define BOOST_PP_FOR_33(s, p, o, m) BOOST_PP_FOR_33_C(BOOST_PP_BOOL(p(34, s)), s, p, o, m)
+# define BOOST_PP_FOR_34(s, p, o, m) BOOST_PP_FOR_34_C(BOOST_PP_BOOL(p(35, s)), s, p, o, m)
+# define BOOST_PP_FOR_35(s, p, o, m) BOOST_PP_FOR_35_C(BOOST_PP_BOOL(p(36, s)), s, p, o, m)
+# define BOOST_PP_FOR_36(s, p, o, m) BOOST_PP_FOR_36_C(BOOST_PP_BOOL(p(37, s)), s, p, o, m)
+# define BOOST_PP_FOR_37(s, p, o, m) BOOST_PP_FOR_37_C(BOOST_PP_BOOL(p(38, s)), s, p, o, m)
+# define BOOST_PP_FOR_38(s, p, o, m) BOOST_PP_FOR_38_C(BOOST_PP_BOOL(p(39, s)), s, p, o, m)
+# define BOOST_PP_FOR_39(s, p, o, m) BOOST_PP_FOR_39_C(BOOST_PP_BOOL(p(40, s)), s, p, o, m)
+# define BOOST_PP_FOR_40(s, p, o, m) BOOST_PP_FOR_40_C(BOOST_PP_BOOL(p(41, s)), s, p, o, m)
+# define BOOST_PP_FOR_41(s, p, o, m) BOOST_PP_FOR_41_C(BOOST_PP_BOOL(p(42, s)), s, p, o, m)
+# define BOOST_PP_FOR_42(s, p, o, m) BOOST_PP_FOR_42_C(BOOST_PP_BOOL(p(43, s)), s, p, o, m)
+# define BOOST_PP_FOR_43(s, p, o, m) BOOST_PP_FOR_43_C(BOOST_PP_BOOL(p(44, s)), s, p, o, m)
+# define BOOST_PP_FOR_44(s, p, o, m) BOOST_PP_FOR_44_C(BOOST_PP_BOOL(p(45, s)), s, p, o, m)
+# define BOOST_PP_FOR_45(s, p, o, m) BOOST_PP_FOR_45_C(BOOST_PP_BOOL(p(46, s)), s, p, o, m)
+# define BOOST_PP_FOR_46(s, p, o, m) BOOST_PP_FOR_46_C(BOOST_PP_BOOL(p(47, s)), s, p, o, m)
+# define BOOST_PP_FOR_47(s, p, o, m) BOOST_PP_FOR_47_C(BOOST_PP_BOOL(p(48, s)), s, p, o, m)
+# define BOOST_PP_FOR_48(s, p, o, m) BOOST_PP_FOR_48_C(BOOST_PP_BOOL(p(49, s)), s, p, o, m)
+# define BOOST_PP_FOR_49(s, p, o, m) BOOST_PP_FOR_49_C(BOOST_PP_BOOL(p(50, s)), s, p, o, m)
+# define BOOST_PP_FOR_50(s, p, o, m) BOOST_PP_FOR_50_C(BOOST_PP_BOOL(p(51, s)), s, p, o, m)
+# define BOOST_PP_FOR_51(s, p, o, m) BOOST_PP_FOR_51_C(BOOST_PP_BOOL(p(52, s)), s, p, o, m)
+# define BOOST_PP_FOR_52(s, p, o, m) BOOST_PP_FOR_52_C(BOOST_PP_BOOL(p(53, s)), s, p, o, m)
+# define BOOST_PP_FOR_53(s, p, o, m) BOOST_PP_FOR_53_C(BOOST_PP_BOOL(p(54, s)), s, p, o, m)
+# define BOOST_PP_FOR_54(s, p, o, m) BOOST_PP_FOR_54_C(BOOST_PP_BOOL(p(55, s)), s, p, o, m)
+# define BOOST_PP_FOR_55(s, p, o, m) BOOST_PP_FOR_55_C(BOOST_PP_BOOL(p(56, s)), s, p, o, m)
+# define BOOST_PP_FOR_56(s, p, o, m) BOOST_PP_FOR_56_C(BOOST_PP_BOOL(p(57, s)), s, p, o, m)
+# define BOOST_PP_FOR_57(s, p, o, m) BOOST_PP_FOR_57_C(BOOST_PP_BOOL(p(58, s)), s, p, o, m)
+# define BOOST_PP_FOR_58(s, p, o, m) BOOST_PP_FOR_58_C(BOOST_PP_BOOL(p(59, s)), s, p, o, m)
+# define BOOST_PP_FOR_59(s, p, o, m) BOOST_PP_FOR_59_C(BOOST_PP_BOOL(p(60, s)), s, p, o, m)
+# define BOOST_PP_FOR_60(s, p, o, m) BOOST_PP_FOR_60_C(BOOST_PP_BOOL(p(61, s)), s, p, o, m)
+# define BOOST_PP_FOR_61(s, p, o, m) BOOST_PP_FOR_61_C(BOOST_PP_BOOL(p(62, s)), s, p, o, m)
+# define BOOST_PP_FOR_62(s, p, o, m) BOOST_PP_FOR_62_C(BOOST_PP_BOOL(p(63, s)), s, p, o, m)
+# define BOOST_PP_FOR_63(s, p, o, m) BOOST_PP_FOR_63_C(BOOST_PP_BOOL(p(64, s)), s, p, o, m)
+# define BOOST_PP_FOR_64(s, p, o, m) BOOST_PP_FOR_64_C(BOOST_PP_BOOL(p(65, s)), s, p, o, m)
+# define BOOST_PP_FOR_65(s, p, o, m) BOOST_PP_FOR_65_C(BOOST_PP_BOOL(p(66, s)), s, p, o, m)
+# define BOOST_PP_FOR_66(s, p, o, m) BOOST_PP_FOR_66_C(BOOST_PP_BOOL(p(67, s)), s, p, o, m)
+# define BOOST_PP_FOR_67(s, p, o, m) BOOST_PP_FOR_67_C(BOOST_PP_BOOL(p(68, s)), s, p, o, m)
+# define BOOST_PP_FOR_68(s, p, o, m) BOOST_PP_FOR_68_C(BOOST_PP_BOOL(p(69, s)), s, p, o, m)
+# define BOOST_PP_FOR_69(s, p, o, m) BOOST_PP_FOR_69_C(BOOST_PP_BOOL(p(70, s)), s, p, o, m)
+# define BOOST_PP_FOR_70(s, p, o, m) BOOST_PP_FOR_70_C(BOOST_PP_BOOL(p(71, s)), s, p, o, m)
+# define BOOST_PP_FOR_71(s, p, o, m) BOOST_PP_FOR_71_C(BOOST_PP_BOOL(p(72, s)), s, p, o, m)
+# define BOOST_PP_FOR_72(s, p, o, m) BOOST_PP_FOR_72_C(BOOST_PP_BOOL(p(73, s)), s, p, o, m)
+# define BOOST_PP_FOR_73(s, p, o, m) BOOST_PP_FOR_73_C(BOOST_PP_BOOL(p(74, s)), s, p, o, m)
+# define BOOST_PP_FOR_74(s, p, o, m) BOOST_PP_FOR_74_C(BOOST_PP_BOOL(p(75, s)), s, p, o, m)
+# define BOOST_PP_FOR_75(s, p, o, m) BOOST_PP_FOR_75_C(BOOST_PP_BOOL(p(76, s)), s, p, o, m)
+# define BOOST_PP_FOR_76(s, p, o, m) BOOST_PP_FOR_76_C(BOOST_PP_BOOL(p(77, s)), s, p, o, m)
+# define BOOST_PP_FOR_77(s, p, o, m) BOOST_PP_FOR_77_C(BOOST_PP_BOOL(p(78, s)), s, p, o, m)
+# define BOOST_PP_FOR_78(s, p, o, m) BOOST_PP_FOR_78_C(BOOST_PP_BOOL(p(79, s)), s, p, o, m)
+# define BOOST_PP_FOR_79(s, p, o, m) BOOST_PP_FOR_79_C(BOOST_PP_BOOL(p(80, s)), s, p, o, m)
+# define BOOST_PP_FOR_80(s, p, o, m) BOOST_PP_FOR_80_C(BOOST_PP_BOOL(p(81, s)), s, p, o, m)
+# define BOOST_PP_FOR_81(s, p, o, m) BOOST_PP_FOR_81_C(BOOST_PP_BOOL(p(82, s)), s, p, o, m)
+# define BOOST_PP_FOR_82(s, p, o, m) BOOST_PP_FOR_82_C(BOOST_PP_BOOL(p(83, s)), s, p, o, m)
+# define BOOST_PP_FOR_83(s, p, o, m) BOOST_PP_FOR_83_C(BOOST_PP_BOOL(p(84, s)), s, p, o, m)
+# define BOOST_PP_FOR_84(s, p, o, m) BOOST_PP_FOR_84_C(BOOST_PP_BOOL(p(85, s)), s, p, o, m)
+# define BOOST_PP_FOR_85(s, p, o, m) BOOST_PP_FOR_85_C(BOOST_PP_BOOL(p(86, s)), s, p, o, m)
+# define BOOST_PP_FOR_86(s, p, o, m) BOOST_PP_FOR_86_C(BOOST_PP_BOOL(p(87, s)), s, p, o, m)
+# define BOOST_PP_FOR_87(s, p, o, m) BOOST_PP_FOR_87_C(BOOST_PP_BOOL(p(88, s)), s, p, o, m)
+# define BOOST_PP_FOR_88(s, p, o, m) BOOST_PP_FOR_88_C(BOOST_PP_BOOL(p(89, s)), s, p, o, m)
+# define BOOST_PP_FOR_89(s, p, o, m) BOOST_PP_FOR_89_C(BOOST_PP_BOOL(p(90, s)), s, p, o, m)
+# define BOOST_PP_FOR_90(s, p, o, m) BOOST_PP_FOR_90_C(BOOST_PP_BOOL(p(91, s)), s, p, o, m)
+# define BOOST_PP_FOR_91(s, p, o, m) BOOST_PP_FOR_91_C(BOOST_PP_BOOL(p(92, s)), s, p, o, m)
+# define BOOST_PP_FOR_92(s, p, o, m) BOOST_PP_FOR_92_C(BOOST_PP_BOOL(p(93, s)), s, p, o, m)
+# define BOOST_PP_FOR_93(s, p, o, m) BOOST_PP_FOR_93_C(BOOST_PP_BOOL(p(94, s)), s, p, o, m)
+# define BOOST_PP_FOR_94(s, p, o, m) BOOST_PP_FOR_94_C(BOOST_PP_BOOL(p(95, s)), s, p, o, m)
+# define BOOST_PP_FOR_95(s, p, o, m) BOOST_PP_FOR_95_C(BOOST_PP_BOOL(p(96, s)), s, p, o, m)
+# define BOOST_PP_FOR_96(s, p, o, m) BOOST_PP_FOR_96_C(BOOST_PP_BOOL(p(97, s)), s, p, o, m)
+# define BOOST_PP_FOR_97(s, p, o, m) BOOST_PP_FOR_97_C(BOOST_PP_BOOL(p(98, s)), s, p, o, m)
+# define BOOST_PP_FOR_98(s, p, o, m) BOOST_PP_FOR_98_C(BOOST_PP_BOOL(p(99, s)), s, p, o, m)
+# define BOOST_PP_FOR_99(s, p, o, m) BOOST_PP_FOR_99_C(BOOST_PP_BOOL(p(100, s)), s, p, o, m)
+# define BOOST_PP_FOR_100(s, p, o, m) BOOST_PP_FOR_100_C(BOOST_PP_BOOL(p(101, s)), s, p, o, m)
+# define BOOST_PP_FOR_101(s, p, o, m) BOOST_PP_FOR_101_C(BOOST_PP_BOOL(p(102, s)), s, p, o, m)
+# define BOOST_PP_FOR_102(s, p, o, m) BOOST_PP_FOR_102_C(BOOST_PP_BOOL(p(103, s)), s, p, o, m)
+# define BOOST_PP_FOR_103(s, p, o, m) BOOST_PP_FOR_103_C(BOOST_PP_BOOL(p(104, s)), s, p, o, m)
+# define BOOST_PP_FOR_104(s, p, o, m) BOOST_PP_FOR_104_C(BOOST_PP_BOOL(p(105, s)), s, p, o, m)
+# define BOOST_PP_FOR_105(s, p, o, m) BOOST_PP_FOR_105_C(BOOST_PP_BOOL(p(106, s)), s, p, o, m)
+# define BOOST_PP_FOR_106(s, p, o, m) BOOST_PP_FOR_106_C(BOOST_PP_BOOL(p(107, s)), s, p, o, m)
+# define BOOST_PP_FOR_107(s, p, o, m) BOOST_PP_FOR_107_C(BOOST_PP_BOOL(p(108, s)), s, p, o, m)
+# define BOOST_PP_FOR_108(s, p, o, m) BOOST_PP_FOR_108_C(BOOST_PP_BOOL(p(109, s)), s, p, o, m)
+# define BOOST_PP_FOR_109(s, p, o, m) BOOST_PP_FOR_109_C(BOOST_PP_BOOL(p(110, s)), s, p, o, m)
+# define BOOST_PP_FOR_110(s, p, o, m) BOOST_PP_FOR_110_C(BOOST_PP_BOOL(p(111, s)), s, p, o, m)
+# define BOOST_PP_FOR_111(s, p, o, m) BOOST_PP_FOR_111_C(BOOST_PP_BOOL(p(112, s)), s, p, o, m)
+# define BOOST_PP_FOR_112(s, p, o, m) BOOST_PP_FOR_112_C(BOOST_PP_BOOL(p(113, s)), s, p, o, m)
+# define BOOST_PP_FOR_113(s, p, o, m) BOOST_PP_FOR_113_C(BOOST_PP_BOOL(p(114, s)), s, p, o, m)
+# define BOOST_PP_FOR_114(s, p, o, m) BOOST_PP_FOR_114_C(BOOST_PP_BOOL(p(115, s)), s, p, o, m)
+# define BOOST_PP_FOR_115(s, p, o, m) BOOST_PP_FOR_115_C(BOOST_PP_BOOL(p(116, s)), s, p, o, m)
+# define BOOST_PP_FOR_116(s, p, o, m) BOOST_PP_FOR_116_C(BOOST_PP_BOOL(p(117, s)), s, p, o, m)
+# define BOOST_PP_FOR_117(s, p, o, m) BOOST_PP_FOR_117_C(BOOST_PP_BOOL(p(118, s)), s, p, o, m)
+# define BOOST_PP_FOR_118(s, p, o, m) BOOST_PP_FOR_118_C(BOOST_PP_BOOL(p(119, s)), s, p, o, m)
+# define BOOST_PP_FOR_119(s, p, o, m) BOOST_PP_FOR_119_C(BOOST_PP_BOOL(p(120, s)), s, p, o, m)
+# define BOOST_PP_FOR_120(s, p, o, m) BOOST_PP_FOR_120_C(BOOST_PP_BOOL(p(121, s)), s, p, o, m)
+# define BOOST_PP_FOR_121(s, p, o, m) BOOST_PP_FOR_121_C(BOOST_PP_BOOL(p(122, s)), s, p, o, m)
+# define BOOST_PP_FOR_122(s, p, o, m) BOOST_PP_FOR_122_C(BOOST_PP_BOOL(p(123, s)), s, p, o, m)
+# define BOOST_PP_FOR_123(s, p, o, m) BOOST_PP_FOR_123_C(BOOST_PP_BOOL(p(124, s)), s, p, o, m)
+# define BOOST_PP_FOR_124(s, p, o, m) BOOST_PP_FOR_124_C(BOOST_PP_BOOL(p(125, s)), s, p, o, m)
+# define BOOST_PP_FOR_125(s, p, o, m) BOOST_PP_FOR_125_C(BOOST_PP_BOOL(p(126, s)), s, p, o, m)
+# define BOOST_PP_FOR_126(s, p, o, m) BOOST_PP_FOR_126_C(BOOST_PP_BOOL(p(127, s)), s, p, o, m)
+# define BOOST_PP_FOR_127(s, p, o, m) BOOST_PP_FOR_127_C(BOOST_PP_BOOL(p(128, s)), s, p, o, m)
+# define BOOST_PP_FOR_128(s, p, o, m) BOOST_PP_FOR_128_C(BOOST_PP_BOOL(p(129, s)), s, p, o, m)
+# define BOOST_PP_FOR_129(s, p, o, m) BOOST_PP_FOR_129_C(BOOST_PP_BOOL(p(130, s)), s, p, o, m)
+# define BOOST_PP_FOR_130(s, p, o, m) BOOST_PP_FOR_130_C(BOOST_PP_BOOL(p(131, s)), s, p, o, m)
+# define BOOST_PP_FOR_131(s, p, o, m) BOOST_PP_FOR_131_C(BOOST_PP_BOOL(p(132, s)), s, p, o, m)
+# define BOOST_PP_FOR_132(s, p, o, m) BOOST_PP_FOR_132_C(BOOST_PP_BOOL(p(133, s)), s, p, o, m)
+# define BOOST_PP_FOR_133(s, p, o, m) BOOST_PP_FOR_133_C(BOOST_PP_BOOL(p(134, s)), s, p, o, m)
+# define BOOST_PP_FOR_134(s, p, o, m) BOOST_PP_FOR_134_C(BOOST_PP_BOOL(p(135, s)), s, p, o, m)
+# define BOOST_PP_FOR_135(s, p, o, m) BOOST_PP_FOR_135_C(BOOST_PP_BOOL(p(136, s)), s, p, o, m)
+# define BOOST_PP_FOR_136(s, p, o, m) BOOST_PP_FOR_136_C(BOOST_PP_BOOL(p(137, s)), s, p, o, m)
+# define BOOST_PP_FOR_137(s, p, o, m) BOOST_PP_FOR_137_C(BOOST_PP_BOOL(p(138, s)), s, p, o, m)
+# define BOOST_PP_FOR_138(s, p, o, m) BOOST_PP_FOR_138_C(BOOST_PP_BOOL(p(139, s)), s, p, o, m)
+# define BOOST_PP_FOR_139(s, p, o, m) BOOST_PP_FOR_139_C(BOOST_PP_BOOL(p(140, s)), s, p, o, m)
+# define BOOST_PP_FOR_140(s, p, o, m) BOOST_PP_FOR_140_C(BOOST_PP_BOOL(p(141, s)), s, p, o, m)
+# define BOOST_PP_FOR_141(s, p, o, m) BOOST_PP_FOR_141_C(BOOST_PP_BOOL(p(142, s)), s, p, o, m)
+# define BOOST_PP_FOR_142(s, p, o, m) BOOST_PP_FOR_142_C(BOOST_PP_BOOL(p(143, s)), s, p, o, m)
+# define BOOST_PP_FOR_143(s, p, o, m) BOOST_PP_FOR_143_C(BOOST_PP_BOOL(p(144, s)), s, p, o, m)
+# define BOOST_PP_FOR_144(s, p, o, m) BOOST_PP_FOR_144_C(BOOST_PP_BOOL(p(145, s)), s, p, o, m)
+# define BOOST_PP_FOR_145(s, p, o, m) BOOST_PP_FOR_145_C(BOOST_PP_BOOL(p(146, s)), s, p, o, m)
+# define BOOST_PP_FOR_146(s, p, o, m) BOOST_PP_FOR_146_C(BOOST_PP_BOOL(p(147, s)), s, p, o, m)
+# define BOOST_PP_FOR_147(s, p, o, m) BOOST_PP_FOR_147_C(BOOST_PP_BOOL(p(148, s)), s, p, o, m)
+# define BOOST_PP_FOR_148(s, p, o, m) BOOST_PP_FOR_148_C(BOOST_PP_BOOL(p(149, s)), s, p, o, m)
+# define BOOST_PP_FOR_149(s, p, o, m) BOOST_PP_FOR_149_C(BOOST_PP_BOOL(p(150, s)), s, p, o, m)
+# define BOOST_PP_FOR_150(s, p, o, m) BOOST_PP_FOR_150_C(BOOST_PP_BOOL(p(151, s)), s, p, o, m)
+# define BOOST_PP_FOR_151(s, p, o, m) BOOST_PP_FOR_151_C(BOOST_PP_BOOL(p(152, s)), s, p, o, m)
+# define BOOST_PP_FOR_152(s, p, o, m) BOOST_PP_FOR_152_C(BOOST_PP_BOOL(p(153, s)), s, p, o, m)
+# define BOOST_PP_FOR_153(s, p, o, m) BOOST_PP_FOR_153_C(BOOST_PP_BOOL(p(154, s)), s, p, o, m)
+# define BOOST_PP_FOR_154(s, p, o, m) BOOST_PP_FOR_154_C(BOOST_PP_BOOL(p(155, s)), s, p, o, m)
+# define BOOST_PP_FOR_155(s, p, o, m) BOOST_PP_FOR_155_C(BOOST_PP_BOOL(p(156, s)), s, p, o, m)
+# define BOOST_PP_FOR_156(s, p, o, m) BOOST_PP_FOR_156_C(BOOST_PP_BOOL(p(157, s)), s, p, o, m)
+# define BOOST_PP_FOR_157(s, p, o, m) BOOST_PP_FOR_157_C(BOOST_PP_BOOL(p(158, s)), s, p, o, m)
+# define BOOST_PP_FOR_158(s, p, o, m) BOOST_PP_FOR_158_C(BOOST_PP_BOOL(p(159, s)), s, p, o, m)
+# define BOOST_PP_FOR_159(s, p, o, m) BOOST_PP_FOR_159_C(BOOST_PP_BOOL(p(160, s)), s, p, o, m)
+# define BOOST_PP_FOR_160(s, p, o, m) BOOST_PP_FOR_160_C(BOOST_PP_BOOL(p(161, s)), s, p, o, m)
+# define BOOST_PP_FOR_161(s, p, o, m) BOOST_PP_FOR_161_C(BOOST_PP_BOOL(p(162, s)), s, p, o, m)
+# define BOOST_PP_FOR_162(s, p, o, m) BOOST_PP_FOR_162_C(BOOST_PP_BOOL(p(163, s)), s, p, o, m)
+# define BOOST_PP_FOR_163(s, p, o, m) BOOST_PP_FOR_163_C(BOOST_PP_BOOL(p(164, s)), s, p, o, m)
+# define BOOST_PP_FOR_164(s, p, o, m) BOOST_PP_FOR_164_C(BOOST_PP_BOOL(p(165, s)), s, p, o, m)
+# define BOOST_PP_FOR_165(s, p, o, m) BOOST_PP_FOR_165_C(BOOST_PP_BOOL(p(166, s)), s, p, o, m)
+# define BOOST_PP_FOR_166(s, p, o, m) BOOST_PP_FOR_166_C(BOOST_PP_BOOL(p(167, s)), s, p, o, m)
+# define BOOST_PP_FOR_167(s, p, o, m) BOOST_PP_FOR_167_C(BOOST_PP_BOOL(p(168, s)), s, p, o, m)
+# define BOOST_PP_FOR_168(s, p, o, m) BOOST_PP_FOR_168_C(BOOST_PP_BOOL(p(169, s)), s, p, o, m)
+# define BOOST_PP_FOR_169(s, p, o, m) BOOST_PP_FOR_169_C(BOOST_PP_BOOL(p(170, s)), s, p, o, m)
+# define BOOST_PP_FOR_170(s, p, o, m) BOOST_PP_FOR_170_C(BOOST_PP_BOOL(p(171, s)), s, p, o, m)
+# define BOOST_PP_FOR_171(s, p, o, m) BOOST_PP_FOR_171_C(BOOST_PP_BOOL(p(172, s)), s, p, o, m)
+# define BOOST_PP_FOR_172(s, p, o, m) BOOST_PP_FOR_172_C(BOOST_PP_BOOL(p(173, s)), s, p, o, m)
+# define BOOST_PP_FOR_173(s, p, o, m) BOOST_PP_FOR_173_C(BOOST_PP_BOOL(p(174, s)), s, p, o, m)
+# define BOOST_PP_FOR_174(s, p, o, m) BOOST_PP_FOR_174_C(BOOST_PP_BOOL(p(175, s)), s, p, o, m)
+# define BOOST_PP_FOR_175(s, p, o, m) BOOST_PP_FOR_175_C(BOOST_PP_BOOL(p(176, s)), s, p, o, m)
+# define BOOST_PP_FOR_176(s, p, o, m) BOOST_PP_FOR_176_C(BOOST_PP_BOOL(p(177, s)), s, p, o, m)
+# define BOOST_PP_FOR_177(s, p, o, m) BOOST_PP_FOR_177_C(BOOST_PP_BOOL(p(178, s)), s, p, o, m)
+# define BOOST_PP_FOR_178(s, p, o, m) BOOST_PP_FOR_178_C(BOOST_PP_BOOL(p(179, s)), s, p, o, m)
+# define BOOST_PP_FOR_179(s, p, o, m) BOOST_PP_FOR_179_C(BOOST_PP_BOOL(p(180, s)), s, p, o, m)
+# define BOOST_PP_FOR_180(s, p, o, m) BOOST_PP_FOR_180_C(BOOST_PP_BOOL(p(181, s)), s, p, o, m)
+# define BOOST_PP_FOR_181(s, p, o, m) BOOST_PP_FOR_181_C(BOOST_PP_BOOL(p(182, s)), s, p, o, m)
+# define BOOST_PP_FOR_182(s, p, o, m) BOOST_PP_FOR_182_C(BOOST_PP_BOOL(p(183, s)), s, p, o, m)
+# define BOOST_PP_FOR_183(s, p, o, m) BOOST_PP_FOR_183_C(BOOST_PP_BOOL(p(184, s)), s, p, o, m)
+# define BOOST_PP_FOR_184(s, p, o, m) BOOST_PP_FOR_184_C(BOOST_PP_BOOL(p(185, s)), s, p, o, m)
+# define BOOST_PP_FOR_185(s, p, o, m) BOOST_PP_FOR_185_C(BOOST_PP_BOOL(p(186, s)), s, p, o, m)
+# define BOOST_PP_FOR_186(s, p, o, m) BOOST_PP_FOR_186_C(BOOST_PP_BOOL(p(187, s)), s, p, o, m)
+# define BOOST_PP_FOR_187(s, p, o, m) BOOST_PP_FOR_187_C(BOOST_PP_BOOL(p(188, s)), s, p, o, m)
+# define BOOST_PP_FOR_188(s, p, o, m) BOOST_PP_FOR_188_C(BOOST_PP_BOOL(p(189, s)), s, p, o, m)
+# define BOOST_PP_FOR_189(s, p, o, m) BOOST_PP_FOR_189_C(BOOST_PP_BOOL(p(190, s)), s, p, o, m)
+# define BOOST_PP_FOR_190(s, p, o, m) BOOST_PP_FOR_190_C(BOOST_PP_BOOL(p(191, s)), s, p, o, m)
+# define BOOST_PP_FOR_191(s, p, o, m) BOOST_PP_FOR_191_C(BOOST_PP_BOOL(p(192, s)), s, p, o, m)
+# define BOOST_PP_FOR_192(s, p, o, m) BOOST_PP_FOR_192_C(BOOST_PP_BOOL(p(193, s)), s, p, o, m)
+# define BOOST_PP_FOR_193(s, p, o, m) BOOST_PP_FOR_193_C(BOOST_PP_BOOL(p(194, s)), s, p, o, m)
+# define BOOST_PP_FOR_194(s, p, o, m) BOOST_PP_FOR_194_C(BOOST_PP_BOOL(p(195, s)), s, p, o, m)
+# define BOOST_PP_FOR_195(s, p, o, m) BOOST_PP_FOR_195_C(BOOST_PP_BOOL(p(196, s)), s, p, o, m)
+# define BOOST_PP_FOR_196(s, p, o, m) BOOST_PP_FOR_196_C(BOOST_PP_BOOL(p(197, s)), s, p, o, m)
+# define BOOST_PP_FOR_197(s, p, o, m) BOOST_PP_FOR_197_C(BOOST_PP_BOOL(p(198, s)), s, p, o, m)
+# define BOOST_PP_FOR_198(s, p, o, m) BOOST_PP_FOR_198_C(BOOST_PP_BOOL(p(199, s)), s, p, o, m)
+# define BOOST_PP_FOR_199(s, p, o, m) BOOST_PP_FOR_199_C(BOOST_PP_BOOL(p(200, s)), s, p, o, m)
+# define BOOST_PP_FOR_200(s, p, o, m) BOOST_PP_FOR_200_C(BOOST_PP_BOOL(p(201, s)), s, p, o, m)
+# define BOOST_PP_FOR_201(s, p, o, m) BOOST_PP_FOR_201_C(BOOST_PP_BOOL(p(202, s)), s, p, o, m)
+# define BOOST_PP_FOR_202(s, p, o, m) BOOST_PP_FOR_202_C(BOOST_PP_BOOL(p(203, s)), s, p, o, m)
+# define BOOST_PP_FOR_203(s, p, o, m) BOOST_PP_FOR_203_C(BOOST_PP_BOOL(p(204, s)), s, p, o, m)
+# define BOOST_PP_FOR_204(s, p, o, m) BOOST_PP_FOR_204_C(BOOST_PP_BOOL(p(205, s)), s, p, o, m)
+# define BOOST_PP_FOR_205(s, p, o, m) BOOST_PP_FOR_205_C(BOOST_PP_BOOL(p(206, s)), s, p, o, m)
+# define BOOST_PP_FOR_206(s, p, o, m) BOOST_PP_FOR_206_C(BOOST_PP_BOOL(p(207, s)), s, p, o, m)
+# define BOOST_PP_FOR_207(s, p, o, m) BOOST_PP_FOR_207_C(BOOST_PP_BOOL(p(208, s)), s, p, o, m)
+# define BOOST_PP_FOR_208(s, p, o, m) BOOST_PP_FOR_208_C(BOOST_PP_BOOL(p(209, s)), s, p, o, m)
+# define BOOST_PP_FOR_209(s, p, o, m) BOOST_PP_FOR_209_C(BOOST_PP_BOOL(p(210, s)), s, p, o, m)
+# define BOOST_PP_FOR_210(s, p, o, m) BOOST_PP_FOR_210_C(BOOST_PP_BOOL(p(211, s)), s, p, o, m)
+# define BOOST_PP_FOR_211(s, p, o, m) BOOST_PP_FOR_211_C(BOOST_PP_BOOL(p(212, s)), s, p, o, m)
+# define BOOST_PP_FOR_212(s, p, o, m) BOOST_PP_FOR_212_C(BOOST_PP_BOOL(p(213, s)), s, p, o, m)
+# define BOOST_PP_FOR_213(s, p, o, m) BOOST_PP_FOR_213_C(BOOST_PP_BOOL(p(214, s)), s, p, o, m)
+# define BOOST_PP_FOR_214(s, p, o, m) BOOST_PP_FOR_214_C(BOOST_PP_BOOL(p(215, s)), s, p, o, m)
+# define BOOST_PP_FOR_215(s, p, o, m) BOOST_PP_FOR_215_C(BOOST_PP_BOOL(p(216, s)), s, p, o, m)
+# define BOOST_PP_FOR_216(s, p, o, m) BOOST_PP_FOR_216_C(BOOST_PP_BOOL(p(217, s)), s, p, o, m)
+# define BOOST_PP_FOR_217(s, p, o, m) BOOST_PP_FOR_217_C(BOOST_PP_BOOL(p(218, s)), s, p, o, m)
+# define BOOST_PP_FOR_218(s, p, o, m) BOOST_PP_FOR_218_C(BOOST_PP_BOOL(p(219, s)), s, p, o, m)
+# define BOOST_PP_FOR_219(s, p, o, m) BOOST_PP_FOR_219_C(BOOST_PP_BOOL(p(220, s)), s, p, o, m)
+# define BOOST_PP_FOR_220(s, p, o, m) BOOST_PP_FOR_220_C(BOOST_PP_BOOL(p(221, s)), s, p, o, m)
+# define BOOST_PP_FOR_221(s, p, o, m) BOOST_PP_FOR_221_C(BOOST_PP_BOOL(p(222, s)), s, p, o, m)
+# define BOOST_PP_FOR_222(s, p, o, m) BOOST_PP_FOR_222_C(BOOST_PP_BOOL(p(223, s)), s, p, o, m)
+# define BOOST_PP_FOR_223(s, p, o, m) BOOST_PP_FOR_223_C(BOOST_PP_BOOL(p(224, s)), s, p, o, m)
+# define BOOST_PP_FOR_224(s, p, o, m) BOOST_PP_FOR_224_C(BOOST_PP_BOOL(p(225, s)), s, p, o, m)
+# define BOOST_PP_FOR_225(s, p, o, m) BOOST_PP_FOR_225_C(BOOST_PP_BOOL(p(226, s)), s, p, o, m)
+# define BOOST_PP_FOR_226(s, p, o, m) BOOST_PP_FOR_226_C(BOOST_PP_BOOL(p(227, s)), s, p, o, m)
+# define BOOST_PP_FOR_227(s, p, o, m) BOOST_PP_FOR_227_C(BOOST_PP_BOOL(p(228, s)), s, p, o, m)
+# define BOOST_PP_FOR_228(s, p, o, m) BOOST_PP_FOR_228_C(BOOST_PP_BOOL(p(229, s)), s, p, o, m)
+# define BOOST_PP_FOR_229(s, p, o, m) BOOST_PP_FOR_229_C(BOOST_PP_BOOL(p(230, s)), s, p, o, m)
+# define BOOST_PP_FOR_230(s, p, o, m) BOOST_PP_FOR_230_C(BOOST_PP_BOOL(p(231, s)), s, p, o, m)
+# define BOOST_PP_FOR_231(s, p, o, m) BOOST_PP_FOR_231_C(BOOST_PP_BOOL(p(232, s)), s, p, o, m)
+# define BOOST_PP_FOR_232(s, p, o, m) BOOST_PP_FOR_232_C(BOOST_PP_BOOL(p(233, s)), s, p, o, m)
+# define BOOST_PP_FOR_233(s, p, o, m) BOOST_PP_FOR_233_C(BOOST_PP_BOOL(p(234, s)), s, p, o, m)
+# define BOOST_PP_FOR_234(s, p, o, m) BOOST_PP_FOR_234_C(BOOST_PP_BOOL(p(235, s)), s, p, o, m)
+# define BOOST_PP_FOR_235(s, p, o, m) BOOST_PP_FOR_235_C(BOOST_PP_BOOL(p(236, s)), s, p, o, m)
+# define BOOST_PP_FOR_236(s, p, o, m) BOOST_PP_FOR_236_C(BOOST_PP_BOOL(p(237, s)), s, p, o, m)
+# define BOOST_PP_FOR_237(s, p, o, m) BOOST_PP_FOR_237_C(BOOST_PP_BOOL(p(238, s)), s, p, o, m)
+# define BOOST_PP_FOR_238(s, p, o, m) BOOST_PP_FOR_238_C(BOOST_PP_BOOL(p(239, s)), s, p, o, m)
+# define BOOST_PP_FOR_239(s, p, o, m) BOOST_PP_FOR_239_C(BOOST_PP_BOOL(p(240, s)), s, p, o, m)
+# define BOOST_PP_FOR_240(s, p, o, m) BOOST_PP_FOR_240_C(BOOST_PP_BOOL(p(241, s)), s, p, o, m)
+# define BOOST_PP_FOR_241(s, p, o, m) BOOST_PP_FOR_241_C(BOOST_PP_BOOL(p(242, s)), s, p, o, m)
+# define BOOST_PP_FOR_242(s, p, o, m) BOOST_PP_FOR_242_C(BOOST_PP_BOOL(p(243, s)), s, p, o, m)
+# define BOOST_PP_FOR_243(s, p, o, m) BOOST_PP_FOR_243_C(BOOST_PP_BOOL(p(244, s)), s, p, o, m)
+# define BOOST_PP_FOR_244(s, p, o, m) BOOST_PP_FOR_244_C(BOOST_PP_BOOL(p(245, s)), s, p, o, m)
+# define BOOST_PP_FOR_245(s, p, o, m) BOOST_PP_FOR_245_C(BOOST_PP_BOOL(p(246, s)), s, p, o, m)
+# define BOOST_PP_FOR_246(s, p, o, m) BOOST_PP_FOR_246_C(BOOST_PP_BOOL(p(247, s)), s, p, o, m)
+# define BOOST_PP_FOR_247(s, p, o, m) BOOST_PP_FOR_247_C(BOOST_PP_BOOL(p(248, s)), s, p, o, m)
+# define BOOST_PP_FOR_248(s, p, o, m) BOOST_PP_FOR_248_C(BOOST_PP_BOOL(p(249, s)), s, p, o, m)
+# define BOOST_PP_FOR_249(s, p, o, m) BOOST_PP_FOR_249_C(BOOST_PP_BOOL(p(250, s)), s, p, o, m)
+# define BOOST_PP_FOR_250(s, p, o, m) BOOST_PP_FOR_250_C(BOOST_PP_BOOL(p(251, s)), s, p, o, m)
+# define BOOST_PP_FOR_251(s, p, o, m) BOOST_PP_FOR_251_C(BOOST_PP_BOOL(p(252, s)), s, p, o, m)
+# define BOOST_PP_FOR_252(s, p, o, m) BOOST_PP_FOR_252_C(BOOST_PP_BOOL(p(253, s)), s, p, o, m)
+# define BOOST_PP_FOR_253(s, p, o, m) BOOST_PP_FOR_253_C(BOOST_PP_BOOL(p(254, s)), s, p, o, m)
+# define BOOST_PP_FOR_254(s, p, o, m) BOOST_PP_FOR_254_C(BOOST_PP_BOOL(p(255, s)), s, p, o, m)
+# define BOOST_PP_FOR_255(s, p, o, m) BOOST_PP_FOR_255_C(BOOST_PP_BOOL(p(256, s)), s, p, o, m)
+# define BOOST_PP_FOR_256(s, p, o, m) BOOST_PP_FOR_256_C(BOOST_PP_BOOL(p(257, s)), s, p, o, m)
+#
+# define BOOST_PP_FOR_1_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(2, s) BOOST_PP_IIF(c, BOOST_PP_FOR_2, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(2, s), p, o, m)
+# define BOOST_PP_FOR_2_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(3, s) BOOST_PP_IIF(c, BOOST_PP_FOR_3, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(3, s), p, o, m)
+# define BOOST_PP_FOR_3_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(4, s) BOOST_PP_IIF(c, BOOST_PP_FOR_4, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(4, s), p, o, m)
+# define BOOST_PP_FOR_4_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(5, s) BOOST_PP_IIF(c, BOOST_PP_FOR_5, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(5, s), p, o, m)
+# define BOOST_PP_FOR_5_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(6, s) BOOST_PP_IIF(c, BOOST_PP_FOR_6, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(6, s), p, o, m)
+# define BOOST_PP_FOR_6_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(7, s) BOOST_PP_IIF(c, BOOST_PP_FOR_7, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(7, s), p, o, m)
+# define BOOST_PP_FOR_7_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(8, s) BOOST_PP_IIF(c, BOOST_PP_FOR_8, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(8, s), p, o, m)
+# define BOOST_PP_FOR_8_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(9, s) BOOST_PP_IIF(c, BOOST_PP_FOR_9, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(9, s), p, o, m)
+# define BOOST_PP_FOR_9_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(10, s) BOOST_PP_IIF(c, BOOST_PP_FOR_10, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(10, s), p, o, m)
+# define BOOST_PP_FOR_10_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(11, s) BOOST_PP_IIF(c, BOOST_PP_FOR_11, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(11, s), p, o, m)
+# define BOOST_PP_FOR_11_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(12, s) BOOST_PP_IIF(c, BOOST_PP_FOR_12, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(12, s), p, o, m)
+# define BOOST_PP_FOR_12_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(13, s) BOOST_PP_IIF(c, BOOST_PP_FOR_13, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(13, s), p, o, m)
+# define BOOST_PP_FOR_13_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(14, s) BOOST_PP_IIF(c, BOOST_PP_FOR_14, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(14, s), p, o, m)
+# define BOOST_PP_FOR_14_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(15, s) BOOST_PP_IIF(c, BOOST_PP_FOR_15, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(15, s), p, o, m)
+# define BOOST_PP_FOR_15_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(16, s) BOOST_PP_IIF(c, BOOST_PP_FOR_16, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(16, s), p, o, m)
+# define BOOST_PP_FOR_16_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(17, s) BOOST_PP_IIF(c, BOOST_PP_FOR_17, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(17, s), p, o, m)
+# define BOOST_PP_FOR_17_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(18, s) BOOST_PP_IIF(c, BOOST_PP_FOR_18, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(18, s), p, o, m)
+# define BOOST_PP_FOR_18_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(19, s) BOOST_PP_IIF(c, BOOST_PP_FOR_19, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(19, s), p, o, m)
+# define BOOST_PP_FOR_19_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(20, s) BOOST_PP_IIF(c, BOOST_PP_FOR_20, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(20, s), p, o, m)
+# define BOOST_PP_FOR_20_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(21, s) BOOST_PP_IIF(c, BOOST_PP_FOR_21, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(21, s), p, o, m)
+# define BOOST_PP_FOR_21_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(22, s) BOOST_PP_IIF(c, BOOST_PP_FOR_22, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(22, s), p, o, m)
+# define BOOST_PP_FOR_22_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(23, s) BOOST_PP_IIF(c, BOOST_PP_FOR_23, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(23, s), p, o, m)
+# define BOOST_PP_FOR_23_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(24, s) BOOST_PP_IIF(c, BOOST_PP_FOR_24, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(24, s), p, o, m)
+# define BOOST_PP_FOR_24_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(25, s) BOOST_PP_IIF(c, BOOST_PP_FOR_25, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(25, s), p, o, m)
+# define BOOST_PP_FOR_25_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(26, s) BOOST_PP_IIF(c, BOOST_PP_FOR_26, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(26, s), p, o, m)
+# define BOOST_PP_FOR_26_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(27, s) BOOST_PP_IIF(c, BOOST_PP_FOR_27, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(27, s), p, o, m)
+# define BOOST_PP_FOR_27_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(28, s) BOOST_PP_IIF(c, BOOST_PP_FOR_28, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(28, s), p, o, m)
+# define BOOST_PP_FOR_28_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(29, s) BOOST_PP_IIF(c, BOOST_PP_FOR_29, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(29, s), p, o, m)
+# define BOOST_PP_FOR_29_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(30, s) BOOST_PP_IIF(c, BOOST_PP_FOR_30, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(30, s), p, o, m)
+# define BOOST_PP_FOR_30_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(31, s) BOOST_PP_IIF(c, BOOST_PP_FOR_31, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(31, s), p, o, m)
+# define BOOST_PP_FOR_31_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(32, s) BOOST_PP_IIF(c, BOOST_PP_FOR_32, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(32, s), p, o, m)
+# define BOOST_PP_FOR_32_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(33, s) BOOST_PP_IIF(c, BOOST_PP_FOR_33, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(33, s), p, o, m)
+# define BOOST_PP_FOR_33_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(34, s) BOOST_PP_IIF(c, BOOST_PP_FOR_34, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(34, s), p, o, m)
+# define BOOST_PP_FOR_34_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(35, s) BOOST_PP_IIF(c, BOOST_PP_FOR_35, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(35, s), p, o, m)
+# define BOOST_PP_FOR_35_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(36, s) BOOST_PP_IIF(c, BOOST_PP_FOR_36, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(36, s), p, o, m)
+# define BOOST_PP_FOR_36_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(37, s) BOOST_PP_IIF(c, BOOST_PP_FOR_37, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(37, s), p, o, m)
+# define BOOST_PP_FOR_37_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(38, s) BOOST_PP_IIF(c, BOOST_PP_FOR_38, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(38, s), p, o, m)
+# define BOOST_PP_FOR_38_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(39, s) BOOST_PP_IIF(c, BOOST_PP_FOR_39, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(39, s), p, o, m)
+# define BOOST_PP_FOR_39_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(40, s) BOOST_PP_IIF(c, BOOST_PP_FOR_40, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(40, s), p, o, m)
+# define BOOST_PP_FOR_40_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(41, s) BOOST_PP_IIF(c, BOOST_PP_FOR_41, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(41, s), p, o, m)
+# define BOOST_PP_FOR_41_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(42, s) BOOST_PP_IIF(c, BOOST_PP_FOR_42, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(42, s), p, o, m)
+# define BOOST_PP_FOR_42_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(43, s) BOOST_PP_IIF(c, BOOST_PP_FOR_43, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(43, s), p, o, m)
+# define BOOST_PP_FOR_43_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(44, s) BOOST_PP_IIF(c, BOOST_PP_FOR_44, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(44, s), p, o, m)
+# define BOOST_PP_FOR_44_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(45, s) BOOST_PP_IIF(c, BOOST_PP_FOR_45, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(45, s), p, o, m)
+# define BOOST_PP_FOR_45_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(46, s) BOOST_PP_IIF(c, BOOST_PP_FOR_46, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(46, s), p, o, m)
+# define BOOST_PP_FOR_46_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(47, s) BOOST_PP_IIF(c, BOOST_PP_FOR_47, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(47, s), p, o, m)
+# define BOOST_PP_FOR_47_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(48, s) BOOST_PP_IIF(c, BOOST_PP_FOR_48, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(48, s), p, o, m)
+# define BOOST_PP_FOR_48_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(49, s) BOOST_PP_IIF(c, BOOST_PP_FOR_49, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(49, s), p, o, m)
+# define BOOST_PP_FOR_49_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(50, s) BOOST_PP_IIF(c, BOOST_PP_FOR_50, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(50, s), p, o, m)
+# define BOOST_PP_FOR_50_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(51, s) BOOST_PP_IIF(c, BOOST_PP_FOR_51, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(51, s), p, o, m)
+# define BOOST_PP_FOR_51_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(52, s) BOOST_PP_IIF(c, BOOST_PP_FOR_52, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(52, s), p, o, m)
+# define BOOST_PP_FOR_52_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(53, s) BOOST_PP_IIF(c, BOOST_PP_FOR_53, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(53, s), p, o, m)
+# define BOOST_PP_FOR_53_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(54, s) BOOST_PP_IIF(c, BOOST_PP_FOR_54, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(54, s), p, o, m)
+# define BOOST_PP_FOR_54_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(55, s) BOOST_PP_IIF(c, BOOST_PP_FOR_55, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(55, s), p, o, m)
+# define BOOST_PP_FOR_55_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(56, s) BOOST_PP_IIF(c, BOOST_PP_FOR_56, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(56, s), p, o, m)
+# define BOOST_PP_FOR_56_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(57, s) BOOST_PP_IIF(c, BOOST_PP_FOR_57, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(57, s), p, o, m)
+# define BOOST_PP_FOR_57_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(58, s) BOOST_PP_IIF(c, BOOST_PP_FOR_58, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(58, s), p, o, m)
+# define BOOST_PP_FOR_58_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(59, s) BOOST_PP_IIF(c, BOOST_PP_FOR_59, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(59, s), p, o, m)
+# define BOOST_PP_FOR_59_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(60, s) BOOST_PP_IIF(c, BOOST_PP_FOR_60, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(60, s), p, o, m)
+# define BOOST_PP_FOR_60_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(61, s) BOOST_PP_IIF(c, BOOST_PP_FOR_61, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(61, s), p, o, m)
+# define BOOST_PP_FOR_61_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(62, s) BOOST_PP_IIF(c, BOOST_PP_FOR_62, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(62, s), p, o, m)
+# define BOOST_PP_FOR_62_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(63, s) BOOST_PP_IIF(c, BOOST_PP_FOR_63, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(63, s), p, o, m)
+# define BOOST_PP_FOR_63_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(64, s) BOOST_PP_IIF(c, BOOST_PP_FOR_64, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(64, s), p, o, m)
+# define BOOST_PP_FOR_64_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(65, s) BOOST_PP_IIF(c, BOOST_PP_FOR_65, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(65, s), p, o, m)
+# define BOOST_PP_FOR_65_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(66, s) BOOST_PP_IIF(c, BOOST_PP_FOR_66, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(66, s), p, o, m)
+# define BOOST_PP_FOR_66_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(67, s) BOOST_PP_IIF(c, BOOST_PP_FOR_67, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(67, s), p, o, m)
+# define BOOST_PP_FOR_67_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(68, s) BOOST_PP_IIF(c, BOOST_PP_FOR_68, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(68, s), p, o, m)
+# define BOOST_PP_FOR_68_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(69, s) BOOST_PP_IIF(c, BOOST_PP_FOR_69, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(69, s), p, o, m)
+# define BOOST_PP_FOR_69_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(70, s) BOOST_PP_IIF(c, BOOST_PP_FOR_70, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(70, s), p, o, m)
+# define BOOST_PP_FOR_70_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(71, s) BOOST_PP_IIF(c, BOOST_PP_FOR_71, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(71, s), p, o, m)
+# define BOOST_PP_FOR_71_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(72, s) BOOST_PP_IIF(c, BOOST_PP_FOR_72, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(72, s), p, o, m)
+# define BOOST_PP_FOR_72_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(73, s) BOOST_PP_IIF(c, BOOST_PP_FOR_73, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(73, s), p, o, m)
+# define BOOST_PP_FOR_73_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(74, s) BOOST_PP_IIF(c, BOOST_PP_FOR_74, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(74, s), p, o, m)
+# define BOOST_PP_FOR_74_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(75, s) BOOST_PP_IIF(c, BOOST_PP_FOR_75, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(75, s), p, o, m)
+# define BOOST_PP_FOR_75_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(76, s) BOOST_PP_IIF(c, BOOST_PP_FOR_76, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(76, s), p, o, m)
+# define BOOST_PP_FOR_76_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(77, s) BOOST_PP_IIF(c, BOOST_PP_FOR_77, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(77, s), p, o, m)
+# define BOOST_PP_FOR_77_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(78, s) BOOST_PP_IIF(c, BOOST_PP_FOR_78, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(78, s), p, o, m)
+# define BOOST_PP_FOR_78_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(79, s) BOOST_PP_IIF(c, BOOST_PP_FOR_79, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(79, s), p, o, m)
+# define BOOST_PP_FOR_79_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(80, s) BOOST_PP_IIF(c, BOOST_PP_FOR_80, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(80, s), p, o, m)
+# define BOOST_PP_FOR_80_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(81, s) BOOST_PP_IIF(c, BOOST_PP_FOR_81, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(81, s), p, o, m)
+# define BOOST_PP_FOR_81_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(82, s) BOOST_PP_IIF(c, BOOST_PP_FOR_82, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(82, s), p, o, m)
+# define BOOST_PP_FOR_82_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(83, s) BOOST_PP_IIF(c, BOOST_PP_FOR_83, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(83, s), p, o, m)
+# define BOOST_PP_FOR_83_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(84, s) BOOST_PP_IIF(c, BOOST_PP_FOR_84, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(84, s), p, o, m)
+# define BOOST_PP_FOR_84_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(85, s) BOOST_PP_IIF(c, BOOST_PP_FOR_85, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(85, s), p, o, m)
+# define BOOST_PP_FOR_85_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(86, s) BOOST_PP_IIF(c, BOOST_PP_FOR_86, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(86, s), p, o, m)
+# define BOOST_PP_FOR_86_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(87, s) BOOST_PP_IIF(c, BOOST_PP_FOR_87, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(87, s), p, o, m)
+# define BOOST_PP_FOR_87_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(88, s) BOOST_PP_IIF(c, BOOST_PP_FOR_88, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(88, s), p, o, m)
+# define BOOST_PP_FOR_88_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(89, s) BOOST_PP_IIF(c, BOOST_PP_FOR_89, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(89, s), p, o, m)
+# define BOOST_PP_FOR_89_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(90, s) BOOST_PP_IIF(c, BOOST_PP_FOR_90, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(90, s), p, o, m)
+# define BOOST_PP_FOR_90_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(91, s) BOOST_PP_IIF(c, BOOST_PP_FOR_91, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(91, s), p, o, m)
+# define BOOST_PP_FOR_91_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(92, s) BOOST_PP_IIF(c, BOOST_PP_FOR_92, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(92, s), p, o, m)
+# define BOOST_PP_FOR_92_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(93, s) BOOST_PP_IIF(c, BOOST_PP_FOR_93, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(93, s), p, o, m)
+# define BOOST_PP_FOR_93_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(94, s) BOOST_PP_IIF(c, BOOST_PP_FOR_94, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(94, s), p, o, m)
+# define BOOST_PP_FOR_94_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(95, s) BOOST_PP_IIF(c, BOOST_PP_FOR_95, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(95, s), p, o, m)
+# define BOOST_PP_FOR_95_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(96, s) BOOST_PP_IIF(c, BOOST_PP_FOR_96, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(96, s), p, o, m)
+# define BOOST_PP_FOR_96_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(97, s) BOOST_PP_IIF(c, BOOST_PP_FOR_97, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(97, s), p, o, m)
+# define BOOST_PP_FOR_97_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(98, s) BOOST_PP_IIF(c, BOOST_PP_FOR_98, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(98, s), p, o, m)
+# define BOOST_PP_FOR_98_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(99, s) BOOST_PP_IIF(c, BOOST_PP_FOR_99, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(99, s), p, o, m)
+# define BOOST_PP_FOR_99_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(100, s) BOOST_PP_IIF(c, BOOST_PP_FOR_100, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(100, s), p, o, m)
+# define BOOST_PP_FOR_100_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(101, s) BOOST_PP_IIF(c, BOOST_PP_FOR_101, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(101, s), p, o, m)
+# define BOOST_PP_FOR_101_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(102, s) BOOST_PP_IIF(c, BOOST_PP_FOR_102, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(102, s), p, o, m)
+# define BOOST_PP_FOR_102_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(103, s) BOOST_PP_IIF(c, BOOST_PP_FOR_103, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(103, s), p, o, m)
+# define BOOST_PP_FOR_103_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(104, s) BOOST_PP_IIF(c, BOOST_PP_FOR_104, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(104, s), p, o, m)
+# define BOOST_PP_FOR_104_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(105, s) BOOST_PP_IIF(c, BOOST_PP_FOR_105, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(105, s), p, o, m)
+# define BOOST_PP_FOR_105_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(106, s) BOOST_PP_IIF(c, BOOST_PP_FOR_106, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(106, s), p, o, m)
+# define BOOST_PP_FOR_106_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(107, s) BOOST_PP_IIF(c, BOOST_PP_FOR_107, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(107, s), p, o, m)
+# define BOOST_PP_FOR_107_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(108, s) BOOST_PP_IIF(c, BOOST_PP_FOR_108, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(108, s), p, o, m)
+# define BOOST_PP_FOR_108_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(109, s) BOOST_PP_IIF(c, BOOST_PP_FOR_109, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(109, s), p, o, m)
+# define BOOST_PP_FOR_109_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(110, s) BOOST_PP_IIF(c, BOOST_PP_FOR_110, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(110, s), p, o, m)
+# define BOOST_PP_FOR_110_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(111, s) BOOST_PP_IIF(c, BOOST_PP_FOR_111, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(111, s), p, o, m)
+# define BOOST_PP_FOR_111_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(112, s) BOOST_PP_IIF(c, BOOST_PP_FOR_112, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(112, s), p, o, m)
+# define BOOST_PP_FOR_112_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(113, s) BOOST_PP_IIF(c, BOOST_PP_FOR_113, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(113, s), p, o, m)
+# define BOOST_PP_FOR_113_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(114, s) BOOST_PP_IIF(c, BOOST_PP_FOR_114, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(114, s), p, o, m)
+# define BOOST_PP_FOR_114_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(115, s) BOOST_PP_IIF(c, BOOST_PP_FOR_115, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(115, s), p, o, m)
+# define BOOST_PP_FOR_115_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(116, s) BOOST_PP_IIF(c, BOOST_PP_FOR_116, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(116, s), p, o, m)
+# define BOOST_PP_FOR_116_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(117, s) BOOST_PP_IIF(c, BOOST_PP_FOR_117, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(117, s), p, o, m)
+# define BOOST_PP_FOR_117_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(118, s) BOOST_PP_IIF(c, BOOST_PP_FOR_118, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(118, s), p, o, m)
+# define BOOST_PP_FOR_118_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(119, s) BOOST_PP_IIF(c, BOOST_PP_FOR_119, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(119, s), p, o, m)
+# define BOOST_PP_FOR_119_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(120, s) BOOST_PP_IIF(c, BOOST_PP_FOR_120, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(120, s), p, o, m)
+# define BOOST_PP_FOR_120_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(121, s) BOOST_PP_IIF(c, BOOST_PP_FOR_121, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(121, s), p, o, m)
+# define BOOST_PP_FOR_121_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(122, s) BOOST_PP_IIF(c, BOOST_PP_FOR_122, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(122, s), p, o, m)
+# define BOOST_PP_FOR_122_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(123, s) BOOST_PP_IIF(c, BOOST_PP_FOR_123, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(123, s), p, o, m)
+# define BOOST_PP_FOR_123_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(124, s) BOOST_PP_IIF(c, BOOST_PP_FOR_124, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(124, s), p, o, m)
+# define BOOST_PP_FOR_124_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(125, s) BOOST_PP_IIF(c, BOOST_PP_FOR_125, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(125, s), p, o, m)
+# define BOOST_PP_FOR_125_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(126, s) BOOST_PP_IIF(c, BOOST_PP_FOR_126, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(126, s), p, o, m)
+# define BOOST_PP_FOR_126_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(127, s) BOOST_PP_IIF(c, BOOST_PP_FOR_127, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(127, s), p, o, m)
+# define BOOST_PP_FOR_127_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(128, s) BOOST_PP_IIF(c, BOOST_PP_FOR_128, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(128, s), p, o, m)
+# define BOOST_PP_FOR_128_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(129, s) BOOST_PP_IIF(c, BOOST_PP_FOR_129, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(129, s), p, o, m)
+# define BOOST_PP_FOR_129_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(130, s) BOOST_PP_IIF(c, BOOST_PP_FOR_130, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(130, s), p, o, m)
+# define BOOST_PP_FOR_130_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(131, s) BOOST_PP_IIF(c, BOOST_PP_FOR_131, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(131, s), p, o, m)
+# define BOOST_PP_FOR_131_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(132, s) BOOST_PP_IIF(c, BOOST_PP_FOR_132, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(132, s), p, o, m)
+# define BOOST_PP_FOR_132_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(133, s) BOOST_PP_IIF(c, BOOST_PP_FOR_133, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(133, s), p, o, m)
+# define BOOST_PP_FOR_133_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(134, s) BOOST_PP_IIF(c, BOOST_PP_FOR_134, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(134, s), p, o, m)
+# define BOOST_PP_FOR_134_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(135, s) BOOST_PP_IIF(c, BOOST_PP_FOR_135, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(135, s), p, o, m)
+# define BOOST_PP_FOR_135_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(136, s) BOOST_PP_IIF(c, BOOST_PP_FOR_136, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(136, s), p, o, m)
+# define BOOST_PP_FOR_136_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(137, s) BOOST_PP_IIF(c, BOOST_PP_FOR_137, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(137, s), p, o, m)
+# define BOOST_PP_FOR_137_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(138, s) BOOST_PP_IIF(c, BOOST_PP_FOR_138, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(138, s), p, o, m)
+# define BOOST_PP_FOR_138_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(139, s) BOOST_PP_IIF(c, BOOST_PP_FOR_139, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(139, s), p, o, m)
+# define BOOST_PP_FOR_139_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(140, s) BOOST_PP_IIF(c, BOOST_PP_FOR_140, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(140, s), p, o, m)
+# define BOOST_PP_FOR_140_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(141, s) BOOST_PP_IIF(c, BOOST_PP_FOR_141, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(141, s), p, o, m)
+# define BOOST_PP_FOR_141_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(142, s) BOOST_PP_IIF(c, BOOST_PP_FOR_142, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(142, s), p, o, m)
+# define BOOST_PP_FOR_142_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(143, s) BOOST_PP_IIF(c, BOOST_PP_FOR_143, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(143, s), p, o, m)
+# define BOOST_PP_FOR_143_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(144, s) BOOST_PP_IIF(c, BOOST_PP_FOR_144, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(144, s), p, o, m)
+# define BOOST_PP_FOR_144_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(145, s) BOOST_PP_IIF(c, BOOST_PP_FOR_145, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(145, s), p, o, m)
+# define BOOST_PP_FOR_145_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(146, s) BOOST_PP_IIF(c, BOOST_PP_FOR_146, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(146, s), p, o, m)
+# define BOOST_PP_FOR_146_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(147, s) BOOST_PP_IIF(c, BOOST_PP_FOR_147, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(147, s), p, o, m)
+# define BOOST_PP_FOR_147_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(148, s) BOOST_PP_IIF(c, BOOST_PP_FOR_148, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(148, s), p, o, m)
+# define BOOST_PP_FOR_148_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(149, s) BOOST_PP_IIF(c, BOOST_PP_FOR_149, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(149, s), p, o, m)
+# define BOOST_PP_FOR_149_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(150, s) BOOST_PP_IIF(c, BOOST_PP_FOR_150, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(150, s), p, o, m)
+# define BOOST_PP_FOR_150_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(151, s) BOOST_PP_IIF(c, BOOST_PP_FOR_151, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(151, s), p, o, m)
+# define BOOST_PP_FOR_151_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(152, s) BOOST_PP_IIF(c, BOOST_PP_FOR_152, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(152, s), p, o, m)
+# define BOOST_PP_FOR_152_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(153, s) BOOST_PP_IIF(c, BOOST_PP_FOR_153, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(153, s), p, o, m)
+# define BOOST_PP_FOR_153_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(154, s) BOOST_PP_IIF(c, BOOST_PP_FOR_154, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(154, s), p, o, m)
+# define BOOST_PP_FOR_154_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(155, s) BOOST_PP_IIF(c, BOOST_PP_FOR_155, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(155, s), p, o, m)
+# define BOOST_PP_FOR_155_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(156, s) BOOST_PP_IIF(c, BOOST_PP_FOR_156, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(156, s), p, o, m)
+# define BOOST_PP_FOR_156_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(157, s) BOOST_PP_IIF(c, BOOST_PP_FOR_157, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(157, s), p, o, m)
+# define BOOST_PP_FOR_157_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(158, s) BOOST_PP_IIF(c, BOOST_PP_FOR_158, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(158, s), p, o, m)
+# define BOOST_PP_FOR_158_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(159, s) BOOST_PP_IIF(c, BOOST_PP_FOR_159, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(159, s), p, o, m)
+# define BOOST_PP_FOR_159_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(160, s) BOOST_PP_IIF(c, BOOST_PP_FOR_160, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(160, s), p, o, m)
+# define BOOST_PP_FOR_160_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(161, s) BOOST_PP_IIF(c, BOOST_PP_FOR_161, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(161, s), p, o, m)
+# define BOOST_PP_FOR_161_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(162, s) BOOST_PP_IIF(c, BOOST_PP_FOR_162, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(162, s), p, o, m)
+# define BOOST_PP_FOR_162_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(163, s) BOOST_PP_IIF(c, BOOST_PP_FOR_163, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(163, s), p, o, m)
+# define BOOST_PP_FOR_163_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(164, s) BOOST_PP_IIF(c, BOOST_PP_FOR_164, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(164, s), p, o, m)
+# define BOOST_PP_FOR_164_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(165, s) BOOST_PP_IIF(c, BOOST_PP_FOR_165, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(165, s), p, o, m)
+# define BOOST_PP_FOR_165_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(166, s) BOOST_PP_IIF(c, BOOST_PP_FOR_166, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(166, s), p, o, m)
+# define BOOST_PP_FOR_166_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(167, s) BOOST_PP_IIF(c, BOOST_PP_FOR_167, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(167, s), p, o, m)
+# define BOOST_PP_FOR_167_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(168, s) BOOST_PP_IIF(c, BOOST_PP_FOR_168, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(168, s), p, o, m)
+# define BOOST_PP_FOR_168_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(169, s) BOOST_PP_IIF(c, BOOST_PP_FOR_169, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(169, s), p, o, m)
+# define BOOST_PP_FOR_169_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(170, s) BOOST_PP_IIF(c, BOOST_PP_FOR_170, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(170, s), p, o, m)
+# define BOOST_PP_FOR_170_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(171, s) BOOST_PP_IIF(c, BOOST_PP_FOR_171, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(171, s), p, o, m)
+# define BOOST_PP_FOR_171_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(172, s) BOOST_PP_IIF(c, BOOST_PP_FOR_172, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(172, s), p, o, m)
+# define BOOST_PP_FOR_172_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(173, s) BOOST_PP_IIF(c, BOOST_PP_FOR_173, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(173, s), p, o, m)
+# define BOOST_PP_FOR_173_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(174, s) BOOST_PP_IIF(c, BOOST_PP_FOR_174, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(174, s), p, o, m)
+# define BOOST_PP_FOR_174_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(175, s) BOOST_PP_IIF(c, BOOST_PP_FOR_175, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(175, s), p, o, m)
+# define BOOST_PP_FOR_175_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(176, s) BOOST_PP_IIF(c, BOOST_PP_FOR_176, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(176, s), p, o, m)
+# define BOOST_PP_FOR_176_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(177, s) BOOST_PP_IIF(c, BOOST_PP_FOR_177, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(177, s), p, o, m)
+# define BOOST_PP_FOR_177_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(178, s) BOOST_PP_IIF(c, BOOST_PP_FOR_178, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(178, s), p, o, m)
+# define BOOST_PP_FOR_178_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(179, s) BOOST_PP_IIF(c, BOOST_PP_FOR_179, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(179, s), p, o, m)
+# define BOOST_PP_FOR_179_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(180, s) BOOST_PP_IIF(c, BOOST_PP_FOR_180, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(180, s), p, o, m)
+# define BOOST_PP_FOR_180_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(181, s) BOOST_PP_IIF(c, BOOST_PP_FOR_181, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(181, s), p, o, m)
+# define BOOST_PP_FOR_181_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(182, s) BOOST_PP_IIF(c, BOOST_PP_FOR_182, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(182, s), p, o, m)
+# define BOOST_PP_FOR_182_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(183, s) BOOST_PP_IIF(c, BOOST_PP_FOR_183, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(183, s), p, o, m)
+# define BOOST_PP_FOR_183_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(184, s) BOOST_PP_IIF(c, BOOST_PP_FOR_184, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(184, s), p, o, m)
+# define BOOST_PP_FOR_184_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(185, s) BOOST_PP_IIF(c, BOOST_PP_FOR_185, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(185, s), p, o, m)
+# define BOOST_PP_FOR_185_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(186, s) BOOST_PP_IIF(c, BOOST_PP_FOR_186, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(186, s), p, o, m)
+# define BOOST_PP_FOR_186_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(187, s) BOOST_PP_IIF(c, BOOST_PP_FOR_187, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(187, s), p, o, m)
+# define BOOST_PP_FOR_187_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(188, s) BOOST_PP_IIF(c, BOOST_PP_FOR_188, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(188, s), p, o, m)
+# define BOOST_PP_FOR_188_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(189, s) BOOST_PP_IIF(c, BOOST_PP_FOR_189, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(189, s), p, o, m)
+# define BOOST_PP_FOR_189_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(190, s) BOOST_PP_IIF(c, BOOST_PP_FOR_190, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(190, s), p, o, m)
+# define BOOST_PP_FOR_190_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(191, s) BOOST_PP_IIF(c, BOOST_PP_FOR_191, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(191, s), p, o, m)
+# define BOOST_PP_FOR_191_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(192, s) BOOST_PP_IIF(c, BOOST_PP_FOR_192, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(192, s), p, o, m)
+# define BOOST_PP_FOR_192_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(193, s) BOOST_PP_IIF(c, BOOST_PP_FOR_193, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(193, s), p, o, m)
+# define BOOST_PP_FOR_193_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(194, s) BOOST_PP_IIF(c, BOOST_PP_FOR_194, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(194, s), p, o, m)
+# define BOOST_PP_FOR_194_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(195, s) BOOST_PP_IIF(c, BOOST_PP_FOR_195, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(195, s), p, o, m)
+# define BOOST_PP_FOR_195_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(196, s) BOOST_PP_IIF(c, BOOST_PP_FOR_196, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(196, s), p, o, m)
+# define BOOST_PP_FOR_196_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(197, s) BOOST_PP_IIF(c, BOOST_PP_FOR_197, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(197, s), p, o, m)
+# define BOOST_PP_FOR_197_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(198, s) BOOST_PP_IIF(c, BOOST_PP_FOR_198, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(198, s), p, o, m)
+# define BOOST_PP_FOR_198_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(199, s) BOOST_PP_IIF(c, BOOST_PP_FOR_199, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(199, s), p, o, m)
+# define BOOST_PP_FOR_199_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(200, s) BOOST_PP_IIF(c, BOOST_PP_FOR_200, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(200, s), p, o, m)
+# define BOOST_PP_FOR_200_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(201, s) BOOST_PP_IIF(c, BOOST_PP_FOR_201, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(201, s), p, o, m)
+# define BOOST_PP_FOR_201_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(202, s) BOOST_PP_IIF(c, BOOST_PP_FOR_202, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(202, s), p, o, m)
+# define BOOST_PP_FOR_202_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(203, s) BOOST_PP_IIF(c, BOOST_PP_FOR_203, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(203, s), p, o, m)
+# define BOOST_PP_FOR_203_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(204, s) BOOST_PP_IIF(c, BOOST_PP_FOR_204, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(204, s), p, o, m)
+# define BOOST_PP_FOR_204_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(205, s) BOOST_PP_IIF(c, BOOST_PP_FOR_205, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(205, s), p, o, m)
+# define BOOST_PP_FOR_205_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(206, s) BOOST_PP_IIF(c, BOOST_PP_FOR_206, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(206, s), p, o, m)
+# define BOOST_PP_FOR_206_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(207, s) BOOST_PP_IIF(c, BOOST_PP_FOR_207, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(207, s), p, o, m)
+# define BOOST_PP_FOR_207_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(208, s) BOOST_PP_IIF(c, BOOST_PP_FOR_208, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(208, s), p, o, m)
+# define BOOST_PP_FOR_208_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(209, s) BOOST_PP_IIF(c, BOOST_PP_FOR_209, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(209, s), p, o, m)
+# define BOOST_PP_FOR_209_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(210, s) BOOST_PP_IIF(c, BOOST_PP_FOR_210, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(210, s), p, o, m)
+# define BOOST_PP_FOR_210_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(211, s) BOOST_PP_IIF(c, BOOST_PP_FOR_211, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(211, s), p, o, m)
+# define BOOST_PP_FOR_211_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(212, s) BOOST_PP_IIF(c, BOOST_PP_FOR_212, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(212, s), p, o, m)
+# define BOOST_PP_FOR_212_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(213, s) BOOST_PP_IIF(c, BOOST_PP_FOR_213, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(213, s), p, o, m)
+# define BOOST_PP_FOR_213_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(214, s) BOOST_PP_IIF(c, BOOST_PP_FOR_214, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(214, s), p, o, m)
+# define BOOST_PP_FOR_214_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(215, s) BOOST_PP_IIF(c, BOOST_PP_FOR_215, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(215, s), p, o, m)
+# define BOOST_PP_FOR_215_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(216, s) BOOST_PP_IIF(c, BOOST_PP_FOR_216, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(216, s), p, o, m)
+# define BOOST_PP_FOR_216_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(217, s) BOOST_PP_IIF(c, BOOST_PP_FOR_217, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(217, s), p, o, m)
+# define BOOST_PP_FOR_217_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(218, s) BOOST_PP_IIF(c, BOOST_PP_FOR_218, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(218, s), p, o, m)
+# define BOOST_PP_FOR_218_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(219, s) BOOST_PP_IIF(c, BOOST_PP_FOR_219, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(219, s), p, o, m)
+# define BOOST_PP_FOR_219_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(220, s) BOOST_PP_IIF(c, BOOST_PP_FOR_220, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(220, s), p, o, m)
+# define BOOST_PP_FOR_220_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(221, s) BOOST_PP_IIF(c, BOOST_PP_FOR_221, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(221, s), p, o, m)
+# define BOOST_PP_FOR_221_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(222, s) BOOST_PP_IIF(c, BOOST_PP_FOR_222, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(222, s), p, o, m)
+# define BOOST_PP_FOR_222_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(223, s) BOOST_PP_IIF(c, BOOST_PP_FOR_223, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(223, s), p, o, m)
+# define BOOST_PP_FOR_223_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(224, s) BOOST_PP_IIF(c, BOOST_PP_FOR_224, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(224, s), p, o, m)
+# define BOOST_PP_FOR_224_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(225, s) BOOST_PP_IIF(c, BOOST_PP_FOR_225, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(225, s), p, o, m)
+# define BOOST_PP_FOR_225_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(226, s) BOOST_PP_IIF(c, BOOST_PP_FOR_226, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(226, s), p, o, m)
+# define BOOST_PP_FOR_226_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(227, s) BOOST_PP_IIF(c, BOOST_PP_FOR_227, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(227, s), p, o, m)
+# define BOOST_PP_FOR_227_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(228, s) BOOST_PP_IIF(c, BOOST_PP_FOR_228, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(228, s), p, o, m)
+# define BOOST_PP_FOR_228_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(229, s) BOOST_PP_IIF(c, BOOST_PP_FOR_229, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(229, s), p, o, m)
+# define BOOST_PP_FOR_229_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(230, s) BOOST_PP_IIF(c, BOOST_PP_FOR_230, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(230, s), p, o, m)
+# define BOOST_PP_FOR_230_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(231, s) BOOST_PP_IIF(c, BOOST_PP_FOR_231, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(231, s), p, o, m)
+# define BOOST_PP_FOR_231_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(232, s) BOOST_PP_IIF(c, BOOST_PP_FOR_232, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(232, s), p, o, m)
+# define BOOST_PP_FOR_232_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(233, s) BOOST_PP_IIF(c, BOOST_PP_FOR_233, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(233, s), p, o, m)
+# define BOOST_PP_FOR_233_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(234, s) BOOST_PP_IIF(c, BOOST_PP_FOR_234, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(234, s), p, o, m)
+# define BOOST_PP_FOR_234_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(235, s) BOOST_PP_IIF(c, BOOST_PP_FOR_235, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(235, s), p, o, m)
+# define BOOST_PP_FOR_235_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(236, s) BOOST_PP_IIF(c, BOOST_PP_FOR_236, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(236, s), p, o, m)
+# define BOOST_PP_FOR_236_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(237, s) BOOST_PP_IIF(c, BOOST_PP_FOR_237, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(237, s), p, o, m)
+# define BOOST_PP_FOR_237_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(238, s) BOOST_PP_IIF(c, BOOST_PP_FOR_238, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(238, s), p, o, m)
+# define BOOST_PP_FOR_238_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(239, s) BOOST_PP_IIF(c, BOOST_PP_FOR_239, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(239, s), p, o, m)
+# define BOOST_PP_FOR_239_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(240, s) BOOST_PP_IIF(c, BOOST_PP_FOR_240, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(240, s), p, o, m)
+# define BOOST_PP_FOR_240_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(241, s) BOOST_PP_IIF(c, BOOST_PP_FOR_241, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(241, s), p, o, m)
+# define BOOST_PP_FOR_241_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(242, s) BOOST_PP_IIF(c, BOOST_PP_FOR_242, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(242, s), p, o, m)
+# define BOOST_PP_FOR_242_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(243, s) BOOST_PP_IIF(c, BOOST_PP_FOR_243, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(243, s), p, o, m)
+# define BOOST_PP_FOR_243_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(244, s) BOOST_PP_IIF(c, BOOST_PP_FOR_244, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(244, s), p, o, m)
+# define BOOST_PP_FOR_244_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(245, s) BOOST_PP_IIF(c, BOOST_PP_FOR_245, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(245, s), p, o, m)
+# define BOOST_PP_FOR_245_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(246, s) BOOST_PP_IIF(c, BOOST_PP_FOR_246, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(246, s), p, o, m)
+# define BOOST_PP_FOR_246_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(247, s) BOOST_PP_IIF(c, BOOST_PP_FOR_247, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(247, s), p, o, m)
+# define BOOST_PP_FOR_247_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(248, s) BOOST_PP_IIF(c, BOOST_PP_FOR_248, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(248, s), p, o, m)
+# define BOOST_PP_FOR_248_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(249, s) BOOST_PP_IIF(c, BOOST_PP_FOR_249, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(249, s), p, o, m)
+# define BOOST_PP_FOR_249_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(250, s) BOOST_PP_IIF(c, BOOST_PP_FOR_250, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(250, s), p, o, m)
+# define BOOST_PP_FOR_250_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(251, s) BOOST_PP_IIF(c, BOOST_PP_FOR_251, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(251, s), p, o, m)
+# define BOOST_PP_FOR_251_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(252, s) BOOST_PP_IIF(c, BOOST_PP_FOR_252, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(252, s), p, o, m)
+# define BOOST_PP_FOR_252_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(253, s) BOOST_PP_IIF(c, BOOST_PP_FOR_253, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(253, s), p, o, m)
+# define BOOST_PP_FOR_253_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(254, s) BOOST_PP_IIF(c, BOOST_PP_FOR_254, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(254, s), p, o, m)
+# define BOOST_PP_FOR_254_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(255, s) BOOST_PP_IIF(c, BOOST_PP_FOR_255, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(255, s), p, o, m)
+# define BOOST_PP_FOR_255_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(256, s) BOOST_PP_IIF(c, BOOST_PP_FOR_256, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(256, s), p, o, m)
+# define BOOST_PP_FOR_256_C(c, s, p, o, m) BOOST_PP_IIF(c, m, BOOST_PP_TUPLE_EAT_2)(257, s) BOOST_PP_IIF(c, BOOST_PP_FOR_257, BOOST_PP_TUPLE_EAT_4)(BOOST_PP_EXPR_IIF(c, o)(257, s), p, o, m)
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/enum.hpp b/third_party/boost/boost/preprocessor/repetition/enum.hpp
new file mode 100644
index 0000000..0198cd9
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/enum.hpp
@@ -0,0 +1,66 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_HPP
+# define BOOST_PREPROCESSOR_REPETITION_ENUM_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/debug/error.hpp>
+# include <boost/preprocessor/detail/auto_rec.hpp>
+# include <boost/preprocessor/punctuation/comma_if.hpp>
+# include <boost/preprocessor/repetition/repeat.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+# include <boost/preprocessor/tuple/rem.hpp>
+#
+# /* BOOST_PP_ENUM */
+#
+# if 0
+#    define BOOST_PP_ENUM(count, macro, data)
+# endif
+#
+# define BOOST_PP_ENUM BOOST_PP_CAT(BOOST_PP_ENUM_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4))
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ENUM_1(c, m, d) BOOST_PP_REPEAT_1(c, BOOST_PP_ENUM_M_1, (m, d))
+#    define BOOST_PP_ENUM_2(c, m, d) BOOST_PP_REPEAT_2(c, BOOST_PP_ENUM_M_2, (m, d))
+#    define BOOST_PP_ENUM_3(c, m, d) BOOST_PP_REPEAT_3(c, BOOST_PP_ENUM_M_3, (m, d))
+# else
+#    define BOOST_PP_ENUM_1(c, m, d) BOOST_PP_ENUM_1_I(c, m, d)
+#    define BOOST_PP_ENUM_2(c, m, d) BOOST_PP_ENUM_2_I(c, m, d)
+#    define BOOST_PP_ENUM_3(c, m, d) BOOST_PP_ENUM_3_I(c, m, d)
+#    define BOOST_PP_ENUM_1_I(c, m, d) BOOST_PP_REPEAT_1(c, BOOST_PP_ENUM_M_1, (m, d))
+#    define BOOST_PP_ENUM_2_I(c, m, d) BOOST_PP_REPEAT_2(c, BOOST_PP_ENUM_M_2, (m, d))
+#    define BOOST_PP_ENUM_3_I(c, m, d) BOOST_PP_REPEAT_3(c, BOOST_PP_ENUM_M_3, (m, d))
+# endif
+#
+# define BOOST_PP_ENUM_4(c, m, d) BOOST_PP_ERROR(0x0003)
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
+#    define BOOST_PP_ENUM_M_1(z, n, md) BOOST_PP_ENUM_M_1_IM(z, n, BOOST_PP_TUPLE_REM_2 md)
+#    define BOOST_PP_ENUM_M_2(z, n, md) BOOST_PP_ENUM_M_2_IM(z, n, BOOST_PP_TUPLE_REM_2 md)
+#    define BOOST_PP_ENUM_M_3(z, n, md) BOOST_PP_ENUM_M_3_IM(z, n, BOOST_PP_TUPLE_REM_2 md)
+#    define BOOST_PP_ENUM_M_1_IM(z, n, im) BOOST_PP_ENUM_M_1_I(z, n, im)
+#    define BOOST_PP_ENUM_M_2_IM(z, n, im) BOOST_PP_ENUM_M_2_I(z, n, im)
+#    define BOOST_PP_ENUM_M_3_IM(z, n, im) BOOST_PP_ENUM_M_3_I(z, n, im)
+# else
+#    define BOOST_PP_ENUM_M_1(z, n, md) BOOST_PP_ENUM_M_1_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md))
+#    define BOOST_PP_ENUM_M_2(z, n, md) BOOST_PP_ENUM_M_2_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md))
+#    define BOOST_PP_ENUM_M_3(z, n, md) BOOST_PP_ENUM_M_3_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md))
+# endif
+#
+# define BOOST_PP_ENUM_M_1_I(z, n, m, d) BOOST_PP_COMMA_IF(n) m(z, n, d)
+# define BOOST_PP_ENUM_M_2_I(z, n, m, d) BOOST_PP_COMMA_IF(n) m(z, n, d)
+# define BOOST_PP_ENUM_M_3_I(z, n, m, d) BOOST_PP_COMMA_IF(n) m(z, n, d)
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/enum_binary_params.hpp b/third_party/boost/boost/preprocessor/repetition/enum_binary_params.hpp
new file mode 100644
index 0000000..a2c1048
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/enum_binary_params.hpp
@@ -0,0 +1,54 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_BINARY_PARAMS_HPP
+# define BOOST_PREPROCESSOR_REPETITION_ENUM_BINARY_PARAMS_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/punctuation/comma_if.hpp>
+# include <boost/preprocessor/repetition/repeat.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+# include <boost/preprocessor/tuple/rem.hpp>
+#
+# /* BOOST_PP_ENUM_BINARY_PARAMS */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ENUM_BINARY_PARAMS(count, p1, p2) BOOST_PP_REPEAT(count, BOOST_PP_ENUM_BINARY_PARAMS_M, (p1, p2))
+# else
+#    define BOOST_PP_ENUM_BINARY_PARAMS(count, p1, p2) BOOST_PP_ENUM_BINARY_PARAMS_I(count, p1, p2)
+#    define BOOST_PP_ENUM_BINARY_PARAMS_I(count, p1, p2) BOOST_PP_REPEAT(count, BOOST_PP_ENUM_BINARY_PARAMS_M, (p1, p2))
+# endif
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
+#    define BOOST_PP_ENUM_BINARY_PARAMS_M(z, n, pp) BOOST_PP_ENUM_BINARY_PARAMS_M_IM(z, n, BOOST_PP_TUPLE_REM_2 pp)
+#    define BOOST_PP_ENUM_BINARY_PARAMS_M_IM(z, n, im) BOOST_PP_ENUM_BINARY_PARAMS_M_I(z, n, im)
+# else
+#    define BOOST_PP_ENUM_BINARY_PARAMS_M(z, n, pp) BOOST_PP_ENUM_BINARY_PARAMS_M_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, pp), BOOST_PP_TUPLE_ELEM(2, 1, pp))
+# endif
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC()
+#    define BOOST_PP_ENUM_BINARY_PARAMS_M_I(z, n, p1, p2) BOOST_PP_ENUM_BINARY_PARAMS_M_II(z, n, p1, p2)
+#    define BOOST_PP_ENUM_BINARY_PARAMS_M_II(z, n, p1, p2) BOOST_PP_COMMA_IF(n) p1 ## n p2 ## n
+# else
+#    define BOOST_PP_ENUM_BINARY_PARAMS_M_I(z, n, p1, p2) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(p1, n) BOOST_PP_CAT(p2, n)
+# endif
+#
+# /* BOOST_PP_ENUM_BINARY_PARAMS_Z */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ENUM_BINARY_PARAMS_Z(z, count, p1, p2) BOOST_PP_REPEAT_ ## z(count, BOOST_PP_ENUM_BINARY_PARAMS_M, (p1, p2))
+# else
+#    define BOOST_PP_ENUM_BINARY_PARAMS_Z(z, count, p1, p2) BOOST_PP_ENUM_BINARY_PARAMS_Z_I(z, count, p1, p2)
+#    define BOOST_PP_ENUM_BINARY_PARAMS_Z_I(z, count, p1, p2) BOOST_PP_REPEAT_ ## z(count, BOOST_PP_ENUM_BINARY_PARAMS_M, (p1, p2))
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/enum_params.hpp b/third_party/boost/boost/preprocessor/repetition/enum_params.hpp
new file mode 100644
index 0000000..65a2369
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/enum_params.hpp
@@ -0,0 +1,41 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_PARAMS_HPP
+# define BOOST_PREPROCESSOR_REPETITION_ENUM_PARAMS_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/punctuation/comma_if.hpp>
+# include <boost/preprocessor/repetition/repeat.hpp>
+#
+# /* BOOST_PP_ENUM_PARAMS */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ENUM_PARAMS(count, param) BOOST_PP_REPEAT(count, BOOST_PP_ENUM_PARAMS_M, param)
+# else
+#    define BOOST_PP_ENUM_PARAMS(count, param) BOOST_PP_ENUM_PARAMS_I(count, param)
+#    define BOOST_PP_ENUM_PARAMS_I(count, param) BOOST_PP_REPEAT(count, BOOST_PP_ENUM_PARAMS_M, param)
+# endif
+#
+# define BOOST_PP_ENUM_PARAMS_M(z, n, param) BOOST_PP_COMMA_IF(n) param ## n
+#
+# /* BOOST_PP_ENUM_PARAMS_Z */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ENUM_PARAMS_Z(z, count, param) BOOST_PP_REPEAT_ ## z(count, BOOST_PP_ENUM_PARAMS_M, param)
+# else
+#    define BOOST_PP_ENUM_PARAMS_Z(z, count, param) BOOST_PP_ENUM_PARAMS_Z_I(z, count, param)
+#    define BOOST_PP_ENUM_PARAMS_Z_I(z, count, param) BOOST_PP_REPEAT_ ## z(count, BOOST_PP_ENUM_PARAMS_M, param)
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/enum_params_with_a_default.hpp b/third_party/boost/boost/preprocessor/repetition/enum_params_with_a_default.hpp
new file mode 100644
index 0000000..7496df6
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/enum_params_with_a_default.hpp
@@ -0,0 +1,25 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_PARAMS_WITH_A_DEFAULT_HPP
+# define BOOST_PREPROCESSOR_REPETITION_ENUM_PARAMS_WITH_A_DEFAULT_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/facilities/intercept.hpp>
+# include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#
+# /* BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT */
+#
+# define BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(count, param, def) BOOST_PP_ENUM_BINARY_PARAMS(count, param, = def BOOST_PP_INTERCEPT)
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/enum_params_with_defaults.hpp b/third_party/boost/boost/preprocessor/repetition/enum_params_with_defaults.hpp
new file mode 100644
index 0000000..fa0106f
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/enum_params_with_defaults.hpp
@@ -0,0 +1,24 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_PARAMS_WITH_DEFAULTS_HPP
+# define BOOST_PREPROCESSOR_REPETITION_ENUM_PARAMS_WITH_DEFAULTS_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#
+# /* BOOST_PP_ENUM_PARAMS_WITH_DEFAULTS */
+#
+# define BOOST_PP_ENUM_PARAMS_WITH_DEFAULTS(count, param, def) BOOST_PP_ENUM_BINARY_PARAMS(count, param, = def)
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/enum_shifted.hpp b/third_party/boost/boost/preprocessor/repetition/enum_shifted.hpp
new file mode 100644
index 0000000..d5b006f
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/enum_shifted.hpp
@@ -0,0 +1,68 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_SHIFTED_HPP
+# define BOOST_PREPROCESSOR_REPETITION_ENUM_SHIFTED_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/arithmetic/dec.hpp>
+# include <boost/preprocessor/arithmetic/inc.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/debug/error.hpp>
+# include <boost/preprocessor/detail/auto_rec.hpp>
+# include <boost/preprocessor/punctuation/comma_if.hpp>
+# include <boost/preprocessor/repetition/repeat.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+# include <boost/preprocessor/tuple/rem.hpp>
+#
+# /* BOOST_PP_ENUM_SHIFTED */
+#
+# if 0
+#    define BOOST_PP_ENUM_SHIFTED(count, macro, data)
+# endif
+#
+# define BOOST_PP_ENUM_SHIFTED BOOST_PP_CAT(BOOST_PP_ENUM_SHIFTED_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4))
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ENUM_SHIFTED_1(c, m, d) BOOST_PP_REPEAT_1(BOOST_PP_DEC(c), BOOST_PP_ENUM_SHIFTED_M_1, (m, d))
+#    define BOOST_PP_ENUM_SHIFTED_2(c, m, d) BOOST_PP_REPEAT_2(BOOST_PP_DEC(c), BOOST_PP_ENUM_SHIFTED_M_2, (m, d))
+#    define BOOST_PP_ENUM_SHIFTED_3(c, m, d) BOOST_PP_REPEAT_3(BOOST_PP_DEC(c), BOOST_PP_ENUM_SHIFTED_M_3, (m, d))
+# else
+#    define BOOST_PP_ENUM_SHIFTED_1(c, m, d) BOOST_PP_ENUM_SHIFTED_1_I(c, m, d)
+#    define BOOST_PP_ENUM_SHIFTED_2(c, m, d) BOOST_PP_ENUM_SHIFTED_1_2(c, m, d)
+#    define BOOST_PP_ENUM_SHIFTED_3(c, m, d) BOOST_PP_ENUM_SHIFTED_1_3(c, m, d)
+#    define BOOST_PP_ENUM_SHIFTED_1_I(c, m, d) BOOST_PP_REPEAT_1(BOOST_PP_DEC(c), BOOST_PP_ENUM_SHIFTED_M_1, (m, d))
+#    define BOOST_PP_ENUM_SHIFTED_2_I(c, m, d) BOOST_PP_REPEAT_2(BOOST_PP_DEC(c), BOOST_PP_ENUM_SHIFTED_M_2, (m, d))
+#    define BOOST_PP_ENUM_SHIFTED_3_I(c, m, d) BOOST_PP_REPEAT_3(BOOST_PP_DEC(c), BOOST_PP_ENUM_SHIFTED_M_3, (m, d))
+# endif
+#
+# define BOOST_PP_ENUM_SHIFTED_4(c, m, d) BOOST_PP_ERROR(0x0003)
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
+#    define BOOST_PP_ENUM_SHIFTED_M_1(z, n, md) BOOST_PP_ENUM_SHIFTED_M_1_IM(z, n, BOOST_PP_TUPLE_REM_2 md)
+#    define BOOST_PP_ENUM_SHIFTED_M_2(z, n, md) BOOST_PP_ENUM_SHIFTED_M_2_IM(z, n, BOOST_PP_TUPLE_REM_2 md)
+#    define BOOST_PP_ENUM_SHIFTED_M_3(z, n, md) BOOST_PP_ENUM_SHIFTED_M_3_IM(z, n, BOOST_PP_TUPLE_REM_2 md)
+#    define BOOST_PP_ENUM_SHIFTED_M_1_IM(z, n, im) BOOST_PP_ENUM_SHIFTED_M_1_I(z, n, im)
+#    define BOOST_PP_ENUM_SHIFTED_M_2_IM(z, n, im) BOOST_PP_ENUM_SHIFTED_M_2_I(z, n, im)
+#    define BOOST_PP_ENUM_SHIFTED_M_3_IM(z, n, im) BOOST_PP_ENUM_SHIFTED_M_3_I(z, n, im)
+# else
+#    define BOOST_PP_ENUM_SHIFTED_M_1(z, n, md) BOOST_PP_ENUM_SHIFTED_M_1_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md))
+#    define BOOST_PP_ENUM_SHIFTED_M_2(z, n, md) BOOST_PP_ENUM_SHIFTED_M_2_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md))
+#    define BOOST_PP_ENUM_SHIFTED_M_3(z, n, md) BOOST_PP_ENUM_SHIFTED_M_3_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md))
+# endif
+#
+# define BOOST_PP_ENUM_SHIFTED_M_1_I(z, n, m, d) BOOST_PP_COMMA_IF(n) m(z, BOOST_PP_INC(n), d)
+# define BOOST_PP_ENUM_SHIFTED_M_2_I(z, n, m, d) BOOST_PP_COMMA_IF(n) m(z, BOOST_PP_INC(n), d)
+# define BOOST_PP_ENUM_SHIFTED_M_3_I(z, n, m, d) BOOST_PP_COMMA_IF(n) m(z, BOOST_PP_INC(n), d)
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/enum_shifted_binary_params.hpp b/third_party/boost/boost/preprocessor/repetition/enum_shifted_binary_params.hpp
new file mode 100644
index 0000000..f3d20fc
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/enum_shifted_binary_params.hpp
@@ -0,0 +1,51 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2005.                                  *
+#  *     Distributed under the Boost Software License, Version 1.0. (See      *
+#  *     accompanying file LICENSE_1_0.txt or copy at                         *
+#  *     http://www.boost.org/LICENSE_1_0.txt)                                *
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_SHIFTED_BINARY_PARAMS_HPP
+# define BOOST_PREPROCESSOR_REPETITION_ENUM_SHIFTED_BINARY_PARAMS_HPP
+#
+# include <boost/preprocessor/arithmetic/dec.hpp>
+# include <boost/preprocessor/arithmetic/inc.hpp>
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/punctuation/comma_if.hpp>
+# include <boost/preprocessor/repetition/repeat.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+# include <boost/preprocessor/tuple/rem.hpp>
+#
+# /* BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS(count, p1, p2) BOOST_PP_REPEAT(BOOST_PP_DEC(count), BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_M, (p1, p2))
+# else
+#    define BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS(count, p1, p2) BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_I(count, p1, p2)
+#    define BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_I(count, p1, p2) BOOST_PP_REPEAT(BOOST_PP_DEC(count), BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_M, (p1, p2))
+# endif
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
+#    define BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_M(z, n, pp) BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_M_IM(z, n, BOOST_PP_TUPLE_REM_2 pp)
+#    define BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_M_IM(z, n, im) BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_M_I(z, n, im)
+# else
+#    define BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_M(z, n, pp) BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_M_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, pp), BOOST_PP_TUPLE_ELEM(2, 1, pp))
+# endif
+#
+# define BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_M_I(z, n, p1, p2) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(p1, BOOST_PP_INC(n)) BOOST_PP_CAT(p2, BOOST_PP_INC(n))
+#
+# /* BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_Z */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_Z(z, count, p1, p2) BOOST_PP_REPEAT_ ## z(BOOST_PP_DEC(count), BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_M, (p1, p2))
+# else
+#    define BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_Z(z, count, p1, p2) BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_Z_I(z, count, p1, p2)
+#    define BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_Z_I(z, count, p1, p2) BOOST_PP_REPEAT_ ## z(BOOST_PP_DEC(count), BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS_M, (p1, p2))
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/enum_shifted_params.hpp b/third_party/boost/boost/preprocessor/repetition/enum_shifted_params.hpp
new file mode 100644
index 0000000..88b2bf4
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/enum_shifted_params.hpp
@@ -0,0 +1,44 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_SHIFTED_PARAMS_HPP
+# define BOOST_PREPROCESSOR_REPETITION_ENUM_SHIFTED_PARAMS_HPP
+#
+# include <boost/preprocessor/arithmetic/dec.hpp>
+# include <boost/preprocessor/arithmetic/inc.hpp>
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/punctuation/comma_if.hpp>
+# include <boost/preprocessor/repetition/repeat.hpp>
+#
+# /* BOOST_PP_ENUM_SHIFTED_PARAMS */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ENUM_SHIFTED_PARAMS(count, param) BOOST_PP_REPEAT(BOOST_PP_DEC(count), BOOST_PP_ENUM_SHIFTED_PARAMS_M, param)
+# else
+#    define BOOST_PP_ENUM_SHIFTED_PARAMS(count, param) BOOST_PP_ENUM_SHIFTED_PARAMS_I(count, param)
+#    define BOOST_PP_ENUM_SHIFTED_PARAMS_I(count, param) BOOST_PP_REPEAT(BOOST_PP_DEC(count), BOOST_PP_ENUM_SHIFTED_PARAMS_M, param)
+# endif
+#
+# define BOOST_PP_ENUM_SHIFTED_PARAMS_M(z, n, param) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(param, BOOST_PP_INC(n))
+#
+# /* BOOST_PP_ENUM_SHIFTED_PARAMS_Z */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ENUM_SHIFTED_PARAMS_Z(z, count, param) BOOST_PP_REPEAT_ ## z(BOOST_PP_DEC(count), BOOST_PP_ENUM_SHIFTED_PARAMS_M, param)
+# else
+#    define BOOST_PP_ENUM_SHIFTED_PARAMS_Z(z, count, param) BOOST_PP_ENUM_SHIFTED_PARAMS_Z_I(z, count, param)
+#    define BOOST_PP_ENUM_SHIFTED_PARAMS_Z_I(z, count, param) BOOST_PP_REPEAT_ ## z(BOOST_PP_DEC(count), BOOST_PP_ENUM_SHIFTED_PARAMS_M, param)
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/enum_trailing.hpp b/third_party/boost/boost/preprocessor/repetition/enum_trailing.hpp
new file mode 100644
index 0000000..20af2d5
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/enum_trailing.hpp
@@ -0,0 +1,63 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_TRAILING_HPP
+# define BOOST_PREPROCESSOR_REPETITION_ENUM_TRAILING_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/debug/error.hpp>
+# include <boost/preprocessor/detail/auto_rec.hpp>
+# include <boost/preprocessor/repetition/repeat.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+# include <boost/preprocessor/tuple/rem.hpp>
+#
+# /* BOOST_PP_ENUM_TRAILING */
+#
+# if 0
+#    define BOOST_PP_ENUM_TRAILING(count, macro, data)
+# endif
+#
+# define BOOST_PP_ENUM_TRAILING BOOST_PP_CAT(BOOST_PP_ENUM_TRAILING_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4))
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ENUM_TRAILING_1(c, m, d) BOOST_PP_REPEAT_1(c, BOOST_PP_ENUM_TRAILING_M_1, (m, d))
+#    define BOOST_PP_ENUM_TRAILING_2(c, m, d) BOOST_PP_REPEAT_2(c, BOOST_PP_ENUM_TRAILING_M_2, (m, d))
+#    define BOOST_PP_ENUM_TRAILING_3(c, m, d) BOOST_PP_REPEAT_3(c, BOOST_PP_ENUM_TRAILING_M_3, (m, d))
+# else
+#    define BOOST_PP_ENUM_TRAILING_1(c, m, d) BOOST_PP_ENUM_TRAILING_1_I(c, m, d)
+#    define BOOST_PP_ENUM_TRAILING_2(c, m, d) BOOST_PP_ENUM_TRAILING_2_I(c, m, d)
+#    define BOOST_PP_ENUM_TRAILING_3(c, m, d) BOOST_PP_ENUM_TRAILING_3_I(c, m, d)
+#    define BOOST_PP_ENUM_TRAILING_1_I(c, m, d) BOOST_PP_REPEAT_1(c, BOOST_PP_ENUM_TRAILING_M_1, (m, d))
+#    define BOOST_PP_ENUM_TRAILING_2_I(c, m, d) BOOST_PP_REPEAT_2(c, BOOST_PP_ENUM_TRAILING_M_2, (m, d))
+#    define BOOST_PP_ENUM_TRAILING_3_I(c, m, d) BOOST_PP_REPEAT_3(c, BOOST_PP_ENUM_TRAILING_M_3, (m, d))
+# endif
+#
+# define BOOST_PP_ENUM_TRAILING_4(c, m, d) BOOST_PP_ERROR(0x0003)
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
+#    define BOOST_PP_ENUM_TRAILING_M_1(z, n, md) BOOST_PP_ENUM_TRAILING_M_1_IM(z, n, BOOST_PP_TUPLE_REM_2 md)
+#    define BOOST_PP_ENUM_TRAILING_M_2(z, n, md) BOOST_PP_ENUM_TRAILING_M_2_IM(z, n, BOOST_PP_TUPLE_REM_2 md)
+#    define BOOST_PP_ENUM_TRAILING_M_3(z, n, md) BOOST_PP_ENUM_TRAILING_M_3_IM(z, n, BOOST_PP_TUPLE_REM_2 md)
+#    define BOOST_PP_ENUM_TRAILING_M_1_IM(z, n, im) BOOST_PP_ENUM_TRAILING_M_1_I(z, n, im)
+#    define BOOST_PP_ENUM_TRAILING_M_2_IM(z, n, im) BOOST_PP_ENUM_TRAILING_M_2_I(z, n, im)
+#    define BOOST_PP_ENUM_TRAILING_M_3_IM(z, n, im) BOOST_PP_ENUM_TRAILING_M_3_I(z, n, im)
+# else
+#    define BOOST_PP_ENUM_TRAILING_M_1(z, n, md) BOOST_PP_ENUM_TRAILING_M_1_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md))
+#    define BOOST_PP_ENUM_TRAILING_M_2(z, n, md) BOOST_PP_ENUM_TRAILING_M_2_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md))
+#    define BOOST_PP_ENUM_TRAILING_M_3(z, n, md) BOOST_PP_ENUM_TRAILING_M_3_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, md), BOOST_PP_TUPLE_ELEM(2, 1, md))
+# endif
+#
+# define BOOST_PP_ENUM_TRAILING_M_1_I(z, n, m, d) , m(z, n, d)
+# define BOOST_PP_ENUM_TRAILING_M_2_I(z, n, m, d) , m(z, n, d)
+# define BOOST_PP_ENUM_TRAILING_M_3_I(z, n, m, d) , m(z, n, d)
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/enum_trailing_binary_params.hpp b/third_party/boost/boost/preprocessor/repetition/enum_trailing_binary_params.hpp
new file mode 100644
index 0000000..e201b69
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/enum_trailing_binary_params.hpp
@@ -0,0 +1,53 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_TRAILING_BINARY_PARAMS_HPP
+# define BOOST_PREPROCESSOR_REPETITION_ENUM_TRAILING_BINARY_PARAMS_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/repetition/repeat.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+# include <boost/preprocessor/tuple/rem.hpp>
+#
+# /* BOOST_PP_ENUM_TRAILING_BINARY_PARAMS */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(count, p1, p2) BOOST_PP_REPEAT(count, BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_M, (p1, p2))
+# else
+#    define BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(count, p1, p2) BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_I(count, p1, p2)
+#    define BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_I(count, p1, p2) BOOST_PP_REPEAT(count, BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_M, (p1, p2))
+# endif
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
+#    define BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_M(z, n, pp) BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_M_IM(z, n, BOOST_PP_TUPLE_REM_2 pp)
+#    define BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_M_IM(z, n, im) BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_M_I(z, n, im)
+# else
+#    define BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_M(z, n, pp) BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_M_I(z, n, BOOST_PP_TUPLE_ELEM(2, 0, pp), BOOST_PP_TUPLE_ELEM(2, 1, pp))
+# endif
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC()
+#    define BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_M_I(z, n, p1, p2) BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_M_II(z, n, p1, p2)
+#    define BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_M_II(z, n, p1, p2) , p1 ## n p2 ## n
+# else
+#    define BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_M_I(z, n, p1, p2) , BOOST_PP_CAT(p1, n) BOOST_PP_CAT(p2, n)
+# endif
+#
+# /* BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(z, count, p1, p2) BOOST_PP_REPEAT_ ## z(count, BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_M, (p1, p2))
+# else
+#    define BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z(z, count, p1, p2) BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z_I(z, count, p1, p2)
+#    define BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_Z_I(z, count, p1, p2) BOOST_PP_REPEAT_ ## z(count, BOOST_PP_ENUM_TRAILING_BINARY_PARAMS_M, (p1, p2))
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/enum_trailing_params.hpp b/third_party/boost/boost/preprocessor/repetition/enum_trailing_params.hpp
new file mode 100644
index 0000000..f7520db
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/enum_trailing_params.hpp
@@ -0,0 +1,38 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_ENUM_TRAILING_PARAMS_HPP
+# define BOOST_PREPROCESSOR_REPETITION_ENUM_TRAILING_PARAMS_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/repetition/repeat.hpp>
+#
+# /* BOOST_PP_ENUM_TRAILING_PARAMS */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ENUM_TRAILING_PARAMS(count, param) BOOST_PP_REPEAT(count, BOOST_PP_ENUM_TRAILING_PARAMS_M, param)
+# else
+#    define BOOST_PP_ENUM_TRAILING_PARAMS(count, param) BOOST_PP_ENUM_TRAILING_PARAMS_I(count, param)
+#    define BOOST_PP_ENUM_TRAILING_PARAMS_I(count, param) BOOST_PP_REPEAT(count, BOOST_PP_ENUM_TRAILING_PARAMS_M, param)
+# endif
+#
+# define BOOST_PP_ENUM_TRAILING_PARAMS_M(z, n, param) , param ## n
+#
+# /* BOOST_PP_ENUM_TRAILING_PARAMS_Z */
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, count, param) BOOST_PP_REPEAT_ ## z(count, BOOST_PP_ENUM_TRAILING_PARAMS_M, param)
+# else
+#    define BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, count, param) BOOST_PP_ENUM_TRAILING_PARAMS_Z_I(z, count, param)
+#    define BOOST_PP_ENUM_TRAILING_PARAMS_Z_I(z, count, param) BOOST_PP_REPEAT_ ## z(count, BOOST_PP_ENUM_TRAILING_PARAMS_M, param)
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/for.hpp b/third_party/boost/boost/preprocessor/repetition/for.hpp
new file mode 100644
index 0000000..c38946b
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/for.hpp
@@ -0,0 +1,324 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_FOR_HPP
+# define BOOST_PREPROCESSOR_REPETITION_FOR_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/debug/error.hpp>
+# include <boost/preprocessor/facilities/empty.hpp>
+# include <boost/preprocessor/logical/bool.hpp>
+# include <boost/preprocessor/detail/auto_rec.hpp>
+#
+# /* BOOST_PP_FOR */
+#
+# if 0
+#    define BOOST_PP_FOR(state, pred, op, macro)
+# endif
+#
+# define BOOST_PP_FOR BOOST_PP_CAT(BOOST_PP_FOR_, BOOST_PP_AUTO_REC(BOOST_PP_FOR_P, 256))
+#
+# define BOOST_PP_FOR_P(n) BOOST_PP_CAT(BOOST_PP_FOR_CHECK_, BOOST_PP_FOR_ ## n(1, BOOST_PP_FOR_SR_P, BOOST_PP_FOR_SR_O, BOOST_PP_FOR_SR_M))
+#
+# define BOOST_PP_FOR_SR_P(r, s) s
+# define BOOST_PP_FOR_SR_O(r, s) 0
+# define BOOST_PP_FOR_SR_M(r, s) BOOST_PP_NIL
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    include <boost/preprocessor/repetition/detail/edg/for.hpp>
+# elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC()
+#    include <boost/preprocessor/repetition/detail/msvc/for.hpp>
+# elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC()
+#    include <boost/preprocessor/repetition/detail/dmc/for.hpp>
+# else
+#    include <boost/preprocessor/repetition/detail/for.hpp>
+# endif
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_DMC()
+# define BOOST_PP_FOR_257_PR(s, p) BOOST_PP_BOOL(p##(257, s))
+# else
+# define BOOST_PP_FOR_257_PR(s, p) BOOST_PP_BOOL(p(257, s))
+# endif
+
+# define BOOST_PP_FOR_257_ERROR() BOOST_PP_ERROR(0x0002)
+# define BOOST_PP_FOR_257(s, p, o, m) \
+	BOOST_PP_IIF \
+		( \
+		BOOST_PP_FOR_257_PR(s,p), \
+		BOOST_PP_FOR_257_ERROR, \
+		BOOST_PP_EMPTY \
+		) \
+	() \
+/**/
+// # define BOOST_PP_FOR_257(s, p, o, m) BOOST_PP_ERROR(0x0002)
+#
+# define BOOST_PP_FOR_CHECK_BOOST_PP_NIL 1
+#
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_1(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_2(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_3(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_4(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_5(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_6(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_7(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_8(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_9(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_10(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_11(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_12(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_13(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_14(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_15(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_16(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_17(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_18(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_19(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_20(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_21(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_22(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_23(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_24(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_25(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_26(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_27(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_28(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_29(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_30(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_31(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_32(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_33(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_34(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_35(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_36(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_37(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_38(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_39(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_40(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_41(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_42(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_43(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_44(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_45(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_46(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_47(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_48(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_49(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_50(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_51(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_52(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_53(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_54(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_55(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_56(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_57(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_58(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_59(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_60(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_61(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_62(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_63(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_64(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_65(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_66(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_67(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_68(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_69(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_70(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_71(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_72(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_73(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_74(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_75(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_76(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_77(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_78(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_79(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_80(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_81(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_82(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_83(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_84(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_85(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_86(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_87(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_88(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_89(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_90(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_91(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_92(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_93(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_94(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_95(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_96(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_97(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_98(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_99(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_100(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_101(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_102(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_103(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_104(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_105(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_106(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_107(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_108(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_109(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_110(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_111(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_112(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_113(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_114(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_115(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_116(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_117(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_118(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_119(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_120(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_121(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_122(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_123(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_124(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_125(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_126(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_127(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_128(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_129(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_130(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_131(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_132(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_133(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_134(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_135(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_136(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_137(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_138(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_139(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_140(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_141(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_142(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_143(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_144(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_145(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_146(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_147(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_148(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_149(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_150(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_151(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_152(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_153(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_154(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_155(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_156(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_157(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_158(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_159(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_160(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_161(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_162(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_163(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_164(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_165(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_166(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_167(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_168(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_169(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_170(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_171(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_172(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_173(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_174(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_175(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_176(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_177(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_178(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_179(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_180(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_181(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_182(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_183(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_184(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_185(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_186(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_187(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_188(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_189(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_190(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_191(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_192(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_193(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_194(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_195(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_196(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_197(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_198(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_199(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_200(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_201(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_202(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_203(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_204(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_205(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_206(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_207(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_208(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_209(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_210(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_211(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_212(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_213(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_214(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_215(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_216(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_217(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_218(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_219(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_220(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_221(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_222(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_223(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_224(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_225(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_226(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_227(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_228(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_229(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_230(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_231(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_232(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_233(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_234(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_235(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_236(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_237(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_238(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_239(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_240(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_241(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_242(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_243(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_244(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_245(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_246(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_247(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_248(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_249(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_250(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_251(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_252(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_253(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_254(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_255(s, p, o, m) 0
+# define BOOST_PP_FOR_CHECK_BOOST_PP_FOR_256(s, p, o, m) 0
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/repeat.hpp b/third_party/boost/boost/preprocessor/repetition/repeat.hpp
new file mode 100644
index 0000000..0172738
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/repeat.hpp
@@ -0,0 +1,825 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_REPEAT_HPP
+# define BOOST_PREPROCESSOR_REPETITION_REPEAT_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/debug/error.hpp>
+# include <boost/preprocessor/detail/auto_rec.hpp>
+# include <boost/preprocessor/tuple/eat.hpp>
+#
+# /* BOOST_PP_REPEAT */
+#
+# if 0
+#    define BOOST_PP_REPEAT(count, macro, data)
+# endif
+#
+# define BOOST_PP_REPEAT BOOST_PP_CAT(BOOST_PP_REPEAT_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4))
+#
+# define BOOST_PP_REPEAT_P(n) BOOST_PP_CAT(BOOST_PP_REPEAT_CHECK_, BOOST_PP_REPEAT_ ## n(1, BOOST_PP_NIL BOOST_PP_TUPLE_EAT_3, BOOST_PP_NIL))
+#
+# define BOOST_PP_REPEAT_CHECK_BOOST_PP_NIL 1
+# define BOOST_PP_REPEAT_CHECK_BOOST_PP_REPEAT_1(c, m, d) 0
+# define BOOST_PP_REPEAT_CHECK_BOOST_PP_REPEAT_2(c, m, d) 0
+# define BOOST_PP_REPEAT_CHECK_BOOST_PP_REPEAT_3(c, m, d) 0
+#
+# define BOOST_PP_REPEAT_1(c, m, d) BOOST_PP_REPEAT_1_I(c, m, d)
+# define BOOST_PP_REPEAT_2(c, m, d) BOOST_PP_REPEAT_2_I(c, m, d)
+# define BOOST_PP_REPEAT_3(c, m, d) BOOST_PP_REPEAT_3_I(c, m, d)
+# define BOOST_PP_REPEAT_4(c, m, d) BOOST_PP_ERROR(0x0003)
+#
+# define BOOST_PP_REPEAT_1_I(c, m, d) BOOST_PP_REPEAT_1_ ## c(m, d)
+# define BOOST_PP_REPEAT_2_I(c, m, d) BOOST_PP_REPEAT_2_ ## c(m, d)
+# define BOOST_PP_REPEAT_3_I(c, m, d) BOOST_PP_REPEAT_3_ ## c(m, d)
+#
+# define BOOST_PP_REPEAT_1ST BOOST_PP_REPEAT_1
+# define BOOST_PP_REPEAT_2ND BOOST_PP_REPEAT_2
+# define BOOST_PP_REPEAT_3RD BOOST_PP_REPEAT_3
+#
+# define BOOST_PP_REPEAT_1_0(m, d)
+# define BOOST_PP_REPEAT_1_1(m, d) m(2, 0, d)
+# define BOOST_PP_REPEAT_1_2(m, d) BOOST_PP_REPEAT_1_1(m, d) m(2, 1, d)
+# define BOOST_PP_REPEAT_1_3(m, d) BOOST_PP_REPEAT_1_2(m, d) m(2, 2, d)
+# define BOOST_PP_REPEAT_1_4(m, d) BOOST_PP_REPEAT_1_3(m, d) m(2, 3, d)
+# define BOOST_PP_REPEAT_1_5(m, d) BOOST_PP_REPEAT_1_4(m, d) m(2, 4, d)
+# define BOOST_PP_REPEAT_1_6(m, d) BOOST_PP_REPEAT_1_5(m, d) m(2, 5, d)
+# define BOOST_PP_REPEAT_1_7(m, d) BOOST_PP_REPEAT_1_6(m, d) m(2, 6, d)
+# define BOOST_PP_REPEAT_1_8(m, d) BOOST_PP_REPEAT_1_7(m, d) m(2, 7, d)
+# define BOOST_PP_REPEAT_1_9(m, d) BOOST_PP_REPEAT_1_8(m, d) m(2, 8, d)
+# define BOOST_PP_REPEAT_1_10(m, d) BOOST_PP_REPEAT_1_9(m, d) m(2, 9, d)
+# define BOOST_PP_REPEAT_1_11(m, d) BOOST_PP_REPEAT_1_10(m, d) m(2, 10, d)
+# define BOOST_PP_REPEAT_1_12(m, d) BOOST_PP_REPEAT_1_11(m, d) m(2, 11, d)
+# define BOOST_PP_REPEAT_1_13(m, d) BOOST_PP_REPEAT_1_12(m, d) m(2, 12, d)
+# define BOOST_PP_REPEAT_1_14(m, d) BOOST_PP_REPEAT_1_13(m, d) m(2, 13, d)
+# define BOOST_PP_REPEAT_1_15(m, d) BOOST_PP_REPEAT_1_14(m, d) m(2, 14, d)
+# define BOOST_PP_REPEAT_1_16(m, d) BOOST_PP_REPEAT_1_15(m, d) m(2, 15, d)
+# define BOOST_PP_REPEAT_1_17(m, d) BOOST_PP_REPEAT_1_16(m, d) m(2, 16, d)
+# define BOOST_PP_REPEAT_1_18(m, d) BOOST_PP_REPEAT_1_17(m, d) m(2, 17, d)
+# define BOOST_PP_REPEAT_1_19(m, d) BOOST_PP_REPEAT_1_18(m, d) m(2, 18, d)
+# define BOOST_PP_REPEAT_1_20(m, d) BOOST_PP_REPEAT_1_19(m, d) m(2, 19, d)
+# define BOOST_PP_REPEAT_1_21(m, d) BOOST_PP_REPEAT_1_20(m, d) m(2, 20, d)
+# define BOOST_PP_REPEAT_1_22(m, d) BOOST_PP_REPEAT_1_21(m, d) m(2, 21, d)
+# define BOOST_PP_REPEAT_1_23(m, d) BOOST_PP_REPEAT_1_22(m, d) m(2, 22, d)
+# define BOOST_PP_REPEAT_1_24(m, d) BOOST_PP_REPEAT_1_23(m, d) m(2, 23, d)
+# define BOOST_PP_REPEAT_1_25(m, d) BOOST_PP_REPEAT_1_24(m, d) m(2, 24, d)
+# define BOOST_PP_REPEAT_1_26(m, d) BOOST_PP_REPEAT_1_25(m, d) m(2, 25, d)
+# define BOOST_PP_REPEAT_1_27(m, d) BOOST_PP_REPEAT_1_26(m, d) m(2, 26, d)
+# define BOOST_PP_REPEAT_1_28(m, d) BOOST_PP_REPEAT_1_27(m, d) m(2, 27, d)
+# define BOOST_PP_REPEAT_1_29(m, d) BOOST_PP_REPEAT_1_28(m, d) m(2, 28, d)
+# define BOOST_PP_REPEAT_1_30(m, d) BOOST_PP_REPEAT_1_29(m, d) m(2, 29, d)
+# define BOOST_PP_REPEAT_1_31(m, d) BOOST_PP_REPEAT_1_30(m, d) m(2, 30, d)
+# define BOOST_PP_REPEAT_1_32(m, d) BOOST_PP_REPEAT_1_31(m, d) m(2, 31, d)
+# define BOOST_PP_REPEAT_1_33(m, d) BOOST_PP_REPEAT_1_32(m, d) m(2, 32, d)
+# define BOOST_PP_REPEAT_1_34(m, d) BOOST_PP_REPEAT_1_33(m, d) m(2, 33, d)
+# define BOOST_PP_REPEAT_1_35(m, d) BOOST_PP_REPEAT_1_34(m, d) m(2, 34, d)
+# define BOOST_PP_REPEAT_1_36(m, d) BOOST_PP_REPEAT_1_35(m, d) m(2, 35, d)
+# define BOOST_PP_REPEAT_1_37(m, d) BOOST_PP_REPEAT_1_36(m, d) m(2, 36, d)
+# define BOOST_PP_REPEAT_1_38(m, d) BOOST_PP_REPEAT_1_37(m, d) m(2, 37, d)
+# define BOOST_PP_REPEAT_1_39(m, d) BOOST_PP_REPEAT_1_38(m, d) m(2, 38, d)
+# define BOOST_PP_REPEAT_1_40(m, d) BOOST_PP_REPEAT_1_39(m, d) m(2, 39, d)
+# define BOOST_PP_REPEAT_1_41(m, d) BOOST_PP_REPEAT_1_40(m, d) m(2, 40, d)
+# define BOOST_PP_REPEAT_1_42(m, d) BOOST_PP_REPEAT_1_41(m, d) m(2, 41, d)
+# define BOOST_PP_REPEAT_1_43(m, d) BOOST_PP_REPEAT_1_42(m, d) m(2, 42, d)
+# define BOOST_PP_REPEAT_1_44(m, d) BOOST_PP_REPEAT_1_43(m, d) m(2, 43, d)
+# define BOOST_PP_REPEAT_1_45(m, d) BOOST_PP_REPEAT_1_44(m, d) m(2, 44, d)
+# define BOOST_PP_REPEAT_1_46(m, d) BOOST_PP_REPEAT_1_45(m, d) m(2, 45, d)
+# define BOOST_PP_REPEAT_1_47(m, d) BOOST_PP_REPEAT_1_46(m, d) m(2, 46, d)
+# define BOOST_PP_REPEAT_1_48(m, d) BOOST_PP_REPEAT_1_47(m, d) m(2, 47, d)
+# define BOOST_PP_REPEAT_1_49(m, d) BOOST_PP_REPEAT_1_48(m, d) m(2, 48, d)
+# define BOOST_PP_REPEAT_1_50(m, d) BOOST_PP_REPEAT_1_49(m, d) m(2, 49, d)
+# define BOOST_PP_REPEAT_1_51(m, d) BOOST_PP_REPEAT_1_50(m, d) m(2, 50, d)
+# define BOOST_PP_REPEAT_1_52(m, d) BOOST_PP_REPEAT_1_51(m, d) m(2, 51, d)
+# define BOOST_PP_REPEAT_1_53(m, d) BOOST_PP_REPEAT_1_52(m, d) m(2, 52, d)
+# define BOOST_PP_REPEAT_1_54(m, d) BOOST_PP_REPEAT_1_53(m, d) m(2, 53, d)
+# define BOOST_PP_REPEAT_1_55(m, d) BOOST_PP_REPEAT_1_54(m, d) m(2, 54, d)
+# define BOOST_PP_REPEAT_1_56(m, d) BOOST_PP_REPEAT_1_55(m, d) m(2, 55, d)
+# define BOOST_PP_REPEAT_1_57(m, d) BOOST_PP_REPEAT_1_56(m, d) m(2, 56, d)
+# define BOOST_PP_REPEAT_1_58(m, d) BOOST_PP_REPEAT_1_57(m, d) m(2, 57, d)
+# define BOOST_PP_REPEAT_1_59(m, d) BOOST_PP_REPEAT_1_58(m, d) m(2, 58, d)
+# define BOOST_PP_REPEAT_1_60(m, d) BOOST_PP_REPEAT_1_59(m, d) m(2, 59, d)
+# define BOOST_PP_REPEAT_1_61(m, d) BOOST_PP_REPEAT_1_60(m, d) m(2, 60, d)
+# define BOOST_PP_REPEAT_1_62(m, d) BOOST_PP_REPEAT_1_61(m, d) m(2, 61, d)
+# define BOOST_PP_REPEAT_1_63(m, d) BOOST_PP_REPEAT_1_62(m, d) m(2, 62, d)
+# define BOOST_PP_REPEAT_1_64(m, d) BOOST_PP_REPEAT_1_63(m, d) m(2, 63, d)
+# define BOOST_PP_REPEAT_1_65(m, d) BOOST_PP_REPEAT_1_64(m, d) m(2, 64, d)
+# define BOOST_PP_REPEAT_1_66(m, d) BOOST_PP_REPEAT_1_65(m, d) m(2, 65, d)
+# define BOOST_PP_REPEAT_1_67(m, d) BOOST_PP_REPEAT_1_66(m, d) m(2, 66, d)
+# define BOOST_PP_REPEAT_1_68(m, d) BOOST_PP_REPEAT_1_67(m, d) m(2, 67, d)
+# define BOOST_PP_REPEAT_1_69(m, d) BOOST_PP_REPEAT_1_68(m, d) m(2, 68, d)
+# define BOOST_PP_REPEAT_1_70(m, d) BOOST_PP_REPEAT_1_69(m, d) m(2, 69, d)
+# define BOOST_PP_REPEAT_1_71(m, d) BOOST_PP_REPEAT_1_70(m, d) m(2, 70, d)
+# define BOOST_PP_REPEAT_1_72(m, d) BOOST_PP_REPEAT_1_71(m, d) m(2, 71, d)
+# define BOOST_PP_REPEAT_1_73(m, d) BOOST_PP_REPEAT_1_72(m, d) m(2, 72, d)
+# define BOOST_PP_REPEAT_1_74(m, d) BOOST_PP_REPEAT_1_73(m, d) m(2, 73, d)
+# define BOOST_PP_REPEAT_1_75(m, d) BOOST_PP_REPEAT_1_74(m, d) m(2, 74, d)
+# define BOOST_PP_REPEAT_1_76(m, d) BOOST_PP_REPEAT_1_75(m, d) m(2, 75, d)
+# define BOOST_PP_REPEAT_1_77(m, d) BOOST_PP_REPEAT_1_76(m, d) m(2, 76, d)
+# define BOOST_PP_REPEAT_1_78(m, d) BOOST_PP_REPEAT_1_77(m, d) m(2, 77, d)
+# define BOOST_PP_REPEAT_1_79(m, d) BOOST_PP_REPEAT_1_78(m, d) m(2, 78, d)
+# define BOOST_PP_REPEAT_1_80(m, d) BOOST_PP_REPEAT_1_79(m, d) m(2, 79, d)
+# define BOOST_PP_REPEAT_1_81(m, d) BOOST_PP_REPEAT_1_80(m, d) m(2, 80, d)
+# define BOOST_PP_REPEAT_1_82(m, d) BOOST_PP_REPEAT_1_81(m, d) m(2, 81, d)
+# define BOOST_PP_REPEAT_1_83(m, d) BOOST_PP_REPEAT_1_82(m, d) m(2, 82, d)
+# define BOOST_PP_REPEAT_1_84(m, d) BOOST_PP_REPEAT_1_83(m, d) m(2, 83, d)
+# define BOOST_PP_REPEAT_1_85(m, d) BOOST_PP_REPEAT_1_84(m, d) m(2, 84, d)
+# define BOOST_PP_REPEAT_1_86(m, d) BOOST_PP_REPEAT_1_85(m, d) m(2, 85, d)
+# define BOOST_PP_REPEAT_1_87(m, d) BOOST_PP_REPEAT_1_86(m, d) m(2, 86, d)
+# define BOOST_PP_REPEAT_1_88(m, d) BOOST_PP_REPEAT_1_87(m, d) m(2, 87, d)
+# define BOOST_PP_REPEAT_1_89(m, d) BOOST_PP_REPEAT_1_88(m, d) m(2, 88, d)
+# define BOOST_PP_REPEAT_1_90(m, d) BOOST_PP_REPEAT_1_89(m, d) m(2, 89, d)
+# define BOOST_PP_REPEAT_1_91(m, d) BOOST_PP_REPEAT_1_90(m, d) m(2, 90, d)
+# define BOOST_PP_REPEAT_1_92(m, d) BOOST_PP_REPEAT_1_91(m, d) m(2, 91, d)
+# define BOOST_PP_REPEAT_1_93(m, d) BOOST_PP_REPEAT_1_92(m, d) m(2, 92, d)
+# define BOOST_PP_REPEAT_1_94(m, d) BOOST_PP_REPEAT_1_93(m, d) m(2, 93, d)
+# define BOOST_PP_REPEAT_1_95(m, d) BOOST_PP_REPEAT_1_94(m, d) m(2, 94, d)
+# define BOOST_PP_REPEAT_1_96(m, d) BOOST_PP_REPEAT_1_95(m, d) m(2, 95, d)
+# define BOOST_PP_REPEAT_1_97(m, d) BOOST_PP_REPEAT_1_96(m, d) m(2, 96, d)
+# define BOOST_PP_REPEAT_1_98(m, d) BOOST_PP_REPEAT_1_97(m, d) m(2, 97, d)
+# define BOOST_PP_REPEAT_1_99(m, d) BOOST_PP_REPEAT_1_98(m, d) m(2, 98, d)
+# define BOOST_PP_REPEAT_1_100(m, d) BOOST_PP_REPEAT_1_99(m, d) m(2, 99, d)
+# define BOOST_PP_REPEAT_1_101(m, d) BOOST_PP_REPEAT_1_100(m, d) m(2, 100, d)
+# define BOOST_PP_REPEAT_1_102(m, d) BOOST_PP_REPEAT_1_101(m, d) m(2, 101, d)
+# define BOOST_PP_REPEAT_1_103(m, d) BOOST_PP_REPEAT_1_102(m, d) m(2, 102, d)
+# define BOOST_PP_REPEAT_1_104(m, d) BOOST_PP_REPEAT_1_103(m, d) m(2, 103, d)
+# define BOOST_PP_REPEAT_1_105(m, d) BOOST_PP_REPEAT_1_104(m, d) m(2, 104, d)
+# define BOOST_PP_REPEAT_1_106(m, d) BOOST_PP_REPEAT_1_105(m, d) m(2, 105, d)
+# define BOOST_PP_REPEAT_1_107(m, d) BOOST_PP_REPEAT_1_106(m, d) m(2, 106, d)
+# define BOOST_PP_REPEAT_1_108(m, d) BOOST_PP_REPEAT_1_107(m, d) m(2, 107, d)
+# define BOOST_PP_REPEAT_1_109(m, d) BOOST_PP_REPEAT_1_108(m, d) m(2, 108, d)
+# define BOOST_PP_REPEAT_1_110(m, d) BOOST_PP_REPEAT_1_109(m, d) m(2, 109, d)
+# define BOOST_PP_REPEAT_1_111(m, d) BOOST_PP_REPEAT_1_110(m, d) m(2, 110, d)
+# define BOOST_PP_REPEAT_1_112(m, d) BOOST_PP_REPEAT_1_111(m, d) m(2, 111, d)
+# define BOOST_PP_REPEAT_1_113(m, d) BOOST_PP_REPEAT_1_112(m, d) m(2, 112, d)
+# define BOOST_PP_REPEAT_1_114(m, d) BOOST_PP_REPEAT_1_113(m, d) m(2, 113, d)
+# define BOOST_PP_REPEAT_1_115(m, d) BOOST_PP_REPEAT_1_114(m, d) m(2, 114, d)
+# define BOOST_PP_REPEAT_1_116(m, d) BOOST_PP_REPEAT_1_115(m, d) m(2, 115, d)
+# define BOOST_PP_REPEAT_1_117(m, d) BOOST_PP_REPEAT_1_116(m, d) m(2, 116, d)
+# define BOOST_PP_REPEAT_1_118(m, d) BOOST_PP_REPEAT_1_117(m, d) m(2, 117, d)
+# define BOOST_PP_REPEAT_1_119(m, d) BOOST_PP_REPEAT_1_118(m, d) m(2, 118, d)
+# define BOOST_PP_REPEAT_1_120(m, d) BOOST_PP_REPEAT_1_119(m, d) m(2, 119, d)
+# define BOOST_PP_REPEAT_1_121(m, d) BOOST_PP_REPEAT_1_120(m, d) m(2, 120, d)
+# define BOOST_PP_REPEAT_1_122(m, d) BOOST_PP_REPEAT_1_121(m, d) m(2, 121, d)
+# define BOOST_PP_REPEAT_1_123(m, d) BOOST_PP_REPEAT_1_122(m, d) m(2, 122, d)
+# define BOOST_PP_REPEAT_1_124(m, d) BOOST_PP_REPEAT_1_123(m, d) m(2, 123, d)
+# define BOOST_PP_REPEAT_1_125(m, d) BOOST_PP_REPEAT_1_124(m, d) m(2, 124, d)
+# define BOOST_PP_REPEAT_1_126(m, d) BOOST_PP_REPEAT_1_125(m, d) m(2, 125, d)
+# define BOOST_PP_REPEAT_1_127(m, d) BOOST_PP_REPEAT_1_126(m, d) m(2, 126, d)
+# define BOOST_PP_REPEAT_1_128(m, d) BOOST_PP_REPEAT_1_127(m, d) m(2, 127, d)
+# define BOOST_PP_REPEAT_1_129(m, d) BOOST_PP_REPEAT_1_128(m, d) m(2, 128, d)
+# define BOOST_PP_REPEAT_1_130(m, d) BOOST_PP_REPEAT_1_129(m, d) m(2, 129, d)
+# define BOOST_PP_REPEAT_1_131(m, d) BOOST_PP_REPEAT_1_130(m, d) m(2, 130, d)
+# define BOOST_PP_REPEAT_1_132(m, d) BOOST_PP_REPEAT_1_131(m, d) m(2, 131, d)
+# define BOOST_PP_REPEAT_1_133(m, d) BOOST_PP_REPEAT_1_132(m, d) m(2, 132, d)
+# define BOOST_PP_REPEAT_1_134(m, d) BOOST_PP_REPEAT_1_133(m, d) m(2, 133, d)
+# define BOOST_PP_REPEAT_1_135(m, d) BOOST_PP_REPEAT_1_134(m, d) m(2, 134, d)
+# define BOOST_PP_REPEAT_1_136(m, d) BOOST_PP_REPEAT_1_135(m, d) m(2, 135, d)
+# define BOOST_PP_REPEAT_1_137(m, d) BOOST_PP_REPEAT_1_136(m, d) m(2, 136, d)
+# define BOOST_PP_REPEAT_1_138(m, d) BOOST_PP_REPEAT_1_137(m, d) m(2, 137, d)
+# define BOOST_PP_REPEAT_1_139(m, d) BOOST_PP_REPEAT_1_138(m, d) m(2, 138, d)
+# define BOOST_PP_REPEAT_1_140(m, d) BOOST_PP_REPEAT_1_139(m, d) m(2, 139, d)
+# define BOOST_PP_REPEAT_1_141(m, d) BOOST_PP_REPEAT_1_140(m, d) m(2, 140, d)
+# define BOOST_PP_REPEAT_1_142(m, d) BOOST_PP_REPEAT_1_141(m, d) m(2, 141, d)
+# define BOOST_PP_REPEAT_1_143(m, d) BOOST_PP_REPEAT_1_142(m, d) m(2, 142, d)
+# define BOOST_PP_REPEAT_1_144(m, d) BOOST_PP_REPEAT_1_143(m, d) m(2, 143, d)
+# define BOOST_PP_REPEAT_1_145(m, d) BOOST_PP_REPEAT_1_144(m, d) m(2, 144, d)
+# define BOOST_PP_REPEAT_1_146(m, d) BOOST_PP_REPEAT_1_145(m, d) m(2, 145, d)
+# define BOOST_PP_REPEAT_1_147(m, d) BOOST_PP_REPEAT_1_146(m, d) m(2, 146, d)
+# define BOOST_PP_REPEAT_1_148(m, d) BOOST_PP_REPEAT_1_147(m, d) m(2, 147, d)
+# define BOOST_PP_REPEAT_1_149(m, d) BOOST_PP_REPEAT_1_148(m, d) m(2, 148, d)
+# define BOOST_PP_REPEAT_1_150(m, d) BOOST_PP_REPEAT_1_149(m, d) m(2, 149, d)
+# define BOOST_PP_REPEAT_1_151(m, d) BOOST_PP_REPEAT_1_150(m, d) m(2, 150, d)
+# define BOOST_PP_REPEAT_1_152(m, d) BOOST_PP_REPEAT_1_151(m, d) m(2, 151, d)
+# define BOOST_PP_REPEAT_1_153(m, d) BOOST_PP_REPEAT_1_152(m, d) m(2, 152, d)
+# define BOOST_PP_REPEAT_1_154(m, d) BOOST_PP_REPEAT_1_153(m, d) m(2, 153, d)
+# define BOOST_PP_REPEAT_1_155(m, d) BOOST_PP_REPEAT_1_154(m, d) m(2, 154, d)
+# define BOOST_PP_REPEAT_1_156(m, d) BOOST_PP_REPEAT_1_155(m, d) m(2, 155, d)
+# define BOOST_PP_REPEAT_1_157(m, d) BOOST_PP_REPEAT_1_156(m, d) m(2, 156, d)
+# define BOOST_PP_REPEAT_1_158(m, d) BOOST_PP_REPEAT_1_157(m, d) m(2, 157, d)
+# define BOOST_PP_REPEAT_1_159(m, d) BOOST_PP_REPEAT_1_158(m, d) m(2, 158, d)
+# define BOOST_PP_REPEAT_1_160(m, d) BOOST_PP_REPEAT_1_159(m, d) m(2, 159, d)
+# define BOOST_PP_REPEAT_1_161(m, d) BOOST_PP_REPEAT_1_160(m, d) m(2, 160, d)
+# define BOOST_PP_REPEAT_1_162(m, d) BOOST_PP_REPEAT_1_161(m, d) m(2, 161, d)
+# define BOOST_PP_REPEAT_1_163(m, d) BOOST_PP_REPEAT_1_162(m, d) m(2, 162, d)
+# define BOOST_PP_REPEAT_1_164(m, d) BOOST_PP_REPEAT_1_163(m, d) m(2, 163, d)
+# define BOOST_PP_REPEAT_1_165(m, d) BOOST_PP_REPEAT_1_164(m, d) m(2, 164, d)
+# define BOOST_PP_REPEAT_1_166(m, d) BOOST_PP_REPEAT_1_165(m, d) m(2, 165, d)
+# define BOOST_PP_REPEAT_1_167(m, d) BOOST_PP_REPEAT_1_166(m, d) m(2, 166, d)
+# define BOOST_PP_REPEAT_1_168(m, d) BOOST_PP_REPEAT_1_167(m, d) m(2, 167, d)
+# define BOOST_PP_REPEAT_1_169(m, d) BOOST_PP_REPEAT_1_168(m, d) m(2, 168, d)
+# define BOOST_PP_REPEAT_1_170(m, d) BOOST_PP_REPEAT_1_169(m, d) m(2, 169, d)
+# define BOOST_PP_REPEAT_1_171(m, d) BOOST_PP_REPEAT_1_170(m, d) m(2, 170, d)
+# define BOOST_PP_REPEAT_1_172(m, d) BOOST_PP_REPEAT_1_171(m, d) m(2, 171, d)
+# define BOOST_PP_REPEAT_1_173(m, d) BOOST_PP_REPEAT_1_172(m, d) m(2, 172, d)
+# define BOOST_PP_REPEAT_1_174(m, d) BOOST_PP_REPEAT_1_173(m, d) m(2, 173, d)
+# define BOOST_PP_REPEAT_1_175(m, d) BOOST_PP_REPEAT_1_174(m, d) m(2, 174, d)
+# define BOOST_PP_REPEAT_1_176(m, d) BOOST_PP_REPEAT_1_175(m, d) m(2, 175, d)
+# define BOOST_PP_REPEAT_1_177(m, d) BOOST_PP_REPEAT_1_176(m, d) m(2, 176, d)
+# define BOOST_PP_REPEAT_1_178(m, d) BOOST_PP_REPEAT_1_177(m, d) m(2, 177, d)
+# define BOOST_PP_REPEAT_1_179(m, d) BOOST_PP_REPEAT_1_178(m, d) m(2, 178, d)
+# define BOOST_PP_REPEAT_1_180(m, d) BOOST_PP_REPEAT_1_179(m, d) m(2, 179, d)
+# define BOOST_PP_REPEAT_1_181(m, d) BOOST_PP_REPEAT_1_180(m, d) m(2, 180, d)
+# define BOOST_PP_REPEAT_1_182(m, d) BOOST_PP_REPEAT_1_181(m, d) m(2, 181, d)
+# define BOOST_PP_REPEAT_1_183(m, d) BOOST_PP_REPEAT_1_182(m, d) m(2, 182, d)
+# define BOOST_PP_REPEAT_1_184(m, d) BOOST_PP_REPEAT_1_183(m, d) m(2, 183, d)
+# define BOOST_PP_REPEAT_1_185(m, d) BOOST_PP_REPEAT_1_184(m, d) m(2, 184, d)
+# define BOOST_PP_REPEAT_1_186(m, d) BOOST_PP_REPEAT_1_185(m, d) m(2, 185, d)
+# define BOOST_PP_REPEAT_1_187(m, d) BOOST_PP_REPEAT_1_186(m, d) m(2, 186, d)
+# define BOOST_PP_REPEAT_1_188(m, d) BOOST_PP_REPEAT_1_187(m, d) m(2, 187, d)
+# define BOOST_PP_REPEAT_1_189(m, d) BOOST_PP_REPEAT_1_188(m, d) m(2, 188, d)
+# define BOOST_PP_REPEAT_1_190(m, d) BOOST_PP_REPEAT_1_189(m, d) m(2, 189, d)
+# define BOOST_PP_REPEAT_1_191(m, d) BOOST_PP_REPEAT_1_190(m, d) m(2, 190, d)
+# define BOOST_PP_REPEAT_1_192(m, d) BOOST_PP_REPEAT_1_191(m, d) m(2, 191, d)
+# define BOOST_PP_REPEAT_1_193(m, d) BOOST_PP_REPEAT_1_192(m, d) m(2, 192, d)
+# define BOOST_PP_REPEAT_1_194(m, d) BOOST_PP_REPEAT_1_193(m, d) m(2, 193, d)
+# define BOOST_PP_REPEAT_1_195(m, d) BOOST_PP_REPEAT_1_194(m, d) m(2, 194, d)
+# define BOOST_PP_REPEAT_1_196(m, d) BOOST_PP_REPEAT_1_195(m, d) m(2, 195, d)
+# define BOOST_PP_REPEAT_1_197(m, d) BOOST_PP_REPEAT_1_196(m, d) m(2, 196, d)
+# define BOOST_PP_REPEAT_1_198(m, d) BOOST_PP_REPEAT_1_197(m, d) m(2, 197, d)
+# define BOOST_PP_REPEAT_1_199(m, d) BOOST_PP_REPEAT_1_198(m, d) m(2, 198, d)
+# define BOOST_PP_REPEAT_1_200(m, d) BOOST_PP_REPEAT_1_199(m, d) m(2, 199, d)
+# define BOOST_PP_REPEAT_1_201(m, d) BOOST_PP_REPEAT_1_200(m, d) m(2, 200, d)
+# define BOOST_PP_REPEAT_1_202(m, d) BOOST_PP_REPEAT_1_201(m, d) m(2, 201, d)
+# define BOOST_PP_REPEAT_1_203(m, d) BOOST_PP_REPEAT_1_202(m, d) m(2, 202, d)
+# define BOOST_PP_REPEAT_1_204(m, d) BOOST_PP_REPEAT_1_203(m, d) m(2, 203, d)
+# define BOOST_PP_REPEAT_1_205(m, d) BOOST_PP_REPEAT_1_204(m, d) m(2, 204, d)
+# define BOOST_PP_REPEAT_1_206(m, d) BOOST_PP_REPEAT_1_205(m, d) m(2, 205, d)
+# define BOOST_PP_REPEAT_1_207(m, d) BOOST_PP_REPEAT_1_206(m, d) m(2, 206, d)
+# define BOOST_PP_REPEAT_1_208(m, d) BOOST_PP_REPEAT_1_207(m, d) m(2, 207, d)
+# define BOOST_PP_REPEAT_1_209(m, d) BOOST_PP_REPEAT_1_208(m, d) m(2, 208, d)
+# define BOOST_PP_REPEAT_1_210(m, d) BOOST_PP_REPEAT_1_209(m, d) m(2, 209, d)
+# define BOOST_PP_REPEAT_1_211(m, d) BOOST_PP_REPEAT_1_210(m, d) m(2, 210, d)
+# define BOOST_PP_REPEAT_1_212(m, d) BOOST_PP_REPEAT_1_211(m, d) m(2, 211, d)
+# define BOOST_PP_REPEAT_1_213(m, d) BOOST_PP_REPEAT_1_212(m, d) m(2, 212, d)
+# define BOOST_PP_REPEAT_1_214(m, d) BOOST_PP_REPEAT_1_213(m, d) m(2, 213, d)
+# define BOOST_PP_REPEAT_1_215(m, d) BOOST_PP_REPEAT_1_214(m, d) m(2, 214, d)
+# define BOOST_PP_REPEAT_1_216(m, d) BOOST_PP_REPEAT_1_215(m, d) m(2, 215, d)
+# define BOOST_PP_REPEAT_1_217(m, d) BOOST_PP_REPEAT_1_216(m, d) m(2, 216, d)
+# define BOOST_PP_REPEAT_1_218(m, d) BOOST_PP_REPEAT_1_217(m, d) m(2, 217, d)
+# define BOOST_PP_REPEAT_1_219(m, d) BOOST_PP_REPEAT_1_218(m, d) m(2, 218, d)
+# define BOOST_PP_REPEAT_1_220(m, d) BOOST_PP_REPEAT_1_219(m, d) m(2, 219, d)
+# define BOOST_PP_REPEAT_1_221(m, d) BOOST_PP_REPEAT_1_220(m, d) m(2, 220, d)
+# define BOOST_PP_REPEAT_1_222(m, d) BOOST_PP_REPEAT_1_221(m, d) m(2, 221, d)
+# define BOOST_PP_REPEAT_1_223(m, d) BOOST_PP_REPEAT_1_222(m, d) m(2, 222, d)
+# define BOOST_PP_REPEAT_1_224(m, d) BOOST_PP_REPEAT_1_223(m, d) m(2, 223, d)
+# define BOOST_PP_REPEAT_1_225(m, d) BOOST_PP_REPEAT_1_224(m, d) m(2, 224, d)
+# define BOOST_PP_REPEAT_1_226(m, d) BOOST_PP_REPEAT_1_225(m, d) m(2, 225, d)
+# define BOOST_PP_REPEAT_1_227(m, d) BOOST_PP_REPEAT_1_226(m, d) m(2, 226, d)
+# define BOOST_PP_REPEAT_1_228(m, d) BOOST_PP_REPEAT_1_227(m, d) m(2, 227, d)
+# define BOOST_PP_REPEAT_1_229(m, d) BOOST_PP_REPEAT_1_228(m, d) m(2, 228, d)
+# define BOOST_PP_REPEAT_1_230(m, d) BOOST_PP_REPEAT_1_229(m, d) m(2, 229, d)
+# define BOOST_PP_REPEAT_1_231(m, d) BOOST_PP_REPEAT_1_230(m, d) m(2, 230, d)
+# define BOOST_PP_REPEAT_1_232(m, d) BOOST_PP_REPEAT_1_231(m, d) m(2, 231, d)
+# define BOOST_PP_REPEAT_1_233(m, d) BOOST_PP_REPEAT_1_232(m, d) m(2, 232, d)
+# define BOOST_PP_REPEAT_1_234(m, d) BOOST_PP_REPEAT_1_233(m, d) m(2, 233, d)
+# define BOOST_PP_REPEAT_1_235(m, d) BOOST_PP_REPEAT_1_234(m, d) m(2, 234, d)
+# define BOOST_PP_REPEAT_1_236(m, d) BOOST_PP_REPEAT_1_235(m, d) m(2, 235, d)
+# define BOOST_PP_REPEAT_1_237(m, d) BOOST_PP_REPEAT_1_236(m, d) m(2, 236, d)
+# define BOOST_PP_REPEAT_1_238(m, d) BOOST_PP_REPEAT_1_237(m, d) m(2, 237, d)
+# define BOOST_PP_REPEAT_1_239(m, d) BOOST_PP_REPEAT_1_238(m, d) m(2, 238, d)
+# define BOOST_PP_REPEAT_1_240(m, d) BOOST_PP_REPEAT_1_239(m, d) m(2, 239, d)
+# define BOOST_PP_REPEAT_1_241(m, d) BOOST_PP_REPEAT_1_240(m, d) m(2, 240, d)
+# define BOOST_PP_REPEAT_1_242(m, d) BOOST_PP_REPEAT_1_241(m, d) m(2, 241, d)
+# define BOOST_PP_REPEAT_1_243(m, d) BOOST_PP_REPEAT_1_242(m, d) m(2, 242, d)
+# define BOOST_PP_REPEAT_1_244(m, d) BOOST_PP_REPEAT_1_243(m, d) m(2, 243, d)
+# define BOOST_PP_REPEAT_1_245(m, d) BOOST_PP_REPEAT_1_244(m, d) m(2, 244, d)
+# define BOOST_PP_REPEAT_1_246(m, d) BOOST_PP_REPEAT_1_245(m, d) m(2, 245, d)
+# define BOOST_PP_REPEAT_1_247(m, d) BOOST_PP_REPEAT_1_246(m, d) m(2, 246, d)
+# define BOOST_PP_REPEAT_1_248(m, d) BOOST_PP_REPEAT_1_247(m, d) m(2, 247, d)
+# define BOOST_PP_REPEAT_1_249(m, d) BOOST_PP_REPEAT_1_248(m, d) m(2, 248, d)
+# define BOOST_PP_REPEAT_1_250(m, d) BOOST_PP_REPEAT_1_249(m, d) m(2, 249, d)
+# define BOOST_PP_REPEAT_1_251(m, d) BOOST_PP_REPEAT_1_250(m, d) m(2, 250, d)
+# define BOOST_PP_REPEAT_1_252(m, d) BOOST_PP_REPEAT_1_251(m, d) m(2, 251, d)
+# define BOOST_PP_REPEAT_1_253(m, d) BOOST_PP_REPEAT_1_252(m, d) m(2, 252, d)
+# define BOOST_PP_REPEAT_1_254(m, d) BOOST_PP_REPEAT_1_253(m, d) m(2, 253, d)
+# define BOOST_PP_REPEAT_1_255(m, d) BOOST_PP_REPEAT_1_254(m, d) m(2, 254, d)
+# define BOOST_PP_REPEAT_1_256(m, d) BOOST_PP_REPEAT_1_255(m, d) m(2, 255, d)
+#
+# define BOOST_PP_REPEAT_2_0(m, d)
+# define BOOST_PP_REPEAT_2_1(m, d) m(3, 0, d)
+# define BOOST_PP_REPEAT_2_2(m, d) BOOST_PP_REPEAT_2_1(m, d) m(3, 1, d)
+# define BOOST_PP_REPEAT_2_3(m, d) BOOST_PP_REPEAT_2_2(m, d) m(3, 2, d)
+# define BOOST_PP_REPEAT_2_4(m, d) BOOST_PP_REPEAT_2_3(m, d) m(3, 3, d)
+# define BOOST_PP_REPEAT_2_5(m, d) BOOST_PP_REPEAT_2_4(m, d) m(3, 4, d)
+# define BOOST_PP_REPEAT_2_6(m, d) BOOST_PP_REPEAT_2_5(m, d) m(3, 5, d)
+# define BOOST_PP_REPEAT_2_7(m, d) BOOST_PP_REPEAT_2_6(m, d) m(3, 6, d)
+# define BOOST_PP_REPEAT_2_8(m, d) BOOST_PP_REPEAT_2_7(m, d) m(3, 7, d)
+# define BOOST_PP_REPEAT_2_9(m, d) BOOST_PP_REPEAT_2_8(m, d) m(3, 8, d)
+# define BOOST_PP_REPEAT_2_10(m, d) BOOST_PP_REPEAT_2_9(m, d) m(3, 9, d)
+# define BOOST_PP_REPEAT_2_11(m, d) BOOST_PP_REPEAT_2_10(m, d) m(3, 10, d)
+# define BOOST_PP_REPEAT_2_12(m, d) BOOST_PP_REPEAT_2_11(m, d) m(3, 11, d)
+# define BOOST_PP_REPEAT_2_13(m, d) BOOST_PP_REPEAT_2_12(m, d) m(3, 12, d)
+# define BOOST_PP_REPEAT_2_14(m, d) BOOST_PP_REPEAT_2_13(m, d) m(3, 13, d)
+# define BOOST_PP_REPEAT_2_15(m, d) BOOST_PP_REPEAT_2_14(m, d) m(3, 14, d)
+# define BOOST_PP_REPEAT_2_16(m, d) BOOST_PP_REPEAT_2_15(m, d) m(3, 15, d)
+# define BOOST_PP_REPEAT_2_17(m, d) BOOST_PP_REPEAT_2_16(m, d) m(3, 16, d)
+# define BOOST_PP_REPEAT_2_18(m, d) BOOST_PP_REPEAT_2_17(m, d) m(3, 17, d)
+# define BOOST_PP_REPEAT_2_19(m, d) BOOST_PP_REPEAT_2_18(m, d) m(3, 18, d)
+# define BOOST_PP_REPEAT_2_20(m, d) BOOST_PP_REPEAT_2_19(m, d) m(3, 19, d)
+# define BOOST_PP_REPEAT_2_21(m, d) BOOST_PP_REPEAT_2_20(m, d) m(3, 20, d)
+# define BOOST_PP_REPEAT_2_22(m, d) BOOST_PP_REPEAT_2_21(m, d) m(3, 21, d)
+# define BOOST_PP_REPEAT_2_23(m, d) BOOST_PP_REPEAT_2_22(m, d) m(3, 22, d)
+# define BOOST_PP_REPEAT_2_24(m, d) BOOST_PP_REPEAT_2_23(m, d) m(3, 23, d)
+# define BOOST_PP_REPEAT_2_25(m, d) BOOST_PP_REPEAT_2_24(m, d) m(3, 24, d)
+# define BOOST_PP_REPEAT_2_26(m, d) BOOST_PP_REPEAT_2_25(m, d) m(3, 25, d)
+# define BOOST_PP_REPEAT_2_27(m, d) BOOST_PP_REPEAT_2_26(m, d) m(3, 26, d)
+# define BOOST_PP_REPEAT_2_28(m, d) BOOST_PP_REPEAT_2_27(m, d) m(3, 27, d)
+# define BOOST_PP_REPEAT_2_29(m, d) BOOST_PP_REPEAT_2_28(m, d) m(3, 28, d)
+# define BOOST_PP_REPEAT_2_30(m, d) BOOST_PP_REPEAT_2_29(m, d) m(3, 29, d)
+# define BOOST_PP_REPEAT_2_31(m, d) BOOST_PP_REPEAT_2_30(m, d) m(3, 30, d)
+# define BOOST_PP_REPEAT_2_32(m, d) BOOST_PP_REPEAT_2_31(m, d) m(3, 31, d)
+# define BOOST_PP_REPEAT_2_33(m, d) BOOST_PP_REPEAT_2_32(m, d) m(3, 32, d)
+# define BOOST_PP_REPEAT_2_34(m, d) BOOST_PP_REPEAT_2_33(m, d) m(3, 33, d)
+# define BOOST_PP_REPEAT_2_35(m, d) BOOST_PP_REPEAT_2_34(m, d) m(3, 34, d)
+# define BOOST_PP_REPEAT_2_36(m, d) BOOST_PP_REPEAT_2_35(m, d) m(3, 35, d)
+# define BOOST_PP_REPEAT_2_37(m, d) BOOST_PP_REPEAT_2_36(m, d) m(3, 36, d)
+# define BOOST_PP_REPEAT_2_38(m, d) BOOST_PP_REPEAT_2_37(m, d) m(3, 37, d)
+# define BOOST_PP_REPEAT_2_39(m, d) BOOST_PP_REPEAT_2_38(m, d) m(3, 38, d)
+# define BOOST_PP_REPEAT_2_40(m, d) BOOST_PP_REPEAT_2_39(m, d) m(3, 39, d)
+# define BOOST_PP_REPEAT_2_41(m, d) BOOST_PP_REPEAT_2_40(m, d) m(3, 40, d)
+# define BOOST_PP_REPEAT_2_42(m, d) BOOST_PP_REPEAT_2_41(m, d) m(3, 41, d)
+# define BOOST_PP_REPEAT_2_43(m, d) BOOST_PP_REPEAT_2_42(m, d) m(3, 42, d)
+# define BOOST_PP_REPEAT_2_44(m, d) BOOST_PP_REPEAT_2_43(m, d) m(3, 43, d)
+# define BOOST_PP_REPEAT_2_45(m, d) BOOST_PP_REPEAT_2_44(m, d) m(3, 44, d)
+# define BOOST_PP_REPEAT_2_46(m, d) BOOST_PP_REPEAT_2_45(m, d) m(3, 45, d)
+# define BOOST_PP_REPEAT_2_47(m, d) BOOST_PP_REPEAT_2_46(m, d) m(3, 46, d)
+# define BOOST_PP_REPEAT_2_48(m, d) BOOST_PP_REPEAT_2_47(m, d) m(3, 47, d)
+# define BOOST_PP_REPEAT_2_49(m, d) BOOST_PP_REPEAT_2_48(m, d) m(3, 48, d)
+# define BOOST_PP_REPEAT_2_50(m, d) BOOST_PP_REPEAT_2_49(m, d) m(3, 49, d)
+# define BOOST_PP_REPEAT_2_51(m, d) BOOST_PP_REPEAT_2_50(m, d) m(3, 50, d)
+# define BOOST_PP_REPEAT_2_52(m, d) BOOST_PP_REPEAT_2_51(m, d) m(3, 51, d)
+# define BOOST_PP_REPEAT_2_53(m, d) BOOST_PP_REPEAT_2_52(m, d) m(3, 52, d)
+# define BOOST_PP_REPEAT_2_54(m, d) BOOST_PP_REPEAT_2_53(m, d) m(3, 53, d)
+# define BOOST_PP_REPEAT_2_55(m, d) BOOST_PP_REPEAT_2_54(m, d) m(3, 54, d)
+# define BOOST_PP_REPEAT_2_56(m, d) BOOST_PP_REPEAT_2_55(m, d) m(3, 55, d)
+# define BOOST_PP_REPEAT_2_57(m, d) BOOST_PP_REPEAT_2_56(m, d) m(3, 56, d)
+# define BOOST_PP_REPEAT_2_58(m, d) BOOST_PP_REPEAT_2_57(m, d) m(3, 57, d)
+# define BOOST_PP_REPEAT_2_59(m, d) BOOST_PP_REPEAT_2_58(m, d) m(3, 58, d)
+# define BOOST_PP_REPEAT_2_60(m, d) BOOST_PP_REPEAT_2_59(m, d) m(3, 59, d)
+# define BOOST_PP_REPEAT_2_61(m, d) BOOST_PP_REPEAT_2_60(m, d) m(3, 60, d)
+# define BOOST_PP_REPEAT_2_62(m, d) BOOST_PP_REPEAT_2_61(m, d) m(3, 61, d)
+# define BOOST_PP_REPEAT_2_63(m, d) BOOST_PP_REPEAT_2_62(m, d) m(3, 62, d)
+# define BOOST_PP_REPEAT_2_64(m, d) BOOST_PP_REPEAT_2_63(m, d) m(3, 63, d)
+# define BOOST_PP_REPEAT_2_65(m, d) BOOST_PP_REPEAT_2_64(m, d) m(3, 64, d)
+# define BOOST_PP_REPEAT_2_66(m, d) BOOST_PP_REPEAT_2_65(m, d) m(3, 65, d)
+# define BOOST_PP_REPEAT_2_67(m, d) BOOST_PP_REPEAT_2_66(m, d) m(3, 66, d)
+# define BOOST_PP_REPEAT_2_68(m, d) BOOST_PP_REPEAT_2_67(m, d) m(3, 67, d)
+# define BOOST_PP_REPEAT_2_69(m, d) BOOST_PP_REPEAT_2_68(m, d) m(3, 68, d)
+# define BOOST_PP_REPEAT_2_70(m, d) BOOST_PP_REPEAT_2_69(m, d) m(3, 69, d)
+# define BOOST_PP_REPEAT_2_71(m, d) BOOST_PP_REPEAT_2_70(m, d) m(3, 70, d)
+# define BOOST_PP_REPEAT_2_72(m, d) BOOST_PP_REPEAT_2_71(m, d) m(3, 71, d)
+# define BOOST_PP_REPEAT_2_73(m, d) BOOST_PP_REPEAT_2_72(m, d) m(3, 72, d)
+# define BOOST_PP_REPEAT_2_74(m, d) BOOST_PP_REPEAT_2_73(m, d) m(3, 73, d)
+# define BOOST_PP_REPEAT_2_75(m, d) BOOST_PP_REPEAT_2_74(m, d) m(3, 74, d)
+# define BOOST_PP_REPEAT_2_76(m, d) BOOST_PP_REPEAT_2_75(m, d) m(3, 75, d)
+# define BOOST_PP_REPEAT_2_77(m, d) BOOST_PP_REPEAT_2_76(m, d) m(3, 76, d)
+# define BOOST_PP_REPEAT_2_78(m, d) BOOST_PP_REPEAT_2_77(m, d) m(3, 77, d)
+# define BOOST_PP_REPEAT_2_79(m, d) BOOST_PP_REPEAT_2_78(m, d) m(3, 78, d)
+# define BOOST_PP_REPEAT_2_80(m, d) BOOST_PP_REPEAT_2_79(m, d) m(3, 79, d)
+# define BOOST_PP_REPEAT_2_81(m, d) BOOST_PP_REPEAT_2_80(m, d) m(3, 80, d)
+# define BOOST_PP_REPEAT_2_82(m, d) BOOST_PP_REPEAT_2_81(m, d) m(3, 81, d)
+# define BOOST_PP_REPEAT_2_83(m, d) BOOST_PP_REPEAT_2_82(m, d) m(3, 82, d)
+# define BOOST_PP_REPEAT_2_84(m, d) BOOST_PP_REPEAT_2_83(m, d) m(3, 83, d)
+# define BOOST_PP_REPEAT_2_85(m, d) BOOST_PP_REPEAT_2_84(m, d) m(3, 84, d)
+# define BOOST_PP_REPEAT_2_86(m, d) BOOST_PP_REPEAT_2_85(m, d) m(3, 85, d)
+# define BOOST_PP_REPEAT_2_87(m, d) BOOST_PP_REPEAT_2_86(m, d) m(3, 86, d)
+# define BOOST_PP_REPEAT_2_88(m, d) BOOST_PP_REPEAT_2_87(m, d) m(3, 87, d)
+# define BOOST_PP_REPEAT_2_89(m, d) BOOST_PP_REPEAT_2_88(m, d) m(3, 88, d)
+# define BOOST_PP_REPEAT_2_90(m, d) BOOST_PP_REPEAT_2_89(m, d) m(3, 89, d)
+# define BOOST_PP_REPEAT_2_91(m, d) BOOST_PP_REPEAT_2_90(m, d) m(3, 90, d)
+# define BOOST_PP_REPEAT_2_92(m, d) BOOST_PP_REPEAT_2_91(m, d) m(3, 91, d)
+# define BOOST_PP_REPEAT_2_93(m, d) BOOST_PP_REPEAT_2_92(m, d) m(3, 92, d)
+# define BOOST_PP_REPEAT_2_94(m, d) BOOST_PP_REPEAT_2_93(m, d) m(3, 93, d)
+# define BOOST_PP_REPEAT_2_95(m, d) BOOST_PP_REPEAT_2_94(m, d) m(3, 94, d)
+# define BOOST_PP_REPEAT_2_96(m, d) BOOST_PP_REPEAT_2_95(m, d) m(3, 95, d)
+# define BOOST_PP_REPEAT_2_97(m, d) BOOST_PP_REPEAT_2_96(m, d) m(3, 96, d)
+# define BOOST_PP_REPEAT_2_98(m, d) BOOST_PP_REPEAT_2_97(m, d) m(3, 97, d)
+# define BOOST_PP_REPEAT_2_99(m, d) BOOST_PP_REPEAT_2_98(m, d) m(3, 98, d)
+# define BOOST_PP_REPEAT_2_100(m, d) BOOST_PP_REPEAT_2_99(m, d) m(3, 99, d)
+# define BOOST_PP_REPEAT_2_101(m, d) BOOST_PP_REPEAT_2_100(m, d) m(3, 100, d)
+# define BOOST_PP_REPEAT_2_102(m, d) BOOST_PP_REPEAT_2_101(m, d) m(3, 101, d)
+# define BOOST_PP_REPEAT_2_103(m, d) BOOST_PP_REPEAT_2_102(m, d) m(3, 102, d)
+# define BOOST_PP_REPEAT_2_104(m, d) BOOST_PP_REPEAT_2_103(m, d) m(3, 103, d)
+# define BOOST_PP_REPEAT_2_105(m, d) BOOST_PP_REPEAT_2_104(m, d) m(3, 104, d)
+# define BOOST_PP_REPEAT_2_106(m, d) BOOST_PP_REPEAT_2_105(m, d) m(3, 105, d)
+# define BOOST_PP_REPEAT_2_107(m, d) BOOST_PP_REPEAT_2_106(m, d) m(3, 106, d)
+# define BOOST_PP_REPEAT_2_108(m, d) BOOST_PP_REPEAT_2_107(m, d) m(3, 107, d)
+# define BOOST_PP_REPEAT_2_109(m, d) BOOST_PP_REPEAT_2_108(m, d) m(3, 108, d)
+# define BOOST_PP_REPEAT_2_110(m, d) BOOST_PP_REPEAT_2_109(m, d) m(3, 109, d)
+# define BOOST_PP_REPEAT_2_111(m, d) BOOST_PP_REPEAT_2_110(m, d) m(3, 110, d)
+# define BOOST_PP_REPEAT_2_112(m, d) BOOST_PP_REPEAT_2_111(m, d) m(3, 111, d)
+# define BOOST_PP_REPEAT_2_113(m, d) BOOST_PP_REPEAT_2_112(m, d) m(3, 112, d)
+# define BOOST_PP_REPEAT_2_114(m, d) BOOST_PP_REPEAT_2_113(m, d) m(3, 113, d)
+# define BOOST_PP_REPEAT_2_115(m, d) BOOST_PP_REPEAT_2_114(m, d) m(3, 114, d)
+# define BOOST_PP_REPEAT_2_116(m, d) BOOST_PP_REPEAT_2_115(m, d) m(3, 115, d)
+# define BOOST_PP_REPEAT_2_117(m, d) BOOST_PP_REPEAT_2_116(m, d) m(3, 116, d)
+# define BOOST_PP_REPEAT_2_118(m, d) BOOST_PP_REPEAT_2_117(m, d) m(3, 117, d)
+# define BOOST_PP_REPEAT_2_119(m, d) BOOST_PP_REPEAT_2_118(m, d) m(3, 118, d)
+# define BOOST_PP_REPEAT_2_120(m, d) BOOST_PP_REPEAT_2_119(m, d) m(3, 119, d)
+# define BOOST_PP_REPEAT_2_121(m, d) BOOST_PP_REPEAT_2_120(m, d) m(3, 120, d)
+# define BOOST_PP_REPEAT_2_122(m, d) BOOST_PP_REPEAT_2_121(m, d) m(3, 121, d)
+# define BOOST_PP_REPEAT_2_123(m, d) BOOST_PP_REPEAT_2_122(m, d) m(3, 122, d)
+# define BOOST_PP_REPEAT_2_124(m, d) BOOST_PP_REPEAT_2_123(m, d) m(3, 123, d)
+# define BOOST_PP_REPEAT_2_125(m, d) BOOST_PP_REPEAT_2_124(m, d) m(3, 124, d)
+# define BOOST_PP_REPEAT_2_126(m, d) BOOST_PP_REPEAT_2_125(m, d) m(3, 125, d)
+# define BOOST_PP_REPEAT_2_127(m, d) BOOST_PP_REPEAT_2_126(m, d) m(3, 126, d)
+# define BOOST_PP_REPEAT_2_128(m, d) BOOST_PP_REPEAT_2_127(m, d) m(3, 127, d)
+# define BOOST_PP_REPEAT_2_129(m, d) BOOST_PP_REPEAT_2_128(m, d) m(3, 128, d)
+# define BOOST_PP_REPEAT_2_130(m, d) BOOST_PP_REPEAT_2_129(m, d) m(3, 129, d)
+# define BOOST_PP_REPEAT_2_131(m, d) BOOST_PP_REPEAT_2_130(m, d) m(3, 130, d)
+# define BOOST_PP_REPEAT_2_132(m, d) BOOST_PP_REPEAT_2_131(m, d) m(3, 131, d)
+# define BOOST_PP_REPEAT_2_133(m, d) BOOST_PP_REPEAT_2_132(m, d) m(3, 132, d)
+# define BOOST_PP_REPEAT_2_134(m, d) BOOST_PP_REPEAT_2_133(m, d) m(3, 133, d)
+# define BOOST_PP_REPEAT_2_135(m, d) BOOST_PP_REPEAT_2_134(m, d) m(3, 134, d)
+# define BOOST_PP_REPEAT_2_136(m, d) BOOST_PP_REPEAT_2_135(m, d) m(3, 135, d)
+# define BOOST_PP_REPEAT_2_137(m, d) BOOST_PP_REPEAT_2_136(m, d) m(3, 136, d)
+# define BOOST_PP_REPEAT_2_138(m, d) BOOST_PP_REPEAT_2_137(m, d) m(3, 137, d)
+# define BOOST_PP_REPEAT_2_139(m, d) BOOST_PP_REPEAT_2_138(m, d) m(3, 138, d)
+# define BOOST_PP_REPEAT_2_140(m, d) BOOST_PP_REPEAT_2_139(m, d) m(3, 139, d)
+# define BOOST_PP_REPEAT_2_141(m, d) BOOST_PP_REPEAT_2_140(m, d) m(3, 140, d)
+# define BOOST_PP_REPEAT_2_142(m, d) BOOST_PP_REPEAT_2_141(m, d) m(3, 141, d)
+# define BOOST_PP_REPEAT_2_143(m, d) BOOST_PP_REPEAT_2_142(m, d) m(3, 142, d)
+# define BOOST_PP_REPEAT_2_144(m, d) BOOST_PP_REPEAT_2_143(m, d) m(3, 143, d)
+# define BOOST_PP_REPEAT_2_145(m, d) BOOST_PP_REPEAT_2_144(m, d) m(3, 144, d)
+# define BOOST_PP_REPEAT_2_146(m, d) BOOST_PP_REPEAT_2_145(m, d) m(3, 145, d)
+# define BOOST_PP_REPEAT_2_147(m, d) BOOST_PP_REPEAT_2_146(m, d) m(3, 146, d)
+# define BOOST_PP_REPEAT_2_148(m, d) BOOST_PP_REPEAT_2_147(m, d) m(3, 147, d)
+# define BOOST_PP_REPEAT_2_149(m, d) BOOST_PP_REPEAT_2_148(m, d) m(3, 148, d)
+# define BOOST_PP_REPEAT_2_150(m, d) BOOST_PP_REPEAT_2_149(m, d) m(3, 149, d)
+# define BOOST_PP_REPEAT_2_151(m, d) BOOST_PP_REPEAT_2_150(m, d) m(3, 150, d)
+# define BOOST_PP_REPEAT_2_152(m, d) BOOST_PP_REPEAT_2_151(m, d) m(3, 151, d)
+# define BOOST_PP_REPEAT_2_153(m, d) BOOST_PP_REPEAT_2_152(m, d) m(3, 152, d)
+# define BOOST_PP_REPEAT_2_154(m, d) BOOST_PP_REPEAT_2_153(m, d) m(3, 153, d)
+# define BOOST_PP_REPEAT_2_155(m, d) BOOST_PP_REPEAT_2_154(m, d) m(3, 154, d)
+# define BOOST_PP_REPEAT_2_156(m, d) BOOST_PP_REPEAT_2_155(m, d) m(3, 155, d)
+# define BOOST_PP_REPEAT_2_157(m, d) BOOST_PP_REPEAT_2_156(m, d) m(3, 156, d)
+# define BOOST_PP_REPEAT_2_158(m, d) BOOST_PP_REPEAT_2_157(m, d) m(3, 157, d)
+# define BOOST_PP_REPEAT_2_159(m, d) BOOST_PP_REPEAT_2_158(m, d) m(3, 158, d)
+# define BOOST_PP_REPEAT_2_160(m, d) BOOST_PP_REPEAT_2_159(m, d) m(3, 159, d)
+# define BOOST_PP_REPEAT_2_161(m, d) BOOST_PP_REPEAT_2_160(m, d) m(3, 160, d)
+# define BOOST_PP_REPEAT_2_162(m, d) BOOST_PP_REPEAT_2_161(m, d) m(3, 161, d)
+# define BOOST_PP_REPEAT_2_163(m, d) BOOST_PP_REPEAT_2_162(m, d) m(3, 162, d)
+# define BOOST_PP_REPEAT_2_164(m, d) BOOST_PP_REPEAT_2_163(m, d) m(3, 163, d)
+# define BOOST_PP_REPEAT_2_165(m, d) BOOST_PP_REPEAT_2_164(m, d) m(3, 164, d)
+# define BOOST_PP_REPEAT_2_166(m, d) BOOST_PP_REPEAT_2_165(m, d) m(3, 165, d)
+# define BOOST_PP_REPEAT_2_167(m, d) BOOST_PP_REPEAT_2_166(m, d) m(3, 166, d)
+# define BOOST_PP_REPEAT_2_168(m, d) BOOST_PP_REPEAT_2_167(m, d) m(3, 167, d)
+# define BOOST_PP_REPEAT_2_169(m, d) BOOST_PP_REPEAT_2_168(m, d) m(3, 168, d)
+# define BOOST_PP_REPEAT_2_170(m, d) BOOST_PP_REPEAT_2_169(m, d) m(3, 169, d)
+# define BOOST_PP_REPEAT_2_171(m, d) BOOST_PP_REPEAT_2_170(m, d) m(3, 170, d)
+# define BOOST_PP_REPEAT_2_172(m, d) BOOST_PP_REPEAT_2_171(m, d) m(3, 171, d)
+# define BOOST_PP_REPEAT_2_173(m, d) BOOST_PP_REPEAT_2_172(m, d) m(3, 172, d)
+# define BOOST_PP_REPEAT_2_174(m, d) BOOST_PP_REPEAT_2_173(m, d) m(3, 173, d)
+# define BOOST_PP_REPEAT_2_175(m, d) BOOST_PP_REPEAT_2_174(m, d) m(3, 174, d)
+# define BOOST_PP_REPEAT_2_176(m, d) BOOST_PP_REPEAT_2_175(m, d) m(3, 175, d)
+# define BOOST_PP_REPEAT_2_177(m, d) BOOST_PP_REPEAT_2_176(m, d) m(3, 176, d)
+# define BOOST_PP_REPEAT_2_178(m, d) BOOST_PP_REPEAT_2_177(m, d) m(3, 177, d)
+# define BOOST_PP_REPEAT_2_179(m, d) BOOST_PP_REPEAT_2_178(m, d) m(3, 178, d)
+# define BOOST_PP_REPEAT_2_180(m, d) BOOST_PP_REPEAT_2_179(m, d) m(3, 179, d)
+# define BOOST_PP_REPEAT_2_181(m, d) BOOST_PP_REPEAT_2_180(m, d) m(3, 180, d)
+# define BOOST_PP_REPEAT_2_182(m, d) BOOST_PP_REPEAT_2_181(m, d) m(3, 181, d)
+# define BOOST_PP_REPEAT_2_183(m, d) BOOST_PP_REPEAT_2_182(m, d) m(3, 182, d)
+# define BOOST_PP_REPEAT_2_184(m, d) BOOST_PP_REPEAT_2_183(m, d) m(3, 183, d)
+# define BOOST_PP_REPEAT_2_185(m, d) BOOST_PP_REPEAT_2_184(m, d) m(3, 184, d)
+# define BOOST_PP_REPEAT_2_186(m, d) BOOST_PP_REPEAT_2_185(m, d) m(3, 185, d)
+# define BOOST_PP_REPEAT_2_187(m, d) BOOST_PP_REPEAT_2_186(m, d) m(3, 186, d)
+# define BOOST_PP_REPEAT_2_188(m, d) BOOST_PP_REPEAT_2_187(m, d) m(3, 187, d)
+# define BOOST_PP_REPEAT_2_189(m, d) BOOST_PP_REPEAT_2_188(m, d) m(3, 188, d)
+# define BOOST_PP_REPEAT_2_190(m, d) BOOST_PP_REPEAT_2_189(m, d) m(3, 189, d)
+# define BOOST_PP_REPEAT_2_191(m, d) BOOST_PP_REPEAT_2_190(m, d) m(3, 190, d)
+# define BOOST_PP_REPEAT_2_192(m, d) BOOST_PP_REPEAT_2_191(m, d) m(3, 191, d)
+# define BOOST_PP_REPEAT_2_193(m, d) BOOST_PP_REPEAT_2_192(m, d) m(3, 192, d)
+# define BOOST_PP_REPEAT_2_194(m, d) BOOST_PP_REPEAT_2_193(m, d) m(3, 193, d)
+# define BOOST_PP_REPEAT_2_195(m, d) BOOST_PP_REPEAT_2_194(m, d) m(3, 194, d)
+# define BOOST_PP_REPEAT_2_196(m, d) BOOST_PP_REPEAT_2_195(m, d) m(3, 195, d)
+# define BOOST_PP_REPEAT_2_197(m, d) BOOST_PP_REPEAT_2_196(m, d) m(3, 196, d)
+# define BOOST_PP_REPEAT_2_198(m, d) BOOST_PP_REPEAT_2_197(m, d) m(3, 197, d)
+# define BOOST_PP_REPEAT_2_199(m, d) BOOST_PP_REPEAT_2_198(m, d) m(3, 198, d)
+# define BOOST_PP_REPEAT_2_200(m, d) BOOST_PP_REPEAT_2_199(m, d) m(3, 199, d)
+# define BOOST_PP_REPEAT_2_201(m, d) BOOST_PP_REPEAT_2_200(m, d) m(3, 200, d)
+# define BOOST_PP_REPEAT_2_202(m, d) BOOST_PP_REPEAT_2_201(m, d) m(3, 201, d)
+# define BOOST_PP_REPEAT_2_203(m, d) BOOST_PP_REPEAT_2_202(m, d) m(3, 202, d)
+# define BOOST_PP_REPEAT_2_204(m, d) BOOST_PP_REPEAT_2_203(m, d) m(3, 203, d)
+# define BOOST_PP_REPEAT_2_205(m, d) BOOST_PP_REPEAT_2_204(m, d) m(3, 204, d)
+# define BOOST_PP_REPEAT_2_206(m, d) BOOST_PP_REPEAT_2_205(m, d) m(3, 205, d)
+# define BOOST_PP_REPEAT_2_207(m, d) BOOST_PP_REPEAT_2_206(m, d) m(3, 206, d)
+# define BOOST_PP_REPEAT_2_208(m, d) BOOST_PP_REPEAT_2_207(m, d) m(3, 207, d)
+# define BOOST_PP_REPEAT_2_209(m, d) BOOST_PP_REPEAT_2_208(m, d) m(3, 208, d)
+# define BOOST_PP_REPEAT_2_210(m, d) BOOST_PP_REPEAT_2_209(m, d) m(3, 209, d)
+# define BOOST_PP_REPEAT_2_211(m, d) BOOST_PP_REPEAT_2_210(m, d) m(3, 210, d)
+# define BOOST_PP_REPEAT_2_212(m, d) BOOST_PP_REPEAT_2_211(m, d) m(3, 211, d)
+# define BOOST_PP_REPEAT_2_213(m, d) BOOST_PP_REPEAT_2_212(m, d) m(3, 212, d)
+# define BOOST_PP_REPEAT_2_214(m, d) BOOST_PP_REPEAT_2_213(m, d) m(3, 213, d)
+# define BOOST_PP_REPEAT_2_215(m, d) BOOST_PP_REPEAT_2_214(m, d) m(3, 214, d)
+# define BOOST_PP_REPEAT_2_216(m, d) BOOST_PP_REPEAT_2_215(m, d) m(3, 215, d)
+# define BOOST_PP_REPEAT_2_217(m, d) BOOST_PP_REPEAT_2_216(m, d) m(3, 216, d)
+# define BOOST_PP_REPEAT_2_218(m, d) BOOST_PP_REPEAT_2_217(m, d) m(3, 217, d)
+# define BOOST_PP_REPEAT_2_219(m, d) BOOST_PP_REPEAT_2_218(m, d) m(3, 218, d)
+# define BOOST_PP_REPEAT_2_220(m, d) BOOST_PP_REPEAT_2_219(m, d) m(3, 219, d)
+# define BOOST_PP_REPEAT_2_221(m, d) BOOST_PP_REPEAT_2_220(m, d) m(3, 220, d)
+# define BOOST_PP_REPEAT_2_222(m, d) BOOST_PP_REPEAT_2_221(m, d) m(3, 221, d)
+# define BOOST_PP_REPEAT_2_223(m, d) BOOST_PP_REPEAT_2_222(m, d) m(3, 222, d)
+# define BOOST_PP_REPEAT_2_224(m, d) BOOST_PP_REPEAT_2_223(m, d) m(3, 223, d)
+# define BOOST_PP_REPEAT_2_225(m, d) BOOST_PP_REPEAT_2_224(m, d) m(3, 224, d)
+# define BOOST_PP_REPEAT_2_226(m, d) BOOST_PP_REPEAT_2_225(m, d) m(3, 225, d)
+# define BOOST_PP_REPEAT_2_227(m, d) BOOST_PP_REPEAT_2_226(m, d) m(3, 226, d)
+# define BOOST_PP_REPEAT_2_228(m, d) BOOST_PP_REPEAT_2_227(m, d) m(3, 227, d)
+# define BOOST_PP_REPEAT_2_229(m, d) BOOST_PP_REPEAT_2_228(m, d) m(3, 228, d)
+# define BOOST_PP_REPEAT_2_230(m, d) BOOST_PP_REPEAT_2_229(m, d) m(3, 229, d)
+# define BOOST_PP_REPEAT_2_231(m, d) BOOST_PP_REPEAT_2_230(m, d) m(3, 230, d)
+# define BOOST_PP_REPEAT_2_232(m, d) BOOST_PP_REPEAT_2_231(m, d) m(3, 231, d)
+# define BOOST_PP_REPEAT_2_233(m, d) BOOST_PP_REPEAT_2_232(m, d) m(3, 232, d)
+# define BOOST_PP_REPEAT_2_234(m, d) BOOST_PP_REPEAT_2_233(m, d) m(3, 233, d)
+# define BOOST_PP_REPEAT_2_235(m, d) BOOST_PP_REPEAT_2_234(m, d) m(3, 234, d)
+# define BOOST_PP_REPEAT_2_236(m, d) BOOST_PP_REPEAT_2_235(m, d) m(3, 235, d)
+# define BOOST_PP_REPEAT_2_237(m, d) BOOST_PP_REPEAT_2_236(m, d) m(3, 236, d)
+# define BOOST_PP_REPEAT_2_238(m, d) BOOST_PP_REPEAT_2_237(m, d) m(3, 237, d)
+# define BOOST_PP_REPEAT_2_239(m, d) BOOST_PP_REPEAT_2_238(m, d) m(3, 238, d)
+# define BOOST_PP_REPEAT_2_240(m, d) BOOST_PP_REPEAT_2_239(m, d) m(3, 239, d)
+# define BOOST_PP_REPEAT_2_241(m, d) BOOST_PP_REPEAT_2_240(m, d) m(3, 240, d)
+# define BOOST_PP_REPEAT_2_242(m, d) BOOST_PP_REPEAT_2_241(m, d) m(3, 241, d)
+# define BOOST_PP_REPEAT_2_243(m, d) BOOST_PP_REPEAT_2_242(m, d) m(3, 242, d)
+# define BOOST_PP_REPEAT_2_244(m, d) BOOST_PP_REPEAT_2_243(m, d) m(3, 243, d)
+# define BOOST_PP_REPEAT_2_245(m, d) BOOST_PP_REPEAT_2_244(m, d) m(3, 244, d)
+# define BOOST_PP_REPEAT_2_246(m, d) BOOST_PP_REPEAT_2_245(m, d) m(3, 245, d)
+# define BOOST_PP_REPEAT_2_247(m, d) BOOST_PP_REPEAT_2_246(m, d) m(3, 246, d)
+# define BOOST_PP_REPEAT_2_248(m, d) BOOST_PP_REPEAT_2_247(m, d) m(3, 247, d)
+# define BOOST_PP_REPEAT_2_249(m, d) BOOST_PP_REPEAT_2_248(m, d) m(3, 248, d)
+# define BOOST_PP_REPEAT_2_250(m, d) BOOST_PP_REPEAT_2_249(m, d) m(3, 249, d)
+# define BOOST_PP_REPEAT_2_251(m, d) BOOST_PP_REPEAT_2_250(m, d) m(3, 250, d)
+# define BOOST_PP_REPEAT_2_252(m, d) BOOST_PP_REPEAT_2_251(m, d) m(3, 251, d)
+# define BOOST_PP_REPEAT_2_253(m, d) BOOST_PP_REPEAT_2_252(m, d) m(3, 252, d)
+# define BOOST_PP_REPEAT_2_254(m, d) BOOST_PP_REPEAT_2_253(m, d) m(3, 253, d)
+# define BOOST_PP_REPEAT_2_255(m, d) BOOST_PP_REPEAT_2_254(m, d) m(3, 254, d)
+# define BOOST_PP_REPEAT_2_256(m, d) BOOST_PP_REPEAT_2_255(m, d) m(3, 255, d)
+#
+# define BOOST_PP_REPEAT_3_0(m, d)
+# define BOOST_PP_REPEAT_3_1(m, d) m(4, 0, d)
+# define BOOST_PP_REPEAT_3_2(m, d) BOOST_PP_REPEAT_3_1(m, d) m(4, 1, d)
+# define BOOST_PP_REPEAT_3_3(m, d) BOOST_PP_REPEAT_3_2(m, d) m(4, 2, d)
+# define BOOST_PP_REPEAT_3_4(m, d) BOOST_PP_REPEAT_3_3(m, d) m(4, 3, d)
+# define BOOST_PP_REPEAT_3_5(m, d) BOOST_PP_REPEAT_3_4(m, d) m(4, 4, d)
+# define BOOST_PP_REPEAT_3_6(m, d) BOOST_PP_REPEAT_3_5(m, d) m(4, 5, d)
+# define BOOST_PP_REPEAT_3_7(m, d) BOOST_PP_REPEAT_3_6(m, d) m(4, 6, d)
+# define BOOST_PP_REPEAT_3_8(m, d) BOOST_PP_REPEAT_3_7(m, d) m(4, 7, d)
+# define BOOST_PP_REPEAT_3_9(m, d) BOOST_PP_REPEAT_3_8(m, d) m(4, 8, d)
+# define BOOST_PP_REPEAT_3_10(m, d) BOOST_PP_REPEAT_3_9(m, d) m(4, 9, d)
+# define BOOST_PP_REPEAT_3_11(m, d) BOOST_PP_REPEAT_3_10(m, d) m(4, 10, d)
+# define BOOST_PP_REPEAT_3_12(m, d) BOOST_PP_REPEAT_3_11(m, d) m(4, 11, d)
+# define BOOST_PP_REPEAT_3_13(m, d) BOOST_PP_REPEAT_3_12(m, d) m(4, 12, d)
+# define BOOST_PP_REPEAT_3_14(m, d) BOOST_PP_REPEAT_3_13(m, d) m(4, 13, d)
+# define BOOST_PP_REPEAT_3_15(m, d) BOOST_PP_REPEAT_3_14(m, d) m(4, 14, d)
+# define BOOST_PP_REPEAT_3_16(m, d) BOOST_PP_REPEAT_3_15(m, d) m(4, 15, d)
+# define BOOST_PP_REPEAT_3_17(m, d) BOOST_PP_REPEAT_3_16(m, d) m(4, 16, d)
+# define BOOST_PP_REPEAT_3_18(m, d) BOOST_PP_REPEAT_3_17(m, d) m(4, 17, d)
+# define BOOST_PP_REPEAT_3_19(m, d) BOOST_PP_REPEAT_3_18(m, d) m(4, 18, d)
+# define BOOST_PP_REPEAT_3_20(m, d) BOOST_PP_REPEAT_3_19(m, d) m(4, 19, d)
+# define BOOST_PP_REPEAT_3_21(m, d) BOOST_PP_REPEAT_3_20(m, d) m(4, 20, d)
+# define BOOST_PP_REPEAT_3_22(m, d) BOOST_PP_REPEAT_3_21(m, d) m(4, 21, d)
+# define BOOST_PP_REPEAT_3_23(m, d) BOOST_PP_REPEAT_3_22(m, d) m(4, 22, d)
+# define BOOST_PP_REPEAT_3_24(m, d) BOOST_PP_REPEAT_3_23(m, d) m(4, 23, d)
+# define BOOST_PP_REPEAT_3_25(m, d) BOOST_PP_REPEAT_3_24(m, d) m(4, 24, d)
+# define BOOST_PP_REPEAT_3_26(m, d) BOOST_PP_REPEAT_3_25(m, d) m(4, 25, d)
+# define BOOST_PP_REPEAT_3_27(m, d) BOOST_PP_REPEAT_3_26(m, d) m(4, 26, d)
+# define BOOST_PP_REPEAT_3_28(m, d) BOOST_PP_REPEAT_3_27(m, d) m(4, 27, d)
+# define BOOST_PP_REPEAT_3_29(m, d) BOOST_PP_REPEAT_3_28(m, d) m(4, 28, d)
+# define BOOST_PP_REPEAT_3_30(m, d) BOOST_PP_REPEAT_3_29(m, d) m(4, 29, d)
+# define BOOST_PP_REPEAT_3_31(m, d) BOOST_PP_REPEAT_3_30(m, d) m(4, 30, d)
+# define BOOST_PP_REPEAT_3_32(m, d) BOOST_PP_REPEAT_3_31(m, d) m(4, 31, d)
+# define BOOST_PP_REPEAT_3_33(m, d) BOOST_PP_REPEAT_3_32(m, d) m(4, 32, d)
+# define BOOST_PP_REPEAT_3_34(m, d) BOOST_PP_REPEAT_3_33(m, d) m(4, 33, d)
+# define BOOST_PP_REPEAT_3_35(m, d) BOOST_PP_REPEAT_3_34(m, d) m(4, 34, d)
+# define BOOST_PP_REPEAT_3_36(m, d) BOOST_PP_REPEAT_3_35(m, d) m(4, 35, d)
+# define BOOST_PP_REPEAT_3_37(m, d) BOOST_PP_REPEAT_3_36(m, d) m(4, 36, d)
+# define BOOST_PP_REPEAT_3_38(m, d) BOOST_PP_REPEAT_3_37(m, d) m(4, 37, d)
+# define BOOST_PP_REPEAT_3_39(m, d) BOOST_PP_REPEAT_3_38(m, d) m(4, 38, d)
+# define BOOST_PP_REPEAT_3_40(m, d) BOOST_PP_REPEAT_3_39(m, d) m(4, 39, d)
+# define BOOST_PP_REPEAT_3_41(m, d) BOOST_PP_REPEAT_3_40(m, d) m(4, 40, d)
+# define BOOST_PP_REPEAT_3_42(m, d) BOOST_PP_REPEAT_3_41(m, d) m(4, 41, d)
+# define BOOST_PP_REPEAT_3_43(m, d) BOOST_PP_REPEAT_3_42(m, d) m(4, 42, d)
+# define BOOST_PP_REPEAT_3_44(m, d) BOOST_PP_REPEAT_3_43(m, d) m(4, 43, d)
+# define BOOST_PP_REPEAT_3_45(m, d) BOOST_PP_REPEAT_3_44(m, d) m(4, 44, d)
+# define BOOST_PP_REPEAT_3_46(m, d) BOOST_PP_REPEAT_3_45(m, d) m(4, 45, d)
+# define BOOST_PP_REPEAT_3_47(m, d) BOOST_PP_REPEAT_3_46(m, d) m(4, 46, d)
+# define BOOST_PP_REPEAT_3_48(m, d) BOOST_PP_REPEAT_3_47(m, d) m(4, 47, d)
+# define BOOST_PP_REPEAT_3_49(m, d) BOOST_PP_REPEAT_3_48(m, d) m(4, 48, d)
+# define BOOST_PP_REPEAT_3_50(m, d) BOOST_PP_REPEAT_3_49(m, d) m(4, 49, d)
+# define BOOST_PP_REPEAT_3_51(m, d) BOOST_PP_REPEAT_3_50(m, d) m(4, 50, d)
+# define BOOST_PP_REPEAT_3_52(m, d) BOOST_PP_REPEAT_3_51(m, d) m(4, 51, d)
+# define BOOST_PP_REPEAT_3_53(m, d) BOOST_PP_REPEAT_3_52(m, d) m(4, 52, d)
+# define BOOST_PP_REPEAT_3_54(m, d) BOOST_PP_REPEAT_3_53(m, d) m(4, 53, d)
+# define BOOST_PP_REPEAT_3_55(m, d) BOOST_PP_REPEAT_3_54(m, d) m(4, 54, d)
+# define BOOST_PP_REPEAT_3_56(m, d) BOOST_PP_REPEAT_3_55(m, d) m(4, 55, d)
+# define BOOST_PP_REPEAT_3_57(m, d) BOOST_PP_REPEAT_3_56(m, d) m(4, 56, d)
+# define BOOST_PP_REPEAT_3_58(m, d) BOOST_PP_REPEAT_3_57(m, d) m(4, 57, d)
+# define BOOST_PP_REPEAT_3_59(m, d) BOOST_PP_REPEAT_3_58(m, d) m(4, 58, d)
+# define BOOST_PP_REPEAT_3_60(m, d) BOOST_PP_REPEAT_3_59(m, d) m(4, 59, d)
+# define BOOST_PP_REPEAT_3_61(m, d) BOOST_PP_REPEAT_3_60(m, d) m(4, 60, d)
+# define BOOST_PP_REPEAT_3_62(m, d) BOOST_PP_REPEAT_3_61(m, d) m(4, 61, d)
+# define BOOST_PP_REPEAT_3_63(m, d) BOOST_PP_REPEAT_3_62(m, d) m(4, 62, d)
+# define BOOST_PP_REPEAT_3_64(m, d) BOOST_PP_REPEAT_3_63(m, d) m(4, 63, d)
+# define BOOST_PP_REPEAT_3_65(m, d) BOOST_PP_REPEAT_3_64(m, d) m(4, 64, d)
+# define BOOST_PP_REPEAT_3_66(m, d) BOOST_PP_REPEAT_3_65(m, d) m(4, 65, d)
+# define BOOST_PP_REPEAT_3_67(m, d) BOOST_PP_REPEAT_3_66(m, d) m(4, 66, d)
+# define BOOST_PP_REPEAT_3_68(m, d) BOOST_PP_REPEAT_3_67(m, d) m(4, 67, d)
+# define BOOST_PP_REPEAT_3_69(m, d) BOOST_PP_REPEAT_3_68(m, d) m(4, 68, d)
+# define BOOST_PP_REPEAT_3_70(m, d) BOOST_PP_REPEAT_3_69(m, d) m(4, 69, d)
+# define BOOST_PP_REPEAT_3_71(m, d) BOOST_PP_REPEAT_3_70(m, d) m(4, 70, d)
+# define BOOST_PP_REPEAT_3_72(m, d) BOOST_PP_REPEAT_3_71(m, d) m(4, 71, d)
+# define BOOST_PP_REPEAT_3_73(m, d) BOOST_PP_REPEAT_3_72(m, d) m(4, 72, d)
+# define BOOST_PP_REPEAT_3_74(m, d) BOOST_PP_REPEAT_3_73(m, d) m(4, 73, d)
+# define BOOST_PP_REPEAT_3_75(m, d) BOOST_PP_REPEAT_3_74(m, d) m(4, 74, d)
+# define BOOST_PP_REPEAT_3_76(m, d) BOOST_PP_REPEAT_3_75(m, d) m(4, 75, d)
+# define BOOST_PP_REPEAT_3_77(m, d) BOOST_PP_REPEAT_3_76(m, d) m(4, 76, d)
+# define BOOST_PP_REPEAT_3_78(m, d) BOOST_PP_REPEAT_3_77(m, d) m(4, 77, d)
+# define BOOST_PP_REPEAT_3_79(m, d) BOOST_PP_REPEAT_3_78(m, d) m(4, 78, d)
+# define BOOST_PP_REPEAT_3_80(m, d) BOOST_PP_REPEAT_3_79(m, d) m(4, 79, d)
+# define BOOST_PP_REPEAT_3_81(m, d) BOOST_PP_REPEAT_3_80(m, d) m(4, 80, d)
+# define BOOST_PP_REPEAT_3_82(m, d) BOOST_PP_REPEAT_3_81(m, d) m(4, 81, d)
+# define BOOST_PP_REPEAT_3_83(m, d) BOOST_PP_REPEAT_3_82(m, d) m(4, 82, d)
+# define BOOST_PP_REPEAT_3_84(m, d) BOOST_PP_REPEAT_3_83(m, d) m(4, 83, d)
+# define BOOST_PP_REPEAT_3_85(m, d) BOOST_PP_REPEAT_3_84(m, d) m(4, 84, d)
+# define BOOST_PP_REPEAT_3_86(m, d) BOOST_PP_REPEAT_3_85(m, d) m(4, 85, d)
+# define BOOST_PP_REPEAT_3_87(m, d) BOOST_PP_REPEAT_3_86(m, d) m(4, 86, d)
+# define BOOST_PP_REPEAT_3_88(m, d) BOOST_PP_REPEAT_3_87(m, d) m(4, 87, d)
+# define BOOST_PP_REPEAT_3_89(m, d) BOOST_PP_REPEAT_3_88(m, d) m(4, 88, d)
+# define BOOST_PP_REPEAT_3_90(m, d) BOOST_PP_REPEAT_3_89(m, d) m(4, 89, d)
+# define BOOST_PP_REPEAT_3_91(m, d) BOOST_PP_REPEAT_3_90(m, d) m(4, 90, d)
+# define BOOST_PP_REPEAT_3_92(m, d) BOOST_PP_REPEAT_3_91(m, d) m(4, 91, d)
+# define BOOST_PP_REPEAT_3_93(m, d) BOOST_PP_REPEAT_3_92(m, d) m(4, 92, d)
+# define BOOST_PP_REPEAT_3_94(m, d) BOOST_PP_REPEAT_3_93(m, d) m(4, 93, d)
+# define BOOST_PP_REPEAT_3_95(m, d) BOOST_PP_REPEAT_3_94(m, d) m(4, 94, d)
+# define BOOST_PP_REPEAT_3_96(m, d) BOOST_PP_REPEAT_3_95(m, d) m(4, 95, d)
+# define BOOST_PP_REPEAT_3_97(m, d) BOOST_PP_REPEAT_3_96(m, d) m(4, 96, d)
+# define BOOST_PP_REPEAT_3_98(m, d) BOOST_PP_REPEAT_3_97(m, d) m(4, 97, d)
+# define BOOST_PP_REPEAT_3_99(m, d) BOOST_PP_REPEAT_3_98(m, d) m(4, 98, d)
+# define BOOST_PP_REPEAT_3_100(m, d) BOOST_PP_REPEAT_3_99(m, d) m(4, 99, d)
+# define BOOST_PP_REPEAT_3_101(m, d) BOOST_PP_REPEAT_3_100(m, d) m(4, 100, d)
+# define BOOST_PP_REPEAT_3_102(m, d) BOOST_PP_REPEAT_3_101(m, d) m(4, 101, d)
+# define BOOST_PP_REPEAT_3_103(m, d) BOOST_PP_REPEAT_3_102(m, d) m(4, 102, d)
+# define BOOST_PP_REPEAT_3_104(m, d) BOOST_PP_REPEAT_3_103(m, d) m(4, 103, d)
+# define BOOST_PP_REPEAT_3_105(m, d) BOOST_PP_REPEAT_3_104(m, d) m(4, 104, d)
+# define BOOST_PP_REPEAT_3_106(m, d) BOOST_PP_REPEAT_3_105(m, d) m(4, 105, d)
+# define BOOST_PP_REPEAT_3_107(m, d) BOOST_PP_REPEAT_3_106(m, d) m(4, 106, d)
+# define BOOST_PP_REPEAT_3_108(m, d) BOOST_PP_REPEAT_3_107(m, d) m(4, 107, d)
+# define BOOST_PP_REPEAT_3_109(m, d) BOOST_PP_REPEAT_3_108(m, d) m(4, 108, d)
+# define BOOST_PP_REPEAT_3_110(m, d) BOOST_PP_REPEAT_3_109(m, d) m(4, 109, d)
+# define BOOST_PP_REPEAT_3_111(m, d) BOOST_PP_REPEAT_3_110(m, d) m(4, 110, d)
+# define BOOST_PP_REPEAT_3_112(m, d) BOOST_PP_REPEAT_3_111(m, d) m(4, 111, d)
+# define BOOST_PP_REPEAT_3_113(m, d) BOOST_PP_REPEAT_3_112(m, d) m(4, 112, d)
+# define BOOST_PP_REPEAT_3_114(m, d) BOOST_PP_REPEAT_3_113(m, d) m(4, 113, d)
+# define BOOST_PP_REPEAT_3_115(m, d) BOOST_PP_REPEAT_3_114(m, d) m(4, 114, d)
+# define BOOST_PP_REPEAT_3_116(m, d) BOOST_PP_REPEAT_3_115(m, d) m(4, 115, d)
+# define BOOST_PP_REPEAT_3_117(m, d) BOOST_PP_REPEAT_3_116(m, d) m(4, 116, d)
+# define BOOST_PP_REPEAT_3_118(m, d) BOOST_PP_REPEAT_3_117(m, d) m(4, 117, d)
+# define BOOST_PP_REPEAT_3_119(m, d) BOOST_PP_REPEAT_3_118(m, d) m(4, 118, d)
+# define BOOST_PP_REPEAT_3_120(m, d) BOOST_PP_REPEAT_3_119(m, d) m(4, 119, d)
+# define BOOST_PP_REPEAT_3_121(m, d) BOOST_PP_REPEAT_3_120(m, d) m(4, 120, d)
+# define BOOST_PP_REPEAT_3_122(m, d) BOOST_PP_REPEAT_3_121(m, d) m(4, 121, d)
+# define BOOST_PP_REPEAT_3_123(m, d) BOOST_PP_REPEAT_3_122(m, d) m(4, 122, d)
+# define BOOST_PP_REPEAT_3_124(m, d) BOOST_PP_REPEAT_3_123(m, d) m(4, 123, d)
+# define BOOST_PP_REPEAT_3_125(m, d) BOOST_PP_REPEAT_3_124(m, d) m(4, 124, d)
+# define BOOST_PP_REPEAT_3_126(m, d) BOOST_PP_REPEAT_3_125(m, d) m(4, 125, d)
+# define BOOST_PP_REPEAT_3_127(m, d) BOOST_PP_REPEAT_3_126(m, d) m(4, 126, d)
+# define BOOST_PP_REPEAT_3_128(m, d) BOOST_PP_REPEAT_3_127(m, d) m(4, 127, d)
+# define BOOST_PP_REPEAT_3_129(m, d) BOOST_PP_REPEAT_3_128(m, d) m(4, 128, d)
+# define BOOST_PP_REPEAT_3_130(m, d) BOOST_PP_REPEAT_3_129(m, d) m(4, 129, d)
+# define BOOST_PP_REPEAT_3_131(m, d) BOOST_PP_REPEAT_3_130(m, d) m(4, 130, d)
+# define BOOST_PP_REPEAT_3_132(m, d) BOOST_PP_REPEAT_3_131(m, d) m(4, 131, d)
+# define BOOST_PP_REPEAT_3_133(m, d) BOOST_PP_REPEAT_3_132(m, d) m(4, 132, d)
+# define BOOST_PP_REPEAT_3_134(m, d) BOOST_PP_REPEAT_3_133(m, d) m(4, 133, d)
+# define BOOST_PP_REPEAT_3_135(m, d) BOOST_PP_REPEAT_3_134(m, d) m(4, 134, d)
+# define BOOST_PP_REPEAT_3_136(m, d) BOOST_PP_REPEAT_3_135(m, d) m(4, 135, d)
+# define BOOST_PP_REPEAT_3_137(m, d) BOOST_PP_REPEAT_3_136(m, d) m(4, 136, d)
+# define BOOST_PP_REPEAT_3_138(m, d) BOOST_PP_REPEAT_3_137(m, d) m(4, 137, d)
+# define BOOST_PP_REPEAT_3_139(m, d) BOOST_PP_REPEAT_3_138(m, d) m(4, 138, d)
+# define BOOST_PP_REPEAT_3_140(m, d) BOOST_PP_REPEAT_3_139(m, d) m(4, 139, d)
+# define BOOST_PP_REPEAT_3_141(m, d) BOOST_PP_REPEAT_3_140(m, d) m(4, 140, d)
+# define BOOST_PP_REPEAT_3_142(m, d) BOOST_PP_REPEAT_3_141(m, d) m(4, 141, d)
+# define BOOST_PP_REPEAT_3_143(m, d) BOOST_PP_REPEAT_3_142(m, d) m(4, 142, d)
+# define BOOST_PP_REPEAT_3_144(m, d) BOOST_PP_REPEAT_3_143(m, d) m(4, 143, d)
+# define BOOST_PP_REPEAT_3_145(m, d) BOOST_PP_REPEAT_3_144(m, d) m(4, 144, d)
+# define BOOST_PP_REPEAT_3_146(m, d) BOOST_PP_REPEAT_3_145(m, d) m(4, 145, d)
+# define BOOST_PP_REPEAT_3_147(m, d) BOOST_PP_REPEAT_3_146(m, d) m(4, 146, d)
+# define BOOST_PP_REPEAT_3_148(m, d) BOOST_PP_REPEAT_3_147(m, d) m(4, 147, d)
+# define BOOST_PP_REPEAT_3_149(m, d) BOOST_PP_REPEAT_3_148(m, d) m(4, 148, d)
+# define BOOST_PP_REPEAT_3_150(m, d) BOOST_PP_REPEAT_3_149(m, d) m(4, 149, d)
+# define BOOST_PP_REPEAT_3_151(m, d) BOOST_PP_REPEAT_3_150(m, d) m(4, 150, d)
+# define BOOST_PP_REPEAT_3_152(m, d) BOOST_PP_REPEAT_3_151(m, d) m(4, 151, d)
+# define BOOST_PP_REPEAT_3_153(m, d) BOOST_PP_REPEAT_3_152(m, d) m(4, 152, d)
+# define BOOST_PP_REPEAT_3_154(m, d) BOOST_PP_REPEAT_3_153(m, d) m(4, 153, d)
+# define BOOST_PP_REPEAT_3_155(m, d) BOOST_PP_REPEAT_3_154(m, d) m(4, 154, d)
+# define BOOST_PP_REPEAT_3_156(m, d) BOOST_PP_REPEAT_3_155(m, d) m(4, 155, d)
+# define BOOST_PP_REPEAT_3_157(m, d) BOOST_PP_REPEAT_3_156(m, d) m(4, 156, d)
+# define BOOST_PP_REPEAT_3_158(m, d) BOOST_PP_REPEAT_3_157(m, d) m(4, 157, d)
+# define BOOST_PP_REPEAT_3_159(m, d) BOOST_PP_REPEAT_3_158(m, d) m(4, 158, d)
+# define BOOST_PP_REPEAT_3_160(m, d) BOOST_PP_REPEAT_3_159(m, d) m(4, 159, d)
+# define BOOST_PP_REPEAT_3_161(m, d) BOOST_PP_REPEAT_3_160(m, d) m(4, 160, d)
+# define BOOST_PP_REPEAT_3_162(m, d) BOOST_PP_REPEAT_3_161(m, d) m(4, 161, d)
+# define BOOST_PP_REPEAT_3_163(m, d) BOOST_PP_REPEAT_3_162(m, d) m(4, 162, d)
+# define BOOST_PP_REPEAT_3_164(m, d) BOOST_PP_REPEAT_3_163(m, d) m(4, 163, d)
+# define BOOST_PP_REPEAT_3_165(m, d) BOOST_PP_REPEAT_3_164(m, d) m(4, 164, d)
+# define BOOST_PP_REPEAT_3_166(m, d) BOOST_PP_REPEAT_3_165(m, d) m(4, 165, d)
+# define BOOST_PP_REPEAT_3_167(m, d) BOOST_PP_REPEAT_3_166(m, d) m(4, 166, d)
+# define BOOST_PP_REPEAT_3_168(m, d) BOOST_PP_REPEAT_3_167(m, d) m(4, 167, d)
+# define BOOST_PP_REPEAT_3_169(m, d) BOOST_PP_REPEAT_3_168(m, d) m(4, 168, d)
+# define BOOST_PP_REPEAT_3_170(m, d) BOOST_PP_REPEAT_3_169(m, d) m(4, 169, d)
+# define BOOST_PP_REPEAT_3_171(m, d) BOOST_PP_REPEAT_3_170(m, d) m(4, 170, d)
+# define BOOST_PP_REPEAT_3_172(m, d) BOOST_PP_REPEAT_3_171(m, d) m(4, 171, d)
+# define BOOST_PP_REPEAT_3_173(m, d) BOOST_PP_REPEAT_3_172(m, d) m(4, 172, d)
+# define BOOST_PP_REPEAT_3_174(m, d) BOOST_PP_REPEAT_3_173(m, d) m(4, 173, d)
+# define BOOST_PP_REPEAT_3_175(m, d) BOOST_PP_REPEAT_3_174(m, d) m(4, 174, d)
+# define BOOST_PP_REPEAT_3_176(m, d) BOOST_PP_REPEAT_3_175(m, d) m(4, 175, d)
+# define BOOST_PP_REPEAT_3_177(m, d) BOOST_PP_REPEAT_3_176(m, d) m(4, 176, d)
+# define BOOST_PP_REPEAT_3_178(m, d) BOOST_PP_REPEAT_3_177(m, d) m(4, 177, d)
+# define BOOST_PP_REPEAT_3_179(m, d) BOOST_PP_REPEAT_3_178(m, d) m(4, 178, d)
+# define BOOST_PP_REPEAT_3_180(m, d) BOOST_PP_REPEAT_3_179(m, d) m(4, 179, d)
+# define BOOST_PP_REPEAT_3_181(m, d) BOOST_PP_REPEAT_3_180(m, d) m(4, 180, d)
+# define BOOST_PP_REPEAT_3_182(m, d) BOOST_PP_REPEAT_3_181(m, d) m(4, 181, d)
+# define BOOST_PP_REPEAT_3_183(m, d) BOOST_PP_REPEAT_3_182(m, d) m(4, 182, d)
+# define BOOST_PP_REPEAT_3_184(m, d) BOOST_PP_REPEAT_3_183(m, d) m(4, 183, d)
+# define BOOST_PP_REPEAT_3_185(m, d) BOOST_PP_REPEAT_3_184(m, d) m(4, 184, d)
+# define BOOST_PP_REPEAT_3_186(m, d) BOOST_PP_REPEAT_3_185(m, d) m(4, 185, d)
+# define BOOST_PP_REPEAT_3_187(m, d) BOOST_PP_REPEAT_3_186(m, d) m(4, 186, d)
+# define BOOST_PP_REPEAT_3_188(m, d) BOOST_PP_REPEAT_3_187(m, d) m(4, 187, d)
+# define BOOST_PP_REPEAT_3_189(m, d) BOOST_PP_REPEAT_3_188(m, d) m(4, 188, d)
+# define BOOST_PP_REPEAT_3_190(m, d) BOOST_PP_REPEAT_3_189(m, d) m(4, 189, d)
+# define BOOST_PP_REPEAT_3_191(m, d) BOOST_PP_REPEAT_3_190(m, d) m(4, 190, d)
+# define BOOST_PP_REPEAT_3_192(m, d) BOOST_PP_REPEAT_3_191(m, d) m(4, 191, d)
+# define BOOST_PP_REPEAT_3_193(m, d) BOOST_PP_REPEAT_3_192(m, d) m(4, 192, d)
+# define BOOST_PP_REPEAT_3_194(m, d) BOOST_PP_REPEAT_3_193(m, d) m(4, 193, d)
+# define BOOST_PP_REPEAT_3_195(m, d) BOOST_PP_REPEAT_3_194(m, d) m(4, 194, d)
+# define BOOST_PP_REPEAT_3_196(m, d) BOOST_PP_REPEAT_3_195(m, d) m(4, 195, d)
+# define BOOST_PP_REPEAT_3_197(m, d) BOOST_PP_REPEAT_3_196(m, d) m(4, 196, d)
+# define BOOST_PP_REPEAT_3_198(m, d) BOOST_PP_REPEAT_3_197(m, d) m(4, 197, d)
+# define BOOST_PP_REPEAT_3_199(m, d) BOOST_PP_REPEAT_3_198(m, d) m(4, 198, d)
+# define BOOST_PP_REPEAT_3_200(m, d) BOOST_PP_REPEAT_3_199(m, d) m(4, 199, d)
+# define BOOST_PP_REPEAT_3_201(m, d) BOOST_PP_REPEAT_3_200(m, d) m(4, 200, d)
+# define BOOST_PP_REPEAT_3_202(m, d) BOOST_PP_REPEAT_3_201(m, d) m(4, 201, d)
+# define BOOST_PP_REPEAT_3_203(m, d) BOOST_PP_REPEAT_3_202(m, d) m(4, 202, d)
+# define BOOST_PP_REPEAT_3_204(m, d) BOOST_PP_REPEAT_3_203(m, d) m(4, 203, d)
+# define BOOST_PP_REPEAT_3_205(m, d) BOOST_PP_REPEAT_3_204(m, d) m(4, 204, d)
+# define BOOST_PP_REPEAT_3_206(m, d) BOOST_PP_REPEAT_3_205(m, d) m(4, 205, d)
+# define BOOST_PP_REPEAT_3_207(m, d) BOOST_PP_REPEAT_3_206(m, d) m(4, 206, d)
+# define BOOST_PP_REPEAT_3_208(m, d) BOOST_PP_REPEAT_3_207(m, d) m(4, 207, d)
+# define BOOST_PP_REPEAT_3_209(m, d) BOOST_PP_REPEAT_3_208(m, d) m(4, 208, d)
+# define BOOST_PP_REPEAT_3_210(m, d) BOOST_PP_REPEAT_3_209(m, d) m(4, 209, d)
+# define BOOST_PP_REPEAT_3_211(m, d) BOOST_PP_REPEAT_3_210(m, d) m(4, 210, d)
+# define BOOST_PP_REPEAT_3_212(m, d) BOOST_PP_REPEAT_3_211(m, d) m(4, 211, d)
+# define BOOST_PP_REPEAT_3_213(m, d) BOOST_PP_REPEAT_3_212(m, d) m(4, 212, d)
+# define BOOST_PP_REPEAT_3_214(m, d) BOOST_PP_REPEAT_3_213(m, d) m(4, 213, d)
+# define BOOST_PP_REPEAT_3_215(m, d) BOOST_PP_REPEAT_3_214(m, d) m(4, 214, d)
+# define BOOST_PP_REPEAT_3_216(m, d) BOOST_PP_REPEAT_3_215(m, d) m(4, 215, d)
+# define BOOST_PP_REPEAT_3_217(m, d) BOOST_PP_REPEAT_3_216(m, d) m(4, 216, d)
+# define BOOST_PP_REPEAT_3_218(m, d) BOOST_PP_REPEAT_3_217(m, d) m(4, 217, d)
+# define BOOST_PP_REPEAT_3_219(m, d) BOOST_PP_REPEAT_3_218(m, d) m(4, 218, d)
+# define BOOST_PP_REPEAT_3_220(m, d) BOOST_PP_REPEAT_3_219(m, d) m(4, 219, d)
+# define BOOST_PP_REPEAT_3_221(m, d) BOOST_PP_REPEAT_3_220(m, d) m(4, 220, d)
+# define BOOST_PP_REPEAT_3_222(m, d) BOOST_PP_REPEAT_3_221(m, d) m(4, 221, d)
+# define BOOST_PP_REPEAT_3_223(m, d) BOOST_PP_REPEAT_3_222(m, d) m(4, 222, d)
+# define BOOST_PP_REPEAT_3_224(m, d) BOOST_PP_REPEAT_3_223(m, d) m(4, 223, d)
+# define BOOST_PP_REPEAT_3_225(m, d) BOOST_PP_REPEAT_3_224(m, d) m(4, 224, d)
+# define BOOST_PP_REPEAT_3_226(m, d) BOOST_PP_REPEAT_3_225(m, d) m(4, 225, d)
+# define BOOST_PP_REPEAT_3_227(m, d) BOOST_PP_REPEAT_3_226(m, d) m(4, 226, d)
+# define BOOST_PP_REPEAT_3_228(m, d) BOOST_PP_REPEAT_3_227(m, d) m(4, 227, d)
+# define BOOST_PP_REPEAT_3_229(m, d) BOOST_PP_REPEAT_3_228(m, d) m(4, 228, d)
+# define BOOST_PP_REPEAT_3_230(m, d) BOOST_PP_REPEAT_3_229(m, d) m(4, 229, d)
+# define BOOST_PP_REPEAT_3_231(m, d) BOOST_PP_REPEAT_3_230(m, d) m(4, 230, d)
+# define BOOST_PP_REPEAT_3_232(m, d) BOOST_PP_REPEAT_3_231(m, d) m(4, 231, d)
+# define BOOST_PP_REPEAT_3_233(m, d) BOOST_PP_REPEAT_3_232(m, d) m(4, 232, d)
+# define BOOST_PP_REPEAT_3_234(m, d) BOOST_PP_REPEAT_3_233(m, d) m(4, 233, d)
+# define BOOST_PP_REPEAT_3_235(m, d) BOOST_PP_REPEAT_3_234(m, d) m(4, 234, d)
+# define BOOST_PP_REPEAT_3_236(m, d) BOOST_PP_REPEAT_3_235(m, d) m(4, 235, d)
+# define BOOST_PP_REPEAT_3_237(m, d) BOOST_PP_REPEAT_3_236(m, d) m(4, 236, d)
+# define BOOST_PP_REPEAT_3_238(m, d) BOOST_PP_REPEAT_3_237(m, d) m(4, 237, d)
+# define BOOST_PP_REPEAT_3_239(m, d) BOOST_PP_REPEAT_3_238(m, d) m(4, 238, d)
+# define BOOST_PP_REPEAT_3_240(m, d) BOOST_PP_REPEAT_3_239(m, d) m(4, 239, d)
+# define BOOST_PP_REPEAT_3_241(m, d) BOOST_PP_REPEAT_3_240(m, d) m(4, 240, d)
+# define BOOST_PP_REPEAT_3_242(m, d) BOOST_PP_REPEAT_3_241(m, d) m(4, 241, d)
+# define BOOST_PP_REPEAT_3_243(m, d) BOOST_PP_REPEAT_3_242(m, d) m(4, 242, d)
+# define BOOST_PP_REPEAT_3_244(m, d) BOOST_PP_REPEAT_3_243(m, d) m(4, 243, d)
+# define BOOST_PP_REPEAT_3_245(m, d) BOOST_PP_REPEAT_3_244(m, d) m(4, 244, d)
+# define BOOST_PP_REPEAT_3_246(m, d) BOOST_PP_REPEAT_3_245(m, d) m(4, 245, d)
+# define BOOST_PP_REPEAT_3_247(m, d) BOOST_PP_REPEAT_3_246(m, d) m(4, 246, d)
+# define BOOST_PP_REPEAT_3_248(m, d) BOOST_PP_REPEAT_3_247(m, d) m(4, 247, d)
+# define BOOST_PP_REPEAT_3_249(m, d) BOOST_PP_REPEAT_3_248(m, d) m(4, 248, d)
+# define BOOST_PP_REPEAT_3_250(m, d) BOOST_PP_REPEAT_3_249(m, d) m(4, 249, d)
+# define BOOST_PP_REPEAT_3_251(m, d) BOOST_PP_REPEAT_3_250(m, d) m(4, 250, d)
+# define BOOST_PP_REPEAT_3_252(m, d) BOOST_PP_REPEAT_3_251(m, d) m(4, 251, d)
+# define BOOST_PP_REPEAT_3_253(m, d) BOOST_PP_REPEAT_3_252(m, d) m(4, 252, d)
+# define BOOST_PP_REPEAT_3_254(m, d) BOOST_PP_REPEAT_3_253(m, d) m(4, 253, d)
+# define BOOST_PP_REPEAT_3_255(m, d) BOOST_PP_REPEAT_3_254(m, d) m(4, 254, d)
+# define BOOST_PP_REPEAT_3_256(m, d) BOOST_PP_REPEAT_3_255(m, d) m(4, 255, d)
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/repetition/repeat_from_to.hpp b/third_party/boost/boost/preprocessor/repetition/repeat_from_to.hpp
new file mode 100644
index 0000000..efe539e
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/repetition/repeat_from_to.hpp
@@ -0,0 +1,87 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_REPETITION_REPEAT_FROM_TO_HPP
+# define BOOST_PREPROCESSOR_REPETITION_REPEAT_FROM_TO_HPP
+#
+# include <boost/preprocessor/arithmetic/add.hpp>
+# include <boost/preprocessor/arithmetic/sub.hpp>
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/control/while.hpp>
+# include <boost/preprocessor/debug/error.hpp>
+# include <boost/preprocessor/detail/auto_rec.hpp>
+# include <boost/preprocessor/repetition/repeat.hpp>
+# include <boost/preprocessor/tuple/elem.hpp>
+# include <boost/preprocessor/tuple/rem.hpp>
+#
+# /* BOOST_PP_REPEAT_FROM_TO */
+#
+# if 0
+#    define BOOST_PP_REPEAT_FROM_TO(first, last, macro, data)
+# endif
+#
+# define BOOST_PP_REPEAT_FROM_TO BOOST_PP_CAT(BOOST_PP_REPEAT_FROM_TO_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4))
+#
+# define BOOST_PP_REPEAT_FROM_TO_1(f, l, m, dt) BOOST_PP_REPEAT_FROM_TO_D_1(BOOST_PP_AUTO_REC(BOOST_PP_WHILE_P, 256), f, l, m, dt)
+# define BOOST_PP_REPEAT_FROM_TO_2(f, l, m, dt) BOOST_PP_REPEAT_FROM_TO_D_2(BOOST_PP_AUTO_REC(BOOST_PP_WHILE_P, 256), f, l, m, dt)
+# define BOOST_PP_REPEAT_FROM_TO_3(f, l, m, dt) BOOST_PP_REPEAT_FROM_TO_D_3(BOOST_PP_AUTO_REC(BOOST_PP_WHILE_P, 256), f, l, m, dt)
+# define BOOST_PP_REPEAT_FROM_TO_4(f, l, m, dt) BOOST_PP_ERROR(0x0003)
+#
+# define BOOST_PP_REPEAT_FROM_TO_1ST BOOST_PP_REPEAT_FROM_TO_1
+# define BOOST_PP_REPEAT_FROM_TO_2ND BOOST_PP_REPEAT_FROM_TO_2
+# define BOOST_PP_REPEAT_FROM_TO_3RD BOOST_PP_REPEAT_FROM_TO_3
+#
+# /* BOOST_PP_REPEAT_FROM_TO_D */
+#
+# if 0
+#    define BOOST_PP_REPEAT_FROM_TO_D(d, first, last, macro, data)
+# endif
+#
+# define BOOST_PP_REPEAT_FROM_TO_D BOOST_PP_CAT(BOOST_PP_REPEAT_FROM_TO_D_, BOOST_PP_AUTO_REC(BOOST_PP_REPEAT_P, 4))
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#    define BOOST_PP_REPEAT_FROM_TO_D_1(d, f, l, m, dt) BOOST_PP_REPEAT_1(BOOST_PP_SUB_D(d, l, f), BOOST_PP_REPEAT_FROM_TO_M_1, (d, f, m, dt))
+#    define BOOST_PP_REPEAT_FROM_TO_D_2(d, f, l, m, dt) BOOST_PP_REPEAT_2(BOOST_PP_SUB_D(d, l, f), BOOST_PP_REPEAT_FROM_TO_M_2, (d, f, m, dt))
+#    define BOOST_PP_REPEAT_FROM_TO_D_3(d, f, l, m, dt) BOOST_PP_REPEAT_3(BOOST_PP_SUB_D(d, l, f), BOOST_PP_REPEAT_FROM_TO_M_3, (d, f, m, dt))
+# else
+#    define BOOST_PP_REPEAT_FROM_TO_D_1(d, f, l, m, dt) BOOST_PP_REPEAT_FROM_TO_D_1_I(d, f, l, m, dt)
+#    define BOOST_PP_REPEAT_FROM_TO_D_2(d, f, l, m, dt) BOOST_PP_REPEAT_FROM_TO_D_2_I(d, f, l, m, dt)
+#    define BOOST_PP_REPEAT_FROM_TO_D_3(d, f, l, m, dt) BOOST_PP_REPEAT_FROM_TO_D_3_I(d, f, l, m, dt)
+#    define BOOST_PP_REPEAT_FROM_TO_D_1_I(d, f, l, m, dt) BOOST_PP_REPEAT_1(BOOST_PP_SUB_D(d, l, f), BOOST_PP_REPEAT_FROM_TO_M_1, (d, f, m, dt))
+#    define BOOST_PP_REPEAT_FROM_TO_D_2_I(d, f, l, m, dt) BOOST_PP_REPEAT_2(BOOST_PP_SUB_D(d, l, f), BOOST_PP_REPEAT_FROM_TO_M_2, (d, f, m, dt))
+#    define BOOST_PP_REPEAT_FROM_TO_D_3_I(d, f, l, m, dt) BOOST_PP_REPEAT_3(BOOST_PP_SUB_D(d, l, f), BOOST_PP_REPEAT_FROM_TO_M_3, (d, f, m, dt))
+# endif
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_STRICT()
+#    define BOOST_PP_REPEAT_FROM_TO_M_1(z, n, dfmd) BOOST_PP_REPEAT_FROM_TO_M_1_IM(z, n, BOOST_PP_TUPLE_REM_4 dfmd)
+#    define BOOST_PP_REPEAT_FROM_TO_M_2(z, n, dfmd) BOOST_PP_REPEAT_FROM_TO_M_2_IM(z, n, BOOST_PP_TUPLE_REM_4 dfmd)
+#    define BOOST_PP_REPEAT_FROM_TO_M_3(z, n, dfmd) BOOST_PP_REPEAT_FROM_TO_M_3_IM(z, n, BOOST_PP_TUPLE_REM_4 dfmd)
+#    define BOOST_PP_REPEAT_FROM_TO_M_1_IM(z, n, im) BOOST_PP_REPEAT_FROM_TO_M_1_I(z, n, im)
+#    define BOOST_PP_REPEAT_FROM_TO_M_2_IM(z, n, im) BOOST_PP_REPEAT_FROM_TO_M_2_I(z, n, im)
+#    define BOOST_PP_REPEAT_FROM_TO_M_3_IM(z, n, im) BOOST_PP_REPEAT_FROM_TO_M_3_I(z, n, im)
+# else
+#    define BOOST_PP_REPEAT_FROM_TO_M_1(z, n, dfmd) BOOST_PP_REPEAT_FROM_TO_M_1_I(z, n, BOOST_PP_TUPLE_ELEM(4, 0, dfmd), BOOST_PP_TUPLE_ELEM(4, 1, dfmd), BOOST_PP_TUPLE_ELEM(4, 2, dfmd), BOOST_PP_TUPLE_ELEM(4, 3, dfmd))
+#    define BOOST_PP_REPEAT_FROM_TO_M_2(z, n, dfmd) BOOST_PP_REPEAT_FROM_TO_M_2_I(z, n, BOOST_PP_TUPLE_ELEM(4, 0, dfmd), BOOST_PP_TUPLE_ELEM(4, 1, dfmd), BOOST_PP_TUPLE_ELEM(4, 2, dfmd), BOOST_PP_TUPLE_ELEM(4, 3, dfmd))
+#    define BOOST_PP_REPEAT_FROM_TO_M_3(z, n, dfmd) BOOST_PP_REPEAT_FROM_TO_M_3_I(z, n, BOOST_PP_TUPLE_ELEM(4, 0, dfmd), BOOST_PP_TUPLE_ELEM(4, 1, dfmd), BOOST_PP_TUPLE_ELEM(4, 2, dfmd), BOOST_PP_TUPLE_ELEM(4, 3, dfmd))
+# endif
+#
+# define BOOST_PP_REPEAT_FROM_TO_M_1_I(z, n, d, f, m, dt) BOOST_PP_REPEAT_FROM_TO_M_1_II(z, BOOST_PP_ADD_D(d, n, f), m, dt)
+# define BOOST_PP_REPEAT_FROM_TO_M_2_I(z, n, d, f, m, dt) BOOST_PP_REPEAT_FROM_TO_M_2_II(z, BOOST_PP_ADD_D(d, n, f), m, dt)
+# define BOOST_PP_REPEAT_FROM_TO_M_3_I(z, n, d, f, m, dt) BOOST_PP_REPEAT_FROM_TO_M_3_II(z, BOOST_PP_ADD_D(d, n, f), m, dt)
+#
+# define BOOST_PP_REPEAT_FROM_TO_M_1_II(z, n, m, dt) m(z, n, dt)
+# define BOOST_PP_REPEAT_FROM_TO_M_2_II(z, n, m, dt) m(z, n, dt)
+# define BOOST_PP_REPEAT_FROM_TO_M_3_II(z, n, m, dt) m(z, n, dt)
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/slot/detail/def.hpp b/third_party/boost/boost/preprocessor/slot/detail/def.hpp
new file mode 100644
index 0000000..885099e
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/slot/detail/def.hpp
@@ -0,0 +1,49 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_SLOT_DETAIL_DEF_HPP
+# define BOOST_PREPROCESSOR_SLOT_DETAIL_DEF_HPP
+#
+# /* BOOST_PP_SLOT_OFFSET_x */
+#
+# define BOOST_PP_SLOT_OFFSET_10(x) (x) % 1000000000UL
+# define BOOST_PP_SLOT_OFFSET_9(x) BOOST_PP_SLOT_OFFSET_10(x) % 100000000UL
+# define BOOST_PP_SLOT_OFFSET_8(x) BOOST_PP_SLOT_OFFSET_9(x) % 10000000UL
+# define BOOST_PP_SLOT_OFFSET_7(x) BOOST_PP_SLOT_OFFSET_8(x) % 1000000UL
+# define BOOST_PP_SLOT_OFFSET_6(x) BOOST_PP_SLOT_OFFSET_7(x) % 100000UL
+# define BOOST_PP_SLOT_OFFSET_5(x) BOOST_PP_SLOT_OFFSET_6(x) % 10000UL
+# define BOOST_PP_SLOT_OFFSET_4(x) BOOST_PP_SLOT_OFFSET_5(x) % 1000UL
+# define BOOST_PP_SLOT_OFFSET_3(x) BOOST_PP_SLOT_OFFSET_4(x) % 100UL
+# define BOOST_PP_SLOT_OFFSET_2(x) BOOST_PP_SLOT_OFFSET_3(x) % 10UL
+#
+# /* BOOST_PP_SLOT_CC_x */
+#
+# define BOOST_PP_SLOT_CC_2(a, b) BOOST_PP_SLOT_CC_2_D(a, b)
+# define BOOST_PP_SLOT_CC_3(a, b, c) BOOST_PP_SLOT_CC_3_D(a, b, c)
+# define BOOST_PP_SLOT_CC_4(a, b, c, d) BOOST_PP_SLOT_CC_4_D(a, b, c, d)
+# define BOOST_PP_SLOT_CC_5(a, b, c, d, e) BOOST_PP_SLOT_CC_5_D(a, b, c, d, e)
+# define BOOST_PP_SLOT_CC_6(a, b, c, d, e, f) BOOST_PP_SLOT_CC_6_D(a, b, c, d, e, f)
+# define BOOST_PP_SLOT_CC_7(a, b, c, d, e, f, g) BOOST_PP_SLOT_CC_7_D(a, b, c, d, e, f, g)
+# define BOOST_PP_SLOT_CC_8(a, b, c, d, e, f, g, h) BOOST_PP_SLOT_CC_8_D(a, b, c, d, e, f, g, h)
+# define BOOST_PP_SLOT_CC_9(a, b, c, d, e, f, g, h, i) BOOST_PP_SLOT_CC_9_D(a, b, c, d, e, f, g, h, i)
+# define BOOST_PP_SLOT_CC_10(a, b, c, d, e, f, g, h, i, j) BOOST_PP_SLOT_CC_10_D(a, b, c, d, e, f, g, h, i, j)
+#
+# define BOOST_PP_SLOT_CC_2_D(a, b) a ## b
+# define BOOST_PP_SLOT_CC_3_D(a, b, c) a ## b ## c
+# define BOOST_PP_SLOT_CC_4_D(a, b, c, d) a ## b ## c ## d
+# define BOOST_PP_SLOT_CC_5_D(a, b, c, d, e) a ## b ## c ## d ## e
+# define BOOST_PP_SLOT_CC_6_D(a, b, c, d, e, f) a ## b ## c ## d ## e ## f
+# define BOOST_PP_SLOT_CC_7_D(a, b, c, d, e, f, g) a ## b ## c ## d ## e ## f ## g
+# define BOOST_PP_SLOT_CC_8_D(a, b, c, d, e, f, g, h) a ## b ## c ## d ## e ## f ## g ## h
+# define BOOST_PP_SLOT_CC_9_D(a, b, c, d, e, f, g, h, i) a ## b ## c ## d ## e ## f ## g ## h ## i
+# define BOOST_PP_SLOT_CC_10_D(a, b, c, d, e, f, g, h, i, j) a ## b ## c ## d ## e ## f ## g ## h ## i ## j
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/slot/detail/shared.hpp b/third_party/boost/boost/preprocessor/slot/detail/shared.hpp
new file mode 100644
index 0000000..c97ac54
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/slot/detail/shared.hpp
@@ -0,0 +1,247 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PP_VALUE
+#    error BOOST_PP_ERROR:  BOOST_PP_VALUE is not defined
+# endif
+#
+# undef BOOST_PP_SLOT_TEMP_1
+# undef BOOST_PP_SLOT_TEMP_2
+# undef BOOST_PP_SLOT_TEMP_3
+# undef BOOST_PP_SLOT_TEMP_4
+# undef BOOST_PP_SLOT_TEMP_5
+# undef BOOST_PP_SLOT_TEMP_6
+# undef BOOST_PP_SLOT_TEMP_7
+# undef BOOST_PP_SLOT_TEMP_8
+# undef BOOST_PP_SLOT_TEMP_9
+# undef BOOST_PP_SLOT_TEMP_10
+#
+# if (BOOST_PP_VALUE) / 1000000000UL == 0
+#    define BOOST_PP_SLOT_TEMP_10 0
+# elif (BOOST_PP_VALUE) / 1000000000UL == 1
+#    define BOOST_PP_SLOT_TEMP_10 1
+# elif (BOOST_PP_VALUE) / 1000000000UL == 2
+#    define BOOST_PP_SLOT_TEMP_10 2
+# elif (BOOST_PP_VALUE) / 1000000000UL == 3
+#    define BOOST_PP_SLOT_TEMP_10 3
+# elif (BOOST_PP_VALUE) / 1000000000UL == 4
+#    define BOOST_PP_SLOT_TEMP_10 4
+# elif (BOOST_PP_VALUE) / 1000000000UL == 5
+#    define BOOST_PP_SLOT_TEMP_10 5
+# elif (BOOST_PP_VALUE) / 1000000000UL == 6
+#    define BOOST_PP_SLOT_TEMP_10 6
+# elif (BOOST_PP_VALUE) / 1000000000UL == 7
+#    define BOOST_PP_SLOT_TEMP_10 7
+# elif (BOOST_PP_VALUE) / 1000000000UL == 8
+#    define BOOST_PP_SLOT_TEMP_10 8
+# elif (BOOST_PP_VALUE) / 1000000000UL == 9
+#    define BOOST_PP_SLOT_TEMP_10 9
+# endif
+#
+# if BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 0
+#    define BOOST_PP_SLOT_TEMP_9 0
+# elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 1
+#    define BOOST_PP_SLOT_TEMP_9 1
+# elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 2
+#    define BOOST_PP_SLOT_TEMP_9 2
+# elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 3
+#    define BOOST_PP_SLOT_TEMP_9 3
+# elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 4
+#    define BOOST_PP_SLOT_TEMP_9 4
+# elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 5
+#    define BOOST_PP_SLOT_TEMP_9 5
+# elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 6
+#    define BOOST_PP_SLOT_TEMP_9 6
+# elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 7
+#    define BOOST_PP_SLOT_TEMP_9 7
+# elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 8
+#    define BOOST_PP_SLOT_TEMP_9 8
+# elif BOOST_PP_SLOT_OFFSET_10(BOOST_PP_VALUE) / 100000000UL == 9
+#    define BOOST_PP_SLOT_TEMP_9 9
+# endif
+#
+# if BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 0
+#    define BOOST_PP_SLOT_TEMP_8 0
+# elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 1
+#    define BOOST_PP_SLOT_TEMP_8 1
+# elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 2
+#    define BOOST_PP_SLOT_TEMP_8 2
+# elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 3
+#    define BOOST_PP_SLOT_TEMP_8 3
+# elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 4
+#    define BOOST_PP_SLOT_TEMP_8 4
+# elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 5
+#    define BOOST_PP_SLOT_TEMP_8 5
+# elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 6
+#    define BOOST_PP_SLOT_TEMP_8 6
+# elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 7
+#    define BOOST_PP_SLOT_TEMP_8 7
+# elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 8
+#    define BOOST_PP_SLOT_TEMP_8 8
+# elif BOOST_PP_SLOT_OFFSET_9(BOOST_PP_VALUE) / 10000000UL == 9
+#    define BOOST_PP_SLOT_TEMP_8 9
+# endif
+#
+# if BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 0
+#    define BOOST_PP_SLOT_TEMP_7 0
+# elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 1
+#    define BOOST_PP_SLOT_TEMP_7 1
+# elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 2
+#    define BOOST_PP_SLOT_TEMP_7 2
+# elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 3
+#    define BOOST_PP_SLOT_TEMP_7 3
+# elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 4
+#    define BOOST_PP_SLOT_TEMP_7 4
+# elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 5
+#    define BOOST_PP_SLOT_TEMP_7 5
+# elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 6
+#    define BOOST_PP_SLOT_TEMP_7 6
+# elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 7
+#    define BOOST_PP_SLOT_TEMP_7 7
+# elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 8
+#    define BOOST_PP_SLOT_TEMP_7 8
+# elif BOOST_PP_SLOT_OFFSET_8(BOOST_PP_VALUE) / 1000000UL == 9
+#    define BOOST_PP_SLOT_TEMP_7 9
+# endif
+#
+# if BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 0
+#    define BOOST_PP_SLOT_TEMP_6 0
+# elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 1
+#    define BOOST_PP_SLOT_TEMP_6 1
+# elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 2
+#    define BOOST_PP_SLOT_TEMP_6 2
+# elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 3
+#    define BOOST_PP_SLOT_TEMP_6 3
+# elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 4
+#    define BOOST_PP_SLOT_TEMP_6 4
+# elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 5
+#    define BOOST_PP_SLOT_TEMP_6 5
+# elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 6
+#    define BOOST_PP_SLOT_TEMP_6 6
+# elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 7
+#    define BOOST_PP_SLOT_TEMP_6 7
+# elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 8
+#    define BOOST_PP_SLOT_TEMP_6 8
+# elif BOOST_PP_SLOT_OFFSET_7(BOOST_PP_VALUE) / 100000UL == 9
+#    define BOOST_PP_SLOT_TEMP_6 9
+# endif
+#
+# if BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 0
+#    define BOOST_PP_SLOT_TEMP_5 0
+# elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 1
+#    define BOOST_PP_SLOT_TEMP_5 1
+# elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 2
+#    define BOOST_PP_SLOT_TEMP_5 2
+# elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 3
+#    define BOOST_PP_SLOT_TEMP_5 3
+# elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 4
+#    define BOOST_PP_SLOT_TEMP_5 4
+# elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 5
+#    define BOOST_PP_SLOT_TEMP_5 5
+# elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 6
+#    define BOOST_PP_SLOT_TEMP_5 6
+# elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 7
+#    define BOOST_PP_SLOT_TEMP_5 7
+# elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 8
+#    define BOOST_PP_SLOT_TEMP_5 8
+# elif BOOST_PP_SLOT_OFFSET_6(BOOST_PP_VALUE) / 10000UL == 9
+#    define BOOST_PP_SLOT_TEMP_5 9
+# endif
+#
+# if BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 0
+#    define BOOST_PP_SLOT_TEMP_4 0
+# elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 1
+#    define BOOST_PP_SLOT_TEMP_4 1
+# elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 2
+#    define BOOST_PP_SLOT_TEMP_4 2
+# elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 3
+#    define BOOST_PP_SLOT_TEMP_4 3
+# elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 4
+#    define BOOST_PP_SLOT_TEMP_4 4
+# elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 5
+#    define BOOST_PP_SLOT_TEMP_4 5
+# elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 6
+#    define BOOST_PP_SLOT_TEMP_4 6
+# elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 7
+#    define BOOST_PP_SLOT_TEMP_4 7
+# elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 8
+#    define BOOST_PP_SLOT_TEMP_4 8
+# elif BOOST_PP_SLOT_OFFSET_5(BOOST_PP_VALUE) / 1000UL == 9
+#    define BOOST_PP_SLOT_TEMP_4 9
+# endif
+#
+# if BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 0
+#    define BOOST_PP_SLOT_TEMP_3 0
+# elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 1
+#    define BOOST_PP_SLOT_TEMP_3 1
+# elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 2
+#    define BOOST_PP_SLOT_TEMP_3 2
+# elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 3
+#    define BOOST_PP_SLOT_TEMP_3 3
+# elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 4
+#    define BOOST_PP_SLOT_TEMP_3 4
+# elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 5
+#    define BOOST_PP_SLOT_TEMP_3 5
+# elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 6
+#    define BOOST_PP_SLOT_TEMP_3 6
+# elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 7
+#    define BOOST_PP_SLOT_TEMP_3 7
+# elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 8
+#    define BOOST_PP_SLOT_TEMP_3 8
+# elif BOOST_PP_SLOT_OFFSET_4(BOOST_PP_VALUE) / 100UL == 9
+#    define BOOST_PP_SLOT_TEMP_3 9
+# endif
+#
+# if BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 0
+#    define BOOST_PP_SLOT_TEMP_2 0
+# elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 1
+#    define BOOST_PP_SLOT_TEMP_2 1
+# elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 2
+#    define BOOST_PP_SLOT_TEMP_2 2
+# elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 3
+#    define BOOST_PP_SLOT_TEMP_2 3
+# elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 4
+#    define BOOST_PP_SLOT_TEMP_2 4
+# elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 5
+#    define BOOST_PP_SLOT_TEMP_2 5
+# elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 6
+#    define BOOST_PP_SLOT_TEMP_2 6
+# elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 7
+#    define BOOST_PP_SLOT_TEMP_2 7
+# elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 8
+#    define BOOST_PP_SLOT_TEMP_2 8
+# elif BOOST_PP_SLOT_OFFSET_3(BOOST_PP_VALUE) / 10UL == 9
+#    define BOOST_PP_SLOT_TEMP_2 9
+# endif
+#
+# if BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 0
+#    define BOOST_PP_SLOT_TEMP_1 0
+# elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 1
+#    define BOOST_PP_SLOT_TEMP_1 1
+# elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 2
+#    define BOOST_PP_SLOT_TEMP_1 2
+# elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 3
+#    define BOOST_PP_SLOT_TEMP_1 3
+# elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 4
+#    define BOOST_PP_SLOT_TEMP_1 4
+# elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 5
+#    define BOOST_PP_SLOT_TEMP_1 5
+# elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 6
+#    define BOOST_PP_SLOT_TEMP_1 6
+# elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 7
+#    define BOOST_PP_SLOT_TEMP_1 7
+# elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 8
+#    define BOOST_PP_SLOT_TEMP_1 8
+# elif BOOST_PP_SLOT_OFFSET_2(BOOST_PP_VALUE) == 9
+#    define BOOST_PP_SLOT_TEMP_1 9
+# endif
+#
+# undef BOOST_PP_VALUE
diff --git a/third_party/boost/boost/preprocessor/slot/slot.hpp b/third_party/boost/boost/preprocessor/slot/slot.hpp
new file mode 100644
index 0000000..147b097
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/slot/slot.hpp
@@ -0,0 +1,32 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002.
+#  *     Distributed under the Boost Software License, Version 1.0. (See
+#  *     accompanying file LICENSE_1_0.txt or copy at
+#  *     http://www.boost.org/LICENSE_1_0.txt)
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_SLOT_SLOT_HPP
+# define BOOST_PREPROCESSOR_SLOT_SLOT_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/slot/detail/def.hpp>
+#
+# /* BOOST_PP_ASSIGN_SLOT */
+#
+# define BOOST_PP_ASSIGN_SLOT(i) BOOST_PP_CAT(BOOST_PP_ASSIGN_SLOT_, i)
+#
+# define BOOST_PP_ASSIGN_SLOT_1 <boost/preprocessor/slot/detail/slot1.hpp>
+# define BOOST_PP_ASSIGN_SLOT_2 <boost/preprocessor/slot/detail/slot2.hpp>
+# define BOOST_PP_ASSIGN_SLOT_3 <boost/preprocessor/slot/detail/slot3.hpp>
+# define BOOST_PP_ASSIGN_SLOT_4 <boost/preprocessor/slot/detail/slot4.hpp>
+# define BOOST_PP_ASSIGN_SLOT_5 <boost/preprocessor/slot/detail/slot5.hpp>
+#
+# /* BOOST_PP_SLOT */
+#
+# define BOOST_PP_SLOT(i) BOOST_PP_CAT(BOOST_PP_SLOT_, i)()
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/stringize.hpp b/third_party/boost/boost/preprocessor/stringize.hpp
new file mode 100644
index 0000000..64dd5fd
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/stringize.hpp
@@ -0,0 +1,33 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_STRINGIZE_HPP
+# define BOOST_PREPROCESSOR_STRINGIZE_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+#
+# /* BOOST_PP_STRINGIZE */
+#
+# if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC()
+#    define BOOST_PP_STRINGIZE(text) BOOST_PP_STRINGIZE_A((text))
+#    define BOOST_PP_STRINGIZE_A(arg) BOOST_PP_STRINGIZE_I arg
+# elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#    define BOOST_PP_STRINGIZE(text) BOOST_PP_STRINGIZE_OO((text))
+#    define BOOST_PP_STRINGIZE_OO(par) BOOST_PP_STRINGIZE_I ## par
+# else
+#    define BOOST_PP_STRINGIZE(text) BOOST_PP_STRINGIZE_I(text)
+# endif
+#
+# define BOOST_PP_STRINGIZE_I(text) #text
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/tuple/detail/is_single_return.hpp b/third_party/boost/boost/preprocessor/tuple/detail/is_single_return.hpp
new file mode 100644
index 0000000..02a4fb2
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/tuple/detail/is_single_return.hpp
@@ -0,0 +1,28 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Edward Diener 2014.                                    *
+#  *     Distributed under the Boost Software License, Version 1.0. (See      *
+#  *     accompanying file LICENSE_1_0.txt or copy at                         *
+#  *     http://www.boost.org/LICENSE_1_0.txt)                                *
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_TUPLE_DETAIL_IS_SINGLE_RETURN_HPP
+# define BOOST_PREPROCESSOR_TUPLE_DETAIL_IS_SINGLE_RETURN_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+#
+# /* BOOST_PP_TUPLE_IS_SINGLE_RETURN */
+#
+# if BOOST_PP_VARIADICS && BOOST_PP_VARIADICS_MSVC
+# include <boost/preprocessor/control/iif.hpp>
+# include <boost/preprocessor/facilities/is_1.hpp>
+# include <boost/preprocessor/tuple/size.hpp>
+# define BOOST_PP_TUPLE_IS_SINGLE_RETURN(sr,nsr,tuple)	\
+	BOOST_PP_IIF(BOOST_PP_IS_1(BOOST_PP_TUPLE_SIZE(tuple)),sr,nsr) \
+	/**/
+# endif /* BOOST_PP_VARIADICS && BOOST_PP_VARIADICS_MSVC */
+#
+# endif /* BOOST_PREPROCESSOR_TUPLE_DETAIL_IS_SINGLE_RETURN_HPP */
diff --git a/third_party/boost/boost/preprocessor/tuple/eat.hpp b/third_party/boost/boost/preprocessor/tuple/eat.hpp
new file mode 100644
index 0000000..7e8a100
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/tuple/eat.hpp
@@ -0,0 +1,115 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002-2011) */
+# /* Revised by Edward Diener (2011,2015) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_TUPLE_EAT_HPP
+# define BOOST_PREPROCESSOR_TUPLE_EAT_HPP
+#
+# include <boost/preprocessor/config/config.hpp>
+#
+# /* BOOST_PP_EAT */
+#
+# if BOOST_PP_VARIADICS
+#    define BOOST_PP_EAT(...)
+# else
+#    define BOOST_PP_EAT(x)
+# endif
+#
+# /* BOOST_PP_TUPLE_EAT */
+#
+# if BOOST_PP_VARIADICS
+#    define BOOST_PP_TUPLE_EAT(size) BOOST_PP_EAT
+# else
+#    if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#        define BOOST_PP_TUPLE_EAT(size) BOOST_PP_TUPLE_EAT_I(size)
+#    else
+#        define BOOST_PP_TUPLE_EAT(size) BOOST_PP_TUPLE_EAT_OO((size))
+#        define BOOST_PP_TUPLE_EAT_OO(par) BOOST_PP_TUPLE_EAT_I ## par
+#    endif
+#    define BOOST_PP_TUPLE_EAT_I(size) BOOST_PP_TUPLE_EAT_ ## size
+# endif
+#
+# if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#     define BOOST_PP_TUPLE_EAT_N(size) BOOST_PP_TUPLE_EAT_N_I(size)
+# else
+#     define BOOST_PP_TUPLE_EAT_N(size) BOOST_PP_TUPLE_EAT_N_OO((size))
+#     define BOOST_PP_TUPLE_EAT_N_OO(par) BOOST_PP_TUPLE_EAT_N_I ## par
+# endif
+# define BOOST_PP_TUPLE_EAT_N_I(size) BOOST_PP_TUPLE_EAT_ ## size
+#
+# define BOOST_PP_TUPLE_EAT_1(e0)
+# define BOOST_PP_TUPLE_EAT_2(e0, e1)
+# define BOOST_PP_TUPLE_EAT_3(e0, e1, e2)
+# define BOOST_PP_TUPLE_EAT_4(e0, e1, e2, e3)
+# define BOOST_PP_TUPLE_EAT_5(e0, e1, e2, e3, e4)
+# define BOOST_PP_TUPLE_EAT_6(e0, e1, e2, e3, e4, e5)
+# define BOOST_PP_TUPLE_EAT_7(e0, e1, e2, e3, e4, e5, e6)
+# define BOOST_PP_TUPLE_EAT_8(e0, e1, e2, e3, e4, e5, e6, e7)
+# define BOOST_PP_TUPLE_EAT_9(e0, e1, e2, e3, e4, e5, e6, e7, e8)
+# define BOOST_PP_TUPLE_EAT_10(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9)
+# define BOOST_PP_TUPLE_EAT_11(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10)
+# define BOOST_PP_TUPLE_EAT_12(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11)
+# define BOOST_PP_TUPLE_EAT_13(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12)
+# define BOOST_PP_TUPLE_EAT_14(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13)
+# define BOOST_PP_TUPLE_EAT_15(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14)
+# define BOOST_PP_TUPLE_EAT_16(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15)
+# define BOOST_PP_TUPLE_EAT_17(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16)
+# define BOOST_PP_TUPLE_EAT_18(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17)
+# define BOOST_PP_TUPLE_EAT_19(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18)
+# define BOOST_PP_TUPLE_EAT_20(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19)
+# define BOOST_PP_TUPLE_EAT_21(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20)
+# define BOOST_PP_TUPLE_EAT_22(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21)
+# define BOOST_PP_TUPLE_EAT_23(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22)
+# define BOOST_PP_TUPLE_EAT_24(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23)
+# define BOOST_PP_TUPLE_EAT_25(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24)
+# define BOOST_PP_TUPLE_EAT_26(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25)
+# define BOOST_PP_TUPLE_EAT_27(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26)
+# define BOOST_PP_TUPLE_EAT_28(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27)
+# define BOOST_PP_TUPLE_EAT_29(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28)
+# define BOOST_PP_TUPLE_EAT_30(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29)
+# define BOOST_PP_TUPLE_EAT_31(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30)
+# define BOOST_PP_TUPLE_EAT_32(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31)
+# define BOOST_PP_TUPLE_EAT_33(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32)
+# define BOOST_PP_TUPLE_EAT_34(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33)
+# define BOOST_PP_TUPLE_EAT_35(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34)
+# define BOOST_PP_TUPLE_EAT_36(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35)
+# define BOOST_PP_TUPLE_EAT_37(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36)
+# define BOOST_PP_TUPLE_EAT_38(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37)
+# define BOOST_PP_TUPLE_EAT_39(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38)
+# define BOOST_PP_TUPLE_EAT_40(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39)
+# define BOOST_PP_TUPLE_EAT_41(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40)
+# define BOOST_PP_TUPLE_EAT_42(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41)
+# define BOOST_PP_TUPLE_EAT_43(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42)
+# define BOOST_PP_TUPLE_EAT_44(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43)
+# define BOOST_PP_TUPLE_EAT_45(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44)
+# define BOOST_PP_TUPLE_EAT_46(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45)
+# define BOOST_PP_TUPLE_EAT_47(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46)
+# define BOOST_PP_TUPLE_EAT_48(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47)
+# define BOOST_PP_TUPLE_EAT_49(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48)
+# define BOOST_PP_TUPLE_EAT_50(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49)
+# define BOOST_PP_TUPLE_EAT_51(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50)
+# define BOOST_PP_TUPLE_EAT_52(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51)
+# define BOOST_PP_TUPLE_EAT_53(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52)
+# define BOOST_PP_TUPLE_EAT_54(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53)
+# define BOOST_PP_TUPLE_EAT_55(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54)
+# define BOOST_PP_TUPLE_EAT_56(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55)
+# define BOOST_PP_TUPLE_EAT_57(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56)
+# define BOOST_PP_TUPLE_EAT_58(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57)
+# define BOOST_PP_TUPLE_EAT_59(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58)
+# define BOOST_PP_TUPLE_EAT_60(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59)
+# define BOOST_PP_TUPLE_EAT_61(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60)
+# define BOOST_PP_TUPLE_EAT_62(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61)
+# define BOOST_PP_TUPLE_EAT_63(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62)
+# define BOOST_PP_TUPLE_EAT_64(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63)
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/tuple/elem.hpp b/third_party/boost/boost/preprocessor/tuple/elem.hpp
new file mode 100644
index 0000000..88044d3
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/tuple/elem.hpp
@@ -0,0 +1,201 @@
+# /* Copyright (C) 2001
+#  * Housemarque Oy
+#  * http://www.housemarque.com
+#  *
+#  * Distributed under the Boost Software License, Version 1.0. (See
+#  * accompanying file LICENSE_1_0.txt or copy at
+#  * http://www.boost.org/LICENSE_1_0.txt)
+#  */
+#
+# /* Revised by Paul Mensonides (2002-2011) */
+# /* Revised by Edward Diener (2011,2014) */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_TUPLE_ELEM_HPP
+# define BOOST_PREPROCESSOR_TUPLE_ELEM_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/facilities/expand.hpp>
+# include <boost/preprocessor/facilities/overload.hpp>
+# include <boost/preprocessor/tuple/rem.hpp>
+# include <boost/preprocessor/variadic/elem.hpp>
+# include <boost/preprocessor/tuple/detail/is_single_return.hpp>
+#
+# if BOOST_PP_VARIADICS
+#    if BOOST_PP_VARIADICS_MSVC
+#        define BOOST_PP_TUPLE_ELEM(...) BOOST_PP_TUPLE_ELEM_I(BOOST_PP_OVERLOAD(BOOST_PP_TUPLE_ELEM_O_, __VA_ARGS__), (__VA_ARGS__))
+#        define BOOST_PP_TUPLE_ELEM_I(m, args) BOOST_PP_TUPLE_ELEM_II(m, args)
+#        define BOOST_PP_TUPLE_ELEM_II(m, args) BOOST_PP_CAT(m ## args,)
+/*
+  Use BOOST_PP_REM_CAT if it is a single element tuple ( which might be empty )
+  else use BOOST_PP_REM. This fixes a VC++ problem with an empty tuple and BOOST_PP_TUPLE_ELEM
+  functionality. See tuple_elem_bug_test.cxx.
+*/
+#    	 define BOOST_PP_TUPLE_ELEM_O_2(n, tuple) \
+			BOOST_PP_VARIADIC_ELEM(n, BOOST_PP_EXPAND(BOOST_PP_TUPLE_IS_SINGLE_RETURN(BOOST_PP_REM_CAT,BOOST_PP_REM,tuple) tuple)) \
+			/**/
+#    else
+#        define BOOST_PP_TUPLE_ELEM(...) BOOST_PP_OVERLOAD(BOOST_PP_TUPLE_ELEM_O_, __VA_ARGS__)(__VA_ARGS__)
+#    	 define BOOST_PP_TUPLE_ELEM_O_2(n, tuple) BOOST_PP_VARIADIC_ELEM(n, BOOST_PP_REM tuple)
+#    endif
+#    define BOOST_PP_TUPLE_ELEM_O_3(size, n, tuple) BOOST_PP_TUPLE_ELEM_O_2(n, tuple)
+# else
+#    if BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MSVC()
+#        define BOOST_PP_TUPLE_ELEM(size, n, tuple) BOOST_PP_TUPLE_ELEM_I(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM_, n), BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM_E_, size), tuple))
+#        define BOOST_PP_TUPLE_ELEM_I(m, args) BOOST_PP_TUPLE_ELEM_II(m, args)
+#        define BOOST_PP_TUPLE_ELEM_II(m, args) BOOST_PP_CAT(m ## args,)
+#    elif BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#        define BOOST_PP_TUPLE_ELEM(size, n, tuple) BOOST_PP_TUPLE_ELEM_I_OO((size, n, tuple))
+#        define BOOST_PP_TUPLE_ELEM_I_OO(par) BOOST_PP_TUPLE_ELEM_I ## par
+#        define BOOST_PP_TUPLE_ELEM_I(size, n, tuple) BOOST_PP_TUPLE_ELEM_II((n, BOOST_PP_TUPLE_ELEM_E_ ## size ## tuple))
+#        define BOOST_PP_TUPLE_ELEM_II(par) BOOST_PP_TUPLE_ELEM_III_OO(par)
+#        define BOOST_PP_TUPLE_ELEM_III_OO(par) BOOST_PP_TUPLE_ELEM_III ## par
+#        define BOOST_PP_TUPLE_ELEM_III(n, etuple) BOOST_PP_TUPLE_ELEM_ ## n ## etuple
+#    else
+#        define BOOST_PP_TUPLE_ELEM(size, n, tuple) BOOST_PP_TUPLE_ELEM_I(BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM_, n) BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM_E_, size) tuple)
+#        define BOOST_PP_TUPLE_ELEM_I(x) x
+#    endif
+#    define BOOST_PP_TUPLE_ELEM_E_1(e0) (e0, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_2(e0, e1) (e0, e1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_3(e0, e1, e2) (e0, e1, e2, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_4(e0, e1, e2, e3) (e0, e1, e2, e3, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_5(e0, e1, e2, e3, e4) (e0, e1, e2, e3, e4, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_6(e0, e1, e2, e3, e4, e5) (e0, e1, e2, e3, e4, e5, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_7(e0, e1, e2, e3, e4, e5, e6) (e0, e1, e2, e3, e4, e5, e6, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_8(e0, e1, e2, e3, e4, e5, e6, e7) (e0, e1, e2, e3, e4, e5, e6, e7, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_9(e0, e1, e2, e3, e4, e5, e6, e7, e8) (e0, e1, e2, e3, e4, e5, e6, e7, e8, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_10(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_11(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_12(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_13(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_14(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_15(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_16(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_17(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_18(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_19(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_20(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_21(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_22(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_23(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_24(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_25(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_26(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_27(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_28(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_29(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_30(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_31(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_32(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_33(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_34(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_35(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_36(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_37(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_38(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_39(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_40(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_41(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_42(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_43(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_44(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_45(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_46(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_47(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_48(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_49(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_50(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_51(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_52(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_53(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_54(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_55(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_56(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, ?, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_57(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, ?, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_58(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, ?, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_59(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, ?, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_60(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, ?, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_61(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, ?, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_62(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, ?, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_63(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62) (e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, ?)
+#    define BOOST_PP_TUPLE_ELEM_E_64
+#    define BOOST_PP_TUPLE_ELEM_0(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e0
+#    define BOOST_PP_TUPLE_ELEM_1(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e1
+#    define BOOST_PP_TUPLE_ELEM_2(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e2
+#    define BOOST_PP_TUPLE_ELEM_3(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e3
+#    define BOOST_PP_TUPLE_ELEM_4(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e4
+#    define BOOST_PP_TUPLE_ELEM_5(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e5
+#    define BOOST_PP_TUPLE_ELEM_6(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e6
+#    define BOOST_PP_TUPLE_ELEM_7(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e7
+#    define BOOST_PP_TUPLE_ELEM_8(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e8
+#    define BOOST_PP_TUPLE_ELEM_9(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e9
+#    define BOOST_PP_TUPLE_ELEM_10(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e10
+#    define BOOST_PP_TUPLE_ELEM_11(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e11
+#    define BOOST_PP_TUPLE_ELEM_12(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e12
+#    define BOOST_PP_TUPLE_ELEM_13(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e13
+#    define BOOST_PP_TUPLE_ELEM_14(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e14
+#    define BOOST_PP_TUPLE_ELEM_15(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e15
+#    define BOOST_PP_TUPLE_ELEM_16(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e16
+#    define BOOST_PP_TUPLE_ELEM_17(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e17
+#    define BOOST_PP_TUPLE_ELEM_18(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e18
+#    define BOOST_PP_TUPLE_ELEM_19(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e19
+#    define BOOST_PP_TUPLE_ELEM_20(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e20
+#    define BOOST_PP_TUPLE_ELEM_21(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e21
+#    define BOOST_PP_TUPLE_ELEM_22(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e22
+#    define BOOST_PP_TUPLE_ELEM_23(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e23
+#    define BOOST_PP_TUPLE_ELEM_24(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e24
+#    define BOOST_PP_TUPLE_ELEM_25(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e25
+#    define BOOST_PP_TUPLE_ELEM_26(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e26
+#    define BOOST_PP_TUPLE_ELEM_27(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e27
+#    define BOOST_PP_TUPLE_ELEM_28(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e28
+#    define BOOST_PP_TUPLE_ELEM_29(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e29
+#    define BOOST_PP_TUPLE_ELEM_30(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e30
+#    define BOOST_PP_TUPLE_ELEM_31(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e31
+#    define BOOST_PP_TUPLE_ELEM_32(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e32
+#    define BOOST_PP_TUPLE_ELEM_33(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e33
+#    define BOOST_PP_TUPLE_ELEM_34(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e34
+#    define BOOST_PP_TUPLE_ELEM_35(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e35
+#    define BOOST_PP_TUPLE_ELEM_36(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e36
+#    define BOOST_PP_TUPLE_ELEM_37(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e37
+#    define BOOST_PP_TUPLE_ELEM_38(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e38
+#    define BOOST_PP_TUPLE_ELEM_39(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e39
+#    define BOOST_PP_TUPLE_ELEM_40(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e40
+#    define BOOST_PP_TUPLE_ELEM_41(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e41
+#    define BOOST_PP_TUPLE_ELEM_42(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e42
+#    define BOOST_PP_TUPLE_ELEM_43(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e43
+#    define BOOST_PP_TUPLE_ELEM_44(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e44
+#    define BOOST_PP_TUPLE_ELEM_45(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e45
+#    define BOOST_PP_TUPLE_ELEM_46(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e46
+#    define BOOST_PP_TUPLE_ELEM_47(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e47
+#    define BOOST_PP_TUPLE_ELEM_48(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e48
+#    define BOOST_PP_TUPLE_ELEM_49(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e49
+#    define BOOST_PP_TUPLE_ELEM_50(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e50
+#    define BOOST_PP_TUPLE_ELEM_51(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e51
+#    define BOOST_PP_TUPLE_ELEM_52(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e52
+#    define BOOST_PP_TUPLE_ELEM_53(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e53
+#    define BOOST_PP_TUPLE_ELEM_54(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e54
+#    define BOOST_PP_TUPLE_ELEM_55(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e55
+#    define BOOST_PP_TUPLE_ELEM_56(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e56
+#    define BOOST_PP_TUPLE_ELEM_57(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e57
+#    define BOOST_PP_TUPLE_ELEM_58(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e58
+#    define BOOST_PP_TUPLE_ELEM_59(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e59
+#    define BOOST_PP_TUPLE_ELEM_60(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e60
+#    define BOOST_PP_TUPLE_ELEM_61(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e61
+#    define BOOST_PP_TUPLE_ELEM_62(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e62
+#    define BOOST_PP_TUPLE_ELEM_63(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e63
+# endif
+#
+# /* directly used elsewhere in Boost... */
+#
+# define BOOST_PP_TUPLE_ELEM_1_0(a) a
+#
+# define BOOST_PP_TUPLE_ELEM_2_0(a, b) a
+# define BOOST_PP_TUPLE_ELEM_2_1(a, b) b
+#
+# define BOOST_PP_TUPLE_ELEM_3_0(a, b, c) a
+# define BOOST_PP_TUPLE_ELEM_3_1(a, b, c) b
+# define BOOST_PP_TUPLE_ELEM_3_2(a, b, c) c
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/tuple/rem.hpp b/third_party/boost/boost/preprocessor/tuple/rem.hpp
new file mode 100644
index 0000000..c934447
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/tuple/rem.hpp
@@ -0,0 +1,149 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Paul Mensonides 2002-2011.                             *
+#  *     (C) Copyright Edward Diener 2011,2013.                               *
+#  *     Distributed under the Boost Software License, Version 1.0. (See      *
+#  *     accompanying file LICENSE_1_0.txt or copy at                         *
+#  *     http://www.boost.org/LICENSE_1_0.txt)                                *
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_TUPLE_REM_HPP
+# define BOOST_PREPROCESSOR_TUPLE_REM_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/config/config.hpp>
+# include <boost/preprocessor/facilities/expand.hpp>
+# include <boost/preprocessor/facilities/overload.hpp>
+# include <boost/preprocessor/tuple/detail/is_single_return.hpp>
+#
+# /* BOOST_PP_REM */
+#
+# if BOOST_PP_VARIADICS
+# 	 if BOOST_PP_VARIADICS_MSVC
+		/* To be used internally when __VA_ARGS__ could be empty ( or is a single element ) */
+#    	define BOOST_PP_REM_CAT(...) BOOST_PP_CAT(__VA_ARGS__,)
+# 	 endif
+#    define BOOST_PP_REM(...) __VA_ARGS__
+# else
+#    define BOOST_PP_REM(x) x
+# endif
+#
+# /* BOOST_PP_TUPLE_REM */
+#
+/*
+  VC++8.0 cannot handle the variadic version of BOOST_PP_TUPLE_REM(size)
+*/
+# if BOOST_PP_VARIADICS && !(BOOST_PP_VARIADICS_MSVC && _MSC_VER <= 1400)
+# 	 if BOOST_PP_VARIADICS_MSVC
+		/* To be used internally when the size could be 0 ( or 1 ) */
+#    	define BOOST_PP_TUPLE_REM_CAT(size) BOOST_PP_REM_CAT
+# 	 endif
+#    define BOOST_PP_TUPLE_REM(size) BOOST_PP_REM
+# else
+#    if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#        define BOOST_PP_TUPLE_REM(size) BOOST_PP_TUPLE_REM_I(size)
+#    else
+#        define BOOST_PP_TUPLE_REM(size) BOOST_PP_TUPLE_REM_OO((size))
+#        define BOOST_PP_TUPLE_REM_OO(par) BOOST_PP_TUPLE_REM_I ## par
+#    endif
+#    define BOOST_PP_TUPLE_REM_I(size) BOOST_PP_TUPLE_REM_ ## size
+# endif
+# define BOOST_PP_TUPLE_REM_0()
+# define BOOST_PP_TUPLE_REM_1(e0) e0
+# define BOOST_PP_TUPLE_REM_2(e0, e1) e0, e1
+# define BOOST_PP_TUPLE_REM_3(e0, e1, e2) e0, e1, e2
+# define BOOST_PP_TUPLE_REM_4(e0, e1, e2, e3) e0, e1, e2, e3
+# define BOOST_PP_TUPLE_REM_5(e0, e1, e2, e3, e4) e0, e1, e2, e3, e4
+# define BOOST_PP_TUPLE_REM_6(e0, e1, e2, e3, e4, e5) e0, e1, e2, e3, e4, e5
+# define BOOST_PP_TUPLE_REM_7(e0, e1, e2, e3, e4, e5, e6) e0, e1, e2, e3, e4, e5, e6
+# define BOOST_PP_TUPLE_REM_8(e0, e1, e2, e3, e4, e5, e6, e7) e0, e1, e2, e3, e4, e5, e6, e7
+# define BOOST_PP_TUPLE_REM_9(e0, e1, e2, e3, e4, e5, e6, e7, e8) e0, e1, e2, e3, e4, e5, e6, e7, e8
+# define BOOST_PP_TUPLE_REM_10(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9
+# define BOOST_PP_TUPLE_REM_11(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10
+# define BOOST_PP_TUPLE_REM_12(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11
+# define BOOST_PP_TUPLE_REM_13(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12
+# define BOOST_PP_TUPLE_REM_14(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13
+# define BOOST_PP_TUPLE_REM_15(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14
+# define BOOST_PP_TUPLE_REM_16(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15
+# define BOOST_PP_TUPLE_REM_17(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16
+# define BOOST_PP_TUPLE_REM_18(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17
+# define BOOST_PP_TUPLE_REM_19(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18
+# define BOOST_PP_TUPLE_REM_20(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19
+# define BOOST_PP_TUPLE_REM_21(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20
+# define BOOST_PP_TUPLE_REM_22(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21
+# define BOOST_PP_TUPLE_REM_23(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22
+# define BOOST_PP_TUPLE_REM_24(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23
+# define BOOST_PP_TUPLE_REM_25(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24
+# define BOOST_PP_TUPLE_REM_26(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25
+# define BOOST_PP_TUPLE_REM_27(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26
+# define BOOST_PP_TUPLE_REM_28(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27
+# define BOOST_PP_TUPLE_REM_29(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28
+# define BOOST_PP_TUPLE_REM_30(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29
+# define BOOST_PP_TUPLE_REM_31(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30
+# define BOOST_PP_TUPLE_REM_32(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31
+# define BOOST_PP_TUPLE_REM_33(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32
+# define BOOST_PP_TUPLE_REM_34(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33
+# define BOOST_PP_TUPLE_REM_35(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34
+# define BOOST_PP_TUPLE_REM_36(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35
+# define BOOST_PP_TUPLE_REM_37(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36
+# define BOOST_PP_TUPLE_REM_38(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37
+# define BOOST_PP_TUPLE_REM_39(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38
+# define BOOST_PP_TUPLE_REM_40(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39
+# define BOOST_PP_TUPLE_REM_41(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40
+# define BOOST_PP_TUPLE_REM_42(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41
+# define BOOST_PP_TUPLE_REM_43(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42
+# define BOOST_PP_TUPLE_REM_44(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43
+# define BOOST_PP_TUPLE_REM_45(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44
+# define BOOST_PP_TUPLE_REM_46(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45
+# define BOOST_PP_TUPLE_REM_47(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46
+# define BOOST_PP_TUPLE_REM_48(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47
+# define BOOST_PP_TUPLE_REM_49(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48
+# define BOOST_PP_TUPLE_REM_50(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49
+# define BOOST_PP_TUPLE_REM_51(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50
+# define BOOST_PP_TUPLE_REM_52(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51
+# define BOOST_PP_TUPLE_REM_53(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52
+# define BOOST_PP_TUPLE_REM_54(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53
+# define BOOST_PP_TUPLE_REM_55(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54
+# define BOOST_PP_TUPLE_REM_56(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55
+# define BOOST_PP_TUPLE_REM_57(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56
+# define BOOST_PP_TUPLE_REM_58(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57
+# define BOOST_PP_TUPLE_REM_59(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58
+# define BOOST_PP_TUPLE_REM_60(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59
+# define BOOST_PP_TUPLE_REM_61(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60
+# define BOOST_PP_TUPLE_REM_62(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61
+# define BOOST_PP_TUPLE_REM_63(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62
+# define BOOST_PP_TUPLE_REM_64(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63
+#
+# /* BOOST_PP_TUPLE_REM_CTOR */
+#
+# if BOOST_PP_VARIADICS
+#    if BOOST_PP_VARIADICS_MSVC
+#        define BOOST_PP_TUPLE_REM_CTOR(...) BOOST_PP_TUPLE_REM_CTOR_I(BOOST_PP_OVERLOAD(BOOST_PP_TUPLE_REM_CTOR_O_, __VA_ARGS__), (__VA_ARGS__))
+#        define BOOST_PP_TUPLE_REM_CTOR_I(m, args) BOOST_PP_TUPLE_REM_CTOR_II(m, args)
+#        define BOOST_PP_TUPLE_REM_CTOR_II(m, args) BOOST_PP_CAT(m ## args,)
+#    	 define BOOST_PP_TUPLE_REM_CTOR_O_1(tuple) BOOST_PP_EXPAND(BOOST_PP_TUPLE_IS_SINGLE_RETURN(BOOST_PP_REM_CAT,BOOST_PP_REM,tuple) tuple)
+#    else
+#        define BOOST_PP_TUPLE_REM_CTOR(...) BOOST_PP_OVERLOAD(BOOST_PP_TUPLE_REM_CTOR_O_, __VA_ARGS__)(__VA_ARGS__)
+#    	 define BOOST_PP_TUPLE_REM_CTOR_O_1(tuple) BOOST_PP_REM tuple
+#    endif
+#    define BOOST_PP_TUPLE_REM_CTOR_O_2(size, tuple) BOOST_PP_TUPLE_REM_CTOR_O_1(tuple)
+# else
+#    if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_EDG()
+#        define BOOST_PP_TUPLE_REM_CTOR(size, tuple) BOOST_PP_TUPLE_REM_CTOR_I(BOOST_PP_TUPLE_REM(size), tuple)
+#    else
+#        define BOOST_PP_TUPLE_REM_CTOR(size, tuple) BOOST_PP_TUPLE_REM_CTOR_D(size, tuple)
+#        define BOOST_PP_TUPLE_REM_CTOR_D(size, tuple) BOOST_PP_TUPLE_REM_CTOR_I(BOOST_PP_TUPLE_REM(size), tuple)
+#    endif
+#    if ~BOOST_PP_CONFIG_FLAGS() & BOOST_PP_CONFIG_MWCC()
+#        define BOOST_PP_TUPLE_REM_CTOR_I(ext, tuple) ext tuple
+#    else
+#        define BOOST_PP_TUPLE_REM_CTOR_I(ext, tuple) BOOST_PP_TUPLE_REM_CTOR_OO((ext, tuple))
+#        define BOOST_PP_TUPLE_REM_CTOR_OO(par) BOOST_PP_TUPLE_REM_CTOR_II ## par
+#        define BOOST_PP_TUPLE_REM_CTOR_II(ext, tuple) ext ## tuple
+#    endif
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/variadic/elem.hpp b/third_party/boost/boost/preprocessor/variadic/elem.hpp
new file mode 100644
index 0000000..be38a94
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/variadic/elem.hpp
@@ -0,0 +1,94 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Edward Diener 2011.                                    *
+#  *     (C) Copyright Paul Mensonides 2011.                                  *
+#  *     Distributed under the Boost Software License, Version 1.0. (See      *
+#  *     accompanying file LICENSE_1_0.txt or copy at                         *
+#  *     http://www.boost.org/LICENSE_1_0.txt)                                *
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_VARIADIC_ELEM_HPP
+# define BOOST_PREPROCESSOR_VARIADIC_ELEM_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/config/config.hpp>
+#
+# /* BOOST_PP_VARIADIC_ELEM */
+#
+# if BOOST_PP_VARIADICS
+#    if BOOST_PP_VARIADICS_MSVC
+#        define BOOST_PP_VARIADIC_ELEM(n, ...) BOOST_PP_VARIADIC_ELEM_I(n,__VA_ARGS__)
+#        define BOOST_PP_VARIADIC_ELEM_I(n, ...) BOOST_PP_CAT(BOOST_PP_CAT(BOOST_PP_VARIADIC_ELEM_, n)(__VA_ARGS__,),)
+#    else
+#        define BOOST_PP_VARIADIC_ELEM(n, ...) BOOST_PP_CAT(BOOST_PP_VARIADIC_ELEM_, n)(__VA_ARGS__,)
+#    endif
+#    define BOOST_PP_VARIADIC_ELEM_0(e0, ...) e0
+#    define BOOST_PP_VARIADIC_ELEM_1(e0, e1, ...) e1
+#    define BOOST_PP_VARIADIC_ELEM_2(e0, e1, e2, ...) e2
+#    define BOOST_PP_VARIADIC_ELEM_3(e0, e1, e2, e3, ...) e3
+#    define BOOST_PP_VARIADIC_ELEM_4(e0, e1, e2, e3, e4, ...) e4
+#    define BOOST_PP_VARIADIC_ELEM_5(e0, e1, e2, e3, e4, e5, ...) e5
+#    define BOOST_PP_VARIADIC_ELEM_6(e0, e1, e2, e3, e4, e5, e6, ...) e6
+#    define BOOST_PP_VARIADIC_ELEM_7(e0, e1, e2, e3, e4, e5, e6, e7, ...) e7
+#    define BOOST_PP_VARIADIC_ELEM_8(e0, e1, e2, e3, e4, e5, e6, e7, e8, ...) e8
+#    define BOOST_PP_VARIADIC_ELEM_9(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, ...) e9
+#    define BOOST_PP_VARIADIC_ELEM_10(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, ...) e10
+#    define BOOST_PP_VARIADIC_ELEM_11(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, ...) e11
+#    define BOOST_PP_VARIADIC_ELEM_12(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, ...) e12
+#    define BOOST_PP_VARIADIC_ELEM_13(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, ...) e13
+#    define BOOST_PP_VARIADIC_ELEM_14(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, ...) e14
+#    define BOOST_PP_VARIADIC_ELEM_15(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, ...) e15
+#    define BOOST_PP_VARIADIC_ELEM_16(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, ...) e16
+#    define BOOST_PP_VARIADIC_ELEM_17(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, ...) e17
+#    define BOOST_PP_VARIADIC_ELEM_18(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, ...) e18
+#    define BOOST_PP_VARIADIC_ELEM_19(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, ...) e19
+#    define BOOST_PP_VARIADIC_ELEM_20(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, ...) e20
+#    define BOOST_PP_VARIADIC_ELEM_21(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, ...) e21
+#    define BOOST_PP_VARIADIC_ELEM_22(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, ...) e22
+#    define BOOST_PP_VARIADIC_ELEM_23(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, ...) e23
+#    define BOOST_PP_VARIADIC_ELEM_24(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, ...) e24
+#    define BOOST_PP_VARIADIC_ELEM_25(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, ...) e25
+#    define BOOST_PP_VARIADIC_ELEM_26(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, ...) e26
+#    define BOOST_PP_VARIADIC_ELEM_27(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, ...) e27
+#    define BOOST_PP_VARIADIC_ELEM_28(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, ...) e28
+#    define BOOST_PP_VARIADIC_ELEM_29(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, ...) e29
+#    define BOOST_PP_VARIADIC_ELEM_30(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, ...) e30
+#    define BOOST_PP_VARIADIC_ELEM_31(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, ...) e31
+#    define BOOST_PP_VARIADIC_ELEM_32(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, ...) e32
+#    define BOOST_PP_VARIADIC_ELEM_33(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, ...) e33
+#    define BOOST_PP_VARIADIC_ELEM_34(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, ...) e34
+#    define BOOST_PP_VARIADIC_ELEM_35(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, ...) e35
+#    define BOOST_PP_VARIADIC_ELEM_36(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, ...) e36
+#    define BOOST_PP_VARIADIC_ELEM_37(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, ...) e37
+#    define BOOST_PP_VARIADIC_ELEM_38(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, ...) e38
+#    define BOOST_PP_VARIADIC_ELEM_39(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, ...) e39
+#    define BOOST_PP_VARIADIC_ELEM_40(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, ...) e40
+#    define BOOST_PP_VARIADIC_ELEM_41(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, ...) e41
+#    define BOOST_PP_VARIADIC_ELEM_42(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, ...) e42
+#    define BOOST_PP_VARIADIC_ELEM_43(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, ...) e43
+#    define BOOST_PP_VARIADIC_ELEM_44(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, ...) e44
+#    define BOOST_PP_VARIADIC_ELEM_45(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, ...) e45
+#    define BOOST_PP_VARIADIC_ELEM_46(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, ...) e46
+#    define BOOST_PP_VARIADIC_ELEM_47(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, ...) e47
+#    define BOOST_PP_VARIADIC_ELEM_48(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, ...) e48
+#    define BOOST_PP_VARIADIC_ELEM_49(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, ...) e49
+#    define BOOST_PP_VARIADIC_ELEM_50(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, ...) e50
+#    define BOOST_PP_VARIADIC_ELEM_51(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, ...) e51
+#    define BOOST_PP_VARIADIC_ELEM_52(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, ...) e52
+#    define BOOST_PP_VARIADIC_ELEM_53(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, ...) e53
+#    define BOOST_PP_VARIADIC_ELEM_54(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, ...) e54
+#    define BOOST_PP_VARIADIC_ELEM_55(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, ...) e55
+#    define BOOST_PP_VARIADIC_ELEM_56(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, ...) e56
+#    define BOOST_PP_VARIADIC_ELEM_57(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, ...) e57
+#    define BOOST_PP_VARIADIC_ELEM_58(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, ...) e58
+#    define BOOST_PP_VARIADIC_ELEM_59(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, ...) e59
+#    define BOOST_PP_VARIADIC_ELEM_60(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, ...) e60
+#    define BOOST_PP_VARIADIC_ELEM_61(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, ...) e61
+#    define BOOST_PP_VARIADIC_ELEM_62(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, ...) e62
+#    define BOOST_PP_VARIADIC_ELEM_63(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63, ...) e63
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/preprocessor/variadic/size.hpp b/third_party/boost/boost/preprocessor/variadic/size.hpp
new file mode 100644
index 0000000..b92a5ff
--- /dev/null
+++ b/third_party/boost/boost/preprocessor/variadic/size.hpp
@@ -0,0 +1,30 @@
+# /* **************************************************************************
+#  *                                                                          *
+#  *     (C) Copyright Edward Diener 2011.                                    *
+#  *     (C) Copyright Paul Mensonides 2011.                                  *
+#  *     Distributed under the Boost Software License, Version 1.0. (See      *
+#  *     accompanying file LICENSE_1_0.txt or copy at                         *
+#  *     http://www.boost.org/LICENSE_1_0.txt)                                *
+#  *                                                                          *
+#  ************************************************************************** */
+#
+# /* See http://www.boost.org for most recent version. */
+#
+# ifndef BOOST_PREPROCESSOR_VARIADIC_SIZE_HPP
+# define BOOST_PREPROCESSOR_VARIADIC_SIZE_HPP
+#
+# include <boost/preprocessor/cat.hpp>
+# include <boost/preprocessor/config/config.hpp>
+#
+# /* BOOST_PP_VARIADIC_SIZE */
+#
+# if BOOST_PP_VARIADICS
+#    if BOOST_PP_VARIADICS_MSVC
+#        define BOOST_PP_VARIADIC_SIZE(...) BOOST_PP_CAT(BOOST_PP_VARIADIC_SIZE_I(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,),)
+#    else
+#        define BOOST_PP_VARIADIC_SIZE(...) BOOST_PP_VARIADIC_SIZE_I(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,)
+#    endif
+#    define BOOST_PP_VARIADIC_SIZE_I(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63, size, ...) size
+# endif
+#
+# endif
diff --git a/third_party/boost/boost/ref.hpp b/third_party/boost/boost/ref.hpp
new file mode 100644
index 0000000..17b56ec
--- /dev/null
+++ b/third_party/boost/boost/ref.hpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2014 Glen Fernandes
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef BOOST_REF_HPP
+#define BOOST_REF_HPP
+
+// The header file at this path is deprecated;
+// use boost/core/ref.hpp instead.
+
+#include <boost/core/ref.hpp>
+
+#endif
diff --git a/third_party/boost/boost/scoped_ptr.hpp b/third_party/boost/boost/scoped_ptr.hpp
new file mode 100644
index 0000000..cb916da
--- /dev/null
+++ b/third_party/boost/boost/scoped_ptr.hpp
@@ -0,0 +1,16 @@
+#ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
+#define BOOST_SCOPED_PTR_HPP_INCLUDED
+
+//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
+//  Copyright (c) 2001, 2002 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
+//
+
+#include <boost/smart_ptr/scoped_ptr.hpp>
+
+#endif // #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
diff --git a/third_party/boost/boost/shared_ptr.hpp b/third_party/boost/boost/shared_ptr.hpp
new file mode 100644
index 0000000..d31978c
--- /dev/null
+++ b/third_party/boost/boost/shared_ptr.hpp
@@ -0,0 +1,19 @@
+#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
+#define BOOST_SHARED_PTR_HPP_INCLUDED
+
+//
+//  shared_ptr.hpp
+//
+//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
+//  Copyright (c) 2001-2008 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
+//
+
+#include <boost/smart_ptr/shared_ptr.hpp>
+
+#endif  // #ifndef BOOST_SHARED_PTR_HPP_INCLUDED
diff --git a/third_party/boost/boost/signals2/connection.hpp b/third_party/boost/boost/signals2/connection.hpp
new file mode 100644
index 0000000..bc03789
--- /dev/null
+++ b/third_party/boost/boost/signals2/connection.hpp
@@ -0,0 +1,374 @@
+/*
+  boost::signals2::connection provides a handle to a signal/slot connection.
+
+  Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+  Begin: 2007-01-23
+*/
+// Copyright Frank Mori Hess 2007-2008.
+// Distributed under the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org/libs/signals2 for library home page.
+
+#ifndef BOOST_SIGNALS2_CONNECTION_HPP
+#define BOOST_SIGNALS2_CONNECTION_HPP
+
+#include <boost/function.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/signals2/detail/auto_buffer.hpp>
+#include <boost/signals2/detail/null_output_iterator.hpp>
+#include <boost/signals2/detail/unique_lock.hpp>
+#include <boost/signals2/slot.hpp>
+#include <boost/weak_ptr.hpp>
+
+namespace boost
+{
+  namespace signals2
+  {
+    inline void null_deleter(const void*) {}
+    namespace detail
+    {
+      // This lock maintains a list of shared_ptr<void>
+      // which will be destroyed only after the lock
+      // has released its mutex.  Used to garbage
+      // collect disconnected slots
+      template<typename Mutex>
+      class garbage_collecting_lock: public noncopyable
+      {
+      public:
+        garbage_collecting_lock(Mutex &m):
+          lock(m)
+        {}
+        void add_trash(const shared_ptr<void> &piece_of_trash)
+        {
+          garbage.push_back(piece_of_trash);
+        }
+      private:
+        // garbage must be declared before lock
+        // to insure it is destroyed after lock is
+        // destroyed.
+        auto_buffer<shared_ptr<void>, store_n_objects<10> > garbage;
+        unique_lock<Mutex> lock;
+      };
+
+      class connection_body_base
+      {
+      public:
+        connection_body_base():
+          _connected(true), m_slot_refcount(1)
+        {
+        }
+        virtual ~connection_body_base() {}
+        void disconnect()
+        {
+          garbage_collecting_lock<connection_body_base> local_lock(*this);
+          nolock_disconnect(local_lock);
+        }
+        template<typename Mutex>
+        void nolock_disconnect(garbage_collecting_lock<Mutex> &lock_arg) const
+        {
+          if(_connected)
+          {
+            _connected = false;
+            dec_slot_refcount(lock_arg);
+          }
+        }
+        virtual bool connected() const = 0;
+        shared_ptr<void> get_blocker()
+        {
+          unique_lock<connection_body_base> local_lock(*this);
+          shared_ptr<void> blocker = _weak_blocker.lock();
+          if(blocker == shared_ptr<void>())
+          {
+            blocker.reset(this, &null_deleter);
+            _weak_blocker = blocker;
+          }
+          return blocker;
+        }
+        bool blocked() const
+        {
+          return !_weak_blocker.expired();
+        }
+        bool nolock_nograb_blocked() const
+        {
+          return nolock_nograb_connected() == false || blocked();
+        }
+        bool nolock_nograb_connected() const {return _connected;}
+        // expose part of Lockable concept of mutex
+        virtual void lock() = 0;
+        virtual void unlock() = 0;
+
+        // Slot refcount should be incremented while
+        // a signal invocation is using the slot, in order
+        // to prevent slot from being destroyed mid-invocation.
+        // garbage_collecting_lock parameter enforces
+        // the existance of a lock before this
+        // method is called
+        template<typename Mutex>
+        void inc_slot_refcount(const garbage_collecting_lock<Mutex> &)
+        {
+          BOOST_ASSERT(m_slot_refcount != 0);
+          ++m_slot_refcount;
+        }
+        // if slot refcount decrements to zero due to this call,
+        // it puts a
+        // shared_ptr to the slot in the garbage collecting lock,
+        // which will destroy the slot only after it unlocks.
+        template<typename Mutex>
+        void dec_slot_refcount(garbage_collecting_lock<Mutex> &lock_arg) const
+        {
+          BOOST_ASSERT(m_slot_refcount != 0);
+          if(--m_slot_refcount == 0)
+          {
+            lock_arg.add_trash(release_slot());
+          }
+        }
+
+      protected:
+        virtual shared_ptr<void> release_slot() const = 0;
+
+        weak_ptr<void> _weak_blocker;
+      private:
+        mutable bool _connected;
+        mutable unsigned m_slot_refcount;
+      };
+
+      template<typename GroupKey, typename SlotType, typename Mutex>
+      class connection_body: public connection_body_base
+      {
+      public:
+        typedef Mutex mutex_type;
+        connection_body(const SlotType &slot_in, const boost::shared_ptr<mutex_type> &signal_mutex):
+          m_slot(new SlotType(slot_in)), _mutex(signal_mutex)
+        {
+        }
+        virtual ~connection_body() {}
+        virtual bool connected() const
+        {
+          garbage_collecting_lock<mutex_type> local_lock(*_mutex);
+          nolock_grab_tracked_objects(local_lock, detail::null_output_iterator());
+          return nolock_nograb_connected();
+        }
+        const GroupKey& group_key() const {return _group_key;}
+        void set_group_key(const GroupKey &key) {_group_key = key;}
+        template<typename M>
+        void disconnect_expired_slot(garbage_collecting_lock<M> &lock_arg)
+        {
+          if(!m_slot) return;
+          bool expired = slot().expired();
+          if(expired == true)
+          {
+            nolock_disconnect(lock_arg);
+          }
+        }
+        template<typename M, typename OutputIterator>
+        void nolock_grab_tracked_objects(garbage_collecting_lock<M> &lock_arg,
+          OutputIterator inserter) const
+        {
+          if(!m_slot) return;
+          slot_base::tracked_container_type::const_iterator it;
+          for(it = slot().tracked_objects().begin();
+            it != slot().tracked_objects().end();
+            ++it)
+          {
+            void_shared_ptr_variant locked_object
+            (
+              apply_visitor
+              (
+                detail::lock_weak_ptr_visitor(),
+                *it
+              )
+            );
+            if(apply_visitor(detail::expired_weak_ptr_visitor(), *it))
+            {
+              nolock_disconnect(lock_arg);
+              return;
+            }
+            *inserter++ = locked_object;
+          }
+        }
+        // expose Lockable concept of mutex
+        virtual void lock()
+        {
+          _mutex->lock();
+        }
+        virtual void unlock()
+        {
+          _mutex->unlock();
+        }
+        SlotType &slot()
+        {
+          return *m_slot;
+        }
+        const SlotType &slot() const
+        {
+          return *m_slot;
+        }
+      protected:
+        virtual shared_ptr<void> release_slot() const
+        {
+
+          shared_ptr<void> released_slot = m_slot;
+          m_slot.reset();
+          return released_slot;
+        }
+      private:
+        mutable boost::shared_ptr<SlotType> m_slot;
+        const boost::shared_ptr<mutex_type> _mutex;
+        GroupKey _group_key;
+      };
+    }
+
+    class shared_connection_block;
+
+    class connection
+    {
+    public:
+      friend class shared_connection_block;
+
+      connection() {}
+      connection(const connection &other): _weak_connection_body(other._weak_connection_body)
+      {}
+      connection(const boost::weak_ptr<detail::connection_body_base> &connectionBody):
+        _weak_connection_body(connectionBody)
+      {}
+
+      // move support
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+      connection(connection && other): _weak_connection_body(std::move(other._weak_connection_body))
+      {
+        // make sure other is reset, in case it is a scoped_connection (so it
+        // won't disconnect on destruction after being moved away from).
+        other._weak_connection_body.reset();
+      }
+      connection & operator=(connection && other)
+      {
+        if(&other == this) return *this;
+        _weak_connection_body = std::move(other._weak_connection_body);
+        // make sure other is reset, in case it is a scoped_connection (so it
+        // won't disconnect on destruction after being moved away from).
+        other._weak_connection_body.reset();
+        return *this;
+      }
+#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+      connection & operator=(const connection & other)
+      {
+        if(&other == this) return *this;
+        _weak_connection_body = other._weak_connection_body;
+        return *this;
+      }
+
+      ~connection() {}
+      void disconnect() const
+      {
+        boost::shared_ptr<detail::connection_body_base> connectionBody(_weak_connection_body.lock());
+        if(connectionBody == 0) return;
+        connectionBody->disconnect();
+      }
+      bool connected() const
+      {
+        boost::shared_ptr<detail::connection_body_base> connectionBody(_weak_connection_body.lock());
+        if(connectionBody == 0) return false;
+        return connectionBody->connected();
+      }
+      bool blocked() const
+      {
+        boost::shared_ptr<detail::connection_body_base> connectionBody(_weak_connection_body.lock());
+        if(connectionBody == 0) return true;
+        return connectionBody->blocked();
+      }
+      bool operator==(const connection& other) const
+      {
+        boost::shared_ptr<detail::connection_body_base> connectionBody(_weak_connection_body.lock());
+        boost::shared_ptr<detail::connection_body_base> otherConnectionBody(other._weak_connection_body.lock());
+        return connectionBody == otherConnectionBody;
+      }
+      bool operator!=(const connection& other) const
+      {
+        return !(*this == other);
+      }
+      bool operator<(const connection& other) const
+      {
+        boost::shared_ptr<detail::connection_body_base> connectionBody(_weak_connection_body.lock());
+        boost::shared_ptr<detail::connection_body_base> otherConnectionBody(other._weak_connection_body.lock());
+        return connectionBody < otherConnectionBody;
+      }
+      void swap(connection &other)
+      {
+        using std::swap;
+        swap(_weak_connection_body, other._weak_connection_body);
+      }
+    protected:
+
+      boost::weak_ptr<detail::connection_body_base> _weak_connection_body;
+    };
+    inline void swap(connection &conn1, connection &conn2)
+    {
+      conn1.swap(conn2);
+    }
+
+    class scoped_connection: public connection
+    {
+    public:
+      scoped_connection() {}
+      scoped_connection(const connection &other):
+        connection(other)
+      {}
+      ~scoped_connection()
+      {
+        disconnect();
+      }
+      scoped_connection& operator=(const connection &rhs)
+      {
+        disconnect();
+        connection::operator=(rhs);
+        return *this;
+      }
+
+      // move support
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+      scoped_connection(scoped_connection && other): connection(std::move(other))
+      {
+      }
+      scoped_connection(connection && other): connection(std::move(other))
+      {
+      }
+      scoped_connection & operator=(scoped_connection && other)
+      {
+        if(&other == this) return *this;
+        disconnect();
+        connection::operator=(std::move(other));
+        return *this;
+      }
+      scoped_connection & operator=(connection && other)
+      {
+        if(&other == this) return *this;
+        disconnect();
+        connection::operator=(std::move(other));
+        return *this;
+      }
+#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+      connection release()
+      {
+        connection conn(_weak_connection_body);
+        _weak_connection_body.reset();
+        return conn;
+      }
+    private:
+      scoped_connection(const scoped_connection &other);
+      scoped_connection& operator=(const scoped_connection &rhs);
+    };
+    // Sun 5.9 compiler doesn't find the swap for base connection class when
+    // arguments are scoped_connection, so we provide this explicitly.
+    inline void swap(scoped_connection &conn1, scoped_connection &conn2)
+    {
+      conn1.swap(conn2);
+    }
+  }
+}
+
+#endif  // BOOST_SIGNALS2_CONNECTION_HPP
diff --git a/third_party/boost/boost/signals2/detail/auto_buffer.hpp b/third_party/boost/boost/signals2/detail/auto_buffer.hpp
new file mode 100644
index 0000000..0970d3d
--- /dev/null
+++ b/third_party/boost/boost/signals2/detail/auto_buffer.hpp
@@ -0,0 +1,1137 @@
+// Copyright Thorsten Ottosen, 2009.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_SIGNALS2_DETAIL_AUTO_BUFFER_HPP_25_02_2009
+#define BOOST_SIGNALS2_DETAIL_AUTO_BUFFER_HPP_25_02_2009
+
+#include <boost/detail/workaround.hpp>
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+#pragma warning(push)
+#pragma warning(disable:4996)
+#endif
+
+#include <boost/assert.hpp>
+#include <boost/iterator/reverse_iterator.hpp>
+#include <boost/iterator/iterator_traits.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/multi_index/detail/scope_guard.hpp>
+#include <boost/swap.hpp>
+#include <boost/type_traits/aligned_storage.hpp>
+#include <boost/type_traits/alignment_of.hpp>
+#include <boost/type_traits/has_nothrow_copy.hpp>
+#include <boost/type_traits/has_nothrow_assign.hpp>
+#include <boost/type_traits/has_trivial_assign.hpp>
+#include <boost/type_traits/has_trivial_constructor.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <algorithm>
+#include <cstring>
+#include <iterator>
+#include <memory>
+#include <stdexcept>
+
+namespace boost
+{
+namespace signals2
+{
+namespace detail
+{
+    //
+    // Policies for creating the stack buffer.
+    //
+    template< unsigned N >
+    struct store_n_objects
+    {
+        BOOST_STATIC_CONSTANT( unsigned, value = N );
+    };
+
+    template< unsigned N >
+    struct store_n_bytes
+    {
+        BOOST_STATIC_CONSTANT( unsigned, value = N );
+    };
+
+    namespace auto_buffer_detail
+    {
+        template< class Policy, class T >
+        struct compute_buffer_size
+        {
+            BOOST_STATIC_CONSTANT( unsigned, value = Policy::value * sizeof(T) );
+        };
+
+        template< unsigned N, class T >
+        struct compute_buffer_size< store_n_bytes<N>, T >
+        {
+            BOOST_STATIC_CONSTANT( unsigned, value = N );
+        };
+
+        template< class Policy, class T >
+        struct compute_buffer_objects
+        {
+            BOOST_STATIC_CONSTANT( unsigned, value = Policy::value );
+        };
+
+        template< unsigned N, class T >
+        struct compute_buffer_objects< store_n_bytes<N>, T >
+        {
+            BOOST_STATIC_CONSTANT( unsigned, value = N / sizeof(T) );
+        };
+    }
+
+    struct default_grow_policy
+    {
+        template< class SizeType >
+        static SizeType new_capacity( SizeType capacity )
+        {
+            //
+            // @remark: we grow the capacity quite agressively.
+            //          this is justified since we aim to minimize
+            //          heap-allocations, and because we mostly use
+            //          the buffer locally.
+            return capacity * 4u;
+        }
+
+        template< class SizeType >
+        static bool should_shrink( SizeType, SizeType )
+        {
+            //
+            // @remark: when defining a new grow policy, one might
+            //          choose that if the waated space is less
+            //          than a certain percentage, then it is of
+            //          little use to shrink.
+            //
+            return true;
+        }
+    };
+
+    template< class T,
+              class StackBufferPolicy = store_n_objects<256>,
+              class GrowPolicy        = default_grow_policy,
+              class Allocator         = std::allocator<T> >
+    class auto_buffer;
+
+
+
+    template
+    <
+        class T,
+        class StackBufferPolicy,
+        class GrowPolicy,
+        class Allocator
+    >
+    class auto_buffer : Allocator
+    {
+    private:
+        enum { N = auto_buffer_detail::
+                   compute_buffer_objects<StackBufferPolicy,T>::value };
+
+        BOOST_STATIC_CONSTANT( bool, is_stack_buffer_empty = N == 0u );
+
+        typedef auto_buffer<T, store_n_objects<0>, GrowPolicy, Allocator>
+                                                         local_buffer;
+
+    public:
+        typedef Allocator                                allocator_type;
+        typedef T                                        value_type;
+        typedef typename Allocator::size_type            size_type;
+        typedef typename Allocator::difference_type      difference_type;
+        typedef T*                                       pointer;
+        typedef typename Allocator::pointer              allocator_pointer;
+        typedef const T*                                 const_pointer;
+        typedef T&                                       reference;
+        typedef const T&                                 const_reference;
+        typedef pointer                                  iterator;
+        typedef const_pointer                            const_iterator;
+        typedef boost::reverse_iterator<iterator>        reverse_iterator;
+        typedef boost::reverse_iterator<const_iterator>  const_reverse_iterator;
+        typedef typename boost::mpl::if_c< boost::has_trivial_assign<T>::value
+                                           && sizeof(T) <= sizeof(long double),
+                                          const value_type,
+                                          const_reference >::type
+                                                      optimized_const_reference;
+    private:
+
+        pointer allocate( size_type capacity_arg )
+        {
+            if( capacity_arg > N )
+                return &*get_allocator().allocate( capacity_arg );
+            else
+                return static_cast<T*>( members_.address() );
+        }
+
+        void deallocate( pointer where, size_type capacity_arg )
+        {
+            if( capacity_arg <= N )
+                return;
+            get_allocator().deallocate( allocator_pointer(where), capacity_arg );
+        }
+
+        template< class I >
+        static void copy_impl( I begin, I end, pointer where, std::random_access_iterator_tag )
+        {
+            copy_rai( begin, end, where, boost::has_trivial_assign<T>() );
+        }
+
+        static void copy_rai( const T* begin, const T* end,
+                              pointer where, const boost::true_type& )
+        {
+            std::memcpy( where, begin, sizeof(T) * std::distance(begin,end) );
+        }
+
+        template< class I, bool b >
+        static void copy_rai( I begin, I end,
+                              pointer where, const boost::integral_constant<bool, b>& )
+        {
+            std::uninitialized_copy( begin, end, where );
+        }
+
+        template< class I >
+        static void copy_impl( I begin, I end, pointer where, std::bidirectional_iterator_tag )
+        {
+            std::uninitialized_copy( begin, end, where );
+        }
+
+        template< class I >
+        static void copy_impl( I begin, I end, pointer where )
+        {
+            copy_impl( begin, end, where,
+                       typename std::iterator_traits<I>::iterator_category() );
+        }
+
+        template< class I, class I2 >
+        static void assign_impl( I begin, I end, I2 where )
+        {
+            assign_impl( begin, end, where, boost::has_trivial_assign<T>() );
+        }
+
+        template< class I, class I2 >
+        static void assign_impl( I begin, I end, I2 where, const boost::true_type& )
+        {
+            std::memcpy( where, begin, sizeof(T) * std::distance(begin,end) );
+        }
+
+        template< class I, class I2 >
+        static void assign_impl( I begin, I end, I2 where, const boost::false_type& )
+        {
+            for( ; begin != end; ++begin, ++where )
+                *where = *begin;
+        }
+
+        void unchecked_push_back_n( size_type n, const boost::true_type& )
+        {
+            std::uninitialized_fill( end(), end() + n, T() );
+            size_ += n;
+        }
+
+        void unchecked_push_back_n( size_type n, const boost::false_type& )
+        {
+            for( size_type i = 0u; i < n; ++i )
+                unchecked_push_back();
+        }
+
+        void auto_buffer_destroy( pointer where, const boost::false_type& )
+        {
+            (*where).~T();
+        }
+
+        void auto_buffer_destroy( pointer, const boost::true_type& )
+        { }
+
+        void auto_buffer_destroy( pointer where )
+        {
+            auto_buffer_destroy( where, boost::has_trivial_destructor<T>() );
+        }
+
+        void destroy_back_n( size_type n, const boost::false_type& )
+        {
+            BOOST_ASSERT( n > 0 );
+            pointer buffer  = buffer_ + size_ - 1u;
+            pointer new_end = buffer - n;
+            for( ; buffer > new_end; --buffer )
+                auto_buffer_destroy( buffer );
+        }
+
+        void destroy_back_n( size_type, const boost::true_type& )
+        { }
+
+        void destroy_back_n( size_type n )
+        {
+            destroy_back_n( n, boost::has_trivial_destructor<T>() );
+        }
+
+        void auto_buffer_destroy( const boost::false_type& x )
+        {
+            if( size_ )
+                destroy_back_n( size_, x );
+            deallocate( buffer_, members_.capacity_ );
+        }
+
+        void auto_buffer_destroy( const boost::true_type& )
+        {
+            deallocate( buffer_, members_.capacity_ );
+        }
+
+        pointer move_to_new_buffer( size_type new_capacity, const boost::false_type& )
+        {
+            pointer new_buffer = allocate( new_capacity ); // strong
+            boost::multi_index::detail::scope_guard guard =
+                boost::multi_index::detail::make_obj_guard( *this,
+                                                            &auto_buffer::deallocate,
+                                                            new_buffer,
+                                                            new_capacity );
+            copy_impl( begin(), end(), new_buffer ); // strong
+            guard.dismiss();                         // nothrow
+            return new_buffer;
+        }
+
+        pointer move_to_new_buffer( size_type new_capacity, const boost::true_type& )
+        {
+            pointer new_buffer = allocate( new_capacity ); // strong
+            copy_impl( begin(), end(), new_buffer );       // nothrow
+            return new_buffer;
+        }
+
+        void reserve_impl( size_type new_capacity )
+        {
+            pointer new_buffer = move_to_new_buffer( new_capacity,
+                                                 boost::has_nothrow_copy<T>() );
+            (*this).~auto_buffer();
+            buffer_   = new_buffer;
+            members_.capacity_ = new_capacity;
+            BOOST_ASSERT( size_ <= members_.capacity_ );
+        }
+
+        size_type new_capacity_impl( size_type n )
+        {
+            BOOST_ASSERT( n > members_.capacity_ );
+            size_type new_capacity = GrowPolicy::new_capacity( members_.capacity_ );
+            // @todo: consider to check for allocator.max_size()
+            return (std::max)(new_capacity,n);
+        }
+
+        static void swap_helper( auto_buffer& l, auto_buffer& r,
+                                 const boost::true_type& )
+        {
+            BOOST_ASSERT( l.is_on_stack() && r.is_on_stack() );
+
+            auto_buffer temp( l.begin(), l.end() );
+            assign_impl( r.begin(), r.end(), l.begin() );
+            assign_impl( temp.begin(), temp.end(), r.begin() );
+            boost::swap( l.size_, r.size_ );
+            boost::swap( l.members_.capacity_, r.members_.capacity_ );
+        }
+
+        static void swap_helper( auto_buffer& l, auto_buffer& r,
+                                 const boost::false_type& )
+        {
+            BOOST_ASSERT( l.is_on_stack() && r.is_on_stack() );
+            size_type min_size    = (std::min)(l.size_,r.size_);
+            size_type max_size    = (std::max)(l.size_,r.size_);
+            size_type diff        = max_size - min_size;
+            auto_buffer* smallest = l.size_ == min_size ? &l : &r;
+            auto_buffer* largest  = smallest == &l ? &r : &l;
+
+            // @remark: the implementation below is not as fast
+            //          as it could be if we assumed T had a default
+            //          constructor.
+
+            size_type i = 0u;
+            for(  ; i < min_size; ++i )
+                boost::swap( (*smallest)[i], (*largest)[i] );
+
+            for( ; i < max_size; ++i )
+                smallest->unchecked_push_back( (*largest)[i] );
+
+            largest->pop_back_n( diff );
+            boost::swap( l.members_.capacity_, r.members_.capacity_ );
+        }
+
+        void one_sided_swap( auto_buffer& temp ) // nothrow
+        {
+            BOOST_ASSERT( !temp.is_on_stack() );
+            this->~auto_buffer();
+            // @remark: must be nothrow
+            get_allocator()    = temp.get_allocator();
+            members_.capacity_ = temp.members_.capacity_;
+            buffer_            = temp.buffer_;
+            BOOST_ASSERT( temp.size_ >= size_ + 1u );
+            size_              = temp.size_;
+            temp.buffer_       = 0;
+            BOOST_ASSERT( temp.is_valid() );
+        }
+
+        template< class I >
+        void insert_impl( const_iterator before, I begin_arg, I end_arg,
+                          std::input_iterator_tag )
+        {
+            for( ; begin_arg != end_arg; ++begin_arg )
+            {
+                before = insert( before, *begin_arg );
+                ++before;
+            }
+        }
+
+        void grow_back( size_type n, const boost::true_type& )
+        {
+            BOOST_ASSERT( size_ + n <= members_.capacity_ );
+            size_ += n;
+        }
+
+        void grow_back( size_type n, const boost::false_type& )
+        {
+            unchecked_push_back_n(n);
+        }
+
+        void grow_back( size_type n )
+        {
+            grow_back( n, boost::has_trivial_constructor<T>() );
+        }
+
+        void grow_back_one( const boost::true_type& )
+        {
+            BOOST_ASSERT( size_ + 1 <= members_.capacity_ );
+            size_ += 1;
+        }
+
+        void grow_back_one( const boost::false_type& )
+        {
+            unchecked_push_back();
+        }
+
+        void grow_back_one()
+        {
+            grow_back_one( boost::has_trivial_constructor<T>() );
+        }
+
+        template< class I >
+        void insert_impl( const_iterator before, I begin_arg, I end_arg,
+                          std::forward_iterator_tag )
+        {
+            difference_type n = std::distance(begin_arg, end_arg);
+
+            if( size_ + n <= members_.capacity_ )
+            {
+                bool is_back_insertion = before == cend();
+                if( !is_back_insertion )
+                {
+                    grow_back( n );
+                    iterator where = const_cast<T*>(before);
+                    std::copy( before, cend() - n, where + n );
+                    assign_impl( begin_arg, end_arg, where );
+                }
+                else
+                {
+                    unchecked_push_back( begin_arg, end_arg );
+                }
+                BOOST_ASSERT( is_valid() );
+                return;
+            }
+
+            auto_buffer temp( new_capacity_impl( size_ + n ) );
+            temp.unchecked_push_back( cbegin(), before );
+            temp.unchecked_push_back( begin_arg, end_arg );
+            temp.unchecked_push_back( before, cend() );
+            one_sided_swap( temp );
+            BOOST_ASSERT( is_valid() );
+        }
+
+    public:
+        bool is_valid() const // invariant
+        {
+            // @remark: allowed for N==0 and when
+            //          using a locally instance
+            //          in insert()/one_sided_swap()
+            if( buffer_ == 0 )
+                return true;
+
+            if( members_.capacity_ < N )
+                return false;
+
+            if( !is_on_stack() && members_.capacity_ <= N )
+                return false;
+
+            if( buffer_ == members_.address() )
+                if( members_.capacity_ > N )
+                    return false;
+
+            if( size_ > members_.capacity_ )
+                return false;
+
+            return true;
+        }
+
+        auto_buffer()
+            : members_( N ),
+              buffer_( static_cast<T*>(members_.address()) ),
+              size_( 0u )
+        {
+            BOOST_ASSERT( is_valid() );
+        }
+
+        auto_buffer( const auto_buffer& r )
+            : members_( (std::max)(r.size_,size_type(N)) ),
+              buffer_( allocate( members_.capacity_ ) ),
+              size_( 0 )
+        {
+            copy_impl( r.begin(), r.end(), buffer_ );
+            size_ = r.size_;
+            BOOST_ASSERT( is_valid() );
+        }
+
+        auto_buffer& operator=( const auto_buffer& r ) // basic
+        {
+            if( this == &r )
+                return *this;
+
+            difference_type diff = size_ - r.size_;
+            if( diff >= 0 )
+            {
+                pop_back_n( static_cast<size_type>(diff) );
+                assign_impl( r.begin(), r.end(), begin() );
+            }
+            else
+            {
+                if( members_.capacity_ >= r.size() )
+                {
+                    unchecked_push_back_n( static_cast<size_type>(-diff) );
+                    assign_impl( r.begin(), r.end(), begin() );
+                }
+                else
+                {
+                    // @remark: we release memory as early as possible
+                    //          since we only give the basic guarantee
+                    (*this).~auto_buffer();
+                    buffer_ = 0;
+                    pointer new_buffer = allocate( r.size() );
+                    boost::multi_index::detail::scope_guard guard =
+                        boost::multi_index::detail::make_obj_guard( *this,
+                                                                    &auto_buffer::deallocate,
+                                                                    new_buffer,
+                                                                    r.size() );
+                    copy_impl( r.begin(), r.end(), new_buffer );
+                    guard.dismiss();
+                    buffer_            = new_buffer;
+                    members_.capacity_ = r.size();
+                    size_              = members_.capacity_;
+                }
+            }
+
+            BOOST_ASSERT( size() == r.size() );
+            BOOST_ASSERT( is_valid() );
+            return *this;
+        }
+
+        explicit auto_buffer( size_type capacity_arg )
+            : members_( (std::max)(capacity_arg, size_type(N)) ),
+              buffer_( allocate(members_.capacity_) ),
+              size_( 0 )
+        {
+            BOOST_ASSERT( is_valid() );
+        }
+
+        auto_buffer( size_type size_arg, optimized_const_reference init_value )
+            : members_( (std::max)(size_arg, size_type(N)) ),
+              buffer_( allocate(members_.capacity_) ),
+              size_( 0 )
+        {
+            std::uninitialized_fill( buffer_, buffer_ + size_arg, init_value );
+            size_ = size_arg;
+            BOOST_ASSERT( is_valid() );
+        }
+
+        auto_buffer( size_type capacity_arg, const allocator_type& a )
+            : allocator_type( a ),
+              members_( (std::max)(capacity_arg, size_type(N)) ),
+              buffer_( allocate(members_.capacity_) ),
+              size_( 0 )
+        {
+            BOOST_ASSERT( is_valid() );
+        }
+
+        auto_buffer( size_type size_arg, optimized_const_reference init_value,
+                     const allocator_type& a )
+            : allocator_type( a ),
+              members_( (std::max)(size_arg, size_type(N)) ),
+              buffer_( allocate(members_.capacity_) ),
+              size_( 0 )
+        {
+            std::uninitialized_fill( buffer_, buffer_ + size_arg, init_value );
+            size_ = size_arg;
+            BOOST_ASSERT( is_valid() );
+        }
+
+        template< class ForwardIterator >
+        auto_buffer( ForwardIterator begin_arg, ForwardIterator end_arg )
+            :
+              members_( std::distance(begin_arg, end_arg) ),
+              buffer_( allocate(members_.capacity_) ),
+              size_( 0 )
+        {
+            copy_impl( begin_arg, end_arg, buffer_ );
+            size_ = members_.capacity_;
+            if( members_.capacity_ < N )
+                members_.capacity_ = N;
+            BOOST_ASSERT( is_valid() );
+        }
+
+        template< class ForwardIterator >
+        auto_buffer( ForwardIterator begin_arg, ForwardIterator end_arg,
+                     const allocator_type& a )
+            : allocator_type( a ),
+              members_( std::distance(begin_arg, end_arg) ),
+              buffer_( allocate(members_.capacity_) ),
+              size_( 0 )
+        {
+            copy_impl( begin_arg, end_arg, buffer_ );
+            size_ = members_.capacity_;
+            if( members_.capacity_ < N )
+                members_.capacity_ = N;
+            BOOST_ASSERT( is_valid() );
+        }
+
+        ~auto_buffer()
+        {
+            BOOST_ASSERT( is_valid() );
+            if( buffer_ ) // do we need this check? Yes, but only
+                // for N = 0u + local instances in one_sided_swap()
+                auto_buffer_destroy( boost::has_trivial_destructor<T>() );
+        }
+
+    public:
+        bool empty() const
+        {
+            return size_ == 0;
+        }
+
+        bool full() const
+        {
+            return size_ == members_.capacity_;
+        }
+
+        bool is_on_stack() const
+        {
+            return members_.capacity_ <= N;
+        }
+
+        size_type size() const
+        {
+            return size_;
+        }
+
+        size_type capacity() const
+        {
+            return members_.capacity_;
+        }
+
+    public:
+        pointer data()
+        {
+            return buffer_;
+        }
+
+        const_pointer data() const
+        {
+            return buffer_;
+        }
+
+        allocator_type& get_allocator()
+        {
+            return static_cast<allocator_type&>(*this);
+        }
+
+        const allocator_type& get_allocator() const
+        {
+            return static_cast<const allocator_type&>(*this);
+        }
+
+    public:
+        iterator begin()
+        {
+            return buffer_;
+        }
+
+        const_iterator begin() const
+        {
+            return buffer_;
+        }
+
+        iterator end()
+        {
+            return buffer_ + size_;
+        }
+
+        const_iterator end() const
+        {
+            return buffer_ + size_;
+        }
+
+        reverse_iterator rbegin()
+        {
+            return reverse_iterator(end());
+        }
+
+        const_reverse_iterator rbegin() const
+        {
+            return const_reverse_iterator(end());
+        }
+
+        reverse_iterator rend()
+        {
+            return reverse_iterator(begin());
+        }
+
+        const_reverse_iterator rend() const
+        {
+            return const_reverse_iterator(begin());
+        }
+
+        const_iterator cbegin() const
+        {
+            return const_cast<const auto_buffer*>(this)->begin();
+        }
+
+        const_iterator cend() const
+        {
+            return const_cast<const auto_buffer*>(this)->end();
+        }
+
+        const_reverse_iterator crbegin() const
+        {
+            return const_cast<const auto_buffer*>(this)->rbegin();
+        }
+
+        const_reverse_iterator crend() const
+        {
+            return const_cast<const auto_buffer*>(this)->rend();
+        }
+
+    public:
+        reference front()
+        {
+            return buffer_[0];
+        }
+
+        optimized_const_reference front() const
+        {
+            return buffer_[0];
+        }
+
+        reference back()
+        {
+            return buffer_[size_-1];
+        }
+
+        optimized_const_reference back() const
+        {
+            return buffer_[size_-1];
+        }
+
+        reference operator[]( size_type n )
+        {
+            BOOST_ASSERT( n < size_ );
+            return buffer_[n];
+        }
+
+        optimized_const_reference operator[]( size_type n ) const
+        {
+            BOOST_ASSERT( n < size_ );
+            return buffer_[n];
+        }
+
+        void unchecked_push_back()
+        {
+            BOOST_ASSERT( !full() );
+            new (buffer_ + size_) T;
+            ++size_;
+        }
+
+        void unchecked_push_back_n( size_type n )
+        {
+            BOOST_ASSERT( size_ + n <= members_.capacity_ );
+            unchecked_push_back_n( n, boost::has_trivial_assign<T>() );
+        }
+
+        void unchecked_push_back( optimized_const_reference x ) // non-growing
+        {
+            BOOST_ASSERT( !full() );
+            new (buffer_ + size_) T( x );
+            ++size_;
+        }
+
+        template< class ForwardIterator >
+        void unchecked_push_back( ForwardIterator begin_arg,
+                                  ForwardIterator end_arg ) // non-growing
+        {
+            BOOST_ASSERT( size_ + std::distance(begin_arg, end_arg) <= members_.capacity_ );
+            copy_impl( begin_arg, end_arg, buffer_ + size_ );
+            size_ += std::distance(begin_arg, end_arg);
+        }
+
+        void reserve_precisely( size_type n )
+        {
+            BOOST_ASSERT( members_.capacity_  >= N );
+
+            if( n <= members_.capacity_ )
+                return;
+            reserve_impl( n );
+            BOOST_ASSERT( members_.capacity_ == n );
+        }
+
+        void reserve( size_type n ) // strong
+        {
+            BOOST_ASSERT( members_.capacity_  >= N );
+
+            if( n <= members_.capacity_ )
+                return;
+
+            reserve_impl( new_capacity_impl( n ) );
+            BOOST_ASSERT( members_.capacity_ >= n );
+        }
+
+        void push_back()
+        {
+            if( size_ != members_.capacity_ )
+            {
+                unchecked_push_back();
+            }
+            else
+            {
+                reserve( size_ + 1u );
+                unchecked_push_back();
+            }
+        }
+
+        void push_back( optimized_const_reference x )
+        {
+            if( size_ != members_.capacity_ )
+            {
+                unchecked_push_back( x );
+            }
+            else
+            {
+               reserve( size_ + 1u );
+               unchecked_push_back( x );
+            }
+        }
+
+        template< class ForwardIterator >
+        void push_back( ForwardIterator begin_arg, ForwardIterator end_arg )
+        {
+            difference_type diff = std::distance(begin_arg, end_arg);
+            if( size_ + diff > members_.capacity_ )
+                reserve( size_ + diff );
+            unchecked_push_back( begin_arg, end_arg );
+        }
+
+        iterator insert( const_iterator before, optimized_const_reference x ) // basic
+        {
+            // @todo: consider if we want to support x in 'this'
+            if( size_ < members_.capacity_ )
+            {
+                bool is_back_insertion = before == cend();
+                iterator where = const_cast<T*>(before);
+
+                if( !is_back_insertion )
+                {
+                    grow_back_one();
+                    std::copy( before, cend() - 1u, where + 1u );
+                    *where = x;
+                    BOOST_ASSERT( is_valid() );
+                 }
+                else
+                {
+                    unchecked_push_back( x );
+                }
+                return where;
+            }
+
+            auto_buffer temp( new_capacity_impl( size_ + 1u ) );
+            temp.unchecked_push_back( cbegin(), before );
+            iterator result = temp.end();
+            temp.unchecked_push_back( x );
+            temp.unchecked_push_back( before, cend() );
+            one_sided_swap( temp );
+            BOOST_ASSERT( is_valid() );
+            return result;
+        }
+
+        void insert( const_iterator before, size_type n,
+                     optimized_const_reference x )
+        {
+            // @todo: see problems above
+            if( size_ + n <= members_.capacity_ )
+            {
+                grow_back( n );
+                iterator where = const_cast<T*>(before);
+                std::copy( before, cend() - n, where + n );
+                std::fill( where, where + n, x );
+                BOOST_ASSERT( is_valid() );
+                return;
+            }
+
+            auto_buffer temp( new_capacity_impl( size_ + n ) );
+            temp.unchecked_push_back( cbegin(), before );
+            std::uninitialized_fill_n( temp.end(), n, x );
+            temp.size_ += n;
+            temp.unchecked_push_back( before, cend() );
+            one_sided_swap( temp );
+            BOOST_ASSERT( is_valid() );
+        }
+
+        template< class ForwardIterator >
+        void insert( const_iterator before,
+                     ForwardIterator begin_arg, ForwardIterator end_arg ) // basic
+        {
+            typedef typename std::iterator_traits<ForwardIterator>
+                ::iterator_category category;
+            insert_impl( before, begin_arg, end_arg, category() );
+        }
+
+        void pop_back()
+        {
+            BOOST_ASSERT( !empty() );
+            auto_buffer_destroy( buffer_ + size_ - 1, boost::has_trivial_destructor<T>() );
+            --size_;
+        }
+
+        void pop_back_n( size_type n )
+        {
+            BOOST_ASSERT( n <= size_ );
+            if( n )
+            {
+                destroy_back_n( n );
+                size_ -= n;
+            }
+        }
+
+        void clear()
+        {
+            pop_back_n( size_ );
+        }
+
+        iterator erase( const_iterator where )
+        {
+            BOOST_ASSERT( !empty() );
+            BOOST_ASSERT( cbegin() <= where );
+            BOOST_ASSERT( cend() > where );
+
+            unsigned elements = cend() - where - 1u;
+
+            if( elements > 0u )
+            {
+                const_iterator start = where + 1u;
+                std::copy( start, start + elements,
+                           const_cast<T*>(where) );
+            }
+            pop_back();
+            BOOST_ASSERT( !full() );
+            iterator result = const_cast<T*>( where );
+            BOOST_ASSERT( result <= end() );
+            return result;
+        }
+
+        iterator erase( const_iterator from, const_iterator to )
+        {
+            BOOST_ASSERT( !(std::distance(from,to)>0) ||
+                          !empty() );
+            BOOST_ASSERT( cbegin() <= from );
+            BOOST_ASSERT( cend() >= to );
+
+            unsigned elements = std::distance(to,cend());
+
+            if( elements > 0u )
+            {
+                BOOST_ASSERT( elements > 0u );
+                std::copy( to, to + elements,
+                           const_cast<T*>(from) );
+            }
+            pop_back_n( std::distance(from,to) );
+            BOOST_ASSERT( !full() );
+            iterator result = const_cast<T*>( from );
+            BOOST_ASSERT( result <= end() );
+            return result;
+        }
+
+        void shrink_to_fit()
+        {
+            if( is_on_stack() || !GrowPolicy::should_shrink(size_,members_.capacity_) )
+                return;
+
+            reserve_impl( size_ );
+            members_.capacity_ = (std::max)(size_type(N),members_.capacity_);
+            BOOST_ASSERT( is_on_stack() || size_ == members_.capacity_ );
+            BOOST_ASSERT( !is_on_stack() || size_ <= members_.capacity_ );
+        }
+
+        pointer uninitialized_grow( size_type n ) // strong
+        {
+            if( size_ + n <= members_.capacity_ )
+                reserve( size_ + n );
+
+            pointer res = end();
+            size_ += n;
+            return res;
+        }
+
+        void uninitialized_shrink( size_type n ) // nothrow
+        {
+            // @remark: test for wrap-around
+            BOOST_ASSERT( size_ - n <= members_.capacity_ );
+            size_ -= n;
+        }
+
+        void uninitialized_resize( size_type n )
+        {
+            if( n > size() )
+                uninitialized_grow( n - size() );
+            else if( n < size() )
+                uninitialized_shrink( size() - n );
+
+           BOOST_ASSERT( size() == n );
+        }
+
+        // nothrow  - if both buffer are on the heap, or
+        //          - if one buffer is on the heap and one has
+        //            'has_allocated_buffer() == false', or
+        //          - if copy-construction cannot throw
+        // basic    - otherwise (better guarantee impossible)
+        // requirement: the allocator must be no-throw-swappable
+        void swap( auto_buffer& r )
+        {
+            bool on_stack      = is_on_stack();
+            bool r_on_stack    = r.is_on_stack();
+            bool both_on_heap  = !on_stack && !r_on_stack;
+            if( both_on_heap )
+            {
+                boost::swap( get_allocator(), r.get_allocator() );
+                boost::swap( members_.capacity_, r.members_.capacity_ );
+                boost::swap( buffer_, r.buffer_ );
+                boost::swap( size_, r.size_ );
+                BOOST_ASSERT( is_valid() );
+                BOOST_ASSERT( r.is_valid() );
+                return;
+            }
+
+            BOOST_ASSERT( on_stack || r_on_stack );
+            bool exactly_one_on_stack = (on_stack && !r_on_stack) ||
+                                        (!on_stack && r_on_stack);
+
+            //
+            // Remark: we now know that we can copy into
+            //         the unused stack buffer.
+            //
+            if( exactly_one_on_stack )
+            {
+                auto_buffer* one_on_stack = on_stack ? this : &r;
+                auto_buffer* other        = on_stack ? &r : this;
+                pointer new_buffer = static_cast<T*>(other->members_.address());
+                copy_impl( one_on_stack->begin(), one_on_stack->end(),
+                           new_buffer );                            // strong
+                one_on_stack->~auto_buffer();                       // nothrow
+                boost::swap( get_allocator(), r.get_allocator() );  // assume nothrow
+                boost::swap( members_.capacity_, r.members_.capacity_ );
+                boost::swap( size_, r.size_ );
+                one_on_stack->buffer_ = other->buffer_;
+                other->buffer_        = new_buffer;
+                BOOST_ASSERT( other->is_on_stack() );
+                BOOST_ASSERT( !one_on_stack->is_on_stack() );
+                BOOST_ASSERT( is_valid() );
+                BOOST_ASSERT( r.is_valid() );
+                return;
+            }
+
+            BOOST_ASSERT( on_stack && r_on_stack );
+            swap_helper( *this, r, boost::has_trivial_assign<T>() );
+            BOOST_ASSERT( is_valid() );
+            BOOST_ASSERT( r.is_valid() );
+        }
+
+    private:
+        typedef boost::aligned_storage< N * sizeof(T),
+                                        boost::alignment_of<T>::value >
+                               storage;
+
+        struct members_type : storage /* to enable EBO */
+        {
+            size_type capacity_;
+
+            members_type( size_type capacity )
+               : capacity_(capacity)
+            { }
+
+            void* address() const
+            { return const_cast<storage&>(static_cast<const storage&>(*this)).address(); }
+        };
+
+        members_type members_;
+        pointer      buffer_;
+        size_type    size_;
+
+    };
+
+    template< class T, class SBP, class GP, class A >
+    inline void swap( auto_buffer<T,SBP,GP,A>& l, auto_buffer<T,SBP,GP,A>& r )
+    {
+        l.swap( r );
+    }
+
+    template< class T, class SBP, class GP, class A >
+    inline bool operator==( const auto_buffer<T,SBP,GP,A>& l,
+                            const auto_buffer<T,SBP,GP,A>& r )
+    {
+        if( l.size() != r.size() )
+            return false;
+        return std::equal( l.begin(), l.end(), r.begin() );
+    }
+
+    template< class T, class SBP, class GP, class A >
+    inline bool operator!=( const auto_buffer<T,SBP,GP,A>& l,
+                            const auto_buffer<T,SBP,GP,A>& r )
+    {
+        return !(l == r);
+    }
+
+    template< class T, class SBP, class GP, class A >
+    inline bool operator<( const auto_buffer<T,SBP,GP,A>& l,
+                           const auto_buffer<T,SBP,GP,A>& r )
+    {
+        return std::lexicographical_compare( l.begin(), l.end(),
+                                             r.begin(), r.end() );
+    }
+
+    template< class T, class SBP, class GP, class A >
+    inline bool operator>( const auto_buffer<T,SBP,GP,A>& l,
+                           const auto_buffer<T,SBP,GP,A>& r )
+    {
+        return (r < l);
+    }
+
+    template< class T, class SBP, class GP, class A >
+    inline bool operator<=( const auto_buffer<T,SBP,GP,A>& l,
+                            const auto_buffer<T,SBP,GP,A>& r )
+    {
+        return !(r > l);
+    }
+
+    template< class T, class SBP, class GP, class A >
+    inline bool operator>=( const auto_buffer<T,SBP,GP,A>& l,
+                            const auto_buffer<T,SBP,GP,A>& r )
+    {
+        return !(l < r);
+    }
+
+} // namespace detail
+} // namespace signals2
+}
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/third_party/boost/boost/signals2/detail/foreign_ptr.hpp b/third_party/boost/boost/signals2/detail/foreign_ptr.hpp
new file mode 100644
index 0000000..4349b38
--- /dev/null
+++ b/third_party/boost/boost/signals2/detail/foreign_ptr.hpp
@@ -0,0 +1,185 @@
+
+//  helper code for dealing with tracking non-boost shared_ptr/weak_ptr
+
+// Copyright Frank Mori Hess 2009.
+// Distributed under the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org/libs/signals2 for library home page.
+
+#ifndef BOOST_SIGNALS2_FOREIGN_PTR_HPP
+#define BOOST_SIGNALS2_FOREIGN_PTR_HPP
+
+#include <algorithm>
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/smart_ptr/bad_weak_ptr.hpp>
+#include <boost/utility/swap.hpp>
+
+#ifndef BOOST_NO_CXX11_SMART_PTR
+#include <memory>
+#endif
+
+namespace boost
+{
+  template<typename T> class shared_ptr;
+  template<typename T> class weak_ptr;
+
+  namespace signals2
+  {
+    template<typename WeakPtr> struct weak_ptr_traits
+    {};
+    template<typename T> struct weak_ptr_traits<boost::weak_ptr<T> >
+    {
+      typedef boost::shared_ptr<T> shared_type;
+    };
+#ifndef BOOST_NO_CXX11_SMART_PTR
+    template<typename T> struct weak_ptr_traits<std::weak_ptr<T> >
+    {
+      typedef std::shared_ptr<T> shared_type;
+    };
+#endif
+
+    template<typename SharedPtr> struct shared_ptr_traits
+    {};
+
+    template<typename T> struct shared_ptr_traits<boost::shared_ptr<T> >
+    {
+      typedef boost::weak_ptr<T> weak_type;
+    };
+#ifndef BOOST_NO_CXX11_SMART_PTR
+    template<typename T> struct shared_ptr_traits<std::shared_ptr<T> >
+    {
+      typedef std::weak_ptr<T> weak_type;
+    };
+#endif
+
+    namespace detail
+    {
+      struct foreign_shared_ptr_impl_base
+      {
+        virtual ~foreign_shared_ptr_impl_base() {}
+        virtual void* get() const = 0;
+        virtual foreign_shared_ptr_impl_base * clone() const = 0;
+      };
+
+      template<typename FSP>
+      class foreign_shared_ptr_impl: public foreign_shared_ptr_impl_base
+      {
+      public:
+        foreign_shared_ptr_impl(const FSP &p): _p(p)
+        {}
+        virtual void * get() const
+        {
+          return _p.get();
+        }
+        virtual foreign_shared_ptr_impl * clone() const
+        {
+          return new foreign_shared_ptr_impl(*this);
+        }
+      private:
+        FSP _p;
+      };
+
+      class foreign_void_shared_ptr
+      {
+      public:
+        foreign_void_shared_ptr():
+          _p(0)
+        {}
+        foreign_void_shared_ptr(const foreign_void_shared_ptr &other):
+          _p(other._p->clone())
+        {}
+        template<typename FSP>
+        explicit foreign_void_shared_ptr(const FSP &fsp):
+          _p(new foreign_shared_ptr_impl<FSP>(fsp))
+        {}
+        ~foreign_void_shared_ptr()
+        {
+          delete _p;
+        }
+        foreign_void_shared_ptr & operator=(const foreign_void_shared_ptr &other)
+        {
+          if(&other == this) return *this;
+          foreign_void_shared_ptr(other).swap(*this);
+          return *this;
+        }
+        void swap(foreign_void_shared_ptr &other)
+        {
+          boost::swap(_p, other._p);
+        }
+      private:
+        foreign_shared_ptr_impl_base *_p;
+      };
+
+      struct foreign_weak_ptr_impl_base
+      {
+        virtual ~foreign_weak_ptr_impl_base() {}
+        virtual foreign_void_shared_ptr lock() const = 0;
+        virtual bool expired() const = 0;
+        virtual foreign_weak_ptr_impl_base * clone() const = 0;
+      };
+
+      template<typename FWP>
+      class foreign_weak_ptr_impl: public foreign_weak_ptr_impl_base
+      {
+      public:
+        foreign_weak_ptr_impl(const FWP &p): _p(p)
+        {}
+        virtual foreign_void_shared_ptr lock() const
+        {
+          return foreign_void_shared_ptr(_p.lock());
+        }
+        virtual bool expired() const
+        {
+          return _p.expired();
+        }
+        virtual foreign_weak_ptr_impl * clone() const
+        {
+          return new foreign_weak_ptr_impl(*this);
+        }
+      private:
+        FWP _p;
+      };
+
+      class foreign_void_weak_ptr
+      {
+      public:
+        foreign_void_weak_ptr()
+        {}
+        foreign_void_weak_ptr(const foreign_void_weak_ptr &other):
+          _p(other._p->clone())
+        {}
+        template<typename FWP>
+        explicit foreign_void_weak_ptr(const FWP &fwp):
+          _p(new foreign_weak_ptr_impl<FWP>(fwp))
+        {}
+        foreign_void_weak_ptr & operator=(const foreign_void_weak_ptr &other)
+        {
+          if(&other == this) return *this;
+          foreign_void_weak_ptr(other).swap(*this);
+          return *this;
+        }
+        void swap(foreign_void_weak_ptr &other)
+        {
+          boost::swap(_p, other._p);
+        }
+        foreign_void_shared_ptr lock() const
+        {
+          return _p->lock();
+        }
+        bool expired() const
+        {
+          return _p->expired();
+        }
+      private:
+        boost::scoped_ptr<foreign_weak_ptr_impl_base> _p;
+      };
+    } // namespace detail
+
+  } // namespace signals2
+} // namespace boost
+
+#endif  // BOOST_SIGNALS2_FOREIGN_PTR_HPP
diff --git a/third_party/boost/boost/signals2/detail/lwm_pthreads.hpp b/third_party/boost/boost/signals2/detail/lwm_pthreads.hpp
new file mode 100644
index 0000000..fb0dd66
--- /dev/null
+++ b/third_party/boost/boost/signals2/detail/lwm_pthreads.hpp
@@ -0,0 +1,78 @@
+//
+//  boost/signals2/detail/lwm_pthreads.hpp
+//
+//  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
+//  Copyright (c) 2008 Frank Mori Hess
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_SIGNALS2_LWM_PTHREADS_HPP
+#define BOOST_SIGNALS2_LWM_PTHREADS_HPP
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/assert.hpp>
+#include <pthread.h>
+
+namespace boost
+{
+
+namespace signals2
+{
+
+class mutex
+{
+private:
+
+    pthread_mutex_t m_;
+
+    mutex(mutex const &);
+    mutex & operator=(mutex const &);
+
+public:
+
+    mutex()
+    {
+
+// HPUX 10.20 / DCE has a nonstandard pthread_mutex_init
+
+#if defined(__hpux) && defined(_DECTHREADS_)
+        BOOST_VERIFY(pthread_mutex_init(&m_, pthread_mutexattr_default) == 0);
+#else
+        BOOST_VERIFY(pthread_mutex_init(&m_, 0) == 0);
+#endif
+    }
+
+    ~mutex()
+    {
+        BOOST_VERIFY(pthread_mutex_destroy(&m_) == 0);
+    }
+
+    void lock()
+    {
+        BOOST_VERIFY(pthread_mutex_lock(&m_) == 0);
+    }
+
+    bool try_lock()
+    {
+        return pthread_mutex_trylock(&m_) == 0;
+    }
+
+    void unlock()
+    {
+        BOOST_VERIFY(pthread_mutex_unlock(&m_) == 0);
+    }
+};
+
+} // namespace signals2
+
+} // namespace boost
+
+#endif // #ifndef BOOST_SIGNALS2_LWM_PTHREADS_HPP
diff --git a/third_party/boost/boost/signals2/detail/null_output_iterator.hpp b/third_party/boost/boost/signals2/detail/null_output_iterator.hpp
new file mode 100644
index 0000000..9e98695
--- /dev/null
+++ b/third_party/boost/boost/signals2/detail/null_output_iterator.hpp
@@ -0,0 +1,34 @@
+/*
+  An output iterator which simply discards output.
+*/
+// Copyright Frank Mori Hess 2008.
+// Distributed under the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org/libs/signals2 for library home page.
+
+#ifndef BOOST_SIGNALS2_NULL_OUTPUT_ITERATOR_HPP
+#define BOOST_SIGNALS2_NULL_OUTPUT_ITERATOR_HPP
+
+#include <boost/function_output_iterator.hpp>
+
+namespace boost
+{
+  namespace signals2
+  {
+    namespace detail
+    {
+      class does_nothing
+      {
+      public:
+        template<typename T>
+          void operator()(const T&) const
+          {}
+      };
+      typedef boost::function_output_iterator<does_nothing> null_output_iterator;
+    } // namespace detail
+  } // namespace signals2
+} // namespace boost
+
+#endif  // BOOST_SIGNALS2_NULL_OUTPUT_ITERATOR_HPP
diff --git a/third_party/boost/boost/signals2/detail/preprocessed_arg_type.hpp b/third_party/boost/boost/signals2/detail/preprocessed_arg_type.hpp
new file mode 100644
index 0000000..02717c9
--- /dev/null
+++ b/third_party/boost/boost/signals2/detail/preprocessed_arg_type.hpp
@@ -0,0 +1,34 @@
+// Boost.Signals2 library
+
+// Copyright Frank Mori Hess 2007-2009.
+// Copyright Timmo Stange 2007.
+// Copyright Douglas Gregor 2001-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_PREPROCESSED_ARG_TYPE_HPP
+#define BOOST_SIGNALS2_PREPROCESSED_ARG_TYPE_HPP
+
+#include <boost/preprocessor/repetition.hpp>
+#include <boost/signals2/detail/signals_common_macros.hpp>
+
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_PP_INC(BOOST_SIGNALS2_MAX_ARGS))
+#define BOOST_PP_FILENAME_1 <boost/signals2/detail/preprocessed_arg_type_template.hpp>
+#include BOOST_PP_ITERATE()
+
+namespace boost
+{
+  namespace signals2
+  {
+    namespace detail
+    {
+      struct std_functional_base
+      {};
+    } // namespace detail
+  } // namespace signals2
+} // namespace boost
+
+#endif // BOOST_SIGNALS2_PREPROCESSED_ARG_TYPE_HPP
diff --git a/third_party/boost/boost/signals2/detail/preprocessed_arg_type_template.hpp b/third_party/boost/boost/signals2/detail/preprocessed_arg_type_template.hpp
new file mode 100644
index 0000000..4f39433
--- /dev/null
+++ b/third_party/boost/boost/signals2/detail/preprocessed_arg_type_template.hpp
@@ -0,0 +1,39 @@
+// Copyright Frank Mori Hess 2009
+//
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+// This file is included iteratively, and should not be protected from multiple inclusion
+
+#define BOOST_SIGNALS2_NUM_ARGS BOOST_PP_ITERATION()
+
+namespace boost
+{
+  namespace signals2
+  {
+    namespace detail
+    {
+      template<unsigned n BOOST_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+        BOOST_SIGNALS2_ARGS_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+        class BOOST_SIGNALS2_PREPROCESSED_ARG_N_TYPE_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS);
+
+// template<typename T1, typename T2, ... , typename TN> class preprocessed_arg_typeN<n, T1, T2, ..., TN>{...} ...
+#define BOOST_SIGNALS2_PREPROCESSED_ARG_TYPE_CLASS_TEMPLATE_SPECIALIZATION(z, n, data) \
+  template<BOOST_SIGNALS2_ARGS_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)> \
+  class BOOST_SIGNALS2_PREPROCESSED_ARG_N_TYPE_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)<n, \
+    BOOST_SIGNALS2_ARGS_TEMPLATE_INSTANTIATION(BOOST_SIGNALS2_NUM_ARGS)> \
+  { \
+  public: \
+    typedef BOOST_PP_CAT(T, BOOST_PP_INC(n)) type; \
+  };
+      BOOST_PP_REPEAT(BOOST_SIGNALS2_NUM_ARGS, BOOST_SIGNALS2_PREPROCESSED_ARG_TYPE_CLASS_TEMPLATE_SPECIALIZATION, ~)
+
+    } // namespace detail
+  } // namespace signals2
+} // namespace boost
+
+#undef BOOST_SIGNALS2_NUM_ARGS
diff --git a/third_party/boost/boost/signals2/detail/replace_slot_function.hpp b/third_party/boost/boost/signals2/detail/replace_slot_function.hpp
new file mode 100644
index 0000000..de8f425
--- /dev/null
+++ b/third_party/boost/boost/signals2/detail/replace_slot_function.hpp
@@ -0,0 +1,32 @@
+// Copyright Frank Mori Hess 2007-2009
+//
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_DETAIL_REPLACE_SLOT_FUNCTION_HPP
+#define BOOST_SIGNALS2_DETAIL_REPLACE_SLOT_FUNCTION_HPP
+
+#include <boost/signals2/slot_base.hpp>
+
+namespace boost
+{
+  namespace signals2
+  {
+    namespace detail
+    {
+      template<typename ResultSlot, typename SlotIn, typename SlotFunction>
+        ResultSlot replace_slot_function(const SlotIn &slot_in, const SlotFunction &fun)
+      {
+        ResultSlot slot(fun);
+        slot.track(slot_in);
+        return slot;
+      }
+    } // namespace detail
+  } // namespace signals2
+} // namespace boost
+
+#endif // BOOST_SIGNALS2_DETAIL_REPLACE_SLOT_FUNCTION_HPP
diff --git a/third_party/boost/boost/signals2/detail/result_type_wrapper.hpp b/third_party/boost/boost/signals2/detail/result_type_wrapper.hpp
new file mode 100644
index 0000000..35dea7c
--- /dev/null
+++ b/third_party/boost/boost/signals2/detail/result_type_wrapper.hpp
@@ -0,0 +1,72 @@
+// Boost.Signals2 library
+
+// Copyright Douglas Gregor 2001-2004.
+// Copyright Frank Mori Hess 2007. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_RESULT_TYPE_WRAPPER_HPP
+#define BOOST_SIGNALS2_RESULT_TYPE_WRAPPER_HPP
+
+#include <boost/config.hpp>
+
+namespace boost {
+  namespace signals2 {
+    namespace detail {
+      // A placeholder for void on compilers that don't support void returns
+      struct void_type {};
+
+      // Replaces void with void_type
+      template<typename R>
+      struct nonvoid {
+        typedef R type;
+      };
+      template<>
+      struct nonvoid<void> {
+        typedef void_type type;
+      };
+
+      // Replaces void with void_type only if compiler doesn't support void returns
+      template<typename R>
+      struct result_type_wrapper {
+        typedef R type;
+      };
+#ifdef BOOST_NO_VOID_RETURNS
+      template<>
+      struct result_type_wrapper<void> {
+        typedef void_type type;
+      };
+#endif
+
+      // specialization deals with possible void return from combiners
+      template<typename R> class combiner_invoker
+      {
+      public:
+        typedef R result_type;
+        template<typename Combiner, typename InputIterator>
+          result_type operator()(Combiner &combiner,
+          InputIterator first, InputIterator last) const
+        {
+          return combiner(first, last);
+        }
+      };
+      template<> class combiner_invoker<void>
+      {
+      public:
+        typedef result_type_wrapper<void>::type result_type;
+        template<typename Combiner, typename InputIterator>
+          result_type operator()(Combiner &combiner,
+          InputIterator first, InputIterator last) const
+        {
+          combiner(first, last);
+          return result_type();
+        }
+      };
+    } // end namespace detail
+  } // end namespace signals2
+} // end namespace boost
+
+#endif // BOOST_SIGNALS2_RESULT_TYPE_WRAPPER_HPP
diff --git a/third_party/boost/boost/signals2/detail/signal_template.hpp b/third_party/boost/boost/signals2/detail/signal_template.hpp
new file mode 100644
index 0000000..cbaca65
--- /dev/null
+++ b/third_party/boost/boost/signals2/detail/signal_template.hpp
@@ -0,0 +1,864 @@
+/*
+  Template for Signa1, Signal2, ... classes that support signals
+  with 1, 2, ... parameters
+
+  Begin: 2007-01-23
+*/
+// Copyright Frank Mori Hess 2007-2008
+//
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// This file is included iteratively, and should not be protected from multiple inclusion
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+#define BOOST_SIGNALS2_NUM_ARGS BOOST_PP_ITERATION()
+#else
+#define BOOST_SIGNALS2_NUM_ARGS 1
+#endif
+
+// R, T1, T2, ..., TN, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION \
+  BOOST_SIGNALS2_SIGNATURE_TEMPLATE_INSTANTIATION(BOOST_SIGNALS2_NUM_ARGS), \
+  Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex
+
+namespace boost
+{
+  namespace signals2
+  {
+    namespace detail
+    {
+      // helper for bound_extended_slot_function that handles specialization for void return
+      template<typename R>
+        class BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_INVOKER_N(BOOST_SIGNALS2_NUM_ARGS)
+      {
+      public:
+        typedef R result_type;
+        template<typename ExtendedSlotFunction BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+          BOOST_SIGNALS2_ARGS_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+          result_type operator()(ExtendedSlotFunction &func, const connection &conn
+            BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+            BOOST_SIGNALS2_FULL_FORWARD_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const
+        {
+          return func(conn BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+            BOOST_SIGNALS2_FORWARDED_ARGS(BOOST_SIGNALS2_NUM_ARGS));
+        }
+      };
+#ifdef BOOST_NO_VOID_RETURNS
+      template<>
+        class BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_INVOKER_N(BOOST_SIGNALS2_NUM_ARGS)<void>
+      {
+      public:
+        typedef result_type_wrapper<void>::type result_type;
+        template<typename ExtendedSlotFunction BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+          BOOST_SIGNALS2_ARGS_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+          result_type operator()(ExtendedSlotFunction &func, const connection &conn
+            BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+            BOOST_SIGNALS2_FULL_FORWARD_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const
+        {
+          func(conn BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+            BOOST_SIGNALS2_FORWARDED_ARGS(BOOST_SIGNALS2_NUM_ARGS));
+          return result_type();
+        }
+      };
+#endif
+// wrapper around an signalN::extended_slot_function which binds the
+// connection argument so it looks like a normal
+// signalN::slot_function
+
+      template<typename ExtendedSlotFunction>
+        class BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N(BOOST_SIGNALS2_NUM_ARGS)
+      {
+      public:
+        typedef typename result_type_wrapper<typename ExtendedSlotFunction::result_type>::type result_type;
+        BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N(BOOST_SIGNALS2_NUM_ARGS)(const ExtendedSlotFunction &fun):
+          _fun(fun), _connection(new connection)
+        {}
+        void set_connection(const connection &conn)
+        {
+          *_connection = conn;
+        }
+
+#if BOOST_SIGNALS2_NUM_ARGS > 0
+        template<BOOST_SIGNALS2_ARGS_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+#endif // BOOST_SIGNALS2_NUM_ARGS > 0
+          result_type operator()(BOOST_SIGNALS2_FULL_FORWARD_ARGS(BOOST_SIGNALS2_NUM_ARGS))
+        {
+          return BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_INVOKER_N(BOOST_SIGNALS2_NUM_ARGS)
+            <typename ExtendedSlotFunction::result_type>()
+            (_fun, *_connection BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+              BOOST_SIGNALS2_FORWARDED_ARGS(BOOST_SIGNALS2_NUM_ARGS));
+        }
+        // const overload
+#if BOOST_SIGNALS2_NUM_ARGS > 0
+        template<BOOST_SIGNALS2_ARGS_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+#endif // BOOST_SIGNALS2_NUM_ARGS > 0
+          result_type operator()(BOOST_SIGNALS2_FULL_FORWARD_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const
+        {
+          return BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_INVOKER_N(BOOST_SIGNALS2_NUM_ARGS)
+            <typename ExtendedSlotFunction::result_type>()
+            (_fun, *_connection BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+              BOOST_SIGNALS2_FORWARDED_ARGS(BOOST_SIGNALS2_NUM_ARGS));
+        }
+        template<typename T>
+          bool operator==(const T &other) const
+        {
+          return _fun == other;
+        }
+      private:
+        BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N(BOOST_SIGNALS2_NUM_ARGS)()
+        {}
+
+        ExtendedSlotFunction _fun;
+        boost::shared_ptr<connection> _connection;
+      };
+
+      template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+        class BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS);
+
+      template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+      class BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION
+      {
+      public:
+        typedef SlotFunction slot_function_type;
+        // typedef slotN<Signature, SlotFunction> slot_type;
+        typedef BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+          <BOOST_SIGNALS2_SIGNATURE_TEMPLATE_INSTANTIATION(BOOST_SIGNALS2_NUM_ARGS),
+          slot_function_type> slot_type;
+        typedef ExtendedSlotFunction extended_slot_function_type;
+        // typedef slotN+1<R, const connection &, T1, T2, ..., TN, extended_slot_function_type> extended_slot_type;
+        typedef BOOST_SIGNALS2_EXTENDED_SLOT_TYPE(BOOST_SIGNALS2_NUM_ARGS) extended_slot_type;
+        typedef typename nonvoid<typename slot_function_type::result_type>::type nonvoid_slot_result_type;
+      private:
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+        class slot_invoker;
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+        typedef variadic_slot_invoker<nonvoid_slot_result_type, Args...> slot_invoker;
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+        typedef slot_call_iterator_cache<nonvoid_slot_result_type, slot_invoker> slot_call_iterator_cache_type;
+        typedef typename group_key<Group>::type group_key_type;
+        typedef shared_ptr<connection_body<group_key_type, slot_type, Mutex> > connection_body_type;
+        typedef grouped_list<Group, GroupCompare, connection_body_type> connection_list_type;
+        typedef BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N(BOOST_SIGNALS2_NUM_ARGS)<extended_slot_function_type>
+          bound_extended_slot_function_type;
+      public:
+        typedef Combiner combiner_type;
+        typedef typename result_type_wrapper<typename combiner_type::result_type>::type result_type;
+        typedef Group group_type;
+        typedef GroupCompare group_compare_type;
+        typedef typename detail::slot_call_iterator_t<slot_invoker,
+          typename connection_list_type::iterator, connection_body<group_key_type, slot_type, Mutex> > slot_call_iterator;
+
+        BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const combiner_type &combiner_arg,
+          const group_compare_type &group_compare):
+          _shared_state(new invocation_state(connection_list_type(group_compare), combiner_arg)),
+          _garbage_collector_it(_shared_state->connection_bodies().end()),
+          _mutex(new mutex_type())
+        {}
+        // connect slot
+        connection connect(const slot_type &slot, connect_position position = at_back)
+        {
+          garbage_collecting_lock<mutex_type> lock(*_mutex);
+          return nolock_connect(lock, slot, position);
+        }
+        connection connect(const group_type &group,
+          const slot_type &slot, connect_position position = at_back)
+        {
+          garbage_collecting_lock<mutex_type> lock(*_mutex);
+          return nolock_connect(lock, group, slot, position);
+        }
+        // connect extended slot
+        connection connect_extended(const extended_slot_type &ext_slot, connect_position position = at_back)
+        {
+          garbage_collecting_lock<mutex_type> lock(*_mutex);
+          bound_extended_slot_function_type bound_slot(ext_slot.slot_function());
+          slot_type slot = replace_slot_function<slot_type>(ext_slot, bound_slot);
+          connection conn = nolock_connect(lock, slot, position);
+          bound_slot.set_connection(conn);
+          return conn;
+        }
+        connection connect_extended(const group_type &group,
+          const extended_slot_type &ext_slot, connect_position position = at_back)
+        {
+          garbage_collecting_lock<Mutex> lock(*_mutex);
+          bound_extended_slot_function_type bound_slot(ext_slot.slot_function());
+          slot_type slot = replace_slot_function<slot_type>(ext_slot, bound_slot);
+          connection conn = nolock_connect(lock, group, slot, position);
+          bound_slot.set_connection(conn);
+          return conn;
+        }
+        // disconnect slot(s)
+        void disconnect_all_slots()
+        {
+          shared_ptr<invocation_state> local_state =
+            get_readable_state();
+          typename connection_list_type::iterator it;
+          for(it = local_state->connection_bodies().begin();
+            it != local_state->connection_bodies().end(); ++it)
+          {
+            (*it)->disconnect();
+          }
+        }
+        void disconnect(const group_type &group)
+        {
+          shared_ptr<invocation_state> local_state =
+            get_readable_state();
+          group_key_type group_key(grouped_slots, group);
+          typename connection_list_type::iterator it;
+          typename connection_list_type::iterator end_it =
+            local_state->connection_bodies().upper_bound(group_key);
+          for(it = local_state->connection_bodies().lower_bound(group_key);
+            it != end_it; ++it)
+          {
+            (*it)->disconnect();
+          }
+        }
+        template <typename T>
+        void disconnect(const T &slot)
+        {
+          typedef mpl::bool_<(is_convertible<T, group_type>::value)> is_group;
+          do_disconnect(slot, is_group());
+        }
+        // emit signal
+        result_type operator ()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS))
+        {
+          shared_ptr<invocation_state> local_state;
+          typename connection_list_type::iterator it;
+          {
+            garbage_collecting_lock<mutex_type> list_lock(*_mutex);
+            // only clean up if it is safe to do so
+            if(_shared_state.unique())
+              nolock_cleanup_connections(list_lock, false, 1);
+            /* Make a local copy of _shared_state while holding mutex, so we are
+            thread safe against the combiner or connection list getting modified
+            during invocation. */
+            local_state = _shared_state;
+          }
+          slot_invoker invoker = slot_invoker(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+          slot_call_iterator_cache_type cache(invoker);
+          invocation_janitor janitor(cache, *this, &local_state->connection_bodies());
+          return detail::combiner_invoker<typename combiner_type::result_type>()
+            (
+              local_state->combiner(),
+              slot_call_iterator(local_state->connection_bodies().begin(), local_state->connection_bodies().end(), cache),
+              slot_call_iterator(local_state->connection_bodies().end(), local_state->connection_bodies().end(), cache)
+            );
+        }
+        result_type operator ()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const
+        {
+          shared_ptr<invocation_state> local_state;
+          typename connection_list_type::iterator it;
+          {
+            garbage_collecting_lock<mutex_type> list_lock(*_mutex);
+            // only clean up if it is safe to do so
+            if(_shared_state.unique())
+              nolock_cleanup_connections(list_lock, false, 1);
+            /* Make a local copy of _shared_state while holding mutex, so we are
+            thread safe against the combiner or connection list getting modified
+            during invocation. */
+            local_state = _shared_state;
+          }
+          slot_invoker invoker = slot_invoker(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+          slot_call_iterator_cache_type cache(invoker);
+          invocation_janitor janitor(cache, *this, &local_state->connection_bodies());
+          return detail::combiner_invoker<typename combiner_type::result_type>()
+            (
+              local_state->combiner(),
+              slot_call_iterator(local_state->connection_bodies().begin(), local_state->connection_bodies().end(), cache),
+              slot_call_iterator(local_state->connection_bodies().end(), local_state->connection_bodies().end(), cache)
+            );
+        }
+        std::size_t num_slots() const
+        {
+          shared_ptr<invocation_state> local_state =
+            get_readable_state();
+          typename connection_list_type::iterator it;
+          std::size_t count = 0;
+          for(it = local_state->connection_bodies().begin();
+            it != local_state->connection_bodies().end(); ++it)
+          {
+            if((*it)->connected()) ++count;
+          }
+          return count;
+        }
+        bool empty() const
+        {
+          shared_ptr<invocation_state> local_state =
+            get_readable_state();
+          typename connection_list_type::iterator it;
+          for(it = local_state->connection_bodies().begin();
+            it != local_state->connection_bodies().end(); ++it)
+          {
+            if((*it)->connected()) return false;
+          }
+          return true;
+        }
+        combiner_type combiner() const
+        {
+          unique_lock<mutex_type> lock(*_mutex);
+          return _shared_state->combiner();
+        }
+        void set_combiner(const combiner_type &combiner_arg)
+        {
+          unique_lock<mutex_type> lock(*_mutex);
+          if(_shared_state.unique())
+            _shared_state->combiner() = combiner_arg;
+          else
+            _shared_state.reset(new invocation_state(*_shared_state, combiner_arg));
+        }
+      private:
+        typedef Mutex mutex_type;
+
+        // slot_invoker is passed to slot_call_iterator_t to run slots
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+        class slot_invoker
+        {
+        public:
+          typedef nonvoid_slot_result_type result_type;
+// typename add_reference<Tn>::type
+#define BOOST_SIGNALS2_ADD_REF_TYPE(z, n, data) \
+  typename add_reference<BOOST_PP_CAT(T, BOOST_PP_INC(n))>::type
+// typename add_reference<Tn>::type argn
+#define BOOST_SIGNALS2_ADD_REF_ARG(z, n, data) \
+  BOOST_SIGNALS2_ADD_REF_TYPE(~, n, ~) \
+  BOOST_SIGNALS2_SIGNATURE_ARG_NAME(~, n, ~)
+// typename add_reference<T1>::type arg1, typename add_reference<T2>::type arg2, ..., typename add_reference<Tn>::type argn
+#define BOOST_SIGNALS2_ADD_REF_ARGS(arity) \
+  BOOST_PP_ENUM(arity, BOOST_SIGNALS2_ADD_REF_ARG, ~)
+          slot_invoker(BOOST_SIGNALS2_ADD_REF_ARGS(BOOST_SIGNALS2_NUM_ARGS)) BOOST_PP_EXPR_IF(BOOST_SIGNALS2_NUM_ARGS, :)
+#undef BOOST_SIGNALS2_ADD_REF_ARGS
+
+// m_argn
+#define BOOST_SIGNALS2_M_ARG_NAME(z, n, data) BOOST_PP_CAT(m_arg, BOOST_PP_INC(n))
+// m_argn ( argn )
+#define BOOST_SIGNALS2_MISC_STATEMENT(z, n, data) \
+  BOOST_SIGNALS2_M_ARG_NAME(~, n, ~) ( BOOST_SIGNALS2_SIGNATURE_ARG_NAME(~, n, ~) )
+// m_arg1(arg1), m_arg2(arg2), ..., m_argn(argn)
+            BOOST_PP_ENUM(BOOST_SIGNALS2_NUM_ARGS, BOOST_SIGNALS2_MISC_STATEMENT, ~)
+#undef BOOST_SIGNALS2_MISC_STATEMENT
+          {}
+          result_type operator ()(const connection_body_type &connectionBody) const
+          {
+            return m_invoke<typename slot_type::result_type>(connectionBody);
+          }
+        private:
+          // declare assignment operator private since this class might have reference or const members
+          slot_invoker & operator=(const slot_invoker &);
+
+#define BOOST_SIGNALS2_ADD_REF_M_ARG_STATEMENT(z, n, data) \
+  BOOST_SIGNALS2_ADD_REF_TYPE(~, n, ~) BOOST_SIGNALS2_M_ARG_NAME(~, n, ~) ;
+          BOOST_PP_REPEAT(BOOST_SIGNALS2_NUM_ARGS, BOOST_SIGNALS2_ADD_REF_M_ARG_STATEMENT, ~)
+#undef BOOST_SIGNALS2_ADD_REF_M_ARG_STATEMENT
+#undef BOOST_SIGNALS2_ADD_REF_ARG
+#undef BOOST_SIGNALS2_ADD_REF_TYPE
+
+// m_arg1, m_arg2, ..., m_argn
+#define BOOST_SIGNALS2_M_ARG_NAMES(arity) BOOST_PP_ENUM(arity, BOOST_SIGNALS2_M_ARG_NAME, ~)
+          template<typename SlotResultType>
+          result_type m_invoke(const connection_body_type &connectionBody,
+            typename boost::enable_if<boost::is_void<SlotResultType> >::type * = 0) const
+          {
+            connectionBody->slot().slot_function()(BOOST_SIGNALS2_M_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+            return void_type();
+          }
+          template<typename SlotResultType>
+          result_type m_invoke(const connection_body_type &connectionBody,
+            typename boost::disable_if<boost::is_void<SlotResultType> >::type * = 0) const
+          {
+            return connectionBody->slot().slot_function()(BOOST_SIGNALS2_M_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+          }
+        };
+#undef BOOST_SIGNALS2_M_ARG_NAMES
+#undef BOOST_SIGNALS2_M_ARG_NAME
+
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+        // a struct used to optimize (minimize) the number of shared_ptrs that need to be created
+        // inside operator()
+        class invocation_state
+        {
+        public:
+          invocation_state(const connection_list_type &connections_in,
+            const combiner_type &combiner_in): _connection_bodies(new connection_list_type(connections_in)),
+            _combiner(new combiner_type(combiner_in))
+          {}
+          invocation_state(const invocation_state &other, const connection_list_type &connections_in):
+            _connection_bodies(new connection_list_type(connections_in)),
+            _combiner(other._combiner)
+          {}
+          invocation_state(const invocation_state &other, const combiner_type &combiner_in):
+            _connection_bodies(other._connection_bodies),
+            _combiner(new combiner_type(combiner_in))
+          {}
+          connection_list_type & connection_bodies() { return *_connection_bodies; }
+          const connection_list_type & connection_bodies() const { return *_connection_bodies; }
+          combiner_type & combiner() { return *_combiner; }
+          const combiner_type & combiner() const { return *_combiner; }
+        private:
+          invocation_state(const invocation_state &);
+
+          shared_ptr<connection_list_type> _connection_bodies;
+          shared_ptr<combiner_type> _combiner;
+        };
+        // Destructor of invocation_janitor does some cleanup when a signal invocation completes.
+        // Code can't be put directly in signal's operator() due to complications from void return types.
+        class invocation_janitor: noncopyable
+        {
+        public:
+          typedef BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) signal_type;
+          invocation_janitor
+          (
+            const slot_call_iterator_cache_type &cache,
+            const signal_type &sig,
+            const connection_list_type *connection_bodies
+          ):_cache(cache), _sig(sig), _connection_bodies(connection_bodies)
+          {}
+          ~invocation_janitor()
+          {
+            // force a full cleanup of disconnected slots if there are too many
+            if(_cache.disconnected_slot_count > _cache.connected_slot_count)
+            {
+              _sig.force_cleanup_connections(_connection_bodies);
+            }
+          }
+        private:
+          const slot_call_iterator_cache_type &_cache;
+          const signal_type &_sig;
+          const connection_list_type *_connection_bodies;
+        };
+
+        // clean up disconnected connections
+        void nolock_cleanup_connections_from(garbage_collecting_lock<mutex_type> &lock,
+          bool grab_tracked,
+          const typename connection_list_type::iterator &begin, unsigned count = 0) const
+        {
+          BOOST_ASSERT(_shared_state.unique());
+          typename connection_list_type::iterator it;
+          unsigned i;
+          for(it = begin, i = 0;
+            it != _shared_state->connection_bodies().end() && (count == 0 || i < count);
+            ++i)
+          {
+            bool connected;
+            if(grab_tracked)
+              (*it)->disconnect_expired_slot(lock);
+            connected = (*it)->nolock_nograb_connected();
+            if(connected == false)
+            {
+              it = _shared_state->connection_bodies().erase((*it)->group_key(), it);
+            }else
+            {
+              ++it;
+            }
+          }
+          _garbage_collector_it = it;
+        }
+        // clean up a few connections in constant time
+        void nolock_cleanup_connections(garbage_collecting_lock<mutex_type> &lock,
+          bool grab_tracked, unsigned count) const
+        {
+          BOOST_ASSERT(_shared_state.unique());
+          typename connection_list_type::iterator begin;
+          if(_garbage_collector_it == _shared_state->connection_bodies().end())
+          {
+            begin = _shared_state->connection_bodies().begin();
+          }else
+          {
+            begin = _garbage_collector_it;
+          }
+          nolock_cleanup_connections_from(lock, grab_tracked, begin, count);
+        }
+        /* Make a new copy of the slot list if it is currently being read somewhere else
+        */
+        void nolock_force_unique_connection_list(garbage_collecting_lock<mutex_type> &lock)
+        {
+          if(_shared_state.unique() == false)
+          {
+            _shared_state.reset(new invocation_state(*_shared_state, _shared_state->connection_bodies()));
+            nolock_cleanup_connections_from(lock, true, _shared_state->connection_bodies().begin());
+          }else
+          {
+            /* We need to try and check more than just 1 connection here to avoid corner
+            cases where certain repeated connect/disconnect patterns cause the slot
+            list to grow without limit. */
+            nolock_cleanup_connections(lock, true, 2);
+          }
+        }
+        // force a full cleanup of the connection list
+        void force_cleanup_connections(const connection_list_type *connection_bodies) const
+        {
+          garbage_collecting_lock<mutex_type> list_lock(*_mutex);
+          // if the connection list passed in as a parameter is no longer in use,
+          // we don't need to do any cleanup.
+          if(&_shared_state->connection_bodies() != connection_bodies)
+          {
+            return;
+          }
+          if(_shared_state.unique() == false)
+          {
+            _shared_state.reset(new invocation_state(*_shared_state, _shared_state->connection_bodies()));
+          }
+          nolock_cleanup_connections_from(list_lock, false, _shared_state->connection_bodies().begin());
+        }
+        shared_ptr<invocation_state> get_readable_state() const
+        {
+          unique_lock<mutex_type> list_lock(*_mutex);
+          return _shared_state;
+        }
+        connection_body_type create_new_connection(garbage_collecting_lock<mutex_type> &lock,
+          const slot_type &slot)
+        {
+          nolock_force_unique_connection_list(lock);
+          return connection_body_type(new connection_body<group_key_type, slot_type, Mutex>(slot, _mutex));
+        }
+        void do_disconnect(const group_type &group, mpl::bool_<true> /* is_group */)
+        {
+          disconnect(group);
+        }
+        template<typename T>
+        void do_disconnect(const T &slot, mpl::bool_<false> /* is_group */)
+        {
+          shared_ptr<invocation_state> local_state =
+            get_readable_state();
+          typename connection_list_type::iterator it;
+          for(it = local_state->connection_bodies().begin();
+            it != local_state->connection_bodies().end(); ++it)
+          {
+            garbage_collecting_lock<connection_body_base> lock(**it);
+            if((*it)->nolock_nograb_connected() == false) continue;
+            if((*it)->slot().slot_function() == slot)
+            {
+              (*it)->nolock_disconnect(lock);
+            }else
+            {
+              // check for wrapped extended slot
+              bound_extended_slot_function_type *fp;
+              fp = (*it)->slot().slot_function().template target<bound_extended_slot_function_type>();
+              if(fp && *fp == slot)
+              {
+                (*it)->nolock_disconnect(lock);
+              }
+            }
+          }
+        }
+        // connect slot
+        connection nolock_connect(garbage_collecting_lock<mutex_type> &lock,
+          const slot_type &slot, connect_position position)
+        {
+          connection_body_type newConnectionBody =
+            create_new_connection(lock, slot);
+          group_key_type group_key;
+          if(position == at_back)
+          {
+            group_key.first = back_ungrouped_slots;
+            _shared_state->connection_bodies().push_back(group_key, newConnectionBody);
+          }else
+          {
+            group_key.first = front_ungrouped_slots;
+            _shared_state->connection_bodies().push_front(group_key, newConnectionBody);
+          }
+          newConnectionBody->set_group_key(group_key);
+          return connection(newConnectionBody);
+        }
+        connection nolock_connect(garbage_collecting_lock<mutex_type> &lock,
+          const group_type &group,
+          const slot_type &slot, connect_position position)
+        {
+          connection_body_type newConnectionBody =
+            create_new_connection(lock, slot);
+          // update map to first connection body in group if needed
+          group_key_type group_key(grouped_slots, group);
+          newConnectionBody->set_group_key(group_key);
+          if(position == at_back)
+          {
+            _shared_state->connection_bodies().push_back(group_key, newConnectionBody);
+          }else  // at_front
+          {
+            _shared_state->connection_bodies().push_front(group_key, newConnectionBody);
+          }
+          return connection(newConnectionBody);
+        }
+
+        // _shared_state is mutable so we can do force_cleanup_connections during a const invocation
+        mutable shared_ptr<invocation_state> _shared_state;
+        mutable typename connection_list_type::iterator _garbage_collector_it;
+        // connection list mutex must never be locked when attempting a blocking lock on a slot,
+        // or you could deadlock.
+        const boost::shared_ptr<mutex_type> _mutex;
+      };
+
+      template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+        class BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS);
+    }
+
+    template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_DEFAULTED_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+      class BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS);
+
+    template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+    class BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+      BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION: public signal_base,
+      public detail::BOOST_SIGNALS2_STD_FUNCTIONAL_BASE
+        (typename detail::result_type_wrapper<typename Combiner::result_type>::type)
+    {
+      typedef detail::BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+        <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION> impl_class;
+    public:
+      typedef detail::BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+        <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION> weak_signal_type;
+      friend class detail::BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+        <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION>;
+
+      typedef SlotFunction slot_function_type;
+      // typedef slotN<Signature, SlotFunction> slot_type;
+      typedef typename impl_class::slot_type slot_type;
+      typedef typename impl_class::extended_slot_function_type extended_slot_function_type;
+      typedef typename impl_class::extended_slot_type extended_slot_type;
+      typedef typename slot_function_type::result_type slot_result_type;
+      typedef Combiner combiner_type;
+      typedef typename impl_class::result_type result_type;
+      typedef Group group_type;
+      typedef GroupCompare group_compare_type;
+      typedef typename impl_class::slot_call_iterator
+        slot_call_iterator;
+      typedef typename mpl::identity<BOOST_SIGNALS2_SIGNATURE_FUNCTION_TYPE(BOOST_SIGNALS2_NUM_ARGS)>::type signature_type;
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+// typedef Tn argn_type;
+#define BOOST_SIGNALS2_MISC_STATEMENT(z, n, data) \
+  typedef BOOST_PP_CAT(T, BOOST_PP_INC(n)) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type);
+      BOOST_PP_REPEAT(BOOST_SIGNALS2_NUM_ARGS, BOOST_SIGNALS2_MISC_STATEMENT, ~)
+#undef BOOST_SIGNALS2_MISC_STATEMENT
+#if BOOST_SIGNALS2_NUM_ARGS == 1
+      typedef arg1_type argument_type;
+#elif BOOST_SIGNALS2_NUM_ARGS == 2
+      typedef arg1_type first_argument_type;
+      typedef arg2_type second_argument_type;
+#endif
+
+      template<unsigned n> class arg : public
+        detail::BOOST_SIGNALS2_PREPROCESSED_ARG_N_TYPE_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+        <n BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+        BOOST_SIGNALS2_ARGS_TEMPLATE_INSTANTIATION(BOOST_SIGNALS2_NUM_ARGS)>
+      {};
+
+      BOOST_STATIC_CONSTANT(int, arity = BOOST_SIGNALS2_NUM_ARGS);
+
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+      template<unsigned n> class arg
+      {
+      public:
+        typedef typename detail::variadic_arg_type<n, Args...>::type type;
+      };
+      BOOST_STATIC_CONSTANT(int, arity = sizeof...(Args));
+
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+      BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const combiner_type &combiner_arg = combiner_type(),
+        const group_compare_type &group_compare = group_compare_type()):
+        _pimpl(new impl_class(combiner_arg, group_compare))
+      {};
+      virtual ~BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)()
+      {
+      }
+
+      //move support
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+      BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(
+        BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) && other)
+      {
+        using std::swap;
+        swap(_pimpl, other._pimpl);
+      };
+
+      BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) &
+        operator=(BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) && rhs)
+      {
+        if(this == &rhs)
+        {
+          return *this;
+        }
+        _pimpl.reset();
+        using std::swap;
+        swap(_pimpl, rhs._pimpl);
+        return *this;
+      }
+#endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+      connection connect(const slot_type &slot, connect_position position = at_back)
+      {
+        return (*_pimpl).connect(slot, position);
+      }
+      connection connect(const group_type &group,
+        const slot_type &slot, connect_position position = at_back)
+      {
+        return (*_pimpl).connect(group, slot, position);
+      }
+      connection connect_extended(const extended_slot_type &slot, connect_position position = at_back)
+      {
+        return (*_pimpl).connect_extended(slot, position);
+      }
+      connection connect_extended(const group_type &group,
+        const extended_slot_type &slot, connect_position position = at_back)
+      {
+        return (*_pimpl).connect_extended(group, slot, position);
+      }
+      void disconnect_all_slots()
+      {
+        (*_pimpl).disconnect_all_slots();
+      }
+      void disconnect(const group_type &group)
+      {
+        (*_pimpl).disconnect(group);
+      }
+      template <typename T>
+      void disconnect(const T &slot)
+      {
+        (*_pimpl).disconnect(slot);
+      }
+      result_type operator ()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS))
+      {
+        return (*_pimpl)(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+      }
+      result_type operator ()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const
+      {
+        return (*_pimpl)(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+      }
+      std::size_t num_slots() const
+      {
+        return (*_pimpl).num_slots();
+      }
+      bool empty() const
+      {
+        return (*_pimpl).empty();
+      }
+      combiner_type combiner() const
+      {
+        return (*_pimpl).combiner();
+      }
+      void set_combiner(const combiner_type &combiner_arg)
+      {
+        return (*_pimpl).set_combiner(combiner_arg);
+      }
+      void swap(BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) & other)
+      {
+        using std::swap;
+        swap(_pimpl, other._pimpl);
+      }
+    protected:
+      virtual shared_ptr<void> lock_pimpl() const
+      {
+        return _pimpl;
+      }
+    private:
+      shared_ptr<impl_class>
+        _pimpl;
+    };
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+    // free swap function for signalN classes, findable by ADL
+    template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+      void swap(
+        BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION> &sig1,
+        BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION> &sig2 )
+    {
+      sig1.swap(sig2);
+    }
+#endif
+
+    namespace detail
+    {
+      // wrapper class for storing other signals as slots with automatic lifetime tracking
+      template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+        class BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS);
+
+      template<BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+        class BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+        BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION
+      {
+      public:
+        typedef typename BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+          <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION>::result_type
+          result_type;
+
+        BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+          (const BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+          <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION>
+          &signal):
+          _weak_pimpl(signal._pimpl)
+        {}
+        result_type operator ()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS))
+        {
+          shared_ptr<detail::BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+            <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION> >
+            shared_pimpl(_weak_pimpl.lock());
+          if(shared_pimpl == 0) throw expired_slot();
+          return (*shared_pimpl)(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+        }
+        result_type operator ()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const
+        {
+          shared_ptr<detail::BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+            <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION> >
+            shared_pimpl(_weak_pimpl.lock());
+          if(shared_pimpl == 0) throw expired_slot();
+          return (*shared_pimpl)(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+        }
+      private:
+        boost::weak_ptr<detail::BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+          <BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION> > _weak_pimpl;
+      };
+
+#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+      template<int arity, typename Signature>
+        class extended_signature: public variadic_extended_signature<Signature>
+      {};
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+      template<int arity, typename Signature>
+        class extended_signature;
+      // partial template specialization
+      template<typename Signature>
+        class extended_signature<BOOST_SIGNALS2_NUM_ARGS, Signature>
+      {
+      public:
+// typename function_traits<Signature>::result_type (
+// const boost::signals2::connection &,
+// typename function_traits<Signature>::arg1_type,
+// typename function_traits<Signature>::arg2_type,
+// ...,
+// typename function_traits<Signature>::argn_type)
+#define BOOST_SIGNALS2_EXT_SIGNATURE(arity, Signature) \
+  typename function_traits<Signature>::result_type ( \
+  const boost::signals2::connection & BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS) \
+  BOOST_PP_ENUM(arity, BOOST_SIGNALS2_SIGNATURE_TO_ARGN_TYPE, Signature) )
+        typedef function<BOOST_SIGNALS2_EXT_SIGNATURE(BOOST_SIGNALS2_NUM_ARGS, Signature)> function_type;
+#undef BOOST_SIGNALS2_EXT_SIGNATURE
+      };
+
+      template<unsigned arity, typename Signature, typename Combiner,
+        typename Group, typename GroupCompare, typename SlotFunction,
+        typename ExtendedSlotFunction, typename Mutex>
+      class signalN;
+      // partial template specialization
+      template<typename Signature, typename Combiner, typename Group,
+        typename GroupCompare, typename SlotFunction,
+        typename ExtendedSlotFunction, typename Mutex>
+      class signalN<BOOST_SIGNALS2_NUM_ARGS, Signature, Combiner, Group,
+        GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex>
+      {
+      public:
+        typedef BOOST_SIGNALS2_SIGNAL_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)<
+          BOOST_SIGNALS2_PORTABLE_SIGNATURE(BOOST_SIGNALS2_NUM_ARGS, Signature),
+          Combiner, Group,
+          GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex> type;
+      };
+
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+    } // namespace detail
+  } // namespace signals2
+} // namespace boost
+
+#undef BOOST_SIGNALS2_NUM_ARGS
+#undef BOOST_SIGNALS2_SIGNAL_TEMPLATE_INSTANTIATION
diff --git a/third_party/boost/boost/signals2/detail/signals_common.hpp b/third_party/boost/boost/signals2/detail/signals_common.hpp
new file mode 100644
index 0000000..8c4baf0
--- /dev/null
+++ b/third_party/boost/boost/signals2/detail/signals_common.hpp
@@ -0,0 +1,77 @@
+// Boost.Signals library
+
+// Copyright Douglas Gregor 2001-2004.
+// Copyright Frank Mori Hess 2007. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_SIGNALS_COMMON_HPP
+#define BOOST_SIGNALS2_SIGNALS_COMMON_HPP
+
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/ref.hpp>
+#include <boost/signals2/signal_base.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+
+namespace boost {
+  namespace signals2 {
+    namespace detail {
+      // Determine if the given type T is a signal
+      template<typename T>
+      class is_signal: public mpl::bool_<is_base_of<signal_base, T>::value>
+      {};
+
+      // A slot can be a signal, a reference to a function object, or a
+      // function object.
+      struct signal_tag {};
+      struct reference_tag {};
+      struct value_tag {};
+
+      // Classify the given slot as a signal, a reference-to-slot, or a
+      // standard slot
+      template<typename S>
+      class get_slot_tag {
+        typedef typename mpl::if_<is_signal<S>,
+          signal_tag, value_tag>::type signal_or_value;
+      public:
+        typedef typename mpl::if_<is_reference_wrapper<S>,
+                            reference_tag,
+                            signal_or_value>::type type;
+      };
+
+      // Get the slot so that it can be copied
+      template<typename F>
+      typename F::weak_signal_type
+      get_invocable_slot(const F &signal, signal_tag)
+      { return typename F::weak_signal_type(signal); }
+
+      template<typename F>
+      const F&
+      get_invocable_slot(const F& f, reference_tag)
+      { return f; }
+
+      template<typename F>
+      const F&
+      get_invocable_slot(const F& f, value_tag)
+      { return f; }
+
+      // Determines the type of the slot - is it a signal, a reference to a
+      // slot or just a normal slot.
+      template<typename F>
+      typename get_slot_tag<F>::type
+      tag_type(const F&)
+      {
+        typedef typename get_slot_tag<F>::type
+          the_tag_type;
+        the_tag_type tag = the_tag_type();
+        return tag;
+      }
+    } // end namespace detail
+  } // end namespace signals2
+} // end namespace boost
+
+#endif // BOOST_SIGNALS2_SIGNALS_COMMON_HPP
diff --git a/third_party/boost/boost/signals2/detail/signals_common_macros.hpp b/third_party/boost/boost/signals2/detail/signals_common_macros.hpp
new file mode 100644
index 0000000..4ca4403
--- /dev/null
+++ b/third_party/boost/boost/signals2/detail/signals_common_macros.hpp
@@ -0,0 +1,215 @@
+/*
+  Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+  Begin: 2007-01-23
+*/
+// Copyright Frank Mori Hess 2007-2008
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_SIGNALS2_SIGNALS_COMMON_MACROS_HPP
+#define BOOST_SIGNALS2_SIGNALS_COMMON_MACROS_HPP
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+#ifndef BOOST_SIGNALS2_MAX_ARGS
+#define BOOST_SIGNALS2_MAX_ARGS 9
+#endif
+
+// signaln
+#define BOOST_SIGNALS2_SIGNAL_CLASS_NAME(arity) BOOST_PP_CAT(signal, arity)
+// weak_signaln
+#define BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(arity) BOOST_PP_CAT(weak_, BOOST_SIGNALS2_SIGNAL_CLASS_NAME(arity))
+// signaln_impl
+#define BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(arity) BOOST_PP_CAT(BOOST_SIGNALS2_SIGNAL_CLASS_NAME(arity), _impl)
+// argn
+#define BOOST_SIGNALS2_SIGNATURE_ARG_NAME(z, n, data) BOOST_PP_CAT(arg, BOOST_PP_INC(n))
+// Tn argn
+#define BOOST_SIGNALS2_SIGNATURE_FULL_ARG(z, n, data) \
+  BOOST_PP_CAT(T, BOOST_PP_INC(n)) BOOST_SIGNALS2_SIGNATURE_ARG_NAME(~, n, ~)
+// T1 arg1, T2 arg2, ..., Tn argn
+#define BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(arity) \
+  BOOST_PP_ENUM(arity, BOOST_SIGNALS2_SIGNATURE_FULL_ARG, ~)
+// arg1, arg2, ..., argn
+#define BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(arity) BOOST_PP_ENUM(arity, BOOST_SIGNALS2_SIGNATURE_ARG_NAME, ~)
+// T1, T2, ..., TN
+#define BOOST_SIGNALS2_ARGS_TEMPLATE_INSTANTIATION(arity) \
+  BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), T)
+// R (T1, T2, ..., TN)
+#define BOOST_SIGNALS2_SIGNATURE_FUNCTION_TYPE(arity) \
+  R ( BOOST_SIGNALS2_ARGS_TEMPLATE_INSTANTIATION(arity) )
+// typename prefixR, typename prefixT1, typename prefixT2, ..., typename prefixTN
+#define BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_DECL(arity, prefix) \
+  typename BOOST_PP_CAT(prefix, R) BOOST_PP_COMMA_IF(arity) \
+  BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), typename BOOST_PP_CAT(prefix, T))
+// typename R, typename T1, typename T2, ..., typename TN
+#define BOOST_SIGNALS2_SIGNATURE_TEMPLATE_DECL(arity) \
+  typename R BOOST_PP_COMMA_IF(arity) \
+  BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), typename T)
+// typename prefixT1, typename prefixT2, ..., typename prefixTN
+#define BOOST_SIGNALS2_PREFIXED_ARGS_TEMPLATE_DECL(arity, prefix) \
+  BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), typename BOOST_PP_CAT(prefix, T))
+// typename T1, typename T2, ..., typename TN
+#define BOOST_SIGNALS2_ARGS_TEMPLATE_DECL(arity) \
+  BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), typename T)
+// prefixR, prefixT1, prefixT2, ..., prefixTN
+#define BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_INSTANTIATION(arity, prefix) \
+  BOOST_PP_CAT(prefix, R) BOOST_PP_COMMA_IF(arity) BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), BOOST_PP_CAT(prefix, T))
+// R, T1, T2, ..., TN
+#define BOOST_SIGNALS2_SIGNATURE_TEMPLATE_INSTANTIATION(arity) \
+  R BOOST_PP_COMMA_IF(arity) BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), T)
+// boost::functionN<R, T1, T2, ..., TN>
+#define BOOST_SIGNALS2_FUNCTION_N_DECL(arity) BOOST_PP_CAT(boost::function, arity)<\
+  BOOST_SIGNALS2_SIGNATURE_TEMPLATE_INSTANTIATION(arity) >
+// R, const boost::signals2::connection&, T1, T2, ..., TN
+#define BOOST_SIGNALS2_EXT_SLOT_TEMPLATE_INSTANTIATION(arity) \
+  R, const boost::signals2::connection&  BOOST_PP_COMMA_IF(arity) \
+  BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), T)
+// boost::functionN<R, const boost::signals2::connection &, T1, T2, ..., TN>
+#define BOOST_SIGNALS2_EXT_FUNCTION_N_DECL(arity) BOOST_PP_CAT(boost::function, BOOST_PP_INC(arity))<\
+  BOOST_SIGNALS2_EXT_SLOT_TEMPLATE_INSTANTIATION(arity) >
+// slotN
+#define BOOST_SIGNALS2_SLOT_CLASS_NAME(arity) BOOST_PP_CAT(slot, arity)
+// slotN+1<R, const connection &, T1, T2, ..., TN, extended_slot_function_type>
+#define BOOST_SIGNALS2_EXTENDED_SLOT_TYPE(arity) \
+  BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_PP_INC(arity))< \
+  BOOST_SIGNALS2_EXT_SLOT_TEMPLATE_INSTANTIATION(arity), \
+  extended_slot_function_type>
+// bound_extended_slot_functionN
+#define BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N(arity) BOOST_PP_CAT(bound_extended_slot_function, arity)
+// bound_extended_slot_function_helperN
+#define BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_INVOKER_N(arity) BOOST_PP_CAT(bound_extended_slot_function_invoker, arity)
+// typename function_traits<Signature>::argn_type
+#define BOOST_SIGNALS2_SIGNATURE_TO_ARGN_TYPE(z, n, Signature) \
+  BOOST_PP_CAT(BOOST_PP_CAT(typename function_traits<Signature>::arg, BOOST_PP_INC(n)), _type)
+// typename function_traits<Signature>::result_type,
+// typename function_traits<Signature>::arg1_type,
+// typename function_traits<Signature>::arg2_type,
+// ...,
+// typename function_traits<Signature>::argn_type
+#define BOOST_SIGNALS2_PORTABLE_SIGNATURE(arity, Signature) \
+  typename function_traits<Signature>::result_type \
+  BOOST_PP_COMMA_IF(arity) BOOST_PP_ENUM(arity, BOOST_SIGNALS2_SIGNATURE_TO_ARGN_TYPE, Signature)
+// prefixTn & argn
+#define BOOST_SIGNALS2_PREFIXED_FULL_REF_ARG(z, n, prefix) \
+  BOOST_PP_CAT(BOOST_PP_CAT(prefix, T), BOOST_PP_INC(n)) & BOOST_SIGNALS2_SIGNATURE_ARG_NAME(~, n, ~)
+// prefixT1 & arg1, prefixT2 & arg2, ..., prefixTn & argn
+#define BOOST_SIGNALS2_PREFIXED_FULL_REF_ARGS(arity, prefix) \
+  BOOST_PP_ENUM(arity, BOOST_SIGNALS2_PREFIXED_FULL_REF_ARG, prefix)
+// Tn & argn
+#define BOOST_SIGNALS2_FULL_CREF_ARG(z, n, data) \
+  const BOOST_PP_CAT(T, BOOST_PP_INC(n)) & BOOST_SIGNALS2_SIGNATURE_ARG_NAME(~, n, ~)
+// const T1 & arg1, const T2 & arg2, ..., const Tn & argn
+#define BOOST_SIGNALS2_FULL_FORWARD_ARGS(arity) \
+  BOOST_PP_ENUM(arity, BOOST_SIGNALS2_FULL_CREF_ARG, ~)
+#define BOOST_SIGNALS2_FORWARDED_ARGS(arity) \
+  BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(arity)
+// preprocessed_arg_typeN
+#define BOOST_SIGNALS2_PREPROCESSED_ARG_N_TYPE_CLASS_NAME(arity) BOOST_PP_CAT(preprocessed_arg_type, arity)
+
+// typename R, typename T1, typename T2, ..., typename TN, typename SlotFunction
+#define BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION_DECL(arity) \
+  BOOST_SIGNALS2_SIGNATURE_TEMPLATE_DECL(arity), \
+  typename SlotFunction
+#define BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION
+
+// typename R, typename T1, typename T2, ..., typename TN, typename Combiner, ...
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_DECL(arity) \
+  BOOST_SIGNALS2_SIGNATURE_TEMPLATE_DECL(arity), \
+  typename Combiner, \
+  typename Group, \
+  typename GroupCompare, \
+  typename SlotFunction, \
+  typename ExtendedSlotFunction, \
+  typename Mutex
+// typename R, typename T1, typename T2, ..., typename TN, typename Combiner = optional_last_value<R>, ...
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_DEFAULTED_DECL(arity) \
+  BOOST_SIGNALS2_SIGNATURE_TEMPLATE_DECL(arity), \
+  typename Combiner = optional_last_value<R>, \
+  typename Group = int, \
+  typename GroupCompare = std::less<Group>, \
+  typename SlotFunction = BOOST_SIGNALS2_FUNCTION_N_DECL(arity), \
+  typename ExtendedSlotFunction = BOOST_SIGNALS2_EXT_FUNCTION_N_DECL(arity), \
+  typename Mutex = signals2::mutex
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION_DECL(arity) BOOST_SIGNALS2_SIGNAL_TEMPLATE_DECL(arity)
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION
+
+#define BOOST_SIGNALS2_STD_FUNCTIONAL_BASE(result_type) std_functional_base
+
+#define BOOST_SIGNALS2_PP_COMMA_IF(arity) BOOST_PP_COMMA_IF(arity)
+
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+#define BOOST_SIGNALS2_SIGNAL_CLASS_NAME(arity) signal
+#define BOOST_SIGNALS2_WEAK_SIGNAL_CLASS_NAME(arity) weak_signal
+#define BOOST_SIGNALS2_SIGNAL_IMPL_CLASS_NAME(arity) signal_impl
+#define BOOST_SIGNALS2_SIGNATURE_TEMPLATE_DECL(arity) typename Signature
+#define BOOST_SIGNALS2_ARGS_TEMPLATE_INSTANTIATION(arity) Args...
+#define BOOST_SIGNALS2_SIGNATURE_TEMPLATE_INSTANTIATION(arity) R (Args...)
+#define BOOST_SIGNALS2_SIGNATURE_FUNCTION_TYPE(arity) R (Args...)
+#define BOOST_SIGNALS2_ARGS_TEMPLATE_DECL(arity) typename ... Args
+#define BOOST_SIGNALS2_FULL_FORWARD_ARGS(arity) Args && ... args
+#define BOOST_SIGNALS2_FORWARDED_ARGS(arity) std::forward<Args>(args)...
+#define BOOST_SIGNALS2_SLOT_CLASS_NAME(arity) slot
+#define BOOST_SIGNALS2_EXTENDED_SLOT_TYPE(arity) slot<R (const connection &, Args...), extended_slot_function_type>
+#define BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_N(arity) bound_extended_slot_function
+#define BOOST_SIGNALS2_BOUND_EXTENDED_SLOT_FUNCTION_INVOKER_N(arity) bound_extended_slot_function_invoker
+#define BOOST_SIGNALS2_FUNCTION_N_DECL(arity) boost::function<Signature>
+#define BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_DECL(arity, prefix) typename prefixSignature
+#define BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_INSTANTIATION(arity, prefix) prefixSignature
+#define BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(arity) Args ... args
+#define BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(arity) args...
+#define BOOST_SIGNALS2_PORTABLE_SIGNATURE(arity, Signature) Signature
+
+#define BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION_DECL(arity) \
+  typename SlotFunction, \
+  typename R, \
+  typename ... Args
+#define BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION \
+  <R (Args...), SlotFunction>
+
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_DECL(arity) \
+  typename Signature, \
+  typename Combiner, \
+  typename Group, \
+  typename GroupCompare, \
+  typename SlotFunction, \
+  typename ExtendedSlotFunction, \
+  typename Mutex
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_DEFAULTED_DECL(arity) \
+  typename Signature, \
+  typename Combiner = optional_last_value<typename boost::function_traits<Signature>::result_type>, \
+  typename Group = int, \
+  typename GroupCompare = std::less<Group>, \
+  typename SlotFunction = boost::function<Signature>, \
+  typename ExtendedSlotFunction = typename detail::variadic_extended_signature<Signature>::function_type, \
+  typename Mutex = signals2::mutex
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION_DECL(arity) \
+  typename Combiner, \
+  typename Group, \
+  typename GroupCompare, \
+  typename SlotFunction, \
+  typename ExtendedSlotFunction, \
+  typename Mutex, \
+  typename R, \
+  typename ... Args
+#define BOOST_SIGNALS2_SIGNAL_TEMPLATE_SPECIALIZATION <\
+  R (Args...), \
+  Combiner, \
+  Group, \
+  GroupCompare, \
+  SlotFunction, \
+  ExtendedSlotFunction, \
+  Mutex>
+
+#define BOOST_SIGNALS2_STD_FUNCTIONAL_BASE(result_type) \
+  std_functional_base<result_type , Args...>
+
+#define BOOST_SIGNALS2_PP_COMMA_IF(arity) ,
+
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+#endif // BOOST_SIGNALS2_SIGNALS_COMMON_MACROS_HPP
diff --git a/third_party/boost/boost/signals2/detail/slot_call_iterator.hpp b/third_party/boost/boost/signals2/detail/slot_call_iterator.hpp
new file mode 100644
index 0000000..418ec0b
--- /dev/null
+++ b/third_party/boost/boost/signals2/detail/slot_call_iterator.hpp
@@ -0,0 +1,194 @@
+// Boost.Signals2 library
+
+// Copyright Douglas Gregor 2001-2004.
+// Copyright Frank Mori Hess 2007-2008.
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_SLOT_CALL_ITERATOR_HPP
+#define BOOST_SIGNALS2_SLOT_CALL_ITERATOR_HPP
+
+#include <boost/assert.hpp>
+#include <boost/aligned_storage.hpp>
+#include <boost/iterator/iterator_facade.hpp>
+#include <boost/optional.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/signals2/connection.hpp>
+#include <boost/signals2/slot_base.hpp>
+#include <boost/signals2/detail/auto_buffer.hpp>
+#include <boost/signals2/detail/unique_lock.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/weak_ptr.hpp>
+
+namespace boost {
+  namespace signals2 {
+    namespace detail {
+      template<typename ResultType, typename Function>
+        class slot_call_iterator_cache
+      {
+      public:
+        slot_call_iterator_cache(const Function &f_arg):
+          f(f_arg),
+          connected_slot_count(0),
+          disconnected_slot_count(0),
+          m_active_slot(0)
+        {}
+
+        ~slot_call_iterator_cache()
+        {
+          if(m_active_slot)
+          {
+            garbage_collecting_lock<connection_body_base> lock(*m_active_slot);
+            m_active_slot->dec_slot_refcount(lock);
+          }
+        }
+
+        template<typename M>
+        void set_active_slot(garbage_collecting_lock<M> &lock,
+          connection_body_base *active_slot)
+        {
+          if(m_active_slot)
+            m_active_slot->dec_slot_refcount(lock);
+          m_active_slot = active_slot;
+          if(m_active_slot)
+            m_active_slot->inc_slot_refcount(lock);
+        }
+
+        optional<ResultType> result;
+        typedef auto_buffer<void_shared_ptr_variant, store_n_objects<10> > tracked_ptrs_type;
+        tracked_ptrs_type tracked_ptrs;
+        Function f;
+        unsigned connected_slot_count;
+        unsigned disconnected_slot_count;
+        connection_body_base *m_active_slot;
+      };
+
+      // Generates a slot call iterator. Essentially, this is an iterator that:
+      //   - skips over disconnected slots in the underlying list
+      //   - calls the connected slots when dereferenced
+      //   - caches the result of calling the slots
+      template<typename Function, typename Iterator, typename ConnectionBody>
+      class slot_call_iterator_t
+        : public boost::iterator_facade<slot_call_iterator_t<Function, Iterator, ConnectionBody>,
+        typename Function::result_type,
+        boost::single_pass_traversal_tag,
+        typename boost::add_const<typename boost::add_reference<typename Function::result_type>::type>::type >
+      {
+        typedef boost::iterator_facade<slot_call_iterator_t<Function, Iterator, ConnectionBody>,
+          typename Function::result_type,
+          boost::single_pass_traversal_tag,
+          typename boost::add_const<typename boost::add_reference<typename Function::result_type>::type>::type >
+        inherited;
+
+        typedef typename Function::result_type result_type;
+
+        typedef slot_call_iterator_cache<result_type, Function> cache_type;
+
+        friend class boost::iterator_core_access;
+
+      public:
+        slot_call_iterator_t(Iterator iter_in, Iterator end_in,
+          cache_type &c):
+          iter(iter_in), end(end_in),
+          cache(&c), callable_iter(end_in)
+        {
+          lock_next_callable();
+        }
+
+        typename inherited::reference
+        dereference() const
+        {
+          if (!cache->result) {
+            try
+            {
+              cache->result.reset(cache->f(*iter));
+            }
+            catch(expired_slot &)
+            {
+              (*iter)->disconnect();
+              throw;
+            }
+          }
+          return cache->result.get();
+        }
+
+        void increment()
+        {
+          ++iter;
+          lock_next_callable();
+          cache->result.reset();
+        }
+
+        bool equal(const slot_call_iterator_t& other) const
+        {
+          return iter == other.iter;
+        }
+
+      private:
+        typedef garbage_collecting_lock<connection_body_base> lock_type;
+
+        void set_callable_iter(lock_type &lock, Iterator newValue) const
+        {
+          callable_iter = newValue;
+          if(callable_iter == end)
+            cache->set_active_slot(lock, 0);
+          else
+            cache->set_active_slot(lock, (*callable_iter).get());
+        }
+
+        void lock_next_callable() const
+        {
+          if(iter == callable_iter)
+          {
+            return;
+          }
+          if(iter == end)
+          {
+            if(callable_iter != end)
+            {
+              lock_type lock(**callable_iter);
+              set_callable_iter(lock, end);
+              return;
+            }
+          }
+          // we're only locking the first connection body,
+          // but it doesn't matter they all use the same mutex
+          lock_type lock(**iter);
+          for(;iter != end; ++iter)
+          {
+            cache->tracked_ptrs.clear();
+            (*iter)->nolock_grab_tracked_objects(lock, std::back_inserter(cache->tracked_ptrs));
+            if((*iter)->nolock_nograb_connected())
+            {
+              ++cache->connected_slot_count;
+            }else
+            {
+              ++cache->disconnected_slot_count;
+            }
+            if((*iter)->nolock_nograb_blocked() == false)
+            {
+              set_callable_iter(lock, iter);
+              break;
+            }
+          }
+          if(iter == end)
+          {
+            set_callable_iter(lock, end);
+          }
+        }
+
+        mutable Iterator iter;
+        Iterator end;
+        cache_type *cache;
+        mutable Iterator callable_iter;
+      };
+    } // end namespace detail
+  } // end namespace BOOST_SIGNALS_NAMESPACE
+} // end namespace boost
+
+#endif // BOOST_SIGNALS2_SLOT_CALL_ITERATOR_HPP
diff --git a/third_party/boost/boost/signals2/detail/slot_groups.hpp b/third_party/boost/boost/signals2/detail/slot_groups.hpp
new file mode 100644
index 0000000..5e1853a
--- /dev/null
+++ b/third_party/boost/boost/signals2/detail/slot_groups.hpp
@@ -0,0 +1,235 @@
+// Boost.Signals2 library
+
+// Copyright Frank Mori Hess 2007-2008.
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_SLOT_GROUPS_HPP
+#define BOOST_SIGNALS2_SLOT_GROUPS_HPP
+
+#include <boost/signals2/connection.hpp>
+#include <boost/optional.hpp>
+#include <list>
+#include <map>
+#include <utility>
+
+namespace boost {
+  namespace signals2 {
+    namespace detail {
+      enum slot_meta_group {front_ungrouped_slots, grouped_slots, back_ungrouped_slots};
+      template<typename Group>
+      struct group_key
+      {
+        typedef std::pair<enum slot_meta_group, boost::optional<Group> > type;
+      };
+      template<typename Group, typename GroupCompare>
+      class group_key_less
+      {
+      public:
+        group_key_less()
+        {}
+        group_key_less(const GroupCompare &group_compare): _group_compare(group_compare)
+        {}
+        bool operator ()(const typename group_key<Group>::type &key1, const typename group_key<Group>::type &key2) const
+        {
+          if(key1.first != key2.first) return key1.first < key2.first;
+          if(key1.first != grouped_slots) return false;
+          return _group_compare(key1.second.get(), key2.second.get());
+        }
+      private:
+        GroupCompare _group_compare;
+      };
+      template<typename Group, typename GroupCompare, typename ValueType>
+      class grouped_list
+      {
+      public:
+        typedef group_key_less<Group, GroupCompare> group_key_compare_type;
+      private:
+        typedef std::list<ValueType> list_type;
+        typedef std::map
+          <
+            typename group_key<Group>::type,
+            typename list_type::iterator,
+            group_key_compare_type
+          > map_type;
+        typedef typename map_type::iterator map_iterator;
+        typedef typename map_type::const_iterator const_map_iterator;
+      public:
+        typedef typename list_type::iterator iterator;
+        typedef typename list_type::const_iterator const_iterator;
+        typedef typename group_key<Group>::type group_key_type;
+
+        grouped_list(const group_key_compare_type &group_key_compare):
+          _group_key_compare(group_key_compare)
+        {}
+        grouped_list(const grouped_list &other): _list(other._list),
+          _group_map(other._group_map), _group_key_compare(other._group_key_compare)
+        {
+          // fix up _group_map
+          typename map_type::const_iterator other_map_it;
+          typename list_type::iterator this_list_it = _list.begin();
+          typename map_type::iterator this_map_it = _group_map.begin();
+          for(other_map_it = other._group_map.begin();
+            other_map_it != other._group_map.end();
+            ++other_map_it, ++this_map_it)
+          {
+            BOOST_ASSERT(this_map_it != _group_map.end());
+            this_map_it->second = this_list_it;
+            typename list_type::const_iterator other_list_it = other.get_list_iterator(other_map_it);
+            typename map_type::const_iterator other_next_map_it = other_map_it;
+            ++other_next_map_it;
+            typename list_type::const_iterator other_next_list_it = other.get_list_iterator(other_next_map_it);
+            while(other_list_it != other_next_list_it)
+            {
+              ++other_list_it;
+              ++this_list_it;
+            }
+          }
+        }
+        iterator begin()
+        {
+          return _list.begin();
+        }
+        iterator end()
+        {
+          return _list.end();
+        }
+        iterator lower_bound(const group_key_type &key)
+        {
+          map_iterator map_it = _group_map.lower_bound(key);
+          return get_list_iterator(map_it);
+        }
+        iterator upper_bound(const group_key_type &key)
+        {
+          map_iterator map_it = _group_map.upper_bound(key);
+          return get_list_iterator(map_it);
+        }
+        void push_front(const group_key_type &key, const ValueType &value)
+        {
+          map_iterator map_it;
+          if(key.first == front_ungrouped_slots)
+          {// optimization
+            map_it = _group_map.begin();
+          }else
+          {
+            map_it = _group_map.lower_bound(key);
+          }
+          m_insert(map_it, key, value);
+        }
+        void push_back(const group_key_type &key, const ValueType &value)
+        {
+          map_iterator map_it;
+          if(key.first == back_ungrouped_slots)
+          {// optimization
+            map_it = _group_map.end();
+          }else
+          {
+            map_it = _group_map.upper_bound(key);
+          }
+          m_insert(map_it, key, value);
+        }
+        void erase(const group_key_type &key)
+        {
+          map_iterator map_it = _group_map.lower_bound(key);
+          iterator begin_list_it = get_list_iterator(map_it);
+          iterator end_list_it = upper_bound(key);
+          if(begin_list_it != end_list_it)
+          {
+            _list.erase(begin_list_it, end_list_it);
+            _group_map.erase(map_it);
+          }
+        }
+        iterator erase(const group_key_type &key, const iterator &it)
+        {
+          BOOST_ASSERT(it != _list.end());
+          map_iterator map_it = _group_map.lower_bound(key);
+          BOOST_ASSERT(map_it != _group_map.end());
+          BOOST_ASSERT(weakly_equivalent(map_it->first, key));
+          if(map_it->second == it)
+          {
+            iterator next = it;
+            ++next;
+            // if next is in same group
+            if(next != upper_bound(key))
+            {
+              _group_map[key] = next;
+            }else
+            {
+              _group_map.erase(map_it);
+            }
+          }
+          return _list.erase(it);
+        }
+        void clear()
+        {
+          _list.clear();
+          _group_map.clear();
+        }
+      private:
+        /* Suppress default assignment operator, since it has the wrong semantics. */
+        grouped_list& operator=(const grouped_list &other);
+
+        bool weakly_equivalent(const group_key_type &arg1, const group_key_type &arg2)
+        {
+          if(_group_key_compare(arg1, arg2)) return false;
+          if(_group_key_compare(arg2, arg1)) return false;
+          return true;
+        }
+        void m_insert(const map_iterator &map_it, const group_key_type &key, const ValueType &value)
+        {
+          iterator list_it = get_list_iterator(map_it);
+          iterator new_it = _list.insert(list_it, value);
+          if(map_it != _group_map.end() && weakly_equivalent(key, map_it->first))
+          {
+            _group_map.erase(map_it);
+          }
+          map_iterator lower_bound_it = _group_map.lower_bound(key);
+          if(lower_bound_it == _group_map.end() ||
+            weakly_equivalent(lower_bound_it->first, key) == false)
+          {
+            /* doing the following instead of just
+              _group_map[key] = new_it;
+              to avoid bogus error when enabling checked iterators with g++ */
+            _group_map.insert(typename map_type::value_type(key, new_it));
+          }
+        }
+        iterator get_list_iterator(const const_map_iterator &map_it)
+        {
+          iterator list_it;
+          if(map_it == _group_map.end())
+          {
+            list_it = _list.end();
+          }else
+          {
+            list_it = map_it->second;
+          }
+          return list_it;
+        }
+        const_iterator get_list_iterator(const const_map_iterator &map_it) const
+        {
+          const_iterator list_it;
+          if(map_it == _group_map.end())
+          {
+            list_it = _list.end();
+          }else
+          {
+            list_it = map_it->second;
+          }
+          return list_it;
+        }
+
+        list_type _list;
+        // holds iterators to first list item in each group
+        map_type _group_map;
+        group_key_compare_type _group_key_compare;
+      };
+    } // end namespace detail
+    enum connect_position { at_back, at_front };
+  } // end namespace signals2
+} // end namespace boost
+
+#endif // BOOST_SIGNALS2_SLOT_GROUPS_HPP
diff --git a/third_party/boost/boost/signals2/detail/slot_template.hpp b/third_party/boost/boost/signals2/detail/slot_template.hpp
new file mode 100644
index 0000000..fc19f51
--- /dev/null
+++ b/third_party/boost/boost/signals2/detail/slot_template.hpp
@@ -0,0 +1,187 @@
+// Boost.Signals2 library
+
+// Copyright Frank Mori Hess 2007-2008.
+// Copyright Timmo Stange 2007.
+// Copyright Douglas Gregor 2001-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+// This file is included iteratively, and should not be protected from multiple inclusion
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+#define BOOST_SIGNALS2_NUM_ARGS BOOST_PP_ITERATION()
+#else
+#define BOOST_SIGNALS2_NUM_ARGS 1
+#endif
+
+
+namespace boost
+{
+  namespace signals2
+  {
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+    template<typename Signature, typename SlotFunction> class slot;
+#else
+    template<typename Signature, typename SlotFunction = boost::function<Signature> >
+      class slot;
+
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1900)
+    template<typename Signature, typename SlotFunction> class slot{};
+#endif
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+    template<BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION_DECL(BOOST_SIGNALS2_NUM_ARGS)>
+      class BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS) BOOST_SIGNALS2_SLOT_TEMPLATE_SPECIALIZATION
+      : public slot_base, public detail::BOOST_SIGNALS2_STD_FUNCTIONAL_BASE(R)
+
+    {
+    public:
+      template<BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS, Other), typename OtherSlotFunction>
+      friend class BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS);
+
+      typedef SlotFunction slot_function_type;
+      typedef R result_type;
+      typedef typename mpl::identity<BOOST_SIGNALS2_SIGNATURE_FUNCTION_TYPE(BOOST_SIGNALS2_NUM_ARGS)>::type signature_type;
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+// typedef Tn argn_type;
+#define BOOST_SIGNALS2_MISC_STATEMENT(z, n, data) \
+    typedef BOOST_PP_CAT(T, BOOST_PP_INC(n)) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(n)), _type);
+          BOOST_PP_REPEAT(BOOST_SIGNALS2_NUM_ARGS, BOOST_SIGNALS2_MISC_STATEMENT, ~)
+#undef BOOST_SIGNALS2_MISC_STATEMENT
+#if BOOST_SIGNALS2_NUM_ARGS == 1
+      typedef arg1_type argument_type;
+#elif BOOST_SIGNALS2_NUM_ARGS == 2
+      typedef arg1_type first_argument_type;
+      typedef arg2_type second_argument_type;
+#endif
+
+      template<unsigned n> class arg : public
+        detail::BOOST_SIGNALS2_PREPROCESSED_ARG_N_TYPE_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+        <n BOOST_SIGNALS2_PP_COMMA_IF(BOOST_SIGNALS2_NUM_ARGS)
+        BOOST_SIGNALS2_ARGS_TEMPLATE_INSTANTIATION(BOOST_SIGNALS2_NUM_ARGS)>
+      {};
+
+      BOOST_STATIC_CONSTANT(int, arity = BOOST_SIGNALS2_NUM_ARGS);
+
+#else // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+      template<unsigned n> class arg
+      {
+      public:
+        typedef typename detail::variadic_arg_type<n, Args...>::type type;
+      };
+      BOOST_STATIC_CONSTANT(int, arity = sizeof...(Args));
+
+#endif // BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+      template<typename F>
+      BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const F& f)
+      {
+        init_slot_function(f);
+      }
+      // copy constructors
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+      template<BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_DECL(BOOST_SIGNALS2_NUM_ARGS, Other), typename OtherSlotFunction>
+      BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)
+        <BOOST_SIGNALS2_PREFIXED_SIGNATURE_TEMPLATE_INSTANTIATION(BOOST_SIGNALS2_NUM_ARGS, Other), OtherSlotFunction> &other_slot):
+        slot_base(other_slot), _slot_function(other_slot._slot_function)
+      {
+      }
+#endif
+      template<typename Signature, typename OtherSlotFunction>
+      BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)(const slot<Signature, OtherSlotFunction> &other_slot):
+        slot_base(other_slot), _slot_function(other_slot._slot_function)
+      {
+      }
+      // bind syntactic sugar
+      BOOST_SIGNALS2_SLOT_N_BINDING_CONSTRUCTORS
+      // invocation
+      R operator()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS))
+      {
+        locked_container_type locked_objects = lock();
+        return _slot_function(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+      }
+      R operator()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS)) const
+      {
+        locked_container_type locked_objects = lock();
+        return _slot_function(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));
+      }
+      // tracking
+      BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const weak_ptr<void> &tracked)      {
+        _tracked_objects.push_back(tracked);
+        return *this;
+      }
+      BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const signal_base &signal)
+      {
+        track_signal(signal);
+        return *this;
+      }
+      BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track(const slot_base &slot)
+      {
+        tracked_container_type::const_iterator it;
+        for(it = slot.tracked_objects().begin(); it != slot.tracked_objects().end(); ++it)
+        {
+          _tracked_objects.push_back(*it);
+        }
+        return *this;
+      }
+      template<typename ForeignWeakPtr>
+      BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track_foreign(const ForeignWeakPtr &tracked,
+        typename weak_ptr_traits<ForeignWeakPtr>::shared_type * /*SFINAE*/ = 0)
+      {
+        _tracked_objects.push_back(detail::foreign_void_weak_ptr(tracked));
+        return *this;
+      }
+      template<typename ForeignSharedPtr>
+      BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)& track_foreign(const ForeignSharedPtr &tracked,
+        typename shared_ptr_traits<ForeignSharedPtr>::weak_type * /*SFINAE*/ = 0)
+      {
+        _tracked_objects.push_back
+        (
+          detail::foreign_void_weak_ptr
+          (
+            typename shared_ptr_traits<ForeignSharedPtr>::weak_type(tracked)
+          )
+        );
+        return *this;
+      }
+
+      const slot_function_type& slot_function() const {return _slot_function;}
+      slot_function_type& slot_function() {return _slot_function;}
+    private:
+      template<typename F>
+      void init_slot_function(const F& f)
+      {
+        _slot_function = detail::get_invocable_slot(f, detail::tag_type(f));
+        signals2::detail::tracked_objects_visitor visitor(this);
+        boost::visit_each(visitor, f);
+      }
+
+      SlotFunction _slot_function;
+    };
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+    namespace detail
+    {
+      template<unsigned arity, typename Signature, typename SlotFunction>
+      class slotN;
+      // partial template specialization
+      template<typename Signature, typename SlotFunction>
+      class slotN<BOOST_SIGNALS2_NUM_ARGS, Signature, SlotFunction>
+      {
+      public:
+        typedef BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)<
+          BOOST_SIGNALS2_PORTABLE_SIGNATURE(BOOST_SIGNALS2_NUM_ARGS, Signature),
+          SlotFunction> type;
+      };
+    }
+#endif
+  } // end namespace signals2
+} // end namespace boost
+
+#undef BOOST_SIGNALS2_NUM_ARGS
diff --git a/third_party/boost/boost/signals2/detail/tracked_objects_visitor.hpp b/third_party/boost/boost/signals2/detail/tracked_objects_visitor.hpp
new file mode 100644
index 0000000..8f0ba7a
--- /dev/null
+++ b/third_party/boost/boost/signals2/detail/tracked_objects_visitor.hpp
@@ -0,0 +1,97 @@
+// Boost.Signals2 library
+
+// Copyright Frank Mori Hess 2007-2008.
+// Copyright Timmo Stange 2007.
+// Copyright Douglas Gregor 2001-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_TRACKED_OBJECTS_VISITOR_HPP
+#define BOOST_SIGNALS2_TRACKED_OBJECTS_VISITOR_HPP
+
+#include <boost/mpl/bool.hpp>
+#include <boost/ref.hpp>
+#include <boost/signals2/detail/signals_common.hpp>
+#include <boost/signals2/slot_base.hpp>
+#include <boost/signals2/trackable.hpp>
+#include <boost/type_traits/is_function.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+#include <boost/utility/addressof.hpp>
+
+namespace boost
+{
+  namespace signals2
+  {
+    namespace detail
+    {
+      // Visitor to collect tracked objects from a bound function.
+      class tracked_objects_visitor
+      {
+      public:
+        tracked_objects_visitor(slot_base *slot) : slot_(slot)
+        {}
+        template<typename T>
+        void operator()(const T& t) const
+        {
+            m_visit_reference_wrapper(t, mpl::bool_<is_reference_wrapper<T>::value>());
+        }
+      private:
+        template<typename T>
+        void m_visit_reference_wrapper(const reference_wrapper<T> &t, const mpl::bool_<true> &) const
+        {
+            m_visit_pointer(t.get_pointer(), mpl::bool_<true>());
+        }
+        template<typename T>
+        void m_visit_reference_wrapper(const T &t, const mpl::bool_<false> &) const
+        {
+            m_visit_pointer(t, mpl::bool_<is_pointer<T>::value>());
+        }
+        template<typename T>
+        void m_visit_pointer(const T &t, const mpl::bool_<true> &) const
+        {
+            m_visit_not_function_pointer(t, mpl::bool_<!is_function<typename remove_pointer<T>::type>::value>());
+        }
+        template<typename T>
+        void m_visit_pointer(const T &t, const mpl::bool_<false> &) const
+        {
+            m_visit_pointer(boost::addressof(t), mpl::bool_<true>());
+        }
+        template<typename T>
+        void m_visit_not_function_pointer(const T *t, const mpl::bool_<true> &) const
+        {
+            m_visit_signal(t, mpl::bool_<is_signal<T>::value>());
+        }
+        template<typename T>
+        void m_visit_not_function_pointer(const T &, const mpl::bool_<false> &) const
+        {}
+        template<typename T>
+        void m_visit_signal(const T *signal, const mpl::bool_<true> &) const
+        {
+          if(signal)
+            slot_->track_signal(*signal);
+        }
+        template<typename T>
+        void m_visit_signal(const T &t, const mpl::bool_<false> &) const
+        {
+            add_if_trackable(t);
+        }
+        void add_if_trackable(const trackable *trackable) const
+        {
+          if(trackable)
+            slot_->_tracked_objects.push_back(trackable->get_weak_ptr());
+        }
+        void add_if_trackable(const void *) const {}
+
+        mutable slot_base * slot_;
+      };
+
+
+    } // end namespace detail
+  } // end namespace signals2
+} // end namespace boost
+
+#endif // BOOST_SIGNALS2_TRACKED_OBJECTS_VISITOR_HPP
diff --git a/third_party/boost/boost/signals2/detail/unique_lock.hpp b/third_party/boost/boost/signals2/detail/unique_lock.hpp
new file mode 100644
index 0000000..13fecf2
--- /dev/null
+++ b/third_party/boost/boost/signals2/detail/unique_lock.hpp
@@ -0,0 +1,42 @@
+/*
+  Provides a basic subset of boost::unique_lock functionality.  Provided only because
+  including boost/thread/locks.hpp requires linking to thread library
+*/
+// Copyright Frank Mori Hess 2008.
+// Distributed under the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org/libs/signals2 for library home page.
+
+#ifndef BOOST_SIGNALS2_UNIQUE_LOCK_HPP
+#define BOOST_SIGNALS2_UNIQUE_LOCK_HPP
+
+#include <boost/noncopyable.hpp>
+
+namespace boost
+{
+  namespace signals2
+  {
+    namespace detail
+    {
+      template<typename Mutex>
+      class unique_lock: public noncopyable
+      {
+      public:
+        unique_lock(Mutex &m): _mutex(m)
+        {
+          _mutex.lock();
+        }
+        ~unique_lock()
+        {
+          _mutex.unlock();
+        }
+      private:
+        Mutex &_mutex;
+      };
+    } // namespace detail
+  } // namespace signals2
+} // namespace boost
+
+#endif  // BOOST_SIGNALS2_UNIQUE_LOCK_HPP
diff --git a/third_party/boost/boost/signals2/expired_slot.hpp b/third_party/boost/boost/signals2/expired_slot.hpp
new file mode 100644
index 0000000..fa6db22
--- /dev/null
+++ b/third_party/boost/boost/signals2/expired_slot.hpp
@@ -0,0 +1,31 @@
+// Boost.Signals2 library
+
+// Copyright Frank Mori Hess 2007-2010.
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_EXPIRED_SLOT_HPP
+#define BOOST_SIGNALS2_EXPIRED_SLOT_HPP
+
+#include <boost/smart_ptr/bad_weak_ptr.hpp>
+
+namespace boost
+{
+  namespace signals2
+  {
+    class expired_slot: public bad_weak_ptr
+    {
+    public:
+      virtual char const * what() const throw()
+      {
+        return "boost::signals2::expired_slot";
+      }
+    };
+  }
+} // end namespace boost
+
+#endif // BOOST_SIGNALS2_EXPIRED_SLOT_HPP
diff --git a/third_party/boost/boost/signals2/mutex.hpp b/third_party/boost/boost/signals2/mutex.hpp
new file mode 100644
index 0000000..e58aca1
--- /dev/null
+++ b/third_party/boost/boost/signals2/mutex.hpp
@@ -0,0 +1,38 @@
+//
+//  boost/signals2/mutex.hpp - header-only mutex
+//
+//  Copyright (c) 2002, 2003 Peter Dimov and Multi Media Ltd.
+//  Copyright (c) 2008 Frank Mori Hess
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//  boost::signals2::mutex is a modification of
+//  boost::detail::lightweight_mutex to follow the newer Lockable
+//  concept of Boost.Thread.
+//
+
+#ifndef BOOST_SIGNALS2_MUTEX_HPP
+#define BOOST_SIGNALS2_MUTEX_HPP
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/config.hpp>
+
+#if !defined(BOOST_HAS_THREADS)
+# include <boost/signals2/detail/lwm_nop.hpp>
+#elif defined(BOOST_HAS_PTHREADS)
+#  include <boost/signals2/detail/lwm_pthreads.hpp>
+#elif defined(BOOST_HAS_WINTHREADS)
+#  include <boost/signals2/detail/lwm_win32_cs.hpp>
+#else
+// Use #define BOOST_DISABLE_THREADS to avoid the error
+#  error Unrecognized threading platform
+#endif
+
+#endif // #ifndef BOOST_SIGNALS2_MUTEX_HPP
diff --git a/third_party/boost/boost/signals2/optional_last_value.hpp b/third_party/boost/boost/signals2/optional_last_value.hpp
new file mode 100644
index 0000000..766e99b
--- /dev/null
+++ b/third_party/boost/boost/signals2/optional_last_value.hpp
@@ -0,0 +1,65 @@
+// optional_last_value function object (documented as part of Boost.Signals2)
+
+// Copyright Frank Mori Hess 2007-2008.
+// Copyright Douglas Gregor 2001-2003.
+// Distributed under the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org/libs/signals2 for library home page.
+
+#ifndef BOOST_SIGNALS2_OPTIONAL_LAST_VALUE_HPP
+#define BOOST_SIGNALS2_OPTIONAL_LAST_VALUE_HPP
+
+#include <boost/optional.hpp>
+#include <boost/signals2/expired_slot.hpp>
+
+namespace boost {
+  namespace signals2 {
+
+    template<typename T>
+      class optional_last_value
+    {
+    public:
+      typedef optional<T> result_type;
+
+      template<typename InputIterator>
+        optional<T> operator()(InputIterator first, InputIterator last) const
+      {
+        optional<T> value;
+        while (first != last)
+        {
+          try
+          {
+            value = *first;
+          }
+          catch(const expired_slot &) {}
+          ++first;
+        }
+        return value;
+      }
+    };
+
+    template<>
+      class optional_last_value<void>
+    {
+    public:
+      typedef void result_type;
+      template<typename InputIterator>
+        result_type operator()(InputIterator first, InputIterator last) const
+      {
+        while (first != last)
+        {
+          try
+          {
+            *first;
+          }
+          catch(const expired_slot &) {}
+          ++first;
+        }
+        return;
+      }
+    };
+  } // namespace signals2
+} // namespace boost
+#endif // BOOST_SIGNALS2_OPTIONAL_LAST_VALUE_HPP
diff --git a/third_party/boost/boost/signals2/preprocessed_signal.hpp b/third_party/boost/boost/signals2/preprocessed_signal.hpp
new file mode 100644
index 0000000..7d43bd5
--- /dev/null
+++ b/third_party/boost/boost/signals2/preprocessed_signal.hpp
@@ -0,0 +1,61 @@
+/*
+  A thread-safe version of Boost.Signals.
+
+  Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+  Begin: 2007-01-23
+*/
+// Copyright Frank Mori Hess 2007-2008
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_PREPROCESSED_SIGNAL_HPP
+#define BOOST_SIGNALS2_PREPROCESSED_SIGNAL_HPP
+
+#include <boost/preprocessor/arithmetic.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/control/expr_if.hpp>
+#include <boost/preprocessor/iteration.hpp>
+#include <boost/preprocessor/repetition.hpp>
+#include <boost/signals2/detail/preprocessed_arg_type.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_SIGNALS2_MAX_ARGS)
+#define BOOST_PP_FILENAME_1 <boost/signals2/detail/signal_template.hpp>
+#include BOOST_PP_ITERATE()
+
+namespace boost
+{
+  namespace signals2
+  {
+    template<typename Signature,
+      typename Combiner = optional_last_value<typename boost::function_traits<Signature>::result_type>,
+      typename Group = int,
+      typename GroupCompare = std::less<Group>,
+      typename SlotFunction = function<Signature>,
+      typename ExtendedSlotFunction = typename detail::extended_signature<function_traits<Signature>::arity, Signature>::function_type,
+      typename Mutex = mutex >
+    class signal: public detail::signalN<function_traits<Signature>::arity,
+      Signature, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex>::type
+    {
+    private:
+      typedef typename detail::signalN<boost::function_traits<Signature>::arity,
+        Signature, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex>::type base_type;
+    public:
+      signal(const Combiner &combiner_arg = Combiner(), const GroupCompare &group_compare = GroupCompare()):
+        base_type(combiner_arg, group_compare)
+      {}
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && BOOST_WORKAROUND(BOOST_MSVC, < 1800)
+      signal(signal && other) : base_type(std::move(other)) {}
+      signal & operator=(signal && other) { base_type::operator=(std::move(other)); return *this; }
+#endif
+    };
+  }
+}
+
+#endif // BOOST_SIGNALS2_PREPROCESSED_SIGNAL_HPP
diff --git a/third_party/boost/boost/signals2/preprocessed_slot.hpp b/third_party/boost/boost/signals2/preprocessed_slot.hpp
new file mode 100644
index 0000000..322b1a1
--- /dev/null
+++ b/third_party/boost/boost/signals2/preprocessed_slot.hpp
@@ -0,0 +1,72 @@
+// Boost.Signals2 library
+
+// Copyright Frank Mori Hess 2007-2009.
+// Copyright Timmo Stange 2007.
+// Copyright Douglas Gregor 2001-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_PREPROCESSED_SLOT_HPP
+#define BOOST_SIGNALS2_PREPROCESSED_SLOT_HPP
+
+#include <boost/preprocessor/repetition.hpp>
+#include <boost/signals2/detail/preprocessed_arg_type.hpp>
+#include <boost/type_traits/function_traits.hpp>
+
+#ifndef BOOST_SIGNALS2_SLOT_MAX_BINDING_ARGS
+#define BOOST_SIGNALS2_SLOT_MAX_BINDING_ARGS 10
+#endif
+
+
+// template<typename Func, typename BindArgT0, typename BindArgT1, ..., typename BindArgTN-1> slotN(...
+#define BOOST_SIGNALS2_SLOT_N_BINDING_CONSTRUCTOR(z, n, data) \
+  template<typename Func, BOOST_SIGNALS2_PREFIXED_ARGS_TEMPLATE_DECL(n, BindArg)> \
+  BOOST_SIGNALS2_SLOT_CLASS_NAME(BOOST_SIGNALS2_NUM_ARGS)( \
+    const Func &func, BOOST_SIGNALS2_PREFIXED_FULL_REF_ARGS(n, const BindArg)) \
+  { \
+    init_slot_function(boost::bind(func, BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(n))); \
+  }
+#define BOOST_SIGNALS2_SLOT_N_BINDING_CONSTRUCTORS \
+  BOOST_PP_REPEAT_FROM_TO(1, BOOST_SIGNALS2_SLOT_MAX_BINDING_ARGS, BOOST_SIGNALS2_SLOT_N_BINDING_CONSTRUCTOR, ~)
+
+
+#define BOOST_PP_ITERATION_LIMITS (0, BOOST_PP_INC(BOOST_SIGNALS2_MAX_ARGS))
+#define BOOST_PP_FILENAME_1 <boost/signals2/detail/slot_template.hpp>
+#include BOOST_PP_ITERATE()
+
+#undef BOOST_SIGNALS2_SLOT_N_BINDING_CONSTRUCTOR
+#undef BOOST_SIGNALS2_SLOT_N_BINDING_CONSTRUCTORS
+
+namespace boost
+{
+  namespace signals2
+  {
+    template<typename Signature,
+      typename SlotFunction = boost::function<Signature> >
+    class slot: public detail::slotN<function_traits<Signature>::arity,
+      Signature, SlotFunction>::type
+    {
+    private:
+      typedef typename detail::slotN<boost::function_traits<Signature>::arity,
+        Signature, SlotFunction>::type base_type;
+    public:
+      template<typename F>
+      slot(const F& f): base_type(f)
+      {}
+      // bind syntactic sugar
+// template<typename F, typename BindArgT0, typename BindArgT1, ..., typename BindArgTn-1> slot(...
+#define BOOST_SIGNALS2_SLOT_BINDING_CONSTRUCTOR(z, n, data) \
+  template<typename Func, BOOST_SIGNALS2_PREFIXED_ARGS_TEMPLATE_DECL(n, BindArg)> \
+    slot(const Func &func, BOOST_SIGNALS2_PREFIXED_FULL_REF_ARGS(n, const BindArg)): \
+    base_type(func, BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(n)) \
+  {}
+      BOOST_PP_REPEAT_FROM_TO(1, BOOST_SIGNALS2_SLOT_MAX_BINDING_ARGS, BOOST_SIGNALS2_SLOT_BINDING_CONSTRUCTOR, ~)
+#undef BOOST_SIGNALS2_SLOT_BINDING_CONSTRUCTOR
+    };
+  } // namespace signals2
+}
+
+#endif // BOOST_SIGNALS2_PREPROCESSED_SLOT_HPP
diff --git a/third_party/boost/boost/signals2/signal.hpp b/third_party/boost/boost/signals2/signal.hpp
new file mode 100644
index 0000000..afdfa66
--- /dev/null
+++ b/third_party/boost/boost/signals2/signal.hpp
@@ -0,0 +1,62 @@
+//  A thread-safe version of Boost.Signals.
+
+// Copyright Frank Mori Hess 2007-2009
+//
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_SIGNAL_HPP
+#define BOOST_SIGNALS2_SIGNAL_HPP
+
+#include <algorithm>
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/function.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/signals2/connection.hpp>
+#include <boost/signals2/detail/unique_lock.hpp>
+#include <boost/signals2/detail/replace_slot_function.hpp>
+#include <boost/signals2/detail/result_type_wrapper.hpp>
+#include <boost/signals2/detail/signals_common.hpp>
+#include <boost/signals2/detail/signals_common_macros.hpp>
+#include <boost/signals2/detail/slot_groups.hpp>
+#include <boost/signals2/detail/slot_call_iterator.hpp>
+#include <boost/signals2/optional_last_value.hpp>
+#include <boost/signals2/mutex.hpp>
+#include <boost/signals2/slot.hpp>
+#include <functional>
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+#include <boost/signals2/preprocessed_signal.hpp>
+#else
+#include <boost/signals2/variadic_signal.hpp>
+#endif
+
+namespace boost
+{
+  namespace signals2
+  {
+    // free swap function, findable by ADL
+    template<typename Signature,
+      typename Combiner,
+      typename Group,
+      typename GroupCompare,
+      typename SlotFunction,
+      typename ExtendedSlotFunction,
+      typename Mutex>
+      void swap(
+        signal<Signature, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex> &sig1,
+        signal<Signature, Combiner, Group, GroupCompare, SlotFunction, ExtendedSlotFunction, Mutex> &sig2)
+    {
+      sig1.swap(sig2);
+    }
+  }
+}
+
+#endif // BOOST_SIGNALS2_SIGNAL_HPP
diff --git a/third_party/boost/boost/signals2/signal_base.hpp b/third_party/boost/boost/signals2/signal_base.hpp
new file mode 100644
index 0000000..05b6b5f
--- /dev/null
+++ b/third_party/boost/boost/signals2/signal_base.hpp
@@ -0,0 +1,33 @@
+// Boost.Signals2 library
+
+// Copyright Frank Mori Hess 2007-2008.
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_SIGNAL_BASE_HPP
+#define BOOST_SIGNALS2_SIGNAL_BASE_HPP
+
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+
+namespace boost {
+  namespace signals2 {
+    class slot_base;
+
+    class signal_base : public noncopyable
+    {
+    public:
+      friend class slot_base;
+
+      virtual ~signal_base() {}
+    protected:
+      virtual shared_ptr<void> lock_pimpl() const = 0;
+    };
+  } // end namespace signals2
+} // end namespace boost
+
+#endif // BOOST_SIGNALS2_SIGNAL_BASE_HPP
diff --git a/third_party/boost/boost/signals2/slot.hpp b/third_party/boost/boost/signals2/slot.hpp
new file mode 100644
index 0000000..b6ec4d7
--- /dev/null
+++ b/third_party/boost/boost/signals2/slot.hpp
@@ -0,0 +1,33 @@
+// Boost.Signals2 library
+
+// Copyright Frank Mori Hess 2009.
+//
+// Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_SLOT_HPP
+#define BOOST_SIGNALS2_SLOT_HPP
+
+#include <boost/bind.hpp>
+#include <boost/config.hpp>
+#include <boost/function.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/ref.hpp>
+#include <boost/signals2/detail/signals_common.hpp>
+#include <boost/signals2/detail/signals_common_macros.hpp>
+#include <boost/signals2/detail/tracked_objects_visitor.hpp>
+#include <boost/signals2/slot_base.hpp>
+#include <boost/visit_each.hpp>
+#include <boost/weak_ptr.hpp>
+
+#ifdef BOOST_NO_CXX11_VARIADIC_TEMPLATES
+#include <boost/signals2/preprocessed_slot.hpp>
+#else
+#include <boost/signals2/variadic_slot.hpp>
+#endif
+
+#endif // BOOST_SIGNALS2_SLOT_HPP
diff --git a/third_party/boost/boost/signals2/slot_base.hpp b/third_party/boost/boost/signals2/slot_base.hpp
new file mode 100644
index 0000000..0dd80db
--- /dev/null
+++ b/third_party/boost/boost/signals2/slot_base.hpp
@@ -0,0 +1,106 @@
+// Boost.Signals2 library
+
+// Copyright Frank Mori Hess 2007-2008.
+// Copyright Timmo Stange 2007.
+// Copyright Douglas Gregor 2001-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_SLOT_BASE_HPP
+#define BOOST_SIGNALS2_SLOT_BASE_HPP
+
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include <boost/signals2/detail/foreign_ptr.hpp>
+#include <boost/signals2/expired_slot.hpp>
+#include <boost/signals2/signal_base.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/variant/variant.hpp>
+#include <vector>
+
+namespace boost
+{
+  namespace signals2
+  {
+    namespace detail
+    {
+      class tracked_objects_visitor;
+      class trackable_pointee;
+
+      typedef boost::variant<boost::weak_ptr<trackable_pointee>, boost::weak_ptr<void>, detail::foreign_void_weak_ptr > void_weak_ptr_variant;
+      typedef boost::variant<boost::shared_ptr<void>, detail::foreign_void_shared_ptr > void_shared_ptr_variant;
+      class lock_weak_ptr_visitor
+      {
+      public:
+        typedef void_shared_ptr_variant result_type;
+        template<typename WeakPtr>
+        result_type operator()(const WeakPtr &wp) const
+        {
+          return wp.lock();
+        }
+        // overload to prevent incrementing use count of shared_ptr associated
+        // with signals2::trackable objects
+        result_type operator()(const weak_ptr<trackable_pointee> &) const
+        {
+          return boost::shared_ptr<void>();
+        }
+      };
+      class expired_weak_ptr_visitor
+      {
+      public:
+        typedef bool result_type;
+        template<typename WeakPtr>
+        bool operator()(const WeakPtr &wp) const
+        {
+          return wp.expired();
+        }
+      };
+    }
+
+    class slot_base
+    {
+    public:
+      typedef std::vector<detail::void_weak_ptr_variant> tracked_container_type;
+      typedef std::vector<detail::void_shared_ptr_variant> locked_container_type;
+
+      const tracked_container_type& tracked_objects() const {return _tracked_objects;}
+      locked_container_type lock() const
+      {
+        locked_container_type locked_objects;
+        tracked_container_type::const_iterator it;
+        for(it = tracked_objects().begin(); it != tracked_objects().end(); ++it)
+        {
+          locked_objects.push_back(apply_visitor(detail::lock_weak_ptr_visitor(), *it));
+          if(apply_visitor(detail::expired_weak_ptr_visitor(), *it))
+          {
+            throw expired_slot();
+          }
+        }
+        return locked_objects;
+      }
+      bool expired() const
+      {
+        tracked_container_type::const_iterator it;
+        for(it = tracked_objects().begin(); it != tracked_objects().end(); ++it)
+        {
+          if(apply_visitor(detail::expired_weak_ptr_visitor(), *it)) return true;
+        }
+        return false;
+      }
+    protected:
+      friend class detail::tracked_objects_visitor;
+
+      void track_signal(const signal_base &signal)
+      {
+        _tracked_objects.push_back(signal.lock_pimpl());
+      }
+
+      tracked_container_type _tracked_objects;
+    };
+  }
+} // end namespace boost
+
+#endif // BOOST_SIGNALS2_SLOT_BASE_HPP
diff --git a/third_party/boost/boost/signals2/trackable.hpp b/third_party/boost/boost/signals2/trackable.hpp
new file mode 100644
index 0000000..7837d3f
--- /dev/null
+++ b/third_party/boost/boost/signals2/trackable.hpp
@@ -0,0 +1,59 @@
+// Boost.Signals2 library
+
+// Copyright Frank Mori Hess 2007,2009.
+// Copyright Timmo Stange 2007.
+// Copyright Douglas Gregor 2001-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Compatibility class to ease porting from the original
+// Boost.Signals library.  However,
+// boost::signals2::trackable is NOT thread-safe.
+
+// For more information, see http://www.boost.org
+
+#ifndef BOOST_SIGNALS2_TRACKABLE_HPP
+#define BOOST_SIGNALS2_TRACKABLE_HPP
+
+#include <boost/assert.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+
+namespace boost {
+  namespace signals2 {
+    namespace detail
+    {
+        class tracked_objects_visitor;
+
+        // trackable_pointee is used to identify the tracked shared_ptr
+        // originating from the signals2::trackable class.  These tracked
+        // shared_ptr are special in that we shouldn't bother to
+        // increment their use count during signal invocation, since
+        // they don't actually control the lifetime of the
+        // signals2::trackable object they are associated with.
+        class trackable_pointee
+        {};
+    }
+    class trackable {
+    protected:
+      trackable(): _tracked_ptr(static_cast<detail::trackable_pointee*>(0)) {}
+      trackable(const trackable &): _tracked_ptr(static_cast<detail::trackable_pointee*>(0)) {}
+      trackable& operator=(const trackable &)
+      {
+          return *this;
+      }
+      ~trackable() {}
+    private:
+      friend class detail::tracked_objects_visitor;
+      weak_ptr<detail::trackable_pointee> get_weak_ptr() const
+      {
+          return _tracked_ptr;
+      }
+
+      shared_ptr<detail::trackable_pointee> _tracked_ptr;
+    };
+  } // end namespace signals2
+} // end namespace boost
+
+#endif // BOOST_SIGNALS2_TRACKABLE_HPP
diff --git a/third_party/boost/boost/smart_ptr/bad_weak_ptr.hpp b/third_party/boost/boost/smart_ptr/bad_weak_ptr.hpp
new file mode 100644
index 0000000..3e0a1b7
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/bad_weak_ptr.hpp
@@ -0,0 +1,59 @@
+#ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
+#define BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  boost/smart_ptr/bad_weak_ptr.hpp
+//
+//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <exception>
+
+#ifdef __BORLANDC__
+# pragma warn -8026     // Functions with excep. spec. are not expanded inline
+#endif
+
+namespace boost
+{
+
+// The standard library that comes with Borland C++ 5.5.1, 5.6.4
+// defines std::exception and its members as having C calling
+// convention (-pc). When the definition of bad_weak_ptr
+// is compiled with -ps, the compiler issues an error.
+// Hence, the temporary #pragma option -pc below.
+
+#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564
+# pragma option push -pc
+#endif
+
+class bad_weak_ptr: public std::exception
+{
+public:
+
+    virtual char const * what() const throw()
+    {
+        return "tr1::bad_weak_ptr";
+    }
+};
+
+#if defined(__BORLANDC__) && __BORLANDC__ <= 0x564
+# pragma option pop
+#endif
+
+} // namespace boost
+
+#ifdef __BORLANDC__
+# pragma warn .8026     // Functions with excep. spec. are not expanded inline
+#endif
+
+#endif  // #ifndef BOOST_SMART_PTR_BAD_WEAK_PTR_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/detail/operator_bool.hpp b/third_party/boost/boost/smart_ptr/detail/operator_bool.hpp
new file mode 100644
index 0000000..c0289b8
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/detail/operator_bool.hpp
@@ -0,0 +1,64 @@
+//  This header intentionally has no include guards.
+//
+//  Copyright (c) 2001-2009, 2012 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+
+#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR )\
+    && !(defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5130))
+
+    explicit operator bool () const BOOST_NOEXCEPT
+    {
+        return px != 0;
+    }
+
+#elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__)
+
+    operator bool () const BOOST_NOEXCEPT
+    {
+        return px != 0;
+    }
+
+#elif defined( _MANAGED )
+
+    static void unspecified_bool( this_type*** )
+    {
+    }
+
+    typedef void (*unspecified_bool_type)( this_type*** );
+
+    operator unspecified_bool_type() const BOOST_NOEXCEPT
+    {
+        return px == 0? 0: unspecified_bool;
+    }
+
+#elif \
+    ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \
+    ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \
+    ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) )
+
+    typedef element_type * (this_type::*unspecified_bool_type)() const;
+
+    operator unspecified_bool_type() const BOOST_NOEXCEPT
+    {
+        return px == 0? 0: &this_type::get;
+    }
+
+#else
+
+    typedef element_type * this_type::*unspecified_bool_type;
+
+    operator unspecified_bool_type() const BOOST_NOEXCEPT
+    {
+        return px == 0? 0: &this_type::px;
+    }
+
+#endif
+
+    // operator! is redundant, but some compilers need it
+    bool operator! () const BOOST_NOEXCEPT
+    {
+        return px == 0;
+    }
diff --git a/third_party/boost/boost/smart_ptr/detail/shared_count.hpp b/third_party/boost/boost/smart_ptr/detail/shared_count.hpp
new file mode 100644
index 0000000..c52f91a
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/detail/shared_count.hpp
@@ -0,0 +1,709 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  detail/shared_count.hpp
+//
+//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+//  Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifdef __BORLANDC__
+# pragma warn -8027     // Functions containing try are not expanded inline
+#endif
+
+#include <boost/config.hpp>
+#include <boost/checked_delete.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/smart_ptr/bad_weak_ptr.hpp>
+#include <boost/smart_ptr/detail/sp_counted_base.hpp>
+#include <boost/smart_ptr/detail/sp_counted_impl.hpp>
+#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
+#include <boost/detail/workaround.hpp>
+// In order to avoid circular dependencies with Boost.TR1
+// we make sure that our include of <memory> doesn't try to
+// pull in the TR1 headers: that's why we use this header
+// rather than including <memory> directly:
+#include <boost/config/no_tr1/memory.hpp>  // std::auto_ptr
+#include <functional>       // std::less
+
+#ifdef BOOST_NO_EXCEPTIONS
+# include <new>              // std::bad_alloc
+#endif
+
+#include <boost/core/addressof.hpp>
+
+#if defined( BOOST_SP_DISABLE_DEPRECATED )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
+namespace boost
+{
+
+namespace movelib
+{
+
+    template< class T, class D > class unique_ptr;
+
+} // namespace movelib
+
+namespace detail
+{
+
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+
+int const shared_count_id = 0x2C35F101;
+int const   weak_count_id = 0x298C38A4;
+
+#endif
+
+struct sp_nothrow_tag {};
+
+template< class D > struct sp_inplace_tag
+{
+};
+
+template< class T > class sp_reference_wrapper
+{
+public:
+
+    explicit sp_reference_wrapper( T & t): t_( boost::addressof( t ) )
+    {
+    }
+
+    template< class Y > void operator()( Y * p ) const
+    {
+        (*t_)( p );
+    }
+
+private:
+
+    T * t_;
+};
+
+template< class D > struct sp_convert_reference
+{
+    typedef D type;
+};
+
+template< class D > struct sp_convert_reference< D& >
+{
+    typedef sp_reference_wrapper< D > type;
+};
+
+class weak_count;
+
+class shared_count
+{
+private:
+
+    sp_counted_base * pi_;
+
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+    int id_;
+#endif
+
+    friend class weak_count;
+
+public:
+
+    shared_count(): pi_(0) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(shared_count_id)
+#endif
+    {
+    }
+
+    template<class Y> explicit shared_count( Y * p ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(shared_count_id)
+#endif
+    {
+#ifndef BOOST_NO_EXCEPTIONS
+
+        try
+        {
+            pi_ = new sp_counted_impl_p<Y>( p );
+        }
+        catch(...)
+        {
+            boost::checked_delete( p );
+            throw;
+        }
+
+#else
+
+        pi_ = new sp_counted_impl_p<Y>( p );
+
+        if( pi_ == 0 )
+        {
+            boost::checked_delete( p );
+            boost::throw_exception( std::bad_alloc() );
+        }
+
+#endif
+    }
+
+#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
+    template<class Y, class D> shared_count( Y * p, D d ): pi_(0)
+#else
+    template<class P, class D> shared_count( P p, D d ): pi_(0)
+#endif
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(shared_count_id)
+#endif
+    {
+#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
+        typedef Y* P;
+#endif
+#ifndef BOOST_NO_EXCEPTIONS
+
+        try
+        {
+            pi_ = new sp_counted_impl_pd<P, D>(p, d);
+        }
+        catch(...)
+        {
+            d(p); // delete p
+            throw;
+        }
+
+#else
+
+        pi_ = new sp_counted_impl_pd<P, D>(p, d);
+
+        if(pi_ == 0)
+        {
+            d(p); // delete p
+            boost::throw_exception(std::bad_alloc());
+        }
+
+#endif
+    }
+
+#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
+
+    template< class P, class D > shared_count( P p, sp_inplace_tag<D> ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(shared_count_id)
+#endif
+    {
+#ifndef BOOST_NO_EXCEPTIONS
+
+        try
+        {
+            pi_ = new sp_counted_impl_pd< P, D >( p );
+        }
+        catch( ... )
+        {
+            D::operator_fn( p ); // delete p
+            throw;
+        }
+
+#else
+
+        pi_ = new sp_counted_impl_pd< P, D >( p );
+
+        if( pi_ == 0 )
+        {
+            D::operator_fn( p ); // delete p
+            boost::throw_exception( std::bad_alloc() );
+        }
+
+#endif // #ifndef BOOST_NO_EXCEPTIONS
+    }
+
+#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
+
+    template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(shared_count_id)
+#endif
+    {
+        typedef sp_counted_impl_pda<P, D, A> impl_type;
+
+#if !defined( BOOST_NO_CXX11_ALLOCATOR )
+
+        typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
+
+#else
+
+        typedef typename A::template rebind< impl_type >::other A2;
+
+#endif
+
+        A2 a2( a );
+
+#ifndef BOOST_NO_EXCEPTIONS
+
+        try
+        {
+#if !defined( BOOST_NO_CXX11_ALLOCATOR )
+
+            impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
+            pi_ = pi;
+            std::allocator_traits<A2>::construct( a2, pi, p, d, a );
+
+#else
+
+            pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
+            ::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
+
+#endif
+        }
+        catch(...)
+        {
+            d( p );
+
+            if( pi_ != 0 )
+            {
+                a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
+            }
+
+            throw;
+        }
+
+#else
+
+#if !defined( BOOST_NO_CXX11_ALLOCATOR )
+
+        impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
+        pi_ = pi;
+
+#else
+
+        pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
+
+#endif
+
+        if( pi_ != 0 )
+        {
+#if !defined( BOOST_NO_CXX11_ALLOCATOR )
+
+            std::allocator_traits<A2>::construct( a2, pi, p, d, a );
+
+#else
+
+            ::new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
+
+#endif
+        }
+        else
+        {
+            d( p );
+            boost::throw_exception( std::bad_alloc() );
+        }
+
+#endif
+    }
+
+#if !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
+
+    template< class P, class D, class A > shared_count( P p, sp_inplace_tag< D >, A a ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(shared_count_id)
+#endif
+    {
+        typedef sp_counted_impl_pda< P, D, A > impl_type;
+
+#if !defined( BOOST_NO_CXX11_ALLOCATOR )
+
+        typedef typename std::allocator_traits<A>::template rebind_alloc< impl_type > A2;
+
+#else
+
+        typedef typename A::template rebind< impl_type >::other A2;
+
+#endif
+
+        A2 a2( a );
+
+#ifndef BOOST_NO_EXCEPTIONS
+
+        try
+        {
+#if !defined( BOOST_NO_CXX11_ALLOCATOR )
+
+            impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
+            pi_ = pi;
+            std::allocator_traits<A2>::construct( a2, pi, p, a );
+
+#else
+
+            pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
+            ::new( static_cast< void* >( pi_ ) ) impl_type( p, a );
+
+#endif
+        }
+        catch(...)
+        {
+            D::operator_fn( p );
+
+            if( pi_ != 0 )
+            {
+                a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
+            }
+
+            throw;
+        }
+
+#else
+
+#if !defined( BOOST_NO_CXX11_ALLOCATOR )
+
+        impl_type * pi = std::allocator_traits<A2>::allocate( a2, 1 );
+        pi_ = pi;
+
+#else
+
+        pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
+
+#endif
+
+        if( pi_ != 0 )
+        {
+#if !defined( BOOST_NO_CXX11_ALLOCATOR )
+
+            std::allocator_traits<A2>::construct( a2, pi, p, a );
+
+#else
+
+            ::new( static_cast< void* >( pi_ ) ) impl_type( p, a );
+
+#endif
+        }
+        else
+        {
+            D::operator_fn( p );
+            boost::throw_exception( std::bad_alloc() );
+        }
+
+#endif // #ifndef BOOST_NO_EXCEPTIONS
+    }
+
+#endif // !defined( BOOST_NO_FUNCTION_TEMPLATE_ORDERING )
+
+#ifndef BOOST_NO_AUTO_PTR
+
+    // auto_ptr<Y> is special cased to provide the strong guarantee
+
+    template<class Y>
+    explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(shared_count_id)
+#endif
+    {
+#ifdef BOOST_NO_EXCEPTIONS
+
+        if( pi_ == 0 )
+        {
+            boost::throw_exception(std::bad_alloc());
+        }
+
+#endif
+
+        r.release();
+    }
+
+#endif
+
+#if !defined( BOOST_NO_CXX11_SMART_PTR )
+
+    template<class Y, class D>
+    explicit shared_count( std::unique_ptr<Y, D> & r ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(shared_count_id)
+#endif
+    {
+        typedef typename sp_convert_reference<D>::type D2;
+
+        D2 d2( r.get_deleter() );
+        pi_ = new sp_counted_impl_pd< typename std::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
+
+#ifdef BOOST_NO_EXCEPTIONS
+
+        if( pi_ == 0 )
+        {
+            boost::throw_exception( std::bad_alloc() );
+        }
+
+#endif
+
+        r.release();
+    }
+
+#endif
+
+    template<class Y, class D>
+    explicit shared_count( boost::movelib::unique_ptr<Y, D> & r ): pi_( 0 )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(shared_count_id)
+#endif
+    {
+        typedef typename sp_convert_reference<D>::type D2;
+
+        D2 d2( r.get_deleter() );
+        pi_ = new sp_counted_impl_pd< typename boost::movelib::unique_ptr<Y, D>::pointer, D2 >( r.get(), d2 );
+
+#ifdef BOOST_NO_EXCEPTIONS
+
+        if( pi_ == 0 )
+        {
+            boost::throw_exception( std::bad_alloc() );
+        }
+
+#endif
+
+        r.release();
+    }
+
+    ~shared_count() // nothrow
+    {
+        if( pi_ != 0 ) pi_->release();
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        id_ = 0;
+#endif
+    }
+
+    shared_count(shared_count const & r): pi_(r.pi_) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(shared_count_id)
+#endif
+    {
+        if( pi_ != 0 ) pi_->add_ref_copy();
+    }
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+    shared_count(shared_count && r): pi_(r.pi_) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(shared_count_id)
+#endif
+    {
+        r.pi_ = 0;
+    }
+
+#endif
+
+    explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
+    shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
+
+    shared_count & operator= (shared_count const & r) // nothrow
+    {
+        sp_counted_base * tmp = r.pi_;
+
+        if( tmp != pi_ )
+        {
+            if( tmp != 0 ) tmp->add_ref_copy();
+            if( pi_ != 0 ) pi_->release();
+            pi_ = tmp;
+        }
+
+        return *this;
+    }
+
+    void swap(shared_count & r) // nothrow
+    {
+        sp_counted_base * tmp = r.pi_;
+        r.pi_ = pi_;
+        pi_ = tmp;
+    }
+
+    long use_count() const // nothrow
+    {
+        return pi_ != 0? pi_->use_count(): 0;
+    }
+
+    bool unique() const // nothrow
+    {
+        return use_count() == 1;
+    }
+
+    bool empty() const // nothrow
+    {
+        return pi_ == 0;
+    }
+
+    friend inline bool operator==(shared_count const & a, shared_count const & b)
+    {
+        return a.pi_ == b.pi_;
+    }
+
+    friend inline bool operator<(shared_count const & a, shared_count const & b)
+    {
+        return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
+    }
+
+    void * get_deleter( sp_typeinfo const & ti ) const
+    {
+        return pi_? pi_->get_deleter( ti ): 0;
+    }
+
+    void * get_untyped_deleter() const
+    {
+        return pi_? pi_->get_untyped_deleter(): 0;
+    }
+};
+
+
+class weak_count
+{
+private:
+
+    sp_counted_base * pi_;
+
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+    int id_;
+#endif
+
+    friend class shared_count;
+
+public:
+
+    weak_count(): pi_(0) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(weak_count_id)
+#endif
+    {
+    }
+
+    weak_count(shared_count const & r): pi_(r.pi_) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(weak_count_id)
+#endif
+    {
+        if(pi_ != 0) pi_->weak_add_ref();
+    }
+
+    weak_count(weak_count const & r): pi_(r.pi_) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(weak_count_id)
+#endif
+    {
+        if(pi_ != 0) pi_->weak_add_ref();
+    }
+
+// Move support
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+    weak_count(weak_count && r): pi_(r.pi_) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(weak_count_id)
+#endif
+    {
+        r.pi_ = 0;
+    }
+
+#endif
+
+    ~weak_count() // nothrow
+    {
+        if(pi_ != 0) pi_->weak_release();
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        id_ = 0;
+#endif
+    }
+
+    weak_count & operator= (shared_count const & r) // nothrow
+    {
+        sp_counted_base * tmp = r.pi_;
+
+        if( tmp != pi_ )
+        {
+            if(tmp != 0) tmp->weak_add_ref();
+            if(pi_ != 0) pi_->weak_release();
+            pi_ = tmp;
+        }
+
+        return *this;
+    }
+
+    weak_count & operator= (weak_count const & r) // nothrow
+    {
+        sp_counted_base * tmp = r.pi_;
+
+        if( tmp != pi_ )
+        {
+            if(tmp != 0) tmp->weak_add_ref();
+            if(pi_ != 0) pi_->weak_release();
+            pi_ = tmp;
+        }
+
+        return *this;
+    }
+
+    void swap(weak_count & r) // nothrow
+    {
+        sp_counted_base * tmp = r.pi_;
+        r.pi_ = pi_;
+        pi_ = tmp;
+    }
+
+    long use_count() const // nothrow
+    {
+        return pi_ != 0? pi_->use_count(): 0;
+    }
+
+    bool empty() const // nothrow
+    {
+        return pi_ == 0;
+    }
+
+    friend inline bool operator==(weak_count const & a, weak_count const & b)
+    {
+        return a.pi_ == b.pi_;
+    }
+
+    friend inline bool operator<(weak_count const & a, weak_count const & b)
+    {
+        return std::less<sp_counted_base *>()(a.pi_, b.pi_);
+    }
+};
+
+inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(shared_count_id)
+#endif
+{
+    if( pi_ == 0 || !pi_->add_ref_lock() )
+    {
+        boost::throw_exception( boost::bad_weak_ptr() );
+    }
+}
+
+inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ )
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        , id_(shared_count_id)
+#endif
+{
+    if( pi_ != 0 && !pi_->add_ref_lock() )
+    {
+        pi_ = 0;
+    }
+}
+
+} // namespace detail
+
+} // namespace boost
+
+#if defined( BOOST_SP_DISABLE_DEPRECATED )
+#pragma GCC diagnostic pop
+#endif
+
+#ifdef __BORLANDC__
+# pragma warn .8027     // Functions containing try are not expanded inline
+#endif
+
+#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/detail/sp_convertible.hpp b/third_party/boost/boost/smart_ptr/detail/sp_convertible.hpp
new file mode 100644
index 0000000..4bba9ed
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/detail/sp_convertible.hpp
@@ -0,0 +1,92 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//  detail/sp_convertible.hpp
+//
+//  Copyright 2008 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/config.hpp>
+#include <cstddef>
+
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_NO_SFINAE )
+# define BOOST_SP_NO_SP_CONVERTIBLE
+#endif
+
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ < 303 )
+# define BOOST_SP_NO_SP_CONVERTIBLE
+#endif
+
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x630 )
+# define BOOST_SP_NO_SP_CONVERTIBLE
+#endif
+
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
+
+namespace boost
+{
+
+namespace detail
+{
+
+template< class Y, class T > struct sp_convertible
+{
+    typedef char (&yes) [1];
+    typedef char (&no)  [2];
+
+    static yes f( T* );
+    static no  f( ... );
+
+    enum _vt { value = sizeof( (f)( static_cast<Y*>(0) ) ) == sizeof(yes) };
+};
+
+template< class Y, class T > struct sp_convertible< Y, T[] >
+{
+    enum _vt { value = false };
+};
+
+template< class Y, class T > struct sp_convertible< Y[], T[] >
+{
+    enum _vt { value = sp_convertible< Y[1], T[1] >::value };
+};
+
+template< class Y, std::size_t N, class T > struct sp_convertible< Y[N], T[] >
+{
+    enum _vt { value = sp_convertible< Y[1], T[1] >::value };
+};
+
+struct sp_empty
+{
+};
+
+template< bool > struct sp_enable_if_convertible_impl;
+
+template<> struct sp_enable_if_convertible_impl<true>
+{
+    typedef sp_empty type;
+};
+
+template<> struct sp_enable_if_convertible_impl<false>
+{
+};
+
+template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_if_convertible_impl< sp_convertible< Y, T >::value >
+{
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // !defined( BOOST_SP_NO_SP_CONVERTIBLE )
+
+#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/detail/sp_counted_base.hpp b/third_party/boost/boost/smart_ptr/detail/sp_counted_base.hpp
new file mode 100644
index 0000000..0addf07
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/detail/sp_counted_base.hpp
@@ -0,0 +1,93 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  detail/sp_counted_base.hpp
+//
+//  Copyright 2005-2013 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/config.hpp>
+#include <boost/smart_ptr/detail/sp_has_sync.hpp>
+
+#if defined( __clang__ ) && defined( __has_extension )
+# if __has_extension( __c_atomic__ )
+#   define BOOST_SP_HAS_CLANG_C11_ATOMICS
+# endif
+#endif
+
+#if defined( BOOST_SP_DISABLE_THREADS )
+# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
+
+#elif defined( BOOST_SP_USE_STD_ATOMIC )
+# include <boost/smart_ptr/detail/sp_counted_base_std_atomic.hpp>
+
+#elif defined( BOOST_SP_USE_SPINLOCK )
+# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
+
+#elif defined( BOOST_SP_USE_PTHREADS )
+# include <boost/smart_ptr/detail/sp_counted_base_pt.hpp>
+
+#elif defined( BOOST_DISABLE_THREADS ) && !defined( BOOST_SP_ENABLE_THREADS ) && !defined( BOOST_DISABLE_WIN32 )
+# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
+
+#elif defined( BOOST_SP_HAS_CLANG_C11_ATOMICS )
+# include <boost/smart_ptr/detail/sp_counted_base_clang.hpp>
+
+#elif defined( __SNC__ )
+# include <boost/smart_ptr/detail/sp_counted_base_snc_ps3.hpp>
+
+#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) && !defined(__PATHSCALE__)
+# include <boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp>
+
+#elif defined(__HP_aCC) && defined(__ia64)
+# include <boost/smart_ptr/detail/sp_counted_base_acc_ia64.hpp>
+
+#elif defined( __GNUC__ ) && defined( __ia64__ ) && !defined( __INTEL_COMPILER ) && !defined(__PATHSCALE__)
+# include <boost/smart_ptr/detail/sp_counted_base_gcc_ia64.hpp>
+
+#elif defined( __IBMCPP__ ) && defined( __powerpc )
+# include <boost/smart_ptr/detail/sp_counted_base_vacpp_ppc.hpp>
+
+#elif defined( __MWERKS__ ) && defined( __POWERPC__ )
+# include <boost/smart_ptr/detail/sp_counted_base_cw_ppc.hpp>
+
+#elif defined( __GNUC__ ) && ( defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc ) ) && !defined(__PATHSCALE__) && !defined( _AIX )
+# include <boost/smart_ptr/detail/sp_counted_base_gcc_ppc.hpp>
+
+#elif defined( __GNUC__ ) && ( defined( __mips__ ) || defined( _mips ) ) && !defined(__PATHSCALE__)
+# include <boost/smart_ptr/detail/sp_counted_base_gcc_mips.hpp>
+
+#elif defined( BOOST_SP_HAS_SYNC )
+# include <boost/smart_ptr/detail/sp_counted_base_sync.hpp>
+
+#elif defined(__GNUC__) && ( defined( __sparcv9 ) || ( defined( __sparcv8 ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 402 ) ) )
+# include <boost/smart_ptr/detail/sp_counted_base_gcc_sparc.hpp>
+
+#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined(__CYGWIN__)
+# include <boost/smart_ptr/detail/sp_counted_base_w32.hpp>
+
+#elif defined( _AIX )
+# include <boost/smart_ptr/detail/sp_counted_base_aix.hpp>
+
+#elif !defined( BOOST_HAS_THREADS )
+# include <boost/smart_ptr/detail/sp_counted_base_nt.hpp>
+
+#else
+# include <boost/smart_ptr/detail/sp_counted_base_spin.hpp>
+
+#endif
+
+#undef BOOST_SP_HAS_CLANG_C11_ATOMICS
+
+#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/detail/sp_counted_base_clang.hpp b/third_party/boost/boost/smart_ptr/detail/sp_counted_base_clang.hpp
new file mode 100644
index 0000000..b3a9f3c
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/detail/sp_counted_base_clang.hpp
@@ -0,0 +1,140 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//  detail/sp_counted_base_clang.hpp - __c11 clang intrinsics
+//
+//  Copyright (c) 2007, 2013, 2015 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/detail/sp_typeinfo.hpp>
+#include <boost/cstdint.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+typedef _Atomic( boost::int_least32_t ) atomic_int_least32_t;
+
+inline void atomic_increment( atomic_int_least32_t * pw )
+{
+    __c11_atomic_fetch_add( pw, 1, __ATOMIC_RELAXED );
+}
+
+inline boost::int_least32_t atomic_decrement( atomic_int_least32_t * pw )
+{
+    return __c11_atomic_fetch_sub( pw, 1, __ATOMIC_ACQ_REL );
+}
+
+inline boost::int_least32_t atomic_conditional_increment( atomic_int_least32_t * pw )
+{
+    // long r = *pw;
+    // if( r != 0 ) ++*pw;
+    // return r;
+
+    boost::int_least32_t r = __c11_atomic_load( pw, __ATOMIC_RELAXED );
+
+    for( ;; )
+    {
+        if( r == 0 )
+        {
+            return r;
+        }
+
+        if( __c11_atomic_compare_exchange_weak( pw, &r, r + 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED ) )
+        {
+            return r;
+        }
+    }
+}
+
+class sp_counted_base
+{
+private:
+
+    sp_counted_base( sp_counted_base const & );
+    sp_counted_base & operator= ( sp_counted_base const & );
+
+    atomic_int_least32_t use_count_;	// #shared
+    atomic_int_least32_t weak_count_;	// #weak + (#shared != 0)
+
+public:
+
+    sp_counted_base()
+    {
+        __c11_atomic_init( &use_count_, 1 );
+        __c11_atomic_init( &weak_count_, 1 );
+    }
+
+    virtual ~sp_counted_base() // nothrow
+    {
+    }
+
+    // dispose() is called when use_count_ drops to zero, to release
+    // the resources managed by *this.
+
+    virtual void dispose() = 0; // nothrow
+
+    // destroy() is called when weak_count_ drops to zero.
+
+    virtual void destroy() // nothrow
+    {
+        delete this;
+    }
+
+    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+    virtual void * get_untyped_deleter() = 0;
+
+    void add_ref_copy()
+    {
+        atomic_increment( &use_count_ );
+    }
+
+    bool add_ref_lock() // true on success
+    {
+        return atomic_conditional_increment( &use_count_ ) != 0;
+    }
+
+    void release() // nothrow
+    {
+        if( atomic_decrement( &use_count_ ) == 1 )
+        {
+            dispose();
+            weak_release();
+        }
+    }
+
+    void weak_add_ref() // nothrow
+    {
+        atomic_increment( &weak_count_ );
+    }
+
+    void weak_release() // nothrow
+    {
+        if( atomic_decrement( &weak_count_ ) == 1 )
+        {
+            destroy();
+        }
+    }
+
+    long use_count() const // nothrow
+    {
+        return __c11_atomic_load( const_cast< atomic_int_least32_t* >( &use_count_ ), __ATOMIC_ACQUIRE );
+    }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_CLANG_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp b/third_party/boost/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
new file mode 100644
index 0000000..173dce5
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp
@@ -0,0 +1,174 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  detail/sp_counted_base_gcc_x86.hpp - g++ on 486+ or AMD64
+//
+//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+//  Copyright 2004-2005 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//
+//  Lock-free algorithm by Alexander Terekhov
+//
+//  Thanks to Ben Hitchings for the #weak + (#shared != 0)
+//  formulation
+//
+
+#include <boost/detail/sp_typeinfo.hpp>
+
+namespace boost
+{
+
+namespace detail
+{
+
+inline int atomic_exchange_and_add( int * pw, int dv )
+{
+    // int r = *pw;
+    // *pw += dv;
+    // return r;
+
+    int r;
+
+    __asm__ __volatile__
+    (
+        "lock\n\t"
+        "xadd %1, %0":
+        "=m"( *pw ), "=r"( r ): // outputs (%0, %1)
+        "m"( *pw ), "1"( dv ): // inputs (%2, %3 == %1)
+        "memory", "cc" // clobbers
+    );
+
+    return r;
+}
+
+inline void atomic_increment( int * pw )
+{
+    //atomic_exchange_and_add( pw, 1 );
+
+    __asm__
+    (
+        "lock\n\t"
+        "incl %0":
+        "=m"( *pw ): // output (%0)
+        "m"( *pw ): // input (%1)
+        "cc" // clobbers
+    );
+}
+
+inline int atomic_conditional_increment( int * pw )
+{
+    // int rv = *pw;
+    // if( rv != 0 ) ++*pw;
+    // return rv;
+
+    int rv, tmp;
+
+    __asm__
+    (
+        "movl %0, %%eax\n\t"
+        "0:\n\t"
+        "test %%eax, %%eax\n\t"
+        "je 1f\n\t"
+        "movl %%eax, %2\n\t"
+        "incl %2\n\t"
+        "lock\n\t"
+        "cmpxchgl %2, %0\n\t"
+        "jne 0b\n\t"
+        "1:":
+        "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2)
+        "m"( *pw ): // input (%3)
+        "cc" // clobbers
+    );
+
+    return rv;
+}
+
+class sp_counted_base
+{
+private:
+
+    sp_counted_base( sp_counted_base const & );
+    sp_counted_base & operator= ( sp_counted_base const & );
+
+    int use_count_;        // #shared
+    int weak_count_;       // #weak + (#shared != 0)
+
+public:
+
+    sp_counted_base(): use_count_( 1 ), weak_count_( 1 )
+    {
+    }
+
+    virtual ~sp_counted_base() // nothrow
+    {
+    }
+
+    // dispose() is called when use_count_ drops to zero, to release
+    // the resources managed by *this.
+
+    virtual void dispose() = 0; // nothrow
+
+    // destroy() is called when weak_count_ drops to zero.
+
+    virtual void destroy() // nothrow
+    {
+        delete this;
+    }
+
+    virtual void * get_deleter( sp_typeinfo const & ti ) = 0;
+    virtual void * get_untyped_deleter() = 0;
+
+    void add_ref_copy()
+    {
+        atomic_increment( &use_count_ );
+    }
+
+    bool add_ref_lock() // true on success
+    {
+        return atomic_conditional_increment( &use_count_ ) != 0;
+    }
+
+    void release() // nothrow
+    {
+        if( atomic_exchange_and_add( &use_count_, -1 ) == 1 )
+        {
+            dispose();
+            weak_release();
+        }
+    }
+
+    void weak_add_ref() // nothrow
+    {
+        atomic_increment( &weak_count_ );
+    }
+
+    void weak_release() // nothrow
+    {
+        if( atomic_exchange_and_add( &weak_count_, -1 ) == 1 )
+        {
+            destroy();
+        }
+    }
+
+    long use_count() const // nothrow
+    {
+        return static_cast<int const volatile &>( use_count_ );
+    }
+};
+
+} // namespace detail
+
+} // namespace boost
+
+#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_BASE_GCC_X86_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/detail/sp_counted_impl.hpp b/third_party/boost/boost/smart_ptr/detail/sp_counted_impl.hpp
new file mode 100644
index 0000000..1222f3c
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/detail/sp_counted_impl.hpp
@@ -0,0 +1,271 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  detail/sp_counted_impl.hpp
+//
+//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
+//  Copyright 2004-2005 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/config.hpp>
+
+#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
+# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
+#endif
+
+#include <boost/checked_delete.hpp>
+#include <boost/smart_ptr/detail/sp_counted_base.hpp>
+
+#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
+#include <boost/smart_ptr/detail/quick_allocator.hpp>
+#endif
+
+#if defined(BOOST_SP_USE_STD_ALLOCATOR)
+#include <memory>           // std::allocator
+#endif
+
+#include <cstddef>          // std::size_t
+
+namespace boost
+{
+
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+
+void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn );
+void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn );
+
+#endif
+
+namespace detail
+{
+
+template<class X> class sp_counted_impl_p: public sp_counted_base
+{
+private:
+
+    X * px_;
+
+    sp_counted_impl_p( sp_counted_impl_p const & );
+    sp_counted_impl_p & operator= ( sp_counted_impl_p const & );
+
+    typedef sp_counted_impl_p<X> this_type;
+
+public:
+
+    explicit sp_counted_impl_p( X * px ): px_( px )
+    {
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        boost::sp_scalar_constructor_hook( px, sizeof(X), this );
+#endif
+    }
+
+    virtual void dispose() // nothrow
+    {
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
+#endif
+        boost::checked_delete( px_ );
+    }
+
+    virtual void * get_deleter( sp_typeinfo const & )
+    {
+        return 0;
+    }
+
+    virtual void * get_untyped_deleter()
+    {
+        return 0;
+    }
+
+#if defined(BOOST_SP_USE_STD_ALLOCATOR)
+
+    void * operator new( std::size_t )
+    {
+        return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
+    }
+
+    void operator delete( void * p )
+    {
+        std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
+    }
+
+#endif
+
+#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
+
+    void * operator new( std::size_t )
+    {
+        return quick_allocator<this_type>::alloc();
+    }
+
+    void operator delete( void * p )
+    {
+        quick_allocator<this_type>::dealloc( p );
+    }
+
+#endif
+};
+
+//
+// Borland's Codeguard trips up over the -Vx- option here:
+//
+#ifdef __CODEGUARD__
+# pragma option push -Vx-
+#endif
+
+template<class P, class D> class sp_counted_impl_pd: public sp_counted_base
+{
+private:
+
+    P ptr; // copy constructor must not throw
+    D del; // copy constructor must not throw
+
+    sp_counted_impl_pd( sp_counted_impl_pd const & );
+    sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
+
+    typedef sp_counted_impl_pd<P, D> this_type;
+
+public:
+
+    // pre: d(p) must not throw
+
+    sp_counted_impl_pd( P p, D & d ): ptr( p ), del( d )
+    {
+    }
+
+    sp_counted_impl_pd( P p ): ptr( p ), del()
+    {
+    }
+
+    virtual void dispose() // nothrow
+    {
+        del( ptr );
+    }
+
+    virtual void * get_deleter( sp_typeinfo const & ti )
+    {
+        return ti == BOOST_SP_TYPEID(D)? &reinterpret_cast<char&>( del ): 0;
+    }
+
+    virtual void * get_untyped_deleter()
+    {
+        return &reinterpret_cast<char&>( del );
+    }
+
+#if defined(BOOST_SP_USE_STD_ALLOCATOR)
+
+    void * operator new( std::size_t )
+    {
+        return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
+    }
+
+    void operator delete( void * p )
+    {
+        std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
+    }
+
+#endif
+
+#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
+
+    void * operator new( std::size_t )
+    {
+        return quick_allocator<this_type>::alloc();
+    }
+
+    void operator delete( void * p )
+    {
+        quick_allocator<this_type>::dealloc( p );
+    }
+
+#endif
+};
+
+template<class P, class D, class A> class sp_counted_impl_pda: public sp_counted_base
+{
+private:
+
+    P p_; // copy constructor must not throw
+    D d_; // copy constructor must not throw
+    A a_; // copy constructor must not throw
+
+    sp_counted_impl_pda( sp_counted_impl_pda const & );
+    sp_counted_impl_pda & operator= ( sp_counted_impl_pda const & );
+
+    typedef sp_counted_impl_pda<P, D, A> this_type;
+
+public:
+
+    // pre: d( p ) must not throw
+
+    sp_counted_impl_pda( P p, D & d, A a ): p_( p ), d_( d ), a_( a )
+    {
+    }
+
+    sp_counted_impl_pda( P p, A a ): p_( p ), d_( a ), a_( a )
+    {
+    }
+
+    virtual void dispose() // nothrow
+    {
+        d_( p_ );
+    }
+
+    virtual void destroy() // nothrow
+    {
+#if !defined( BOOST_NO_CXX11_ALLOCATOR )
+
+        typedef typename std::allocator_traits<A>::template rebind_alloc< this_type > A2;
+
+#else
+
+        typedef typename A::template rebind< this_type >::other A2;
+
+#endif
+
+        A2 a2( a_ );
+
+#if !defined( BOOST_NO_CXX11_ALLOCATOR )
+
+        std::allocator_traits<A2>::destroy( a2, this );
+
+#else
+
+        this->~this_type();
+
+#endif
+
+        a2.deallocate( this, 1 );
+    }
+
+    virtual void * get_deleter( sp_typeinfo const & ti )
+    {
+        return ti == BOOST_SP_TYPEID( D )? &reinterpret_cast<char&>( d_ ): 0;
+    }
+
+    virtual void * get_untyped_deleter()
+    {
+        return &reinterpret_cast<char&>( d_ );
+    }
+};
+
+#ifdef __CODEGUARD__
+# pragma option pop
+#endif
+
+} // namespace detail
+
+} // namespace boost
+
+#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/detail/sp_disable_deprecated.hpp b/third_party/boost/boost/smart_ptr/detail/sp_disable_deprecated.hpp
new file mode 100644
index 0000000..f79bdf3
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/detail/sp_disable_deprecated.hpp
@@ -0,0 +1,40 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  boost/smart_ptr/detail/sp_disable_deprecated.hpp
+//
+//  Copyright 2015 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/config.hpp>
+
+#if defined( __GNUC__ ) && ( defined( __GXX_EXPERIMENTAL_CXX0X__ ) || ( __cplusplus >= 201103L ) )
+
+# if defined( BOOST_GCC )
+
+#  if BOOST_GCC >= 40600
+#   define BOOST_SP_DISABLE_DEPRECATED
+#  endif
+
+# elif defined( __clang__ ) && defined( __has_warning )
+
+#  if __has_warning( "-Wdeprecated-declarations" )
+#   define BOOST_SP_DISABLE_DEPRECATED
+#  endif
+
+# endif
+
+#endif
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_DISABLE_DEPRECATED_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/detail/sp_has_sync.hpp b/third_party/boost/boost/smart_ptr/detail/sp_has_sync.hpp
new file mode 100644
index 0000000..51c8682
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/detail/sp_has_sync.hpp
@@ -0,0 +1,69 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  boost/smart_ptr/detail/sp_has_sync.hpp
+//
+//  Copyright (c) 2008, 2009 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  Defines the BOOST_SP_HAS_SYNC macro if the __sync_* intrinsics
+//  are available.
+//
+
+#ifndef BOOST_SP_NO_SYNC
+
+#if defined( __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 )
+
+# define BOOST_SP_HAS_SYNC
+
+#elif defined( __IBMCPP__ ) && ( __IBMCPP__ >= 1210 )
+
+# define BOOST_SP_HAS_SYNC
+
+#elif defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 401 )
+
+#define BOOST_SP_HAS_SYNC
+
+#if defined( __arm__ )  || defined( __armel__ )
+#undef BOOST_SP_HAS_SYNC
+#endif
+
+#if defined( __hppa ) || defined( __hppa__ )
+#undef BOOST_SP_HAS_SYNC
+#endif
+
+#if defined( __m68k__ )
+#undef BOOST_SP_HAS_SYNC
+#endif
+
+#if defined( __sh__ )
+#undef BOOST_SP_HAS_SYNC
+#endif
+
+#if defined( __sparc__ )
+#undef BOOST_SP_HAS_SYNC
+#endif
+
+#if defined( __INTEL_COMPILER ) && !defined( __ia64__ ) && ( __INTEL_COMPILER < 1110 )
+#undef BOOST_SP_HAS_SYNC
+#endif
+
+#if defined(__PATHSCALE__) && ((__PATHCC__ == 4) && (__PATHCC_MINOR__ < 9))
+#undef BOOST_SP_HAS_SYNC
+#endif
+
+#endif
+
+#endif // #ifndef BOOST_SP_NO_SYNC
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_HAS_SYNC_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/detail/sp_nullptr_t.hpp b/third_party/boost/boost/smart_ptr/detail/sp_nullptr_t.hpp
new file mode 100644
index 0000000..219ae80
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/detail/sp_nullptr_t.hpp
@@ -0,0 +1,45 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//  detail/sp_nullptr_t.hpp
+//
+//  Copyright 2013 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/config.hpp>
+#include <cstddef>
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+namespace boost
+{
+
+namespace detail
+{
+
+#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) )
+
+    typedef decltype(nullptr) sp_nullptr_t;
+
+#else
+
+    typedef std::nullptr_t sp_nullptr_t;
+
+#endif
+
+} // namespace detail
+
+} // namespace boost
+
+#endif // !defined( BOOST_NO_CXX11_NULLPTR )
+
+#endif  // #ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/detail/spinlock.hpp b/third_party/boost/boost/smart_ptr/detail/spinlock.hpp
new file mode 100644
index 0000000..19f93d7
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/detail/spinlock.hpp
@@ -0,0 +1,65 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  boost/detail/spinlock.hpp
+//
+//  Copyright (c) 2008 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  struct spinlock
+//  {
+//      void lock();
+//      bool try_lock();
+//      void unlock();
+//
+//      class scoped_lock;
+//  };
+//
+//  #define BOOST_DETAIL_SPINLOCK_INIT <unspecified>
+//
+
+#include <boost/config.hpp>
+#include <boost/smart_ptr/detail/sp_has_sync.hpp>
+
+#if defined( BOOST_SP_USE_STD_ATOMIC )
+# if !defined( __clang__ )
+#   include <boost/smart_ptr/detail/spinlock_std_atomic.hpp>
+# else
+//  Clang (at least up to 3.4) can't compile spinlock_pool when
+//  using std::atomic, so substitute the __sync implementation instead.
+#   include <boost/smart_ptr/detail/spinlock_sync.hpp>
+# endif
+
+#elif defined( BOOST_SP_USE_PTHREADS )
+#  include <boost/smart_ptr/detail/spinlock_pt.hpp>
+
+#elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ )
+#  include <boost/smart_ptr/detail/spinlock_gcc_arm.hpp>
+
+#elif defined( BOOST_SP_HAS_SYNC )
+#  include <boost/smart_ptr/detail/spinlock_sync.hpp>
+
+#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+#  include <boost/smart_ptr/detail/spinlock_w32.hpp>
+
+#elif defined(BOOST_HAS_PTHREADS)
+#  include <boost/smart_ptr/detail/spinlock_pt.hpp>
+
+#elif !defined(BOOST_HAS_THREADS)
+#  include <boost/smart_ptr/detail/spinlock_nt.hpp>
+
+#else
+#  error Unrecognized threading platform
+#endif
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/detail/spinlock_pool.hpp b/third_party/boost/boost/smart_ptr/detail/spinlock_pool.hpp
new file mode 100644
index 0000000..2ddf22e
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/detail/spinlock_pool.hpp
@@ -0,0 +1,91 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  boost/detail/spinlock_pool.hpp
+//
+//  Copyright (c) 2008 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  spinlock_pool<0> is reserved for atomic<>, when/if it arrives
+//  spinlock_pool<1> is reserved for shared_ptr reference counts
+//  spinlock_pool<2> is reserved for shared_ptr atomic access
+//
+
+#include <boost/config.hpp>
+#include <boost/smart_ptr/detail/spinlock.hpp>
+#include <cstddef>
+
+namespace boost
+{
+
+namespace detail
+{
+
+template< int M > class spinlock_pool
+{
+private:
+
+    static spinlock pool_[ 41 ];
+
+public:
+
+    static spinlock & spinlock_for( void const * pv )
+    {
+#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64
+        std::size_t i = reinterpret_cast< unsigned long long >( pv ) % 41;
+#else
+        std::size_t i = reinterpret_cast< std::size_t >( pv ) % 41;
+#endif
+        return pool_[ i ];
+    }
+
+    class scoped_lock
+    {
+    private:
+
+        spinlock & sp_;
+
+        scoped_lock( scoped_lock const & );
+        scoped_lock & operator=( scoped_lock const & );
+
+    public:
+
+        explicit scoped_lock( void const * pv ): sp_( spinlock_for( pv ) )
+        {
+            sp_.lock();
+        }
+
+        ~scoped_lock()
+        {
+            sp_.unlock();
+        }
+    };
+};
+
+template< int M > spinlock spinlock_pool< M >::pool_[ 41 ] =
+{
+    BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+    BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+    BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+    BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+    BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+    BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+    BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+    BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT, BOOST_DETAIL_SPINLOCK_INIT,
+    BOOST_DETAIL_SPINLOCK_INIT
+};
+
+} // namespace detail
+} // namespace boost
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_POOL_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/detail/spinlock_sync.hpp b/third_party/boost/boost/smart_ptr/detail/spinlock_sync.hpp
new file mode 100644
index 0000000..a7145c5
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/detail/spinlock_sync.hpp
@@ -0,0 +1,87 @@
+#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  Copyright (c) 2008 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#include <boost/smart_ptr/detail/yield_k.hpp>
+
+#if defined( __ia64__ ) && defined( __INTEL_COMPILER )
+# include <ia64intrin.h>
+#endif
+
+namespace boost
+{
+
+namespace detail
+{
+
+class spinlock
+{
+public:
+
+    int v_;
+
+public:
+
+    bool try_lock()
+    {
+        int r = __sync_lock_test_and_set( &v_, 1 );
+        return r == 0;
+    }
+
+    void lock()
+    {
+        for( unsigned k = 0; !try_lock(); ++k )
+        {
+            boost::detail::yield( k );
+        }
+    }
+
+    void unlock()
+    {
+        __sync_lock_release( &v_ );
+    }
+
+public:
+
+    class scoped_lock
+    {
+    private:
+
+        spinlock & sp_;
+
+        scoped_lock( scoped_lock const & );
+        scoped_lock & operator=( scoped_lock const & );
+
+    public:
+
+        explicit scoped_lock( spinlock & sp ): sp_( sp )
+        {
+            sp.lock();
+        }
+
+        ~scoped_lock()
+        {
+            sp_.unlock();
+        }
+    };
+};
+
+} // namespace detail
+} // namespace boost
+
+#define BOOST_DETAIL_SPINLOCK_INIT {0}
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_SYNC_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/detail/yield_k.hpp b/third_party/boost/boost/smart_ptr/detail/yield_k.hpp
new file mode 100644
index 0000000..44d1836
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/detail/yield_k.hpp
@@ -0,0 +1,177 @@
+#ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
+#define BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  yield_k.hpp
+//
+//  Copyright (c) 2008 Peter Dimov
+//  Copyright (c) Microsoft Corporation 2014
+//
+//  void yield( unsigned k );
+//
+//  Typical use:
+//
+//  for( unsigned k = 0; !try_lock(); ++k ) yield( k );
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+//
+
+#include <boost/config.hpp>
+#include <boost/predef.h>
+
+#if BOOST_PLAT_WINDOWS_RUNTIME
+#include <thread>
+#endif
+
+// BOOST_SMT_PAUSE
+
+#if defined(_MSC_VER) && _MSC_VER >= 1310 && ( defined(_M_IX86) || defined(_M_X64) )
+
+extern "C" void _mm_pause();
+
+#define BOOST_SMT_PAUSE _mm_pause();
+
+#elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
+
+#define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" );
+
+#endif
+
+//
+
+#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ )
+
+#if defined( BOOST_USE_WINDOWS_H )
+# include <windows.h>
+#endif
+
+namespace boost
+{
+
+namespace detail
+{
+
+#if !defined( BOOST_USE_WINDOWS_H ) && !BOOST_PLAT_WINDOWS_RUNTIME
+#if !BOOST_COMP_CLANG || !defined __MINGW32__
+  extern "C" void __stdcall Sleep( unsigned long ms );
+#else
+#include <_mingw.h>
+#if !defined __MINGW64_VERSION_MAJOR
+  extern "C" void __stdcall Sleep( unsigned long ms );
+#else
+  extern "C" __declspec(dllimport) void __stdcall Sleep( unsigned long ms );
+#endif
+#endif
+#endif
+
+inline void yield( unsigned k )
+{
+    if( k < 4 )
+    {
+    }
+#if defined( BOOST_SMT_PAUSE )
+    else if( k < 16 )
+    {
+        BOOST_SMT_PAUSE
+    }
+#endif
+#if !BOOST_PLAT_WINDOWS_RUNTIME
+    else if( k < 32 )
+    {
+        Sleep( 0 );
+    }
+    else
+    {
+        Sleep( 1 );
+    }
+#else
+    else
+    {
+        // Sleep isn't supported on the Windows Runtime.
+        std::this_thread::yield();
+    }
+#endif
+}
+
+} // namespace detail
+
+} // namespace boost
+
+#elif defined( BOOST_HAS_PTHREADS )
+
+#ifndef _AIX
+#include <sched.h>
+#else
+   // AIX's sched.h defines ::var which sometimes conflicts with Lambda's var
+       extern "C" int sched_yield(void);
+#endif
+
+#include <time.h>
+
+namespace boost
+{
+
+namespace detail
+{
+
+inline void yield( unsigned k )
+{
+    if( k < 4 )
+    {
+    }
+#if defined( BOOST_SMT_PAUSE )
+    else if( k < 16 )
+    {
+        BOOST_SMT_PAUSE
+    }
+#endif
+    else if( k < 32 || k & 1 )
+    {
+        sched_yield();
+    }
+    else
+    {
+        // g++ -Wextra warns on {} or {0}
+        struct timespec rqtp = { 0, 0 };
+
+        // POSIX says that timespec has tv_sec and tv_nsec
+        // But it doesn't guarantee order or placement
+
+        rqtp.tv_sec = 0;
+        rqtp.tv_nsec = 1000;
+
+        nanosleep( &rqtp, 0 );
+    }
+}
+
+} // namespace detail
+
+} // namespace boost
+
+#else
+
+namespace boost
+{
+
+namespace detail
+{
+
+inline void yield( unsigned )
+{
+}
+
+} // namespace detail
+
+} // namespace boost
+
+#endif
+
+#endif // #ifndef BOOST_SMART_PTR_DETAIL_YIELD_K_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/enable_shared_from_this.hpp b/third_party/boost/boost/smart_ptr/enable_shared_from_this.hpp
new file mode 100644
index 0000000..4e3f243
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/enable_shared_from_this.hpp
@@ -0,0 +1,89 @@
+#ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
+#define BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
+
+//
+//  enable_shared_from_this.hpp
+//
+//  Copyright 2002, 2009 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+//
+//  http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
+//
+
+#include <boost/smart_ptr/weak_ptr.hpp>
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+
+namespace boost
+{
+
+template<class T> class enable_shared_from_this
+{
+protected:
+
+    enable_shared_from_this() BOOST_NOEXCEPT
+    {
+    }
+
+    enable_shared_from_this(enable_shared_from_this const &) BOOST_NOEXCEPT
+    {
+    }
+
+    enable_shared_from_this & operator=(enable_shared_from_this const &) BOOST_NOEXCEPT
+    {
+        return *this;
+    }
+
+    ~enable_shared_from_this() BOOST_NOEXCEPT // ~weak_ptr<T> newer throws, so this call also must not throw
+    {
+    }
+
+public:
+
+    shared_ptr<T> shared_from_this()
+    {
+        shared_ptr<T> p( weak_this_ );
+        BOOST_ASSERT( p.get() == this );
+        return p;
+    }
+
+    shared_ptr<T const> shared_from_this() const
+    {
+        shared_ptr<T const> p( weak_this_ );
+        BOOST_ASSERT( p.get() == this );
+        return p;
+    }
+
+    weak_ptr<T> weak_from_this() BOOST_NOEXCEPT
+    {
+        return weak_this_;
+    }
+
+    weak_ptr<T const> weak_from_this() const BOOST_NOEXCEPT
+    {
+        return weak_this_;
+    }
+
+public: // actually private, but avoids compiler template friendship issues
+
+    // Note: invoked automatically by shared_ptr; do not call
+    template<class X, class Y> void _internal_accept_owner( shared_ptr<X> const * ppx, Y * py ) const
+    {
+        if( weak_this_.expired() )
+        {
+            weak_this_ = shared_ptr<T>( *ppx, py );
+        }
+    }
+
+private:
+
+    mutable weak_ptr<T> weak_this_;
+};
+
+} // namespace boost
+
+#endif  // #ifndef BOOST_SMART_PTR_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/scoped_ptr.hpp b/third_party/boost/boost/smart_ptr/scoped_ptr.hpp
new file mode 100644
index 0000000..d5d8720
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/scoped_ptr.hpp
@@ -0,0 +1,167 @@
+#ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
+#define BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
+
+//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
+//  Copyright (c) 2001, 2002 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org/libs/smart_ptr/scoped_ptr.htm
+//
+
+#include <boost/config.hpp>
+#include <boost/assert.hpp>
+#include <boost/checked_delete.hpp>
+#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
+#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
+#include <boost/detail/workaround.hpp>
+
+#ifndef BOOST_NO_AUTO_PTR
+# include <memory>          // for std::auto_ptr
+#endif
+
+#if defined( BOOST_SP_DISABLE_DEPRECATED )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
+namespace boost
+{
+
+// Debug hooks
+
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+
+void sp_scalar_constructor_hook(void * p);
+void sp_scalar_destructor_hook(void * p);
+
+#endif
+
+//  scoped_ptr mimics a built-in pointer except that it guarantees deletion
+//  of the object pointed to, either on destruction of the scoped_ptr or via
+//  an explicit reset(). scoped_ptr is a simple solution for simple needs;
+//  use shared_ptr or std::auto_ptr if your needs are more complex.
+
+template<class T> class scoped_ptr // noncopyable
+{
+private:
+
+    T * px;
+
+    scoped_ptr(scoped_ptr const &);
+    scoped_ptr & operator=(scoped_ptr const &);
+
+    typedef scoped_ptr<T> this_type;
+
+    void operator==( scoped_ptr const& ) const;
+    void operator!=( scoped_ptr const& ) const;
+
+public:
+
+    typedef T element_type;
+
+    explicit scoped_ptr( T * p = 0 ): px( p ) // never throws
+    {
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        boost::sp_scalar_constructor_hook( px );
+#endif
+    }
+
+#ifndef BOOST_NO_AUTO_PTR
+
+    explicit scoped_ptr( std::auto_ptr<T> p ) BOOST_NOEXCEPT : px( p.release() )
+    {
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        boost::sp_scalar_constructor_hook( px );
+#endif
+    }
+
+#endif
+
+    ~scoped_ptr() // never throws
+    {
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+        boost::sp_scalar_destructor_hook( px );
+#endif
+        boost::checked_delete( px );
+    }
+
+    void reset(T * p = 0) // never throws
+    {
+        BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
+        this_type(p).swap(*this);
+    }
+
+    T & operator*() const // never throws
+    {
+        BOOST_ASSERT( px != 0 );
+        return *px;
+    }
+
+    T * operator->() const // never throws
+    {
+        BOOST_ASSERT( px != 0 );
+        return px;
+    }
+
+    T * get() const BOOST_NOEXCEPT
+    {
+        return px;
+    }
+
+// implicit conversion to "bool"
+#include <boost/smart_ptr/detail/operator_bool.hpp>
+
+    void swap(scoped_ptr & b) BOOST_NOEXCEPT
+    {
+        T * tmp = b.px;
+        b.px = px;
+        px = tmp;
+    }
+};
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+template<class T> inline bool operator==( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+{
+    return p.get() == 0;
+}
+
+template<class T> inline bool operator==( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+    return p.get() == 0;
+}
+
+template<class T> inline bool operator!=( scoped_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+{
+    return p.get() != 0;
+}
+
+template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, scoped_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+    return p.get() != 0;
+}
+
+#endif
+
+template<class T> inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b) BOOST_NOEXCEPT
+{
+    a.swap(b);
+}
+
+// get_pointer(p) is a generic way to say p.get()
+
+template<class T> inline T * get_pointer(scoped_ptr<T> const & p) BOOST_NOEXCEPT
+{
+    return p.get();
+}
+
+} // namespace boost
+
+#if defined( BOOST_SP_DISABLE_DEPRECATED )
+#pragma GCC diagnostic pop
+#endif
+
+#endif // #ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/shared_ptr.hpp b/third_party/boost/boost/smart_ptr/shared_ptr.hpp
new file mode 100644
index 0000000..e8ccb2a
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/shared_ptr.hpp
@@ -0,0 +1,1077 @@
+#ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
+#define BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
+
+//
+//  shared_ptr.hpp
+//
+//  (C) Copyright Greg Colvin and Beman Dawes 1998, 1999.
+//  Copyright (c) 2001-2008 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation.
+//
+
+#include <boost/config.hpp>   // for broken compiler workarounds
+
+// In order to avoid circular dependencies with Boost.TR1
+// we make sure that our include of <memory> doesn't try to
+// pull in the TR1 headers: that's why we use this header
+// rather than including <memory> directly:
+#include <boost/config/no_tr1/memory.hpp>  // std::auto_ptr
+
+#include <boost/assert.hpp>
+#include <boost/checked_delete.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/smart_ptr/detail/shared_count.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/smart_ptr/detail/sp_convertible.hpp>
+#include <boost/smart_ptr/detail/sp_nullptr_t.hpp>
+#include <boost/smart_ptr/detail/sp_disable_deprecated.hpp>
+
+#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
+#include <boost/smart_ptr/detail/spinlock_pool.hpp>
+#endif
+
+#include <algorithm>            // for std::swap
+#include <functional>           // for std::less
+#include <typeinfo>             // for std::bad_cast
+#include <cstddef>              // for std::size_t
+
+#if !defined(BOOST_NO_IOSTREAM)
+#if !defined(BOOST_NO_IOSFWD)
+#include <iosfwd>               // for std::basic_ostream
+#else
+#include <ostream>
+#endif
+#endif
+
+#if defined( BOOST_SP_DISABLE_DEPRECATED )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+
+namespace boost
+{
+
+template<class T> class shared_ptr;
+template<class T> class weak_ptr;
+template<class T> class enable_shared_from_this;
+class enable_shared_from_raw;
+
+namespace movelib
+{
+
+    template< class T, class D > class unique_ptr;
+
+} // namespace movelib
+
+namespace detail
+{
+
+// sp_element, element_type
+
+template< class T > struct sp_element
+{
+    typedef T type;
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template< class T > struct sp_element< T[] >
+{
+    typedef T type;
+};
+
+#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
+
+template< class T, std::size_t N > struct sp_element< T[N] >
+{
+    typedef T type;
+};
+
+#endif
+
+#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+// sp_dereference, return type of operator*
+
+template< class T > struct sp_dereference
+{
+    typedef T & type;
+};
+
+template<> struct sp_dereference< void >
+{
+    typedef void type;
+};
+
+#if !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
+
+template<> struct sp_dereference< void const >
+{
+    typedef void type;
+};
+
+template<> struct sp_dereference< void volatile >
+{
+    typedef void type;
+};
+
+template<> struct sp_dereference< void const volatile >
+{
+    typedef void type;
+};
+
+#endif // !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS)
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template< class T > struct sp_dereference< T[] >
+{
+    typedef void type;
+};
+
+#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
+
+template< class T, std::size_t N > struct sp_dereference< T[N] >
+{
+    typedef void type;
+};
+
+#endif
+
+#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+// sp_member_access, return type of operator->
+
+template< class T > struct sp_member_access
+{
+    typedef T * type;
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template< class T > struct sp_member_access< T[] >
+{
+    typedef void type;
+};
+
+#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
+
+template< class T, std::size_t N > struct sp_member_access< T[N] >
+{
+    typedef void type;
+};
+
+#endif
+
+#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+// sp_array_access, return type of operator[]
+
+template< class T > struct sp_array_access
+{
+    typedef void type;
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template< class T > struct sp_array_access< T[] >
+{
+    typedef T & type;
+};
+
+#if !defined( __BORLANDC__ ) || !BOOST_WORKAROUND( __BORLANDC__, < 0x600 )
+
+template< class T, std::size_t N > struct sp_array_access< T[N] >
+{
+    typedef T & type;
+};
+
+#endif
+
+#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+// sp_extent, for operator[] index check
+
+template< class T > struct sp_extent
+{
+    enum _vt { value = 0 };
+};
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template< class T, std::size_t N > struct sp_extent< T[N] >
+{
+    enum _vt { value = N };
+};
+
+#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+// enable_shared_from_this support
+
+template< class X, class Y, class T > inline void sp_enable_shared_from_this( boost::shared_ptr<X> const * ppx, Y const * py, boost::enable_shared_from_this< T > const * pe )
+{
+    if( pe != 0 )
+    {
+        pe->_internal_accept_owner( ppx, const_cast< Y* >( py ) );
+    }
+}
+
+template< class X, class Y > inline void sp_enable_shared_from_this( boost::shared_ptr<X> * ppx, Y const * py, boost::enable_shared_from_raw const * pe );
+
+#ifdef _MANAGED
+
+// Avoid C4793, ... causes native code generation
+
+struct sp_any_pointer
+{
+    template<class T> sp_any_pointer( T* ) {}
+};
+
+inline void sp_enable_shared_from_this( sp_any_pointer, sp_any_pointer, sp_any_pointer )
+{
+}
+
+#else // _MANAGED
+
+inline void sp_enable_shared_from_this( ... )
+{
+}
+
+#endif // _MANAGED
+
+#if !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_NO_AUTO_PTR )
+
+// rvalue auto_ptr support based on a technique by Dave Abrahams
+
+template< class T, class R > struct sp_enable_if_auto_ptr
+{
+};
+
+template< class T, class R > struct sp_enable_if_auto_ptr< std::auto_ptr< T >, R >
+{
+    typedef R type;
+};
+
+#endif
+
+// sp_assert_convertible
+
+template< class Y, class T > inline void sp_assert_convertible()
+{
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
+
+    // static_assert( sp_convertible< Y, T >::value );
+    typedef char tmp[ sp_convertible< Y, T >::value? 1: -1 ];
+    (void)sizeof( tmp );
+
+#else
+
+    T* p = static_cast< Y* >( 0 );
+    (void)p;
+
+#endif
+}
+
+// pointer constructor helper
+
+template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T > * ppx, Y * p, boost::detail::shared_count & pn )
+{
+    boost::detail::shared_count( p ).swap( pn );
+    boost::detail::sp_enable_shared_from_this( ppx, p, p );
+}
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template< class T, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * p, boost::detail::shared_count & pn )
+{
+    sp_assert_convertible< Y[], T[] >();
+    boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn );
+}
+
+template< class T, std::size_t N, class Y > inline void sp_pointer_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * p, boost::detail::shared_count & pn )
+{
+    sp_assert_convertible< Y[N], T[N] >();
+    boost::detail::shared_count( p, boost::checked_array_deleter< T >() ).swap( pn );
+}
+
+#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+// deleter constructor helper
+
+template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T > * ppx, Y * p )
+{
+    boost::detail::sp_enable_shared_from_this( ppx, p, p );
+}
+
+#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+template< class T, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[] > * /*ppx*/, Y * /*p*/ )
+{
+    sp_assert_convertible< Y[], T[] >();
+}
+
+template< class T, std::size_t N, class Y > inline void sp_deleter_construct( boost::shared_ptr< T[N] > * /*ppx*/, Y * /*p*/ )
+{
+    sp_assert_convertible< Y[N], T[N] >();
+}
+
+#endif // !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+} // namespace detail
+
+
+//
+//  shared_ptr
+//
+//  An enhanced relative of scoped_ptr with reference counted copy semantics.
+//  The object pointed to is deleted when the last shared_ptr pointing to it
+//  is destroyed or reset.
+//
+
+template<class T> class shared_ptr
+{
+private:
+
+    // Borland 5.5.1 specific workaround
+    typedef shared_ptr<T> this_type;
+
+public:
+
+    typedef typename boost::detail::sp_element< T >::type element_type;
+
+    shared_ptr() BOOST_NOEXCEPT : px( 0 ), pn() // never throws in 1.30+
+    {
+    }
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+    shared_ptr( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT : px( 0 ), pn() // never throws
+    {
+    }
+
+#endif
+
+    template<class Y>
+    explicit shared_ptr( Y * p ): px( p ), pn() // Y must be complete
+    {
+        boost::detail::sp_pointer_construct( this, p, pn );
+    }
+
+    //
+    // Requirements: D's copy constructor must not throw
+    //
+    // shared_ptr will release p by calling d(p)
+    //
+
+    template<class Y, class D> shared_ptr( Y * p, D d ): px( p ), pn( p, d )
+    {
+        boost::detail::sp_deleter_construct( this, p );
+    }
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+    template<class D> shared_ptr( boost::detail::sp_nullptr_t p, D d ): px( p ), pn( p, d )
+    {
+    }
+
+#endif
+
+    // As above, but with allocator. A's copy constructor shall not throw.
+
+    template<class Y, class D, class A> shared_ptr( Y * p, D d, A a ): px( p ), pn( p, d, a )
+    {
+        boost::detail::sp_deleter_construct( this, p );
+    }
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+    template<class D, class A> shared_ptr( boost::detail::sp_nullptr_t p, D d, A a ): px( p ), pn( p, d, a )
+    {
+    }
+
+#endif
+
+//  generated copy constructor, destructor are fine...
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+// ... except in C++0x, move disables the implicit copy
+
+    shared_ptr( shared_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
+    {
+    }
+
+#endif
+
+    template<class Y>
+    explicit shared_ptr( weak_ptr<Y> const & r ): pn( r.pn ) // may throw
+    {
+        boost::detail::sp_assert_convertible< Y, T >();
+
+        // it is now safe to copy r.px, as pn(r.pn) did not throw
+        px = r.px;
+    }
+
+    template<class Y>
+    shared_ptr( weak_ptr<Y> const & r, boost::detail::sp_nothrow_tag )
+    BOOST_NOEXCEPT : px( 0 ), pn( r.pn, boost::detail::sp_nothrow_tag() )
+    {
+        if( !pn.empty() )
+        {
+            px = r.px;
+        }
+    }
+
+    template<class Y>
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
+
+    shared_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
+
+#else
+
+    shared_ptr( shared_ptr<Y> const & r )
+
+#endif
+    BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
+    {
+        boost::detail::sp_assert_convertible< Y, T >();
+    }
+
+    // aliasing
+    template< class Y >
+    shared_ptr( shared_ptr<Y> const & r, element_type * p ) BOOST_NOEXCEPT : px( p ), pn( r.pn )
+    {
+    }
+
+#ifndef BOOST_NO_AUTO_PTR
+
+    template<class Y>
+    explicit shared_ptr( std::auto_ptr<Y> & r ): px(r.get()), pn()
+    {
+        boost::detail::sp_assert_convertible< Y, T >();
+
+        Y * tmp = r.get();
+        pn = boost::detail::shared_count( r );
+
+        boost::detail::sp_deleter_construct( this, tmp );
+    }
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+    template<class Y>
+    shared_ptr( std::auto_ptr<Y> && r ): px(r.get()), pn()
+    {
+        boost::detail::sp_assert_convertible< Y, T >();
+
+        Y * tmp = r.get();
+        pn = boost::detail::shared_count( r );
+
+        boost::detail::sp_deleter_construct( this, tmp );
+    }
+
+#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+    template<class Ap>
+    explicit shared_ptr( Ap r, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type = 0 ): px( r.get() ), pn()
+    {
+        typedef typename Ap::element_type Y;
+
+        boost::detail::sp_assert_convertible< Y, T >();
+
+        Y * tmp = r.get();
+        pn = boost::detail::shared_count( r );
+
+        boost::detail::sp_deleter_construct( this, tmp );
+    }
+
+#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+#endif // BOOST_NO_AUTO_PTR
+
+#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+    template< class Y, class D >
+    shared_ptr( std::unique_ptr< Y, D > && r ): px( r.get() ), pn()
+    {
+        boost::detail::sp_assert_convertible< Y, T >();
+
+        typename std::unique_ptr< Y, D >::pointer tmp = r.get();
+        pn = boost::detail::shared_count( r );
+
+        boost::detail::sp_deleter_construct( this, tmp );
+    }
+
+#endif
+
+    template< class Y, class D >
+    shared_ptr( boost::movelib::unique_ptr< Y, D > r ): px( r.get() ), pn()
+    {
+        boost::detail::sp_assert_convertible< Y, T >();
+
+        typename boost::movelib::unique_ptr< Y, D >::pointer tmp = r.get();
+        pn = boost::detail::shared_count( r );
+
+        boost::detail::sp_deleter_construct( this, tmp );
+    }
+
+    // assignment
+
+    shared_ptr & operator=( shared_ptr const & r ) BOOST_NOEXCEPT
+    {
+        this_type(r).swap(*this);
+        return *this;
+    }
+
+#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1400)
+
+    template<class Y>
+    shared_ptr & operator=(shared_ptr<Y> const & r) BOOST_NOEXCEPT
+    {
+        this_type(r).swap(*this);
+        return *this;
+    }
+
+#endif
+
+#ifndef BOOST_NO_AUTO_PTR
+
+    template<class Y>
+    shared_ptr & operator=( std::auto_ptr<Y> & r )
+    {
+        this_type( r ).swap( *this );
+        return *this;
+    }
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+    template<class Y>
+    shared_ptr & operator=( std::auto_ptr<Y> && r )
+    {
+        this_type( static_cast< std::auto_ptr<Y> && >( r ) ).swap( *this );
+        return *this;
+    }
+
+#elif !defined( BOOST_NO_SFINAE ) && !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION )
+
+    template<class Ap>
+    typename boost::detail::sp_enable_if_auto_ptr< Ap, shared_ptr & >::type operator=( Ap r )
+    {
+        this_type( r ).swap( *this );
+        return *this;
+    }
+
+#endif // BOOST_NO_SFINAE, BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+
+#endif // BOOST_NO_AUTO_PTR
+
+#if !defined( BOOST_NO_CXX11_SMART_PTR ) && !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+    template<class Y, class D>
+    shared_ptr & operator=( std::unique_ptr<Y, D> && r )
+    {
+        this_type( static_cast< std::unique_ptr<Y, D> && >( r ) ).swap(*this);
+        return *this;
+    }
+
+#endif
+
+    template<class Y, class D>
+    shared_ptr & operator=( boost::movelib::unique_ptr<Y, D> r )
+    {
+        // this_type( static_cast< unique_ptr<Y, D> && >( r ) ).swap( *this );
+
+        boost::detail::sp_assert_convertible< Y, T >();
+
+        typename boost::movelib::unique_ptr< Y, D >::pointer p = r.get();
+
+        shared_ptr tmp;
+
+        tmp.px = p;
+        tmp.pn = boost::detail::shared_count( r );
+
+        boost::detail::sp_deleter_construct( &tmp, p );
+
+        tmp.swap( *this );
+
+        return *this;
+    }
+
+// Move support
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+    shared_ptr( shared_ptr && r ) BOOST_NOEXCEPT : px( r.px ), pn()
+    {
+        pn.swap( r.pn );
+        r.px = 0;
+    }
+
+    template<class Y>
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
+
+    shared_ptr( shared_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
+
+#else
+
+    shared_ptr( shared_ptr<Y> && r )
+
+#endif
+    BOOST_NOEXCEPT : px( r.px ), pn()
+    {
+        boost::detail::sp_assert_convertible< Y, T >();
+
+        pn.swap( r.pn );
+        r.px = 0;
+    }
+
+    shared_ptr & operator=( shared_ptr && r ) BOOST_NOEXCEPT
+    {
+        this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
+        return *this;
+    }
+
+    template<class Y>
+    shared_ptr & operator=( shared_ptr<Y> && r ) BOOST_NOEXCEPT
+    {
+        this_type( static_cast< shared_ptr<Y> && >( r ) ).swap( *this );
+        return *this;
+    }
+
+#endif
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+    shared_ptr & operator=( boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT // never throws
+    {
+        this_type().swap(*this);
+        return *this;
+    }
+
+#endif
+
+    void reset() BOOST_NOEXCEPT // never throws in 1.30+
+    {
+        this_type().swap(*this);
+    }
+
+    template<class Y> void reset( Y * p ) // Y must be complete
+    {
+        BOOST_ASSERT( p == 0 || p != px ); // catch self-reset errors
+        this_type( p ).swap( *this );
+    }
+
+    template<class Y, class D> void reset( Y * p, D d )
+    {
+        this_type( p, d ).swap( *this );
+    }
+
+    template<class Y, class D, class A> void reset( Y * p, D d, A a )
+    {
+        this_type( p, d, a ).swap( *this );
+    }
+
+    template<class Y> void reset( shared_ptr<Y> const & r, element_type * p )
+    {
+        this_type( r, p ).swap( *this );
+    }
+
+    // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
+    typename boost::detail::sp_dereference< T >::type operator* () const
+    {
+        BOOST_ASSERT( px != 0 );
+        return *px;
+    }
+
+    // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
+    typename boost::detail::sp_member_access< T >::type operator-> () const
+    {
+        BOOST_ASSERT( px != 0 );
+        return px;
+    }
+
+    // never throws (but has a BOOST_ASSERT in it, so not marked with BOOST_NOEXCEPT)
+    typename boost::detail::sp_array_access< T >::type operator[] ( std::ptrdiff_t i ) const
+    {
+        BOOST_ASSERT( px != 0 );
+        BOOST_ASSERT( i >= 0 && ( i < boost::detail::sp_extent< T >::value || boost::detail::sp_extent< T >::value == 0 ) );
+
+        return static_cast< typename boost::detail::sp_array_access< T >::type >( px[ i ] );
+    }
+
+    element_type * get() const BOOST_NOEXCEPT
+    {
+        return px;
+    }
+
+// implicit conversion to "bool"
+#include <boost/smart_ptr/detail/operator_bool.hpp>
+
+    bool unique() const BOOST_NOEXCEPT
+    {
+        return pn.unique();
+    }
+
+    long use_count() const BOOST_NOEXCEPT
+    {
+        return pn.use_count();
+    }
+
+    void swap( shared_ptr & other ) BOOST_NOEXCEPT
+    {
+        std::swap(px, other.px);
+        pn.swap(other.pn);
+    }
+
+    template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
+    {
+        return pn < rhs.pn;
+    }
+
+    template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
+    {
+        return pn < rhs.pn;
+    }
+
+    void * _internal_get_deleter( boost::detail::sp_typeinfo const & ti ) const BOOST_NOEXCEPT
+    {
+        return pn.get_deleter( ti );
+    }
+
+    void * _internal_get_untyped_deleter() const BOOST_NOEXCEPT
+    {
+        return pn.get_untyped_deleter();
+    }
+
+    bool _internal_equiv( shared_ptr const & r ) const BOOST_NOEXCEPT
+    {
+        return px == r.px && pn == r.pn;
+    }
+
+// Tasteless as this may seem, making all members public allows member templates
+// to work in the absence of member template friends. (Matthew Langston)
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+
+private:
+
+    template<class Y> friend class shared_ptr;
+    template<class Y> friend class weak_ptr;
+
+
+#endif
+
+    element_type * px;                 // contained pointer
+    boost::detail::shared_count pn;    // reference counter
+
+};  // shared_ptr
+
+template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
+{
+    return a.get() == b.get();
+}
+
+template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
+{
+    return a.get() != b.get();
+}
+
+#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
+
+// Resolve the ambiguity between our op!= and the one in rel_ops
+
+template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b) BOOST_NOEXCEPT
+{
+    return a.get() != b.get();
+}
+
+#endif
+
+#if !defined( BOOST_NO_CXX11_NULLPTR )
+
+template<class T> inline bool operator==( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+{
+    return p.get() == 0;
+}
+
+template<class T> inline bool operator==( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+    return p.get() == 0;
+}
+
+template<class T> inline bool operator!=( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
+{
+    return p.get() != 0;
+}
+
+template<class T> inline bool operator!=( boost::detail::sp_nullptr_t, shared_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+    return p.get() != 0;
+}
+
+#endif
+
+template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) BOOST_NOEXCEPT
+{
+    return a.owner_before( b );
+}
+
+template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) BOOST_NOEXCEPT
+{
+    a.swap(b);
+}
+
+template<class T, class U> shared_ptr<T> static_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
+{
+    (void) static_cast< T* >( static_cast< U* >( 0 ) );
+
+    typedef typename shared_ptr<T>::element_type E;
+
+    E * p = static_cast< E* >( r.get() );
+    return shared_ptr<T>( r, p );
+}
+
+template<class T, class U> shared_ptr<T> const_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
+{
+    (void) const_cast< T* >( static_cast< U* >( 0 ) );
+
+    typedef typename shared_ptr<T>::element_type E;
+
+    E * p = const_cast< E* >( r.get() );
+    return shared_ptr<T>( r, p );
+}
+
+template<class T, class U> shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
+{
+    (void) dynamic_cast< T* >( static_cast< U* >( 0 ) );
+
+    typedef typename shared_ptr<T>::element_type E;
+
+    E * p = dynamic_cast< E* >( r.get() );
+    return p? shared_ptr<T>( r, p ): shared_ptr<T>();
+}
+
+template<class T, class U> shared_ptr<T> reinterpret_pointer_cast( shared_ptr<U> const & r ) BOOST_NOEXCEPT
+{
+    (void) reinterpret_cast< T* >( static_cast< U* >( 0 ) );
+
+    typedef typename shared_ptr<T>::element_type E;
+
+    E * p = reinterpret_cast< E* >( r.get() );
+    return shared_ptr<T>( r, p );
+}
+
+// get_pointer() enables boost::mem_fn to recognize shared_ptr
+
+template<class T> inline typename shared_ptr<T>::element_type * get_pointer(shared_ptr<T> const & p) BOOST_NOEXCEPT
+{
+    return p.get();
+}
+
+// operator<<
+
+#if !defined(BOOST_NO_IOSTREAM)
+
+#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) &&  (__GNUC__ < 3) )
+
+template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p)
+{
+    os << p.get();
+    return os;
+}
+
+#else
+
+// in STLport's no-iostreams mode no iostream symbols can be used
+#ifndef _STLP_NO_IOSTREAMS
+
+# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT)
+// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL
+using std::basic_ostream;
+template<class E, class T, class Y> basic_ostream<E, T> & operator<< (basic_ostream<E, T> & os, shared_ptr<Y> const & p)
+# else
+template<class E, class T, class Y> std::basic_ostream<E, T> & operator<< (std::basic_ostream<E, T> & os, shared_ptr<Y> const & p)
+# endif
+{
+    os << p.get();
+    return os;
+}
+
+#endif // _STLP_NO_IOSTREAMS
+
+#endif // __GNUC__ < 3
+
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+// get_deleter
+
+namespace detail
+{
+
+#if ( defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) ) || \
+    ( defined(__EDG_VERSION__) && BOOST_WORKAROUND(__EDG_VERSION__, <= 238) ) || \
+    ( defined(__HP_aCC) && BOOST_WORKAROUND(__HP_aCC, <= 33500) )
+
+// g++ 2.9x doesn't allow static_cast<X const *>(void *)
+// apparently EDG 2.38 and HP aCC A.03.35 also don't accept it
+
+template<class D, class T> D * basic_get_deleter(shared_ptr<T> const & p)
+{
+    void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
+    return const_cast<D *>(static_cast<D const *>(q));
+}
+
+#else
+
+template<class D, class T> D * basic_get_deleter( shared_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+    return static_cast<D *>( p._internal_get_deleter(BOOST_SP_TYPEID(D)) );
+}
+
+#endif
+
+class esft2_deleter_wrapper
+{
+private:
+
+    shared_ptr<void const volatile> deleter_;
+
+public:
+
+    esft2_deleter_wrapper()
+    {
+    }
+
+    template< class T > void set_deleter( shared_ptr<T> const & deleter )
+    {
+        deleter_ = deleter;
+    }
+
+    template<typename D> D* get_deleter() const BOOST_NOEXCEPT
+    {
+        return boost::detail::basic_get_deleter<D>( deleter_ );
+    }
+
+    template< class T> void operator()( T* )
+    {
+        BOOST_ASSERT( deleter_.use_count() <= 1 );
+        deleter_.reset();
+    }
+};
+
+} // namespace detail
+
+template<class D, class T> D * get_deleter( shared_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+    D *del = boost::detail::basic_get_deleter<D>(p);
+
+    if(del == 0)
+    {
+        boost::detail::esft2_deleter_wrapper *del_wrapper = boost::detail::basic_get_deleter<boost::detail::esft2_deleter_wrapper>(p);
+// The following get_deleter method call is fully qualified because
+// older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter<D>()
+        if(del_wrapper) del = del_wrapper->::boost::detail::esft2_deleter_wrapper::get_deleter<D>();
+    }
+
+    return del;
+}
+
+// atomic access
+
+#if !defined(BOOST_SP_NO_ATOMIC_ACCESS)
+
+template<class T> inline bool atomic_is_lock_free( shared_ptr<T> const * /*p*/ ) BOOST_NOEXCEPT
+{
+    return false;
+}
+
+template<class T> shared_ptr<T> atomic_load( shared_ptr<T> const * p )
+{
+    boost::detail::spinlock_pool<2>::scoped_lock lock( p );
+    return *p;
+}
+
+template<class T> inline shared_ptr<T> atomic_load_explicit( shared_ptr<T> const * p, /*memory_order mo*/ int )
+{
+    return atomic_load( p );
+}
+
+template<class T> void atomic_store( shared_ptr<T> * p, shared_ptr<T> r )
+{
+    boost::detail::spinlock_pool<2>::scoped_lock lock( p );
+    p->swap( r );
+}
+
+template<class T> inline void atomic_store_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ int )
+{
+    atomic_store( p, r ); // std::move( r )
+}
+
+template<class T> shared_ptr<T> atomic_exchange( shared_ptr<T> * p, shared_ptr<T> r )
+{
+    boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
+
+    sp.lock();
+    p->swap( r );
+    sp.unlock();
+
+    return r; // return std::move( r )
+}
+
+template<class T> shared_ptr<T> atomic_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> r, /*memory_order mo*/ int )
+{
+    return atomic_exchange( p, r ); // std::move( r )
+}
+
+template<class T> bool atomic_compare_exchange( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w )
+{
+    boost::detail::spinlock & sp = boost::detail::spinlock_pool<2>::spinlock_for( p );
+
+    sp.lock();
+
+    if( p->_internal_equiv( *v ) )
+    {
+        p->swap( w );
+
+        sp.unlock();
+
+        return true;
+    }
+    else
+    {
+        shared_ptr<T> tmp( *p );
+
+        sp.unlock();
+
+        tmp.swap( *v );
+        return false;
+    }
+}
+
+template<class T> inline bool atomic_compare_exchange_explicit( shared_ptr<T> * p, shared_ptr<T> * v, shared_ptr<T> w, /*memory_order success*/ int, /*memory_order failure*/ int )
+{
+    return atomic_compare_exchange( p, v, w ); // std::move( w )
+}
+
+#endif // !defined(BOOST_SP_NO_ATOMIC_ACCESS)
+
+// hash_value
+
+template< class T > struct hash;
+
+template< class T > std::size_t hash_value( boost::shared_ptr<T> const & p ) BOOST_NOEXCEPT
+{
+    return boost::hash< T* >()( p.get() );
+}
+
+} // namespace boost
+
+#if defined( BOOST_SP_DISABLE_DEPRECATED )
+#pragma GCC diagnostic pop
+#endif
+
+#endif  // #ifndef BOOST_SMART_PTR_SHARED_PTR_HPP_INCLUDED
diff --git a/third_party/boost/boost/smart_ptr/weak_ptr.hpp b/third_party/boost/boost/smart_ptr/weak_ptr.hpp
new file mode 100644
index 0000000..e3e9ad9
--- /dev/null
+++ b/third_party/boost/boost/smart_ptr/weak_ptr.hpp
@@ -0,0 +1,253 @@
+#ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
+#define BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
+
+//
+//  weak_ptr.hpp
+//
+//  Copyright (c) 2001, 2002, 2003 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+//  See http://www.boost.org/libs/smart_ptr/weak_ptr.htm for documentation.
+//
+
+#include <memory> // boost.TR1 include order fix
+#include <boost/smart_ptr/detail/shared_count.hpp>
+#include <boost/smart_ptr/shared_ptr.hpp>
+
+namespace boost
+{
+
+template<class T> class weak_ptr
+{
+private:
+
+    // Borland 5.5.1 specific workarounds
+    typedef weak_ptr<T> this_type;
+
+public:
+
+    typedef typename boost::detail::sp_element< T >::type element_type;
+
+    weak_ptr() BOOST_NOEXCEPT : px(0), pn() // never throws in 1.30+
+    {
+    }
+
+//  generated copy constructor, assignment, destructor are fine...
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+// ... except in C++0x, move disables the implicit copy
+
+    weak_ptr( weak_ptr const & r ) BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
+    {
+    }
+
+    weak_ptr & operator=( weak_ptr const & r ) BOOST_NOEXCEPT
+    {
+        px = r.px;
+        pn = r.pn;
+        return *this;
+    }
+
+#endif
+
+//
+//  The "obvious" converting constructor implementation:
+//
+//  template<class Y>
+//  weak_ptr(weak_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws
+//  {
+//  }
+//
+//  has a serious problem.
+//
+//  r.px may already have been invalidated. The px(r.px)
+//  conversion may require access to *r.px (virtual inheritance).
+//
+//  It is not possible to avoid spurious access violations since
+//  in multithreaded programs r.px may be invalidated at any point.
+//
+
+    template<class Y>
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
+
+    weak_ptr( weak_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
+
+#else
+
+    weak_ptr( weak_ptr<Y> const & r )
+
+#endif
+    BOOST_NOEXCEPT : px(r.lock().get()), pn(r.pn)
+    {
+        boost::detail::sp_assert_convertible< Y, T >();
+    }
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+    template<class Y>
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
+
+    weak_ptr( weak_ptr<Y> && r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
+
+#else
+
+    weak_ptr( weak_ptr<Y> && r )
+
+#endif
+    BOOST_NOEXCEPT : px( r.lock().get() ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
+    {
+        boost::detail::sp_assert_convertible< Y, T >();
+        r.px = 0;
+    }
+
+    // for better efficiency in the T == Y case
+    weak_ptr( weak_ptr && r )
+    BOOST_NOEXCEPT : px( r.px ), pn( static_cast< boost::detail::weak_count && >( r.pn ) )
+    {
+        r.px = 0;
+    }
+
+    // for better efficiency in the T == Y case
+    weak_ptr & operator=( weak_ptr && r ) BOOST_NOEXCEPT
+    {
+        this_type( static_cast< weak_ptr && >( r ) ).swap( *this );
+        return *this;
+    }
+
+
+#endif
+
+    template<class Y>
+#if !defined( BOOST_SP_NO_SP_CONVERTIBLE )
+
+    weak_ptr( shared_ptr<Y> const & r, typename boost::detail::sp_enable_if_convertible<Y,T>::type = boost::detail::sp_empty() )
+
+#else
+
+    weak_ptr( shared_ptr<Y> const & r )
+
+#endif
+    BOOST_NOEXCEPT : px( r.px ), pn( r.pn )
+    {
+        boost::detail::sp_assert_convertible< Y, T >();
+    }
+
+#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1300)
+
+    template<class Y>
+    weak_ptr & operator=( weak_ptr<Y> const & r ) BOOST_NOEXCEPT
+    {
+        boost::detail::sp_assert_convertible< Y, T >();
+
+        px = r.lock().get();
+        pn = r.pn;
+
+        return *this;
+    }
+
+#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES )
+
+    template<class Y>
+    weak_ptr & operator=( weak_ptr<Y> && r ) BOOST_NOEXCEPT
+    {
+        this_type( static_cast< weak_ptr<Y> && >( r ) ).swap( *this );
+        return *this;
+    }
+
+#endif
+
+    template<class Y>
+    weak_ptr & operator=( shared_ptr<Y> const & r ) BOOST_NOEXCEPT
+    {
+        boost::detail::sp_assert_convertible< Y, T >();
+
+        px = r.px;
+        pn = r.pn;
+
+        return *this;
+    }
+
+#endif
+
+    shared_ptr<T> lock() const BOOST_NOEXCEPT
+    {
+        return shared_ptr<T>( *this, boost::detail::sp_nothrow_tag() );
+    }
+
+    long use_count() const BOOST_NOEXCEPT
+    {
+        return pn.use_count();
+    }
+
+    bool expired() const BOOST_NOEXCEPT
+    {
+        return pn.use_count() == 0;
+    }
+
+    bool _empty() const // extension, not in std::weak_ptr
+    {
+        return pn.empty();
+    }
+
+    void reset() BOOST_NOEXCEPT // never throws in 1.30+
+    {
+        this_type().swap(*this);
+    }
+
+    void swap(this_type & other) BOOST_NOEXCEPT
+    {
+        std::swap(px, other.px);
+        pn.swap(other.pn);
+    }
+
+    template<typename Y>
+    void _internal_aliasing_assign(weak_ptr<Y> const & r, element_type * px2)
+    {
+        px = px2;
+        pn = r.pn;
+    }
+
+    template<class Y> bool owner_before( weak_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
+    {
+        return pn < rhs.pn;
+    }
+
+    template<class Y> bool owner_before( shared_ptr<Y> const & rhs ) const BOOST_NOEXCEPT
+    {
+        return pn < rhs.pn;
+    }
+
+// Tasteless as this may seem, making all members public allows member templates
+// to work in the absence of member template friends. (Matthew Langston)
+
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+
+private:
+
+    template<class Y> friend class weak_ptr;
+    template<class Y> friend class shared_ptr;
+
+#endif
+
+    element_type * px;            // contained pointer
+    boost::detail::weak_count pn; // reference counter
+
+};  // weak_ptr
+
+template<class T, class U> inline bool operator<(weak_ptr<T> const & a, weak_ptr<U> const & b) BOOST_NOEXCEPT
+{
+    return a.owner_before( b );
+}
+
+template<class T> void swap(weak_ptr<T> & a, weak_ptr<T> & b) BOOST_NOEXCEPT
+{
+    a.swap(b);
+}
+
+} // namespace boost
+
+#endif  // #ifndef BOOST_SMART_PTR_WEAK_PTR_HPP_INCLUDED
diff --git a/third_party/boost/boost/static_assert.hpp b/third_party/boost/boost/static_assert.hpp
new file mode 100644
index 0000000..3170923
--- /dev/null
+++ b/third_party/boost/boost/static_assert.hpp
@@ -0,0 +1,178 @@
+//  (C) Copyright John Maddock 2000.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org/libs/static_assert for documentation.
+
+/*
+ Revision history:
+   02 August 2000
+      Initial version.
+*/
+
+#ifndef BOOST_STATIC_ASSERT_HPP
+#define BOOST_STATIC_ASSERT_HPP
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+#if defined(__GNUC__) && !defined(__GXX_EXPERIMENTAL_CXX0X__)
+//
+// This is horrible, but it seems to be the only we can shut up the
+// "anonymous variadic macros were introduced in C99 [-Wvariadic-macros]"
+// warning that get spewed out otherwise in non-C++11 mode.
+//
+#pragma GCC system_header
+#endif
+
+#ifndef BOOST_NO_CXX11_STATIC_ASSERT
+#  ifndef BOOST_NO_CXX11_VARIADIC_MACROS
+#     define BOOST_STATIC_ASSERT_MSG( ... ) static_assert(__VA_ARGS__)
+#  else
+#     define BOOST_STATIC_ASSERT_MSG( B, Msg ) static_assert( B, Msg )
+#  endif
+#else
+#     define BOOST_STATIC_ASSERT_MSG( B, Msg ) BOOST_STATIC_ASSERT( B )
+#endif
+
+#ifdef __BORLANDC__
+//
+// workaround for buggy integral-constant expression support:
+#define BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS
+#endif
+
+#if defined(__GNUC__) && (__GNUC__ == 3) && ((__GNUC_MINOR__ == 3) || (__GNUC_MINOR__ == 4))
+// gcc 3.3 and 3.4 don't produce good error messages with the default version:
+#  define BOOST_SA_GCC_WORKAROUND
+#endif
+
+//
+// If the compiler issues warnings about old C style casts,
+// then enable this:
+//
+#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4)))
+#  ifndef BOOST_NO_CXX11_VARIADIC_MACROS
+#     define BOOST_STATIC_ASSERT_BOOL_CAST( ... ) ((__VA_ARGS__) == 0 ? false : true)
+#  else
+#     define BOOST_STATIC_ASSERT_BOOL_CAST( x ) ((x) == 0 ? false : true)
+#  endif
+#else
+#  ifndef BOOST_NO_CXX11_VARIADIC_MACROS
+#     define BOOST_STATIC_ASSERT_BOOL_CAST( ... ) (bool)(__VA_ARGS__)
+#  else
+#     define BOOST_STATIC_ASSERT_BOOL_CAST(x) (bool)(x)
+#  endif
+#endif
+
+#ifndef BOOST_NO_CXX11_STATIC_ASSERT
+#  ifndef BOOST_NO_CXX11_VARIADIC_MACROS
+#     define BOOST_STATIC_ASSERT( ... ) static_assert(__VA_ARGS__, #__VA_ARGS__)
+#  else
+#     define BOOST_STATIC_ASSERT( B ) static_assert(B, #B)
+#  endif
+#else
+
+namespace boost{
+
+// HP aCC cannot deal with missing names for template value parameters
+template <bool x> struct STATIC_ASSERTION_FAILURE;
+
+template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
+
+// HP aCC cannot deal with missing names for template value parameters
+template<int x> struct static_assert_test{};
+
+}
+
+//
+// Implicit instantiation requires that all member declarations be
+// instantiated, but that the definitions are *not* instantiated.
+//
+// It's not particularly clear how this applies to enum's or typedefs;
+// both are described as declarations [7.1.3] and [7.2] in the standard,
+// however some compilers use "delayed evaluation" of one or more of
+// these when implicitly instantiating templates.  We use typedef declarations
+// by default, but try defining BOOST_USE_ENUM_STATIC_ASSERT if the enum
+// version gets better results from your compiler...
+//
+// Implementation:
+// Both of these versions rely on sizeof(incomplete_type) generating an error
+// message containing the name of the incomplete type.  We use
+// "STATIC_ASSERTION_FAILURE" as the type name here to generate
+// an eye catching error message.  The result of the sizeof expression is either
+// used as an enum initialiser, or as a template argument depending which version
+// is in use...
+// Note that the argument to the assert is explicitly cast to bool using old-
+// style casts: too many compilers currently have problems with static_cast
+// when used inside integral constant expressions.
+//
+#if !defined(BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS)
+
+#if defined(BOOST_MSVC) && defined(BOOST_NO_CXX11_VARIADIC_MACROS)
+#define BOOST_STATIC_ASSERT( B ) \
+   typedef ::boost::static_assert_test<\
+      sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST ( B ) >)>\
+         BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__)
+#elif defined(BOOST_MSVC)
+#define BOOST_STATIC_ASSERT(...) \
+   typedef ::boost::static_assert_test<\
+      sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST (__VA_ARGS__) >)>\
+         BOOST_JOIN(boost_static_assert_typedef_, __COUNTER__)
+#elif (defined(BOOST_INTEL_CXX_VERSION) || defined(BOOST_SA_GCC_WORKAROUND))  && defined(BOOST_NO_CXX11_VARIADIC_MACROS)
+// agurt 15/sep/02: a special care is needed to force Intel C++ issue an error
+// instead of warning in case of failure
+# define BOOST_STATIC_ASSERT( B ) \
+    typedef char BOOST_JOIN(boost_static_assert_typedef_, __LINE__) \
+        [ ::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >::value ]
+#elif (defined(BOOST_INTEL_CXX_VERSION) || defined(BOOST_SA_GCC_WORKAROUND))  && !defined(BOOST_NO_CXX11_VARIADIC_MACROS)
+// agurt 15/sep/02: a special care is needed to force Intel C++ issue an error
+// instead of warning in case of failure
+# define BOOST_STATIC_ASSERT(...) \
+    typedef char BOOST_JOIN(boost_static_assert_typedef_, __LINE__) \
+        [ ::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( __VA_ARGS__ ) >::value ]
+#elif defined(__sgi)
+// special version for SGI MIPSpro compiler
+#define BOOST_STATIC_ASSERT( B ) \
+   BOOST_STATIC_CONSTANT(bool, \
+     BOOST_JOIN(boost_static_assert_test_, __LINE__) = ( B )); \
+   typedef ::boost::static_assert_test<\
+     sizeof(::boost::STATIC_ASSERTION_FAILURE< \
+       BOOST_JOIN(boost_static_assert_test_, __LINE__) >)>\
+         BOOST_JOIN(boost_static_assert_typedef_, __LINE__)
+#elif BOOST_WORKAROUND(__MWERKS__, <= 0x3003)
+// special version for CodeWarrior <= 8.x
+#define BOOST_STATIC_ASSERT( B ) \
+   BOOST_STATIC_CONSTANT(int, \
+     BOOST_JOIN(boost_static_assert_test_, __LINE__) = \
+       sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >) )
+#else
+// generic version
+#  ifndef BOOST_NO_CXX11_VARIADIC_MACROS
+#     define BOOST_STATIC_ASSERT( ... ) \
+         typedef ::boost::static_assert_test<\
+            sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( __VA_ARGS__ ) >)>\
+               BOOST_JOIN(boost_static_assert_typedef_, __LINE__) BOOST_ATTRIBUTE_UNUSED
+#  else
+#     define BOOST_STATIC_ASSERT( B ) \
+         typedef ::boost::static_assert_test<\
+            sizeof(::boost::STATIC_ASSERTION_FAILURE< BOOST_STATIC_ASSERT_BOOL_CAST( B ) >)>\
+               BOOST_JOIN(boost_static_assert_typedef_, __LINE__) BOOST_ATTRIBUTE_UNUSED
+#  endif
+#endif
+
+#else
+// alternative enum based implementation:
+#  ifndef BOOST_NO_CXX11_VARIADIC_MACROS
+#    define BOOST_STATIC_ASSERT( ... ) \
+         enum { BOOST_JOIN(boost_static_assert_enum_, __LINE__) \
+            = sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( __VA_ARGS__ ) >) }
+#  else
+#    define BOOST_STATIC_ASSERT(B) \
+         enum { BOOST_JOIN(boost_static_assert_enum_, __LINE__) \
+            = sizeof(::boost::STATIC_ASSERTION_FAILURE< (bool)( B ) >) }
+#  endif
+#endif
+#endif // defined(BOOST_NO_CXX11_STATIC_ASSERT)
+
+#endif // BOOST_STATIC_ASSERT_HPP
diff --git a/third_party/boost/boost/swap.hpp b/third_party/boost/boost/swap.hpp
new file mode 100644
index 0000000..55cafa4
--- /dev/null
+++ b/third_party/boost/boost/swap.hpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2014 Glen Fernandes
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef BOOST_SWAP_HPP
+#define BOOST_SWAP_HPP
+
+// The header file at this path is deprecated;
+// use boost/core/swap.hpp instead.
+
+#include <boost/core/swap.hpp>
+
+#endif
diff --git a/third_party/boost/boost/throw_exception.hpp b/third_party/boost/boost/throw_exception.hpp
new file mode 100644
index 0000000..aa977df
--- /dev/null
+++ b/third_party/boost/boost/throw_exception.hpp
@@ -0,0 +1,102 @@
+#ifndef UUID_AA15E74A856F11E08B8D93F24824019B
+#define UUID_AA15E74A856F11E08B8D93F24824019B
+#if (__GNUC__*100+__GNUC_MINOR__>301) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
+#pragma GCC system_header
+#endif
+#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
+#pragma warning(push,1)
+#endif
+
+// MS compatible compilers support #pragma once
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+//
+//  boost/throw_exception.hpp
+//
+//  Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
+//  Copyright (c) 2008-2009 Emil Dotchevski and Reverge Studios, Inc.
+//
+//  Distributed under the Boost Software License, Version 1.0. (See
+//  accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  http://www.boost.org/libs/utility/throw_exception.html
+//
+
+#include <boost/detail/workaround.hpp>
+#include <boost/config.hpp>
+#include <exception>
+
+#if !defined( BOOST_EXCEPTION_DISABLE ) && defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT(0x593) )
+# define BOOST_EXCEPTION_DISABLE
+#endif
+
+#if !defined( BOOST_EXCEPTION_DISABLE ) && defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, < 1310 )
+# define BOOST_EXCEPTION_DISABLE
+#endif
+
+#if !defined( BOOST_EXCEPTION_DISABLE )
+# include <boost/exception/exception.hpp>
+#if !defined(BOOST_THROW_EXCEPTION_CURRENT_FUNCTION)
+# include <boost/current_function.hpp>
+# define BOOST_THROW_EXCEPTION_CURRENT_FUNCTION BOOST_CURRENT_FUNCTION
+#endif
+# define BOOST_THROW_EXCEPTION(x) ::boost::exception_detail::throw_exception_(x,BOOST_THROW_EXCEPTION_CURRENT_FUNCTION,__FILE__,__LINE__)
+#else
+# define BOOST_THROW_EXCEPTION(x) ::boost::throw_exception(x)
+#endif
+
+namespace boost
+{
+#ifdef BOOST_NO_EXCEPTIONS
+
+void throw_exception( std::exception const & e ); // user defined
+
+#else
+
+inline void throw_exception_assert_compatibility( std::exception const & ) { }
+
+template<class E> BOOST_NORETURN inline void throw_exception( E const & e )
+{
+    //All boost exceptions are required to derive from std::exception,
+    //to ensure compatibility with BOOST_NO_EXCEPTIONS.
+    throw_exception_assert_compatibility(e);
+
+#ifndef BOOST_EXCEPTION_DISABLE
+    throw enable_current_exception(enable_error_info(e));
+#else
+    throw e;
+#endif
+}
+
+#endif
+
+#if !defined( BOOST_EXCEPTION_DISABLE )
+    namespace
+    exception_detail
+    {
+        template <class E>
+        BOOST_NORETURN
+        void
+        throw_exception_( E const & x, char const * current_function, char const * file, int line )
+        {
+            boost::throw_exception(
+                set_info(
+                    set_info(
+                        set_info(
+                            enable_error_info(x),
+                            throw_function(current_function)),
+                        throw_file(file)),
+                    throw_line(line)));
+        }
+    }
+#endif
+} // namespace boost
+
+#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS)
+#pragma warning(pop)
+#endif
+#endif
diff --git a/third_party/boost/boost/type.hpp b/third_party/boost/boost/type.hpp
new file mode 100644
index 0000000..ab81c91
--- /dev/null
+++ b/third_party/boost/boost/type.hpp
@@ -0,0 +1,18 @@
+// (C) Copyright David Abrahams 2001.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_TYPE_DWA20010120_HPP
+# define BOOST_TYPE_DWA20010120_HPP
+
+namespace boost {
+
+  // Just a simple "type envelope". Useful in various contexts, mostly to work
+  // around some MSVC deficiencies.
+  template <class T>
+  struct type {};
+
+}
+
+#endif // BOOST_TYPE_DWA20010120_HPP
diff --git a/third_party/boost/boost/type_index.hpp b/third_party/boost/boost/type_index.hpp
new file mode 100644
index 0000000..7a9b146
--- /dev/null
+++ b/third_party/boost/boost/type_index.hpp
@@ -0,0 +1,264 @@
+//
+// Copyright (c) Antony Polukhin, 2012-2014.
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_TYPE_INDEX_HPP
+#define BOOST_TYPE_INDEX_HPP
+
+/// \file boost/type_index.hpp
+/// \brief Includes minimal set of headers required to use the Boost.TypeIndex library.
+///
+/// By inclusion of this file most optimal type index classes will be included and used
+/// as a boost::typeindex::type_index and boost::typeindex::type_info.
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+# pragma once
+#endif
+
+#if defined(BOOST_TYPE_INDEX_USER_TYPEINDEX)
+#   include BOOST_TYPE_INDEX_USER_TYPEINDEX
+#   ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
+#       pragma detect_mismatch( "boost__type_index__abi", "user defined type_index class is used: " BOOST_STRINGIZE(BOOST_TYPE_INDEX_USER_TYPEINDEX))
+#   endif
+#elif (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
+#   include <boost/type_index/stl_type_index.hpp>
+#   if defined(BOOST_NO_RTTI) || defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)
+#       include <boost/type_index/detail/stl_register_class.hpp>
+#       ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
+#           pragma detect_mismatch( "boost__type_index__abi", "RTTI is off - typeid() is used only for templates")
+#       endif
+#   else
+#       ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
+#           pragma detect_mismatch( "boost__type_index__abi", "RTTI is used")
+#       endif
+#   endif
+#else
+#   include <boost/type_index/ctti_type_index.hpp>
+#   include <boost/type_index/detail/ctti_register_class.hpp>
+#   ifdef BOOST_HAS_PRAGMA_DETECT_MISMATCH
+#       pragma detect_mismatch( "boost__type_index__abi", "RTTI is off - using CTTI")
+#   endif
+#endif
+
+#ifndef BOOST_TYPE_INDEX_REGISTER_CLASS
+#define BOOST_TYPE_INDEX_REGISTER_CLASS
+#endif
+
+namespace boost { namespace typeindex {
+
+#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
+
+/// \def BOOST_TYPE_INDEX_FUNCTION_SIGNATURE
+/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is used by boost::typeindex::ctti_type_index class to
+/// deduce the name of a type. If your compiler is not recognized
+/// by the TypeIndex library and you wish to work with boost::typeindex::ctti_type_index, you may
+/// define this macro by yourself.
+///
+/// BOOST_TYPE_INDEX_FUNCTION_SIGNATURE must be defined to a compiler specific macro
+/// that outputs the \b whole function signature \b including \b template \b parameters.
+///
+/// If your compiler is not recognised and BOOST_TYPE_INDEX_FUNCTION_SIGNATURE is not defined,
+/// then a compile-time error will arise at any attempt to use boost::typeindex::ctti_type_index classes.
+///
+/// See BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS and BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING
+/// for an information of how to tune the implementation to make a nice pretty_name() output.
+#define BOOST_TYPE_INDEX_FUNCTION_SIGNATURE BOOST_CURRENT_FUNCTION
+
+/// \def BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING
+/// This is a helper macro for making correct pretty_names() with RTTI off.
+///
+/// BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING macro may be defined to
+/// '(begin_skip, end_skip, runtime_skip, runtime_skip_until)' with parameters for adding a
+/// support for compilers, that by default are not recognized by TypeIndex library.
+///
+/// \b Example:
+///
+/// Imagine the situation when
+/// \code boost::typeindex::ctti_type_index::type_id<int>().pretty_name() \endcode
+/// returns the following string:
+/// \code "static const char *boost::detail::ctti<int>::n() [T = int]" \endcode
+/// and \code boost::typeindex::ctti_type_index::type_id<short>().pretty_name() \endcode returns the following:
+/// \code "static const char *boost::detail::ctti<short>::n() [T = short]" \endcode
+///
+/// As we may see first 39 characters are "static const char *boost::detail::ctti<" and they do not depend on
+/// the type T. After first 39 characters we have a human readable type name which is duplicated at the end
+/// of a string. String always ends on ']', which consumes 1 character.
+///
+/// Now if we define `BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING` to
+/// `(39, 1, false, "")` we'll be getting \code "int>::n() [T = int" \endcode
+/// for `boost::typeindex::ctti_type_index::type_id<int>().pretty_name()` and \code "short>::n() [T = short" \endcode
+/// for `boost::typeindex::ctti_type_index::type_id<short>().pretty_name()`.
+///
+/// Now we need to take additional care of the characters that go before the last mention of our type. We'll
+/// do that by telling the macro that we need to cut off everything that goes before the "T = " including the "T = "
+/// itself:
+///
+/// \code (39, 1, true, "T = ") \endcode
+///
+/// In case of GCC or Clang command line we need to add the following line while compiling all the sources:
+///
+/// \code
+/// -DBOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING='(39, 1, true, "T = ")'
+/// \endcode
+/// \param begin_skip How many characters must be skipped at the beginning of the type holding string.
+/// Must be a compile time constant.
+/// \param end_skip How many characters must be skipped at the end of the type holding string.
+/// Must be a compile time constant.
+/// \param runtime_skip Do we need additional checks at runtime to cut off the more characters.
+/// Must be `true` or `false`.
+/// \param runtime_skip_until Skip all the characters before the following string (including the string itself).
+/// Must be a compile time array of characters.
+///
+/// See [RTTI emulation limitations](boost_typeindex/rtti_emulation_limitations.html) for more info.
+#define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING (0, 0, false, "")
+
+
+    /// Depending on a compiler flags, optimal implementation of type_index will be used
+    /// as a default boost::typeindex::type_index.
+    ///
+    /// Could be a boost::typeindex::stl_type_index, boost::typeindex::ctti_type_index or
+    /// user defined type_index class.
+    ///
+    /// \b See boost::typeindex::type_index_facade for a full description of type_index functions.
+    typedef platform_specific type_index;
+#elif defined(BOOST_TYPE_INDEX_USER_TYPEINDEX)
+    // Nothing to do
+#elif (!defined(BOOST_NO_RTTI) && !defined(BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY)) || defined(BOOST_MSVC)
+    typedef boost::typeindex::stl_type_index type_index;
+#else
+    typedef boost::typeindex::ctti_type_index type_index;
+#endif
+
+/// Depending on a compiler flags, optimal implementation of type_info will be used
+/// as a default boost::typeindex::type_info.
+///
+/// Could be a std::type_info, boost::typeindex::detail::ctti_data or
+/// some user defined class.
+///
+/// type_info \b is \b not copyable or default constructible. It is \b not assignable too!
+typedef type_index::type_info_t type_info;
+
+#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
+
+/// \def BOOST_TYPE_INDEX_USER_TYPEINDEX
+/// BOOST_TYPE_INDEX_USER_TYPEINDEX can be defined to the path to header file
+/// with user provided implementation of type_index.
+///
+/// See [Making a custom type_index](boost_typeindex/making_a_custom_type_index.html) section
+/// of documentation for usage example.
+#define BOOST_TYPE_INDEX_USER_TYPEINDEX <full/absolute/path/to/header/with/type_index.hpp>
+
+
+/// \def BOOST_TYPE_INDEX_REGISTER_CLASS
+/// BOOST_TYPE_INDEX_REGISTER_CLASS is used to help to emulate RTTI.
+/// Put this macro into the public section of polymorphic class to allow runtime type detection.
+///
+/// Depending on the typeid() availability this macro will expand to nothing or to virtual helper function
+/// `virtual const type_info& boost_type_info_type_id_runtime_() const noexcept`.
+///
+/// \b Example:
+/// \code
+/// class A {
+/// public:
+///     BOOST_TYPE_INDEX_REGISTER_CLASS
+///     virtual ~A(){}
+/// };
+///
+/// struct B: public A {
+///     BOOST_TYPE_INDEX_REGISTER_CLASS
+/// };
+///
+/// struct C: public B {
+///     BOOST_TYPE_INDEX_REGISTER_CLASS
+/// };
+///
+/// ...
+///
+/// C c1;
+/// A* pc1 = &c1;
+/// assert(boost::typeindex::type_id<C>() == boost::typeindex::type_id_runtime(*pc1));
+/// \endcode
+#define BOOST_TYPE_INDEX_REGISTER_CLASS nothing-or-some-virtual-functions
+
+/// \def BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY
+/// BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY is a helper macro that must be defined if mixing
+/// RTTI on/off modules. See
+/// [Mixing sources with RTTI on and RTTI off](boost_typeindex/mixing_sources_with_rtti_on_and_.html)
+/// section of documentation for more info.
+#define BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY
+
+#endif // defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
+
+
+/// Function to get boost::typeindex::type_index for a type T.
+/// Removes const, volatile && and & modifiers from T.
+///
+/// \b Example:
+/// \code
+/// type_index ti = type_id<int&>();
+/// std::cout << ti.pretty_name();  // Outputs 'int'
+/// \endcode
+///
+/// \tparam T Type for which type_index must be created.
+/// \throw Nothing.
+/// \return boost::typeindex::type_index with information about the specified type T.
+template <class T>
+inline type_index type_id() BOOST_NOEXCEPT {
+    return type_index::type_id<T>();
+}
+
+/// Function for constructing boost::typeindex::type_index instance for type T.
+/// Does not remove const, volatile, & and && modifiers from T.
+///
+/// If T has no const, volatile, & and && modifiers, then returns exactly
+/// the same result as in case of calling `type_id<T>()`.
+///
+/// \b Example:
+/// \code
+/// type_index ti = type_id_with_cvr<int&>();
+/// std::cout << ti.pretty_name();  // Outputs 'int&'
+/// \endcode
+///
+/// \tparam T Type for which type_index must be created.
+/// \throw Nothing.
+/// \return boost::typeindex::type_index with information about the specified type T.
+template <class T>
+inline type_index type_id_with_cvr() BOOST_NOEXCEPT {
+    return type_index::type_id_with_cvr<T>();
+}
+
+/// Function that works exactly like C++ typeid(rtti_val) call, but returns boost::type_index.
+///
+/// Retunrs runtime information about specified type.
+///
+/// \b Requirements: RTTI available or Base and Derived classes must be marked with BOOST_TYPE_INDEX_REGISTER_CLASS.
+///
+/// \b Example:
+/// \code
+/// struct Base { virtual ~Base(){} };
+/// struct Derived: public Base  {};
+/// ...
+/// Derived d;
+/// Base& b = d;
+/// type_index ti = type_id_runtime(b);
+/// std::cout << ti.pretty_name();  // Outputs 'Derived'
+/// \endcode
+///
+/// \param runtime_val Varaible which runtime type must be returned.
+/// \throw Nothing.
+/// \return boost::typeindex::type_index with information about the specified variable.
+template <class T>
+inline type_index type_id_runtime(const T& runtime_val) BOOST_NOEXCEPT {
+    return type_index::type_id_runtime(runtime_val);
+}
+
+}} // namespace boost::typeindex
+
+
+
+#endif // BOOST_TYPE_INDEX_HPP
diff --git a/third_party/boost/boost/type_index/ctti_type_index.hpp b/third_party/boost/boost/type_index/ctti_type_index.hpp
new file mode 100644
index 0000000..1583ff8
--- /dev/null
+++ b/third_party/boost/boost/type_index/ctti_type_index.hpp
@@ -0,0 +1,178 @@
+//
+// Copyright (c) Antony Polukhin, 2013-2014.
+//
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP
+#define BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP
+
+/// \file ctti_type_index.hpp
+/// \brief Contains boost::typeindex::ctti_type_index class.
+///
+/// boost::typeindex::ctti_type_index class can be used as a drop-in replacement
+/// for std::type_index.
+///
+/// It is used in situations when typeid() method is not available or
+/// BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro is defined.
+
+#include <boost/type_index/type_index_facade.hpp>
+#include <boost/type_index/detail/compile_time_type_info.hpp>
+
+#include <cstring>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+# pragma once
+#endif
+
+namespace boost { namespace typeindex {
+
+namespace detail {
+
+// That's the most trickiest part of the TypeIndex library:
+//      1) we do not want to give user ability to manually construct and compare `struct-that-represents-type`
+//      2) we need to distinguish between `struct-that-represents-type` and `const char*`
+//      3) we need a thread-safe way to have references to instances `struct-that-represents-type`
+//      4) we need a compile-time control to make sure that user does not copy or
+// default construct `struct-that-represents-type`
+//
+// Solution would be the following:
+
+/// \class ctti_data
+/// Standard-layout class with private constructors and assignment operators.
+///
+/// You can not work with this class directly. The  purpose of this class is to hold type info
+/// \b when \b RTTI \b is \b off and allow ctti_type_index construction from itself.
+///
+/// \b Example:
+/// \code
+/// const detail::ctti_data& foo();
+/// ...
+/// type_index ti = type_index(foo());
+/// std::cout << ti.pretty_name();
+/// \endcode
+class ctti_data {
+#ifndef BOOST_NO_CXX11_DELETED_FUNCTIONS
+public:
+    ctti_data() = delete;
+    ctti_data(const ctti_data&) = delete;
+    ctti_data& operator=(const ctti_data&) = delete;
+#else
+private:
+    ctti_data();
+    ctti_data(const ctti_data&);
+    ctti_data& operator=(const ctti_data&);
+#endif
+};
+
+} // namespace detail
+
+/// Helper method for getting detail::ctti_data of a template parameter T.
+template <class T>
+inline const detail::ctti_data& ctti_construct() BOOST_NOEXCEPT {
+    // Standard C++11, 5.2.10 Reinterpret cast:
+    // An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue
+    // v of type "pointer to T1" is converted to the type "pointer to cv T2", the result is static_cast<cv
+    // T2*>(static_cast<cv void*>(v)) if both T1 and T2 are standard-layout types (3.9) and the alignment
+    // requirements of T2 are no stricter than those of T1, or if either type is void. Converting a prvalue of type
+    // "pointer to T1" to the type "pointer to T2" (where T1 and T2 are object types and where the alignment
+    // requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer
+    // value.
+    //
+    // Alignments are checked in `type_index_test_ctti_alignment.cpp` test.
+    return *reinterpret_cast<const detail::ctti_data*>(boost::detail::ctti<T>::n());
+}
+
+/// \class ctti_type_index
+/// This class is a wrapper that pretends to work exactly like stl_type_index, but does
+/// not require RTTI support. \b For \b description \b of \b functions \b see type_index_facade.
+///
+/// This class produces slightly longer type names, so consider using stl_type_index
+/// in situations when typeid() is working.
+class ctti_type_index: public type_index_facade<ctti_type_index, detail::ctti_data> {
+    const detail::ctti_data* data_;
+
+    inline std::size_t get_raw_name_length() const BOOST_NOEXCEPT;
+
+public:
+    typedef detail::ctti_data type_info_t;
+
+    inline ctti_type_index() BOOST_NOEXCEPT
+        : data_(&ctti_construct<void>())
+    {}
+
+    inline ctti_type_index(const type_info_t& data) BOOST_NOEXCEPT
+        : data_(&data)
+    {}
+
+    inline const type_info_t&  type_info() const BOOST_NOEXCEPT;
+    inline const char*  raw_name() const BOOST_NOEXCEPT;
+    inline std::string  pretty_name() const;
+    inline std::size_t  hash_code() const BOOST_NOEXCEPT;
+
+    template <class T>
+    inline static ctti_type_index type_id() BOOST_NOEXCEPT;
+
+    template <class T>
+    inline static ctti_type_index type_id_with_cvr() BOOST_NOEXCEPT;
+
+    template <class T>
+    inline static ctti_type_index type_id_runtime(const T& variable) BOOST_NOEXCEPT;
+};
+
+
+inline const ctti_type_index::type_info_t& ctti_type_index::type_info() const BOOST_NOEXCEPT {
+    return *data_;
+}
+
+
+template <class T>
+inline ctti_type_index ctti_type_index::type_id() BOOST_NOEXCEPT {
+    typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<T>::type no_ref_t;
+    typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<no_ref_t>::type no_cvr_t;
+    return ctti_construct<no_cvr_t>();
+}
+
+
+
+template <class T>
+inline ctti_type_index ctti_type_index::type_id_with_cvr() BOOST_NOEXCEPT {
+    return ctti_construct<T>();
+}
+
+
+template <class T>
+inline ctti_type_index ctti_type_index::type_id_runtime(const T& variable) BOOST_NOEXCEPT {
+    return variable.boost_type_index_type_id_runtime_();
+}
+
+
+inline const char* ctti_type_index::raw_name() const BOOST_NOEXCEPT {
+    return reinterpret_cast<const char*>(data_);
+}
+
+inline std::size_t ctti_type_index::get_raw_name_length() const BOOST_NOEXCEPT {
+    return std::strlen(raw_name() + detail::ctti_skip_size_at_end);
+}
+
+
+inline std::string ctti_type_index::pretty_name() const {
+    std::size_t len = get_raw_name_length();
+    while (raw_name()[len - 1] == ' ') --len; // MSVC sometimes adds whitespaces
+    return std::string(raw_name(), len);
+}
+
+
+inline std::size_t ctti_type_index::hash_code() const BOOST_NOEXCEPT {
+    return boost::hash_range(raw_name(), raw_name() + get_raw_name_length());
+}
+
+
+}} // namespace boost::typeindex
+
+#endif // BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP
diff --git a/third_party/boost/boost/type_index/detail/compile_time_type_info.hpp b/third_party/boost/boost/type_index/detail/compile_time_type_info.hpp
new file mode 100644
index 0000000..be4a84c
--- /dev/null
+++ b/third_party/boost/boost/type_index/detail/compile_time_type_info.hpp
@@ -0,0 +1,143 @@
+//
+// Copyright (c) Antony Polukhin, 2012-2014.
+//
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
+#define BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
+
+/// \file compile_time_type_info.hpp
+/// \brief Contains helper macros and implementation details of boost::typeindex::ctti_type_index.
+/// Not intended for inclusion from user's code.
+
+#include <boost/config.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/mpl/bool.hpp>
+#include <algorithm>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+# pragma once
+#endif
+
+/// @cond
+#define BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(begin_skip, end_skip, runtime_skip, runtime_skip_until)   \
+    namespace boost { namespace typeindex { namespace detail {                                                  \
+        BOOST_STATIC_CONSTEXPR std::size_t ctti_skip_size_at_begin  = begin_skip;                               \
+        BOOST_STATIC_CONSTEXPR std::size_t ctti_skip_size_at_end    = end_skip;                                 \
+        BOOST_STATIC_CONSTEXPR bool ctti_skip_more_at_runtime       = runtime_skip;                             \
+        BOOST_STATIC_CONSTEXPR char ctti_skip_until_runtime[]       = runtime_skip_until;                       \
+    }}} /* namespace boost::typeindex::detail */                                                                \
+    /**/
+/// @endcond
+
+#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
+    /* Nothing to document. All the macro docs are moved to <boost/type_index.hpp> */
+#elif defined(BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING)
+
+#   include <boost/preprocessor/facilities/expand.hpp>
+    BOOST_PP_EXPAND( BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING )
+
+#elif defined(_MSC_VER)
+    // sizeof("const char *__cdecl boost::detail::ctti<") - 1, sizeof(">::n(void)") - 1
+    BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(40, 10, false, "")
+#elif defined(__clang__) && defined(__APPLE__)
+    // Someone made __clang_major__ equal to LLVM version rather than compiler version
+    // on APPLE platform.
+    //
+    // Using less efficient solution because there is no good way to detect real version of Clang.
+    // sizeof("static const char *boost::detail::ctti<") - 1, sizeof("]") - 1, true, "???????????>::n() [T = int"
+    BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ")
+#elif defined(__clang__) && (__clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ == 0))
+    // sizeof("static const char *boost::detail::ctti<") - 1, sizeof(">::n()") - 1
+    // note: checked on 3.0
+    BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 6, false, "")
+#elif defined(__clang__) && __clang_major__ == 3 && __clang_minor__ > 0
+    // sizeof("static const char *boost::detail::ctti<") - 1, sizeof("]") - 1, true, "int>::n() [T = int"
+    // note: checked on 3.1, 3.4
+    BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(39, 1, true, "T = ")
+#elif defined(__GNUC__)
+    // sizeof("static const char* boost::detail::ctti<T>::n() [with T = ") - 1, sizeof("]") - 1
+    BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(57, 1, false, "")
+#else
+    // Deafult code for other platforms... Just skip nothing!
+    BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS(0, 0, false, "")
+#endif
+
+#undef BOOST_TYPE_INDEX_REGISTER_CTTI_PARSING_PARAMS
+
+namespace boost { namespace typeindex { namespace detail {
+    template <bool Condition>
+    inline void assert_compile_time_legths() BOOST_NOEXCEPT {
+        BOOST_STATIC_ASSERT_MSG(
+            Condition,
+            "TypeIndex library is misconfigured for your compiler. "
+            "Please define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to correct values. See section "
+            "'RTTI emulation limitations' of the documentation for more information."
+        );
+    }
+
+    template <std::size_t ArrayLength>
+    inline const char* skip_begining_runtime(const char* begin, boost::mpl::false_) BOOST_NOEXCEPT {
+        return begin;
+    }
+
+    template <std::size_t ArrayLength>
+    inline const char* skip_begining_runtime(const char* begin, boost::mpl::true_) BOOST_NOEXCEPT {
+        const char* const it = std::search(
+            begin, begin + ArrayLength,
+            ctti_skip_until_runtime, ctti_skip_until_runtime + sizeof(ctti_skip_until_runtime) - 1
+        );
+        return (it == begin + ArrayLength ? begin : it + sizeof(ctti_skip_until_runtime) - 1);
+    }
+
+    template <std::size_t ArrayLength>
+    inline const char* skip_begining(const char* begin) BOOST_NOEXCEPT {
+        assert_compile_time_legths<(ArrayLength > ctti_skip_size_at_begin + ctti_skip_size_at_end)>();
+        return skip_begining_runtime<ArrayLength - ctti_skip_size_at_begin>(
+            begin + ctti_skip_size_at_begin,
+            boost::mpl::bool_<ctti_skip_more_at_runtime>()
+        );
+    }
+}}} // namespace boost::typeindex::detail
+
+namespace boost { namespace detail {
+
+/// Noncopyable type_info that does not require RTTI.
+/// CTTI == Compile Time Type Info.
+/// This name must be as short as possible, to avoid code bloat
+template <class T>
+struct ctti {
+
+    /// Returns raw name. Must be as short, as possible, to avoid code bloat
+    static const char* n() BOOST_NOEXCEPT {
+    #if defined(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE)
+        return boost::typeindex::detail::skip_begining< sizeof(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE >(BOOST_TYPE_INDEX_FUNCTION_SIGNATURE);
+    #elif defined(__FUNCSIG__)
+        return boost::typeindex::detail::skip_begining< sizeof(__FUNCSIG__) >(__FUNCSIG__);
+    #elif defined(__PRETTY_FUNCTION__) \
+                || defined(__GNUC__) \
+                || (defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)) \
+                || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) \
+                || (defined(__ICC) && (__ICC >= 600)) \
+                || defined(__ghs__) \
+                || defined(__DMC__)
+
+        return boost::typeindex::detail::skip_begining< sizeof(__PRETTY_FUNCTION__) >(__PRETTY_FUNCTION__);
+    #else
+        BOOST_STATIC_ASSERT_MSG(
+            sizeof(T) && false,
+            "TypeIndex library could not detect your compiler. "
+            "Please make the BOOST_TYPE_INDEX_FUNCTION_SIGNATURE macro use "
+            "correct compiler macro for getting the whole function name. "
+            "Define BOOST_TYPE_INDEX_CTTI_USER_DEFINED_PARSING to correct value after that."
+        );
+    #endif
+    }
+};
+
+}} // namespace boost::detail
+
+#endif // BOOST_TYPE_INDEX_DETAIL_COMPILE_TIME_TYPE_INFO_HPP
diff --git a/third_party/boost/boost/type_index/detail/ctti_register_class.hpp b/third_party/boost/boost/type_index/detail/ctti_register_class.hpp
new file mode 100644
index 0000000..fa8598e
--- /dev/null
+++ b/third_party/boost/boost/type_index/detail/ctti_register_class.hpp
@@ -0,0 +1,39 @@
+//
+// Copyright (c) Antony Polukhin, 2013-2014.
+//
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP
+#define BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP
+
+/// \file ctti_register_class.hpp
+/// \brief Contains BOOST_TYPE_INDEX_REGISTER_CLASS macro implementation that uses boost::typeindex::ctti_type_index.
+/// Not intended for inclusion from user's code.
+
+#include <boost/type_index/ctti_type_index.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+# pragma once
+#endif
+
+namespace boost { namespace typeindex { namespace detail {
+
+template <class T>
+inline const ctti_data& ctti_construct_typeid_ref(const T*) BOOST_NOEXCEPT {
+    return ctti_construct<T>();
+}
+
+}}} // namespace boost::typeindex::detail
+
+/// @cond
+#define BOOST_TYPE_INDEX_REGISTER_CLASS                                                                             \
+    virtual const boost::typeindex::detail::ctti_data& boost_type_index_type_id_runtime_() const BOOST_NOEXCEPT {   \
+        return boost::typeindex::detail::ctti_construct_typeid_ref(this);                                           \
+    }                                                                                                               \
+/**/
+/// @endcond
+
+#endif // BOOST_TYPE_INDEX_CTTI_REGISTER_CLASS_HPP
diff --git a/third_party/boost/boost/type_index/stl_type_index.hpp b/third_party/boost/boost/type_index/stl_type_index.hpp
new file mode 100644
index 0000000..3e1f658
--- /dev/null
+++ b/third_party/boost/boost/type_index/stl_type_index.hpp
@@ -0,0 +1,272 @@
+//
+// Copyright (c) Antony Polukhin, 2013-2014.
+//
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
+#define BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
+
+/// \file stl_type_index.hpp
+/// \brief Contains boost::typeindex::stl_type_index class.
+///
+/// boost::typeindex::stl_type_index class can be used as a drop-in replacement
+/// for std::type_index.
+///
+/// It is used in situations when RTTI is enabled or typeid() method is available.
+/// When typeid() is disabled or BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro
+/// is defined boost::typeindex::ctti is usually used instead of boost::typeindex::stl_type_index.
+
+#include <boost/type_index/type_index_facade.hpp>
+
+// MSVC is capable of calling typeid(T) even when RTTI is off
+#if defined(BOOST_NO_RTTI) && !defined(BOOST_MSVC)
+#error "File boost/type_index/stl_type_index.ipp is not usable when typeid() is not available."
+#endif
+
+#include <typeinfo>
+#include <cstring>                                  // std::strcmp, std::strlen, std::strstr
+#include <stdexcept>
+#include <boost/static_assert.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/core/demangle.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/is_volatile.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/or.hpp>
+
+#if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
+        || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
+#   include <boost/type_traits/is_signed.hpp>
+#   include <boost/type_traits/make_signed.hpp>
+#   include <boost/mpl/identity.hpp>
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+# pragma once
+#endif
+
+namespace boost { namespace typeindex {
+
+/// \class stl_type_index
+/// This class is a wrapper around std::type_info, that workarounds issues and provides
+/// much more rich interface. \b For \b description \b of \b functions \b see type_index_facade.
+///
+/// This class requires typeid() to work. For cases when RTTI is disabled see ctti_type_index.
+class stl_type_index
+    : public type_index_facade<
+        stl_type_index,
+        #ifdef BOOST_NO_STD_TYPEINFO
+            type_info
+        #else
+            std::type_info
+        #endif
+    >
+{
+public:
+#ifdef BOOST_NO_STD_TYPEINFO
+    typedef type_info type_info_t;
+#else
+    typedef std::type_info type_info_t;
+#endif
+
+private:
+    const type_info_t* data_;
+
+public:
+    inline stl_type_index() BOOST_NOEXCEPT
+        : data_(&typeid(void))
+    {}
+
+    inline stl_type_index(const type_info_t& data) BOOST_NOEXCEPT
+        : data_(&data)
+    {}
+
+    inline const type_info_t&  type_info() const BOOST_NOEXCEPT;
+
+    inline const char*  raw_name() const BOOST_NOEXCEPT;
+    inline const char*  name() const BOOST_NOEXCEPT;
+    inline std::string  pretty_name() const;
+
+    inline std::size_t  hash_code() const BOOST_NOEXCEPT;
+    inline bool         equal(const stl_type_index& rhs) const BOOST_NOEXCEPT;
+    inline bool         before(const stl_type_index& rhs) const BOOST_NOEXCEPT;
+
+    template <class T>
+    inline static stl_type_index type_id() BOOST_NOEXCEPT;
+
+    template <class T>
+    inline static stl_type_index type_id_with_cvr() BOOST_NOEXCEPT;
+
+    template <class T>
+    inline static stl_type_index type_id_runtime(const T& value) BOOST_NOEXCEPT;
+};
+
+inline const stl_type_index::type_info_t& stl_type_index::type_info() const BOOST_NOEXCEPT {
+    return *data_;
+}
+
+
+inline const char* stl_type_index::raw_name() const BOOST_NOEXCEPT {
+#ifdef _MSC_VER
+    return data_->raw_name();
+#else
+    return data_->name();
+#endif
+}
+
+inline const char* stl_type_index::name() const BOOST_NOEXCEPT {
+    return data_->name();
+}
+
+inline std::string stl_type_index::pretty_name() const {
+    static const char cvr_saver_name[] = "boost::typeindex::detail::cvr_saver<";
+    static BOOST_CONSTEXPR_OR_CONST std::string::size_type cvr_saver_name_len = sizeof(cvr_saver_name) - 1;
+
+    // In case of MSVC demangle() is a no-op, and name() already returns demangled name.
+    // In case of GCC and Clang (on non-Windows systems) name() returns mangled name and demangle() undecorates it.
+    const boost::core::scoped_demangled_name demangled_name(data_->name());
+
+    const char* begin = demangled_name.get();
+    if (!begin) {
+        boost::throw_exception(std::runtime_error("Type name demangling failed"));
+    }
+
+    const std::string::size_type len = std::strlen(begin);
+    const char* end = begin + len;
+
+    if (len > cvr_saver_name_len) {
+        const char* b = std::strstr(begin, cvr_saver_name);
+        if (b) {
+            b += cvr_saver_name_len;
+
+            // Trim leading spaces
+            while (*b == ' ') {         // the string is zero terminated, we won't exceed the buffer size
+                ++ b;
+            }
+
+            // Skip the closing angle bracket
+            const char* e = end - 1;
+            while (e > b && *e != '>') {
+                -- e;
+            }
+
+            // Trim trailing spaces
+            while (e > b && *(e - 1) == ' ') {
+                -- e;
+            }
+
+            if (b < e) {
+                // Parsing seems to have succeeded, the type name is not empty
+                begin = b;
+                end = e;
+            }
+        }
+    }
+
+    return std::string(begin, end);
+}
+
+
+inline std::size_t stl_type_index::hash_code() const BOOST_NOEXCEPT {
+#if _MSC_VER > 1600 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5 && defined(__GXX_EXPERIMENTAL_CXX0X__))
+    return data_->hash_code();
+#else
+    return boost::hash_range(raw_name(), raw_name() + std::strlen(raw_name()));
+#endif
+}
+
+
+/// @cond
+
+// for this compiler at least, cross-shared-library type_info
+// comparisons don't work, so we are using typeid(x).name() instead.
+# if (defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5))) \
+    || defined(_AIX) \
+    || (defined(__sgi) && defined(__host_mips)) \
+    || (defined(__hpux) && defined(__HP_aCC)) \
+    || (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
+#  define BOOST_CLASSINFO_COMPARE_BY_NAMES
+# endif
+
+/// @endcond
+
+inline bool stl_type_index::equal(const stl_type_index& rhs) const BOOST_NOEXCEPT {
+#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
+    return raw_name() == rhs.raw_name() || !std::strcmp(raw_name(), rhs.raw_name());
+#else
+    return *data_ == *rhs.data_;
+#endif
+}
+
+inline bool stl_type_index::before(const stl_type_index& rhs) const BOOST_NOEXCEPT {
+#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
+    return raw_name() != rhs.raw_name() && std::strcmp(raw_name(), rhs.raw_name()) < 0;
+#else
+    return !!data_->before(*rhs.data_);
+#endif
+}
+
+#ifdef BOOST_CLASSINFO_COMPARE_BY_NAMES
+#undef BOOST_CLASSINFO_COMPARE_BY_NAMES
+#endif
+
+
+
+template <class T>
+inline stl_type_index stl_type_index::type_id() BOOST_NOEXCEPT {
+    typedef BOOST_DEDUCED_TYPENAME boost::remove_reference<T>::type no_ref_t;
+    typedef BOOST_DEDUCED_TYPENAME boost::remove_cv<no_ref_t>::type no_cvr_prefinal_t;
+
+    #  if (defined(__EDG_VERSION__) && __EDG_VERSION__ < 245) \
+        || (defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 744)
+
+        // Old EDG-based compilers seem to mistakenly distinguish 'integral' from 'signed integral'
+        // in typeid() expressions. Full template specialization for 'integral' fixes that issue:
+        typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
+            boost::is_signed<no_cvr_prefinal_t>,
+            boost::make_signed<no_cvr_prefinal_t>,
+            boost::mpl::identity<no_cvr_prefinal_t>
+        >::type no_cvr_prefinal_lazy_t;
+
+        typedef BOOST_DEDUCED_TYPENAME no_cvr_prefinal_t::type no_cvr_t;
+    #else
+        typedef no_cvr_prefinal_t no_cvr_t;
+    #endif
+
+    return typeid(no_cvr_t);
+}
+
+namespace detail {
+    template <class T> class cvr_saver{};
+}
+
+template <class T>
+inline stl_type_index stl_type_index::type_id_with_cvr() BOOST_NOEXCEPT {
+    typedef BOOST_DEDUCED_TYPENAME boost::mpl::if_<
+        boost::mpl::or_<boost::is_reference<T>, boost::is_const<T>, boost::is_volatile<T> >,
+        detail::cvr_saver<T>,
+        T
+    >::type type;
+
+    return typeid(type);
+}
+
+
+template <class T>
+inline stl_type_index stl_type_index::type_id_runtime(const T& value) BOOST_NOEXCEPT {
+#ifdef BOOST_NO_RTTI
+    return value.boost_type_index_type_id_runtime_();
+#else
+    return typeid(value);
+#endif
+}
+
+}} // namespace boost::typeindex
+
+#endif // BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
diff --git a/third_party/boost/boost/type_index/type_index_facade.hpp b/third_party/boost/boost/type_index/type_index_facade.hpp
new file mode 100644
index 0000000..4c8481a
--- /dev/null
+++ b/third_party/boost/boost/type_index/type_index_facade.hpp
@@ -0,0 +1,299 @@
+//
+// Copyright (c) Antony Polukhin, 2013-2015.
+//
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
+#define BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
+
+#include <boost/config.hpp>
+#include <string>
+#include <cstring>
+
+#if !defined(BOOST_NO_IOSTREAM)
+#if !defined(BOOST_NO_IOSFWD)
+#include <iosfwd>               // for std::basic_ostream
+#else
+#include <ostream>
+#endif
+#endif
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+# pragma once
+#endif
+
+// Forward declaration from #include <boost/functional/hash_fwd.hpp>
+namespace boost {
+    template <class It> std::size_t hash_range(It, It);
+}
+
+namespace boost { namespace typeindex {
+
+/// \class type_index_facade
+///
+/// This class takes care about the comparison operators, hash functions and
+/// ostream operators. Use this class as a public base class for defining new
+/// type_info-conforming classes.
+///
+/// \b Example:
+/// \code
+/// class stl_type_index: public type_index_facade<stl_type_index, std::type_info>
+/// {
+/// public:
+///     typedef std::type_info type_info_t;
+/// private:
+///     const type_info_t* data_;
+///
+/// public:
+///     stl_type_index(const type_info_t& data) noexcept
+///         : data_(&data)
+///     {}
+/// // ...
+/// };
+/// \endcode
+///
+/// \tparam Derived Class derived from type_index_facade.
+/// \tparam TypeInfo Class that will be used as a base type_info class.
+/// \note Take a look at the protected methods. They are \b not \b defined in type_index_facade.
+/// Protected member functions raw_name() \b must be defined in Derived class. All the other
+/// methods are mandatory.
+/// \see 'Making a custom type_index' section for more information about
+/// creating your own type_index using type_index_facade.
+template <class Derived, class TypeInfo>
+class type_index_facade {
+private:
+    /// @cond
+    const Derived & derived() const BOOST_NOEXCEPT {
+      return *static_cast<Derived const*>(this);
+    }
+    /// @endcond
+public:
+    typedef TypeInfo                                type_info_t;
+
+    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
+    /// \return Name of a type. By default returns Derived::raw_name().
+    inline const char* name() const BOOST_NOEXCEPT {
+        return derived().raw_name();
+    }
+
+    /// \b Override: This function \b may be redefined in Derived class. Overrides may throw.
+    /// \return Human readable type name. By default returns Derived::name().
+    inline std::string pretty_name() const {
+        return derived().name();
+    }
+
+    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
+    /// \return True if two types are equal. By default compares types by raw_name().
+    inline bool equal(const Derived& rhs) const BOOST_NOEXCEPT {
+        const char* const left = derived().raw_name();
+        const char* const right = rhs.raw_name();
+        return left == right || !std::strcmp(left, right);
+    }
+
+    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
+    /// \return True if rhs is greater than this. By default compares types by raw_name().
+    inline bool before(const Derived& rhs) const BOOST_NOEXCEPT {
+        const char* const left = derived().raw_name();
+        const char* const right = rhs.raw_name();
+        return left != right && std::strcmp(left, right) < 0;
+    }
+
+    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
+    /// \return Hash code of a type. By default hashes types by raw_name().
+    /// \note <boost/functional/hash.hpp> has to be included if this function is used.
+    inline std::size_t hash_code() const BOOST_NOEXCEPT {
+        const char* const name_raw = derived().raw_name();
+        return boost::hash_range(name_raw, name_raw + std::strlen(name_raw));
+    }
+
+#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
+protected:
+    /// \b Override: This function \b must be redefined in Derived class. Overrides \b must not throw.
+    /// \return Pointer to unredable/raw type name.
+    inline const char* raw_name() const BOOST_NOEXCEPT;
+
+    /// \b Override: This function \b may be redefined in Derived class. Overrides \b must not throw.
+    /// \return Const reference to underlying low level type_info_t.
+    inline const type_info_t& type_info() const BOOST_NOEXCEPT;
+
+    /// This is a factory method that is used to create instances of Derived classes.
+    /// boost::typeindex::type_id() will call this method, if Derived has same type as boost::typeindex::type_index.
+    ///
+    /// \b Override: This function \b may be redefined and made public in Derived class. Overrides \b must not throw.
+    /// Overrides \b must remove const, volatile && and & modifiers from T.
+    /// \tparam T Type for which type_index must be created.
+    /// \return type_index for type T.
+    template <class T>
+    static Derived type_id() BOOST_NOEXCEPT;
+
+    /// This is a factory method that is used to create instances of Derived classes.
+    /// boost::typeindex::type_id_with_cvr() will call this method, if Derived has same type as boost::typeindex::type_index.
+    ///
+    /// \b Override: This function \b may be redefined and made public in Derived class. Overrides \b must not throw.
+    /// Overrides \b must \b not remove const, volatile && and & modifiers from T.
+    /// \tparam T Type for which type_index must be created.
+    /// \return type_index for type T.
+    template <class T>
+    static Derived type_id_with_cvr() BOOST_NOEXCEPT;
+
+    /// This is a factory method that is used to create instances of Derived classes.
+    /// boost::typeindex::type_id_runtime(const T&) will call this method, if Derived has same type as boost::typeindex::type_index.
+    ///
+    /// \b Override: This function \b may be redefined and made public in Derived class.
+    /// \param variable Variable which runtime type will be stored in type_index.
+    /// \return type_index with runtime type of variable.
+    template <class T>
+    static Derived type_id_runtime(const T& variable) BOOST_NOEXCEPT;
+
+#endif
+
+};
+
+/// @cond
+template <class Derived, class TypeInfo>
+inline bool operator == (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
+    return static_cast<Derived const&>(lhs).equal(static_cast<Derived const&>(rhs));
+}
+
+template <class Derived, class TypeInfo>
+inline bool operator < (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
+    return static_cast<Derived const&>(lhs).before(static_cast<Derived const&>(rhs));;
+}
+
+
+
+template <class Derived, class TypeInfo>
+inline bool operator > (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
+    return rhs < lhs;
+}
+
+template <class Derived, class TypeInfo>
+inline bool operator <= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
+    return !(lhs > rhs);
+}
+
+template <class Derived, class TypeInfo>
+inline bool operator >= (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
+    return !(lhs < rhs);
+}
+
+template <class Derived, class TypeInfo>
+inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
+    return !(lhs == rhs);
+}
+
+// ######################### COMPARISONS with Derived ############################ //
+template <class Derived, class TypeInfo>
+inline bool operator == (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
+    return Derived(lhs) == rhs;
+}
+
+template <class Derived, class TypeInfo>
+inline bool operator < (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
+    return Derived(lhs) < rhs;
+}
+
+template <class Derived, class TypeInfo>
+inline bool operator > (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
+    return rhs < Derived(lhs);
+}
+
+template <class Derived, class TypeInfo>
+inline bool operator <= (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
+    return !(Derived(lhs) > rhs);
+}
+
+template <class Derived, class TypeInfo>
+inline bool operator >= (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
+    return !(Derived(lhs) < rhs);
+}
+
+template <class Derived, class TypeInfo>
+inline bool operator != (const TypeInfo& lhs, const type_index_facade<Derived, TypeInfo>& rhs) BOOST_NOEXCEPT {
+    return !(Derived(lhs) == rhs);
+}
+
+
+template <class Derived, class TypeInfo>
+inline bool operator == (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
+    return lhs == Derived(rhs);
+}
+
+template <class Derived, class TypeInfo>
+inline bool operator < (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
+    return lhs < Derived(rhs);
+}
+
+template <class Derived, class TypeInfo>
+inline bool operator > (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
+    return Derived(rhs) < lhs;
+}
+
+template <class Derived, class TypeInfo>
+inline bool operator <= (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
+    return !(lhs > Derived(rhs));
+}
+
+template <class Derived, class TypeInfo>
+inline bool operator >= (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
+    return !(lhs < Derived(rhs));
+}
+
+template <class Derived, class TypeInfo>
+inline bool operator != (const type_index_facade<Derived, TypeInfo>& lhs, const TypeInfo& rhs) BOOST_NOEXCEPT {
+    return !(lhs == Derived(rhs));
+}
+
+// ######################### COMPARISONS with Derived END ############################ //
+
+/// @endcond
+
+#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
+
+/// noexcept comparison operators for type_index_facade classes.
+bool operator ==, !=, <, ... (const type_index_facade& lhs, const type_index_facade& rhs) noexcept;
+
+/// noexcept comparison operators for type_index_facade and it's TypeInfo classes.
+bool operator ==, !=, <, ... (const type_index_facade& lhs, const TypeInfo& rhs) noexcept;
+
+/// noexcept comparison operators for type_index_facade's TypeInfo and type_index_facade classes.
+bool operator ==, !=, <, ... (const TypeInfo& lhs, const type_index_facade& rhs) noexcept;
+
+#endif
+
+#ifndef BOOST_NO_IOSTREAM
+#ifdef BOOST_NO_TEMPLATED_IOSTREAMS
+/// @cond
+/// Ostream operator that will output demangled name
+template <class Derived, class TypeInfo>
+inline std::ostream& operator<<(std::ostream& ostr, const type_index_facade<Derived, TypeInfo>& ind) {
+    ostr << static_cast<Derived const&>(ind).pretty_name();
+    return ostr;
+}
+/// @endcond
+#else
+/// Ostream operator that will output demangled name.
+template <class CharT, class TriatT, class Derived, class TypeInfo>
+inline std::basic_ostream<CharT, TriatT>& operator<<(
+    std::basic_ostream<CharT, TriatT>& ostr,
+    const type_index_facade<Derived, TypeInfo>& ind)
+{
+    ostr << static_cast<Derived const&>(ind).pretty_name();
+    return ostr;
+}
+#endif // BOOST_NO_TEMPLATED_IOSTREAMS
+#endif // BOOST_NO_IOSTREAM
+
+/// This free function is used by Boost's unordered containers.
+/// \note <boost/functional/hash.hpp> has to be included if this function is used.
+template <class Derived, class TypeInfo>
+inline std::size_t hash_value(const type_index_facade<Derived, TypeInfo>& lhs) BOOST_NOEXCEPT {
+    return static_cast<Derived const&>(lhs).hash_code();
+}
+
+}} // namespace boost::typeindex
+
+#endif // BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
diff --git a/third_party/boost/boost/type_traits/add_const.hpp b/third_party/boost/boost/type_traits/add_const.hpp
new file mode 100644
index 0000000..5b0b455
--- /dev/null
+++ b/third_party/boost/boost/type_traits/add_const.hpp
@@ -0,0 +1,46 @@
+
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
+//  Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_ADD_CONST_HPP_INCLUDED
+#define BOOST_TT_ADD_CONST_HPP_INCLUDED
+
+#include <boost/type_traits/detail/config.hpp>
+
+namespace boost {
+
+// * convert a type T to const type - add_const<T>
+// this is not required since the result is always
+// the same as "T const", but it does suppress warnings
+// from some compilers:
+
+#if defined(BOOST_MSVC)
+// This bogus warning will appear when add_const is applied to a
+// const volatile reference because we can't detect const volatile
+// references with MSVC6.
+#   pragma warning(push)
+#   pragma warning(disable:4181) // warning C4181: qualifier applied to reference type ignored
+#endif
+
+   template <class T> struct add_const
+   {
+      typedef T const type;
+   };
+
+#if defined(BOOST_MSVC)
+#   pragma warning(pop)
+#endif
+
+   template <class T> struct add_const<T&>
+   {
+      typedef T& type;
+   };
+
+} // namespace boost
+
+#endif // BOOST_TT_ADD_CONST_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/add_lvalue_reference.hpp b/third_party/boost/boost/type_traits/add_lvalue_reference.hpp
new file mode 100644
index 0000000..5539c94
--- /dev/null
+++ b/third_party/boost/boost/type_traits/add_lvalue_reference.hpp
@@ -0,0 +1,27 @@
+//  Copyright 2010 John Maddock
+
+//  Distributed under the Boost Software License, Version 1.0.
+//  See http://www.boost.org/LICENSE_1_0.txt
+
+#ifndef BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP
+#define BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP
+
+#include <boost/type_traits/add_reference.hpp>
+
+namespace boost{
+
+template <class T> struct add_lvalue_reference
+{
+   typedef typename boost::add_reference<T>::type type;
+};
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+template <class T> struct add_lvalue_reference<T&&>
+{
+   typedef T& type;
+};
+#endif
+
+}
+
+#endif  // BOOST_TYPE_TRAITS_EXT_ADD_LVALUE_REFERENCE__HPP
diff --git a/third_party/boost/boost/type_traits/add_pointer.hpp b/third_party/boost/boost/type_traits/add_pointer.hpp
new file mode 100644
index 0000000..745f63a
--- /dev/null
+++ b/third_party/boost/boost/type_traits/add_pointer.hpp
@@ -0,0 +1,61 @@
+
+// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_ADD_POINTER_HPP_INCLUDED
+#define BOOST_TT_ADD_POINTER_HPP_INCLUDED
+
+#include <boost/type_traits/remove_reference.hpp>
+
+namespace boost {
+
+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x5A0)
+//
+// For some reason this implementation stops Borlands compiler
+// from dropping cv-qualifiers, it still fails with references
+// to arrays for some reason though (shrug...) (JM 20021104)
+//
+template <typename T>
+struct add_pointer
+{
+    typedef T* type;
+};
+template <typename T>
+struct add_pointer<T&>
+{
+    typedef T* type;
+};
+template <typename T>
+struct add_pointer<T&const>
+{
+    typedef T* type;
+};
+template <typename T>
+struct add_pointer<T&volatile>
+{
+    typedef T* type;
+};
+template <typename T>
+struct add_pointer<T&const volatile>
+{
+    typedef T* type;
+};
+
+#else
+
+template <typename T>
+struct add_pointer
+{
+    typedef typename remove_reference<T>::type no_ref_type;
+    typedef no_ref_type* type;
+};
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_ADD_POINTER_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/add_reference.hpp b/third_party/boost/boost/type_traits/add_reference.hpp
new file mode 100644
index 0000000..526f259
--- /dev/null
+++ b/third_party/boost/boost/type_traits/add_reference.hpp
@@ -0,0 +1,59 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_ADD_REFERENCE_HPP_INCLUDED
+#define BOOST_TT_ADD_REFERENCE_HPP_INCLUDED
+
+#include <boost/detail/workaround.hpp>
+#include <boost/config.hpp>
+
+namespace boost {
+
+namespace detail {
+
+//
+// We can't filter out rvalue_references at the same level as
+// references or we get ambiguities from msvc:
+//
+
+template <typename T>
+struct add_reference_impl
+{
+    typedef T& type;
+};
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+template <typename T>
+struct add_reference_impl<T&&>
+{
+    typedef T&& type;
+};
+#endif
+
+} // namespace detail
+
+template <class T> struct add_reference
+{
+   typedef typename boost::detail::add_reference_impl<T>::type type;
+};
+template <class T> struct add_reference<T&>
+{
+   typedef T& type;
+};
+
+// these full specialisations are always required:
+template <> struct add_reference<void> { typedef void type; };
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template <> struct add_reference<const void> { typedef void type; };
+template <> struct add_reference<const volatile void> { typedef void type; };
+template <> struct add_reference<volatile void> { typedef void type; };
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_ADD_REFERENCE_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/add_rvalue_reference.hpp b/third_party/boost/boost/type_traits/add_rvalue_reference.hpp
new file mode 100644
index 0000000..0ec0ff2
--- /dev/null
+++ b/third_party/boost/boost/type_traits/add_rvalue_reference.hpp
@@ -0,0 +1,63 @@
+//  add_rvalue_reference.hpp  ---------------------------------------------------------//
+
+//  Copyright 2010 Vicente J. Botet Escriba
+
+//  Distributed under the Boost Software License, Version 1.0.
+//  See http://www.boost.org/LICENSE_1_0.txt
+
+#ifndef BOOST_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP
+#define BOOST_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP
+
+#include <boost/config.hpp>
+
+//----------------------------------------------------------------------------//
+
+#include <boost/type_traits/is_void.hpp>
+#include <boost/type_traits/is_reference.hpp>
+
+//----------------------------------------------------------------------------//
+//                                                                            //
+//                           C++03 implementation of                          //
+//             20.9.7.2 Reference modifications [meta.trans.ref]              //
+//                          Written by Vicente J. Botet Escriba               //
+//                                                                            //
+// If T names an object or function type then the member typedef type
+// shall name T&&; otherwise, type shall name T. [ Note: This rule reflects
+// the semantics of reference collapsing. For example, when a type T names
+// a type T1&, the type add_rvalue_reference<T>::type is not an rvalue
+// reference. -end note ]
+//----------------------------------------------------------------------------//
+
+namespace boost {
+
+namespace type_traits_detail {
+
+    template <typename T, bool b>
+    struct add_rvalue_reference_helper
+    { typedef T   type; };
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+    template <typename T>
+    struct add_rvalue_reference_helper<T, true>
+    {
+        typedef T&&   type;
+    };
+#endif
+
+    template <typename T>
+    struct add_rvalue_reference_imp
+    {
+       typedef typename boost::type_traits_detail::add_rvalue_reference_helper
+                  <T, (is_void<T>::value == false && is_reference<T>::value == false) >::type type;
+    };
+
+}
+
+template <class T> struct add_rvalue_reference
+{
+   typedef typename boost::type_traits_detail::add_rvalue_reference_imp<T>::type type;
+};
+
+}  // namespace boost
+
+#endif  // BOOST_TYPE_TRAITS_EXT_ADD_RVALUE_REFERENCE__HPP
diff --git a/third_party/boost/boost/type_traits/add_volatile.hpp b/third_party/boost/boost/type_traits/add_volatile.hpp
new file mode 100644
index 0000000..cc43b0d
--- /dev/null
+++ b/third_party/boost/boost/type_traits/add_volatile.hpp
@@ -0,0 +1,40 @@
+
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
+//  Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_ADD_VOLATILE_HPP_INCLUDED
+#define BOOST_TT_ADD_VOLATILE_HPP_INCLUDED
+
+#include <boost/config.hpp>
+
+namespace boost {
+
+// * convert a type T to volatile type - add_volatile<T>
+// this is not required since the result is always
+// the same as "T volatile", but it does suppress warnings
+// from some compilers:
+
+#if defined(BOOST_MSVC)
+// This bogus warning will appear when add_volatile is applied to a
+// const volatile reference because we can't detect const volatile
+// references with MSVC6.
+#   pragma warning(push)
+#   pragma warning(disable:4181) // warning C4181: qualifier applied to reference type ignored
+#endif
+
+template <class T> struct add_volatile{ typedef T volatile type; };
+
+#if defined(BOOST_MSVC)
+#   pragma warning(pop)
+#endif
+
+template <class T> struct add_volatile<T&>{ typedef T& type; };
+
+} // namespace boost
+
+#endif // BOOST_TT_ADD_VOLATILE_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/aligned_storage.hpp b/third_party/boost/boost/type_traits/aligned_storage.hpp
new file mode 100644
index 0000000..13a5c9e
--- /dev/null
+++ b/third_party/boost/boost/type_traits/aligned_storage.hpp
@@ -0,0 +1,138 @@
+//-----------------------------------------------------------------------------
+// boost aligned_storage.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2002-2003
+// Eric Friedman, Itay Maman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_TT_ALIGNED_STORAGE_HPP
+#define BOOST_TT_ALIGNED_STORAGE_HPP
+
+#include <cstddef> // for std::size_t
+
+#include "boost/config.hpp"
+#include "boost/detail/workaround.hpp"
+#include "boost/type_traits/alignment_of.hpp"
+#include "boost/type_traits/type_with_alignment.hpp"
+#include "boost/type_traits/is_pod.hpp"
+#include "boost/type_traits/conditional.hpp"
+
+namespace boost {
+
+namespace detail { namespace aligned_storage {
+
+BOOST_STATIC_CONSTANT(
+      std::size_t
+    , alignment_of_max_align = ::boost::alignment_of<boost::detail::max_align>::value
+    );
+
+//
+// To be TR1 conforming this must be a POD type:
+//
+template <
+      std::size_t size_
+    , std::size_t alignment_
+>
+struct aligned_storage_imp
+{
+    union data_t
+    {
+        char buf[size_];
+
+        typename ::boost::type_with_alignment<alignment_>::type align_;
+    } data_;
+    void* address() const { return const_cast<aligned_storage_imp*>(this); }
+};
+template <std::size_t size>
+struct aligned_storage_imp<size, std::size_t(-1)>
+{
+   union data_t
+   {
+      char buf[size];
+      ::boost::detail::max_align align_;
+   } data_;
+   void* address() const { return const_cast<aligned_storage_imp*>(this); }
+};
+
+template< std::size_t alignment_ >
+struct aligned_storage_imp<0u,alignment_>
+{
+    /* intentionally empty */
+    void* address() const { return 0; }
+};
+
+}} // namespace detail::aligned_storage
+
+template <
+      std::size_t size_
+    , std::size_t alignment_ = std::size_t(-1)
+>
+class aligned_storage :
+#ifndef __BORLANDC__
+   private
+#else
+   public
+#endif
+   ::boost::detail::aligned_storage::aligned_storage_imp<size_, alignment_>
+{
+
+public: // constants
+
+    typedef ::boost::detail::aligned_storage::aligned_storage_imp<size_, alignment_> type;
+
+    BOOST_STATIC_CONSTANT(
+          std::size_t
+        , size = size_
+        );
+    BOOST_STATIC_CONSTANT(
+          std::size_t
+        , alignment = (
+              alignment_ == std::size_t(-1)
+            ? ::boost::detail::aligned_storage::alignment_of_max_align
+            : alignment_
+            )
+        );
+
+private: // noncopyable
+
+    aligned_storage(const aligned_storage&);
+    aligned_storage& operator=(const aligned_storage&);
+
+public: // structors
+
+    aligned_storage()
+    {
+    }
+
+    ~aligned_storage()
+    {
+    }
+
+public: // accessors
+
+    void* address()
+    {
+        return static_cast<type*>(this)->address();
+    }
+
+    const void* address() const
+    {
+        return static_cast<const type*>(this)->address();
+    }
+};
+
+//
+// Make sure that is_pod recognises aligned_storage<>::type
+// as a POD (Note that aligned_storage<> itself is not a POD):
+//
+template <std::size_t size_, std::size_t alignment_>
+struct is_pod< ::boost::detail::aligned_storage::aligned_storage_imp<size_, alignment_> > : public true_type{};
+
+} // namespace boost
+
+#endif // BOOST_ALIGNED_STORAGE_HPP
diff --git a/third_party/boost/boost/type_traits/alignment_of.hpp b/third_party/boost/boost/type_traits/alignment_of.hpp
new file mode 100644
index 0000000..9fe9b3b
--- /dev/null
+++ b/third_party/boost/boost/type_traits/alignment_of.hpp
@@ -0,0 +1,118 @@
+
+//  (C) Copyright John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_ALIGNMENT_OF_HPP_INCLUDED
+#define BOOST_TT_ALIGNMENT_OF_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <cstddef>
+
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+
+#ifdef BOOST_MSVC
+#   pragma warning(push)
+#   pragma warning(disable: 4121 4512) // alignment is sensitive to packing
+#endif
+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x600)
+#pragma option push -Vx- -Ve-
+#endif
+
+namespace boost {
+
+template <typename T> struct alignment_of;
+
+// get the alignment of some arbitrary type:
+namespace detail {
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4324) // structure was padded due to __declspec(align())
+#endif
+template <typename T>
+struct alignment_of_hack
+{
+    char c;
+    T t;
+    alignment_of_hack();
+};
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+template <unsigned A, unsigned S>
+struct alignment_logic
+{
+    BOOST_STATIC_CONSTANT(std::size_t, value = A < S ? A : S);
+};
+
+
+template< typename T >
+struct alignment_of_impl
+{
+#if defined(BOOST_MSVC) && (BOOST_MSVC >= 1400)
+    //
+    // With MSVC both the native __alignof operator
+    // and our own logic gets things wrong from time to time :-(
+    // Using a combination of the two seems to make the most of a bad job:
+    //
+    BOOST_STATIC_CONSTANT(std::size_t, value =
+        (::boost::detail::alignment_logic<
+            sizeof(::boost::detail::alignment_of_hack<T>) - sizeof(T),
+            __alignof(T)
+        >::value));
+#elif !defined(BOOST_ALIGNMENT_OF)
+    BOOST_STATIC_CONSTANT(std::size_t, value =
+        (::boost::detail::alignment_logic<
+            sizeof(::boost::detail::alignment_of_hack<T>) - sizeof(T),
+            sizeof(T)
+        >::value));
+#else
+   //
+   // We put this here, rather than in the definition of
+   // alignment_of below, because MSVC's __alignof doesn't
+   // always work in that context for some unexplained reason.
+   // (See type_with_alignment tests for test cases).
+   //
+   BOOST_STATIC_CONSTANT(std::size_t, value = BOOST_ALIGNMENT_OF(T));
+#endif
+};
+
+} // namespace detail
+
+template <class T> struct alignment_of : public integral_constant<std::size_t, ::boost::detail::alignment_of_impl<T>::value>{};
+
+// references have to be treated specially, assume
+// that a reference is just a special pointer:
+template <typename T> struct alignment_of<T&> : public alignment_of<T*>{};
+
+#ifdef __BORLANDC__
+// long double gives an incorrect value of 10 (!)
+// unless we do this...
+struct long_double_wrapper{ long double ld; };
+template<> struct alignment_of<long double> : public alignment_of<long_double_wrapper>{};
+#endif
+
+// void has to be treated specially:
+template<> struct alignment_of<void> : integral_constant<std::size_t, 0>{};
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template<> struct alignment_of<void const> : integral_constant<std::size_t, 0>{};
+template<> struct alignment_of<void const volatile> : integral_constant<std::size_t, 0>{};
+template<> struct alignment_of<void volatile> : integral_constant<std::size_t, 0>{};
+#endif
+
+} // namespace boost
+
+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x600)
+#pragma option pop
+#endif
+#ifdef BOOST_MSVC
+#   pragma warning(pop)
+#endif
+
+#endif // BOOST_TT_ALIGNMENT_OF_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/composite_traits.hpp b/third_party/boost/boost/type_traits/composite_traits.hpp
new file mode 100644
index 0000000..cc394a4
--- /dev/null
+++ b/third_party/boost/boost/type_traits/composite_traits.hpp
@@ -0,0 +1,24 @@
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
+//  Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+//
+//  defines traits classes for composite types:
+//  is_array, is_pointer, is_reference, is_member_pointer, is_enum, is_union.
+//
+
+#ifndef BOOST_TT_COMPOSITE_TRAITS_HPP_INCLUDED
+#define BOOST_TT_COMPOSITE_TRAITS_HPP_INCLUDED
+
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/is_enum.hpp>
+#include <boost/type_traits/is_member_pointer.hpp>
+#include <boost/type_traits/is_member_function_pointer.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/is_union.hpp>
+
+#endif // BOOST_TT_COMPOSITE_TRAITS_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/conditional.hpp b/third_party/boost/boost/type_traits/conditional.hpp
new file mode 100644
index 0000000..675d9d5
--- /dev/null
+++ b/third_party/boost/boost/type_traits/conditional.hpp
@@ -0,0 +1,20 @@
+//  (C) Copyright John Maddock 2010.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+
+#ifndef BOOST_TT_CONDITIONAL_HPP_INCLUDED
+#define BOOST_TT_CONDITIONAL_HPP_INCLUDED
+
+namespace boost {
+
+template <bool b, class T, class U> struct conditional { typedef T type; };
+template <class T, class U> struct conditional<false, T, U> { typedef U type; };
+
+} // namespace boost
+
+
+#endif // BOOST_TT_CONDITIONAL_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/decay.hpp b/third_party/boost/boost/type_traits/decay.hpp
new file mode 100644
index 0000000..fa1ed9a
--- /dev/null
+++ b/third_party/boost/boost/type_traits/decay.hpp
@@ -0,0 +1,43 @@
+//  (C) Copyright John Maddock & Thorsten Ottosen 2005.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+
+#ifndef BOOST_TT_DECAY_HPP_INCLUDED
+#define BOOST_TT_DECAY_HPP_INCLUDED
+
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/is_function.hpp>
+#include <boost/type_traits/remove_bounds.hpp>
+#include <boost/type_traits/add_pointer.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+
+namespace boost
+{
+
+   namespace detail
+   {
+
+      template <class T, bool Array, bool Function> struct decay_imp { typedef typename remove_cv<T>::type type; };
+      template <class T> struct decay_imp<T, true, false> { typedef typename remove_bounds<T>::type* type; };
+      template <class T> struct decay_imp<T, false, true> { typedef T* type; };
+
+   }
+
+    template< class T >
+    struct decay
+    {
+    private:
+        typedef typename remove_reference<T>::type Ty;
+    public:
+       typedef typename boost::detail::decay_imp<Ty, boost::is_array<Ty>::value, boost::is_function<Ty>::value>::type type;
+    };
+
+} // namespace boost
+
+
+#endif // BOOST_TT_DECAY_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/declval.hpp b/third_party/boost/boost/type_traits/declval.hpp
new file mode 100644
index 0000000..a050012
--- /dev/null
+++ b/third_party/boost/boost/type_traits/declval.hpp
@@ -0,0 +1,44 @@
+//  declval.hpp  -------------------------------------------------------------//
+
+//  Copyright 2010 Vicente J. Botet Escriba
+
+//  Distributed under the Boost Software License, Version 1.0.
+//  See http://www.boost.org/LICENSE_1_0.txt
+
+#ifndef BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED
+#define BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED
+
+#include <boost/config.hpp>
+
+//----------------------------------------------------------------------------//
+
+#include <boost/type_traits/add_rvalue_reference.hpp>
+
+//----------------------------------------------------------------------------//
+//                                                                            //
+//                           C++03 implementation of                          //
+//                   20.2.4 Function template declval [declval]               //
+//                          Written by Vicente J. Botet Escriba               //
+//                                                                            //
+// 1 The library provides the function template declval to simplify the
+// definition of expressions which occur as unevaluated operands.
+// 2 Remarks: If this function is used, the program is ill-formed.
+// 3 Remarks: The template parameter T of declval may be an incomplete type.
+// [ Example:
+//
+// template <class To, class From>
+// decltype(static_cast<To>(declval<From>())) convert(From&&);
+//
+// declares a function template convert which only participates in overloading
+// if the type From can be explicitly converted to type To. For another example
+// see class template common_type (20.9.7.6). -end example ]
+//----------------------------------------------------------------------------//
+
+namespace boost {
+
+    template <typename T>
+    typename add_rvalue_reference<T>::type declval() BOOST_NOEXCEPT; // as unevaluated operand
+
+}  // namespace boost
+
+#endif  // BOOST_TYPE_TRAITS_DECLVAL_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/detail/config.hpp b/third_party/boost/boost/type_traits/detail/config.hpp
new file mode 100644
index 0000000..13ef3c1
--- /dev/null
+++ b/third_party/boost/boost/type_traits/detail/config.hpp
@@ -0,0 +1,70 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_CONFIG_HPP_INCLUDED
+#define BOOST_TT_CONFIG_HPP_INCLUDED
+
+#ifndef BOOST_CONFIG_HPP
+#include <boost/config.hpp>
+#endif
+#include <boost/version.hpp>
+#include <boost/detail/workaround.hpp>
+
+//
+// whenever we have a conversion function with ellipses
+// it needs to be declared __cdecl to suppress compiler
+// warnings from MS and Borland compilers (this *must*
+// appear before we include is_same.hpp below):
+#if defined(BOOST_MSVC) || (defined(__BORLANDC__) && !defined(BOOST_DISABLE_WIN32))
+#   define BOOST_TT_DECL __cdecl
+#else
+#   define BOOST_TT_DECL /**/
+#endif
+
+# if (BOOST_WORKAROUND(__MWERKS__, < 0x3000)                         \
+    || BOOST_WORKAROUND(__IBMCPP__, < 600 )                         \
+    || BOOST_WORKAROUND(__BORLANDC__, < 0x5A0)                      \
+    || defined(__ghs)                                               \
+    || BOOST_WORKAROUND(__HP_aCC, < 60700)           \
+    || BOOST_WORKAROUND(MPW_CPLUS, BOOST_TESTED_AT(0x890))          \
+    || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580)))       \
+    && defined(BOOST_NO_IS_ABSTRACT)
+
+#   define BOOST_TT_NO_CONFORMING_IS_CLASS_IMPLEMENTATION 1
+
+#endif
+
+#ifndef BOOST_TT_NO_CONFORMING_IS_CLASS_IMPLEMENTATION
+# define BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION 1
+#endif
+
+//
+// define BOOST_TT_TEST_MS_FUNC_SIGS
+// when we want to test __stdcall etc function types with is_function etc
+// (Note, does not work with Borland, even though it does support __stdcall etc):
+//
+#if defined(_MSC_EXTENSIONS) && !defined(__BORLANDC__)
+#  define BOOST_TT_TEST_MS_FUNC_SIGS
+#endif
+
+//
+// define BOOST_TT_NO_CV_FUNC_TEST
+// if tests for cv-qualified member functions don't
+// work in is_member_function_pointer
+//
+#if BOOST_WORKAROUND(__MWERKS__, < 0x3000) || BOOST_WORKAROUND(__IBMCPP__, <= 600)
+#  define BOOST_TT_NO_CV_FUNC_TEST
+#endif
+
+//
+// Macros that have been deprecated, defined here for backwards compatibility:
+//
+#define BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION(x)
+#define BOOST_TT_BROKEN_COMPILER_SPEC(x)
+
+#endif // BOOST_TT_CONFIG_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/detail/has_binary_operator.hpp b/third_party/boost/boost/type_traits/detail/has_binary_operator.hpp
new file mode 100644
index 0000000..039a6bb
--- /dev/null
+++ b/third_party/boost/boost/type_traits/detail/has_binary_operator.hpp
@@ -0,0 +1,222 @@
+//  (C) Copyright 2009-2011 Frederic Bron, Robert Stewart, Steven Watanabe & Roman Perepelitsa.
+//
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#include <boost/config.hpp>
+#include <boost/type_traits/detail/yes_no_type.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/type_traits/is_base_of.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/is_fundamental.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+// cannot include this header without getting warnings of the kind:
+// gcc:
+//    warning: value computed is not used
+//    warning: comparison between signed and unsigned integer expressions
+// msvc:
+//    warning C4018: '<' : signed/unsigned mismatch
+//    warning C4244: '+=' : conversion from 'double' to 'char', possible loss of data
+//    warning C4547: '*' : operator before comma has no effect; expected operator with side-effect
+//    warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
+//    warning C4804: '<' : unsafe use of type 'bool' in operation
+//    warning C4805: '==' : unsafe mix of type 'bool' and type 'char' in operation
+// cannot find another implementation -> declared as system header to suppress these warnings.
+#if defined(__GNUC__)
+#   pragma GCC system_header
+#elif defined(BOOST_MSVC)
+#   pragma warning ( push )
+#   pragma warning ( disable : 4018 4244 4547 4800 4804 4805 4913)
+#   if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
+#       pragma warning ( disable : 6334)
+#   endif
+#endif
+
+namespace boost {
+namespace detail {
+
+// This namespace ensures that argument-dependent name lookup does not mess things up.
+namespace BOOST_JOIN(BOOST_TT_TRAIT_NAME,_impl) {
+
+// 1. a function to have an instance of type T without requiring T to be default
+// constructible
+template <typename T> T &make();
+
+
+// 2. we provide our operator definition for types that do not have one already
+
+// a type returned from operator BOOST_TT_TRAIT_OP when no such operator is
+// found in the type's own namespace (our own operator is used) so that we have
+// a means to know that our operator was used
+struct no_operator { };
+
+// this class allows implicit conversions and makes the following operator
+// definition less-preferred than any other such operators that might be found
+// via argument-dependent name lookup
+struct any { template <class T> any(T const&); };
+
+// when operator BOOST_TT_TRAIT_OP is not available, this one is used
+no_operator operator BOOST_TT_TRAIT_OP (const any&, const any&);
+
+
+// 3. checks if the operator returns void or not
+// conditions: Lhs!=void and Rhs!=void
+
+// we first redefine "operator," so that we have no compilation error if
+// operator BOOST_TT_TRAIT_OP returns void and we can use the return type of
+// (lhs BOOST_TT_TRAIT_OP rhs, returns_void_t()) to deduce if
+// operator BOOST_TT_TRAIT_OP returns void or not:
+// - operator BOOST_TT_TRAIT_OP returns void   -> (lhs BOOST_TT_TRAIT_OP rhs, returns_void_t()) returns returns_void_t
+// - operator BOOST_TT_TRAIT_OP returns !=void -> (lhs BOOST_TT_TRAIT_OP rhs, returns_void_t()) returns int
+struct returns_void_t { };
+template <typename T> int operator,(const T&, returns_void_t);
+template <typename T> int operator,(const volatile T&, returns_void_t);
+
+// this intermediate trait has member value of type bool:
+// - value==true -> operator BOOST_TT_TRAIT_OP returns void
+// - value==false -> operator BOOST_TT_TRAIT_OP does not return void
+template < typename Lhs, typename Rhs >
+struct operator_returns_void {
+   // overloads of function returns_void make the difference
+   // yes_type and no_type have different size by construction
+   static ::boost::type_traits::yes_type returns_void(returns_void_t);
+   static ::boost::type_traits::no_type returns_void(int);
+   BOOST_STATIC_CONSTANT(bool, value = (sizeof(::boost::type_traits::yes_type)==sizeof(returns_void((make<Lhs>() BOOST_TT_TRAIT_OP make<Rhs>(),returns_void_t())))));
+};
+
+
+// 4. checks if the return type is Ret or Ret==dont_care
+// conditions: Lhs!=void and Rhs!=void
+
+struct dont_care { };
+
+template < typename Lhs, typename Rhs, typename Ret, bool Returns_void >
+struct operator_returns_Ret;
+
+template < typename Lhs, typename Rhs >
+struct operator_returns_Ret < Lhs, Rhs, dont_care, true > {
+   BOOST_STATIC_CONSTANT(bool, value = true);
+};
+
+template < typename Lhs, typename Rhs >
+struct operator_returns_Ret < Lhs, Rhs, dont_care, false > {
+   BOOST_STATIC_CONSTANT(bool, value = true);
+};
+
+template < typename Lhs, typename Rhs >
+struct operator_returns_Ret < Lhs, Rhs, void, true > {
+   BOOST_STATIC_CONSTANT(bool, value = true);
+};
+
+template < typename Lhs, typename Rhs >
+struct operator_returns_Ret < Lhs, Rhs, void, false > {
+   BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+template < typename Lhs, typename Rhs, typename Ret >
+struct operator_returns_Ret < Lhs, Rhs, Ret, true > {
+   BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+// otherwise checks if it is convertible to Ret using the sizeof trick
+// based on overload resolution
+// condition: Ret!=void and Ret!=dont_care and the operator does not return void
+template < typename Lhs, typename Rhs, typename Ret >
+struct operator_returns_Ret < Lhs, Rhs, Ret, false > {
+   static ::boost::type_traits::yes_type is_convertible_to_Ret(Ret); // this version is preferred for types convertible to Ret
+   static ::boost::type_traits::no_type is_convertible_to_Ret(...); // this version is used otherwise
+
+   BOOST_STATIC_CONSTANT(bool, value = (sizeof(is_convertible_to_Ret(make<Lhs>() BOOST_TT_TRAIT_OP make<Rhs>()))==sizeof(::boost::type_traits::yes_type)));
+};
+
+
+// 5. checks for operator existence
+// condition: Lhs!=void and Rhs!=void
+
+// checks if our definition of operator BOOST_TT_TRAIT_OP is used or an other
+// existing one;
+// this is done with redefinition of "operator," that returns no_operator or has_operator
+struct has_operator { };
+no_operator operator,(no_operator, has_operator);
+
+template < typename Lhs, typename Rhs >
+struct operator_exists {
+   static ::boost::type_traits::yes_type s_check(has_operator); // this version is preferred when operator exists
+   static ::boost::type_traits::no_type s_check(no_operator); // this version is used otherwise
+
+   BOOST_STATIC_CONSTANT(bool, value = (sizeof(s_check(((make<Lhs>() BOOST_TT_TRAIT_OP make<Rhs>()),make<has_operator>())))==sizeof(::boost::type_traits::yes_type)));
+};
+
+
+// 6. main trait: to avoid any compilation error, this class behaves
+// differently when operator BOOST_TT_TRAIT_OP(Lhs, Rhs) is forbidden by the
+// standard.
+// Forbidden_if is a bool that is:
+// - true when the operator BOOST_TT_TRAIT_OP(Lhs, Rhs) is forbidden by the standard
+//   (would yield compilation error if used)
+// - false otherwise
+template < typename Lhs, typename Rhs, typename Ret, bool Forbidden_if >
+struct trait_impl1;
+
+template < typename Lhs, typename Rhs, typename Ret >
+struct trait_impl1 < Lhs, Rhs, Ret, true > {
+   BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+template < typename Lhs, typename Rhs, typename Ret >
+struct trait_impl1 < Lhs, Rhs, Ret, false > {
+   BOOST_STATIC_CONSTANT(bool,
+      value = (operator_exists < Lhs, Rhs >::value && operator_returns_Ret < Lhs, Rhs, Ret, operator_returns_void < Lhs, Rhs >::value >::value));
+};
+
+// some specializations needs to be declared for the special void case
+template < typename Rhs, typename Ret >
+struct trait_impl1 < void, Rhs, Ret, false > {
+   BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+template < typename Lhs, typename Ret >
+struct trait_impl1 < Lhs, void, Ret, false > {
+   BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+template < typename Ret >
+struct trait_impl1 < void, void, Ret, false > {
+   BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+// defines some typedef for convenience
+template < typename Lhs, typename Rhs, typename Ret >
+struct trait_impl {
+   typedef typename ::boost::remove_reference<Lhs>::type Lhs_noref;
+   typedef typename ::boost::remove_reference<Rhs>::type Rhs_noref;
+   typedef typename ::boost::remove_cv<Lhs_noref>::type Lhs_nocv;
+   typedef typename ::boost::remove_cv<Rhs_noref>::type Rhs_nocv;
+   typedef typename ::boost::remove_cv< typename ::boost::remove_reference< typename ::boost::remove_pointer<Lhs_noref>::type >::type >::type Lhs_noptr;
+   typedef typename ::boost::remove_cv< typename ::boost::remove_reference< typename ::boost::remove_pointer<Rhs_noref>::type >::type >::type Rhs_noptr;
+   BOOST_STATIC_CONSTANT(bool, value = (trait_impl1 < Lhs_noref, Rhs_noref, Ret, BOOST_TT_FORBIDDEN_IF >::value));
+};
+
+} // namespace impl
+} // namespace detail
+
+// this is the accessible definition of the trait to end user
+template <class Lhs, class Rhs=Lhs, class Ret=::boost::detail::BOOST_JOIN(BOOST_TT_TRAIT_NAME,_impl)::dont_care>
+struct BOOST_TT_TRAIT_NAME : public integral_constant<bool, (::boost::detail::BOOST_JOIN(BOOST_TT_TRAIT_NAME, _impl)::trait_impl < Lhs, Rhs, Ret >::value)>{};
+
+} // namespace boost
+
+#if defined(BOOST_MSVC)
+#   pragma warning ( pop )
+#endif
diff --git a/third_party/boost/boost/type_traits/detail/is_function_ptr_helper.hpp b/third_party/boost/boost/type_traits/detail/is_function_ptr_helper.hpp
new file mode 100644
index 0000000..3538e40
--- /dev/null
+++ b/third_party/boost/boost/type_traits/detail/is_function_ptr_helper.hpp
@@ -0,0 +1,176 @@
+
+//  Copyright 2000 John Maddock (john@johnmaddock.co.uk)
+//  Copyright 2002 Aleksey Gurtovoy (agurtovoy@meta-comm.com)
+//
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+///// header body
+
+#ifndef BOOST_TT_DETAIL_IS_FUNCTION_PTR_HELPER_HPP_INCLUDED
+#define BOOST_TT_DETAIL_IS_FUNCTION_PTR_HELPER_HPP_INCLUDED
+
+#if defined(BOOST_TT_PREPROCESSING_MODE)
+//
+// Hide these #include from dependency analysers as
+// these are required in maintenance mode only:
+//
+#define PP1 <boost/preprocessor/iterate.hpp>
+#include PP1
+#undef PP1
+#define PP1 <boost/preprocessor/enum_params.hpp>
+#include PP1
+#undef PP1
+#define PP1 <boost/preprocessor/comma_if.hpp>
+#include PP1
+#undef PP1
+#endif
+
+namespace boost {
+namespace type_traits {
+
+template <class R>
+struct is_function_ptr_helper
+{
+    BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+#if !defined(BOOST_TT_PREPROCESSING_MODE)
+// preprocessor-generated part, don't edit by hand!
+
+template <class R >
+struct is_function_ptr_helper<R (*)()> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R >
+struct is_function_ptr_helper<R (*)( ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0>
+struct is_function_ptr_helper<R (*)( T0)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0>
+struct is_function_ptr_helper<R (*)( T0 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1>
+struct is_function_ptr_helper<R (*)( T0 , T1)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1>
+struct is_function_ptr_helper<R (*)( T0 , T1 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23 , class T24>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23 , class T24>
+struct is_function_ptr_helper<R (*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+#else
+
+#undef BOOST_STATIC_CONSTANT
+#define BOOST_PP_ITERATION_PARAMS_1 \
+    (3, (0, 25, "boost/type_traits/detail/is_function_ptr_helper.hpp"))
+#include BOOST_PP_ITERATE()
+
+#endif // BOOST_TT_PREPROCESSING_MODE
+
+} // namespace type_traits
+} // namespace boost
+
+#endif // BOOST_TT_DETAIL_IS_FUNCTION_PTR_HELPER_HPP_INCLUDED
+
+///// iteration
+
+#else
+#define BOOST_PP_COUNTER BOOST_PP_FRAME_ITERATION(1)
+
+template <class R BOOST_PP_COMMA_IF(BOOST_PP_COUNTER) BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,class T)>
+struct is_function_ptr_helper<R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T))> { BOOST_STATIC_CONSTANT(bool, value = true); };
+@#ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING
+template <class R BOOST_PP_COMMA_IF(BOOST_PP_COUNTER) BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,class T)>
+struct is_function_ptr_helper<R (*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T) ...)> { BOOST_STATIC_CONSTANT(bool, value = true); };
+@#endif
+#undef BOOST_PP_COUNTER
+#endif // BOOST_PP_IS_ITERATING
diff --git a/third_party/boost/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp b/third_party/boost/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp
new file mode 100644
index 0000000..4dfb9c5
--- /dev/null
+++ b/third_party/boost/boost/type_traits/detail/is_mem_fun_pointer_impl.hpp
@@ -0,0 +1,722 @@
+
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes,
+//  Aleksey Gurtovoy, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#if !defined(BOOST_PP_IS_ITERATING)
+
+///// header body
+
+#ifndef BOOST_TT_DETAIL_IS_MEM_FUN_POINTER_IMPL_HPP_INCLUDED
+#define BOOST_TT_DETAIL_IS_MEM_FUN_POINTER_IMPL_HPP_INCLUDED
+
+#include <boost/config.hpp>
+
+#if defined(BOOST_TT_PREPROCESSING_MODE)
+//
+// Maintenance mode, hide include dependencies
+// from trackers:
+//
+#define PPI <boost/preprocessor/iterate.hpp>
+#include PPI
+#undef PPI
+#define PPI <boost/preprocessor/enum_params.hpp>
+#include PPI
+#undef PPI
+#define PPI <boost/preprocessor/comma_if.hpp>
+#include PPI
+#undef PPI
+#endif
+
+namespace boost {
+namespace type_traits {
+
+template <typename T>
+struct is_mem_fun_pointer_impl
+{
+    BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+#if !defined(BOOST_TT_PREPROCESSING_MODE)
+// pre-processed code, don't edit, try GNU cpp with
+// cpp -I../../../ -DBOOST_TT_PREPROCESSING_MODE -x c++ -P filename
+
+template <class R, class T >
+struct is_mem_fun_pointer_impl<R (T::*)() > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T >
+struct is_mem_fun_pointer_impl<R (T::*)( ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T >
+struct is_mem_fun_pointer_impl<R (T::*)() const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T >
+struct is_mem_fun_pointer_impl<R (T::*)() volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T >
+struct is_mem_fun_pointer_impl<R (T::*)() const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T >
+struct is_mem_fun_pointer_impl<R (T::*)( ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T >
+struct is_mem_fun_pointer_impl<R (T::*)( ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T >
+struct is_mem_fun_pointer_impl<R (T::*)( ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0>
+struct is_mem_fun_pointer_impl<R (T::*)( T0) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0>
+struct is_mem_fun_pointer_impl<R (T::*)( T0) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0>
+struct is_mem_fun_pointer_impl<R (T::*)( T0) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0>
+struct is_mem_fun_pointer_impl<R (T::*)( T0) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23 , class T24>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23 , class T24>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23 , class T24>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23 , class T24>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23 , class T24>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23 , class T24>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23 , class T24>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T , class T0 , class T1 , class T2 , class T3 , class T4 , class T5 , class T6 , class T7 , class T8 , class T9 , class T10 , class T11 , class T12 , class T13 , class T14 , class T15 , class T16 , class T17 , class T18 , class T19 , class T20 , class T21 , class T22 , class T23 , class T24>
+struct is_mem_fun_pointer_impl<R (T::*)( T0 , T1 , T2 , T3 , T4 , T5 , T6 , T7 , T8 , T9 , T10 , T11 , T12 , T13 , T14 , T15 , T16 , T17 , T18 , T19 , T20 , T21 , T22 , T23 , T24 ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+#endif
+
+#else
+
+#undef BOOST_STATIC_CONSTANT
+#define BOOST_PP_ITERATION_PARAMS_1 \
+    (3, (0, 25, "boost/type_traits/detail/is_mem_fun_pointer_impl.hpp"))
+#include BOOST_PP_ITERATE()
+
+#endif // BOOST_TT_PREPROCESSING_MODE
+
+} // namespace type_traits
+} // namespace boost
+
+#endif // BOOST_TT_DETAIL_IS_MEM_FUN_POINTER_IMPL_HPP_INCLUDED
+
+///// iteration
+
+#else
+#define BOOST_PP_COUNTER BOOST_PP_FRAME_ITERATION(1)
+
+template <class R, class T BOOST_PP_COMMA_IF(BOOST_PP_COUNTER) BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,class T)>
+struct is_mem_fun_pointer_impl<R (T::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+@#ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING
+template <class R, class T BOOST_PP_COMMA_IF(BOOST_PP_COUNTER) BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,class T)>
+struct is_mem_fun_pointer_impl<R (T::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T) ...) > { BOOST_STATIC_CONSTANT(bool, value = true); };
+@#endif
+
+@#if !defined(BOOST_TT_NO_CV_FUNC_TEST)
+template <class R, class T BOOST_PP_COMMA_IF(BOOST_PP_COUNTER) BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,class T)>
+struct is_mem_fun_pointer_impl<R (T::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T BOOST_PP_COMMA_IF(BOOST_PP_COUNTER) BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,class T)>
+struct is_mem_fun_pointer_impl<R (T::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T BOOST_PP_COMMA_IF(BOOST_PP_COUNTER) BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,class T)>
+struct is_mem_fun_pointer_impl<R (T::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T)) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+@#ifndef BOOST_TT_NO_ELLIPSIS_IN_FUNC_TESTING
+template <class R, class T BOOST_PP_COMMA_IF(BOOST_PP_COUNTER) BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,class T)>
+struct is_mem_fun_pointer_impl<R (T::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T) ...) const > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T BOOST_PP_COMMA_IF(BOOST_PP_COUNTER) BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,class T)>
+struct is_mem_fun_pointer_impl<R (T::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T) ...) volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+
+template <class R, class T BOOST_PP_COMMA_IF(BOOST_PP_COUNTER) BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,class T)>
+struct is_mem_fun_pointer_impl<R (T::*)(BOOST_PP_ENUM_PARAMS(BOOST_PP_COUNTER,T) ...) const volatile > { BOOST_STATIC_CONSTANT(bool, value = true); };
+@#endif
+@#endif
+
+#undef BOOST_PP_COUNTER
+#endif // BOOST_PP_IS_ITERATING
diff --git a/third_party/boost/boost/type_traits/detail/yes_no_type.hpp b/third_party/boost/boost/type_traits/detail/yes_no_type.hpp
new file mode 100644
index 0000000..f583730
--- /dev/null
+++ b/third_party/boost/boost/type_traits/detail/yes_no_type.hpp
@@ -0,0 +1,26 @@
+
+//  (C) Copyright John Maddock and Steve Cleary 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+//
+//  macros and helpers for working with integral-constant-expressions.
+
+#ifndef BOOST_TT_DETAIL_YES_NO_TYPE_HPP_INCLUDED
+#define BOOST_TT_DETAIL_YES_NO_TYPE_HPP_INCLUDED
+
+namespace boost {
+namespace type_traits {
+
+typedef char yes_type;
+struct no_type
+{
+   char padding[8];
+};
+
+} // namespace type_traits
+} // namespace boost
+
+#endif // BOOST_TT_DETAIL_YES_NO_TYPE_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/function_traits.hpp b/third_party/boost/boost/type_traits/function_traits.hpp
new file mode 100644
index 0000000..a01d372
--- /dev/null
+++ b/third_party/boost/boost/type_traits/function_traits.hpp
@@ -0,0 +1,174 @@
+
+//  Copyright 2000 John Maddock (john@johnmaddock.co.uk)
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_FUNCTION_TRAITS_HPP_INCLUDED
+#define BOOST_TT_FUNCTION_TRAITS_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/type_traits/is_function.hpp>
+#include <boost/type_traits/add_pointer.hpp>
+
+namespace boost {
+
+namespace detail {
+
+template<typename Function> struct function_traits_helper;
+
+template<typename R>
+struct function_traits_helper<R (*)(void)>
+{
+  BOOST_STATIC_CONSTANT(unsigned, arity = 0);
+  typedef R result_type;
+};
+
+template<typename R, typename T1>
+struct function_traits_helper<R (*)(T1)>
+{
+  BOOST_STATIC_CONSTANT(unsigned, arity = 1);
+  typedef R result_type;
+  typedef T1 arg1_type;
+  typedef T1 argument_type;
+};
+
+template<typename R, typename T1, typename T2>
+struct function_traits_helper<R (*)(T1, T2)>
+{
+  BOOST_STATIC_CONSTANT(unsigned, arity = 2);
+  typedef R result_type;
+  typedef T1 arg1_type;
+  typedef T2 arg2_type;
+  typedef T1 first_argument_type;
+  typedef T2 second_argument_type;
+};
+
+template<typename R, typename T1, typename T2, typename T3>
+struct function_traits_helper<R (*)(T1, T2, T3)>
+{
+  BOOST_STATIC_CONSTANT(unsigned, arity = 3);
+  typedef R result_type;
+  typedef T1 arg1_type;
+  typedef T2 arg2_type;
+  typedef T3 arg3_type;
+};
+
+template<typename R, typename T1, typename T2, typename T3, typename T4>
+struct function_traits_helper<R (*)(T1, T2, T3, T4)>
+{
+  BOOST_STATIC_CONSTANT(unsigned, arity = 4);
+  typedef R result_type;
+  typedef T1 arg1_type;
+  typedef T2 arg2_type;
+  typedef T3 arg3_type;
+  typedef T4 arg4_type;
+};
+
+template<typename R, typename T1, typename T2, typename T3, typename T4,
+         typename T5>
+struct function_traits_helper<R (*)(T1, T2, T3, T4, T5)>
+{
+  BOOST_STATIC_CONSTANT(unsigned, arity = 5);
+  typedef R result_type;
+  typedef T1 arg1_type;
+  typedef T2 arg2_type;
+  typedef T3 arg3_type;
+  typedef T4 arg4_type;
+  typedef T5 arg5_type;
+};
+
+template<typename R, typename T1, typename T2, typename T3, typename T4,
+         typename T5, typename T6>
+struct function_traits_helper<R (*)(T1, T2, T3, T4, T5, T6)>
+{
+  BOOST_STATIC_CONSTANT(unsigned, arity = 6);
+  typedef R result_type;
+  typedef T1 arg1_type;
+  typedef T2 arg2_type;
+  typedef T3 arg3_type;
+  typedef T4 arg4_type;
+  typedef T5 arg5_type;
+  typedef T6 arg6_type;
+};
+
+template<typename R, typename T1, typename T2, typename T3, typename T4,
+         typename T5, typename T6, typename T7>
+struct function_traits_helper<R (*)(T1, T2, T3, T4, T5, T6, T7)>
+{
+  BOOST_STATIC_CONSTANT(unsigned, arity = 7);
+  typedef R result_type;
+  typedef T1 arg1_type;
+  typedef T2 arg2_type;
+  typedef T3 arg3_type;
+  typedef T4 arg4_type;
+  typedef T5 arg5_type;
+  typedef T6 arg6_type;
+  typedef T7 arg7_type;
+};
+
+template<typename R, typename T1, typename T2, typename T3, typename T4,
+         typename T5, typename T6, typename T7, typename T8>
+struct function_traits_helper<R (*)(T1, T2, T3, T4, T5, T6, T7, T8)>
+{
+  BOOST_STATIC_CONSTANT(unsigned, arity = 8);
+  typedef R result_type;
+  typedef T1 arg1_type;
+  typedef T2 arg2_type;
+  typedef T3 arg3_type;
+  typedef T4 arg4_type;
+  typedef T5 arg5_type;
+  typedef T6 arg6_type;
+  typedef T7 arg7_type;
+  typedef T8 arg8_type;
+};
+
+template<typename R, typename T1, typename T2, typename T3, typename T4,
+         typename T5, typename T6, typename T7, typename T8, typename T9>
+struct function_traits_helper<R (*)(T1, T2, T3, T4, T5, T6, T7, T8, T9)>
+{
+  BOOST_STATIC_CONSTANT(unsigned, arity = 9);
+  typedef R result_type;
+  typedef T1 arg1_type;
+  typedef T2 arg2_type;
+  typedef T3 arg3_type;
+  typedef T4 arg4_type;
+  typedef T5 arg5_type;
+  typedef T6 arg6_type;
+  typedef T7 arg7_type;
+  typedef T8 arg8_type;
+  typedef T9 arg9_type;
+};
+
+template<typename R, typename T1, typename T2, typename T3, typename T4,
+         typename T5, typename T6, typename T7, typename T8, typename T9,
+         typename T10>
+struct function_traits_helper<R (*)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)>
+{
+  BOOST_STATIC_CONSTANT(unsigned, arity = 10);
+  typedef R result_type;
+  typedef T1 arg1_type;
+  typedef T2 arg2_type;
+  typedef T3 arg3_type;
+  typedef T4 arg4_type;
+  typedef T5 arg5_type;
+  typedef T6 arg6_type;
+  typedef T7 arg7_type;
+  typedef T8 arg8_type;
+  typedef T9 arg9_type;
+  typedef T10 arg10_type;
+};
+
+} // end namespace detail
+
+template<typename Function>
+struct function_traits :
+  public boost::detail::function_traits_helper<typename boost::add_pointer<Function>::type>
+{
+};
+
+}
+
+#endif // BOOST_TT_FUNCTION_TRAITS_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/has_minus.hpp b/third_party/boost/boost/type_traits/has_minus.hpp
new file mode 100644
index 0000000..5e13c16
--- /dev/null
+++ b/third_party/boost/boost/type_traits/has_minus.hpp
@@ -0,0 +1,60 @@
+//  (C) Copyright 2009-2011 Frederic Bron.
+//
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_HAS_MINUS_HPP_INCLUDED
+#define BOOST_TT_HAS_MINUS_HPP_INCLUDED
+
+#define BOOST_TT_TRAIT_NAME has_minus
+#define BOOST_TT_TRAIT_OP -
+#define BOOST_TT_FORBIDDEN_IF\
+   (\
+      /* Lhs==pointer and Rhs==fundamental and Rhs!=integral */\
+      (\
+         ::boost::is_pointer< Lhs_noref >::value && \
+         ::boost::is_fundamental< Rhs_nocv >::value && \
+         (!  ::boost::is_integral< Rhs_noref >::value )\
+      ) || \
+      /* Lhs==void* and (Rhs==fundamental or Rhs==pointer) */\
+      (\
+         ::boost::is_pointer< Lhs_noref >::value && \
+         ::boost::is_void< Lhs_noptr >::value && \
+         ( \
+            ::boost::is_fundamental< Rhs_nocv >::value || \
+            ::boost::is_pointer< Rhs_noref >::value\
+          )\
+      ) || \
+      /* Rhs==void* and (Lhs==fundamental or Lhs==pointer) */\
+      (\
+         ::boost::is_pointer< Rhs_noref >::value && \
+         ::boost::is_void< Rhs_noptr >::value && \
+         (\
+            ::boost::is_fundamental< Lhs_nocv >::value || \
+            ::boost::is_pointer< Lhs_noref >::value\
+          )\
+      ) ||\
+      /* Lhs=fundamental and Rhs=pointer */\
+      (\
+         ::boost::is_fundamental< Lhs_nocv >::value && \
+         ::boost::is_pointer< Rhs_noref >::value\
+      ) ||\
+      /* two different pointers */\
+      (\
+         ::boost::is_pointer< Lhs_noref >::value && \
+         ::boost::is_pointer< Rhs_noref >::value && \
+         (!  ::boost::is_same< Lhs_nocv, Rhs_nocv >::value )\
+      )\
+      )
+
+
+#include <boost/type_traits/detail/has_binary_operator.hpp>
+
+#undef BOOST_TT_TRAIT_NAME
+#undef BOOST_TT_TRAIT_OP
+#undef BOOST_TT_FORBIDDEN_IF
+
+#endif
diff --git a/third_party/boost/boost/type_traits/has_minus_assign.hpp b/third_party/boost/boost/type_traits/has_minus_assign.hpp
new file mode 100644
index 0000000..b53474e
--- /dev/null
+++ b/third_party/boost/boost/type_traits/has_minus_assign.hpp
@@ -0,0 +1,65 @@
+//  (C) Copyright 2009-2011 Frederic Bron.
+//
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_HAS_MINUS_ASSIGN_HPP_INCLUDED
+#define BOOST_TT_HAS_MINUS_ASSIGN_HPP_INCLUDED
+
+#define BOOST_TT_TRAIT_NAME has_minus_assign
+#define BOOST_TT_TRAIT_OP -=
+#define BOOST_TT_FORBIDDEN_IF\
+   (\
+      /* Lhs==pointer and Rhs==fundamental and Rhs!=integral */\
+      (\
+         ::boost::is_pointer< Lhs_noref >::value && \
+         ::boost::is_fundamental< Rhs_nocv >::value && \
+         (!  ::boost::is_integral< Rhs_noref >::value )\
+      ) || \
+      /* Lhs==void* and Rhs==fundamental */\
+      (\
+         ::boost::is_pointer< Lhs_noref >::value && \
+         ::boost::is_void< Lhs_noptr >::value && \
+         ::boost::is_fundamental< Rhs_nocv >::value\
+      ) || \
+      /* Rhs==void* and Lhs==fundamental */\
+      (\
+         ::boost::is_pointer< Rhs_noref >::value && \
+         ::boost::is_void< Rhs_noptr >::value && \
+         ::boost::is_fundamental< Lhs_nocv >::value\
+      ) || \
+      /* Lhs=fundamental and Rhs=pointer */\
+      (\
+         ::boost::is_fundamental< Lhs_nocv >::value && \
+         ::boost::is_pointer< Rhs_noref >::value\
+      ) || \
+      /* Lhs==pointer and Rhs==pointer */\
+      (\
+         ::boost::is_pointer< Lhs_noref >::value && \
+         ::boost::is_pointer< Rhs_noref >::value\
+      ) || \
+      /* (Lhs==fundamental or Lhs==pointer) and (Rhs==fundamental or Rhs==pointer) and (Lhs==const) */\
+      (\
+         (\
+            ::boost::is_fundamental< Lhs_nocv >::value || \
+            ::boost::is_pointer< Lhs_noref >::value\
+         ) && \
+         (\
+            ::boost::is_fundamental< Rhs_nocv >::value || \
+            ::boost::is_pointer< Rhs_noref >::value\
+          ) && \
+         ::boost::is_const< Lhs_noref >::value\
+      )\
+      )
+
+
+#include <boost/type_traits/detail/has_binary_operator.hpp>
+
+#undef BOOST_TT_TRAIT_NAME
+#undef BOOST_TT_TRAIT_OP
+#undef BOOST_TT_FORBIDDEN_IF
+
+#endif
diff --git a/third_party/boost/boost/type_traits/has_nothrow_assign.hpp b/third_party/boost/boost/type_traits/has_nothrow_assign.hpp
new file mode 100644
index 0000000..8d82230
--- /dev/null
+++ b/third_party/boost/boost/type_traits/has_nothrow_assign.hpp
@@ -0,0 +1,83 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_HAS_NOTHROW_ASSIGN_HPP_INCLUDED
+#define BOOST_TT_HAS_NOTHROW_ASSIGN_HPP_INCLUDED
+
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/type_traits/intrinsics.hpp>
+
+#if !defined(BOOST_HAS_NOTHROW_ASSIGN) || defined(BOOST_MSVC) || defined(BOOST_INTEL)
+#include <boost/type_traits/has_trivial_assign.hpp>
+#if !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+#include <boost/type_traits/declval.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_volatile.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/is_assignable.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#endif
+#endif
+#if defined(__GNUC__) || defined(__SUNPRO_CC)
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_volatile.hpp>
+#include <boost/type_traits/is_assignable.hpp>
+#include <boost/type_traits/is_array.hpp>
+#ifdef BOOST_INTEL
+#include <boost/type_traits/is_pod.hpp>
+#endif
+#endif
+
+namespace boost {
+
+#if !defined(BOOST_HAS_NOTHROW_ASSIGN) && !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+
+   namespace detail
+   {
+      template <class T, bool b1, bool b2> struct has_nothrow_assign_imp{ static const bool value = false; };
+      template <class T>          struct has_nothrow_assign_imp<T, false, true>{ static const bool value = noexcept(boost::declval<typename add_reference<T>::type>() = boost::declval<typename add_reference<T const>::type>()); };
+      template <class T, std::size_t N> struct has_nothrow_assign_imp<T[N], false, true>{ static const bool value = has_nothrow_assign_imp<T, false, true>::value; };
+      template <class T>          struct has_nothrow_assign_imp<T[], false, true>{ static const bool value = has_nothrow_assign_imp<T, false, true>::value; };
+   }
+
+#endif
+
+   template <class T>
+   struct has_nothrow_assign : public integral_constant < bool,
+#ifndef BOOST_HAS_NOTHROW_ASSIGN
+#if !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+      // Portable C++11 version:
+      detail::has_nothrow_assign_imp<T,
+      (is_const<typename remove_reference<T>::type>::value || is_volatile<typename remove_reference<T>::type>::value || is_reference<T>::value),
+      is_assignable<typename add_reference<T>::type, typename add_reference<const T>::type>::value
+      >::value
+#else
+      ::boost::has_trivial_assign<T>::value
+#endif
+#else
+      BOOST_HAS_NOTHROW_ASSIGN(T)
+#endif
+   > {};
+
+template <class T, std::size_t N> struct has_nothrow_assign <T[N]> : public has_nothrow_assign<T> {};
+template <> struct has_nothrow_assign<void> : public false_type{};
+template <class T> struct has_nothrow_assign<T volatile> : public false_type{};
+template <class T> struct has_nothrow_assign<T&> : public false_type{};
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+template <class T> struct has_nothrow_assign<T&&> : public false_type{};
+#endif
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template <> struct has_nothrow_assign<void const> : public false_type{};
+template <> struct has_nothrow_assign<void const volatile> : public false_type{};
+template <> struct has_nothrow_assign<void volatile> : public false_type{};
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_HAS_NOTHROW_ASSIGN_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/has_nothrow_constructor.hpp b/third_party/boost/boost/type_traits/has_nothrow_constructor.hpp
new file mode 100644
index 0000000..e5af89f
--- /dev/null
+++ b/third_party/boost/boost/type_traits/has_nothrow_constructor.hpp
@@ -0,0 +1,72 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_HAS_NOTHROW_CONSTRUCTOR_HPP_INCLUDED
+#define BOOST_TT_HAS_NOTHROW_CONSTRUCTOR_HPP_INCLUDED
+
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+
+#ifdef BOOST_HAS_NOTHROW_CONSTRUCTOR
+
+#if defined(BOOST_MSVC) || defined(BOOST_INTEL)
+#include <boost/type_traits/has_trivial_constructor.hpp>
+#endif
+#if defined(__GNUC__ ) || defined(__SUNPRO_CC)
+#include <boost/type_traits/is_default_constructible.hpp>
+#endif
+
+namespace boost {
+
+template <class T> struct has_nothrow_constructor : public integral_constant<bool, BOOST_HAS_NOTHROW_CONSTRUCTOR(T)>{};
+
+#elif !defined(BOOST_NO_CXX11_NOEXCEPT)
+
+#include <boost/type_traits/is_default_constructible.hpp>
+#include <boost/type_traits/remove_all_extents.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4197) // top-level volatile in cast is ignored
+#endif
+
+namespace boost { namespace detail{
+
+   template <class T, bool b> struct has_nothrow_constructor_imp : public boost::integral_constant<bool, false>{};
+   template <class T> struct has_nothrow_constructor_imp<T, true> : public boost::integral_constant<bool, noexcept(T())>{};
+   template <class T, std::size_t N> struct has_nothrow_constructor_imp<T[N], true> : public has_nothrow_constructor_imp<T, true> {};
+}
+
+template <class T> struct has_nothrow_constructor : public detail::has_nothrow_constructor_imp<T, is_default_constructible<T>::value>{};
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#else
+
+#include <boost/type_traits/has_trivial_constructor.hpp>
+
+namespace boost {
+
+template <class T> struct has_nothrow_constructor : public ::boost::has_trivial_constructor<T> {};
+
+#endif
+
+template<> struct has_nothrow_constructor<void> : public false_type {};
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template<> struct has_nothrow_constructor<void const> : public false_type{};
+template<> struct has_nothrow_constructor<void const volatile> : public false_type{};
+template<> struct has_nothrow_constructor<void volatile> : public false_type{};
+#endif
+
+template <class T> struct has_nothrow_default_constructor : public has_nothrow_constructor<T>{};
+
+} // namespace boost
+
+#endif // BOOST_TT_HAS_NOTHROW_CONSTRUCTOR_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/has_nothrow_copy.hpp b/third_party/boost/boost/type_traits/has_nothrow_copy.hpp
new file mode 100644
index 0000000..8810abc
--- /dev/null
+++ b/third_party/boost/boost/type_traits/has_nothrow_copy.hpp
@@ -0,0 +1,82 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_HAS_NOTHROW_COPY_HPP_INCLUDED
+#define BOOST_TT_HAS_NOTHROW_COPY_HPP_INCLUDED
+
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+
+#ifdef BOOST_HAS_NOTHROW_COPY
+
+#if defined(BOOST_CLANG) || defined(__GNUC__) || defined(__ghs__) || defined(__CODEGEARC__) || defined(__SUNPRO_CC)
+#include <boost/type_traits/is_volatile.hpp>
+#include <boost/type_traits/is_copy_constructible.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/is_array.hpp>
+#ifdef BOOST_INTEL
+#include <boost/type_traits/is_pod.hpp>
+#endif
+#elif defined(BOOST_MSVC) || defined(BOOST_INTEL)
+#include <boost/type_traits/has_trivial_copy.hpp>
+#include <boost/type_traits/is_array.hpp>
+#ifdef BOOST_INTEL
+#include <boost/type_traits/add_lvalue_reference.hpp>
+#include <boost/type_traits/add_const.hpp>
+#endif
+#endif
+
+namespace boost {
+
+template <class T> struct has_nothrow_copy_constructor : public integral_constant<bool, BOOST_HAS_NOTHROW_COPY(T)>{};
+
+#elif !defined(BOOST_NO_CXX11_NOEXCEPT)
+
+#include <boost/type_traits/declval.hpp>
+#include <boost/type_traits/is_copy_constructible.hpp>
+
+namespace boost{
+
+namespace detail{
+
+template <class T, bool b>
+struct has_nothrow_copy_constructor_imp : public boost::integral_constant<bool, false>{};
+template <class T>
+struct has_nothrow_copy_constructor_imp<T, true> : public boost::integral_constant<bool, noexcept(T(boost::declval<const T&>()))>{};
+
+}
+
+template <class T> struct has_nothrow_copy_constructor : public detail::has_nothrow_copy_constructor_imp<T, boost::is_copy_constructible<T>::value>{};
+
+#else
+
+#include <boost/type_traits/has_trivial_copy.hpp>
+
+namespace boost{
+
+template <class T> struct has_nothrow_copy_constructor : public integral_constant<bool, ::boost::has_trivial_copy<T>::value>{};
+
+#endif
+
+template <> struct has_nothrow_copy_constructor<void> : public false_type{};
+template <class T> struct has_nothrow_copy_constructor<T volatile> : public false_type{};
+template <class T> struct has_nothrow_copy_constructor<T&> : public false_type{};
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+template <class T> struct has_nothrow_copy_constructor<T&&> : public false_type{};
+#endif
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template <> struct has_nothrow_copy_constructor<void const> : public false_type{};
+template <> struct has_nothrow_copy_constructor<void volatile> : public false_type{};
+template <> struct has_nothrow_copy_constructor<void const volatile> : public false_type{};
+#endif
+
+template <class T> struct has_nothrow_copy : public has_nothrow_copy_constructor<T>{};
+
+} // namespace boost
+
+#endif // BOOST_TT_HAS_NOTHROW_COPY_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/has_plus.hpp b/third_party/boost/boost/type_traits/has_plus.hpp
new file mode 100644
index 0000000..2d79328
--- /dev/null
+++ b/third_party/boost/boost/type_traits/has_plus.hpp
@@ -0,0 +1,54 @@
+//  (C) Copyright 2009-2011 Frederic Bron.
+//
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_HAS_PLUS_HPP_INCLUDED
+#define BOOST_TT_HAS_PLUS_HPP_INCLUDED
+
+#define BOOST_TT_TRAIT_NAME has_plus
+#define BOOST_TT_TRAIT_OP +
+#define BOOST_TT_FORBIDDEN_IF\
+   (\
+      /* Lhs==pointer and Rhs==pointer */\
+      (\
+         ::boost::is_pointer< Lhs_noref >::value && \
+         ::boost::is_pointer< Rhs_noref >::value\
+      ) || \
+      /* Lhs==void* and Rhs==fundamental */\
+      (\
+         ::boost::is_pointer< Lhs_noref >::value && \
+         ::boost::is_void< Lhs_noptr >::value && \
+         ::boost::is_fundamental< Rhs_nocv >::value\
+      ) || \
+      /* Rhs==void* and Lhs==fundamental */\
+      (\
+         ::boost::is_pointer< Rhs_noref >::value && \
+         ::boost::is_void< Rhs_noptr >::value && \
+         ::boost::is_fundamental< Lhs_nocv >::value\
+      ) || \
+      /* Lhs==pointer and Rhs==fundamental and Rhs!=integral */\
+      (\
+         ::boost::is_pointer< Lhs_noref >::value && \
+         ::boost::is_fundamental< Rhs_nocv >::value && \
+         (!  ::boost::is_integral< Rhs_noref >::value )\
+      ) || \
+      /* Rhs==pointer and Lhs==fundamental and Lhs!=integral */\
+      (\
+         ::boost::is_pointer< Rhs_noref >::value && \
+         ::boost::is_fundamental< Lhs_nocv >::value && \
+         (!  ::boost::is_integral< Lhs_noref >::value )\
+      )\
+   )
+
+
+#include <boost/type_traits/detail/has_binary_operator.hpp>
+
+#undef BOOST_TT_TRAIT_NAME
+#undef BOOST_TT_TRAIT_OP
+#undef BOOST_TT_FORBIDDEN_IF
+
+#endif
diff --git a/third_party/boost/boost/type_traits/has_plus_assign.hpp b/third_party/boost/boost/type_traits/has_plus_assign.hpp
new file mode 100644
index 0000000..5ef6f23
--- /dev/null
+++ b/third_party/boost/boost/type_traits/has_plus_assign.hpp
@@ -0,0 +1,66 @@
+//  (C) Copyright 2009-2011 Frederic Bron.
+//
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_HAS_PLUS_ASSIGN_HPP_INCLUDED
+#define BOOST_TT_HAS_PLUS_ASSIGN_HPP_INCLUDED
+
+#define BOOST_TT_TRAIT_NAME has_plus_assign
+#define BOOST_TT_TRAIT_OP +=
+#define BOOST_TT_FORBIDDEN_IF\
+   (\
+      /* Lhs==pointer and Rhs==pointer */\
+      (\
+         ::boost::is_pointer< Lhs_noref >::value && \
+         ::boost::is_pointer< Rhs_noref >::value\
+      ) || \
+      /* Lhs==void* and Rhs==fundamental */\
+      (\
+         ::boost::is_pointer< Lhs_noref >::value && \
+         ::boost::is_void< Lhs_noptr >::value && \
+         ::boost::is_fundamental< Rhs_nocv >::value\
+      ) || \
+      /* Rhs==void* and Lhs==fundamental */\
+      (\
+         ::boost::is_pointer< Rhs_noref >::value && \
+         ::boost::is_void< Rhs_noptr >::value && \
+         ::boost::is_fundamental< Lhs_nocv >::value\
+      ) || \
+      /* Lhs==pointer and Rhs==fundamental and Rhs!=integral */\
+      (\
+         ::boost::is_pointer< Lhs_noref >::value && \
+         ::boost::is_fundamental< Rhs_nocv >::value && \
+         (!  ::boost::is_integral< Rhs_noref >::value )\
+      ) || \
+      /* Rhs==pointer and Lhs==fundamental and Lhs!=bool */\
+      (\
+         ::boost::is_pointer< Rhs_noref >::value && \
+         ::boost::is_fundamental< Lhs_nocv >::value && \
+         (!  ::boost::is_same< Lhs_nocv, bool >::value )\
+      ) || \
+      /* (Lhs==fundamental or Lhs==pointer) and (Rhs==fundamental or Rhs==pointer) and (Lhs==const) */\
+      (\
+         (\
+            ::boost::is_fundamental< Lhs_nocv >::value || \
+            ::boost::is_pointer< Lhs_noref >::value\
+          ) && \
+         ( \
+            ::boost::is_fundamental< Rhs_nocv >::value || \
+            ::boost::is_pointer< Rhs_noref >::value\
+          ) && \
+         ::boost::is_const< Lhs_noref >::value\
+      )\
+      )
+
+
+#include <boost/type_traits/detail/has_binary_operator.hpp>
+
+#undef BOOST_TT_TRAIT_NAME
+#undef BOOST_TT_TRAIT_OP
+#undef BOOST_TT_FORBIDDEN_IF
+
+#endif
diff --git a/third_party/boost/boost/type_traits/has_trivial_assign.hpp b/third_party/boost/boost/type_traits/has_trivial_assign.hpp
new file mode 100644
index 0000000..a5e625d
--- /dev/null
+++ b/third_party/boost/boost/type_traits/has_trivial_assign.hpp
@@ -0,0 +1,51 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_HAS_TRIVIAL_ASSIGN_HPP_INCLUDED
+#define BOOST_TT_HAS_TRIVIAL_ASSIGN_HPP_INCLUDED
+
+#include <boost/type_traits/detail/config.hpp>
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+
+#if !defined(BOOST_HAS_TRIVIAL_ASSIGN) || defined(BOOST_MSVC) || defined(__GNUC__) || defined(BOOST_INTEL) || defined(__SUNPRO_CC) || defined(__clang)
+#include <boost/type_traits/is_pod.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_volatile.hpp>
+#include <boost/type_traits/is_assignable.hpp>
+#endif
+
+namespace boost {
+
+   template <typename T>
+   struct has_trivial_assign : public integral_constant < bool,
+#ifdef BOOST_HAS_TRIVIAL_ASSIGN
+      BOOST_HAS_TRIVIAL_ASSIGN(T)
+#else
+      ::boost::is_pod<T>::value && !::boost::is_const<T>::value && !::boost::is_volatile<T>::value
+#endif
+   > {};
+
+   template<> struct has_trivial_assign<void> : public false_type{};
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+   template<> struct has_trivial_assign<void const> : public false_type{};
+   template<> struct has_trivial_assign<void const volatile> : public false_type{};
+   template<> struct has_trivial_assign<void volatile> : public false_type{};
+#endif
+   template <class T> struct has_trivial_assign<T volatile> : public false_type{};
+   template <class T> struct has_trivial_assign<T&> : public false_type{};
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+   template <class T> struct has_trivial_assign<T&&> : public false_type{};
+#endif
+   // Arrays are not explictly assignable:
+   template <typename T, std::size_t N> struct has_trivial_assign<T[N]> : public false_type{};
+   template <typename T> struct has_trivial_assign<T[]> : public false_type{};
+
+} // namespace boost
+
+#endif // BOOST_TT_HAS_TRIVIAL_ASSIGN_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/has_trivial_constructor.hpp b/third_party/boost/boost/type_traits/has_trivial_constructor.hpp
new file mode 100644
index 0000000..06c137d
--- /dev/null
+++ b/third_party/boost/boost/type_traits/has_trivial_constructor.hpp
@@ -0,0 +1,57 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_HAS_TRIVIAL_CONSTRUCTOR_HPP_INCLUDED
+#define BOOST_TT_HAS_TRIVIAL_CONSTRUCTOR_HPP_INCLUDED
+
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/is_pod.hpp>
+#include <boost/type_traits/is_default_constructible.hpp>
+
+#ifdef BOOST_HAS_TRIVIAL_CONSTRUCTOR
+#ifdef BOOST_HAS_SGI_TYPE_TRAITS
+#include <boost/type_traits/is_same.hpp>
+#elif defined(__GNUC__) || defined(__SUNPRO_CC)
+#include <boost/type_traits/is_volatile.hpp>
+#ifdef BOOST_INTEL
+#include <boost/type_traits/is_pod.hpp>
+#endif
+#endif
+#endif
+
+
+#if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || defined(BOOST_CLANG) || (defined(__SUNPRO_CC) && defined(BOOST_HAS_TRIVIAL_CONSTRUCTOR))
+#include <boost/type_traits/is_default_constructible.hpp>
+#define BOOST_TT_TRIVIAL_CONSTRUCT_FIX && is_default_constructible<T>::value
+#else
+//
+// Mot all compilers, particularly older GCC versions can handle the fix above.
+#define BOOST_TT_TRIVIAL_CONSTRUCT_FIX
+#endif
+
+namespace boost {
+
+template <typename T> struct has_trivial_constructor
+#ifdef BOOST_HAS_TRIVIAL_CONSTRUCTOR
+   : public integral_constant <bool, ((::boost::is_pod<T>::value || BOOST_HAS_TRIVIAL_CONSTRUCTOR(T)) BOOST_TT_TRIVIAL_CONSTRUCT_FIX)>{};
+#else
+   : public integral_constant <bool, ::boost::is_pod<T>::value>{};
+#endif
+
+template <> struct has_trivial_constructor<void> : public boost::false_type{};
+template <> struct has_trivial_constructor<void const> : public boost::false_type{};
+template <> struct has_trivial_constructor<void const volatile> : public boost::false_type{};
+template <> struct has_trivial_constructor<void volatile> : public boost::false_type{};
+
+template <class T> struct has_trivial_default_constructor : public has_trivial_constructor<T> {};
+
+#undef BOOST_TT_TRIVIAL_CONSTRUCT_FIX
+
+} // namespace boost
+
+#endif // BOOST_TT_HAS_TRIVIAL_CONSTRUCTOR_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/has_trivial_copy.hpp b/third_party/boost/boost/type_traits/has_trivial_copy.hpp
new file mode 100644
index 0000000..bc55de3
--- /dev/null
+++ b/third_party/boost/boost/type_traits/has_trivial_copy.hpp
@@ -0,0 +1,62 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_HAS_TRIVIAL_COPY_HPP_INCLUDED
+#define BOOST_TT_HAS_TRIVIAL_COPY_HPP_INCLUDED
+
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/is_pod.hpp>
+#include <boost/type_traits/is_reference.hpp>
+
+#if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)) || defined(BOOST_CLANG) || (defined(__SUNPRO_CC) && defined(BOOST_HAS_TRIVIAL_COPY))
+#include <boost/type_traits/is_copy_constructible.hpp>
+#define BOOST_TT_TRIVIAL_CONSTRUCT_FIX && is_copy_constructible<T>::value
+#else
+#define BOOST_TT_TRIVIAL_CONSTRUCT_FIX
+#endif
+
+#ifdef BOOST_INTEL
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_lvalue_reference.hpp>
+#endif
+
+namespace boost {
+
+template <typename T> struct has_trivial_copy
+: public integral_constant<bool,
+#ifdef BOOST_HAS_TRIVIAL_COPY
+   BOOST_HAS_TRIVIAL_COPY(T) BOOST_TT_TRIVIAL_CONSTRUCT_FIX
+#else
+   ::boost::is_pod<T>::value
+#endif
+>{};
+// Arrays are not explicitly copyable:
+template <typename T, std::size_t N> struct has_trivial_copy<T[N]> : public false_type{};
+template <typename T> struct has_trivial_copy<T[]> : public false_type{};
+// Are volatile types ever trivial?  We don't really know, so assume not:
+template <typename T> struct has_trivial_copy<T volatile> : public false_type{};
+
+template <> struct has_trivial_copy<void> : public false_type{};
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template <> struct has_trivial_copy<void const> : public false_type{};
+template <> struct has_trivial_copy<void volatile> : public false_type{};
+template <> struct has_trivial_copy<void const volatile> : public false_type{};
+#endif
+
+template <class T> struct has_trivial_copy<T&> : public false_type{};
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+template <class T> struct has_trivial_copy<T&&> : public false_type{};
+#endif
+
+template <class T> struct has_trivial_copy_constructor : public has_trivial_copy<T>{};
+
+#undef BOOST_TT_TRIVIAL_CONSTRUCT_FIX
+
+} // namespace boost
+
+#endif // BOOST_TT_HAS_TRIVIAL_COPY_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/has_trivial_destructor.hpp b/third_party/boost/boost/type_traits/has_trivial_destructor.hpp
new file mode 100644
index 0000000..763283d
--- /dev/null
+++ b/third_party/boost/boost/type_traits/has_trivial_destructor.hpp
@@ -0,0 +1,48 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_HAS_TRIVIAL_DESTRUCTOR_HPP_INCLUDED
+#define BOOST_TT_HAS_TRIVIAL_DESTRUCTOR_HPP_INCLUDED
+
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+
+#ifdef BOOST_HAS_TRIVIAL_DESTRUCTOR
+
+#if defined(BOOST_INTEL) || defined(BOOST_MSVC)
+#include <boost/type_traits/is_pod.hpp>
+#endif
+#ifdef BOOST_HAS_SGI_TYPE_TRAITS
+#include <boost/type_traits/is_same.hpp>
+#endif
+
+#if defined(__GNUC__) || defined(__clang) || defined(__SUNPRO_CC)
+#include <boost/type_traits/is_destructible.hpp>
+#endif
+
+namespace boost {
+
+template <typename T> struct has_trivial_destructor : public integral_constant<bool, BOOST_HAS_TRIVIAL_DESTRUCTOR(T)>{};
+#else
+#include <boost/type_traits/is_pod.hpp>
+
+namespace boost{
+
+template <typename T> struct has_trivial_destructor : public integral_constant<bool, ::boost::is_pod<T>::value>{};
+#endif
+
+template <> struct has_trivial_destructor<void> : public false_type{};
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template <> struct has_trivial_destructor<void const> : public false_type{};
+template <> struct has_trivial_destructor<void const volatile> : public false_type{};
+template <> struct has_trivial_destructor<void volatile> : public false_type{};
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_HAS_TRIVIAL_DESTRUCTOR_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/has_trivial_move_assign.hpp b/third_party/boost/boost/type_traits/has_trivial_move_assign.hpp
new file mode 100644
index 0000000..f7bb198
--- /dev/null
+++ b/third_party/boost/boost/type_traits/has_trivial_move_assign.hpp
@@ -0,0 +1,72 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  (C) Copyright Eric Friedman 2002-2003.
+//  (C) Copyright Antony Polukhin 2013.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_HAS_TRIVIAL_MOVE_ASSIGN_HPP_INCLUDED
+#define BOOST_TT_HAS_TRIVIAL_MOVE_ASSIGN_HPP_INCLUDED
+
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+
+#if !defined(BOOST_HAS_TRIVIAL_MOVE_ASSIGN) || defined(BOOST_MSVC) || defined(BOOST_INTEL)
+#include <boost/type_traits/is_pod.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_volatile.hpp>
+#ifdef BOOST_MSVC
+#include <boost/type_traits/is_reference.hpp>
+#endif
+#endif
+
+#if defined(__GNUC__) || defined(__clang)
+#include <boost/type_traits/is_assignable.hpp>
+#include <boost/type_traits/is_volatile.hpp>
+#endif
+
+#ifdef __SUNPRO_CC
+#include <boost/type_traits/is_assignable.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#if __cplusplus >= 201103
+#define SOLARIS_EXTRA_CHECK && is_assignable<typename remove_const<T>::type&, typename remove_const<T>::type&&>::value
+#endif
+#endif
+
+#ifndef SOLARIS_EXTRA_CHECK
+#define SOLARIS_EXTRA_CHECK
+#endif
+
+namespace boost{
+
+template <typename T>
+struct has_trivial_move_assign : public integral_constant<bool,
+#ifdef BOOST_HAS_TRIVIAL_MOVE_ASSIGN
+   BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T)
+#else
+   ::boost::is_pod<T>::value && !::boost::is_const<T>::value && !::boost::is_volatile<T>::value SOLARIS_EXTRA_CHECK
+#endif
+   > {};
+
+template <> struct has_trivial_move_assign<void> : public false_type{};
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template <> struct has_trivial_move_assign<void const> : public false_type{};
+template <> struct has_trivial_move_assign<void const volatile> : public false_type{};
+template <> struct has_trivial_move_assign<void volatile> : public false_type{};
+#endif
+template <class T> struct has_trivial_move_assign<T&> : public false_type{};
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+template <class T> struct has_trivial_move_assign<T&&> : public false_type{};
+#endif
+// Array types are not assignable:
+template <class T, std::size_t N> struct has_trivial_move_assign<T[N]> : public false_type{};
+template <class T> struct has_trivial_move_assign<T[]> : public false_type{};
+
+} // namespace boost
+
+#undef SOLARIS_EXTRA_CHECK
+
+#endif // BOOST_TT_HAS_TRIVIAL_MOVE_ASSIGN_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/has_trivial_move_constructor.hpp b/third_party/boost/boost/type_traits/has_trivial_move_constructor.hpp
new file mode 100644
index 0000000..a2d76b5
--- /dev/null
+++ b/third_party/boost/boost/type_traits/has_trivial_move_constructor.hpp
@@ -0,0 +1,77 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  (C) Copyright Eric Friedman 2002-2003.
+//  (C) Copyright Antony Polukhin 2013.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_HAS_TRIVIAL_MOVE_CONSTRUCTOR_HPP_INCLUDED
+#define BOOST_TT_HAS_TRIVIAL_MOVE_CONSTRUCTOR_HPP_INCLUDED
+
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+
+#ifdef BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR
+
+#if defined(BOOST_MSVC) || defined(BOOST_INTEL)
+#include <boost/type_traits/is_pod.hpp>
+#include <boost/type_traits/is_volatile.hpp>
+#endif
+
+#if defined(__GNUC__) || defined(__clang)
+#include <boost/type_traits/is_constructible.hpp>
+#include <boost/type_traits/is_volatile.hpp>
+#endif
+
+
+namespace boost {
+
+template <typename T> struct has_trivial_move_constructor : public integral_constant<bool, BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T)>{};
+
+#else
+
+#ifdef __SUNPRO_CC
+#include <boost/type_traits/is_constructible.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#if __cplusplus >= 201103
+#define SOLARIS_EXTRA_CHECK && is_constructible<typename remove_const<T>::type, typename remove_const<T>::type&&>::value
+#endif
+#endif
+
+#ifndef SOLARIS_EXTRA_CHECK
+#define SOLARIS_EXTRA_CHECK
+#endif
+
+#include <boost/type_traits/is_pod.hpp>
+#include <boost/type_traits/is_volatile.hpp>
+
+namespace boost {
+
+template <typename T> struct has_trivial_move_constructor
+   : public integral_constant<bool, ::boost::is_pod<T>::value && !::boost::is_volatile<T>::value SOLARIS_EXTRA_CHECK>{};
+
+#undef SOLARIS_EXTRA_CHECK
+
+#endif
+
+template <> struct has_trivial_move_constructor<void> : public false_type{};
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template <> struct has_trivial_move_constructor<void const> : public false_type{};
+template <> struct has_trivial_move_constructor<void volatile> : public false_type{};
+template <> struct has_trivial_move_constructor<void const volatile> : public false_type{};
+#endif
+// What should we do with reference types??? The standard seems to suggest these are trivial, even if the thing they reference is not:
+template <class T> struct has_trivial_move_constructor<T&> : public true_type{};
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+template <class T> struct has_trivial_move_constructor<T&&> : public true_type{};
+#endif
+// Arrays can not be explicitly copied:
+template <class T, std::size_t N> struct has_trivial_move_constructor<T[N]> : public false_type{};
+template <class T> struct has_trivial_move_constructor<T[]> : public false_type{};
+
+} // namespace boost
+
+#endif // BOOST_TT_HAS_TRIVIAL_MOVE_CONSTRUCTOR_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/integral_constant.hpp b/third_party/boost/boost/type_traits/integral_constant.hpp
new file mode 100644
index 0000000..5b66a8a
--- /dev/null
+++ b/third_party/boost/boost/type_traits/integral_constant.hpp
@@ -0,0 +1,106 @@
+//  (C) Copyright John Maddock 2015.
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP
+#define BOOST_TYPE_TRAITS_INTEGRAL_CONSTANT_HPP
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+#if (BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400)) \
+   || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) \
+   || BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840)) \
+   || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) \
+   || BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, BOOST_TESTED_AT(810)) )
+
+
+namespace boost{
+   namespace mpl
+   {
+      template <bool B> struct bool_;
+      template <class I, I val> struct integral_c;
+      struct integral_c_tag;
+   }
+}
+
+#else
+
+namespace mpl_{
+
+   template <bool B> struct bool_;
+   template <class I, I val> struct integral_c;
+   struct integral_c_tag;
+}
+
+namespace boost
+{
+   namespace mpl
+   {
+      using ::mpl_::bool_;
+      using ::mpl_::integral_c;
+      using ::mpl_::integral_c_tag;
+   }
+}
+
+#endif
+
+namespace boost{
+
+   template <class T, T val>
+   struct integral_constant
+   {
+      typedef mpl::integral_c_tag tag;
+      typedef T value_type;
+      typedef integral_constant<T, val> type;
+      static const T value = val;
+      //
+      // This helper function is just to disable type-punning
+      // warnings from GCC:
+      //
+      template <class U>
+      static U& dereference(U* p) { return *p; }
+
+      operator const mpl::integral_c<T, val>& ()const
+      {
+         static const char data[sizeof(long)] = { 0 };
+         return dereference(reinterpret_cast<const mpl::integral_c<T, val>*>(&data));
+      }
+      BOOST_CONSTEXPR operator T()const { return val; }
+   };
+
+   template <class T, T val>
+   T const integral_constant<T, val>::value;
+
+   template <bool val>
+   struct integral_constant<bool, val>
+   {
+      typedef mpl::integral_c_tag tag;
+      typedef bool value_type;
+      typedef integral_constant<bool, val> type;
+      static const bool value = val;
+      //
+      // This helper function is just to disable type-punning
+      // warnings from GCC:
+      //
+      template <class T>
+      static T& dereference(T* p) { return *p; }
+
+      operator const mpl::bool_<val>& ()const
+      {
+         static const char data = 0;
+         return dereference(reinterpret_cast<const mpl::bool_<val>*>(&data));
+      }
+      BOOST_CONSTEXPR operator bool()const { return val; }
+   };
+
+   template <bool val>
+   bool const integral_constant<bool, val>::value;
+
+   typedef integral_constant<bool, true> true_type;
+   typedef integral_constant<bool, false> false_type;
+
+}
+
+#endif
diff --git a/third_party/boost/boost/type_traits/integral_promotion.hpp b/third_party/boost/boost/type_traits/integral_promotion.hpp
new file mode 100644
index 0000000..9a542b7
--- /dev/null
+++ b/third_party/boost/boost/type_traits/integral_promotion.hpp
@@ -0,0 +1,180 @@
+// Copyright 2005 Alexander Nasonov.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef FILE_boost_type_traits_integral_promotion_hpp_INCLUDED
+#define FILE_boost_type_traits_integral_promotion_hpp_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_enum.hpp>
+#include <boost/type_traits/is_volatile.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+
+namespace boost {
+
+namespace type_traits { namespace detail {
+
+// 4.5/2
+template <class T> struct need_promotion : public boost::is_enum<T> {};
+
+// 4.5/1
+template<> struct need_promotion<char              > : public true_type {};
+template<> struct need_promotion<signed char       > : public true_type {};
+template<> struct need_promotion<unsigned char     > : public true_type {};
+template<> struct need_promotion<signed short int  > : public true_type {};
+template<> struct need_promotion<unsigned short int> : public true_type {};
+
+
+// Specializations for non-standard types.
+// Type is promoted if it's smaller then int.
+
+#define BOOST_TT_AUX_PROMOTE_NONSTANDARD_TYPE(T) \
+    template<> struct need_promotion<T>          \
+        : public integral_constant<bool, (sizeof(T) < sizeof(int))> {};
+
+// Same set of integral types as in boost/type_traits/is_integral.hpp.
+// Please, keep in sync.
+#if (defined(BOOST_INTEL_CXX_VERSION) && defined(_MSC_VER) && (BOOST_INTEL_CXX_VERSION <= 600)) \
+    || (defined(__BORLANDC__) && (__BORLANDC__ == 0x600) && (_MSC_VER < 1300))
+// TODO: common macro for this #if. Or better yet, PP SEQ of non-standard types.
+BOOST_TT_AUX_PROMOTE_NONSTANDARD_TYPE(__int8          )
+BOOST_TT_AUX_PROMOTE_NONSTANDARD_TYPE(unsigned __int8 )
+BOOST_TT_AUX_PROMOTE_NONSTANDARD_TYPE(__int16         )
+BOOST_TT_AUX_PROMOTE_NONSTANDARD_TYPE(unsigned __int16)
+BOOST_TT_AUX_PROMOTE_NONSTANDARD_TYPE(__int32         )
+BOOST_TT_AUX_PROMOTE_NONSTANDARD_TYPE(unsigned __int32)
+#ifdef __BORLANDC__
+BOOST_TT_AUX_PROMOTE_NONSTANDARD_TYPE(unsigned __int64)
+BOOST_TT_AUX_PROMOTE_NONSTANDARD_TYPE(         __int64)
+#endif
+#endif
+
+#if defined(BOOST_HAS_LONG_LONG)
+BOOST_TT_AUX_PROMOTE_NONSTANDARD_TYPE(boost::ulong_long_type)
+BOOST_TT_AUX_PROMOTE_NONSTANDARD_TYPE(boost::long_long_type )
+#elif defined(BOOST_HAS_MS_INT64)
+BOOST_TT_AUX_PROMOTE_NONSTANDARD_TYPE(unsigned __int64)
+BOOST_TT_AUX_PROMOTE_NONSTANDARD_TYPE(         __int64)
+#endif
+
+#undef BOOST_TT_AUX_PROMOTE_NONSTANDARD_TYPE
+
+
+#ifndef BOOST_NO_INTRINSIC_WCHAR_T
+// 4.5/2
+template<> struct need_promotion<wchar_t> : public true_type {};
+#endif
+
+// 4.5/3 (integral bit-field) is not supported.
+
+// 4.5/4
+template<> struct need_promotion<bool> : public true_type {};
+
+
+// Get promoted type by index and cv qualifiers.
+
+template<int Index, int IsConst, int IsVolatile> struct promote_from_index;
+
+#define BOOST_TT_AUX_PROMOTE_FROM_INDEX(N,T)                                   \
+    template<> struct promote_from_index<N,0,0> { typedef T type; };           \
+    template<> struct promote_from_index<N,0,1> { typedef T volatile type; };  \
+    template<> struct promote_from_index<N,1,0> { typedef T const type; };     \
+    template<> struct promote_from_index<N,1,1> { typedef T const volatile type; };
+
+
+BOOST_TT_AUX_PROMOTE_FROM_INDEX(1, int          )
+BOOST_TT_AUX_PROMOTE_FROM_INDEX(2, unsigned int )
+BOOST_TT_AUX_PROMOTE_FROM_INDEX(3, long         )
+BOOST_TT_AUX_PROMOTE_FROM_INDEX(4, unsigned long)
+
+
+// WARNING: integral promotions to non-standard types
+// long long and __int64 are not defined by the standard.
+// Additional specialisations and overloads shouldn't
+// introduce ambiguity, though.
+
+#if defined(BOOST_HAS_LONG_LONG)
+BOOST_TT_AUX_PROMOTE_FROM_INDEX(5, boost::long_long_type )
+BOOST_TT_AUX_PROMOTE_FROM_INDEX(6, boost::ulong_long_type)
+#elif defined(BOOST_HAS_MS_INT64)
+BOOST_TT_AUX_PROMOTE_FROM_INDEX(7, __int64         )
+BOOST_TT_AUX_PROMOTE_FROM_INDEX(8, unsigned __int64)
+#endif
+
+#undef BOOST_TT_AUX_PROMOTE_FROM_INDEX
+
+
+// Define BOOST_TT_AUX_PROMOTED_INDEX_TESTER:
+#if !defined(BOOST_MSVC)
+
+template<int N>
+struct sized_type_for_promotion
+{
+    typedef char (&type)[N];
+};
+
+#define BOOST_TT_AUX_PROMOTED_INDEX_TESTER(I,T) \
+    sized_type_for_promotion<I>::type promoted_index_tester(T);
+
+#else
+
+#define BOOST_TT_AUX_PROMOTED_INDEX_TESTER(I,T) \
+    char (&promoted_index_tester(T))[I];
+
+#endif
+
+BOOST_TT_AUX_PROMOTED_INDEX_TESTER(1, int          )
+BOOST_TT_AUX_PROMOTED_INDEX_TESTER(2, unsigned int )
+BOOST_TT_AUX_PROMOTED_INDEX_TESTER(3, long         )
+BOOST_TT_AUX_PROMOTED_INDEX_TESTER(4, unsigned long)
+
+#if defined(BOOST_HAS_LONG_LONG)
+BOOST_TT_AUX_PROMOTED_INDEX_TESTER(5, boost::long_long_type )
+BOOST_TT_AUX_PROMOTED_INDEX_TESTER(6, boost::ulong_long_type)
+#elif defined(BOOST_HAS_MS_INT64)
+BOOST_TT_AUX_PROMOTED_INDEX_TESTER(7, __int64         )
+BOOST_TT_AUX_PROMOTED_INDEX_TESTER(8, unsigned __int64)
+#endif
+
+#undef BOOST_TT_AUX_PROMOTED_INDEX_TESTER
+
+
+// Get an index of promoted type for type T.
+// Precondition: need_promotion<T>
+template<class T>
+struct promoted_index
+{
+    static T testee; // undefined
+    BOOST_STATIC_CONSTANT(int, value = sizeof(promoted_index_tester(+testee)) );
+    // Unary plus promotes testee                    LOOK HERE ---> ^
+};
+
+template<class T>
+struct integral_promotion_impl
+{
+    typedef BOOST_DEDUCED_TYPENAME promote_from_index<
+        (boost::type_traits::detail::promoted_index<T>::value)
+      , (boost::is_const<T>::value)
+      , (boost::is_volatile<T>::value)
+      >::type type;
+};
+
+template<class T, bool b> struct integral_promotion { typedef T type; };
+template<class T> struct integral_promotion<T, true> : public integral_promotion_impl<T>{};
+
+} }
+
+template <class T> struct integral_promotion
+{
+private:
+   typedef boost::type_traits::detail::need_promotion<typename remove_cv<T>::type> tag_type;
+public:
+   typedef typename boost::type_traits::detail::integral_promotion<T, tag_type::value>::type type;
+};
+
+}
+
+#endif // #ifndef FILE_boost_type_traits_integral_promotion_hpp_INCLUDED
diff --git a/third_party/boost/boost/type_traits/intrinsics.hpp b/third_party/boost/boost/type_traits/intrinsics.hpp
new file mode 100644
index 0000000..610f7f9
--- /dev/null
+++ b/third_party/boost/boost/type_traits/intrinsics.hpp
@@ -0,0 +1,379 @@
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_INTRINSICS_HPP_INCLUDED
+#define BOOST_TT_INTRINSICS_HPP_INCLUDED
+
+#ifndef BOOST_TT_DISABLE_INTRINSICS
+
+#include <boost/config.hpp>
+
+#ifndef BOOST_TT_CONFIG_HPP_INCLUDED
+#include <boost/type_traits/detail/config.hpp>
+#endif
+
+//
+// Helper macros for builtin compiler support.
+// If your compiler has builtin support for any of the following
+// traits concepts, then redefine the appropriate macros to pick
+// up on the compiler support:
+//
+// (these should largely ignore cv-qualifiers)
+// BOOST_IS_UNION(T) should evaluate to true if T is a union type
+// BOOST_IS_POD(T) should evaluate to true if T is a POD type
+// BOOST_IS_EMPTY(T) should evaluate to true if T is an empty class type (and not a union)
+// BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) should evaluate to true if "T x;" has no effect
+// BOOST_HAS_TRIVIAL_COPY(T) should evaluate to true if T(t) <==> memcpy
+// BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) should evaluate to true if T(boost::move(t)) <==> memcpy
+// BOOST_HAS_TRIVIAL_ASSIGN(T) should evaluate to true if t = u <==> memcpy
+// BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) should evaluate to true if t = boost::move(u) <==> memcpy
+// BOOST_HAS_TRIVIAL_DESTRUCTOR(T) should evaluate to true if ~T() has no effect
+// BOOST_HAS_NOTHROW_CONSTRUCTOR(T) should evaluate to true if "T x;" can not throw
+// BOOST_HAS_NOTHROW_COPY(T) should evaluate to true if T(t) can not throw
+// BOOST_HAS_NOTHROW_ASSIGN(T) should evaluate to true if t = u can not throw
+// BOOST_HAS_VIRTUAL_DESTRUCTOR(T) should evaluate to true T has a virtual destructor
+// BOOST_IS_NOTHROW_MOVE_CONSTRUCT(T) should evaluate to true if T has a non-throwing move constructor.
+// BOOST_IS_NOTHROW_MOVE_ASSIGN(T) should evaluate to true if T has a non-throwing move assignment operator.
+//
+// The following can also be defined: when detected our implementation is greatly simplified.
+//
+// BOOST_IS_ABSTRACT(T) true if T is an abstract type
+// BOOST_IS_BASE_OF(T,U) true if T is a base class of U
+// BOOST_IS_CLASS(T) true if T is a class type (and not a union)
+// BOOST_IS_CONVERTIBLE(T,U) true if T is convertible to U
+// BOOST_IS_ENUM(T) true is T is an enum
+// BOOST_IS_POLYMORPHIC(T) true if T is a polymorphic type
+// BOOST_ALIGNMENT_OF(T) should evaluate to the alignment requirements of type T.
+//
+// define BOOST_TT_DISABLE_INTRINSICS to prevent any intrinsics being used (mostly used when testing)
+//
+
+#ifdef BOOST_HAS_SGI_TYPE_TRAITS
+    // Hook into SGI's __type_traits class, this will pick up user supplied
+    // specializations as well as SGI - compiler supplied specializations.
+#   include <boost/type_traits/is_same.hpp>
+#   ifdef __NetBSD__
+      // There are two different versions of type_traits.h on NetBSD on Spark
+      // use an implicit include via algorithm instead, to make sure we get
+      // the same version as the std lib:
+#     include <algorithm>
+#   else
+#    include <type_traits.h>
+#   endif
+#   define BOOST_IS_POD(T) ::boost::is_same< typename ::__type_traits<T>::is_POD_type, ::__true_type>::value
+#   define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) ::boost::is_same< typename ::__type_traits<T>::has_trivial_default_constructor, ::__true_type>::value
+#   define BOOST_HAS_TRIVIAL_COPY(T) ::boost::is_same< typename ::__type_traits<T>::has_trivial_copy_constructor, ::__true_type>::value
+#   define BOOST_HAS_TRIVIAL_ASSIGN(T) ::boost::is_same< typename ::__type_traits<T>::has_trivial_assignment_operator, ::__true_type>::value
+#   define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) ::boost::is_same< typename ::__type_traits<T>::has_trivial_destructor, ::__true_type>::value
+
+#   ifdef __sgi
+#      define BOOST_HAS_TYPE_TRAITS_INTRINSICS
+#   endif
+#endif
+
+#if defined(__MSL_CPP__) && (__MSL_CPP__ >= 0x8000)
+    // Metrowerks compiler is acquiring intrinsic type traits support
+    // post version 8.  We hook into the published interface to pick up
+    // user defined specializations as well as compiler intrinsics as
+    // and when they become available:
+#   include <msl_utility>
+#   define BOOST_IS_UNION(T) BOOST_STD_EXTENSION_NAMESPACE::is_union<T>::value
+#   define BOOST_IS_POD(T) BOOST_STD_EXTENSION_NAMESPACE::is_POD<T>::value
+#   define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_default_ctor<T>::value
+#   define BOOST_HAS_TRIVIAL_COPY(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_copy_ctor<T>::value
+#   define BOOST_HAS_TRIVIAL_ASSIGN(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_assignment<T>::value
+#   define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) BOOST_STD_EXTENSION_NAMESPACE::has_trivial_dtor<T>::value
+#   define BOOST_HAS_TYPE_TRAITS_INTRINSICS
+#endif
+
+#if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\
+         || (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500))
+//
+// Note that even though these intrinsics rely on other type traits classes
+// we do not #include those here as it produces cyclic dependencies and
+// can cause the intrinsics to not even be used at all!
+//
+#   define BOOST_IS_UNION(T) __is_union(T)
+#   define BOOST_IS_POD(T) (__is_pod(T) && __has_trivial_constructor(T))
+#   define BOOST_IS_EMPTY(T) __is_empty(T)
+#   define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T)
+#   define BOOST_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) || ( ::boost::is_pod<T>::value && ! ::boost::is_const<T>::value && !::boost::is_volatile<T>::value))
+#   define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) || ::boost::is_pod<T>::value)
+#   define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) || ::boost::has_trivial_constructor<T>::value)
+#if !defined(BOOST_INTEL)
+#   define BOOST_HAS_NOTHROW_COPY(T) ((__has_nothrow_copy(T) || ::boost::has_trivial_copy<T>::value) && !is_array<T>::value)
+#   define BOOST_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T) || ::boost::is_pod<T>::value)
+#elif (_MSC_VER >= 1900)
+#   define BOOST_HAS_NOTHROW_COPY(T) ((__is_nothrow_constructible(T, typename add_lvalue_reference<typename add_const<T>::type>::type)) && !is_array<T>::value)
+#   define BOOST_HAS_TRIVIAL_COPY(T) (__is_trivially_constructible(T, typename add_lvalue_reference<typename add_const<T>::type>::type))
+#endif
+#   define BOOST_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T) || ::boost::has_trivial_assign<T>::value)
+#   define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
+
+#   define BOOST_IS_ABSTRACT(T) __is_abstract(T)
+#   define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same<T,U>::value)
+#   define BOOST_IS_CLASS(T) __is_class(T)
+#   define BOOST_IS_CONVERTIBLE(T,U) ((__is_convertible_to(T,U) || (is_same<T,U>::value && !is_function<U>::value)) && !__is_abstract(U))
+#   define BOOST_IS_ENUM(T) __is_enum(T)
+//  This one fails if the default alignment has been changed with /Zp:
+//  #   define BOOST_ALIGNMENT_OF(T) __alignof(T)
+
+#   if defined(_MSC_VER) && (_MSC_VER >= 1700)
+#       define BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) ((__has_trivial_move_constructor(T) || boost::is_pod<T>::value) && ! ::boost::is_volatile<T>::value && ! ::boost::is_reference<T>::value)
+#       define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) ((__has_trivial_move_assign(T) || boost::is_pod<T>::value) && ! ::boost::is_const<T>::value && !::boost::is_volatile<T>::value && ! ::boost::is_reference<T>::value)
+#   endif
+#ifndef BOOST_NO_CXX11_FINAL
+//  This one doesn't quite always do the right thing on older VC++ versions
+//  we really need it when the final keyword is supporyted though:
+#   define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T)
+#endif
+#if _MSC_FULL_VER >= 180020827
+#   define BOOST_IS_NOTHROW_MOVE_ASSIGN(T) (__is_nothrow_assignable(T&, T&&))
+#   define BOOST_IS_NOTHROW_MOVE_CONSTRUCT(T) (__is_nothrow_constructible(T, T&&))
+#endif
+#   define BOOST_HAS_TYPE_TRAITS_INTRINSICS
+#endif
+
+#if defined(__DMC__) && (__DMC__ >= 0x848)
+// For Digital Mars C++, www.digitalmars.com
+#   define BOOST_IS_UNION(T) (__typeinfo(T) & 0x400)
+#   define BOOST_IS_POD(T) (__typeinfo(T) & 0x800)
+#   define BOOST_IS_EMPTY(T) (__typeinfo(T) & 0x1000)
+#   define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) (__typeinfo(T) & 0x10)
+#   define BOOST_HAS_TRIVIAL_COPY(T) (__typeinfo(T) & 0x20)
+#   define BOOST_HAS_TRIVIAL_ASSIGN(T) (__typeinfo(T) & 0x40)
+#   define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__typeinfo(T) & 0x8)
+#   define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__typeinfo(T) & 0x80)
+#   define BOOST_HAS_NOTHROW_COPY(T) (__typeinfo(T) & 0x100)
+#   define BOOST_HAS_NOTHROW_ASSIGN(T) (__typeinfo(T) & 0x200)
+#   define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) (__typeinfo(T) & 0x4)
+#   define BOOST_HAS_TYPE_TRAITS_INTRINSICS
+#endif
+
+#if defined(BOOST_CLANG) && defined(__has_feature) && !defined(__CUDACC__)
+//
+// Note that these intrinsics are disabled for the CUDA meta-compiler as it appears
+// to not support them, even though the underlying clang compiler does so.
+// This is a rubbish fix as it basically stops type traits from working correctly,
+// but maybe the best we can do for now.  See https://svn.boost.org/trac/boost/ticket/10694
+//
+//
+// Note that even though these intrinsics rely on other type traits classes
+// we do not #include those here as it produces cyclic dependencies and
+// can cause the intrinsics to not even be used at all!
+//
+#   include <cstddef>
+
+#   if __has_feature(is_union)
+#     define BOOST_IS_UNION(T) __is_union(T)
+#   endif
+#   if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_pod)
+#     define BOOST_IS_POD(T) __is_pod(T)
+#   endif
+#   if (!defined(__GLIBCXX__) || (__GLIBCXX__ >= 20080306 && __GLIBCXX__ != 20080519)) && __has_feature(is_empty)
+#     define BOOST_IS_EMPTY(T) __is_empty(T)
+#   endif
+#   if __has_feature(has_trivial_constructor)
+#     define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T)
+#   endif
+#   if __has_feature(has_trivial_copy)
+#     define BOOST_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T) && !is_reference<T>::value)
+#   endif
+#   if __has_feature(has_trivial_assign)
+#     define BOOST_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) && !is_volatile<T>::value && is_assignable<T&, const T&>::value)
+#   endif
+#   if __has_feature(has_trivial_destructor)
+#     define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T)  && is_destructible<T>::value)
+#   endif
+#   if __has_feature(has_nothrow_constructor)
+#     define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) && is_default_constructible<T>::value)
+#   endif
+#   if __has_feature(has_nothrow_copy)
+#     define BOOST_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T) && !is_volatile<T>::value && !is_reference<T>::value && is_copy_constructible<T>::value)
+#   endif
+#   if __has_feature(has_nothrow_assign)
+#     define BOOST_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T) && !is_volatile<T>::value && is_assignable<T&, const T&>::value)
+#   endif
+#   if __has_feature(has_virtual_destructor)
+#     define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
+#   endif
+#   if __has_feature(is_abstract)
+#     define BOOST_IS_ABSTRACT(T) __is_abstract(T)
+#   endif
+#   if __has_feature(is_base_of)
+#     define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same<T,U>::value)
+#   endif
+#   if __has_feature(is_class)
+#     define BOOST_IS_CLASS(T) __is_class(T)
+#   endif
+#   if __has_feature(is_convertible_to)
+#     define BOOST_IS_CONVERTIBLE(T,U) __is_convertible_to(T,U)
+#   endif
+#   if __has_feature(is_enum)
+#     define BOOST_IS_ENUM(T) __is_enum(T)
+#   endif
+#   if __has_feature(is_polymorphic)
+#     define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T)
+#   endif
+#   if __has_feature(has_trivial_move_constructor)
+#     define BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) (__has_trivial_move_constructor(T)  && is_constructible<T, T&&>::value && !::boost::is_volatile<T>::value)
+#   endif
+#   if __has_feature(has_trivial_move_assign)
+#     define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) (__has_trivial_move_assign(T) && is_assignable<T&, T&&>::value && !::boost::is_volatile<T>::value)
+#   endif
+#   if (!defined(unix) && !defined(__unix__)) || defined(__LP64__) || !defined(__GNUC__)
+// GCC sometimes lies about alignment requirements
+// of type double on 32-bit unix platforms, use the
+// old implementation instead in that case:
+#     define BOOST_ALIGNMENT_OF(T) __alignof(T)
+#   endif
+#   if __has_feature(is_final)
+#     define BOOST_IS_FINAL(T) __is_final(T)
+#   endif
+
+#   define BOOST_HAS_TYPE_TRAITS_INTRINSICS
+#endif
+
+#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) && !defined(__GCCXML__))) && !defined(BOOST_CLANG)
+//
+// Note that even though these intrinsics rely on other type traits classes
+// we do not #include those here as it produces cyclic dependencies and
+// can cause the intrinsics to not even be used at all!
+//
+
+#ifdef BOOST_INTEL
+#  define BOOST_INTEL_TT_OPTS || is_pod<T>::value
+#else
+#  define BOOST_INTEL_TT_OPTS
+#endif
+
+#   define BOOST_IS_UNION(T) __is_union(T)
+#   define BOOST_IS_POD(T) __is_pod(T)
+#   define BOOST_IS_EMPTY(T) __is_empty(T)
+#   define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) ((__has_trivial_constructor(T) BOOST_INTEL_TT_OPTS) && ! ::boost::is_volatile<T>::value)
+#   define BOOST_HAS_TRIVIAL_COPY(T) ((__has_trivial_copy(T) BOOST_INTEL_TT_OPTS) && !is_reference<T>::value)
+#if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409
+#   define BOOST_HAS_TRIVIAL_ASSIGN(T) ((__has_trivial_assign(T) BOOST_INTEL_TT_OPTS) && ! ::boost::is_volatile<T>::value && ! ::boost::is_const<T>::value && is_assignable<T&, const T&>::value)
+#   define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) BOOST_INTEL_TT_OPTS && is_destructible<T>::value)
+#   define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) && is_default_constructible<T>::value BOOST_INTEL_TT_OPTS)
+#   define BOOST_HAS_NOTHROW_COPY(T) ((__has_nothrow_copy(T) BOOST_INTEL_TT_OPTS) && !is_volatile<T>::value && !is_reference<T>::value && is_copy_constructible<T>::value)
+#   define BOOST_HAS_NOTHROW_ASSIGN(T) ((__has_nothrow_assign(T) BOOST_INTEL_TT_OPTS) && !is_volatile<T>::value && !is_const<T>::value && is_assignable<T&, const T&>::value)
+#else
+#   define BOOST_HAS_TRIVIAL_ASSIGN(T) ((__has_trivial_assign(T) BOOST_INTEL_TT_OPTS) && ! ::boost::is_volatile<T>::value && ! ::boost::is_const<T>::value)
+#   define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T) BOOST_INTEL_TT_OPTS)
+#   define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_constructor(T) BOOST_INTEL_TT_OPTS)
+#   define BOOST_HAS_NOTHROW_COPY(T) ((__has_nothrow_copy(T) BOOST_INTEL_TT_OPTS) && !is_volatile<T>::value && !is_reference<T>::value && !is_array<T>::value)
+#   define BOOST_HAS_NOTHROW_ASSIGN(T) ((__has_nothrow_assign(T) BOOST_INTEL_TT_OPTS) && !is_volatile<T>::value && !is_const<T>::value && !is_array<T>::value)
+#endif
+#   define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
+
+#   define BOOST_IS_ABSTRACT(T) __is_abstract(T)
+#   define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same<T,U>::value)
+#   define BOOST_IS_CLASS(T) __is_class(T)
+#   define BOOST_IS_ENUM(T) __is_enum(T)
+#   define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T)
+#   if (!defined(unix) && !defined(__unix__)) || defined(__LP64__)
+      // GCC sometimes lies about alignment requirements
+      // of type double on 32-bit unix platforms, use the
+      // old implementation instead in that case:
+#     define BOOST_ALIGNMENT_OF(T) __alignof__(T)
+#   endif
+#   if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7))
+#     define BOOST_IS_FINAL(T) __is_final(T)
+#   endif
+
+#   if (__GNUC__ >= 5) && (__cplusplus >= 201103)
+#     define BOOST_HAS_TRIVIAL_MOVE_ASSIGN(T) (__is_trivially_assignable(T&, T&&) && is_assignable<T&, T&&>::value && !::boost::is_volatile<T>::value)
+#     define BOOST_HAS_TRIVIAL_MOVE_CONSTRUCTOR(T) (__is_trivially_constructible(T, T&&) && is_constructible<T, T&&>::value && !::boost::is_volatile<T>::value)
+#   endif
+
+#   define BOOST_HAS_TYPE_TRAITS_INTRINSICS
+#endif
+
+#if defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130)
+#   define BOOST_IS_UNION(T) __oracle_is_union(T)
+#   define BOOST_IS_POD(T) (__oracle_is_pod(T) && !is_function<T>::value)
+#   define BOOST_IS_EMPTY(T) __oracle_is_empty(T)
+#   define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) (__oracle_has_trivial_constructor(T) && ! ::boost::is_volatile<T>::value)
+#   define BOOST_HAS_TRIVIAL_COPY(T) (__oracle_has_trivial_copy(T) && !is_reference<T>::value)
+#   define BOOST_HAS_TRIVIAL_ASSIGN(T) ((__oracle_has_trivial_assign(T) || __oracle_is_trivial(T)) && ! ::boost::is_volatile<T>::value && ! ::boost::is_const<T>::value && is_assignable<T&, const T&>::value)
+#   define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__oracle_has_trivial_destructor(T) && is_destructible<T>::value)
+#   define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) ((__oracle_has_nothrow_constructor(T) || __oracle_has_trivial_constructor(T) || __oracle_is_trivial(T)) && is_default_constructible<T>::value)
+//  __oracle_has_nothrow_copy appears to behave the same as __oracle_has_nothrow_assign, disabled for now:
+//#   define BOOST_HAS_NOTHROW_COPY(T) ((__oracle_has_nothrow_copy(T) || __oracle_has_trivial_copy(T) || __oracle_is_trivial(T)) && !is_volatile<T>::value && !is_reference<T>::value && is_copy_constructible<T>::value)
+#   define BOOST_HAS_NOTHROW_ASSIGN(T) ((__oracle_has_nothrow_assign(T) || __oracle_has_trivial_assign(T) || __oracle_is_trivial(T)) && !is_volatile<T>::value && !is_const<T>::value && is_assignable<T&, const T&>::value)
+#   define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __oracle_has_virtual_destructor(T)
+
+#   define BOOST_IS_ABSTRACT(T) __oracle_is_abstract(T)
+//#   define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same<T,U>::value)
+#   define BOOST_IS_CLASS(T) __oracle_is_class(T)
+#   define BOOST_IS_ENUM(T) __oracle_is_enum(T)
+#   define BOOST_IS_POLYMORPHIC(T) __oracle_is_polymorphic(T)
+#   define BOOST_ALIGNMENT_OF(T) __alignof__(T)
+#   define BOOST_IS_FINAL(T) __oracle_is_final(T)
+
+#   define BOOST_HAS_TYPE_TRAITS_INTRINSICS
+#endif
+
+#if defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600)
+#   include <boost/type_traits/is_same.hpp>
+#   include <boost/type_traits/is_reference.hpp>
+#   include <boost/type_traits/is_volatile.hpp>
+
+#   define BOOST_IS_UNION(T) __is_union(T)
+#   define BOOST_IS_POD(T) __is_pod(T)
+#   define BOOST_IS_EMPTY(T) __is_empty(T)
+#   define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) __has_trivial_constructor(T)
+#   define BOOST_HAS_TRIVIAL_COPY(T) (__has_trivial_copy(T) && !is_reference<T>::value)
+#   define BOOST_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) && !is_volatile<T>::value)
+#   define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) __has_trivial_destructor(T)
+#   define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) __has_nothrow_constructor(T)
+#   define BOOST_HAS_NOTHROW_COPY(T) (__has_nothrow_copy(T) && !is_volatile<T>::value && !is_reference<T>::value)
+#   define BOOST_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T) && !is_volatile<T>::value)
+#   define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
+
+#   define BOOST_IS_ABSTRACT(T) __is_abstract(T)
+#   define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_same<T,U>::value)
+#   define BOOST_IS_CLASS(T) __is_class(T)
+#   define BOOST_IS_ENUM(T) __is_enum(T)
+#   define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T)
+#   define BOOST_ALIGNMENT_OF(T) __alignof__(T)
+#   define BOOST_HAS_TYPE_TRAITS_INTRINSICS
+#endif
+
+# if defined(__CODEGEARC__)
+#   include <boost/type_traits/is_same.hpp>
+#   include <boost/type_traits/is_reference.hpp>
+#   include <boost/type_traits/is_volatile.hpp>
+#   include <boost/type_traits/is_void.hpp>
+
+#   define BOOST_IS_UNION(T) __is_union(T)
+#   define BOOST_IS_POD(T) __is_pod(T)
+#   define BOOST_IS_EMPTY(T) __is_empty(T)
+#   define BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) (__has_trivial_default_constructor(T))
+#   define BOOST_HAS_TRIVIAL_COPY(T) (__has_trivial_copy_constructor(T) && !is_reference<T>::value)
+#   define BOOST_HAS_TRIVIAL_ASSIGN(T) (__has_trivial_assign(T) && !is_volatile<T>::value)
+#   define BOOST_HAS_TRIVIAL_DESTRUCTOR(T) (__has_trivial_destructor(T))
+#   define BOOST_HAS_NOTHROW_CONSTRUCTOR(T) (__has_nothrow_default_constructor(T))
+#   define BOOST_HAS_NOTHROW_COPY(T) (__has_nothrow_copy_constructor(T) && !is_volatile<T>::value && !is_reference<T>::value)
+#   define BOOST_HAS_NOTHROW_ASSIGN(T) (__has_nothrow_assign(T) && !is_volatile<T>::value)
+#   define BOOST_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
+
+#   define BOOST_IS_ABSTRACT(T) __is_abstract(T)
+#   define BOOST_IS_BASE_OF(T,U) (__is_base_of(T,U) && !is_void<T>::value && !is_void<U>::value)
+#   define BOOST_IS_CLASS(T) __is_class(T)
+#   define BOOST_IS_CONVERTIBLE(T,U) (__is_convertible(T,U) || is_void<U>::value)
+#   define BOOST_IS_ENUM(T) __is_enum(T)
+#   define BOOST_IS_POLYMORPHIC(T) __is_polymorphic(T)
+#   define BOOST_ALIGNMENT_OF(T) alignof(T)
+
+#   define BOOST_HAS_TYPE_TRAITS_INTRINSICS
+#endif
+
+#endif // BOOST_TT_DISABLE_INTRINSICS
+
+#endif // BOOST_TT_INTRINSICS_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_abstract.hpp b/third_party/boost/boost/type_traits/is_abstract.hpp
new file mode 100644
index 0000000..225b0f7
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_abstract.hpp
@@ -0,0 +1,149 @@
+#ifndef BOOST_TT_IS_ABSTRACT_CLASS_HPP
+#define BOOST_TT_IS_ABSTRACT_CLASS_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// is_abstract_class.hpp:
+//
+//  (C) Copyright 2002 Rani Sharoni (rani_sharoni@hotmail.com) and Robert Ramey
+//  Use, modification and distribution is subject to the Boost Software
+//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt)
+//
+//  See http://www.boost.org for updates, documentation, and revision history.
+//
+
+// Compile type discovery whether given type is abstract class or not.
+//
+//   Requires DR 337 to be supported by compiler
+//   (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#337).
+//
+//
+// Believed (Jan 2004) to work on:
+//  - GCC 3.4
+//  - VC++ 7.1
+//  - compilers with new EDG frontend (Intel C++ 7, Comeau 4.3.2)
+//
+// Doesn't work on:
+//  - VC++6, VC++7.0 and less
+//  - GCC 3.3.X and less
+//  - Borland C++ 6 and less
+//
+//
+// History:
+//  - Originally written by Rani Sharoni, see
+//    http://groups.google.com/groups?selm=df893da6.0207110613.75b2fe90%40posting.google.com
+//    At this time supported by EDG (Intel C++ 7, Comeau 4.3.2) and VC7.1.
+//  - Adapted and added into Boost.Serialization library by Robert Ramey
+//    (starting with submission #10).
+//  - Jan 2004: GCC 3.4 fixed to support DR337 (Giovanni Bajo).
+//  - Jan 2004: modified to be part of Boost.TypeTraits (Pavel Vozenilek).
+//  - Nov 2004: Christoph Ludwig found that the implementation did not work with
+//              template types and gcc-3.4 or VC7.1, fix due to Christoph Ludwig
+//              and John Maddock.
+//  - Dec 2004: Added new config macro BOOST_NO_IS_ABSTRACT which causes the template
+//              to degrade gracefully, rather than trash the compiler (John Maddock).
+//
+
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#ifndef BOOST_IS_ABSTRACT
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/detail/yes_no_type.hpp>
+#include <boost/type_traits/is_class.hpp>
+#ifdef BOOST_NO_IS_ABSTRACT
+#include <boost/type_traits/is_polymorphic.hpp>
+#endif
+#endif
+
+namespace boost {
+
+namespace detail{
+
+#ifdef BOOST_IS_ABSTRACT
+template <class T>
+struct is_abstract_imp
+{
+   BOOST_STATIC_CONSTANT(bool, value = BOOST_IS_ABSTRACT(T));
+};
+#elif !defined(BOOST_NO_IS_ABSTRACT)
+template<class T>
+struct is_abstract_imp2
+{
+   // Deduction fails if T is void, function type,
+   // reference type (14.8.2/2)or an abstract class type
+   // according to review status issue #337
+   //
+   template<class U>
+   static type_traits::no_type check_sig(U (*)[1]);
+   template<class U>
+   static type_traits::yes_type check_sig(...);
+   //
+   // T must be a complete type, further if T is a template then
+   // it must be instantiated in order for us to get the right answer:
+   //
+   BOOST_STATIC_ASSERT(sizeof(T) != 0);
+
+   // GCC2 won't even parse this template if we embed the computation
+   // of s1 in the computation of value.
+#ifdef __GNUC__
+   BOOST_STATIC_CONSTANT(std::size_t, s1 = sizeof(is_abstract_imp2<T>::template check_sig<T>(0)));
+#else
+#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
+#pragma warning(push)
+#pragma warning(disable:6334)
+#endif
+   BOOST_STATIC_CONSTANT(std::size_t, s1 = sizeof(check_sig<T>(0)));
+#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
+#pragma warning(pop)
+#endif
+#endif
+
+   BOOST_STATIC_CONSTANT(bool, value =
+      (s1 == sizeof(type_traits::yes_type)));
+};
+
+template <bool v>
+struct is_abstract_select
+{
+   template <class T>
+   struct rebind
+   {
+      typedef is_abstract_imp2<T> type;
+   };
+};
+template <>
+struct is_abstract_select<false>
+{
+   template <class T>
+   struct rebind
+   {
+      typedef false_type type;
+   };
+};
+
+template <class T>
+struct is_abstract_imp
+{
+   typedef is_abstract_select< ::boost::is_class<T>::value> selector;
+   typedef typename selector::template rebind<T> binder;
+   typedef typename binder::type type;
+
+   BOOST_STATIC_CONSTANT(bool, value = type::value);
+};
+
+#endif
+}
+
+#ifndef BOOST_NO_IS_ABSTRACT
+template <class T> struct is_abstract : public integral_constant<bool, ::boost::detail::is_abstract_imp<T>::value> {};
+#else
+template <class T> struct is_abstract : public integral_constant<bool, ::boost::detail::is_polymorphic_imp<T>::value> {};
+#endif
+
+} // namespace boost
+
+#endif //BOOST_TT_IS_ABSTRACT_CLASS_HPP
diff --git a/third_party/boost/boost/type_traits/is_arithmetic.hpp b/third_party/boost/boost/type_traits/is_arithmetic.hpp
new file mode 100644
index 0000000..c23811e
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_arithmetic.hpp
@@ -0,0 +1,22 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_ARITHMETIC_HPP_INCLUDED
+#define BOOST_TT_IS_ARITHMETIC_HPP_INCLUDED
+
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_floating_point.hpp>
+
+namespace boost {
+
+template <class T>
+struct is_arithmetic : public integral_constant<bool, is_integral<T>::value || is_floating_point<T>::value> {};
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_ARITHMETIC_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_array.hpp b/third_party/boost/boost/type_traits/is_array.hpp
new file mode 100644
index 0000000..717a28f
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_array.hpp
@@ -0,0 +1,43 @@
+
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
+//  Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+
+// Some fixes for is_array are based on a newsgroup posting by Jonathan Lundquist.
+
+
+#ifndef BOOST_TT_IS_ARRAY_HPP_INCLUDED
+#define BOOST_TT_IS_ARRAY_HPP_INCLUDED
+
+#include <boost/type_traits/integral_constant.hpp>
+#include <cstddef>
+
+namespace boost {
+
+#if defined( __CODEGEARC__ )
+   template <class T> struct is_array : public integral_constant<bool, __is_array(T)> {};
+#else
+   template <class T> struct is_array : public false_type {};
+#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS)
+   template <class T, std::size_t N> struct is_array<T[N]> : public true_type {};
+   template <class T, std::size_t N> struct is_array<T const[N]> : public true_type{};
+   template <class T, std::size_t N> struct is_array<T volatile[N]> : public true_type{};
+   template <class T, std::size_t N> struct is_array<T const volatile[N]> : public true_type{};
+#if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && !defined(__IBMCPP__) &&  !BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840))
+   template <class T> struct is_array<T[]> : public true_type{};
+   template <class T> struct is_array<T const[]> : public true_type{};
+   template <class T> struct is_array<T const volatile[]> : public true_type{};
+   template <class T> struct is_array<T volatile[]> : public true_type{};
+#endif
+#endif
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_ARRAY_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_assignable.hpp b/third_party/boost/boost/type_traits/is_assignable.hpp
new file mode 100644
index 0000000..9cf681d
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_assignable.hpp
@@ -0,0 +1,76 @@
+
+//  (C) Copyright John Maddock 2015.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_ASSIGNABLE_HPP_INCLUDED
+#define BOOST_TT_IS_ASSIGNABLE_HPP_INCLUDED
+
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/detail/workaround.hpp>
+
+namespace boost{
+
+   template <class T, class U = T> struct is_assignable;
+
+}
+
+#if !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800)
+
+#include <boost/type_traits/detail/yes_no_type.hpp>
+#include <boost/type_traits/declval.hpp>
+
+namespace boost{
+
+   namespace detail{
+
+      struct is_assignable_imp
+      {
+         template<typename T, typename U, typename = decltype(boost::declval<T>() = boost::declval<U>())>
+         static boost::type_traits::yes_type test(int);
+
+         template<typename, typename>
+         static boost::type_traits::no_type test(...);
+      };
+
+   }
+
+   template <class T, class U> struct is_assignable : public integral_constant<bool, sizeof(detail::is_assignable_imp::test<T, U>(0)) == sizeof(boost::type_traits::yes_type)>{};
+   template <class T, std::size_t N, class U> struct is_assignable<T[N], U> : public is_assignable<T, U>{};
+   template <class T, std::size_t N, class U> struct is_assignable<T(&)[N], U> : public is_assignable<T&, U>{};
+   template <class T, class U> struct is_assignable<T[], U> : public is_assignable<T, U>{};
+   template <class T, class U> struct is_assignable<T(&)[], U> : public is_assignable<T&, U>{};
+   template <class U> struct is_assignable<void, U> : public integral_constant<bool, false>{};
+   template <class U> struct is_assignable<void const, U> : public integral_constant<bool, false>{};
+   template <class U> struct is_assignable<void volatile, U> : public integral_constant<bool, false>{};
+   template <class U> struct is_assignable<void const volatile, U> : public integral_constant<bool, false>{};
+
+#else
+
+#include <boost/type_traits/has_trivial_assign.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+namespace boost{
+
+   // We don't know how to implement this:
+   template <class T, class U> struct is_assignable : public integral_constant<bool, false>{};
+   template <class T, class U> struct is_assignable<T&, U> : public integral_constant<bool, is_pod<T>::value && is_pod<typename remove_reference<U>::type>::value>{};
+   template <class T, class U> struct is_assignable<const T&, U> : public integral_constant<bool, false>{};
+   template <class U> struct is_assignable<void, U> : public integral_constant<bool, false>{};
+   template <class U> struct is_assignable<void const, U> : public integral_constant<bool, false>{};
+   template <class U> struct is_assignable<void volatile, U> : public integral_constant<bool, false>{};
+   template <class U> struct is_assignable<void const volatile, U> : public integral_constant<bool, false>{};
+   /*
+   template <> struct is_assignable<void, void> : public integral_constant<bool, false>{};
+   template <> struct is_assignable<void const, void const> : public integral_constant<bool, false>{};
+   template <> struct is_assignable<void volatile, void volatile> : public integral_constant<bool, false>{};
+   template <> struct is_assignable<void const volatile, void const volatile> : public integral_constant<bool, false>{};
+   */
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_ASSIGNABLE_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_base_and_derived.hpp b/third_party/boost/boost/type_traits/is_base_and_derived.hpp
new file mode 100644
index 0000000..a2cbbbc
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_base_and_derived.hpp
@@ -0,0 +1,244 @@
+
+//  (C) Copyright Rani Sharoni 2003.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_BASE_AND_DERIVED_HPP_INCLUDED
+#define BOOST_TT_IS_BASE_AND_DERIVED_HPP_INCLUDED
+
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#ifndef BOOST_IS_BASE_OF
+#include <boost/type_traits/is_class.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/config.hpp>
+#include <boost/static_assert.hpp>
+#endif
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+namespace boost {
+
+namespace detail {
+
+#ifndef BOOST_IS_BASE_OF
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581)) \
+ && !BOOST_WORKAROUND(__SUNPRO_CC , <= 0x540) \
+ && !BOOST_WORKAROUND(__EDG_VERSION__, <= 243) \
+ && !BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840))
+
+                             // The EDG version number is a lower estimate.
+                             // It is not currently known which EDG version
+                             // exactly fixes the problem.
+
+/*************************************************************************
+
+This version detects ambiguous base classes and private base classes
+correctly, and was devised by Rani Sharoni.
+
+Explanation by Terje Slettebo and Rani Sharoni.
+
+Let's take the multiple base class below as an example, and the following
+will also show why there's not a problem with private or ambiguous base
+class:
+
+struct B {};
+struct B1 : B {};
+struct B2 : B {};
+struct D : private B1, private B2 {};
+
+is_base_and_derived<B, D>::value;
+
+First, some terminology:
+
+SC  - Standard conversion
+UDC - User-defined conversion
+
+A user-defined conversion sequence consists of an SC, followed by an UDC,
+followed by another SC. Either SC may be the identity conversion.
+
+When passing the default-constructed Host object to the overloaded check_sig()
+functions (initialization 8.5/14/4/3), we have several viable implicit
+conversion sequences:
+
+For "static no_type check_sig(B const volatile *, int)" we have the conversion
+sequences:
+
+C -> C const (SC - Qualification Adjustment) -> B const volatile* (UDC)
+C -> D const volatile* (UDC) -> B1 const volatile* / B2 const volatile* ->
+     B const volatile* (SC - Conversion)
+
+For "static yes_type check_sig(D const volatile *, T)" we have the conversion
+sequence:
+
+C -> D const volatile* (UDC)
+
+According to 13.3.3.1/4, in context of user-defined conversion only the
+standard conversion sequence is considered when selecting the best viable
+function, so it only considers up to the user-defined conversion. For the
+first function this means choosing between C -> C const and C -> C, and it
+chooses the latter, because it's a proper subset (13.3.3.2/3/2) of the
+former. Therefore, we have:
+
+C -> D const volatile* (UDC) -> B1 const volatile* / B2 const volatile* ->
+     B const volatile* (SC - Conversion)
+C -> D const volatile* (UDC)
+
+Here, the principle of the "shortest subsequence" applies again, and it
+chooses C -> D const volatile*. This shows that it doesn't even need to
+consider the multiple paths to B, or accessibility, as that possibility is
+eliminated before it could possibly cause ambiguity or access violation.
+
+If D is not derived from B, it has to choose between C -> C const -> B const
+volatile* for the first function, and C -> D const volatile* for the second
+function, which are just as good (both requires a UDC, 13.3.3.2), had it not
+been for the fact that "static no_type check_sig(B const volatile *, int)" is
+not templated, which makes C -> C const -> B const volatile* the best choice
+(13.3.3/1/4), resulting in "no".
+
+Also, if Host::operator B const volatile* hadn't been const, the two
+conversion sequences for "static no_type check_sig(B const volatile *, int)", in
+the case where D is derived from B, would have been ambiguous.
+
+See also
+http://groups.google.com/groups?selm=df893da6.0301280859.522081f7%40posting.
+google.com and links therein.
+
+*************************************************************************/
+
+template <typename B, typename D>
+struct bd_helper
+{
+   //
+   // This VC7.1 specific workaround stops the compiler from generating
+   // an internal compiler error when compiling with /vmg (thanks to
+   // Aleksey Gurtovoy for figuring out the workaround).
+   //
+#if !BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+    template <typename T>
+    static type_traits::yes_type check_sig(D const volatile *, T);
+    static type_traits::no_type  check_sig(B const volatile *, int);
+#else
+    static type_traits::yes_type check_sig(D const volatile *, long);
+    static type_traits::no_type  check_sig(B const volatile * const&, int);
+#endif
+};
+
+template<typename B, typename D>
+struct is_base_and_derived_impl2
+{
+#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
+#pragma warning(push)
+#pragma warning(disable:6334)
+#endif
+    //
+    // May silently do the wrong thing with incomplete types
+    // unless we trap them here:
+    //
+    BOOST_STATIC_ASSERT(sizeof(B) != 0);
+    BOOST_STATIC_ASSERT(sizeof(D) != 0);
+
+    struct Host
+    {
+#if !BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+        operator B const volatile *() const;
+#else
+        operator B const volatile * const&() const;
+#endif
+        operator D const volatile *();
+    };
+
+    BOOST_STATIC_CONSTANT(bool, value =
+        sizeof(bd_helper<B,D>::check_sig(Host(), 0)) == sizeof(type_traits::yes_type));
+#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
+#pragma warning(pop)
+#endif
+};
+
+#else
+
+//
+// broken version:
+//
+template<typename B, typename D>
+struct is_base_and_derived_impl2
+{
+    BOOST_STATIC_CONSTANT(bool, value =
+        (::boost::is_convertible<D*,B*>::value));
+};
+
+#define BOOST_BROKEN_IS_BASE_AND_DERIVED
+
+#endif
+
+template <typename B, typename D>
+struct is_base_and_derived_impl3
+{
+    BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+template <bool ic1, bool ic2, bool iss>
+struct is_base_and_derived_select
+{
+   template <class T, class U>
+   struct rebind
+   {
+      typedef is_base_and_derived_impl3<T,U> type;
+   };
+};
+
+template <>
+struct is_base_and_derived_select<true,true,false>
+{
+   template <class T, class U>
+   struct rebind
+   {
+      typedef is_base_and_derived_impl2<T,U> type;
+   };
+};
+
+template <typename B, typename D>
+struct is_base_and_derived_impl
+{
+    typedef typename remove_cv<B>::type ncvB;
+    typedef typename remove_cv<D>::type ncvD;
+
+    typedef is_base_and_derived_select<
+       ::boost::is_class<B>::value,
+       ::boost::is_class<D>::value,
+       ::boost::is_same<ncvB,ncvD>::value> selector;
+    typedef typename selector::template rebind<ncvB,ncvD> binder;
+    typedef typename binder::type bound_type;
+
+    BOOST_STATIC_CONSTANT(bool, value = bound_type::value);
+};
+#else
+template <typename B, typename D>
+struct is_base_and_derived_impl
+{
+    typedef typename remove_cv<B>::type ncvB;
+    typedef typename remove_cv<D>::type ncvD;
+
+    BOOST_STATIC_CONSTANT(bool, value = (BOOST_IS_BASE_OF(B,D) && ! ::boost::is_same<ncvB,ncvD>::value));
+};
+#endif
+} // namespace detail
+
+template <class Base, class Derived> struct is_base_and_derived
+   : public integral_constant<bool, (::boost::detail::is_base_and_derived_impl<Base, Derived>::value)> {};
+
+template <class Base, class Derived> struct is_base_and_derived<Base&, Derived> : public false_type{};
+template <class Base, class Derived> struct is_base_and_derived<Base, Derived&> : public false_type{};
+template <class Base, class Derived> struct is_base_and_derived<Base&, Derived&> : public false_type{};
+
+#if BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610))
+template <class Base> struct is_base_and_derived<Base, Base> : public true_type{};
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_BASE_AND_DERIVED_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_base_of.hpp b/third_party/boost/boost/type_traits/is_base_of.hpp
new file mode 100644
index 0000000..e4c6ca9
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_base_of.hpp
@@ -0,0 +1,39 @@
+
+//  (C) Copyright Rani Sharoni 2003-2005.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_BASE_OF_HPP_INCLUDED
+#define BOOST_TT_IS_BASE_OF_HPP_INCLUDED
+
+#include <boost/type_traits/is_base_and_derived.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_class.hpp>
+
+namespace boost {
+
+   namespace detail{
+      template <class B, class D>
+      struct is_base_of_imp
+      {
+          typedef typename remove_cv<B>::type ncvB;
+          typedef typename remove_cv<D>::type ncvD;
+          BOOST_STATIC_CONSTANT(bool, value = (
+            (::boost::detail::is_base_and_derived_impl<ncvB,ncvD>::value) ||
+            (::boost::is_same<ncvB,ncvD>::value && ::boost::is_class<ncvB>::value)));
+      };
+   }
+
+   template <class Base, class Derived> struct is_base_of
+      : public integral_constant<bool, (::boost::detail::is_base_of_imp<Base, Derived>::value)> {};
+
+   template <class Base, class Derived> struct is_base_of<Base, Derived&> : false_type{};
+   template <class Base, class Derived> struct is_base_of<Base&, Derived&> : false_type{};
+   template <class Base, class Derived> struct is_base_of<Base&, Derived> : false_type{};
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_BASE_AND_DERIVED_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_class.hpp b/third_party/boost/boost/type_traits/is_class.hpp
new file mode 100644
index 0000000..aa35dbb
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_class.hpp
@@ -0,0 +1,114 @@
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
+//  Hinnant & John Maddock 2000-2003.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+
+#ifndef BOOST_TT_IS_CLASS_HPP_INCLUDED
+#define BOOST_TT_IS_CLASS_HPP_INCLUDED
+
+#include <boost/type_traits/detail/config.hpp>
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#ifndef BOOST_IS_CLASS
+#   include <boost/type_traits/is_union.hpp>
+
+#ifdef BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION
+#   include <boost/type_traits/detail/yes_no_type.hpp>
+#else
+#   include <boost/type_traits/is_scalar.hpp>
+#   include <boost/type_traits/is_array.hpp>
+#   include <boost/type_traits/is_reference.hpp>
+#   include <boost/type_traits/is_void.hpp>
+#   include <boost/type_traits/is_function.hpp>
+#endif
+
+#endif // BOOST_IS_CLASS
+
+namespace boost {
+
+namespace detail {
+
+#ifndef BOOST_IS_CLASS
+#ifdef BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION
+
+// This is actually the conforming implementation which works with
+// abstract classes.  However, enough compilers have trouble with
+// it that most will use the one in
+// boost/type_traits/object_traits.hpp. This implementation
+// actually works with VC7.0, but other interactions seem to fail
+// when we use it.
+
+// is_class<> metafunction due to Paul Mensonides
+// (leavings@attbi.com). For more details:
+// http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1
+#if defined(__GNUC__)  && !defined(__EDG_VERSION__)
+
+template <class U> ::boost::type_traits::yes_type is_class_tester(void(U::*)(void));
+template <class U> ::boost::type_traits::no_type is_class_tester(...);
+
+template <typename T>
+struct is_class_impl
+{
+
+    BOOST_STATIC_CONSTANT(bool, value =
+            sizeof(is_class_tester<T>(0)) == sizeof(::boost::type_traits::yes_type)
+            && ! ::boost::is_union<T>::value
+        );
+};
+
+#else
+
+template <typename T>
+struct is_class_impl
+{
+    template <class U> static ::boost::type_traits::yes_type is_class_tester(void(U::*)(void));
+    template <class U> static ::boost::type_traits::no_type is_class_tester(...);
+
+    BOOST_STATIC_CONSTANT(bool, value =
+            sizeof(is_class_tester<T>(0)) == sizeof(::boost::type_traits::yes_type)
+            && ! ::boost::is_union<T>::value
+        );
+};
+
+#endif
+
+#else
+
+template <typename T>
+struct is_class_impl
+{
+    BOOST_STATIC_CONSTANT(bool, value =
+        ! ::boost::is_union<T>::value >::value
+        && ! ::boost::is_scalar<T>::value
+        && ! ::boost::is_array<T>::value
+        && ! ::boost::is_reference<T>::value
+        && ! ::boost::is_void<T>::value
+        && ! ::boost::is_function<T>::value
+        );
+};
+
+# endif // BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION
+# else // BOOST_IS_CLASS
+template <typename T>
+struct is_class_impl
+{
+    BOOST_STATIC_CONSTANT(bool, value = BOOST_IS_CLASS(T));
+};
+# endif // BOOST_IS_CLASS
+
+} // namespace detail
+
+template <class T> struct is_class : public integral_constant<bool, ::boost::detail::is_class_impl<T>::value> {};
+# ifdef __EDG_VERSION__
+template <class T> struct is_class<const T> : public is_class<T>{};
+template <class T> struct is_class<const volatile T> : public is_class<T>{};
+template <class T> struct is_class<volatile T> : public is_class<T>{};
+# endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_CLASS_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_const.hpp b/third_party/boost/boost/type_traits/is_const.hpp
new file mode 100644
index 0000000..6cbeef8
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_const.hpp
@@ -0,0 +1,45 @@
+
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes,
+//      Howard Hinnant and John Maddock 2000.
+//  (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001
+
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+//    Fixed is_pointer, is_reference, is_const, is_volatile, is_same,
+//    is_member_pointer based on the Simulated Partial Specialization work
+//    of Mat Marcus and Jesse Jones. See  http://opensource.adobe.com or
+//    http://groups.yahoo.com/group/boost/message/5441
+//    Some workarounds in here use ideas suggested from "Generic<Programming>:
+//    Mappings between Types and Values"
+//    by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html).
+
+
+#ifndef BOOST_TT_IS_CONST_HPP_INCLUDED
+#define BOOST_TT_IS_CONST_HPP_INCLUDED
+
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace boost {
+
+#if defined( __CODEGEARC__ )
+
+   template <class T>
+   struct is_const : public integral_constant<bool, __is_const(T)> {};
+
+#else
+
+   template <class T>
+   struct is_const : public false_type {};
+   template <class T> struct is_const<T const> : public true_type{};
+   template <class T, size_t N> struct is_const<T const[N]> : public true_type{};
+   template <class T> struct is_const<T const[]> : public true_type{};
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_CONST_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_convertible.hpp b/third_party/boost/boost/type_traits/is_convertible.hpp
new file mode 100644
index 0000000..a1e642c
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_convertible.hpp
@@ -0,0 +1,488 @@
+
+// Copyright 2000 John Maddock (john@johnmaddock.co.uk)
+// Copyright 2000 Jeremy Siek (jsiek@lsc.nd.edu)
+// Copyright 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
+//
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED
+#define BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED
+
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#ifndef BOOST_IS_CONVERTIBLE
+#include <boost/type_traits/detail/yes_no_type.hpp>
+#include <boost/type_traits/detail/config.hpp>
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/type_traits/is_void.hpp>
+#if !defined(BOOST_NO_IS_ABSTRACT)
+#include <boost/type_traits/is_abstract.hpp>
+#endif
+#include <boost/type_traits/add_lvalue_reference.hpp>
+#include <boost/type_traits/add_rvalue_reference.hpp>
+#include <boost/type_traits/is_function.hpp>
+
+#if defined(__MWERKS__)
+#include <boost/type_traits/remove_reference.hpp>
+#endif
+#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+#  include <boost/type_traits/declval.hpp>
+#endif
+#elif defined(BOOST_MSVC) || defined(BOOST_INTEL)
+#include <boost/type_traits/is_function.hpp>
+#include <boost/type_traits/is_same.hpp>
+#endif // BOOST_IS_CONVERTIBLE
+
+namespace boost {
+
+#ifndef BOOST_IS_CONVERTIBLE
+
+// is one type convertible to another?
+//
+// there are multiple versions of the is_convertible
+// template, almost every compiler seems to require its
+// own version.
+//
+// Thanks to Andrei Alexandrescu for the original version of the
+// conversion detection technique!
+//
+
+namespace detail {
+
+#if !defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !(defined(BOOST_GCC) && (BOOST_GCC < 40700))
+
+   // This is a C++11 conforming version, place this first and use it wherever possible:
+
+#  define BOOST_TT_CXX11_IS_CONVERTIBLE
+
+   template <class A, class B, class C>
+   struct or_helper
+   {
+      static const bool value = (A::value || B::value || C::value);
+   };
+
+   template<typename From, typename To, bool b = or_helper<boost::is_void<From>, boost::is_function<To>, boost::is_array<To> >::value>
+   struct is_convertible_basic_impl
+   {
+      // Nothing converts to function or array, but void converts to void:
+      static const bool value = is_void<To>::value;
+   };
+
+   template<typename From, typename To>
+   class is_convertible_basic_impl<From, To, false>
+   {
+      typedef char one;
+      typedef int  two;
+
+      template<typename To1>
+      static void test_aux(To1);
+
+      template<typename From1, typename To1>
+      static decltype(test_aux<To1>(boost::declval<From1>()), one()) test(int);
+
+      template<typename, typename>
+      static two test(...);
+
+   public:
+      static const bool value = sizeof(test<From, To>(0)) == 1;
+   };
+
+#elif defined(__BORLANDC__) && (__BORLANDC__ < 0x560)
+//
+// special version for Borland compilers
+// this version breaks when used for some
+// UDT conversions:
+//
+template <typename From, typename To>
+struct is_convertible_impl
+{
+#pragma option push -w-8074
+    // This workaround for Borland breaks the EDG C++ frontend,
+    // so we only use it for Borland.
+    template <typename T> struct checker
+    {
+        static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
+        static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(T);
+    };
+
+    static typename add_lvalue_reference<From>::type  _m_from;
+    static bool const value = sizeof( checker<To>::_m_check(_m_from) )
+        == sizeof(::boost::type_traits::yes_type);
+#pragma option pop
+};
+
+#elif defined(__GNUC__) || defined(__BORLANDC__) && (__BORLANDC__ < 0x600)
+// special version for gcc compiler + recent Borland versions
+// note that this does not pass UDT's through (...)
+
+struct any_conversion
+{
+    template <typename T> any_conversion(const volatile T&);
+    template <typename T> any_conversion(const T&);
+    template <typename T> any_conversion(volatile T&);
+    template <typename T> any_conversion(T&);
+};
+
+template <typename T> struct checker
+{
+    static boost::type_traits::no_type _m_check(any_conversion ...);
+    static boost::type_traits::yes_type _m_check(T, int);
+};
+
+template <typename From, typename To>
+struct is_convertible_basic_impl
+{
+    typedef typename add_lvalue_reference<From>::type lvalue_type;
+    typedef typename add_rvalue_reference<From>::type rvalue_type;
+    static lvalue_type _m_from;
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 6)))
+    static bool const value =
+        sizeof( boost::detail::checker<To>::_m_check(static_cast<rvalue_type>(_m_from), 0) )
+        == sizeof(::boost::type_traits::yes_type);
+#else
+    static bool const value =
+        sizeof( boost::detail::checker<To>::_m_check(_m_from, 0) )
+        == sizeof(::boost::type_traits::yes_type);
+#endif
+};
+
+#elif (defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 245) && !defined(__ICL)) \
+      || defined(__IBMCPP__) || defined(__HP_aCC)
+//
+// This is *almost* an ideal world implementation as it doesn't rely
+// on undefined behaviour by passing UDT's through (...).
+// Unfortunately it doesn't quite pass all the tests for most compilers (sigh...)
+// Enable this for your compiler if is_convertible_test.cpp will compile it...
+//
+// Note we do not enable this for VC7.1, because even though it passes all the
+// type_traits tests it is known to cause problems when instantiation occurs
+// deep within the instantiation tree :-(
+//
+struct any_conversion
+{
+    template <typename T> any_conversion(const volatile T&);
+    template <typename T> any_conversion(const T&);
+    template <typename T> any_conversion(volatile T&);
+    // we need this constructor to catch references to functions
+    // (which can not be cv-qualified):
+    template <typename T> any_conversion(T&);
+};
+
+template <typename From, typename To>
+struct is_convertible_basic_impl
+{
+    static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...);
+    static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int);
+    typedef typename add_lvalue_reference<From>::type lvalue_type;
+    typedef typename add_rvalue_reference<From>::type rvalue_type;
+    static lvalue_type _m_from;
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_STATIC_CONSTANT(bool, value =
+        sizeof( _m_check(static_cast<rvalue_type>(_m_from), 0) ) == sizeof(::boost::type_traits::yes_type)
+        );
+#else
+    BOOST_STATIC_CONSTANT(bool, value =
+        sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type)
+        );
+#endif
+};
+
+#elif defined(__DMC__)
+
+struct any_conversion
+{
+    template <typename T> any_conversion(const volatile T&);
+    template <typename T> any_conversion(const T&);
+    template <typename T> any_conversion(volatile T&);
+    // we need this constructor to catch references to functions
+    // (which can not be cv-qualified):
+    template <typename T> any_conversion(T&);
+};
+
+template <typename From, typename To>
+struct is_convertible_basic_impl
+{
+    // Using '...' doesn't always work on Digital Mars. This version seems to.
+    template <class T>
+    static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion,  float, T);
+    static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int, int);
+    typedef typename add_lvalue_reference<From>::type lvalue_type;
+    typedef typename add_rvalue_reference<From>::type rvalue_type;
+    static lvalue_type _m_from;
+
+    // Static constants sometime cause the conversion of _m_from to To to be
+    // called. This doesn't happen with an enum.
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    enum { value =
+        sizeof( _m_check(static_cast<rvalue_type>(_m_from), 0, 0) ) == sizeof(::boost::type_traits::yes_type)
+        };
+#else
+    enum { value =
+        sizeof( _m_check(_m_from, 0, 0) ) == sizeof(::boost::type_traits::yes_type)
+        };
+#endif
+};
+
+#elif defined(__MWERKS__)
+//
+// CW works with the technique implemented above for EDG, except when From
+// is a function type (or a reference to such a type), in which case
+// any_conversion won't be accepted as a valid conversion. We detect this
+// exceptional situation and channel it through an alternative algorithm.
+//
+
+template <typename From, typename To,bool FromIsFunctionRef>
+struct is_convertible_basic_impl_aux;
+
+struct any_conversion
+{
+    template <typename T> any_conversion(const volatile T&);
+    template <typename T> any_conversion(const T&);
+    template <typename T> any_conversion(volatile T&);
+    template <typename T> any_conversion(T&);
+};
+
+template <typename From, typename To>
+struct is_convertible_basic_impl_aux<From,To,false /*FromIsFunctionRef*/>
+{
+    static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(any_conversion ...);
+    static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To, int);
+    typedef typename add_lvalue_reference<From>::type lvalue_type;
+    typedef typename add_rvalue_reference<From>::type rvalue_type;
+    static lvalue_type _m_from;
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_STATIC_CONSTANT(bool, value =
+        sizeof( _m_check(static_cast<rvalue_type>(_m_from), 0) ) == sizeof(::boost::type_traits::yes_type)
+        );
+#else
+    BOOST_STATIC_CONSTANT(bool, value =
+        sizeof( _m_check(_m_from, 0) ) == sizeof(::boost::type_traits::yes_type)
+        );
+#endif
+};
+
+template <typename From, typename To>
+struct is_convertible_basic_impl_aux<From,To,true /*FromIsFunctionRef*/>
+{
+    static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
+    static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To);
+    typedef typename add_lvalue_reference<From>::type lvalue_type;
+    typedef typename add_rvalue_reference<From>::type rvalue_type;
+    static lvalue_type _m_from;
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    BOOST_STATIC_CONSTANT(bool, value =
+        sizeof( _m_check(static_cast<rvalue_type>(_m_from)) ) == sizeof(::boost::type_traits::yes_type)
+        );
+#else
+    BOOST_STATIC_CONSTANT(bool, value =
+        sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type)
+        );
+#endif
+};
+
+template <typename From, typename To>
+struct is_convertible_basic_impl:
+  is_convertible_basic_impl_aux<
+    From,To,
+    ::boost::is_function<typename ::boost::remove_reference<From>::type>::value
+  >
+{};
+
+#else
+//
+// This version seems to work pretty well for a wide spectrum of compilers,
+// however it does rely on undefined behaviour by passing UDT's through (...).
+//
+
+//Workaround for old compilers like MSVC 7.1 to avoid
+//forming a reference to an array of unknown bound
+template <typename From>
+struct is_convertible_basic_impl_add_lvalue_reference
+   : add_lvalue_reference<From>
+{};
+
+template <typename From>
+struct is_convertible_basic_impl_add_lvalue_reference<From[]>
+{
+    typedef From type [];
+};
+
+template <typename From, typename To>
+struct is_convertible_basic_impl
+{
+    static ::boost::type_traits::no_type BOOST_TT_DECL _m_check(...);
+    static ::boost::type_traits::yes_type BOOST_TT_DECL _m_check(To);
+    typedef typename is_convertible_basic_impl_add_lvalue_reference<From>::type lvalue_type;
+    static lvalue_type _m_from;
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4244)
+#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
+#pragma warning(disable:6334)
+#endif
+#endif
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    typedef typename add_rvalue_reference<From>::type rvalue_type;
+    BOOST_STATIC_CONSTANT(bool, value =
+        sizeof( _m_check(static_cast<rvalue_type>(_m_from)) ) == sizeof(::boost::type_traits::yes_type)
+        );
+#else
+    BOOST_STATIC_CONSTANT(bool, value =
+        sizeof( _m_check(_m_from) ) == sizeof(::boost::type_traits::yes_type)
+        );
+#endif
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+};
+
+#endif // is_convertible_impl
+
+#if defined(__DMC__)
+// As before, a static constant sometimes causes errors on Digital Mars.
+template <typename From, typename To>
+struct is_convertible_impl
+{
+    enum {
+       value = ( ::boost::detail::is_convertible_basic_impl<From,To>::value && ! ::boost::is_array<To>::value && ! ::boost::is_function<To>::value)
+    };
+};
+#elif !defined(__BORLANDC__) || __BORLANDC__ > 0x551
+template <typename From, typename To>
+struct is_convertible_impl
+{
+   BOOST_STATIC_CONSTANT(bool, value = ( ::boost::detail::is_convertible_basic_impl<From, To>::value && !::boost::is_array<To>::value && !::boost::is_function<To>::value));
+};
+#endif
+
+template <bool trivial1, bool trivial2, bool abstract_target>
+struct is_convertible_impl_select
+{
+   template <class From, class To>
+   struct rebind
+   {
+      typedef is_convertible_impl<From, To> type;
+   };
+};
+
+template <>
+struct is_convertible_impl_select<true, true, false>
+{
+   template <class From, class To>
+   struct rebind
+   {
+      typedef true_type type;
+   };
+};
+
+template <>
+struct is_convertible_impl_select<false, false, true>
+{
+   template <class From, class To>
+   struct rebind
+   {
+      typedef false_type type;
+   };
+};
+
+template <>
+struct is_convertible_impl_select<true, false, true>
+{
+   template <class From, class To>
+   struct rebind
+   {
+      typedef false_type type;
+   };
+};
+
+template <typename From, typename To>
+struct is_convertible_impl_dispatch_base
+{
+#if !BOOST_WORKAROUND(__HP_aCC, < 60700)
+   typedef is_convertible_impl_select<
+      ::boost::is_arithmetic<From>::value,
+      ::boost::is_arithmetic<To>::value,
+#if !defined(BOOST_NO_IS_ABSTRACT) && !defined(BOOST_TT_CXX11_IS_CONVERTIBLE)
+      // We need to filter out abstract types, only if we don't have a strictly conforming C++11 version:
+      ::boost::is_abstract<To>::value
+#else
+      false
+#endif
+   > selector;
+#else
+   typedef is_convertible_impl_select<false, false, false> selector;
+#endif
+   typedef typename selector::template rebind<From, To> isc_binder;
+   typedef typename isc_binder::type type;
+};
+
+template <typename From, typename To>
+struct is_convertible_impl_dispatch
+   : public is_convertible_impl_dispatch_base<From, To>::type
+{};
+
+//
+// Now add the full and partial specialisations
+// for void types, these are common to all the
+// implementation above:
+//
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+
+template <> struct is_convertible_impl_dispatch<void, void> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void, void const> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void, void const volatile> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void, void volatile> : public true_type{};
+
+template <> struct is_convertible_impl_dispatch<void const, void> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void const, void const> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void const, void const volatile> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void const, void volatile> : public true_type{};
+
+template <> struct is_convertible_impl_dispatch<void const volatile, void> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void const volatile, void const> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void const volatile, void const volatile> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void const volatile, void volatile> : public true_type{};
+
+template <> struct is_convertible_impl_dispatch<void volatile, void> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void volatile, void const> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void volatile, void const volatile> : public true_type{};
+template <> struct is_convertible_impl_dispatch<void volatile, void volatile> : public true_type{};
+
+#else
+template <> struct is_convertible_impl_dispatch<void, void> : public true_type{};
+#endif // BOOST_NO_CV_VOID_SPECIALIZATIONS
+
+template <class To> struct is_convertible_impl_dispatch<void, To> : public false_type{};
+template <class From> struct is_convertible_impl_dispatch<From, void> : public false_type{};
+
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template <class To> struct is_convertible_impl_dispatch<void const, To> : public false_type{};
+template <class From> struct is_convertible_impl_dispatch<From, void const> : public false_type{};
+template <class To> struct is_convertible_impl_dispatch<void const volatile, To> : public false_type{};
+template <class From> struct is_convertible_impl_dispatch<From, void const volatile> : public false_type{};
+template <class To> struct is_convertible_impl_dispatch<void volatile, To> : public false_type{};
+template <class From> struct is_convertible_impl_dispatch<From, void volatile> : public false_type{};
+#endif
+
+} // namespace detail
+
+template <class From, class To>
+struct is_convertible : public integral_constant<bool, ::boost::detail::is_convertible_impl_dispatch<From, To>::value> {};
+
+#else
+
+template <class From, class To>
+struct is_convertible : public integral_constant<bool, BOOST_IS_CONVERTIBLE(From, To)> {};
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_CONVERTIBLE_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_copy_constructible.hpp b/third_party/boost/boost/type_traits/is_copy_constructible.hpp
new file mode 100644
index 0000000..b6e7ae3
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_copy_constructible.hpp
@@ -0,0 +1,187 @@
+//  (C) Copyright Antony Polukhin 2013.
+//
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_COPY_CONSTRUCTIBLE_HPP_INCLUDED
+#define BOOST_TT_IS_COPY_CONSTRUCTIBLE_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40900)
+
+#include <boost/type_traits/is_constructible.hpp>
+
+#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1800)
+
+namespace boost {
+
+template <class T> struct is_copy_constructible : public boost::is_constructible<T, const T&>{};
+
+template <> struct is_copy_constructible<void> : public false_type{};
+template <> struct is_copy_constructible<void const> : public false_type{};
+template <> struct is_copy_constructible<void const volatile> : public false_type{};
+template <> struct is_copy_constructible<void volatile> : public false_type{};
+
+} // namespace boost
+
+#else
+//
+// Special version for VC12 which has a problem when a base class (such as non_copyable) has a deleted
+// copy constructor.  In this case the compiler thinks there really is a copy-constructor and tries to
+// instantiate the deleted member.  std::is_copy_constructible has the same issue (or at least returns
+// an incorrect value, which just defers the issue into the users code) as well.  We can at least fix
+// boost::non_copyable as a base class as a special case:
+//
+#include <boost/type_traits/is_base_and_derived.hpp>
+#include <boost/noncopyable.hpp>
+
+namespace boost {
+
+   namespace detail
+   {
+
+      template <class T, bool b> struct is_copy_constructible_imp : public boost::is_constructible<T, const T&>{};
+      template <class T> struct is_copy_constructible_imp<T, true> : public false_type{};
+
+   }
+
+   template <class T> struct is_copy_constructible : public detail::is_copy_constructible_imp<T, is_base_and_derived<boost::noncopyable, T>::value>{};
+
+   template <> struct is_copy_constructible<void> : public false_type{};
+   template <> struct is_copy_constructible<void const> : public false_type{};
+   template <> struct is_copy_constructible<void const volatile> : public false_type{};
+   template <> struct is_copy_constructible<void volatile> : public false_type{};
+
+} // namespace boost
+
+#endif
+
+#else
+
+#include <boost/type_traits/detail/yes_no_type.hpp>
+#include <boost/type_traits/is_base_and_derived.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/is_rvalue_reference.hpp>
+#include <boost/type_traits/declval.hpp>
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/declval.hpp>
+#include <boost/noncopyable.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4181)
+#endif
+
+namespace boost {
+
+   namespace detail{
+
+      template <bool DerivedFromNoncopyable, class T>
+      struct is_copy_constructible_impl2 {
+
+         // Intel compiler has problems with SFINAE for copy constructors and deleted functions:
+         //
+         // error: function *function_name* cannot be referenced -- it is a deleted function
+         // static boost::type_traits::yes_type test(T1&, decltype(T1(boost::declval<T1&>()))* = 0);
+         //                                                        ^
+         //
+         // MSVC 12.0 (Visual 2013) has problems when the copy constructor has been deleted. See:
+         // https://connect.microsoft.com/VisualStudio/feedback/details/800328/std-is-copy-constructible-is-broken
+#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_INTEL_CXX_VERSION) && !(defined(BOOST_MSVC) && _MSC_VER == 1800)
+
+#ifdef BOOST_NO_CXX11_DECLTYPE
+         template <class T1>
+         static boost::type_traits::yes_type test(const T1&, boost::mpl::int_<sizeof(T1(boost::declval<const T1&>()))>* = 0);
+#else
+         template <class T1>
+         static boost::type_traits::yes_type test(const T1&, decltype(T1(boost::declval<const T1&>()))* = 0);
+#endif
+
+         static boost::type_traits::no_type test(...);
+#else
+         template <class T1>
+         static boost::type_traits::no_type test(const T1&, typename T1::boost_move_no_copy_constructor_or_assign* = 0);
+         static boost::type_traits::yes_type test(...);
+#endif
+
+         // If you see errors like this:
+         //
+         //      `'T::T(const T&)' is private`
+         //      `boost/type_traits/is_copy_constructible.hpp:68:5: error: within this context`
+         //
+         // then you are trying to call that macro for a structure defined like that:
+         //
+         //      struct T {
+         //          ...
+         //      private:
+         //          T(const T &);
+         //          ...
+         //      };
+         //
+         // To fix that you must modify your structure:
+         //
+         //      // C++03 and C++11 version
+         //      struct T: private boost::noncopyable {
+         //          ...
+         //      private:
+         //          T(const T &);
+         //          ...
+         //      };
+         //
+         //      // C++11 version
+         //      struct T {
+         //          ...
+         //      private:
+         //          T(const T &) = delete;
+         //          ...
+         //      };
+         BOOST_STATIC_CONSTANT(bool, value = (
+            sizeof(test(
+            boost::declval<BOOST_DEDUCED_TYPENAME boost::add_reference<T const>::type>()
+            )) == sizeof(boost::type_traits::yes_type)
+            &&
+            !boost::is_rvalue_reference<T>::value
+            && !boost::is_array<T>::value
+            ));
+      };
+
+      template <class T>
+      struct is_copy_constructible_impl2<true, T> {
+         BOOST_STATIC_CONSTANT(bool, value = false);
+      };
+
+      template <class T>
+      struct is_copy_constructible_impl {
+
+         BOOST_STATIC_CONSTANT(bool, value = (
+            boost::detail::is_copy_constructible_impl2<
+            boost::is_base_and_derived<boost::noncopyable, T>::value,
+            T
+            >::value
+            ));
+      };
+
+   } // namespace detail
+
+   template <class T> struct is_copy_constructible : public integral_constant<bool, ::boost::detail::is_copy_constructible_impl<T>::value>{};
+   template <> struct is_copy_constructible<void> : public false_type{};
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+   template <> struct is_copy_constructible<void const> : public false_type{};
+   template <> struct is_copy_constructible<void volatile> : public false_type{};
+   template <> struct is_copy_constructible<void const volatile> : public false_type{};
+#endif
+
+} // namespace boost
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+#endif
+
+#endif // BOOST_TT_IS_COPY_CONSTRUCTIBLE_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_default_constructible.hpp b/third_party/boost/boost/type_traits/is_default_constructible.hpp
new file mode 100644
index 0000000..74bddb7
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_default_constructible.hpp
@@ -0,0 +1,64 @@
+
+//  (C) Copyright John Maddock 2015.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_DEFAULT_CONSTRUCTIBLE_HPP_INCLUDED
+#define BOOST_TT_IS_DEFAULT_CONSTRUCTIBLE_HPP_INCLUDED
+
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/detail/workaround.hpp>
+
+#if !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40500)
+
+#include <boost/type_traits/detail/yes_no_type.hpp>
+
+namespace boost{
+
+   namespace detail{
+
+      struct is_default_constructible_imp
+      {
+         template<typename _Tp, typename = decltype(_Tp())>
+         static boost::type_traits::yes_type test(int);
+
+         template<typename>
+         static boost::type_traits::no_type test(...);
+      };
+
+   }
+
+   template <class T> struct is_default_constructible : public integral_constant<bool, sizeof(detail::is_default_constructible_imp::test<T>(0)) == sizeof(boost::type_traits::yes_type)>{};
+   template <class T, std::size_t N> struct is_default_constructible<T[N]> : public is_default_constructible<T>{};
+   template <class T> struct is_default_constructible<T[]> : public is_default_constructible<T>{};
+   template <class T> struct is_default_constructible<T&> : public integral_constant<bool, false>{};
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+   template <class T> struct is_default_constructible<T&&> : public integral_constant<bool, false>{};
+#endif
+   template <> struct is_default_constructible<void> : public integral_constant<bool, false>{};
+   template <> struct is_default_constructible<void const> : public integral_constant<bool, false>{};
+   template <> struct is_default_constructible<void volatile> : public integral_constant<bool, false>{};
+   template <> struct is_default_constructible<void const volatile> : public integral_constant<bool, false>{};
+
+#else
+
+#include <boost/type_traits/is_pod.hpp>
+
+namespace boost{
+
+   // We don't know how to implement this, note we can not use has_trivial_constructor here
+   // because the correct implementation of that trait requires this one:
+   template <class T> struct is_default_constructible : public is_pod<T>{};
+   template <> struct is_default_constructible<void> : public integral_constant<bool, false>{};
+   template <> struct is_default_constructible<void const> : public integral_constant<bool, false>{};
+   template <> struct is_default_constructible<void volatile> : public integral_constant<bool, false>{};
+   template <> struct is_default_constructible<void const volatile> : public integral_constant<bool, false>{};
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_DEFAULT_CONSTRUCTIBLE_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_destructible.hpp b/third_party/boost/boost/type_traits/is_destructible.hpp
new file mode 100644
index 0000000..9f1e5d9
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_destructible.hpp
@@ -0,0 +1,60 @@
+
+//  (C) Copyright John Maddock 2015.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_DESTRUCTIBLE_HPP_INCLUDED
+#define BOOST_TT_IS_DESTRUCTIBLE_HPP_INCLUDED
+
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/detail/workaround.hpp>
+
+#if !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800)
+
+#include <boost/type_traits/detail/yes_no_type.hpp>
+#include <boost/type_traits/declval.hpp>
+
+namespace boost{
+
+   namespace detail{
+
+      struct is_destructible_imp
+      {
+         template<typename T, typename = decltype(boost::declval<T&>().~T())>
+         static boost::type_traits::yes_type test(int);
+         template<typename>
+         static boost::type_traits::no_type test(...);
+      };
+
+   }
+
+   template <class T> struct is_destructible : public integral_constant<bool, sizeof(detail::is_destructible_imp::test<T>(0)) == sizeof(boost::type_traits::yes_type)>{};
+
+#else
+
+#include <boost/type_traits/is_pod.hpp>
+#include <boost/type_traits/is_class.hpp>
+
+namespace boost{
+
+   // We don't know how to implement this:
+   template <class T> struct is_destructible : public integral_constant<bool, is_pod<T>::value || is_class<T>::value>{};
+#endif
+
+   template <> struct is_destructible<void> : public false_type{};
+   template <> struct is_destructible<void const> : public false_type{};
+   template <> struct is_destructible<void volatile> : public false_type{};
+   template <> struct is_destructible<void const volatile> : public false_type{};
+   template <class T> struct is_destructible<T&> : public is_destructible<T>{};
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+   template <class T> struct is_destructible<T&&> : public is_destructible<T>{};
+#endif
+   template <class T, std::size_t N> struct is_destructible<T[N]> : public is_destructible<T>{};
+   template <class T> struct is_destructible<T[]> : public is_destructible<T>{};
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_DESTRUCTIBLE_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_empty.hpp b/third_party/boost/boost/type_traits/is_empty.hpp
new file mode 100644
index 0000000..f57b82a
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_empty.hpp
@@ -0,0 +1,119 @@
+
+// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_EMPTY_HPP_INCLUDED
+#define BOOST_TT_IS_EMPTY_HPP_INCLUDED
+
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/detail/config.hpp>
+#include <boost/type_traits/intrinsics.hpp>
+
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/is_class.hpp>
+#include <boost/type_traits/add_reference.hpp>
+
+#ifndef BOOST_INTERNAL_IS_EMPTY
+#define BOOST_INTERNAL_IS_EMPTY(T) false
+#else
+#define BOOST_INTERNAL_IS_EMPTY(T) BOOST_IS_EMPTY(T)
+#endif
+
+namespace boost {
+
+namespace detail {
+
+
+#ifdef BOOST_MSVC
+#pragma warning(push)
+#pragma warning(disable:4624) // destructor could not be generated
+#endif
+
+template <typename T>
+struct empty_helper_t1 : public T
+{
+    empty_helper_t1();  // hh compiler bug workaround
+    int i[256];
+private:
+   // suppress compiler warnings:
+   empty_helper_t1(const empty_helper_t1&);
+   empty_helper_t1& operator=(const empty_helper_t1&);
+};
+
+#ifdef BOOST_MSVC
+#pragma warning(pop)
+#endif
+
+struct empty_helper_t2 { int i[256]; };
+
+#if !BOOST_WORKAROUND(__BORLANDC__, < 0x600)
+
+template <typename T, bool is_a_class = false>
+struct empty_helper
+{
+    BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+template <typename T>
+struct empty_helper<T, true>
+{
+    BOOST_STATIC_CONSTANT(
+        bool, value = (sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2))
+        );
+};
+
+template <typename T>
+struct is_empty_impl
+{
+    typedef typename remove_cv<T>::type cvt;
+    BOOST_STATIC_CONSTANT(
+        bool,
+        value = ( ::boost::detail::empty_helper<cvt,::boost::is_class<T>::value>::value || BOOST_INTERNAL_IS_EMPTY(cvt)));
+};
+
+#else // __BORLANDC__
+
+template <typename T, bool is_a_class, bool convertible_to_int>
+struct empty_helper
+{
+    BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+template <typename T>
+struct empty_helper<T, true, false>
+{
+    BOOST_STATIC_CONSTANT(bool, value = (
+        sizeof(empty_helper_t1<T>) == sizeof(empty_helper_t2)
+        ));
+};
+
+template <typename T>
+struct is_empty_impl
+{
+   typedef typename remove_cv<T>::type cvt;
+   typedef typename add_reference<T>::type r_type;
+
+   BOOST_STATIC_CONSTANT(
+       bool, value = (
+              ::boost::detail::empty_helper<
+                  cvt
+                , ::boost::is_class<T>::value
+                , ::boost::is_convertible< r_type,int>::value
+              >::value || BOOST_INTERNAL_IS_EMPTY(cvt));
+};
+
+#endif // __BORLANDC__
+
+} // namespace detail
+
+template <class T> struct is_empty : integral_constant<bool, ::boost::detail::is_empty_impl<T>::value> {};
+
+} // namespace boost
+
+#undef BOOST_INTERNAL_IS_EMPTY
+
+#endif // BOOST_TT_IS_EMPTY_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_enum.hpp b/third_party/boost/boost/type_traits/is_enum.hpp
new file mode 100644
index 0000000..73f162d
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_enum.hpp
@@ -0,0 +1,166 @@
+
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
+//  Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+
+#ifndef BOOST_TT_IS_ENUM_HPP_INCLUDED
+#define BOOST_TT_IS_ENUM_HPP_INCLUDED
+
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#ifndef BOOST_IS_ENUM
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/is_array.hpp>
+#ifdef __GNUC__
+#include <boost/type_traits/is_function.hpp>
+#endif
+#include <boost/type_traits/detail/config.hpp>
+#if defined(BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION)
+#  include <boost/type_traits/is_class.hpp>
+#  include <boost/type_traits/is_union.hpp>
+#endif
+#endif
+
+namespace boost {
+
+#ifndef BOOST_IS_ENUM
+#if !(defined(__BORLANDC__) && (__BORLANDC__ <= 0x551))
+
+namespace detail {
+
+#if defined(BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION)
+
+template <typename T>
+struct is_class_or_union
+{
+   BOOST_STATIC_CONSTANT(bool, value = ::boost::is_class<T>::value || ::boost::is_union<T>::value);
+};
+
+#else
+
+template <typename T>
+struct is_class_or_union
+{
+# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581))// we simply can't detect it this way.
+    BOOST_STATIC_CONSTANT(bool, value = false);
+# else
+    template <class U> static ::boost::type_traits::yes_type is_class_or_union_tester(void(U::*)(void));
+
+#  if BOOST_WORKAROUND(__MWERKS__, <= 0x3000) // no SFINAE
+    static ::boost::type_traits::no_type is_class_or_union_tester(...);
+    BOOST_STATIC_CONSTANT(
+        bool, value = sizeof(is_class_or_union_tester(0)) == sizeof(::boost::type_traits::yes_type));
+#  else
+    template <class U>
+    static ::boost::type_traits::no_type is_class_or_union_tester(...);
+    BOOST_STATIC_CONSTANT(
+        bool, value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(::boost::type_traits::yes_type));
+#  endif
+# endif
+};
+#endif
+
+struct int_convertible
+{
+    int_convertible(int);
+};
+
+// Don't evaluate convertibility to int_convertible unless the type
+// is non-arithmetic. This suppresses warnings with GCC.
+template <bool is_typename_arithmetic_or_reference = true>
+struct is_enum_helper
+{
+    template <typename T> struct type
+    {
+        BOOST_STATIC_CONSTANT(bool, value = false);
+    };
+};
+
+template <>
+struct is_enum_helper<false>
+{
+    template <typename T> struct type
+    {
+       static const bool value = ::boost::is_convertible<typename boost::add_reference<T>::type, ::boost::detail::int_convertible>::value;
+    };
+};
+
+template <typename T> struct is_enum_impl
+{
+   //typedef ::boost::add_reference<T> ar_t;
+   //typedef typename ar_t::type r_type;
+
+#if defined(__GNUC__)
+
+#ifdef BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION
+
+   // We MUST check for is_class_or_union on conforming compilers in
+   // order to correctly deduce that noncopyable types are not enums
+   // (dwa 2002/04/15)...
+   BOOST_STATIC_CONSTANT(bool, selector =
+           ::boost::is_arithmetic<T>::value
+         || ::boost::is_reference<T>::value
+         || ::boost::is_function<T>::value
+         || is_class_or_union<T>::value
+         || is_array<T>::value);
+#else
+   // ...however, not checking is_class_or_union on non-conforming
+   // compilers prevents a dependency recursion.
+   BOOST_STATIC_CONSTANT(bool, selector =
+           ::boost::is_arithmetic<T>::value
+         || ::boost::is_reference<T>::value
+         || ::boost::is_function<T>::value
+         || is_array<T>::value);
+#endif // BOOST_TT_HAS_CONFORMING_IS_CLASS_IMPLEMENTATION
+
+#else // !defined(__GNUC__):
+
+   BOOST_STATIC_CONSTANT(bool, selector =
+           ::boost::is_arithmetic<T>::value
+         || ::boost::is_reference<T>::value
+         || is_class_or_union<T>::value
+         || is_array<T>::value);
+
+#endif
+
+#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
+    typedef ::boost::detail::is_enum_helper<
+          ::boost::detail::is_enum_impl<T>::selector
+        > se_t;
+#else
+    typedef ::boost::detail::is_enum_helper<selector> se_t;
+#endif
+
+    typedef typename se_t::template type<T> helper;
+    BOOST_STATIC_CONSTANT(bool, value = helper::value);
+};
+
+} // namespace detail
+
+template <class T> struct is_enum : public integral_constant<bool, ::boost::detail::is_enum_impl<T>::value> {};
+
+#else // __BORLANDC__
+//
+// buggy is_convertible prevents working
+// implementation of is_enum:
+template <class T> struct is_enum : public integral_constant<bool, false> {};
+
+#endif
+
+#else // BOOST_IS_ENUM
+
+template <class T> struct is_enum : public integral_constant<bool, BOOST_IS_ENUM(T)> {};
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_ENUM_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_floating_point.hpp b/third_party/boost/boost/type_traits/is_floating_point.hpp
new file mode 100644
index 0000000..fef7fd7
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_floating_point.hpp
@@ -0,0 +1,30 @@
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000-2005.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TYPE_TRAITS_IS_FLOATING_HPP_INCLUDED
+#define BOOST_TYPE_TRAITS_IS_FLOATING_HPP_INCLUDED
+
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace boost {
+
+//* is a type T a floating-point type described in the standard (3.9.1p8)
+   template <class T> struct is_floating_point : public false_type{};
+   template <class T> struct is_floating_point<const T> : public is_floating_point<T>{};
+   template <class T> struct is_floating_point<volatile const T> : public is_floating_point<T>{};
+   template <class T> struct is_floating_point<volatile T> : public is_floating_point<T>{};
+   template<> struct is_floating_point<float> : public true_type{};
+   template<> struct is_floating_point<double> : public true_type{};
+   template<> struct is_floating_point<long double> : public true_type{};
+
+#if defined(BOOST_HAS_FLOAT128)
+   template<> struct is_floating_point<__float128> : public true_type{};
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TYPE_TRAITS_IS_FLOAT_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_function.hpp b/third_party/boost/boost/type_traits/is_function.hpp
new file mode 100644
index 0000000..f77c1f0
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_function.hpp
@@ -0,0 +1,102 @@
+
+//  Copyright 2000 John Maddock (john@johnmaddock.co.uk)
+//  Copyright 2002 Aleksey Gurtovoy (agurtovoy@meta-comm.com)
+//
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_FUNCTION_HPP_INCLUDED
+#define BOOST_TT_IS_FUNCTION_HPP_INCLUDED
+
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/detail/config.hpp>
+
+#if !defined(BOOST_TT_TEST_MS_FUNC_SIGS)
+#   include <boost/type_traits/detail/is_function_ptr_helper.hpp>
+#else
+#   include <boost/type_traits/detail/is_function_ptr_tester.hpp>
+#   include <boost/type_traits/detail/yes_no_type.hpp>
+#endif
+
+// is a type a function?
+// Please note that this implementation is unnecessarily complex:
+// we could just use !is_convertible<T*, const volatile void*>::value,
+// except that some compilers erroneously allow conversions from
+// function pointers to void*.
+
+namespace boost {
+
+#if !defined( __CODEGEARC__ )
+
+namespace detail {
+
+#if !defined(BOOST_TT_TEST_MS_FUNC_SIGS)
+template<bool is_ref = true>
+struct is_function_chooser
+{
+   template< typename T > struct result_
+      : public false_type {};
+};
+
+template <>
+struct is_function_chooser<false>
+{
+    template< typename T > struct result_
+        : public ::boost::type_traits::is_function_ptr_helper<T*> {};
+};
+
+template <typename T>
+struct is_function_impl
+    : public is_function_chooser< ::boost::is_reference<T>::value >
+        ::BOOST_NESTED_TEMPLATE result_<T>
+{
+};
+
+#else
+
+template <typename T>
+struct is_function_impl
+{
+#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
+#pragma warning(push)
+#pragma warning(disable:6334)
+#endif
+    static T* t;
+    BOOST_STATIC_CONSTANT(
+        bool, value = sizeof(::boost::type_traits::is_function_ptr_tester(t))
+        == sizeof(::boost::type_traits::yes_type)
+        );
+#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
+#pragma warning(pop)
+#endif
+};
+
+template <typename T>
+struct is_function_impl<T&> : public false_type
+{};
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+template <typename T>
+struct is_function_impl<T&&> : public false_type
+{};
+#endif
+
+#endif
+
+} // namespace detail
+
+#endif // !defined( __CODEGEARC__ )
+
+#if defined( __CODEGEARC__ )
+template <class T> struct is_function : integral_constant<bool, __is_function(T)> {};
+#else
+template <class T> struct is_function : integral_constant<bool, ::boost::detail::is_function_impl<T>::value> {};
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+template <class T> struct is_function<T&&> : public false_type {};
+#endif
+#endif
+} // namespace boost
+
+#endif // BOOST_TT_IS_FUNCTION_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_fundamental.hpp b/third_party/boost/boost/type_traits/is_fundamental.hpp
new file mode 100644
index 0000000..f58767a
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_fundamental.hpp
@@ -0,0 +1,26 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_FUNDAMENTAL_HPP_INCLUDED
+#define BOOST_TT_IS_FUNDAMENTAL_HPP_INCLUDED
+
+#include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/type_traits/is_void.hpp>
+
+namespace boost {
+
+//* is a type T a fundamental type described in the standard (3.9.1)
+#if defined( __CODEGEARC__ )
+template <class T> struct is_fundamental : public integral_constant<bool, __is_fundamental(T)> {};
+#else
+template <class T> struct is_fundamental : public integral_constant<bool, ::boost::is_arithmetic<T>::value || ::boost::is_void<T>::value> {};
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_FUNDAMENTAL_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_integral.hpp b/third_party/boost/boost/type_traits/is_integral.hpp
new file mode 100644
index 0000000..691cfad
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_integral.hpp
@@ -0,0 +1,89 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_INTEGRAL_HPP_INCLUDED
+#define BOOST_TT_IS_INTEGRAL_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace boost {
+
+#if defined( __CODEGEARC__ )
+   template <class T>
+   struct is_integral : public integral_constant<bool, __is_integral(T)> {};
+#else
+
+template <class T> struct is_integral : public false_type {};
+template <class T> struct is_integral<const T> : public is_integral<T> {};
+template <class T> struct is_integral<volatile const T> : public is_integral<T>{};
+template <class T> struct is_integral<volatile T> : public is_integral<T>{};
+
+//* is a type T an [cv-qualified-] integral type described in the standard (3.9.1p3)
+// as an extension we include long long, as this is likely to be added to the
+// standard at a later date
+template<> struct is_integral<unsigned char> : public true_type {};
+template<> struct is_integral<unsigned short> : public true_type{};
+template<> struct is_integral<unsigned int> : public true_type{};
+template<> struct is_integral<unsigned long> : public true_type{};
+
+template<> struct is_integral<signed char> : public true_type{};
+template<> struct is_integral<short> : public true_type{};
+template<> struct is_integral<int> : public true_type{};
+template<> struct is_integral<long> : public true_type{};
+
+template<> struct is_integral<char> : public true_type{};
+template<> struct is_integral<bool> : public true_type{};
+
+#ifndef BOOST_NO_INTRINSIC_WCHAR_T
+// If the following line fails to compile and you're using the Intel
+// compiler, see http://lists.boost.org/MailArchives/boost-users/msg06567.php,
+// and define BOOST_NO_INTRINSIC_WCHAR_T on the command line.
+template<> struct is_integral<wchar_t> : public true_type{};
+#endif
+
+// Same set of integral types as in boost/type_traits/integral_promotion.hpp.
+// Please, keep in sync. -- Alexander Nasonov
+#if (defined(BOOST_INTEL_CXX_VERSION) && defined(_MSC_VER) && (BOOST_INTEL_CXX_VERSION <= 600)) \
+    || (defined(__BORLANDC__) && (__BORLANDC__ == 0x600) && (_MSC_VER < 1300))
+template<> struct is_integral<unsigned __int8> : public true_type{};
+template<> struct is_integral<unsigned __int16> : public true_type{};
+template<> struct is_integral<unsigned __int32> : public true_type{};
+template<> struct is_integral<__int8> : public true_type{};
+template<> struct is_integral<__int16> : public true_type{};
+template<> struct is_integral<__int32> : public true_type{};
+#ifdef __BORLANDC__
+template<> struct is_integral<unsigned __int64> : public true_type{};
+template<> struct is_integral<__int64> : public true_type{};
+#endif
+#endif
+
+# if defined(BOOST_HAS_LONG_LONG)
+template<> struct is_integral< ::boost::ulong_long_type> : public true_type{};
+template<> struct is_integral< ::boost::long_long_type> : public true_type{};
+#elif defined(BOOST_HAS_MS_INT64)
+template<> struct is_integral<unsigned __int64> : public true_type{};
+template<> struct is_integral<__int64> : public true_type{};
+#endif
+
+#ifdef BOOST_HAS_INT128
+template<> struct is_integral<boost::int128_type> : public true_type{};
+template<> struct is_integral<boost::uint128_type> : public true_type{};
+#endif
+#ifndef BOOST_NO_CXX11_CHAR16_T
+template<> struct is_integral<char16_t> : public true_type{};
+#endif
+#ifndef BOOST_NO_CXX11_CHAR32_T
+template<> struct is_integral<char32_t> : public true_type{};
+#endif
+
+#endif  // non-CodeGear implementation
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_INTEGRAL_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_lvalue_reference.hpp b/third_party/boost/boost/type_traits/is_lvalue_reference.hpp
new file mode 100644
index 0000000..39e12ce
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_lvalue_reference.hpp
@@ -0,0 +1,49 @@
+
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes,
+//      Howard Hinnant and John Maddock 2000.
+//  (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001
+
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+//    Fixed is_pointer, is_lvalue_reference, is_const, is_volatile, is_same,
+//    is_member_pointer based on the Simulated Partial Specialization work
+//    of Mat Marcus and Jesse Jones. See  http://opensource.adobe.com or
+//    http://groups.yahoo.com/group/boost/message/5441
+//    Some workarounds in here use ideas suggested from "Generic<Programming>:
+//    Mappings between Types and Values"
+//    by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html).
+
+
+#ifndef BOOST_TT_IS_LVALUE_REFERENCE_HPP_INCLUDED
+#define BOOST_TT_IS_LVALUE_REFERENCE_HPP_INCLUDED
+
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace boost {
+
+#if defined( __CODEGEARC__ )
+   template <class T> struct is_lvalue_reference : public integral_constant<bool, __is_reference(T)>{};
+#else
+
+   template <class T> struct is_lvalue_reference : public false_type{};
+   template <class T> struct is_lvalue_reference<T&> : public true_type{};
+
+#if  defined(BOOST_ILLEGAL_CV_REFERENCES)
+// these are illegal specialisations; cv-qualifies applied to
+// references have no effect according to [8.3.2p1],
+// C++ Builder requires them though as it treats cv-qualified
+// references as distinct types...
+   template <class T> struct is_lvalue_reference<T&const> : public true_type{};
+   template <class T> struct is_lvalue_reference<T&volatile> : public true_type{};
+   template <class T> struct is_lvalue_reference<T&const volatile> : public true_type{};
+#endif
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_REFERENCE_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_member_function_pointer.hpp b/third_party/boost/boost/type_traits/is_member_function_pointer.hpp
new file mode 100644
index 0000000..c278f71
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_member_function_pointer.hpp
@@ -0,0 +1,120 @@
+
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
+//  Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+
+#ifndef BOOST_TT_IS_MEMBER_FUNCTION_POINTER_HPP_INCLUDED
+#define BOOST_TT_IS_MEMBER_FUNCTION_POINTER_HPP_INCLUDED
+
+#include <boost/type_traits/detail/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+#if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && !defined(BOOST_TT_TEST_MS_FUNC_SIGS)
+   //
+   // Note: we use the "workaround" version for MSVC because it works for
+   // __stdcall etc function types, where as the partial specialisation
+   // version does not do so.
+   //
+#   include <boost/type_traits/detail/is_mem_fun_pointer_impl.hpp>
+#   include <boost/type_traits/remove_cv.hpp>
+#   include <boost/type_traits/integral_constant.hpp>
+#else
+#   include <boost/type_traits/is_reference.hpp>
+#   include <boost/type_traits/is_array.hpp>
+#   include <boost/type_traits/detail/yes_no_type.hpp>
+#   include <boost/type_traits/detail/is_mem_fun_pointer_tester.hpp>
+#endif
+
+namespace boost {
+
+#if defined( __CODEGEARC__ )
+template <class T> struct is_member_function_pointer : public integral_constant<bool, __is_member_function_pointer( T )> {};
+#elif !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && !defined(BOOST_TT_TEST_MS_FUNC_SIGS)
+
+template <class T> struct is_member_function_pointer
+   : public ::boost::integral_constant<bool, ::boost::type_traits::is_mem_fun_pointer_impl<typename remove_cv<T>::type>::value>{};
+
+#else
+
+namespace detail {
+
+#ifndef __BORLANDC__
+
+template <bool>
+struct is_mem_fun_pointer_select
+{
+   template <class T> struct result_ : public false_type{};
+};
+
+template <>
+struct is_mem_fun_pointer_select<false>
+{
+    template <typename T> struct result_
+    {
+#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
+#pragma warning(push)
+#pragma warning(disable:6334)
+#endif
+        static T* make_t;
+        typedef result_<T> self_type;
+
+        BOOST_STATIC_CONSTANT(
+            bool, value = (
+                1 == sizeof(::boost::type_traits::is_mem_fun_pointer_tester(self_type::make_t))
+            ));
+#if BOOST_WORKAROUND(BOOST_MSVC_FULL_VER, >= 140050000)
+#pragma warning(pop)
+#endif
+    };
+};
+
+template <typename T>
+struct is_member_function_pointer_impl
+    : public is_mem_fun_pointer_select<
+      ::boost::is_reference<T>::value || ::boost::is_array<T>::value>::template result_<T>{};
+
+template <typename T>
+struct is_member_function_pointer_impl<T&> : public false_type{};
+
+#else // Borland C++
+
+template <typename T>
+struct is_member_function_pointer_impl
+{
+   static T* m_t;
+   BOOST_STATIC_CONSTANT(
+              bool, value =
+               (1 == sizeof(type_traits::is_mem_fun_pointer_tester(m_t))) );
+};
+
+template <typename T>
+struct is_member_function_pointer_impl<T&>
+{
+   BOOST_STATIC_CONSTANT(bool, value = false);
+};
+
+#endif
+
+template<> struct is_member_function_pointer_impl<void> : public false_type{};
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template<> struct is_member_function_pointer_impl<void const> : public false_type{};
+template<> struct is_member_function_pointer_impl<void const volatile> : public false_type{};
+template<> struct is_member_function_pointer_impl<void volatile> : public false_type{};
+#endif
+
+} // namespace detail
+
+template <class T>
+struct is_member_function_pointer
+   : public integral_constant<bool, ::boost::detail::is_member_function_pointer_impl<T>::value>{};
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_MEMBER_FUNCTION_POINTER_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_member_pointer.hpp b/third_party/boost/boost/type_traits/is_member_pointer.hpp
new file mode 100644
index 0000000..80e9b44
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_member_pointer.hpp
@@ -0,0 +1,45 @@
+
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes,
+//      Howard Hinnant and John Maddock 2000.
+//  (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001
+
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+//    Fixed is_pointer, is_reference, is_const, is_volatile, is_same,
+//    is_member_pointer based on the Simulated Partial Specialization work
+//    of Mat Marcus and Jesse Jones. See  http://opensource.adobe.com or
+//    http://groups.yahoo.com/group/boost/message/5441
+//    Some workarounds in here use ideas suggested from "Generic<Programming>:
+//    Mappings between Types and Values"
+//    by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html).
+
+
+#ifndef BOOST_TT_IS_MEMBER_POINTER_HPP_INCLUDED
+#define BOOST_TT_IS_MEMBER_POINTER_HPP_INCLUDED
+
+#include <boost/detail/workaround.hpp>
+#include <boost/type_traits/is_member_function_pointer.hpp>
+
+namespace boost {
+
+#if defined( __CODEGEARC__ )
+template <class T> struct is_member_pointer : public integral_constant<bool, __is_member_pointer(T)>{};
+#else
+template <class T> struct is_member_pointer : public integral_constant<bool, ::boost::is_member_function_pointer<T>::value>{};
+template <class T, class U> struct is_member_pointer<U T::* > : public true_type{};
+
+#if !BOOST_WORKAROUND(__MWERKS__,<=0x3003) && !BOOST_WORKAROUND(__IBMCPP__, <=600)
+template <class T, class U> struct is_member_pointer<U T::*const> : public true_type{};
+template <class T, class U> struct is_member_pointer<U T::*const volatile> : public true_type{};
+template <class T, class U> struct is_member_pointer<U T::*volatile> : public true_type{};
+#endif
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_MEMBER_POINTER_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_nothrow_move_assignable.hpp b/third_party/boost/boost/type_traits/is_nothrow_move_assignable.hpp
new file mode 100644
index 0000000..96db1a0
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_nothrow_move_assignable.hpp
@@ -0,0 +1,81 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  (C) Copyright Eric Friedman 2002-2003.
+//  (C) Copyright Antony Polukhin 2013.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_NOTHROW_MOVE_ASSIGNABLE_HPP_INCLUDED
+#define BOOST_TT_IS_NOTHROW_MOVE_ASSIGNABLE_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/type_traits/has_trivial_move_assign.hpp>
+#include <boost/type_traits/has_nothrow_assign.hpp>
+#include <boost/type_traits/is_array.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/declval.hpp>
+
+namespace boost {
+
+#ifdef BOOST_IS_NOTHROW_MOVE_ASSIGN
+
+template <class T>
+struct is_nothrow_move_assignable : public integral_constant<bool, BOOST_IS_NOTHROW_MOVE_ASSIGN(T)>{};
+template <class T> struct is_nothrow_move_assignable<T const> : public false_type{};
+template <class T> struct is_nothrow_move_assignable<T volatile> : public false_type{};
+template <class T> struct is_nothrow_move_assignable<T const volatile> : public false_type{};
+template <class T> struct is_nothrow_move_assignable<T&> : public false_type{};
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+template <class T> struct is_nothrow_move_assignable<T&&> : public false_type{};
+#endif
+
+#elif !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_SFINAE_EXPR)
+
+namespace detail{
+
+template <class T, class Enable = void>
+struct false_or_cpp11_noexcept_move_assignable: public ::boost::false_type {};
+
+template <class T>
+struct false_or_cpp11_noexcept_move_assignable <
+        T,
+        typename ::boost::enable_if_c<sizeof(T) && BOOST_NOEXCEPT_EXPR(::boost::declval<T&>() = ::boost::declval<T>())>::type
+    > : public ::boost::integral_constant<bool, BOOST_NOEXCEPT_EXPR(::boost::declval<T&>() = ::boost::declval<T>())>
+{};
+
+}
+
+template <class T>
+struct is_nothrow_move_assignable : public integral_constant<bool, ::boost::detail::false_or_cpp11_noexcept_move_assignable<T>::value>{};
+
+template <class T> struct is_nothrow_move_assignable<T const> : public ::boost::false_type {};
+template <class T> struct is_nothrow_move_assignable<T const volatile> : public ::boost::false_type{};
+template <class T> struct is_nothrow_move_assignable<T volatile> : public ::boost::false_type{};
+template <class T> struct is_nothrow_move_assignable<T&> : public ::boost::false_type{};
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+template <class T> struct is_nothrow_move_assignable<T&&> : public ::boost::false_type{};
+#endif
+
+#else
+
+template <class T>
+struct is_nothrow_move_assignable : public integral_constant<bool,
+   (::boost::has_trivial_move_assign<T>::value || ::boost::has_nothrow_assign<T>::value) &&  ! ::boost::is_array<T>::value>{};
+
+#endif
+
+
+template <> struct is_nothrow_move_assignable<void> : public false_type{};
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template <> struct is_nothrow_move_assignable<void const> : public false_type{};
+template <> struct is_nothrow_move_assignable<void const volatile> : public false_type{};
+template <> struct is_nothrow_move_assignable<void volatile> : public false_type{};
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_NOTHROW_MOVE_ASSIGNABLE_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_nothrow_move_constructible.hpp b/third_party/boost/boost/type_traits/is_nothrow_move_constructible.hpp
new file mode 100644
index 0000000..8f4cee2
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_nothrow_move_constructible.hpp
@@ -0,0 +1,86 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  (C) Copyright Eric Friedman 2002-2003.
+//  (C) Copyright Antony Polukhin 2013.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_NOTHROW_MOVE_CONSTRUCTIBLE_HPP_INCLUDED
+#define BOOST_TT_IS_NOTHROW_MOVE_CONSTRUCTIBLE_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/detail/workaround.hpp>
+
+#ifdef BOOST_IS_NOTHROW_MOVE_CONSTRUCT
+
+namespace boost {
+
+template <class T>
+struct is_nothrow_move_constructible : public integral_constant<bool, BOOST_IS_NOTHROW_MOVE_CONSTRUCT(T)>{};
+
+template <class T> struct is_nothrow_move_constructible<volatile T> : public ::boost::false_type {};
+template <class T> struct is_nothrow_move_constructible<const volatile T> : public ::boost::false_type{};
+
+#elif !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_SFINAE_EXPR) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40700)
+
+#include <boost/type_traits/declval.hpp>
+#include <boost/utility/enable_if.hpp>
+
+namespace boost{ namespace detail{
+
+template <class T, class Enable = void>
+struct false_or_cpp11_noexcept_move_constructible: public ::boost::false_type {};
+
+template <class T>
+struct false_or_cpp11_noexcept_move_constructible <
+        T,
+        typename ::boost::enable_if_c<sizeof(T) && BOOST_NOEXCEPT_EXPR(T(::boost::declval<T>()))>::type
+    > : public ::boost::integral_constant<bool, BOOST_NOEXCEPT_EXPR(T(::boost::declval<T>()))>
+{};
+
+}
+
+template <class T> struct is_nothrow_move_constructible
+   : public integral_constant<bool, ::boost::detail::false_or_cpp11_noexcept_move_constructible<T>::value>{};
+
+template <class T> struct is_nothrow_move_constructible<volatile T> : public ::boost::false_type {};
+template <class T> struct is_nothrow_move_constructible<const volatile T> : public ::boost::false_type{};
+template <class T, std::size_t N> struct is_nothrow_move_constructible<T[N]> : public ::boost::false_type{};
+template <class T> struct is_nothrow_move_constructible<T[]> : public ::boost::false_type{};
+
+#else
+
+#include <boost/type_traits/has_trivial_move_constructor.hpp>
+#include <boost/type_traits/has_nothrow_copy.hpp>
+#include <boost/type_traits/is_array.hpp>
+
+namespace boost{
+
+template <class T>
+struct is_nothrow_move_constructible
+   : public integral_constant<bool,
+   (::boost::has_trivial_move_constructor<T>::value || ::boost::has_nothrow_copy<T>::value) && !::boost::is_array<T>::value>
+{};
+
+#endif
+
+template <> struct is_nothrow_move_constructible<void> : false_type{};
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template <> struct is_nothrow_move_constructible<void const> : false_type{};
+template <> struct is_nothrow_move_constructible<void volatile> : false_type{};
+template <> struct is_nothrow_move_constructible<void const volatile> : false_type{};
+#endif
+// References are always trivially constructible, even if the thing they reference is not:
+template <class T> struct is_nothrow_move_constructible<T&> : public ::boost::true_type{};
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+template <class T> struct is_nothrow_move_constructible<T&&> : public ::boost::true_type{};
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_NOTHROW_MOVE_CONSTRUCTIBLE_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_pod.hpp b/third_party/boost/boost/type_traits/is_pod.hpp
new file mode 100644
index 0000000..9204c93
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_pod.hpp
@@ -0,0 +1,58 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_POD_HPP_INCLUDED
+#define BOOST_TT_IS_POD_HPP_INCLUDED
+
+#include <boost/type_traits/detail/config.hpp>
+#include <boost/type_traits/is_void.hpp>
+#include <boost/type_traits/is_scalar.hpp>
+#include <boost/type_traits/intrinsics.hpp>
+
+#ifdef __SUNPRO_CC
+#include <boost/type_traits/is_function.hpp>
+#endif
+
+#include <cstddef>
+
+#ifndef BOOST_IS_POD
+#define BOOST_INTERNAL_IS_POD(T) false
+#else
+#define BOOST_INTERNAL_IS_POD(T) BOOST_IS_POD(T)
+#endif
+
+namespace boost {
+
+// forward declaration, needed by 'is_pod_array_helper' template below
+template< typename T > struct is_POD;
+
+template <typename T> struct is_pod
+: public integral_constant<bool, ::boost::is_scalar<T>::value || ::boost::is_void<T>::value || BOOST_INTERNAL_IS_POD(T)>
+{};
+
+#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS)
+template <typename T, std::size_t sz> struct is_pod<T[sz]> : public is_pod<T>{};
+#endif
+
+
+// the following help compilers without partial specialization support:
+template<> struct is_pod<void> : public true_type{};
+
+#ifndef BOOST_NO_CV_VOID_SPECIALIZATIONS
+template<> struct is_pod<void const> : public true_type{};
+template<> struct is_pod<void const volatile> : public true_type{};
+template<> struct is_pod<void volatile> : public true_type{};
+#endif
+
+template<class T> struct is_POD : public is_pod<T>{};
+
+} // namespace boost
+
+#undef BOOST_INTERNAL_IS_POD
+
+#endif // BOOST_TT_IS_POD_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_pointer.hpp b/third_party/boost/boost/type_traits/is_pointer.hpp
new file mode 100644
index 0000000..55f8a3e
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_pointer.hpp
@@ -0,0 +1,47 @@
+
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes,
+//      Howard Hinnant and John Maddock 2000.
+//  (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001
+
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+//    Fixed is_pointer, is_reference, is_const, is_volatile, is_same,
+//    is_member_pointer based on the Simulated Partial Specialization work
+//    of Mat Marcus and Jesse Jones. See  http://opensource.adobe.com or
+//    http://groups.yahoo.com/group/boost/message/5441
+//    Some workarounds in here use ideas suggested from "Generic<Programming>:
+//    Mappings between Types and Values"
+//    by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html).
+
+
+#ifndef BOOST_TT_IS_POINTER_HPP_INCLUDED
+#define BOOST_TT_IS_POINTER_HPP_INCLUDED
+
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace boost {
+
+#if defined( __CODEGEARC__ )
+template <class T> struct is_pointer : public integral_constant<bool, __is_pointer(T)>{};
+#else
+template <class T> struct is_pointer : public false_type{};
+template <class T> struct is_pointer<T*> : public true_type{};
+template <class T> struct is_pointer<T*const> : public true_type{};
+template <class T> struct is_pointer<T*const volatile> : public true_type{};
+template <class T> struct is_pointer<T*volatile> : public true_type{};
+
+#ifdef BOOST_MSVC
+template <class T> struct is_pointer<T const> : public is_pointer<T>{};
+template <class T> struct is_pointer<T const volatile> : public is_pointer<T>{};
+template <class T> struct is_pointer<T volatile> : public is_pointer<T>{};
+#endif
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_POINTER_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_reference.hpp b/third_party/boost/boost/type_traits/is_reference.hpp
new file mode 100644
index 0000000..4584a2d
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_reference.hpp
@@ -0,0 +1,29 @@
+
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes,
+//      Howard Hinnant and John Maddock 2000, 2010.
+//  (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001
+
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_REFERENCE_HPP_INCLUDED
+#define BOOST_TT_IS_REFERENCE_HPP_INCLUDED
+
+#include <boost/type_traits/is_lvalue_reference.hpp>
+#include <boost/type_traits/is_rvalue_reference.hpp>
+
+namespace boost {
+
+template <class T> struct is_reference
+   : public
+   integral_constant<
+      bool,
+      ::boost::is_lvalue_reference<T>::value || ::boost::is_rvalue_reference<T>::value>
+{};
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_REFERENCE_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_rvalue_reference.hpp b/third_party/boost/boost/type_traits/is_rvalue_reference.hpp
new file mode 100644
index 0000000..df7a1af
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_rvalue_reference.hpp
@@ -0,0 +1,24 @@
+
+//  (C) John Maddock 2010.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_RVALUE_REFERENCE_HPP_INCLUDED
+#define BOOST_TT_IS_RVALUE_REFERENCE_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace boost {
+
+template <class T> struct is_rvalue_reference : public false_type {};
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+template <class T> struct is_rvalue_reference<T&&> : public true_type {};
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_REFERENCE_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_same.hpp b/third_party/boost/boost/type_traits/is_same.hpp
new file mode 100644
index 0000000..6a0bd7c
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_same.hpp
@@ -0,0 +1,40 @@
+
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes,
+//      Howard Hinnant and John Maddock 2000.
+//  (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001
+
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+//    Fixed is_pointer, is_reference, is_const, is_volatile, is_same,
+//    is_member_pointer based on the Simulated Partial Specialization work
+//    of Mat Marcus and Jesse Jones. See  http://opensource.adobe.com or
+//    http://groups.yahoo.com/group/boost/message/5441
+//    Some workarounds in here use ideas suggested from "Generic<Programming>:
+//    Mappings between Types and Values"
+//    by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html).
+
+
+#ifndef BOOST_TT_IS_SAME_HPP_INCLUDED
+#define BOOST_TT_IS_SAME_HPP_INCLUDED
+
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace boost {
+
+
+   template <class T, class U> struct is_same : public false_type {};
+   template <class T> struct is_same<T,T> : public true_type {};
+#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
+// without this, Borland's compiler gives the wrong answer for
+// references to arrays:
+   template <class T> struct is_same<T&, T&> : public true_type{};
+#endif
+
+
+} // namespace boost
+
+#endif  // BOOST_TT_IS_SAME_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_scalar.hpp b/third_party/boost/boost/type_traits/is_scalar.hpp
new file mode 100644
index 0000000..3031440
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_scalar.hpp
@@ -0,0 +1,27 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_SCALAR_HPP_INCLUDED
+#define BOOST_TT_IS_SCALAR_HPP_INCLUDED
+
+#include <boost/type_traits/is_arithmetic.hpp>
+#include <boost/type_traits/is_enum.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/type_traits/is_member_pointer.hpp>
+#include <boost/config.hpp>
+
+namespace boost {
+
+template <typename T>
+struct is_scalar
+   : public integral_constant<bool, ::boost::is_arithmetic<T>::value || ::boost::is_enum<T>::value || ::boost::is_pointer<T>::value || ::boost::is_member_pointer<T>::value>
+{};
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_SCALAR_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_signed.hpp b/third_party/boost/boost/type_traits/is_signed.hpp
new file mode 100644
index 0000000..93d7285
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_signed.hpp
@@ -0,0 +1,163 @@
+
+//  (C) Copyright John Maddock 2005.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+
+#ifndef BOOST_TT_IS_SIGNED_HPP_INCLUDED
+#define BOOST_TT_IS_SIGNED_HPP_INCLUDED
+
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/is_enum.hpp>
+#include <climits>
+
+namespace boost {
+
+#if !defined( __CODEGEARC__ )
+
+#if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1310) && \
+    !(defined(__EDG_VERSION__) && __EDG_VERSION__ <= 238) &&\
+    !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
+
+namespace detail{
+
+template <class T>
+struct is_signed_values
+{
+   //
+   // Note that we cannot use BOOST_STATIC_CONSTANT here, using enum's
+   // rather than "real" static constants simply doesn't work or give
+   // the correct answer.
+   //
+   typedef typename remove_cv<T>::type no_cv_t;
+   static const no_cv_t minus_one = (static_cast<no_cv_t>(-1));
+   static const no_cv_t zero = (static_cast<no_cv_t>(0));
+};
+
+template <class T>
+struct is_signed_helper
+{
+   typedef typename remove_cv<T>::type no_cv_t;
+   BOOST_STATIC_CONSTANT(bool, value = (!(::boost::detail::is_signed_values<T>::minus_one  > boost::detail::is_signed_values<T>::zero)));
+};
+
+template <bool integral_type>
+struct is_signed_select_helper
+{
+   template <class T>
+   struct rebind
+   {
+      typedef is_signed_helper<T> type;
+   };
+};
+
+template <>
+struct is_signed_select_helper<false>
+{
+   template <class T>
+   struct rebind
+   {
+      typedef false_type type;
+   };
+};
+
+template <class T>
+struct is_signed_impl
+{
+   typedef ::boost::detail::is_signed_select_helper< ::boost::is_integral<T>::value || ::boost::is_enum<T>::value> selector;
+   typedef typename selector::template rebind<T> binder;
+   typedef typename binder::type type;
+   BOOST_STATIC_CONSTANT(bool, value = type::value);
+};
+
+}
+
+template <class T> struct is_signed : public integral_constant<bool, boost::detail::is_signed_impl<T>::value> {};
+
+#else
+
+template <class T> struct is_signed : public false_type{};
+
+#endif
+
+#else //defined( __CODEGEARC__ )
+   template <class T> struct is_signed : public integral_constant<bool, __is_signed(T)>{};
+#endif
+
+template <> struct is_signed<signed char> : public true_type{};
+template <> struct is_signed<const signed char> : public true_type{};
+template <> struct is_signed<volatile signed char> : public true_type{};
+template <> struct is_signed<const volatile signed char> : public true_type{};
+template <> struct is_signed<short> : public true_type{};
+template <> struct is_signed<const short> : public true_type{};
+template <> struct is_signed<volatile short> : public true_type{};
+template <> struct is_signed<const volatile short> : public true_type{};
+template <> struct is_signed<int> : public true_type{};
+template <> struct is_signed<const int> : public true_type{};
+template <> struct is_signed<volatile int> : public true_type{};
+template <> struct is_signed<const volatile int> : public true_type{};
+template <> struct is_signed<long> : public true_type{};
+template <> struct is_signed<const long> : public true_type{};
+template <> struct is_signed<volatile long> : public true_type{};
+template <> struct is_signed<const volatile long> : public true_type{};
+
+template <> struct is_signed<unsigned char> : public false_type{};
+template <> struct is_signed<const unsigned char> : public false_type{};
+template <> struct is_signed<volatile unsigned char> : public false_type{};
+template <> struct is_signed<const volatile unsigned char> : public false_type{};
+template <> struct is_signed<unsigned short> : public false_type{};
+template <> struct is_signed<const unsigned short> : public false_type{};
+template <> struct is_signed<volatile unsigned short> : public false_type{};
+template <> struct is_signed<const volatile unsigned short> : public false_type{};
+template <> struct is_signed<unsigned int> : public false_type{};
+template <> struct is_signed<const unsigned int> : public false_type{};
+template <> struct is_signed<volatile unsigned int> : public false_type{};
+template <> struct is_signed<const volatile unsigned int> : public false_type{};
+template <> struct is_signed<unsigned long> : public false_type{};
+template <> struct is_signed<const unsigned long> : public false_type{};
+template <> struct is_signed<volatile unsigned long> : public false_type{};
+template <> struct is_signed<const volatile unsigned long> : public false_type{};
+#ifdef BOOST_HAS_LONG_LONG
+template <> struct is_signed< ::boost::long_long_type> : public true_type{};
+template <> struct is_signed<const ::boost::long_long_type> : public true_type{};
+template <> struct is_signed<volatile ::boost::long_long_type> : public true_type{};
+template <> struct is_signed<const volatile ::boost::long_long_type> : public true_type{};
+
+template <> struct is_signed< ::boost::ulong_long_type> : public false_type{};
+template <> struct is_signed<const ::boost::ulong_long_type> : public false_type{};
+template <> struct is_signed<volatile ::boost::ulong_long_type> : public false_type{};
+template <> struct is_signed<const volatile ::boost::ulong_long_type> : public false_type{};
+#endif
+#if defined(CHAR_MIN)
+#if CHAR_MIN != 0
+template <> struct is_signed<char> : public true_type{};
+template <> struct is_signed<const char> : public true_type{};
+template <> struct is_signed<volatile char> : public true_type{};
+template <> struct is_signed<const volatile char> : public true_type{};
+#else
+template <> struct is_signed<char> : public false_type{};
+template <> struct is_signed<const char> : public false_type{};
+template <> struct is_signed<volatile char> : public false_type{};
+template <> struct is_signed<const volatile char> : public false_type{};
+#endif
+#endif
+#if defined(WCHAR_MIN) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
+#if WCHAR_MIN != 0
+template <> struct is_signed<wchar_t> : public true_type{};
+template <> struct is_signed<const wchar_t> : public true_type{};
+template <> struct is_signed<volatile wchar_t> : public true_type{};
+template <> struct is_signed<const volatile wchar_t> : public true_type{};
+#else
+template <> struct is_signed<wchar_t> : public false_type{};
+template <> struct is_signed<const wchar_t> : public false_type{};
+template <> struct is_signed<volatile wchar_t> : public false_type{};
+template <> struct is_signed<const volatile wchar_t> : public false_type{};
+#endif
+#endif
+} // namespace boost
+
+#endif // BOOST_TT_IS_MEMBER_FUNCTION_POINTER_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_stateless.hpp b/third_party/boost/boost/type_traits/is_stateless.hpp
new file mode 100644
index 0000000..8a008ca
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_stateless.hpp
@@ -0,0 +1,33 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_STATELESS_HPP_INCLUDED
+#define BOOST_TT_IS_STATELESS_HPP_INCLUDED
+
+#include <boost/type_traits/has_trivial_constructor.hpp>
+#include <boost/type_traits/has_trivial_copy.hpp>
+#include <boost/type_traits/has_trivial_destructor.hpp>
+#include <boost/type_traits/is_class.hpp>
+#include <boost/type_traits/is_empty.hpp>
+#include <boost/config.hpp>
+
+namespace boost {
+
+template <typename T>
+struct is_stateless
+ : public integral_constant<bool,
+      (::boost::has_trivial_constructor<T>::value
+      && ::boost::has_trivial_copy<T>::value
+      && ::boost::has_trivial_destructor<T>::value
+      && ::boost::is_class<T>::value
+      && ::boost::is_empty<T>::value)>
+{};
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_STATELESS_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_union.hpp b/third_party/boost/boost/type_traits/is_union.hpp
new file mode 100644
index 0000000..da8b4b2
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_union.hpp
@@ -0,0 +1,31 @@
+
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
+//  Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+
+#ifndef BOOST_TT_IS_UNION_HPP_INCLUDED
+#define BOOST_TT_IS_UNION_HPP_INCLUDED
+
+#include <boost/type_traits/intrinsics.hpp>
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace boost {
+
+#ifdef BOOST_IS_UNION
+template <class T> struct is_union : public integral_constant<bool, BOOST_IS_UNION(T)> {};
+#else
+template <class T> struct is_union : public integral_constant<bool, false> {};
+#endif
+
+template <class T> struct is_union<T const> : public is_union<T>{};
+template <class T> struct is_union<T volatile const> : public is_union<T>{};
+template <class T> struct is_union<T volatile> : public is_union<T>{};
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_UNION_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_unsigned.hpp b/third_party/boost/boost/type_traits/is_unsigned.hpp
new file mode 100644
index 0000000..b97e474
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_unsigned.hpp
@@ -0,0 +1,163 @@
+
+//  (C) Copyright John Maddock 2005.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+
+#ifndef BOOST_TT_IS_UNSIGNED_HPP_INCLUDED
+#define BOOST_TT_IS_UNSIGNED_HPP_INCLUDED
+
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_enum.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+
+#include <climits>
+
+namespace boost {
+
+#if !defined( __CODEGEARC__ )
+
+#if !(defined(BOOST_MSVC) && BOOST_MSVC <= 1310) &&\
+    !(defined(__EDG_VERSION__) && __EDG_VERSION__ <= 238) &&\
+    !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
+
+namespace detail{
+
+template <class T>
+struct is_unsigned_values
+{
+   //
+   // Note that we cannot use BOOST_STATIC_CONSTANT here, using enum's
+   // rather than "real" static constants simply doesn't work or give
+   // the correct answer.
+   //
+   typedef typename remove_cv<T>::type no_cv_t;
+   static const no_cv_t minus_one = (static_cast<no_cv_t>(-1));
+   static const no_cv_t zero = (static_cast<no_cv_t>(0));
+};
+
+template <class T>
+struct is_ununsigned_helper
+{
+   BOOST_STATIC_CONSTANT(bool, value = (::boost::detail::is_unsigned_values<T>::minus_one > ::boost::detail::is_unsigned_values<T>::zero));
+};
+
+template <bool integral_type>
+struct is_unsigned_select_helper
+{
+   template <class T>
+   struct rebind
+   {
+      typedef is_ununsigned_helper<T> type;
+   };
+};
+
+template <>
+struct is_unsigned_select_helper<false>
+{
+   template <class T>
+   struct rebind
+   {
+      typedef false_type type;
+   };
+};
+
+template <class T>
+struct is_unsigned
+{
+   typedef ::boost::detail::is_unsigned_select_helper< ::boost::is_integral<T>::value || ::boost::is_enum<T>::value > selector;
+   typedef typename selector::template rebind<T> binder;
+   typedef typename binder::type type;
+   BOOST_STATIC_CONSTANT(bool, value = type::value);
+};
+
+} // namespace detail
+
+template <class T> struct is_unsigned : public integral_constant<bool, boost::detail::is_unsigned<T>::value> {};
+
+#else
+
+template <class T> struct is_unsigned : public false_type{};
+
+#endif
+
+#else // defined( __CODEGEARC__ )
+template <class T> struct is_unsigned : public integral_constant<bool, __is_unsigned(T)> {};
+#endif
+
+template <> struct is_unsigned<unsigned char> : public true_type{};
+template <> struct is_unsigned<const unsigned char> : public true_type{};
+template <> struct is_unsigned<volatile unsigned char> : public true_type{};
+template <> struct is_unsigned<const volatile unsigned char> : public true_type{};
+template <> struct is_unsigned<unsigned short> : public true_type{};
+template <> struct is_unsigned<const unsigned short> : public true_type{};
+template <> struct is_unsigned<volatile unsigned short> : public true_type{};
+template <> struct is_unsigned<const volatile unsigned short> : public true_type{};
+template <> struct is_unsigned<unsigned int> : public true_type{};
+template <> struct is_unsigned<const unsigned int> : public true_type{};
+template <> struct is_unsigned<volatile unsigned int> : public true_type{};
+template <> struct is_unsigned<const volatile unsigned int> : public true_type{};
+template <> struct is_unsigned<unsigned long> : public true_type{};
+template <> struct is_unsigned<const unsigned long> : public true_type{};
+template <> struct is_unsigned<volatile unsigned long> : public true_type{};
+template <> struct is_unsigned<const volatile unsigned long> : public true_type{};
+
+template <> struct is_unsigned<signed char> : public false_type{};
+template <> struct is_unsigned<const signed char> : public false_type{};
+template <> struct is_unsigned<volatile signed char> : public false_type{};
+template <> struct is_unsigned<const volatile signed char> : public false_type{};
+template <> struct is_unsigned< short> : public false_type{};
+template <> struct is_unsigned<const  short> : public false_type{};
+template <> struct is_unsigned<volatile  short> : public false_type{};
+template <> struct is_unsigned<const volatile  short> : public false_type{};
+template <> struct is_unsigned< int> : public false_type{};
+template <> struct is_unsigned<const  int> : public false_type{};
+template <> struct is_unsigned<volatile  int> : public false_type{};
+template <> struct is_unsigned<const volatile  int> : public false_type{};
+template <> struct is_unsigned< long> : public false_type{};
+template <> struct is_unsigned<const  long> : public false_type{};
+template <> struct is_unsigned<volatile  long> : public false_type{};
+template <> struct is_unsigned<const volatile  long> : public false_type{};
+#ifdef BOOST_HAS_LONG_LONG
+template <> struct is_unsigned< ::boost::ulong_long_type> : public true_type{};
+template <> struct is_unsigned<const ::boost::ulong_long_type> : public true_type{};
+template <> struct is_unsigned<volatile ::boost::ulong_long_type> : public true_type{};
+template <> struct is_unsigned<const volatile ::boost::ulong_long_type> : public true_type{};
+
+template <> struct is_unsigned< ::boost::long_long_type> : public false_type{};
+template <> struct is_unsigned<const ::boost::long_long_type> : public false_type{};
+template <> struct is_unsigned<volatile ::boost::long_long_type> : public false_type{};
+template <> struct is_unsigned<const volatile ::boost::long_long_type> : public false_type{};
+#endif
+#if defined(CHAR_MIN)
+#if CHAR_MIN == 0
+template <> struct is_unsigned<char> : public true_type{};
+template <> struct is_unsigned<const char> : public true_type{};
+template <> struct is_unsigned<volatile char> : public true_type{};
+template <> struct is_unsigned<const volatile char> : public true_type{};
+#else
+template <> struct is_unsigned<char> : public false_type{};
+template <> struct is_unsigned<const char> : public false_type{};
+template <> struct is_unsigned<volatile char> : public false_type{};
+template <> struct is_unsigned<const volatile char> : public false_type{};
+#endif
+#endif
+#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) && defined(WCHAR_MIN)
+#if WCHAR_MIN == 0
+template <> struct is_unsigned<wchar_t> : public true_type{};
+template <> struct is_unsigned<const wchar_t> : public true_type{};
+template <> struct is_unsigned<volatile wchar_t> : public true_type{};
+template <> struct is_unsigned<const volatile wchar_t> : public true_type{};
+#else
+template <> struct is_unsigned<wchar_t> : public false_type{};
+template <> struct is_unsigned<const wchar_t> : public false_type{};
+template <> struct is_unsigned<volatile wchar_t> : public false_type{};
+template <> struct is_unsigned<const volatile wchar_t> : public false_type{};
+#endif
+#endif
+} // namespace boost
+
+#endif // BOOST_TT_IS_MEMBER_FUNCTION_POINTER_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_void.hpp b/third_party/boost/boost/type_traits/is_void.hpp
new file mode 100644
index 0000000..183f8ab
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_void.hpp
@@ -0,0 +1,26 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_IS_VOID_HPP_INCLUDED
+#define BOOST_TT_IS_VOID_HPP_INCLUDED
+
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace boost {
+
+template <class T>
+struct is_void : public false_type {};
+
+template<> struct is_void<void> : public true_type {};
+template<> struct is_void<const void> : public true_type{};
+template<> struct is_void<const volatile void> : public true_type{};
+template<> struct is_void<volatile void> : public true_type{};
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_VOID_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/is_volatile.hpp b/third_party/boost/boost/type_traits/is_volatile.hpp
new file mode 100644
index 0000000..2181821
--- /dev/null
+++ b/third_party/boost/boost/type_traits/is_volatile.hpp
@@ -0,0 +1,45 @@
+
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes,
+//      Howard Hinnant and John Maddock 2000.
+//  (C) Copyright Mat Marcus, Jesse Jones and Adobe Systems Inc 2001
+
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+//    Fixed is_pointer, is_reference, is_const, is_volatile, is_same,
+//    is_member_pointer based on the Simulated Partial Specialization work
+//    of Mat Marcus and Jesse Jones. See  http://opensource.adobe.com or
+//    http://groups.yahoo.com/group/boost/message/5441
+//    Some workarounds in here use ideas suggested from "Generic<Programming>:
+//    Mappings between Types and Values"
+//    by Andrei Alexandrescu (see http://www.cuj.com/experts/1810/alexandr.html).
+
+
+#ifndef BOOST_TT_IS_VOLATILE_HPP_INCLUDED
+#define BOOST_TT_IS_VOLATILE_HPP_INCLUDED
+
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace boost {
+
+#if defined( __CODEGEARC__ )
+
+   template <class T>
+   struct is_volatile : public integral_constant<bool, __is_volatile(T)> {};
+
+#else
+
+   template <class T>
+   struct is_volatile : public false_type {};
+   template <class T> struct is_volatile<T volatile> : public true_type{};
+   template <class T, size_t N> struct is_volatile<T volatile[N]> : public true_type{};
+   template <class T> struct is_volatile<T volatile[]> : public true_type{};
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_IS_VOLATILE_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/make_signed.hpp b/third_party/boost/boost/type_traits/make_signed.hpp
new file mode 100644
index 0000000..a53771e
--- /dev/null
+++ b/third_party/boost/boost/type_traits/make_signed.hpp
@@ -0,0 +1,130 @@
+
+//  (C) Copyright John Maddock 2007.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_MAKE_SIGNED_HPP_INCLUDED
+#define BOOST_TT_MAKE_SIGNED_HPP_INCLUDED
+
+#include <boost/type_traits/conditional.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_signed.hpp>
+#include <boost/type_traits/is_unsigned.hpp>
+#include <boost/type_traits/is_enum.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_volatile.hpp>
+#include <boost/type_traits/add_const.hpp>
+#include <boost/type_traits/add_volatile.hpp>
+#include <boost/static_assert.hpp>
+
+namespace boost {
+
+template <class T>
+struct make_signed
+{
+private:
+   BOOST_STATIC_ASSERT_MSG(( ::boost::is_integral<T>::value || ::boost::is_enum<T>::value), "The template argument to make_signed must be an integer or enum type.");
+   BOOST_STATIC_ASSERT_MSG(!(::boost::is_same<typename remove_cv<T>::type, bool>::value), "The template argument to make_signed must not be the type bool.");
+
+   typedef typename remove_cv<T>::type t_no_cv;
+   typedef typename conditional<
+      (::boost::is_signed<T>::value
+      && ::boost::is_integral<T>::value
+      && ! ::boost::is_same<t_no_cv, char>::value
+      && ! ::boost::is_same<t_no_cv, wchar_t>::value
+      && ! ::boost::is_same<t_no_cv, bool>::value),
+      T,
+      typename conditional<
+         (::boost::is_integral<T>::value
+         && ! ::boost::is_same<t_no_cv, char>::value
+         && ! ::boost::is_same<t_no_cv, wchar_t>::value
+         && ! ::boost::is_same<t_no_cv, bool>::value),
+         typename conditional<
+            is_same<t_no_cv, unsigned char>::value,
+            signed char,
+            typename conditional<
+               is_same<t_no_cv, unsigned short>::value,
+               signed short,
+               typename conditional<
+                  is_same<t_no_cv, unsigned int>::value,
+                  int,
+                  typename conditional<
+                     is_same<t_no_cv, unsigned long>::value,
+                     long,
+#if defined(BOOST_HAS_LONG_LONG)
+#ifdef BOOST_HAS_INT128
+                     typename conditional<
+                        sizeof(t_no_cv) == sizeof(boost::long_long_type),
+                        boost::long_long_type,
+                        boost::int128_type
+                     >::type
+#else
+                     boost::long_long_type
+#endif
+#elif defined(BOOST_HAS_MS_INT64)
+                     __int64
+#else
+                     long
+#endif
+                  >::type
+               >::type
+            >::type
+         >::type,
+         // Not a regular integer type:
+         typename conditional<
+            sizeof(t_no_cv) == sizeof(unsigned char),
+            signed char,
+            typename conditional<
+               sizeof(t_no_cv) == sizeof(unsigned short),
+               signed short,
+               typename conditional<
+                  sizeof(t_no_cv) == sizeof(unsigned int),
+                  int,
+                  typename conditional<
+                     sizeof(t_no_cv) == sizeof(unsigned long),
+                     long,
+#if defined(BOOST_HAS_LONG_LONG)
+#ifdef BOOST_HAS_INT128
+                     typename conditional<
+                        sizeof(t_no_cv) == sizeof(boost::long_long_type),
+                        boost::long_long_type,
+                        boost::int128_type
+                     >::type
+#else
+                     boost::long_long_type
+#endif
+#elif defined(BOOST_HAS_MS_INT64)
+                     __int64
+#else
+                     long
+#endif
+                  >::type
+               >::type
+            >::type
+         >::type
+      >::type
+   >::type base_integer_type;
+
+   // Add back any const qualifier:
+   typedef typename conditional<
+      is_const<T>::value,
+      typename add_const<base_integer_type>::type,
+      base_integer_type
+   >::type const_base_integer_type;
+public:
+   // Add back any volatile qualifier:
+   typedef typename conditional<
+      is_volatile<T>::value,
+      typename add_volatile<const_base_integer_type>::type,
+      const_base_integer_type
+   >::type type;
+};
+
+} // namespace boost
+
+#endif // BOOST_TT_ADD_REFERENCE_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/remove_bounds.hpp b/third_party/boost/boost/type_traits/remove_bounds.hpp
new file mode 100644
index 0000000..7de49d9
--- /dev/null
+++ b/third_party/boost/boost/type_traits/remove_bounds.hpp
@@ -0,0 +1,21 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_REMOVE_BOUNDS_HPP_INCLUDED
+#define BOOST_TT_REMOVE_BOUNDS_HPP_INCLUDED
+
+#include <boost/type_traits/remove_extent.hpp>
+
+namespace boost
+{
+
+template <class T> struct remove_bounds : public remove_extent<T> {};
+
+} // namespace boost
+
+#endif // BOOST_TT_REMOVE_BOUNDS_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/remove_const.hpp b/third_party/boost/boost/type_traits/remove_const.hpp
new file mode 100644
index 0000000..901cb15
--- /dev/null
+++ b/third_party/boost/boost/type_traits/remove_const.hpp
@@ -0,0 +1,33 @@
+
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
+//  Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+
+#ifndef BOOST_TT_REMOVE_CONST_HPP_INCLUDED
+#define BOOST_TT_REMOVE_CONST_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <cstddef>
+#include <boost/detail/workaround.hpp>
+
+namespace boost {
+
+   //  convert a type T to a non-cv-qualified type - remove_const<T>
+   template <class T> struct remove_const{ typedef T type; };
+   template <class T> struct remove_const<T const>{ typedef T type; };
+
+#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS)
+   template <class T, std::size_t N> struct remove_const<T const[N]>{ typedef T type[N]; };
+#if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && !defined(__IBMCPP__) &&  !BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840))
+   template <class T> struct remove_const<T const[]>{ typedef T type[]; };
+#endif
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_REMOVE_CONST_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/remove_cv.hpp b/third_party/boost/boost/type_traits/remove_cv.hpp
new file mode 100644
index 0000000..8d8c5ef
--- /dev/null
+++ b/third_party/boost/boost/type_traits/remove_cv.hpp
@@ -0,0 +1,40 @@
+
+//  (C) Copyright Dave Abrahams, Steve Cleary, Beman Dawes, Howard
+//  Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+
+#ifndef BOOST_TT_REMOVE_CV_HPP_INCLUDED
+#define BOOST_TT_REMOVE_CV_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+#include <cstddef>
+
+namespace boost {
+
+   //  convert a type T to a non-cv-qualified type - remove_cv<T>
+template <class T> struct remove_cv{ typedef T type; };
+template <class T> struct remove_cv<T const>{ typedef T type;  };
+template <class T> struct remove_cv<T volatile>{ typedef T type; };
+template <class T> struct remove_cv<T const volatile>{ typedef T type; };
+
+#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS)
+template <class T, std::size_t N> struct remove_cv<T const[N]>{ typedef T type[N]; };
+template <class T, std::size_t N> struct remove_cv<T const volatile[N]>{ typedef T type[N]; };
+template <class T, std::size_t N> struct remove_cv<T volatile[N]>{ typedef T type[N]; };
+#if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) && !defined(__IBMCPP__) &&  !BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840))
+template <class T> struct remove_cv<T const[]>{ typedef T type[]; };
+template <class T> struct remove_cv<T const volatile[]>{ typedef T type[]; };
+template <class T> struct remove_cv<T volatile[]>{ typedef T type[]; };
+#endif
+#endif
+
+
+} // namespace boost
+
+#endif // BOOST_TT_REMOVE_CV_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/remove_extent.hpp b/third_party/boost/boost/type_traits/remove_extent.hpp
new file mode 100644
index 0000000..0b50a07
--- /dev/null
+++ b/third_party/boost/boost/type_traits/remove_extent.hpp
@@ -0,0 +1,35 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000-2005.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_REMOVE_EXTENT_HPP_INCLUDED
+#define BOOST_TT_REMOVE_EXTENT_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+#include <cstddef>
+
+namespace boost {
+
+template <class T> struct remove_extent{ typedef T type; };
+
+#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS)
+template <typename T, std::size_t N> struct remove_extent<T[N]> { typedef T type; };
+template <typename T, std::size_t N> struct remove_extent<T const[N]> { typedef T const type; };
+template <typename T, std::size_t N> struct remove_extent<T volatile [N]> { typedef T volatile type; };
+template <typename T, std::size_t N> struct remove_extent<T const volatile [N]> { typedef T const volatile type; };
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) && !defined(__IBMCPP__) &&  !BOOST_WORKAROUND(__DMC__, BOOST_TESTED_AT(0x840))
+template <typename T> struct remove_extent<T[]> { typedef T type; };
+template <typename T> struct remove_extent<T const[]> { typedef T const type; };
+template <typename T> struct remove_extent<T volatile[]> { typedef T volatile type; };
+template <typename T> struct remove_extent<T const volatile[]> { typedef T const volatile type; };
+#endif
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_REMOVE_BOUNDS_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/remove_pointer.hpp b/third_party/boost/boost/type_traits/remove_pointer.hpp
new file mode 100644
index 0000000..7e8af96
--- /dev/null
+++ b/third_party/boost/boost/type_traits/remove_pointer.hpp
@@ -0,0 +1,77 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_REMOVE_POINTER_HPP_INCLUDED
+#define BOOST_TT_REMOVE_POINTER_HPP_INCLUDED
+
+#include <boost/config.hpp>
+
+#if defined(BOOST_MSVC)
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/type_traits/is_pointer.hpp>
+#endif
+
+namespace boost {
+
+#ifdef BOOST_MSVC
+
+namespace detail{
+
+   //
+   // We need all this crazy indirection because a type such as:
+   //
+   // T (*const)(U)
+   //
+   // Does not bind to a <T*> or <T*const> partial specialization with VC10 and earlier
+   //
+   template <class T>
+   struct remove_pointer_imp
+   {
+      typedef T type;
+   };
+
+   template <class T>
+   struct remove_pointer_imp<T*>
+   {
+      typedef T type;
+   };
+
+   template <class T, bool b>
+   struct remove_pointer_imp3
+   {
+      typedef typename remove_pointer_imp<typename boost::remove_cv<T>::type>::type type;
+   };
+
+   template <class T>
+   struct remove_pointer_imp3<T, false>
+   {
+      typedef T type;
+   };
+
+   template <class T>
+   struct remove_pointer_imp2
+   {
+      typedef typename remove_pointer_imp3<T, ::boost::is_pointer<T>::value>::type type;
+   };
+}
+
+template <class T> struct remove_pointer{ typedef typename boost::detail::remove_pointer_imp2<T>::type type; };
+
+#else
+
+template <class T> struct remove_pointer{ typedef T type; };
+template <class T> struct remove_pointer<T*>{ typedef T type; };
+template <class T> struct remove_pointer<T*const>{ typedef T type; };
+template <class T> struct remove_pointer<T*volatile>{ typedef T type; };
+template <class T> struct remove_pointer<T*const volatile>{ typedef T type; };
+
+#endif
+
+} // namespace boost
+
+#endif // BOOST_TT_REMOVE_POINTER_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/remove_reference.hpp b/third_party/boost/boost/type_traits/remove_reference.hpp
new file mode 100644
index 0000000..f75e677
--- /dev/null
+++ b/third_party/boost/boost/type_traits/remove_reference.hpp
@@ -0,0 +1,54 @@
+
+//  (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_REMOVE_REFERENCE_HPP_INCLUDED
+#define BOOST_TT_REMOVE_REFERENCE_HPP_INCLUDED
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+namespace boost {
+
+
+namespace detail{
+//
+// We can't filter out rvalue_references at the same level as
+// references or we get ambiguities from msvc:
+//
+template <class T>
+struct remove_rvalue_ref
+{
+   typedef T type;
+};
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+template <class T>
+struct remove_rvalue_ref<T&&>
+{
+   typedef T type;
+};
+#endif
+
+} // namespace detail
+
+template <class T> struct remove_reference{ typedef typename boost::detail::remove_rvalue_ref<T>::type type; };
+template <class T> struct remove_reference<T&>{ typedef T type; };
+
+#if defined(BOOST_ILLEGAL_CV_REFERENCES)
+// these are illegal specialisations; cv-qualifies applied to
+// references have no effect according to [8.3.2p1],
+// C++ Builder requires them though as it treats cv-qualified
+// references as distinct types...
+template <class T> struct remove_reference<T&const>{ typedef T type; };
+template <class T> struct remove_reference<T&volatile>{ typedef T type; };
+template <class T> struct remove_reference<T&const volatile>{ typedef T type; };
+#endif
+
+
+} // namespace boost
+
+#endif // BOOST_TT_REMOVE_REFERENCE_HPP_INCLUDED
diff --git a/third_party/boost/boost/type_traits/type_with_alignment.hpp b/third_party/boost/boost/type_traits/type_with_alignment.hpp
new file mode 100644
index 0000000..b592edd
--- /dev/null
+++ b/third_party/boost/boost/type_traits/type_with_alignment.hpp
@@ -0,0 +1,259 @@
+//  (C) Copyright John Maddock 2000.
+//  Use, modification and distribution are subject to the Boost Software License,
+//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt).
+//
+//  See http://www.boost.org/libs/type_traits for most recent version including documentation.
+
+#ifndef BOOST_TT_TYPE_WITH_ALIGNMENT_INCLUDED
+#define BOOST_TT_TYPE_WITH_ALIGNMENT_INCLUDED
+
+#include <boost/type_traits/alignment_of.hpp>
+#include <boost/type_traits/is_pod.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/config.hpp>
+#include <cstddef>
+#include <boost/detail/workaround.hpp>
+
+#ifdef BOOST_MSVC
+#   pragma warning(push)
+#   pragma warning(disable: 4121) // alignment is sensitive to packing
+#endif
+
+#ifdef _MSC_VER
+#include <boost/type_traits/conditional.hpp>
+#endif
+
+namespace boost {
+   namespace detail{
+
+#ifndef __BORLANDC__
+
+      union max_align
+      {
+         char c;
+         short s;
+         int i;
+         long l;
+#ifndef BOOST_NO_LONG_LONG
+         boost::long_long_type ll;
+#endif
+#ifdef BOOST_HAS_INT128
+         boost::int128_type i128;
+#endif
+         float f;
+         double d;
+         long double ld;
+#ifdef BOOST_HAS_FLOAT128
+         __float128 f128;
+#endif
+      };
+
+template <std::size_t Target, bool check> struct long_double_alignment{ typedef long double type; };
+template <std::size_t Target> struct long_double_alignment<Target, false>{ typedef boost::detail::max_align type; };
+
+template <std::size_t Target, bool check> struct double_alignment{ typedef double type; };
+template <std::size_t Target> struct double_alignment<Target, false>{ typedef typename long_double_alignment<Target, boost::alignment_of<long double>::value >= Target>::type type; };
+
+#ifndef BOOST_NO_LONG_LONG
+template <std::size_t Target, bool check> struct long_long_alignment{ typedef boost::long_long_type type; };
+template <std::size_t Target> struct long_long_alignment<Target, false>{ typedef typename double_alignment<Target, boost::alignment_of<double>::value >= Target>::type type; };
+#endif
+
+template <std::size_t Target, bool check> struct long_alignment{ typedef long type; };
+#ifndef BOOST_NO_LONG_LONG
+template <std::size_t Target> struct long_alignment<Target, false>{ typedef typename long_long_alignment<Target, boost::alignment_of<boost::long_long_type>::value >= Target>::type type; };
+#else
+template <std::size_t Target> struct long_alignment<Target, false>{ typedef typename double_alignment<Target, boost::alignment_of<double>::value >= Target>::type type; };
+#endif
+
+template <std::size_t Target, bool check> struct int_alignment{ typedef int type; };
+template <std::size_t Target> struct int_alignment<Target, false>{ typedef typename long_alignment<Target, boost::alignment_of<long>::value >= Target>::type type; };
+
+template <std::size_t Target, bool check> struct short_alignment{ typedef short type; };
+template <std::size_t Target> struct short_alignment<Target, false>{ typedef typename int_alignment<Target, boost::alignment_of<int>::value >= Target>::type type; };
+
+template <std::size_t Target, bool check> struct char_alignment{ typedef char type; };
+template <std::size_t Target> struct char_alignment<Target, false>{ typedef typename short_alignment<Target, boost::alignment_of<short>::value >= Target>::type type; };
+
+}
+
+template <std::size_t Align>
+struct type_with_alignment
+{
+   typedef typename boost::detail::char_alignment<Align, boost::alignment_of<char>::value >= Align>::type type;
+};
+
+#if (defined(__GNUC__) || (defined (__SUNPRO_CC) &&  (__SUNPRO_CC >= 0x5130)) || defined(__clang__)) && !defined(BOOST_TT_DISABLE_INTRINSICS)
+namespace tt_align_ns {
+struct __attribute__((__aligned__(2))) a2 {};
+struct __attribute__((__aligned__(4))) a4 {};
+struct __attribute__((__aligned__(8))) a8 {};
+struct __attribute__((__aligned__(16))) a16 {};
+struct __attribute__((__aligned__(32))) a32 {};
+struct __attribute__((__aligned__(64))) a64 {};
+struct __attribute__((__aligned__(128))) a128 {};
+}
+
+template<> struct type_with_alignment<1>  { public: typedef char type; };
+template<> struct type_with_alignment<2>  { public: typedef tt_align_ns::a2 type; };
+template<> struct type_with_alignment<4>  { public: typedef tt_align_ns::a4 type; };
+template<> struct type_with_alignment<8>  { public: typedef tt_align_ns::a8 type; };
+template<> struct type_with_alignment<16> { public: typedef tt_align_ns::a16 type; };
+template<> struct type_with_alignment<32> { public: typedef tt_align_ns::a32 type; };
+template<> struct type_with_alignment<64> { public: typedef tt_align_ns::a64 type; };
+template<> struct type_with_alignment<128> { public: typedef tt_align_ns::a128 type; };
+
+template<> struct is_pod< ::boost::tt_align_ns::a2> : public true_type{};
+template<> struct is_pod< ::boost::tt_align_ns::a4> : public true_type{};
+template<> struct is_pod< ::boost::tt_align_ns::a8> : public true_type{};
+template<> struct is_pod< ::boost::tt_align_ns::a16> : public true_type{};
+template<> struct is_pod< ::boost::tt_align_ns::a32> : public true_type{};
+template<> struct is_pod< ::boost::tt_align_ns::a64> : public true_type{};
+template<> struct is_pod< ::boost::tt_align_ns::a128> : public true_type{};
+
+#endif
+#if (defined(BOOST_MSVC) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && !defined(BOOST_TT_DISABLE_INTRINSICS)
+//
+// MSVC supports types which have alignments greater than the normal
+// maximum: these are used for example in the types __m64 and __m128
+// to provide types with alignment requirements which match the SSE
+// registers.  Therefore we extend type_with_alignment<> to support
+// such types, however, we have to be careful to use a builtin type
+// whenever possible otherwise we break previously working code:
+// see http://article.gmane.org/gmane.comp.lib.boost.devel/173011
+// for an example and test case.  Thus types like a8 below will
+// be used *only* if the existing implementation can't provide a type
+// with suitable alignment.  This does mean however, that type_with_alignment<>
+// may return a type which cannot be passed through a function call
+// by value (and neither can any type containing such a type like
+// Boost.Optional).  However, this only happens when we have no choice
+// in the matter because no other "ordinary" type is available.
+//
+namespace tt_align_ns {
+struct __declspec(align(8)) a8 {
+   char m[8];
+   typedef a8 type;
+};
+struct __declspec(align(16)) a16 {
+   char m[16];
+   typedef a16 type;
+};
+struct __declspec(align(32)) a32 {
+   char m[32];
+   typedef a32 type;
+};
+struct __declspec(align(64)) a64
+{
+   char m[64];
+   typedef a64 type;
+};
+struct __declspec(align(128)) a128 {
+   char m[128];
+   typedef a128 type;
+};
+}
+
+template<> struct type_with_alignment<8>
+{
+   typedef boost::conditional<
+      ::boost::alignment_of<boost::detail::max_align>::value < 8,
+      tt_align_ns::a8,
+      boost::detail::char_alignment<8, false> >::type t1;
+public:
+   typedef t1::type type;
+};
+template<> struct type_with_alignment<16>
+{
+   typedef boost::conditional<
+      ::boost::alignment_of<boost::detail::max_align>::value < 16,
+      tt_align_ns::a16,
+      boost::detail::char_alignment<16, false> >::type t1;
+public:
+   typedef t1::type type;
+};
+template<> struct type_with_alignment<32>
+{
+   typedef boost::conditional<
+      ::boost::alignment_of<boost::detail::max_align>::value < 32,
+      tt_align_ns::a32,
+      boost::detail::char_alignment<32, false> >::type t1;
+public:
+   typedef t1::type type;
+};
+template<> struct type_with_alignment<64> {
+   typedef boost::conditional<
+      ::boost::alignment_of<boost::detail::max_align>::value < 64,
+      tt_align_ns::a64,
+      boost::detail::char_alignment<64, false> >::type t1;
+public:
+   typedef t1::type type;
+};
+template<> struct type_with_alignment<128> {
+   typedef boost::conditional<
+      ::boost::alignment_of<boost::detail::max_align>::value < 128,
+      tt_align_ns::a128,
+      boost::detail::char_alignment<128, false> >::type t1;
+public:
+   typedef t1::type type;
+};
+
+template<> struct is_pod< ::boost::tt_align_ns::a8> : public true_type{};
+template<> struct is_pod< ::boost::tt_align_ns::a16> : public true_type{};
+template<> struct is_pod< ::boost::tt_align_ns::a32> : public true_type{};
+template<> struct is_pod< ::boost::tt_align_ns::a64> : public true_type{};
+template<> struct is_pod< ::boost::tt_align_ns::a128> : public true_type{};
+
+#endif
+
+#else
+
+//
+// Borland specific version, we have this for two reasons:
+// 1) The version above doesn't always compile (with the new test cases for example)
+// 2) Because of Borlands #pragma option we can create types with alignments that are
+//    greater that the largest aligned builtin type.
+
+namespace tt_align_ns{
+#pragma option push -a16
+struct a2{ short s; };
+struct a4{ int s; };
+struct a8{ double s; };
+struct a16{ long double s; };
+#pragma option pop
+}
+
+namespace detail {
+
+typedef ::boost::tt_align_ns::a16 max_align;
+
+}
+//#if ! BOOST_WORKAROUND(__CODEGEARC__, BOOST_TESTED_AT(0x610))
+template <> struct is_pod< ::boost::tt_align_ns::a2> : public true_type{};
+template <> struct is_pod< ::boost::tt_align_ns::a4> : public true_type{};
+template <> struct is_pod< ::boost::tt_align_ns::a8> : public true_type{};
+template <> struct is_pod< ::boost::tt_align_ns::a16> : public true_type{};
+//#endif
+
+template <std::size_t N> struct type_with_alignment
+{
+   // We should never get to here, but if we do use the maximally
+   // aligned type:
+   // BOOST_STATIC_ASSERT(0);
+   typedef tt_align_ns::a16 type;
+};
+template <> struct type_with_alignment<1>{ typedef char type; };
+template <> struct type_with_alignment<2>{ typedef tt_align_ns::a2 type; };
+template <> struct type_with_alignment<4>{ typedef tt_align_ns::a4 type; };
+template <> struct type_with_alignment<8>{ typedef tt_align_ns::a8 type; };
+template <> struct type_with_alignment<16>{ typedef tt_align_ns::a16 type; };
+
+#endif
+
+} // namespace boost
+
+#ifdef BOOST_MSVC
+#   pragma warning(pop)
+#endif
+
+#endif // BOOST_TT_TYPE_WITH_ALIGNMENT_INCLUDED
diff --git a/third_party/boost/boost/utility/addressof.hpp b/third_party/boost/boost/utility/addressof.hpp
new file mode 100644
index 0000000..db4da80
--- /dev/null
+++ b/third_party/boost/boost/utility/addressof.hpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2014 Glen Fernandes
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef BOOST_UTILITY_ADDRESSOF_HPP
+#define BOOST_UTILITY_ADDRESSOF_HPP
+
+// The header file at this path is deprecated;
+// use boost/core/addressof.hpp instead.
+
+#include <boost/core/addressof.hpp>
+
+#endif
diff --git a/third_party/boost/boost/utility/compare_pointees.hpp b/third_party/boost/boost/utility/compare_pointees.hpp
new file mode 100644
index 0000000..31b05c2
--- /dev/null
+++ b/third_party/boost/boost/utility/compare_pointees.hpp
@@ -0,0 +1,67 @@
+// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/optional for documentation.
+//
+// You are welcome to contact the author at:
+//  fernando_cacciola@hotmail.com
+//
+#ifndef BOOST_UTILITY_COMPARE_POINTEES_25AGO2003_HPP
+#define BOOST_UTILITY_COMPARE_POINTEES_25AGO2003_HPP
+
+#include<functional>
+
+namespace boost {
+
+// template<class OP> bool equal_pointees(OP const& x, OP const& y);
+// template<class OP> struct equal_pointees_t;
+//
+// Being OP a model of OptionalPointee (either a pointer or an optional):
+//
+// If both x and y have valid pointees, returns the result of (*x == *y)
+// If only one has a valid pointee, returns false.
+// If none have valid pointees, returns true.
+// No-throw
+template<class OptionalPointee>
+inline
+bool equal_pointees ( OptionalPointee const& x, OptionalPointee const& y )
+{
+  return (!x) != (!y) ? false : ( !x ? true : (*x) == (*y) ) ;
+}
+
+template<class OptionalPointee>
+struct equal_pointees_t : std::binary_function<OptionalPointee,OptionalPointee,bool>
+{
+  bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const
+    { return equal_pointees(x,y) ; }
+} ;
+
+// template<class OP> bool less_pointees(OP const& x, OP const& y);
+// template<class OP> struct less_pointees_t;
+//
+// Being OP a model of OptionalPointee (either a pointer or an optional):
+//
+// If y has not a valid pointee, returns false.
+// ElseIf x has not a valid pointee, returns true.
+// ElseIf both x and y have valid pointees, returns the result of (*x < *y)
+// No-throw
+template<class OptionalPointee>
+inline
+bool less_pointees ( OptionalPointee const& x, OptionalPointee const& y )
+{
+  return !y ? false : ( !x ? true : (*x) < (*y) ) ;
+}
+
+template<class OptionalPointee>
+struct less_pointees_t : std::binary_function<OptionalPointee,OptionalPointee,bool>
+{
+  bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const
+    { return less_pointees(x,y) ; }
+} ;
+
+} // namespace boost
+
+#endif
diff --git a/third_party/boost/boost/utility/declval.hpp b/third_party/boost/boost/utility/declval.hpp
new file mode 100644
index 0000000..229e9a3
--- /dev/null
+++ b/third_party/boost/boost/utility/declval.hpp
@@ -0,0 +1,13 @@
+//  declval.hpp  -------------------------------------------------------------//
+
+//  Copyright 2010 Vicente J. Botet Escriba
+
+//  Distributed under the Boost Software License, Version 1.0.
+//  See http://www.boost.org/LICENSE_1_0.txt
+
+#ifndef BOOST_UTILITY_DECLVAL_HPP
+#define BOOST_UTILITY_DECLVAL_HPP
+
+#include <boost/type_traits/declval.hpp>
+
+#endif  // BOOST_UTILITY_DECLVAL_HPP
diff --git a/third_party/boost/boost/utility/enable_if.hpp b/third_party/boost/boost/utility/enable_if.hpp
new file mode 100644
index 0000000..803bfca
--- /dev/null
+++ b/third_party/boost/boost/utility/enable_if.hpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2014 Glen Fernandes
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef BOOST_UTILITY_ENABLE_IF_HPP
+#define BOOST_UTILITY_ENABLE_IF_HPP
+
+// The header file at this path is deprecated;
+// use boost/core/enable_if.hpp instead.
+
+#include <boost/core/enable_if.hpp>
+
+#endif
diff --git a/third_party/boost/boost/utility/swap.hpp b/third_party/boost/boost/utility/swap.hpp
new file mode 100644
index 0000000..dd9ecd9
--- /dev/null
+++ b/third_party/boost/boost/utility/swap.hpp
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2014 Glen Fernandes
+ *
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#ifndef BOOST_UTILITY_SWAP_HPP
+#define BOOST_UTILITY_SWAP_HPP
+
+// The header file at this path is deprecated;
+// use boost/core/swap.hpp instead.
+
+#include <boost/core/swap.hpp>
+
+#endif
diff --git a/third_party/boost/boost/variant/apply_visitor.hpp b/third_party/boost/boost/variant/apply_visitor.hpp
new file mode 100644
index 0000000..53bada0
--- /dev/null
+++ b/third_party/boost/boost/variant/apply_visitor.hpp
@@ -0,0 +1,20 @@
+//-----------------------------------------------------------------------------
+// boost variant/apply_visitor.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_APPLY_VISITOR_HPP
+#define BOOST_VARIANT_APPLY_VISITOR_HPP
+
+#include "boost/variant/detail/apply_visitor_unary.hpp"
+#include "boost/variant/detail/apply_visitor_binary.hpp"
+#include "boost/variant/detail/apply_visitor_delayed.hpp"
+
+#endif // BOOST_VARIANT_APPLY_VISITOR_HPP
diff --git a/third_party/boost/boost/variant/detail/apply_visitor_binary.hpp b/third_party/boost/boost/variant/detail/apply_visitor_binary.hpp
new file mode 100644
index 0000000..e5e22e1
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/apply_visitor_binary.hpp
@@ -0,0 +1,280 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/apply_visitor_binary.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2002-2003 Eric Friedman
+// Copyright (c) 2014 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
+#define BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
+
+#include "boost/config.hpp"
+#include "boost/detail/workaround.hpp"
+#include "boost/variant/detail/generic_result_type.hpp"
+
+#include "boost/variant/detail/apply_visitor_unary.hpp"
+
+#if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
+#include "boost/utility/enable_if.hpp"
+#include "boost/mpl/not.hpp"
+#include "boost/type_traits/is_const.hpp"
+#endif
+
+
+#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
+#   include "boost/variant/detail/has_result_type.hpp"
+#endif
+
+namespace boost {
+
+//////////////////////////////////////////////////////////////////////////
+// function template apply_visitor(visitor, visitable1, visitable2)
+//
+// Visits visitable1 and visitable2 such that their values (which we
+// shall call x and y, respectively) are used as arguments in the
+// expression visitor(x, y).
+//
+
+namespace detail { namespace variant {
+
+template <typename Visitor, typename Value1>
+class apply_visitor_binary_invoke
+{
+public: // visitor typedefs
+
+    typedef typename Visitor::result_type
+        result_type;
+
+private: // representation
+
+    Visitor& visitor_;
+    Value1& value1_;
+
+public: // structors
+
+    apply_visitor_binary_invoke(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT
+        : visitor_(visitor)
+        , value1_(value1)
+    {
+    }
+
+public: // visitor interfaces
+
+    template <typename Value2>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
+    operator()(Value2& value2)
+    {
+        return visitor_(value1_, value2);
+    }
+
+private:
+    apply_visitor_binary_invoke& operator=(const apply_visitor_binary_invoke&);
+};
+
+template <typename Visitor, typename Visitable2>
+class apply_visitor_binary_unwrap
+{
+public: // visitor typedefs
+
+    typedef typename Visitor::result_type
+        result_type;
+
+private: // representation
+
+    Visitor& visitor_;
+    Visitable2& visitable2_;
+
+public: // structors
+
+    apply_visitor_binary_unwrap(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT
+        : visitor_(visitor)
+        , visitable2_(visitable2)
+    {
+    }
+
+public: // visitor interfaces
+
+    template <typename Value1>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
+    operator()(Value1& value1)
+    {
+        apply_visitor_binary_invoke<
+              Visitor
+            , Value1
+            > invoker(visitor_, value1);
+
+        return boost::apply_visitor(invoker, visitable2_);
+    }
+
+private:
+    apply_visitor_binary_unwrap& operator=(const apply_visitor_binary_unwrap&);
+
+};
+
+}} // namespace detail::variant
+
+//
+// nonconst-visitor version:
+//
+
+#if !BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
+
+#   define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
+    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
+    /**/
+
+#else // EDG-based compilers
+
+#   define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
+    typename enable_if< \
+          mpl::not_< is_const< V > > \
+        , BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
+        >::type \
+    /**/
+
+#endif // EDG-based compilers workaround
+
+template <typename Visitor, typename Visitable1, typename Visitable2>
+inline
+    BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor)
+apply_visitor(
+      Visitor& visitor
+    , Visitable1& visitable1, Visitable2& visitable2
+    )
+{
+    ::boost::detail::variant::apply_visitor_binary_unwrap<
+          Visitor, Visitable2
+        > unwrapper(visitor, visitable2);
+
+    return boost::apply_visitor(unwrapper, visitable1);
+}
+
+#undef BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE
+
+//
+// const-visitor version:
+//
+
+template <typename Visitor, typename Visitable1, typename Visitable2>
+inline
+    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
+          typename Visitor::result_type
+        )
+apply_visitor(
+      const Visitor& visitor
+    , Visitable1& visitable1, Visitable2& visitable2
+    )
+{
+    ::boost::detail::variant::apply_visitor_binary_unwrap<
+          const Visitor, Visitable2
+        > unwrapper(visitor, visitable2);
+
+    return boost::apply_visitor(unwrapper, visitable1);
+}
+
+
+#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
+
+//////////////////////////////////////////////////////////////////////////
+// function template apply_visitor(visitor, visitable1, visitable2)
+//
+// C++14 part.
+//
+
+namespace detail { namespace variant {
+
+template <typename Visitor, typename Value1>
+class apply_visitor_binary_invoke_cpp14
+{
+    Visitor& visitor_;
+    Value1& value1_;
+
+public: // structors
+
+    apply_visitor_binary_invoke_cpp14(Visitor& visitor, Value1& value1) BOOST_NOEXCEPT
+        : visitor_(visitor)
+        , value1_(value1)
+    {
+    }
+
+public: // visitor interfaces
+
+    template <typename Value2>
+    decltype(auto) operator()(Value2& value2)
+    {
+        return visitor_(value1_, value2);
+    }
+
+private:
+    apply_visitor_binary_invoke_cpp14& operator=(const apply_visitor_binary_invoke_cpp14&);
+};
+
+template <typename Visitor, typename Visitable2>
+class apply_visitor_binary_unwrap_cpp14
+{
+    Visitor& visitor_;
+    Visitable2& visitable2_;
+
+public: // structors
+
+    apply_visitor_binary_unwrap_cpp14(Visitor& visitor, Visitable2& visitable2) BOOST_NOEXCEPT
+        : visitor_(visitor)
+        , visitable2_(visitable2)
+    {
+    }
+
+public: // visitor interfaces
+
+    template <typename Value1>
+    decltype(auto) operator()(Value1& value1)
+    {
+        apply_visitor_binary_invoke_cpp14<
+              Visitor
+            , Value1
+            > invoker(visitor_, value1);
+
+        return boost::apply_visitor(invoker, visitable2_);
+    }
+
+private:
+    apply_visitor_binary_unwrap_cpp14& operator=(const apply_visitor_binary_unwrap_cpp14&);
+};
+
+}} // namespace detail::variant
+
+template <typename Visitor, typename Visitable1, typename Visitable2>
+inline decltype(auto) apply_visitor(Visitor& visitor, Visitable1& visitable1, Visitable2& visitable2,
+    typename boost::disable_if<
+        boost::detail::variant::has_result_type<Visitor>
+    >::type* = 0)
+{
+    ::boost::detail::variant::apply_visitor_binary_unwrap_cpp14<
+          Visitor, Visitable2
+        > unwrapper(visitor, visitable2);
+
+    return boost::apply_visitor(unwrapper, visitable1);
+}
+
+template <typename Visitor, typename Visitable1, typename Visitable2>
+inline decltype(auto) apply_visitor(const Visitor& visitor, Visitable1& visitable1, Visitable2& visitable2,
+    typename boost::disable_if<
+        boost::detail::variant::has_result_type<Visitor>
+    >::type* = 0)
+{
+    ::boost::detail::variant::apply_visitor_binary_unwrap_cpp14<
+          const Visitor, Visitable2
+        > unwrapper(visitor, visitable2);
+
+    return boost::apply_visitor(unwrapper, visitable1);
+}
+
+#endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
+
+} // namespace boost
+
+#endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_BINARY_HPP
diff --git a/third_party/boost/boost/variant/detail/apply_visitor_delayed.hpp b/third_party/boost/boost/variant/detail/apply_visitor_delayed.hpp
new file mode 100644
index 0000000..29f4614
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/apply_visitor_delayed.hpp
@@ -0,0 +1,151 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/apply_visitor_delayed.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2002-2003
+// Eric Friedman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_DELAYED_HPP
+#define BOOST_VARIANT_DETAIL_APPLY_VISITOR_DELAYED_HPP
+
+#include "boost/variant/detail/generic_result_type.hpp"
+
+#include "boost/variant/detail/apply_visitor_unary.hpp"
+#include "boost/variant/detail/apply_visitor_binary.hpp"
+#include "boost/variant/variant_fwd.hpp" // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
+
+
+#include "boost/variant/detail/has_result_type.hpp"
+#include <boost/core/enable_if.hpp>
+
+namespace boost {
+
+//////////////////////////////////////////////////////////////////////////
+// function template apply_visitor(visitor)
+//
+// Returns a function object, overloaded for unary and binary usage, that
+// visits its arguments using visitor (or a copy of visitor) via
+//  * apply_visitor( visitor, [argument] )
+// under unary invocation, or
+//  * apply_visitor( visitor, [argument1], [argument2] )
+// under binary invocation.
+//
+// NOTE: Unlike other apply_visitor forms, the visitor object must be
+//   non-const; this prevents user from giving temporary, to disastrous
+//   effect (i.e., returned function object would have dead reference).
+//
+
+template <typename Visitor>
+class apply_visitor_delayed_t
+{
+public: // visitor typedefs
+
+    typedef typename Visitor::result_type
+        result_type;
+
+private: // representation
+
+    Visitor& visitor_;
+
+public: // structors
+
+    explicit apply_visitor_delayed_t(Visitor& visitor) BOOST_NOEXCEPT
+      : visitor_(visitor)
+    {
+    }
+
+#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
+
+public: // N-ary visitor interface
+    template <typename... Visitables>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
+    operator()(Visitables&... visitables) const
+    {
+        return apply_visitor(visitor_, visitables...);
+    }
+
+#else // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
+
+public: // unary visitor interface
+
+    template <typename Visitable>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
+    operator()(Visitable& visitable) const
+    {
+        return apply_visitor(visitor_, visitable);
+    }
+
+public: // binary visitor interface
+
+    template <typename Visitable1, typename Visitable2>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
+    operator()(Visitable1& visitable1, Visitable2& visitable2) const
+    {
+        return apply_visitor(visitor_, visitable1, visitable2);
+    }
+
+#endif // !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
+
+private:
+    apply_visitor_delayed_t& operator=(const apply_visitor_delayed_t&);
+
+};
+
+template <typename Visitor>
+inline typename boost::enable_if<
+        boost::detail::variant::has_result_type<Visitor>,
+        apply_visitor_delayed_t<Visitor>
+    >::type apply_visitor(Visitor& visitor)
+{
+    return apply_visitor_delayed_t<Visitor>(visitor);
+}
+
+#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) \
+    && !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
+
+template <typename Visitor>
+class apply_visitor_delayed_cpp14_t
+{
+private: // representation
+    Visitor& visitor_;
+
+public: // structors
+
+    explicit apply_visitor_delayed_cpp14_t(Visitor& visitor) BOOST_NOEXCEPT
+      : visitor_(visitor)
+    {
+    }
+
+public: // N-ary visitor interface
+    template <typename... Visitables>
+    decltype(auto) operator()(Visitables&... visitables) const
+    {
+        return apply_visitor(visitor_, visitables...);
+    }
+
+private:
+    apply_visitor_delayed_cpp14_t& operator=(const apply_visitor_delayed_cpp14_t&);
+
+};
+
+template <typename Visitor>
+inline  typename boost::disable_if<
+        boost::detail::variant::has_result_type<Visitor>,
+        apply_visitor_delayed_cpp14_t<Visitor>
+    >::type apply_visitor(Visitor& visitor)
+{
+    return apply_visitor_delayed_cpp14_t<Visitor>(visitor);
+}
+
+#endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
+            // && !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
+
+
+} // namespace boost
+
+#endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_DELAYED_HPP
diff --git a/third_party/boost/boost/variant/detail/apply_visitor_unary.hpp b/third_party/boost/boost/variant/detail/apply_visitor_unary.hpp
new file mode 100644
index 0000000..63c21a3
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/apply_visitor_unary.hpp
@@ -0,0 +1,173 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/apply_visitor_unary.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2002-2003 Eric Friedman
+// Copyright (c) 2014 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP
+#define BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP
+
+#include "boost/config.hpp"
+#include "boost/detail/workaround.hpp"
+#include "boost/variant/detail/generic_result_type.hpp"
+
+#if BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
+#include "boost/core/enable_if.hpp"
+#include "boost/mpl/not.hpp"
+#include "boost/type_traits/is_const.hpp"
+#endif
+
+#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
+#   include <boost/mpl/distance.hpp>
+#   include <boost/mpl/advance.hpp>
+#   include <boost/mpl/deref.hpp>
+#   include <boost/mpl/size.hpp>
+#   include <boost/utility/declval.hpp>
+#   include <boost/core/enable_if.hpp>
+#   include "boost/variant/detail/has_result_type.hpp"
+#endif
+
+namespace boost {
+
+//////////////////////////////////////////////////////////////////////////
+// function template apply_visitor(visitor, visitable)
+//
+// Visits visitable with visitor.
+//
+
+//
+// nonconst-visitor version:
+//
+
+#if !BOOST_WORKAROUND(__EDG__, BOOST_TESTED_AT(302))
+
+#   define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
+    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
+    /**/
+
+#else // EDG-based compilers
+
+#   define BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(V) \
+    typename enable_if< \
+          mpl::not_< is_const< V > > \
+        , BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename V::result_type) \
+        >::type \
+    /**/
+
+#endif // EDG-based compilers workaround
+
+template <typename Visitor, typename Visitable>
+inline
+    BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE(Visitor)
+apply_visitor(Visitor& visitor, Visitable& visitable)
+{
+    return visitable.apply_visitor(visitor);
+}
+
+#undef BOOST_VARIANT_AUX_APPLY_VISITOR_NON_CONST_RESULT_TYPE
+
+//
+// const-visitor version:
+//
+
+template <typename Visitor, typename Visitable>
+inline
+    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
+apply_visitor(const Visitor& visitor, Visitable& visitable)
+{
+    return visitable.apply_visitor(visitor);
+}
+
+
+#if !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
+
+// C++14
+namespace detail { namespace variant {
+
+// This class serves only metaprogramming purposes. none of its methods must be called at runtime!
+template <class Visitor, class Variant>
+struct result_multideduce1 {
+    typedef typename Variant::types                 types;
+    typedef typename boost::mpl::begin<types>::type begin_it;
+    typedef typename boost::mpl::advance<
+        begin_it, boost::mpl::int_<boost::mpl::size<types>::type::value - 1>
+    >::type                                         last_it;
+
+    // For metaprogramming purposes ONLY! Do not use this method (and class) at runtime!
+    static Visitor& vis() BOOST_NOEXCEPT {
+        // Functions that work with lambdas must be defined in same translation unit.
+        // Because of that, we can not use `boost::decval<Visitor&>()` here.
+        Visitor&(*f)() = 0; // pointer to function
+        return f();
+    }
+
+    static decltype(auto) deduce_impl(last_it, unsigned /*helper*/) {
+        typedef typename boost::mpl::deref<last_it>::type value_t;
+        return vis()( boost::declval< value_t& >() );
+    }
+
+    template <class It>
+    static decltype(auto) deduce_impl(It, unsigned helper) {
+        typedef typename boost::mpl::next<It>::type next_t;
+        typedef typename boost::mpl::deref<It>::type value_t;
+        if (helper == boost::mpl::distance<begin_it, It>::type::value) {
+            return deduce_impl(next_t(), ++helper);
+        }
+
+        return vis()( boost::declval< value_t& >() );
+    }
+
+    static decltype(auto) deduce() {
+        return deduce_impl(begin_it(), 0);
+    }
+};
+
+template <class Visitor, class Variant>
+struct result_wrapper1
+{
+    typedef decltype(result_multideduce1<Visitor, Variant>::deduce()) result_type;
+
+    Visitor& visitor_;
+    explicit result_wrapper1(Visitor& visitor) BOOST_NOEXCEPT
+        : visitor_(visitor)
+    {}
+
+    template <class T>
+    result_type operator()(T& val) const {
+        return visitor_(val);
+    }
+};
+
+}} // namespace detail::variant
+
+template <typename Visitor, typename Visitable>
+inline decltype(auto) apply_visitor(Visitor& visitor, Visitable& visitable,
+    typename boost::disable_if<
+        boost::detail::variant::has_result_type<Visitor>
+    >::type* = 0)
+{
+    boost::detail::variant::result_wrapper1<Visitor, Visitable> cpp14_vis(visitor);
+    return visitable.apply_visitor(cpp14_vis);
+}
+
+template <typename Visitor, typename Visitable>
+inline decltype(auto) apply_visitor(const Visitor& visitor, Visitable& visitable,
+    typename boost::disable_if<
+        boost::detail::variant::has_result_type<Visitor>
+    >::type* = 0)
+{
+    boost::detail::variant::result_wrapper1<const Visitor, Visitable> cpp14_vis(visitor);
+    return visitable.apply_visitor(cpp14_vis);
+}
+
+#endif // !defined(BOOST_NO_CXX14_DECLTYPE_AUTO) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276)
+
+} // namespace boost
+
+#endif // BOOST_VARIANT_DETAIL_APPLY_VISITOR_UNARY_HPP
diff --git a/third_party/boost/boost/variant/detail/backup_holder.hpp b/third_party/boost/boost/variant/detail/backup_holder.hpp
new file mode 100644
index 0000000..1ccf160
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/backup_holder.hpp
@@ -0,0 +1,95 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/backup_holder.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP
+#define BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP
+
+#include "boost/config.hpp"
+#include "boost/assert.hpp"
+
+namespace boost {
+namespace detail { namespace variant {
+
+template <typename T>
+class backup_holder
+{
+private: // representation
+
+    T* backup_;
+
+public: // structors
+
+    ~backup_holder() BOOST_NOEXCEPT
+    {
+        delete backup_;
+    }
+
+    explicit backup_holder(T* backup) BOOST_NOEXCEPT
+        : backup_(backup)
+    {
+    }
+
+    backup_holder(const backup_holder&);
+
+public: // modifiers
+
+    backup_holder& operator=(const backup_holder& rhs)
+    {
+        *backup_ = rhs.get();
+        return *this;
+    }
+
+    backup_holder& operator=(const T& rhs)
+    {
+        *backup_ = rhs;
+        return *this;
+    }
+
+    void swap(backup_holder& rhs) BOOST_NOEXCEPT
+    {
+        T* tmp = rhs.backup_;
+        rhs.backup_ = this->backup_;
+        this->backup_ = tmp;
+    }
+
+public: // queries
+
+    T& get() BOOST_NOEXCEPT
+    {
+        return *backup_;
+    }
+
+    const T& get() const BOOST_NOEXCEPT
+    {
+        return *backup_;
+    }
+
+};
+
+template <typename T>
+backup_holder<T>::backup_holder(const backup_holder&)
+    : backup_(0)
+{
+    // not intended for copy, but do not want to prohibit syntactically
+    BOOST_ASSERT(false);
+}
+
+template <typename T>
+void swap(backup_holder<T>& lhs, backup_holder<T>& rhs) BOOST_NOEXCEPT
+{
+    lhs.swap(rhs);
+}
+
+}} // namespace detail::variant
+} // namespace boost
+
+#endif // BOOST_VARIANT_DETAIL_BACKUP_HOLDER_HPP
diff --git a/third_party/boost/boost/variant/detail/cast_storage.hpp b/third_party/boost/boost/variant/detail/cast_storage.hpp
new file mode 100644
index 0000000..24feed6
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/cast_storage.hpp
@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/cast_storage.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_DETAIL_CAST_STORAGE_HPP
+#define BOOST_VARIANT_DETAIL_CAST_STORAGE_HPP
+
+#include "boost/config.hpp"
+
+namespace boost {
+namespace detail { namespace variant {
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) function template cast_storage
+//
+// Casts the given storage to the specified type, but with qualification.
+//
+
+template <typename T>
+inline T& cast_storage(void* storage)
+{
+    return *static_cast<T*>(storage);
+}
+
+template <typename T>
+inline const T& cast_storage(const void* storage)
+{
+    return *static_cast<const T*>(storage);
+}
+
+}} // namespace detail::variant
+} // namespace boost
+
+#endif // BOOST_VARIANT_DETAIL_CAST_STORAGE_HPP
diff --git a/third_party/boost/boost/variant/detail/config.hpp b/third_party/boost/boost/variant/detail/config.hpp
new file mode 100644
index 0000000..84564a4
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/config.hpp
@@ -0,0 +1,37 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/config.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_DETAIL_CONFIG_HPP
+#define BOOST_VARIANT_DETAIL_CONFIG_HPP
+
+#include "boost/config.hpp"
+#include "boost/detail/workaround.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+// macro BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING
+//
+#if BOOST_WORKAROUND(__MWERKS__, <= 0x3201) \
+ || BOOST_WORKAROUND(BOOST_INTEL, <= 700) \
+ && !defined(BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING)
+#   define BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// macro BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND
+//
+#if !defined(BOOST_NO_SFINAE) \
+ && !BOOST_WORKAROUND(BOOST_INTEL, <= 700) \
+ && !defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND)
+#   define BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND
+#endif
+
+#endif // BOOST_VARIANT_DETAIL_CONFIG_HPP
diff --git a/third_party/boost/boost/variant/detail/enable_recursive_fwd.hpp b/third_party/boost/boost/variant/detail/enable_recursive_fwd.hpp
new file mode 100644
index 0000000..39a6b71
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/enable_recursive_fwd.hpp
@@ -0,0 +1,87 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/enable_recursive_fwd.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_FWD_HPP
+#define BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_FWD_HPP
+
+#include "boost/mpl/aux_/config/ctps.hpp"
+
+#include "boost/mpl/bool_fwd.hpp"
+
+#   include "boost/mpl/bool.hpp"
+
+namespace boost {
+namespace detail { namespace variant {
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) tag recursive_flag
+//
+// Signifies that the variant should perform recursive substituion.
+//
+
+
+template <typename T>
+struct recursive_flag
+{
+    typedef T type;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) metafunction is_recursive_flag
+//
+// Signifies that the variant should perform recursive substituion.
+//
+
+
+template <typename T>
+struct is_recursive_flag
+    : mpl::false_
+{
+};
+
+template <typename T>
+struct is_recursive_flag< recursive_flag<T> >
+    : mpl::true_
+{
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) metafunction enable_recursive
+//
+// Attempts recursive_variant_ tag substitution, wrapping with
+// boost::recursive_wrapper if substituion occurs w/ non-indirect result
+// (i.e., not a reference or pointer) *and* NoWrapper is false_.
+//
+template <
+      typename T
+    , typename RecursiveVariant
+    , typename NoWrapper = mpl::false_
+    >
+struct enable_recursive;
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) metafunction class quoted_enable_recursive
+//
+// Same behavior as enable_recursive metafunction (see above).
+//
+template <
+      typename RecursiveVariant
+    , typename NoWrapper = mpl::false_
+    >
+struct quoted_enable_recursive;
+
+}} // namespace detail::variant
+} // namespace boost
+
+#endif // BOOST_VARIANT_DETAIL_ENABLE_RECURSIVE_FWD_HPP
diff --git a/third_party/boost/boost/variant/detail/forced_return.hpp b/third_party/boost/boost/variant/detail/forced_return.hpp
new file mode 100644
index 0000000..522b796
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/forced_return.hpp
@@ -0,0 +1,102 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/forced_return.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_DETAIL_FORCED_RETURN_HPP
+#define BOOST_VARIANT_DETAIL_FORCED_RETURN_HPP
+
+#include "boost/config.hpp"
+#include "boost/variant/detail/generic_result_type.hpp"
+#include "boost/assert.hpp"
+
+namespace boost {
+namespace detail { namespace variant {
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) function template forced_return
+//
+// Logical error to permit invocation at runtime, but (artificially) satisfies
+// compile-time requirement of returning a result value.
+//
+
+#if !defined(BOOST_MSVC)                                \
+ && !defined(BOOST_NO_VOID_RETURNS)
+
+// "standard" implementation:
+
+template <typename T>
+inline T forced_return()
+{
+    // logical error: should never be here! (see above)
+    BOOST_ASSERT(false);
+
+    T (*dummy_function_ptr)() = 0;
+    return dummy_function_ptr();
+}
+
+template <>
+inline void forced_return<void>()
+{
+    // logical error: should never be here! (see above)
+    BOOST_ASSERT(false);
+}
+
+#elif !defined(BOOST_MSVC)
+
+// workaround implementation
+//
+// TODO: Determine the most efficient way to handle this -- as below? by
+// throwing? by recursive call to forced_return itself? etc.
+//
+
+template <typename T>
+inline
+    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T)
+forced_return()
+{
+    // logical error: should never be here! (see above)
+    BOOST_ASSERT(false);
+
+    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T) (*dummy)() = 0;
+    return dummy();
+}
+
+#else // defined(BOOST_MSVC)
+
+# pragma warning( push )
+# pragma warning( disable : 4702 ) // unreachable code
+// msvc-specific implementation
+//
+// Leverages __declspec(noreturn) for optimized implementation.
+//
+
+__declspec(noreturn)
+inline void forced_return_no_return() {};
+
+template <typename T>
+inline
+    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T)
+forced_return()
+{
+    // logical error: should never be here! (see above)
+    BOOST_ASSERT(false);
+
+    forced_return_no_return();
+}
+
+# pragma warning( pop )
+
+#endif // BOOST_MSVC optimization
+
+}} // namespace detail::variant
+} // namespace boost
+
+#endif // BOOST_VARIANT_DETAIL_FORCED_RETURN_HPP
diff --git a/third_party/boost/boost/variant/detail/generic_result_type.hpp b/third_party/boost/boost/variant/detail/generic_result_type.hpp
new file mode 100644
index 0000000..b3fbb19
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/generic_result_type.hpp
@@ -0,0 +1,88 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/generic_result_type.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_DETAIL_GENERIC_RESULT_TYPE_HPP
+#define BOOST_VARIANT_DETAIL_GENERIC_RESULT_TYPE_HPP
+
+#include "boost/config.hpp"
+
+//////////////////////////////////////////////////////////////////////////
+// (workaround) macro BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE
+//
+// On compilers with BOOST_NO_VOID_RETURNS, this macro provides a route
+// to a single syntax for dealing with template functions that may (but
+// not necessarily) return nothing (i.e. void).
+//
+// BOOST_VARIANT_AUX_RETURN_VOID provided for compilers w/ (erroneous?)
+// warnings about non-void functions not returning a value.
+//
+
+#if !defined(BOOST_NO_VOID_RETURNS)
+
+#define BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T) \
+    T   \
+    /**/
+
+#define BOOST_VARIANT_AUX_RETURN_VOID  \
+    /**/
+
+#define BOOST_VARIANT_AUX_RETURN_VOID_TYPE \
+    void    \
+    /**/
+
+#else // defined(BOOST_NO_VOID_RETURNS)
+
+namespace boost {
+namespace detail { namespace variant {
+
+struct fake_return_void
+{
+    fake_return_void()
+    {
+    }
+
+    template <typename T>
+    fake_return_void(const T&)
+    {
+    }
+};
+
+template <typename T>
+struct no_void_returns_helper
+{
+    typedef T type;
+};
+
+template <>
+struct no_void_returns_helper<void>
+{
+    typedef fake_return_void type;
+};
+
+}} // namespace detail::variant
+} // namespace boost
+
+#define BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(T) \
+    BOOST_DEDUCED_TYPENAME                                           \
+        ::boost::detail::variant::no_void_returns_helper< T >::type  \
+    /**/
+
+#define BOOST_VARIANT_AUX_RETURN_VOID  \
+    return ::boost::detail::variant::fake_return_void()     \
+    /**/
+
+#define BOOST_VARIANT_AUX_RETURN_VOID_TYPE  \
+    ::boost::detail::variant::fake_return_void
+
+#endif // BOOST_NO_VOID_RETURNS workaround
+
+#endif // BOOST_VARIANT_DETAIL_GENERIC_RESULT_TYPE_HPP
diff --git a/third_party/boost/boost/variant/detail/has_result_type.hpp b/third_party/boost/boost/variant/detail/has_result_type.hpp
new file mode 100644
index 0000000..18f6490
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/has_result_type.hpp
@@ -0,0 +1,36 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/has_result_type.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2014-2015 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_DETAIL_HAS_RESULT_TYPE_HPP
+#define BOOST_VARIANT_DETAIL_HAS_RESULT_TYPE_HPP
+
+#include "boost/config.hpp"
+#include "boost/type_traits/remove_reference.hpp"
+
+
+namespace boost { namespace detail { namespace variant {
+
+template <typename T >
+struct has_result_type {
+private:
+    typedef char                      yes;
+    typedef struct { char array[2]; } no;
+
+    template<typename C> static yes test(typename boost::remove_reference<typename C::result_type>::type*);
+    template<typename C> static no  test(...);
+
+public:
+    BOOST_STATIC_CONSTANT(bool, value = sizeof(test<T>(0)) == sizeof(yes));
+};
+
+}}} // namespace boost::detail::variant
+
+#endif // BOOST_VARIANT_DETAIL_HAS_RESULT_TYPE_HPP
diff --git a/third_party/boost/boost/variant/detail/hash_variant.hpp b/third_party/boost/boost/variant/detail/hash_variant.hpp
new file mode 100644
index 0000000..6ba73ae
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/hash_variant.hpp
@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/hash_variant.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2011
+// Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#ifndef BOOST_HASH_VARIANT_FUNCTION_HPP
+#define BOOST_HASH_VARIANT_FUNCTION_HPP
+
+#if defined(_MSC_VER)
+# pragma once
+#endif
+
+#include <boost/variant/variant_fwd.hpp>
+#include <boost/variant/static_visitor.hpp>
+#include <boost/variant/apply_visitor.hpp>
+#include <boost/functional/hash_fwd.hpp>
+
+namespace boost {
+
+    namespace detail { namespace variant {
+        struct variant_hasher: public boost::static_visitor<std::size_t> {
+            template <class T>
+            std::size_t operator()(T const& val) const {
+                boost::hash<T> hasher;
+                return hasher(val);
+            }
+        };
+    }}
+
+    template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
+    std::size_t hash_value(variant< BOOST_VARIANT_ENUM_PARAMS(T) > const& val) {
+        std::size_t seed = boost::apply_visitor(detail::variant::variant_hasher(), val);
+        hash_combine(seed, val.which());
+        return seed;
+    }
+}
+
+#endif
diff --git a/third_party/boost/boost/variant/detail/initializer.hpp b/third_party/boost/boost/variant/detail/initializer.hpp
new file mode 100644
index 0000000..98c9c22
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/initializer.hpp
@@ -0,0 +1,249 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/initializer.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2002-2003
+// Eric Friedman, Itay Maman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_DETAIL_INITIALIZER_HPP
+#define BOOST_VARIANT_DETAIL_INITIALIZER_HPP
+
+#include <new> // for placement new
+
+#include "boost/config.hpp"
+
+#include "boost/call_traits.hpp"
+#include "boost/detail/reference_content.hpp"
+#include "boost/variant/recursive_wrapper_fwd.hpp"
+#include "boost/variant/detail/move.hpp"
+
+#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
+#   include "boost/mpl/aux_/value_wknd.hpp"
+#   include "boost/mpl/int.hpp"
+#   include "boost/mpl/iter_fold.hpp"
+#   include "boost/mpl/next.hpp"
+#   include "boost/mpl/deref.hpp"
+#   include "boost/mpl/pair.hpp"
+#   include "boost/mpl/protect.hpp"
+#else
+#   include "boost/variant/variant_fwd.hpp"
+#   include "boost/preprocessor/cat.hpp"
+#   include "boost/preprocessor/enum.hpp"
+#   include "boost/preprocessor/repeat.hpp"
+#endif
+
+namespace boost {
+namespace detail { namespace variant {
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) support to simulate standard overload resolution rules
+//
+// The below initializers allows variant to follow standard overload
+// resolution rules over the specified set of bounded types.
+//
+// On compilers where using declarations in class templates can correctly
+// avoid name hiding, use an optimal solution based on the variant's typelist.
+//
+// Otherwise, use a preprocessor workaround based on knowledge of the fixed
+// size of the variant's psuedo-variadic template parameter list.
+//
+
+#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
+
+// (detail) quoted metafunction make_initializer_node
+//
+// Exposes a pair whose first type is a node in the initializer hierarchy.
+//
+struct make_initializer_node
+{
+    template <typename BaseIndexPair, typename Iterator>
+    struct apply
+    {
+    private: // helpers, for metafunction result (below)
+
+        typedef typename BaseIndexPair::first
+            base;
+        typedef typename BaseIndexPair::second
+            index;
+
+        class initializer_node
+            : public base
+        {
+        private: // helpers, for static functions (below)
+
+            typedef typename mpl::deref<Iterator>::type
+                recursive_enabled_T;
+            typedef typename unwrap_recursive<recursive_enabled_T>::type
+                public_T;
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+            typedef boost::is_reference<public_T>
+                is_reference_content_t;
+
+            typedef typename boost::mpl::if_<is_reference_content_t, public_T, const public_T& >::type
+                param_T;
+
+            template <class T> struct disable_overload{};
+
+            typedef typename boost::mpl::if_<is_reference_content_t, disable_overload<public_T>, public_T&& >::type
+                param2_T;
+#else
+            typedef typename call_traits<public_T>::param_type
+                param_T;
+#endif
+
+        public: // static functions
+
+            using base::initialize;
+
+            static int initialize(void* dest, param_T operand)
+            {
+                typedef typename boost::detail::make_reference_content<
+                      recursive_enabled_T
+                    >::type internal_T;
+
+                new(dest) internal_T(operand);
+                return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which
+            }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+            static int initialize(void* dest, param2_T operand)
+            {
+                // This assert must newer trigger, because all the reference contents are
+                // handled by the initilize(void* dest, param_T operand) function above
+                BOOST_ASSERT(!is_reference_content_t::value);
+
+                typedef typename boost::mpl::if_<is_reference_content_t, param2_T, recursive_enabled_T>::type value_T;
+                new(dest) value_T( boost::detail::variant::move(operand) );
+                return BOOST_MPL_AUX_VALUE_WKND(index)::value; // which
+            }
+#endif
+        };
+
+        friend class initializer_node;
+
+    public: // metafunction result
+
+        typedef mpl::pair<
+              initializer_node
+            , typename mpl::next< index >::type
+            > type;
+
+    };
+};
+
+// (detail) class initializer_root
+//
+// Every level of the initializer hierarchy must expose the name
+// "initialize," so initializer_root provides a dummy function:
+//
+class initializer_root
+{
+public: // static functions
+
+    static void initialize();
+
+};
+
+#else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
+
+    // Obsolete. Remove.
+    #define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_PARAMS \
+          BOOST_VARIANT_ENUM_PARAMS(typename recursive_enabled_T) \
+    /**/
+
+    // Obsolete. Remove.
+    #define BOOST_VARIANT_AUX_PP_INITIALIZER_DEFINE_PARAM_T(N) \
+        typedef typename unwrap_recursive< \
+              BOOST_PP_CAT(recursive_enabled_T,N) \
+            >::type BOOST_PP_CAT(public_T,N); \
+        typedef typename call_traits< \
+              BOOST_PP_CAT(public_T,N) \
+            >::param_type BOOST_PP_CAT(param_T,N); \
+    /**/
+
+template < BOOST_VARIANT_ENUM_PARAMS(typename recursive_enabled_T) >
+struct preprocessor_list_initializer
+{
+public: // static functions
+
+    #define BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION(z,N,_) \
+        typedef typename unwrap_recursive< \
+              BOOST_PP_CAT(recursive_enabled_T,N) \
+            >::type BOOST_PP_CAT(public_T,N); \
+        typedef typename call_traits< \
+              BOOST_PP_CAT(public_T,N) \
+            >::param_type BOOST_PP_CAT(param_T,N); \
+        static int initialize( \
+              void* dest \
+            , BOOST_PP_CAT(param_T,N) operand \
+            ) \
+        { \
+            typedef typename boost::detail::make_reference_content< \
+                  BOOST_PP_CAT(recursive_enabled_T,N) \
+                >::type internal_T; \
+            \
+            new(dest) internal_T(operand); \
+            return (N); /*which*/ \
+        } \
+        /**/
+
+    BOOST_PP_REPEAT(
+          BOOST_VARIANT_LIMIT_TYPES
+        , BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION
+        , _
+        )
+
+    #undef BOOST_VARIANT_AUX_PP_INITIALIZE_FUNCTION
+
+};
+
+#endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround
+
+}} // namespace detail::variant
+} // namespace boost
+
+///////////////////////////////////////////////////////////////////////////////
+// macro BOOST_VARIANT_AUX_INITIALIZER_T
+//
+// Given both the variant's typelist and a basename for forming the list of
+// bounded types (i.e., T becomes T1, T2, etc.), exposes the initializer
+// most appropriate to the current compiler.
+//
+
+#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
+
+#define BOOST_VARIANT_AUX_INITIALIZER_T( mpl_seq, typename_base ) \
+    ::boost::mpl::iter_fold< \
+          mpl_seq \
+        , ::boost::mpl::pair< \
+              ::boost::detail::variant::initializer_root \
+            , ::boost::mpl::int_<0> \
+            > \
+        , ::boost::mpl::protect< \
+              ::boost::detail::variant::make_initializer_node \
+            > \
+        >::type::first \
+    /**/
+
+#else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
+
+    // Obsolete. Remove.
+    #define BOOST_VARIANT_AUX_PP_INITIALIZER_TEMPLATE_ARGS(typename_base) \
+          BOOST_VARIANT_ENUM_PARAMS(typename_base) \
+        /**/
+
+#define BOOST_VARIANT_AUX_INITIALIZER_T( mpl_seq, typename_base ) \
+    ::boost::detail::variant::preprocessor_list_initializer< \
+          BOOST_VARIANT_ENUM_PARAMS(typename_base) \
+        > \
+    /**/
+
+#endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround
+
+#endif // BOOST_VARIANT_DETAIL_INITIALIZER_HPP
diff --git a/third_party/boost/boost/variant/detail/make_variant_list.hpp b/third_party/boost/boost/variant/detail/make_variant_list.hpp
new file mode 100644
index 0000000..9bc2e69
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/make_variant_list.hpp
@@ -0,0 +1,73 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/make_variant_list.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2002-2003 Eric Friedman, Itay Maman
+// Copyright (c) 2013 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_DETAIL_MAKE_VARIANT_LIST_HPP
+#define BOOST_VARIANT_DETAIL_MAKE_VARIANT_LIST_HPP
+
+#include "boost/variant/variant_fwd.hpp"
+
+#include "boost/mpl/list.hpp"
+#include "boost/preprocessor/cat.hpp"
+#include "boost/preprocessor/enum.hpp"
+
+namespace boost {
+namespace detail { namespace variant {
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) metafunction make_variant_list
+//
+// Provides a MPL-compatible sequence with the specified non-void types
+// as arguments.
+//
+// Rationale: see class template convert_void (variant_fwd.hpp) and using-
+// declaration workaround (below).
+//
+
+#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
+
+template < typename... T >
+struct make_variant_list
+{
+    typedef typename mpl::list< T... >::type type;
+};
+
+#else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
+
+template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
+struct make_variant_list
+{
+public: // metafunction result
+
+    // [Define a macro to convert any void(NN) tags to mpl::void...]
+#   define BOOST_VARIANT_AUX_CONVERT_VOID(z, N,_)  \
+        typename convert_void< BOOST_PP_CAT(T,N) >::type
+
+    // [...so that the specified types can be passed to mpl::list...]
+    typedef typename mpl::list<
+          BOOST_PP_ENUM(
+              BOOST_VARIANT_LIMIT_TYPES
+            , BOOST_VARIANT_AUX_CONVERT_VOID
+            , _
+            )
+        >::type type;
+
+    // [...and, finally, the conversion macro can be undefined:]
+#   undef BOOST_VARIANT_AUX_CONVERT_VOID
+
+};
+
+#endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround
+
+}} // namespace detail::variant
+} // namespace boost
+
+#endif // BOOST_VARIANT_DETAIL_MAKE_VARIANT_LIST_HPP
diff --git a/third_party/boost/boost/variant/detail/move.hpp b/third_party/boost/boost/variant/detail/move.hpp
new file mode 100644
index 0000000..e605b92
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/move.hpp
@@ -0,0 +1,50 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/move.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+//  Copyright (c) 2002-2003 Eric Friedman
+//  Copyright (c) 2002 by Andrei Alexandrescu
+//  Copyright (c) 2013-2014 Antony Polukhin
+//
+//  Use, modification and distribution are subject to the
+//  Boost Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+//  This file derivative of MoJO. Much thanks to Andrei for his initial work.
+//  See <http://www.cuj.com/experts/2102/alexandr.htm> for information on MOJO.
+//  Re-issued here under the Boost Software License, with permission of the original
+//  author (Andrei Alexandrescu).
+
+
+#ifndef BOOST_VARIANT_DETAIL_MOVE_HPP
+#define BOOST_VARIANT_DETAIL_MOVE_HPP
+
+#include <iterator> // for iterator_traits
+#include <new> // for placement new
+
+#include "boost/config.hpp"
+#include "boost/detail/workaround.hpp"
+#include "boost/move/move.hpp"
+#include "boost/move/adl_move_swap.hpp"
+
+namespace boost { namespace detail { namespace variant {
+
+using boost::move;
+
+//////////////////////////////////////////////////////////////////////////
+// function template move_swap
+//
+// Swaps using Koenig lookup but falls back to move-swap for primitive
+// types and on non-conforming compilers.
+//
+
+template <typename T>
+inline void move_swap(T& lhs, T& rhs)
+{
+    ::boost::adl_move_swap(lhs, rhs);
+}
+
+}}} // namespace boost::detail::variant
+
+#endif // BOOST_VARIANT_DETAIL_MOVE_HPP
diff --git a/third_party/boost/boost/variant/detail/over_sequence.hpp b/third_party/boost/boost/variant/detail/over_sequence.hpp
new file mode 100644
index 0000000..ff20a01
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/over_sequence.hpp
@@ -0,0 +1,58 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/over_sequence.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman
+//
+// Portions Copyright (C) 2002 David Abrahams
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_DETAIL_OVER_SEQUENCE_HPP
+#define BOOST_VARIANT_DETAIL_OVER_SEQUENCE_HPP
+
+#include "boost/mpl/aux_/config/ctps.hpp"
+
+
+namespace boost {
+namespace detail { namespace variant {
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class over_sequence
+//
+// Wrapper used to indicate bounded types for variant are from type sequence.
+//
+template <typename Types>
+struct over_sequence
+{
+    typedef Types type;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) metafunction is_over_sequence (modeled on code by David Abrahams)
+//
+// Indicates whether the specified type is of form over_sequence<...> or not.
+//
+
+
+template <typename T>
+struct is_over_sequence
+    : mpl::false_
+{
+};
+
+template <typename Types>
+struct is_over_sequence< over_sequence<Types> >
+    : mpl::true_
+{
+};
+
+
+}} // namespace detail::variant
+} // namespace boost
+
+#endif // BOOST_VARIANT_DETAIL_OVER_SEQUENCE_HPP
diff --git a/third_party/boost/boost/variant/detail/substitute_fwd.hpp b/third_party/boost/boost/variant/detail/substitute_fwd.hpp
new file mode 100644
index 0000000..8084cb8
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/substitute_fwd.hpp
@@ -0,0 +1,58 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/substitute_fwd.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_DETAIL_SUBSTITUTE_FWD_HPP
+#define BOOST_VARIANT_DETAIL_SUBSTITUTE_FWD_HPP
+
+#include "boost/mpl/aux_/lambda_arity_param.hpp"
+#include "boost/mpl/aux_/template_arity.hpp"
+#include "boost/mpl/int_fwd.hpp"
+
+
+///////////////////////////////////////////////////////////////////////////////
+// BOOST_VARIANT_DETAIL_NO_SUBSTITUTE
+//
+// Defined if 'substitute' is not implementable on the current compiler.
+//
+
+#include "boost/mpl/aux_/config/ctps.hpp"
+#include "boost/mpl/aux_/config/ttp.hpp"
+
+#if defined(BOOST_NO_TEMPLATE_TEMPLATE_PARAMETERS) \
+ && !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
+#   define BOOST_VARIANT_DETAIL_NO_SUBSTITUTE
+#endif
+
+namespace boost {
+namespace detail { namespace variant {
+
+#if !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
+
+///////////////////////////////////////////////////////////////////////////////
+// metafunction substitute
+//
+// Substitutes one type for another in the given type expression.
+//
+template <
+      typename T, typename Dest, typename Source
+      BOOST_MPL_AUX_LAMBDA_ARITY_PARAM(
+          typename Arity = mpl::int_< mpl::aux::template_arity<T>::value >
+        )
+    >
+struct substitute;
+
+#endif // !defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE)
+
+}} // namespace detail::variant
+} // namespace boost
+
+#endif // BOOST_VARIANT_DETAIL_SUBSTITUTE_FWD_HPP
diff --git a/third_party/boost/boost/variant/detail/variant_io.hpp b/third_party/boost/boost/variant/detail/variant_io.hpp
new file mode 100644
index 0000000..192a3de
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/variant_io.hpp
@@ -0,0 +1,95 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/variant_io.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2002-2003
+// Eric Friedman, Itay Maman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_DETAIL_VARIANT_IO_HPP
+#define BOOST_VARIANT_DETAIL_VARIANT_IO_HPP
+
+#include <iosfwd> // for std::basic_ostream forward declare
+
+#include "boost/variant/variant_fwd.hpp"
+
+#include "boost/detail/templated_streams.hpp"
+#include "boost/variant/static_visitor.hpp"
+
+namespace boost {
+
+///////////////////////////////////////////////////////////////////////////////
+// function template operator<<
+//
+// Outputs the content of the given variant to the given ostream.
+//
+
+// forward declare (allows output of embedded variant< variant< ... >, ... >)
+template <
+      BOOST_TEMPLATED_STREAM_ARGS(E,T)
+    BOOST_TEMPLATED_STREAM_COMMA
+      BOOST_VARIANT_ENUM_PARAMS(typename U)
+    >
+inline BOOST_TEMPLATED_STREAM(ostream, E,T)& operator<<(
+      BOOST_TEMPLATED_STREAM(ostream, E,T)& out
+    , const variant< BOOST_VARIANT_ENUM_PARAMS(U) >& rhs
+    );
+
+namespace detail { namespace variant {
+
+template <typename OStream>
+class printer
+    : public boost::static_visitor<>
+{
+private: // representation
+
+    OStream& out_;
+
+public: // structors
+
+    explicit printer(OStream& out)
+        : out_( out )
+    {
+    }
+
+public: // visitor interface
+
+    template <typename T>
+    void operator()(const T& operand) const
+    {
+        out_ << operand;
+    }
+
+private:
+    printer& operator=(const printer&);
+
+};
+
+}} // namespace detail::variant
+
+template <
+      BOOST_TEMPLATED_STREAM_ARGS(E,T)
+    BOOST_TEMPLATED_STREAM_COMMA
+      BOOST_VARIANT_ENUM_PARAMS(typename U)
+    >
+inline BOOST_TEMPLATED_STREAM(ostream, E,T)& operator<<(
+      BOOST_TEMPLATED_STREAM(ostream, E,T)& out
+    , const variant< BOOST_VARIANT_ENUM_PARAMS(U) >& rhs
+    )
+{
+    detail::variant::printer<
+          BOOST_TEMPLATED_STREAM(ostream, E,T)
+        > visitor(out);
+
+    rhs.apply_visitor(visitor);
+
+    return out;
+}
+
+} // namespace boost
+
+#endif // BOOST_VARIANT_DETAIL_VARIANT_IO_HPP
diff --git a/third_party/boost/boost/variant/detail/visitation_impl.hpp b/third_party/boost/boost/variant/detail/visitation_impl.hpp
new file mode 100644
index 0000000..3e9ad5f
--- /dev/null
+++ b/third_party/boost/boost/variant/detail/visitation_impl.hpp
@@ -0,0 +1,277 @@
+//-----------------------------------------------------------------------------
+// boost variant/detail/visitation_impl.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003
+// Eric Friedman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP
+#define BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP
+
+#include "boost/config.hpp"
+
+#include "boost/variant/detail/backup_holder.hpp"
+#include "boost/variant/detail/cast_storage.hpp"
+#include "boost/variant/detail/forced_return.hpp"
+#include "boost/variant/detail/generic_result_type.hpp"
+#include "boost/variant/variant_fwd.hpp" // for BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
+
+#include "boost/mpl/eval_if.hpp"
+#include "boost/mpl/bool.hpp"
+#include "boost/mpl/identity.hpp"
+#include "boost/mpl/int.hpp"
+#include "boost/mpl/next.hpp"
+#include "boost/mpl/deref.hpp"
+#include "boost/mpl/or.hpp"
+#include "boost/preprocessor/cat.hpp"
+#include "boost/preprocessor/inc.hpp"
+#include "boost/preprocessor/repeat.hpp"
+#include "boost/type_traits/is_same.hpp"
+#include "boost/type_traits/has_nothrow_copy.hpp"
+#include "boost/type_traits/is_nothrow_move_constructible.hpp"
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning (push)
+# pragma warning (disable : 4702) //unreachable code
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
+//
+// Unrolls variant's visitation mechanism to reduce template instantiation
+// and potentially increase runtime performance. (TODO: Investigate further.)
+//
+#if !defined(BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
+
+#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
+#   include "boost/mpl/limits/list.hpp"
+#   define BOOST_VARIANT_VISITATION_UNROLLING_LIMIT   \
+        BOOST_MPL_LIMIT_LIST_SIZE
+#else
+#   define BOOST_VARIANT_VISITATION_UNROLLING_LIMIT   \
+        BOOST_VARIANT_LIMIT_TYPES
+#endif
+
+#endif
+
+namespace boost {
+namespace detail { namespace variant {
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class apply_visitor_unrolled
+//
+// Tag type indicates when visitation_impl is unrolled.
+//
+struct apply_visitor_unrolled {};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class template visitation_impl_step
+//
+// "Never ending" iterator range facilitates visitation_impl unrolling.
+//
+
+
+template <typename Iter, typename LastIter>
+struct visitation_impl_step
+{
+    typedef typename mpl::deref<Iter>::type type;
+
+    typedef typename mpl::next<Iter>::type next_iter;
+    typedef visitation_impl_step<
+          next_iter, LastIter
+        > next;
+};
+
+template <typename LastIter>
+struct visitation_impl_step< LastIter,LastIter >
+{
+    typedef apply_visitor_unrolled type;
+    typedef visitation_impl_step next;
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) function template visitation_impl_invoke
+//
+// Invokes the given visitor on the specified type in the given storage.
+//
+
+template <typename Visitor, typename VoidPtrCV, typename T>
+inline
+    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
+visitation_impl_invoke_impl(
+      int, Visitor& visitor, VoidPtrCV storage, T*
+    , mpl::true_// never_uses_backup
+    )
+{
+    return visitor.internal_visit(
+          cast_storage<T>(storage), 1L
+        );
+}
+
+template <typename Visitor, typename VoidPtrCV, typename T>
+inline
+    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
+visitation_impl_invoke_impl(
+      int internal_which, Visitor& visitor, VoidPtrCV storage, T*
+    , mpl::false_// never_uses_backup
+    )
+{
+    if (internal_which >= 0)
+    {
+        return visitor.internal_visit(
+              cast_storage<T>(storage), 1L
+            );
+    }
+    else
+    {
+        return visitor.internal_visit(
+              cast_storage< backup_holder<T> >(storage), 1L
+            );
+    }
+}
+
+template <typename Visitor, typename VoidPtrCV, typename T, typename NoBackupFlag>
+inline
+    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
+visitation_impl_invoke(
+      int internal_which, Visitor& visitor, VoidPtrCV storage, T* t
+    , NoBackupFlag
+    , int
+    )
+{
+    typedef typename mpl::or_<
+          NoBackupFlag
+        , is_nothrow_move_constructible<T>
+        , has_nothrow_copy<T>
+        >::type never_uses_backup;
+
+    return (visitation_impl_invoke_impl)(
+          internal_which, visitor, storage, t
+        , never_uses_backup()
+        );
+}
+
+template <typename Visitor, typename VoidPtrCV, typename NBF>
+inline
+    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
+visitation_impl_invoke(int, Visitor&, VoidPtrCV, apply_visitor_unrolled*, NBF, long)
+{
+    // should never be here at runtime!
+    typedef typename Visitor::result_type result_type;
+    return ::boost::detail::variant::forced_return< result_type >();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) function template visitation_impl
+//
+// Invokes the given visitor on the type in the given variant storage.
+//
+
+template <
+      typename W, typename S
+    , typename Visitor, typename VPCV
+    , typename NBF
+    >
+inline
+    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
+visitation_impl(
+      int, int, Visitor&, VPCV
+    , mpl::true_ // is_apply_visitor_unrolled
+    , NBF, W* = 0, S* = 0
+    )
+{
+    // should never be here at runtime!
+    typedef typename Visitor::result_type result_type;
+    return ::boost::detail::variant::forced_return< result_type >();
+}
+
+template <
+      typename Which, typename step0
+    , typename Visitor, typename VoidPtrCV
+    , typename NoBackupFlag
+    >
+inline
+    BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
+visitation_impl(
+      const int internal_which, const int logical_which
+    , Visitor& visitor, VoidPtrCV storage
+    , mpl::false_ // is_apply_visitor_unrolled
+    , NoBackupFlag no_backup_flag
+    , Which* = 0, step0* = 0
+    )
+{
+    // Typedef apply_visitor_unrolled steps and associated types...
+#   define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF(z, N, _) \
+    typedef typename BOOST_PP_CAT(step,N)::type BOOST_PP_CAT(T,N); \
+    typedef typename BOOST_PP_CAT(step,N)::next \
+        BOOST_PP_CAT(step, BOOST_PP_INC(N)); \
+    /**/
+
+    BOOST_PP_REPEAT(
+          BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
+        , BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF
+        , _
+        )
+
+#   undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_TYPEDEF
+
+    // ...switch on the target which-index value...
+    switch (logical_which)
+    {
+
+    // ...applying the appropriate case:
+#   define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE(z, N, _) \
+    case (Which::value + (N)): \
+        return (visitation_impl_invoke)( \
+              internal_which, visitor, storage \
+            , static_cast<BOOST_PP_CAT(T,N)*>(0) \
+            , no_backup_flag, 1L \
+            ); \
+    /**/
+
+    BOOST_PP_REPEAT(
+          BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
+        , BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
+        , _
+        )
+
+#   undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
+
+    default: break;
+    }
+
+    // If not handled in this iteration, continue unrolling:
+    typedef mpl::int_<
+          Which::value + (BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
+        > next_which;
+
+    typedef BOOST_PP_CAT(step, BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
+        next_step;
+
+    typedef typename next_step::type next_type;
+    typedef typename is_same< next_type,apply_visitor_unrolled >::type
+        is_apply_visitor_unrolled;
+
+    return visitation_impl(
+          internal_which, logical_which
+        , visitor, storage
+        , is_apply_visitor_unrolled()
+        , no_backup_flag
+        , static_cast<next_which*>(0), static_cast<next_step*>(0)
+        );
+}
+
+}} // namespace detail::variant
+} // namespace boost
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
+
+#endif // BOOST_VARIANT_DETAIL_VISITATION_IMPL_HPP
diff --git a/third_party/boost/boost/variant/recursive_wrapper_fwd.hpp b/third_party/boost/boost/variant/recursive_wrapper_fwd.hpp
new file mode 100644
index 0000000..b46774d
--- /dev/null
+++ b/third_party/boost/boost/variant/recursive_wrapper_fwd.hpp
@@ -0,0 +1,99 @@
+//-----------------------------------------------------------------------------
+// boost variant/recursive_wrapper_fwd.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2002
+// Eric Friedman, Itay Maman
+//
+// Portions Copyright (C) 2002 David Abrahams
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP
+#define BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP
+
+#include "boost/mpl/aux_/config/ctps.hpp"
+#include "boost/mpl/aux_/lambda_support.hpp"
+#include <boost/type_traits/integral_constant.hpp>
+
+namespace boost {
+
+//////////////////////////////////////////////////////////////////////////
+// class template recursive_wrapper
+//
+// Enables recursive types in templates by breaking cyclic dependencies.
+//
+// For example:
+//
+//   class my;
+//
+//   typedef variant< int, recursive_wrapper<my> > var;
+//
+//   class my {
+//     var var_;
+//     ...
+//   };
+//
+template <typename T> class recursive_wrapper;
+
+///////////////////////////////////////////////////////////////////////////////
+// metafunction is_recursive_wrapper (modeled on code by David Abrahams)
+//
+// True iff specified type matches recursive_wrapper<T>.
+//
+
+namespace detail {
+
+
+template <typename T>
+struct is_recursive_wrapper_impl
+    : mpl::false_
+{
+};
+
+template <typename T>
+struct is_recursive_wrapper_impl< recursive_wrapper<T> >
+    : mpl::true_
+{
+};
+
+
+} // namespace detail
+
+template< typename T > struct is_recursive_wrapper
+    : public ::boost::integral_constant<bool,(::boost::detail::is_recursive_wrapper_impl<T>::value)>
+{
+public:
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_recursive_wrapper,(T))
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// metafunction unwrap_recursive
+//
+// If specified type T matches recursive_wrapper<U>, then U; else T.
+//
+
+
+template <typename T>
+struct unwrap_recursive
+{
+    typedef T type;
+
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,unwrap_recursive,(T))
+};
+
+template <typename T>
+struct unwrap_recursive< recursive_wrapper<T> >
+{
+    typedef T type;
+
+    BOOST_MPL_AUX_LAMBDA_SUPPORT_SPEC(1,unwrap_recursive,(T))
+};
+
+
+} // namespace boost
+
+#endif // BOOST_VARIANT_RECURSIVE_WRAPPER_FWD_HPP
diff --git a/third_party/boost/boost/variant/static_visitor.hpp b/third_party/boost/boost/variant/static_visitor.hpp
new file mode 100644
index 0000000..7fe9ca6
--- /dev/null
+++ b/third_party/boost/boost/variant/static_visitor.hpp
@@ -0,0 +1,95 @@
+//-----------------------------------------------------------------------------
+// boost variant/static_visitor.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2002-2003
+// Eric Friedman
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_STATIC_VISITOR_HPP
+#define BOOST_VARIANT_STATIC_VISITOR_HPP
+
+#include "boost/config.hpp"
+#include "boost/detail/workaround.hpp"
+
+#include "boost/mpl/if.hpp"
+#include "boost/type_traits/is_base_and_derived.hpp"
+
+#include <boost/type_traits/integral_constant.hpp>
+#include <boost/mpl/aux_/lambda_support.hpp>
+
+namespace boost {
+
+//////////////////////////////////////////////////////////////////////////
+// class template static_visitor
+//
+// An empty base class that typedefs the return type of a deriving static
+// visitor. The class is analogous to std::unary_function in this role.
+//
+
+namespace detail {
+
+    struct is_static_visitor_tag { };
+
+    typedef void static_visitor_default_return;
+
+} // namespace detail
+
+template <typename R = ::boost::detail::static_visitor_default_return>
+class static_visitor
+    : public detail::is_static_visitor_tag
+{
+public: // typedefs
+
+    typedef R result_type;
+
+protected: // for use as base class only
+#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)
+    static_visitor() = default;
+    ~static_visitor() = default;
+#else
+    static_visitor()  BOOST_NOEXCEPT { }
+    ~static_visitor()  BOOST_NOEXCEPT { }
+#endif
+};
+
+//////////////////////////////////////////////////////////////////////////
+// metafunction is_static_visitor
+//
+// Value metafunction indicates whether the specified type derives from
+// static_visitor<...>.
+//
+// NOTE #1: This metafunction does NOT check whether the specified type
+//  fulfills the requirements of the StaticVisitor concept.
+//
+// NOTE #2: This template never needs to be specialized!
+//
+
+namespace detail {
+
+template <typename T>
+struct is_static_visitor_impl
+{
+    BOOST_STATIC_CONSTANT(bool, value =
+        (::boost::is_base_and_derived<
+            detail::is_static_visitor_tag,
+            T
+        >::value));
+};
+
+} // namespace detail
+
+template< typename T > struct is_static_visitor
+	: public ::boost::integral_constant<bool,(::boost::detail::is_static_visitor_impl<T>::value)>
+{
+public:
+    BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_static_visitor,(T))
+};
+
+} // namespace boost
+
+#endif // BOOST_VARIANT_STATIC_VISITOR_HPP
diff --git a/third_party/boost/boost/variant/variant.hpp b/third_party/boost/boost/variant/variant.hpp
new file mode 100644
index 0000000..ba74588
--- /dev/null
+++ b/third_party/boost/boost/variant/variant.hpp
@@ -0,0 +1,2418 @@
+//-----------------------------------------------------------------------------
+// boost variant/variant.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2002-2003 Eric Friedman, Itay Maman
+// Copyright (c) 2012-2014 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Thanks to Adam Romanek for providing patches for exception-disabled env.
+
+#ifndef BOOST_VARIANT_VARIANT_HPP
+#define BOOST_VARIANT_VARIANT_HPP
+
+#include <cstddef> // for std::size_t
+#include <new> // for placement new
+
+#include "boost/type_index.hpp"
+
+#include "boost/variant/detail/config.hpp"
+#include "boost/mpl/aux_/value_wknd.hpp"
+
+#include "boost/variant/variant_fwd.hpp"
+#include "boost/variant/detail/backup_holder.hpp"
+#include "boost/variant/detail/enable_recursive_fwd.hpp"
+#include "boost/variant/detail/forced_return.hpp"
+#include "boost/variant/detail/initializer.hpp"
+#include "boost/variant/detail/make_variant_list.hpp"
+#include "boost/variant/detail/over_sequence.hpp"
+#include "boost/variant/detail/visitation_impl.hpp"
+#include "boost/variant/detail/hash_variant.hpp"
+
+#include "boost/variant/detail/generic_result_type.hpp"
+#include "boost/variant/detail/move.hpp"
+
+#include "boost/detail/no_exceptions_support.hpp"
+#include "boost/detail/reference_content.hpp"
+#include "boost/aligned_storage.hpp"
+#include "boost/blank.hpp"
+#include "boost/math/common_factor_ct.hpp"
+#include "boost/static_assert.hpp"
+#include "boost/preprocessor/cat.hpp"
+#include "boost/preprocessor/repeat.hpp"
+#include "boost/type_traits/alignment_of.hpp"
+#include "boost/type_traits/add_const.hpp"
+#include "boost/type_traits/has_nothrow_constructor.hpp"
+#include "boost/type_traits/has_nothrow_copy.hpp"
+#include "boost/type_traits/is_nothrow_move_assignable.hpp"
+#include "boost/type_traits/is_nothrow_move_constructible.hpp"
+#include "boost/type_traits/is_const.hpp"
+#include "boost/type_traits/is_same.hpp"
+#include "boost/type_traits/is_rvalue_reference.hpp"
+#include "boost/utility/enable_if.hpp"
+#include "boost/utility/declval.hpp"
+#include "boost/variant/recursive_wrapper_fwd.hpp"
+#include "boost/variant/static_visitor.hpp"
+
+#include "boost/mpl/assert.hpp"
+#include "boost/mpl/begin_end.hpp"
+#include "boost/mpl/bool.hpp"
+#include "boost/mpl/deref.hpp"
+#include "boost/mpl/empty.hpp"
+#include "boost/mpl/eval_if.hpp"
+#include "boost/mpl/find_if.hpp"
+#include "boost/mpl/fold.hpp"
+#include "boost/mpl/front.hpp"
+#include "boost/mpl/identity.hpp"
+#include "boost/mpl/if.hpp"
+#include "boost/mpl/int.hpp"
+#include "boost/mpl/is_sequence.hpp"
+#include "boost/mpl/iterator_range.hpp"
+#include "boost/mpl/iter_fold_if.hpp"
+#include "boost/mpl/logical.hpp"
+#include "boost/mpl/max_element.hpp"
+#include "boost/mpl/next.hpp"
+#include "boost/mpl/not.hpp"
+#include "boost/mpl/pair.hpp"
+#include "boost/mpl/protect.hpp"
+#include "boost/mpl/push_front.hpp"
+#include "boost/mpl/same_as.hpp"
+#include "boost/mpl/size_t.hpp"
+#include "boost/mpl/sizeof.hpp"
+#include "boost/mpl/transform.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+// Implementation Macros:
+//
+// BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
+//   Defined in boost/variant/detail/visitation_impl.hpp.
+//
+// BOOST_VARIANT_MINIMIZE_SIZE
+//   When #defined, implementation employs all known means to minimize the
+//   size of variant obje   cts. However, often unsuccessful due to alignment
+//   issues, and potentially harmful to runtime speed, so not enabled by
+//   default. (TODO: Investigate further.)
+
+#if defined(BOOST_VARIANT_MINIMIZE_SIZE)
+#   include <climits> // for SCHAR_MAX
+#   include "boost/mpl/eval_if.hpp"
+#   include "boost/mpl/equal_to.hpp"
+#   include "boost/mpl/identity.hpp"
+#   include "boost/mpl/int.hpp"
+#   include "boost/mpl/if.hpp"
+#   include "boost/mpl/less.hpp"
+#   include "boost/mpl/long.hpp"
+#   include "boost/mpl/O1_size.hpp"
+#endif
+
+
+namespace boost {
+
+namespace detail { namespace variant {
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) metafunction max_value
+//
+// Finds the maximum value of the unary metafunction F over Sequence.
+//
+template <typename Sequence, typename F>
+struct max_value
+{
+private: // helpers, for metafunction result (below)
+
+    typedef typename mpl::transform1<Sequence, F>::type transformed_;
+    typedef typename mpl::max_element<transformed_
+
+        >::type max_it;
+
+public: // metafunction result
+
+    typedef typename mpl::deref<max_it>::type
+        type;
+
+};
+
+struct add_alignment
+{
+    template <typename State, typename Item>
+    struct apply
+        : mpl::size_t<
+              ::boost::math::static_lcm<
+                  BOOST_MPL_AUX_VALUE_WKND(State)::value
+                , ::boost::alignment_of<Item>::value
+                >::value
+            >
+    {};
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) metafunction find_fallback_type
+//
+// Provides a fallback (i.e., nothrow default-constructible) type from the
+// specified sequence, or no_fallback_type if not found.
+//
+// This implementation is designed to prefer boost::blank over other potential
+// fallback types, regardless of its position in the specified sequence.
+//
+
+class no_fallback_type;
+
+struct find_fallback_type_pred
+{
+    template <typename Iterator>
+    struct apply
+    {
+    private:
+        typedef typename mpl::deref<Iterator>::type t_;
+
+    public:
+        typedef mpl::not_< has_nothrow_constructor<t_> > type;
+    };
+};
+
+template <typename Types>
+struct find_fallback_type
+{
+private: // helpers, for metafunction result (below)
+
+    typedef typename mpl::end<Types>::type end_it;
+
+    // [Find the first suitable fallback type...]
+
+    typedef typename mpl::iter_fold_if<
+          Types
+        , mpl::int_<0>, mpl::protect< mpl::next<> >
+        , mpl::protect< find_fallback_type_pred >
+        >::type first_result_;
+
+    typedef typename first_result_::first first_result_index;
+    typedef typename first_result_::second first_result_it;
+
+    // [...now search the rest of the sequence for boost::blank...]
+
+    typedef typename mpl::iter_fold_if<
+          mpl::iterator_range< first_result_it,end_it >
+        , first_result_index, mpl::protect< mpl::next<> >
+        , mpl::protect< mpl::not_same_as<boost::blank> >
+        >::type second_result_;
+
+    typedef typename second_result_::second second_result_it;
+
+public: // metafunction result
+
+    // [...and return the results of the search:]
+    typedef typename mpl::eval_if<
+          is_same< second_result_it,end_it >
+        , mpl::if_<
+              is_same< first_result_it,end_it >
+            , mpl::pair< no_fallback_type,no_fallback_type >
+            , first_result_
+            >
+        , mpl::identity< second_result_ >
+        >::type type;
+
+};
+
+#ifndef BOOST_NO_CXX11_NOEXCEPT
+///////////////////////////////////////////////////////////////////////////////
+// (detail) metafunction is_variant_move_noexcept_constructible
+//
+// Returns true_type if all the types are nothrow move constructible.
+//
+template <class Types>
+struct is_variant_move_noexcept_constructible {
+    typedef typename boost::mpl::find_if<
+        Types, mpl::not_<boost::is_nothrow_move_constructible<boost::mpl::_1> >
+    >::type iterator_t;
+
+    typedef typename boost::mpl::end<Types>::type end_t;
+    typedef typename boost::is_same<
+        iterator_t, end_t
+    >::type type;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) metafunction is_variant_move_noexcept_assignable
+//
+// Returns true_type if all the types are nothrow move constructible.
+//
+template <class Types>
+struct is_variant_move_noexcept_assignable {
+    typedef typename boost::mpl::find_if<
+        Types, mpl::not_<boost::is_nothrow_move_assignable<boost::mpl::_1> >
+    >::type iterator_t;
+
+    typedef typename boost::mpl::end<Types>::type end_t;
+    typedef typename boost::is_same<
+        iterator_t, end_t
+    >::type type;
+};
+#endif // BOOST_NO_CXX11_NOEXCEPT
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) metafunction make_storage
+//
+// Provides an aligned storage type capable of holding any of the types
+// specified in the given type-sequence.
+//
+
+template <typename Types, typename NeverUsesBackupFlag>
+struct make_storage
+{
+private: // helpers, for metafunction result (below)
+
+    typedef typename mpl::eval_if<
+          NeverUsesBackupFlag
+        , mpl::identity< Types >
+        , mpl::push_front<
+              Types, backup_holder<void*>
+            >
+        >::type types;
+
+    typedef typename max_value<
+          types, mpl::sizeof_<mpl::_1>
+        >::type max_size;
+
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551))
+
+    typedef typename mpl::fold<
+          types
+        , mpl::size_t<1>
+        , add_alignment
+        >::type max_alignment;
+
+#else // borland
+
+    // temporary workaround -- use maximal alignment
+    typedef mpl::size_t< -1 > max_alignment;
+
+#endif // borland workaround
+
+public: // metafunction result
+
+    typedef ::boost::aligned_storage<
+          BOOST_MPL_AUX_VALUE_WKND(max_size)::value
+        , BOOST_MPL_AUX_VALUE_WKND(max_alignment)::value
+        > type;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class destroyer
+//
+// Internal visitor that destroys the value it visits.
+//
+struct destroyer
+    : public static_visitor<>
+{
+public: // visitor interfaces
+
+    template <typename T>
+        BOOST_VARIANT_AUX_RETURN_VOID_TYPE
+    internal_visit(T& operand, int) const BOOST_NOEXCEPT
+    {
+        operand.~T(); // must be noexcept
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0551)) || \
+    BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
+        operand; // suppresses warnings
+#endif
+
+        BOOST_VARIANT_AUX_RETURN_VOID;
+    }
+
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class template known_get
+//
+// Visitor that returns a reference to content of the specified type.
+//
+// Precondition: visited variant MUST contain logical content of type T.
+//
+template <typename T>
+class known_get
+    : public static_visitor<T&>
+{
+
+public: // visitor interface
+
+    T& operator()(T& operand) const BOOST_NOEXCEPT
+    {
+        return operand;
+    }
+
+    template <typename U>
+    T& operator()(U&) const
+    {
+        // logical error to be here: see precondition above
+        return ::boost::detail::variant::forced_return< T& >();
+    }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class copy_into
+//
+// Internal visitor that copies the value it visits into the given buffer.
+//
+class copy_into
+    : public static_visitor<>
+{
+private: // representation
+
+    void* storage_;
+
+public: // structors
+
+    explicit copy_into(void* storage) BOOST_NOEXCEPT
+        : storage_(storage)
+    {
+    }
+
+public: // internal visitor interface
+
+    template <typename T>
+        BOOST_VARIANT_AUX_RETURN_VOID_TYPE
+    internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
+    {
+        new(storage_) T( operand.get() );
+        BOOST_VARIANT_AUX_RETURN_VOID;
+    }
+
+    template <typename T>
+        BOOST_VARIANT_AUX_RETURN_VOID_TYPE
+    internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const
+    {
+        new(storage_) T( operand.get() );
+        BOOST_VARIANT_AUX_RETURN_VOID;
+    }
+
+    template <typename T>
+        BOOST_VARIANT_AUX_RETURN_VOID_TYPE
+    internal_visit(const T& operand, int) const
+    {
+        new(storage_) T(operand);
+        BOOST_VARIANT_AUX_RETURN_VOID;
+    }
+
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class move_into
+//
+// Internal visitor that moves the value it visits into the given buffer.
+//
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+class move_into
+    : public static_visitor<>
+{
+private: // representation
+
+    void* storage_;
+
+public: // structors
+
+    explicit move_into(void* storage) BOOST_NOEXCEPT
+        : storage_(storage)
+    {
+    }
+
+public: // internal visitor interface
+
+    template <typename T>
+        BOOST_VARIANT_AUX_RETURN_VOID_TYPE
+    internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
+    {
+        new(storage_) T( ::boost::detail::variant::move(operand.get()) );
+        BOOST_VARIANT_AUX_RETURN_VOID;
+    }
+
+    template <typename T>
+        BOOST_VARIANT_AUX_RETURN_VOID_TYPE
+    internal_visit(T& operand, int) const BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(T(boost::declval<T>())))
+    {
+        new(storage_) T(::boost::detail::variant::move(operand));
+        BOOST_VARIANT_AUX_RETURN_VOID;
+    }
+};
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class assign_storage
+//
+// Internal visitor that assigns the given storage (which must be a
+// constructed value of the same type) to the value it visits.
+//
+struct assign_storage
+    : public static_visitor<>
+{
+private: // representation
+
+    const void* rhs_storage_;
+
+public: // structors
+
+    explicit assign_storage(const void* rhs_storage) BOOST_NOEXCEPT
+        : rhs_storage_(rhs_storage)
+    {
+    }
+
+public: // internal visitor interfaces
+
+    template <typename T>
+        BOOST_VARIANT_AUX_RETURN_VOID_TYPE
+    internal_visit(backup_holder<T>& lhs_content, long) const
+    {
+        lhs_content.get()
+            = static_cast< const backup_holder<T>* >(rhs_storage_)->get();
+        BOOST_VARIANT_AUX_RETURN_VOID;
+    }
+
+    template <typename T>
+        BOOST_VARIANT_AUX_RETURN_VOID_TYPE
+    internal_visit(const backup_holder<T>& lhs_content, long) const
+    {
+        lhs_content.get()
+            = static_cast< const backup_holder<T>* >(rhs_storage_)->get();
+        BOOST_VARIANT_AUX_RETURN_VOID;
+    }
+
+    template <typename T>
+        BOOST_VARIANT_AUX_RETURN_VOID_TYPE
+    internal_visit(T& lhs_content, int) const
+    {
+        // NOTE TO USER :
+        // Compile error here indicates one of variant's bounded types does
+        // not meet the requirements of the Assignable concept. Thus,
+        // variant is not Assignable.
+        //
+        // Hint: Are any of the bounded types const-qualified or references?
+        //
+        lhs_content = *static_cast< const T* >(rhs_storage_);
+        BOOST_VARIANT_AUX_RETURN_VOID;
+    }
+
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class move_storage
+//
+// Internal visitor that moves the given storage (which must be a
+// constructed value of the same type) to the value it visits.
+//
+struct move_storage
+    : public static_visitor<>
+{
+private: // representation
+
+    void* rhs_storage_;
+
+public: // structors
+
+    explicit move_storage(void* rhs_storage) BOOST_NOEXCEPT
+        : rhs_storage_(rhs_storage)
+    {
+    }
+
+public: // internal visitor interfaces
+
+    template <typename T>
+        BOOST_VARIANT_AUX_RETURN_VOID_TYPE
+    internal_visit(backup_holder<T>& lhs_content, long) const
+    {
+        lhs_content.get()
+            = ::boost::detail::variant::move(static_cast<backup_holder<T>* >(rhs_storage_)->get());
+        BOOST_VARIANT_AUX_RETURN_VOID;
+    }
+
+    template <typename T>
+        BOOST_VARIANT_AUX_RETURN_VOID_TYPE
+    internal_visit(const backup_holder<T>& lhs_content, long) const
+    {
+        lhs_content.get()
+            = ::boost::detail::variant::move(static_cast<backup_holder<T>* >(rhs_storage_)->get());
+        BOOST_VARIANT_AUX_RETURN_VOID;
+    }
+
+    template <typename T>
+        BOOST_VARIANT_AUX_RETURN_VOID_TYPE
+    internal_visit(T& lhs_content, int) const
+    {
+        // NOTE TO USER :
+        // Compile error here indicates one of variant's bounded types does
+        // not meet the requirements of the Assignable concept. Thus,
+        // variant is not Assignable.
+        //
+        // Hint: Are any of the bounded types const-qualified or references?
+        //
+        lhs_content = ::boost::detail::variant::move(*static_cast<T* >(rhs_storage_));
+        BOOST_VARIANT_AUX_RETURN_VOID;
+    }
+
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class direct_assigner
+//
+// Generic static visitor that: if and only if the visited value is of the
+// specified type, assigns the given value to the visited value and returns
+// true; else returns false.
+//
+template <typename T>
+class direct_assigner
+    : public static_visitor<bool>
+{
+private: // representation
+
+    const T& rhs_;
+
+public: // structors
+
+    explicit direct_assigner(const T& rhs) BOOST_NOEXCEPT
+        : rhs_(rhs)
+    {
+    }
+
+public: // visitor interface
+
+    bool operator()(T& lhs)
+    {
+        lhs = rhs_;
+        return true;
+    }
+
+    template <typename U>
+    bool operator()(U&) BOOST_NOEXCEPT
+    {
+        return false;
+    }
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
+private:
+    // silence MSVC warning C4512: assignment operator could not be generated
+    direct_assigner& operator= (direct_assigner const&);
+#endif
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class direct_mover
+//
+// Generic static visitor that: if and only if the visited value is of the
+// specified type, move assigns the given value to the visited value and returns
+// true; else returns false.
+//
+template <typename T>
+class direct_mover
+    : public static_visitor<bool>
+{
+private: // representation
+
+    T& rhs_;
+
+public: // structors
+
+    explicit direct_mover(T& rhs) BOOST_NOEXCEPT
+        : rhs_(rhs)
+    {
+    }
+
+public: // visitor interface
+
+    bool operator()(T& lhs)
+    {
+        lhs = ::boost::detail::variant::move(rhs_);
+        return true;
+    }
+
+    template <typename U>
+    bool operator()(U&) BOOST_NOEXCEPT
+    {
+        return false;
+    }
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
+private:
+    // silence MSVC warning C4512: assignment operator could not be generated
+    direct_mover& operator= (direct_mover const&);
+#endif
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class backup_assigner
+//
+// Internal visitor that "assigns" the given value to the visited value,
+// using backup to recover if the destroy-copy sequence fails.
+//
+// NOTE: This needs to be a friend of variant, as it needs access to
+// indicate_which, indicate_backup_which, etc.
+//
+template <typename Variant>
+class backup_assigner
+    : public static_visitor<>
+{
+private: // representation
+
+    Variant& lhs_;
+    int rhs_which_;
+    const void* rhs_content_;
+    void (*copy_rhs_content_)(void*, const void*);
+
+public: // structors
+
+    template<class RhsT>
+    backup_assigner(Variant& lhs, int rhs_which, const RhsT& rhs_content)
+        : lhs_(lhs)
+        , rhs_which_(rhs_which)
+        , rhs_content_(&rhs_content)
+        , copy_rhs_content_(&construct_impl<RhsT>)
+    {
+    }
+
+private: // helpers, for visitor interface (below)
+
+    template<class RhsT>
+    static void construct_impl(void* addr, const void* obj)
+    {
+        new(addr) RhsT(*static_cast<const RhsT*>(obj));
+    }
+
+    template <typename LhsT>
+    void backup_assign_impl(
+          backup_holder<LhsT>& lhs_content
+        , mpl::false_ // is_nothrow_move_constructible
+        , long
+        )
+    {
+        // Move lhs content to backup...
+        backup_holder<LhsT> backup_lhs_content(0);
+        backup_lhs_content.swap(lhs_content); // nothrow
+
+        // ...destroy lhs content...
+        lhs_content.~backup_holder<LhsT>(); // nothrow
+
+        BOOST_TRY
+        {
+            // ...and attempt to copy rhs content into lhs storage:
+            copy_rhs_content_(lhs_.storage_.address(), rhs_content_);
+        }
+        BOOST_CATCH (...)
+        {
+            // In case of failure, copy backup pointer to lhs storage...
+            new(lhs_.storage_.address())
+                    backup_holder<LhsT>( 0 ); // nothrow
+
+            static_cast<backup_holder<LhsT>* >(lhs_.storage_.address())
+                    ->swap(backup_lhs_content); // nothrow
+
+            // ...and rethrow:
+            BOOST_RETHROW;
+        }
+        BOOST_CATCH_END
+
+        // In case of success, indicate new content type:
+        lhs_.indicate_which(rhs_which_); // nothrow
+    }
+
+    template <typename LhsT>
+    void backup_assign_impl(
+          LhsT& lhs_content
+        , mpl::true_ // is_nothrow_move_constructible
+        , int
+        )
+    {
+        // Move lhs content to backup...
+        LhsT backup_lhs_content(
+              ::boost::detail::variant::move(lhs_content)
+            ); // nothrow
+
+        // ...destroy lhs content...
+        lhs_content.~LhsT(); // nothrow
+
+        BOOST_TRY
+        {
+            // ...and attempt to copy rhs content into lhs storage:
+            copy_rhs_content_(lhs_.storage_.address(), rhs_content_);
+        }
+        BOOST_CATCH (...)
+        {
+            // In case of failure, restore backup content to lhs storage...
+            new(lhs_.storage_.address())
+                LhsT(
+                      ::boost::detail::variant::move(backup_lhs_content)
+                    ); // nothrow
+
+            // ...and rethrow:
+            BOOST_RETHROW;
+        }
+        BOOST_CATCH_END
+
+        // In case of success, indicate new content type:
+        lhs_.indicate_which(rhs_which_); // nothrow
+    }
+
+    template <typename LhsT>
+    void backup_assign_impl(
+          LhsT& lhs_content
+        , mpl::false_ // is_nothrow_move_constructible
+        , int
+        )
+    {
+        // Backup lhs content...
+        LhsT* backup_lhs_ptr = new LhsT(lhs_content);
+
+        // ...destroy lhs content...
+        lhs_content.~LhsT(); // nothrow
+
+        BOOST_TRY
+        {
+            // ...and attempt to copy rhs content into lhs storage:
+            copy_rhs_content_(lhs_.storage_.address(), rhs_content_);
+        }
+        BOOST_CATCH (...)
+        {
+            // In case of failure, copy backup pointer to lhs storage...
+            new(lhs_.storage_.address())
+                backup_holder<LhsT>( backup_lhs_ptr ); // nothrow
+
+            // ...indicate now using backup...
+            lhs_.indicate_backup_which( lhs_.which() ); // nothrow
+
+            // ...and rethrow:
+            BOOST_RETHROW;
+        }
+        BOOST_CATCH_END
+
+        // In case of success, indicate new content type...
+        lhs_.indicate_which(rhs_which_); // nothrow
+
+        // ...and delete backup:
+        delete backup_lhs_ptr; // nothrow
+    }
+
+public: // visitor interface
+
+    template <typename LhsT>
+        BOOST_VARIANT_AUX_RETURN_VOID_TYPE
+    internal_visit(LhsT& lhs_content, int)
+    {
+        typedef typename is_nothrow_move_constructible<LhsT>::type
+            nothrow_move;
+
+        backup_assign_impl( lhs_content, nothrow_move(), 1L);
+
+        BOOST_VARIANT_AUX_RETURN_VOID;
+    }
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
+private:
+    // silence MSVC warning C4512: assignment operator could not be generated
+    backup_assigner& operator= (backup_assigner const&);
+#endif
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class swap_with
+//
+// Visitor that swaps visited value with content of given variant.
+//
+// Precondition: Given variant MUST have same logical type as visited value.
+//
+template <typename Variant>
+struct swap_with
+    : public static_visitor<>
+{
+private: // representation
+
+    Variant& toswap_;
+
+public: // structors
+
+    explicit swap_with(Variant& toswap) BOOST_NOEXCEPT
+        : toswap_(toswap)
+    {
+    }
+
+public: // internal visitor interfaces
+
+    template <typename T>
+    void operator()(T& operand) const
+    {
+        // Since the precondition ensures types are same, get T...
+        known_get<T> getter;
+        T& other = toswap_.apply_visitor(getter);
+
+        // ...and swap:
+        ::boost::detail::variant::move_swap( operand, other );
+    }
+
+private:
+    swap_with& operator=(const swap_with&);
+
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class reflect
+//
+// Generic static visitor that performs a typeid on the value it visits.
+//
+
+class reflect
+    : public static_visitor<const boost::typeindex::type_info&>
+{
+public: // visitor interfaces
+
+    template <typename T>
+    const boost::typeindex::type_info& operator()(const T&) const BOOST_NOEXCEPT
+    {
+        return boost::typeindex::type_id<T>().type_info();
+    }
+
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class comparer
+//
+// Generic static visitor that compares the content of the given lhs variant
+// with the visited rhs content using Comp.
+//
+// Precondition: lhs.which() == rhs.which()
+//
+template <typename Variant, typename Comp>
+class comparer
+    : public static_visitor<bool>
+{
+private: // representation
+
+    const Variant& lhs_;
+
+public: // structors
+
+    explicit comparer(const Variant& lhs) BOOST_NOEXCEPT
+        : lhs_(lhs)
+    {
+    }
+
+public: // visitor interfaces
+
+    template <typename T>
+    bool operator()(const T& rhs_content) const
+    {
+        // Since the precondition ensures lhs and rhs types are same, get T...
+        known_get<const T> getter;
+        const T& lhs_content = lhs_.apply_visitor(getter);
+
+        // ...and compare lhs and rhs contents:
+        return Comp()(lhs_content, rhs_content);
+    }
+
+private:
+    comparer& operator=(const comparer&);
+
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class equal_comp
+//
+// Generic function object compares lhs with rhs using operator==.
+//
+struct equal_comp
+{
+    template <typename T>
+    bool operator()(const T& lhs, const T& rhs) const
+    {
+        return lhs == rhs;
+    }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class less_comp
+//
+// Generic function object compares lhs with rhs using operator<.
+//
+struct less_comp
+{
+    template <typename T>
+    bool operator()(const T& lhs, const T& rhs) const
+    {
+        return lhs < rhs;
+    }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class template invoke_visitor
+//
+// Internal visitor that invokes the given visitor using:
+//  * for wrappers (e.g., recursive_wrapper), the wrapper's held value.
+//  * for all other values, the value itself.
+//
+template <typename Visitor>
+class invoke_visitor
+{
+private: // representation
+
+    Visitor& visitor_;
+
+public: // visitor typedefs
+
+    typedef typename Visitor::result_type
+        result_type;
+
+public: // structors
+
+    explicit invoke_visitor(Visitor& visitor) BOOST_NOEXCEPT
+        : visitor_(visitor)
+    {
+    }
+
+#if !defined(BOOST_NO_VOID_RETURNS)
+
+public: // internal visitor interfaces
+
+    template <typename T>
+    result_type internal_visit(T& operand, int)
+    {
+        return visitor_(operand);
+    }
+
+#   if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0564))
+    template <typename T>
+    result_type internal_visit(const T& operand, int)
+    {
+        return visitor_(operand);
+    }
+#   endif
+
+#else // defined(BOOST_NO_VOID_RETURNS)
+
+private: // helpers, for internal visitor interfaces (below)
+
+    template <typename T>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
+    visit_impl(T& operand, mpl::false_)
+    {
+        return visitor_(operand);
+    }
+
+    template <typename T>
+        BOOST_VARIANT_AUX_RETURN_VOID_TYPE
+    visit_impl(T& operand, mpl::true_)
+    {
+        visitor_(operand);
+        BOOST_VARIANT_AUX_RETURN_VOID;
+    }
+
+public: // internal visitor interfaces
+
+    template <typename T>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
+    internal_visit(T& operand, int)
+    {
+        typedef typename is_same<result_type, void>::type
+            has_void_result_type;
+
+        return visit_impl(operand, has_void_result_type());
+    }
+
+#endif // BOOST_NO_VOID_RETURNS) workaround
+
+public: // internal visitor interfaces, cont.
+
+    template <typename T>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
+    internal_visit(boost::recursive_wrapper<T>& operand, long)
+    {
+        return internal_visit( operand.get(), 1L );
+    }
+
+    template <typename T>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
+    internal_visit(const boost::recursive_wrapper<T>& operand, long)
+    {
+        return internal_visit( operand.get(), 1L );
+    }
+
+    template <typename T>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
+    internal_visit(boost::detail::reference_content<T>& operand, long)
+    {
+        return internal_visit( operand.get(), 1L );
+    }
+
+    template <typename T>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
+    internal_visit(const boost::detail::reference_content<T>& operand, long)
+    {
+        return internal_visit( operand.get(), 1L );
+    }
+
+    template <typename T>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
+    internal_visit(boost::detail::variant::backup_holder<T>& operand, long)
+    {
+        return internal_visit( operand.get(), 1L );
+    }
+
+    template <typename T>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(result_type)
+    internal_visit(const boost::detail::variant::backup_holder<T>& operand, long)
+    {
+        return internal_visit( operand.get(), 1L );
+    }
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
+private:
+    // silence MSVC warning C4512: assignment operator could not be generated
+    invoke_visitor& operator= (invoke_visitor const&);
+#endif
+};
+
+}} // namespace detail::variant
+
+///////////////////////////////////////////////////////////////////////////////
+// class template variant (concept inspired by Andrei Alexandrescu)
+//
+// See docs and boost/variant/variant_fwd.hpp for more information.
+//
+template <
+      typename T0_
+    , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename T)
+    >
+class variant
+{
+private: // helpers, for typedefs (below)
+
+    typedef variant wknd_self_t;
+
+    struct is_recursive_
+        : detail::variant::is_recursive_flag<T0_>
+    {
+    };
+
+    typedef typename mpl::eval_if<
+          is_recursive_
+        , T0_
+        , mpl::identity< T0_ >
+        >::type unwrapped_T0_;
+
+    struct is_sequence_based_
+        : detail::variant::is_over_sequence<unwrapped_T0_>
+    {
+    };
+
+#if !defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
+
+private: // helpers, for typedefs (below)
+
+    typedef typename mpl::eval_if<
+          is_sequence_based_
+        , unwrapped_T0_ // over_sequence<...>::type
+        , detail::variant::make_variant_list<
+              unwrapped_T0_
+            , BOOST_VARIANT_ENUM_SHIFTED_PARAMS(T)
+            >
+        >::type specified_types;
+
+    BOOST_STATIC_ASSERT((
+          ::boost::mpl::not_< mpl::empty<specified_types> >::value
+        ));
+
+    typedef typename mpl::eval_if<
+          is_recursive_
+        , mpl::transform<
+              specified_types
+            , mpl::protect<
+                  detail::variant::quoted_enable_recursive<wknd_self_t>
+                >
+            >
+        , mpl::identity< specified_types >
+        >::type recursive_enabled_types;
+
+public: // public typedefs
+
+    typedef typename mpl::transform<
+          recursive_enabled_types
+        , unwrap_recursive<mpl::_1>
+        >::type types;
+
+private: // internal typedefs
+
+    typedef typename mpl::transform<
+          recursive_enabled_types
+        , mpl::protect< detail::make_reference_content<> >
+        >::type internal_types;
+
+    typedef typename mpl::front<
+          internal_types
+        >::type internal_T0;
+
+#else // defined(BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
+
+private: // helpers, for typedefs (below)
+
+    typedef unwrapped_T0_ T0;
+
+    #define BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS(z,N,_) \
+        typedef typename mpl::eval_if< \
+              is_recursive_ \
+            , detail::variant::enable_recursive< \
+                  BOOST_PP_CAT(T,N) \
+                , wknd_self_t \
+                > \
+            , mpl::identity< BOOST_PP_CAT(T,N) > \
+            >::type BOOST_PP_CAT(recursive_enabled_T,N); \
+        /**/
+
+    BOOST_PP_REPEAT(
+          BOOST_VARIANT_LIMIT_TYPES
+        , BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
+        , _
+        )
+
+    #undef BOOST_VARIANT_AUX_ENABLE_RECURSIVE_TYPEDEFS
+
+    #define BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS(z,N,_) \
+        typedef typename unwrap_recursive< \
+              BOOST_PP_CAT(recursive_enabled_T,N) \
+            >::type BOOST_PP_CAT(public_T,N); \
+        /**/
+
+    BOOST_PP_REPEAT(
+          BOOST_VARIANT_LIMIT_TYPES
+        , BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS
+        , _
+        )
+
+    #undef BOOST_VARIANT_AUX_UNWRAP_RECURSIVE_TYPEDEFS
+
+public: // public typedefs
+
+    typedef typename detail::variant::make_variant_list<
+          BOOST_VARIANT_ENUM_PARAMS(public_T)
+        >::type types;
+
+private: // helpers, for internal typedefs (below)
+
+    #define BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS(z,N,_) \
+        typedef detail::make_reference_content< \
+              BOOST_PP_CAT(recursive_enabled_T,N) \
+            >::type BOOST_PP_CAT(internal_T,N); \
+        /**/
+
+    BOOST_PP_REPEAT(
+          BOOST_VARIANT_LIMIT_TYPES
+        , BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS
+        , _
+        )
+
+    #undef BOOST_VARIANT_AUX_MAKE_REFERENCE_CONTENT_TYPEDEFS
+
+private: // internal typedefs
+
+    typedef typename detail::variant::make_variant_list<
+          BOOST_VARIANT_ENUM_PARAMS(internal_T)
+        >::type internal_types;
+
+private: // static precondition assertions
+
+    // NOTE TO USER :
+    // variant< type-sequence > syntax is not supported on this compiler!
+    //
+    BOOST_MPL_ASSERT_NOT(( is_sequence_based_ ));
+
+#endif // BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT workaround
+
+private: // helpers, for representation (below)
+
+    typedef typename detail::variant::find_fallback_type<
+          internal_types
+        >::type fallback_type_result_;
+
+    typedef typename fallback_type_result_::first
+        fallback_type_index_;
+    typedef typename fallback_type_result_::second
+        fallback_type_;
+
+    struct has_fallback_type_
+        : mpl::not_<
+              is_same< fallback_type_, detail::variant::no_fallback_type >
+            >
+    {
+    };
+
+    typedef has_fallback_type_
+        never_uses_backup_flag;
+
+    typedef typename detail::variant::make_storage<
+          internal_types, never_uses_backup_flag
+        >::type storage_t;
+
+#ifndef BOOST_NO_CXX11_NOEXCEPT
+    typedef typename detail::variant::is_variant_move_noexcept_constructible<
+        internal_types
+    > variant_move_noexcept_constructible;
+
+    typedef typename detail::variant::is_variant_move_noexcept_assignable<
+        internal_types
+    > variant_move_noexcept_assignable;
+
+#endif
+
+private: // helpers, for representation (below)
+
+    // which_ on:
+    // * [0,  size<internal_types>) indicates stack content
+    // * [-size<internal_types>, 0) indicates pointer to heap backup
+    // if which_ >= 0:
+    // * then which() -> which_
+    // * else which() -> -(which_ + 1)
+
+#if !defined(BOOST_VARIANT_MINIMIZE_SIZE)
+
+    typedef int which_t;
+
+#else // defined(BOOST_VARIANT_MINIMIZE_SIZE)
+
+    // [if O1_size available, then attempt which_t size optimization...]
+    // [select signed char if fewer than SCHAR_MAX types, else signed int:]
+    typedef typename mpl::eval_if<
+          mpl::equal_to< mpl::O1_size<internal_types>, mpl::long_<-1> >
+        , mpl::identity< int >
+        , mpl::if_<
+              mpl::less< mpl::O1_size<internal_types>, mpl::int_<SCHAR_MAX> >
+            , signed char
+            , int
+            >
+        >::type which_t;
+
+#endif // BOOST_VARIANT_MINIMIZE_SIZE switch
+
+// representation -- private when possible
+#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
+    private:
+#else
+    public:
+#endif
+
+    which_t which_;
+    storage_t storage_;
+
+    void indicate_which(int which_arg) BOOST_NOEXCEPT
+    {
+        which_ = static_cast<which_t>( which_arg );
+    }
+
+    void indicate_backup_which(int which_arg) BOOST_NOEXCEPT
+    {
+        which_ = static_cast<which_t>( -(which_arg + 1) );
+    }
+
+private: // helpers, for queries (below)
+
+    bool using_backup() const BOOST_NOEXCEPT
+    {
+        return which_ < 0;
+    }
+
+public: // queries
+
+    int which() const BOOST_NOEXCEPT
+    {
+        // If using heap backup...
+        if (using_backup())
+            // ...then return adjusted which_:
+            return -(which_ + 1);
+
+        // Otherwise, return which_ directly:
+        return which_;
+    }
+
+private: // helpers, for structors (below)
+
+    struct initializer
+        : BOOST_VARIANT_AUX_INITIALIZER_T(
+              recursive_enabled_types, recursive_enabled_T
+            )
+    {
+    };
+
+    void destroy_content() BOOST_NOEXCEPT
+    {
+        detail::variant::destroyer visitor;
+        this->internal_apply_visitor(visitor);
+    }
+
+public: // structors
+
+    ~variant() BOOST_NOEXCEPT
+    {
+        destroy_content();
+    }
+
+    variant()
+#if !(defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5130))
+              BOOST_NOEXCEPT_IF(boost::has_nothrow_constructor<internal_T0>::value)
+#endif
+    {
+#ifdef _MSC_VER
+#pragma warning( push )
+// behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized
+#pragma warning( disable : 4345 )
+#endif
+        // NOTE TO USER :
+        // Compile error from here indicates that the first bound
+        // type is not default-constructible, and so variant cannot
+        // support its own default-construction.
+        //
+        new( storage_.address() ) internal_T0();
+        indicate_which(0); // zero is the index of the first bounded type
+#ifdef _MSC_VER
+#pragma warning( pop )
+#endif
+    }
+
+private: // helpers, for structors, cont. (below)
+
+    class convert_copy_into
+        : public static_visitor<int>
+    {
+    private: // representation
+
+        void* storage_;
+
+    public: // structors
+
+        explicit convert_copy_into(void* storage) BOOST_NOEXCEPT
+            : storage_(storage)
+        {
+        }
+
+    public: // internal visitor interfaces (below)
+
+        template <typename T>
+        int internal_visit(T& operand, int) const
+        {
+            // NOTE TO USER :
+            // Compile error here indicates one of the source variant's types
+            // cannot be unambiguously converted to the destination variant's
+            // types (or that no conversion exists).
+            //
+            return initializer::initialize(storage_, operand);
+        }
+
+#   if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0564))
+        template <typename T>
+        result_type internal_visit(const T& operand, int) const
+        {
+            return initializer::initialize(storage_, operand);
+        }
+#   endif
+
+        template <typename T>
+        int internal_visit(boost::detail::reference_content<T>& operand, long) const
+        {
+            return internal_visit( operand.get(), 1L );
+        }
+
+        template <typename T>
+        int internal_visit(const boost::detail::reference_content<T>& operand, long) const
+        {
+            return internal_visit( operand.get(), 1L );
+        }
+
+        template <typename T>
+        int internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
+        {
+            return internal_visit( operand.get(), 1L );
+        }
+
+        template <typename T>
+        int internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const
+        {
+            return internal_visit( operand.get(), 1L );
+        }
+
+        template <typename T>
+        int internal_visit(boost::recursive_wrapper<T>& operand, long) const
+        {
+            return internal_visit( operand.get(), 1L );
+        }
+
+        template <typename T>
+        int internal_visit(const boost::recursive_wrapper<T>& operand, long) const
+        {
+            return internal_visit( operand.get(), 1L );
+        }
+
+    };
+
+    friend class convert_copy_into;
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    class convert_move_into
+        : public static_visitor<int>
+    {
+    private: // representation
+
+        void* storage_;
+
+    public: // structors
+
+        explicit convert_move_into(void* storage) BOOST_NOEXCEPT
+            : storage_(storage)
+        {
+        }
+
+    public: // internal visitor interfaces (below)
+
+        template <typename T>
+        int internal_visit(T& operand, int) const
+        {
+            // NOTE TO USER :
+            // Compile error here indicates one of the source variant's types
+            // cannot be unambiguously converted to the destination variant's
+            // types (or that no conversion exists).
+            //
+            return initializer::initialize(storage_, detail::variant::move(operand) );
+        }
+
+        template <typename T>
+        int internal_visit(boost::detail::reference_content<T>& operand, long) const
+        {
+            return internal_visit( operand.get(), 1L );
+        }
+
+        template <typename T>
+        int internal_visit(const boost::detail::reference_content<T>& operand, long) const
+        {
+            return internal_visit( operand.get(), 1L );
+        }
+
+        template <typename T>
+        int internal_visit(boost::detail::variant::backup_holder<T>& operand, long) const
+        {
+            return internal_visit( operand.get(), 1L );
+        }
+
+        template <typename T>
+        int internal_visit(const boost::detail::variant::backup_holder<T>& operand, long) const
+        {
+            return internal_visit( operand.get(), 1L );
+        }
+
+        template <typename T>
+        int internal_visit(boost::recursive_wrapper<T>& operand, long) const
+        {
+            return internal_visit( operand.get(), 1L );
+        }
+
+        template <typename T>
+        int internal_visit(const boost::recursive_wrapper<T>& operand, long) const
+        {
+            return internal_visit( operand.get(), 1L );
+        }
+    };
+
+    friend class convert_move_into;
+#endif
+
+private: // helpers, for structors, below
+
+    template <typename T>
+    void convert_construct(
+          T& operand
+        , int
+        , mpl::false_ = mpl::false_() // is_foreign_variant
+        )
+    {
+        // NOTE TO USER :
+        // Compile error here indicates that the given type is not
+        // unambiguously convertible to one of the variant's types
+        // (or that no conversion exists).
+        //
+        indicate_which(
+              initializer::initialize(
+                  storage_.address()
+                , operand
+                )
+            );
+    }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    template <typename T>
+    typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type convert_construct(
+          T&& operand
+        , int
+        , mpl::false_ = mpl::false_() // is_foreign_variant
+        )
+    {
+        // NOTE TO USER :
+        // Compile error here indicates that the given type is not
+        // unambiguously convertible to one of the variant's types
+        // (or that no conversion exists).
+        //
+        indicate_which(
+              initializer::initialize(
+                  storage_.address()
+                , detail::variant::move(operand)
+                )
+            );
+    }
+#endif
+
+    template <typename Variant>
+    void convert_construct(
+          Variant& operand
+        , long
+        , mpl::true_// is_foreign_variant
+        )
+    {
+        convert_copy_into visitor(storage_.address());
+        indicate_which(
+              operand.internal_apply_visitor(visitor)
+            );
+    }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    template <typename Variant>
+    typename boost::enable_if<boost::is_rvalue_reference<Variant&&> >::type convert_construct(
+          Variant&& operand
+        , long
+        , mpl::true_// is_foreign_variant
+        )
+    {
+        convert_move_into visitor(storage_.address());
+        indicate_which(
+              operand.internal_apply_visitor(visitor)
+            );
+    }
+#endif
+
+    template <typename Variant>
+    void convert_construct_variant(Variant& operand)
+    {
+        // [Determine if the given variant is itself a bounded type, or if its
+        //  content needs to be converted (i.e., it is a 'foreign' variant):]
+        //
+
+        typedef typename mpl::find_if<
+              types
+            , is_same<
+                  add_const<mpl::_1>
+                , const Variant
+                >
+            >::type found_it;
+
+        typedef typename mpl::end<types>::type not_found;
+        typedef typename is_same<
+              found_it, not_found
+            >::type is_foreign_variant;
+
+        // Convert construct from operand:
+        convert_construct(
+              operand, 1L
+            , is_foreign_variant()
+            );
+    }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    template <typename Variant>
+    typename boost::enable_if<boost::is_rvalue_reference<Variant&&> >::type convert_construct_variant(Variant&& operand)
+    {
+        // [Determine if the given variant is itself a bounded type, or if its
+        //  content needs to be converted (i.e., it is a 'foreign' variant):]
+        //
+
+        typedef typename mpl::find_if<
+              types
+            , is_same<
+                  add_const<mpl::_1>
+                , const Variant
+                >
+            >::type found_it;
+
+        typedef typename mpl::end<types>::type not_found;
+        typedef typename is_same<
+              found_it, not_found
+            >::type is_foreign_variant;
+
+        // Convert move construct from operand:
+        convert_construct(
+              detail::variant::move(operand), 1L
+            , is_foreign_variant()
+            );
+    }
+#endif
+
+    template <BOOST_VARIANT_ENUM_PARAMS(typename U)>
+    void convert_construct(
+          boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand
+        , long
+        )
+    {
+        convert_construct_variant(operand);
+    }
+
+    template <BOOST_VARIANT_ENUM_PARAMS(typename U)>
+    void convert_construct(
+          const boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>& operand
+        , long
+        )
+    {
+        convert_construct_variant(operand);
+    }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    template <BOOST_VARIANT_ENUM_PARAMS(typename U)>
+    void convert_construct(
+          boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>&& operand
+        , long
+        )
+    {
+        convert_construct_variant( detail::variant::move(operand) );
+    }
+#endif
+
+public: // structors, cont.
+
+#if !defined(BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING)
+
+    template <typename T>
+    variant(const T& operand)
+    {
+        convert_construct(operand, 1L);
+    }
+
+    template <typename T>
+    variant(T& operand)
+    {
+        convert_construct(operand, 1L);
+    }
+
+#elif defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND)
+
+    // For compilers that cannot distinguish between T& and const T& in
+    // template constructors, but do fully support SFINAE, we can workaround:
+
+    template <typename T>
+    variant(const T& operand)
+    {
+        convert_construct(operand, 1L);
+    }
+
+    template <typename T>
+    variant(
+          T& operand
+        , typename enable_if<
+              mpl::not_< is_const<T> >
+            , void
+            >::type* = 0
+        )
+    {
+        convert_construct(operand, 1L);
+    }
+
+#else // !defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND)
+
+    // For compilers that cannot distinguish between T& and const T& in
+    // template constructors, and do NOT support SFINAE, we can't workaround:
+
+    template <typename T>
+    variant(const T& operand)
+    {
+        convert_construct(operand, 1L);
+    }
+#endif // BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING workarounds
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    template <class T>
+    variant(T&& operand, typename boost::enable_if<boost::is_rvalue_reference<T&&> >::type* = 0,
+        typename boost::disable_if<boost::is_const<T> >::type* = 0)
+    {
+        convert_construct( detail::variant::move(operand), 1L);
+    }
+#endif
+
+public: // structors, cont.
+
+    // [MSVC6 requires copy constructor appear after template constructors]
+    variant(const variant& operand)
+    {
+        // Copy the value of operand into *this...
+        detail::variant::copy_into visitor( storage_.address() );
+        operand.internal_apply_visitor(visitor);
+
+        // ...and activate the *this's primary storage on success:
+        indicate_which(operand.which());
+    }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    variant(variant&& operand) BOOST_NOEXCEPT_IF(variant_move_noexcept_constructible::type::value)
+    {
+        // Move the value of operand into *this...
+        detail::variant::move_into visitor( storage_.address() );
+        operand.internal_apply_visitor(visitor);
+
+        // ...and activate the *this's primary storage on success:
+        indicate_which(operand.which());
+    }
+#endif
+
+private: // helpers, for modifiers (below)
+
+#   if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
+    template <typename Variant>
+    friend class detail::variant::backup_assigner;
+#   endif
+
+    // class assigner
+    //
+    // Internal visitor that "assigns" the visited value to the given variant
+    // by appropriate destruction and copy-construction.
+    //
+
+    class assigner
+        : public static_visitor<>
+    {
+    protected: // representation
+
+        variant& lhs_;
+        const int rhs_which_;
+
+    public: // structors
+
+        assigner(variant& lhs, int rhs_which) BOOST_NOEXCEPT
+            : lhs_(lhs)
+            , rhs_which_(rhs_which)
+        {
+        }
+
+    protected: // helpers, for internal visitor interface (below)
+
+        template <typename RhsT, typename B1, typename B2>
+        void assign_impl(
+              const RhsT& rhs_content
+            , mpl::true_ // has_nothrow_copy
+            , B1 // is_nothrow_move_constructible
+            , B2 // has_fallback_type
+            ) const BOOST_NOEXCEPT
+        {
+            // Destroy lhs's content...
+            lhs_.destroy_content(); // nothrow
+
+            // ...copy rhs content into lhs's storage...
+            new(lhs_.storage_.address())
+                RhsT( rhs_content ); // nothrow
+
+            // ...and indicate new content type:
+            lhs_.indicate_which(rhs_which_); // nothrow
+        }
+
+        template <typename RhsT, typename B>
+        void assign_impl(
+              const RhsT& rhs_content
+            , mpl::false_ // has_nothrow_copy
+            , mpl::true_ // is_nothrow_move_constructible
+            , B // has_fallback_type
+            ) const
+        {
+            // Attempt to make a temporary copy (so as to move it below)...
+            RhsT temp(rhs_content);
+
+            // ...and upon success destroy lhs's content...
+            lhs_.destroy_content(); // nothrow
+
+            // ...move the temporary copy into lhs's storage...
+            new(lhs_.storage_.address())
+                RhsT( detail::variant::move(temp) ); // nothrow
+
+            // ...and indicate new content type:
+            lhs_.indicate_which(rhs_which_); // nothrow
+        }
+
+        void construct_fallback() const BOOST_NOEXCEPT {
+            // In case of failure, default-construct fallback type in lhs's storage...
+            new (lhs_.storage_.address())
+                fallback_type_; // nothrow
+
+            // ...indicate construction of fallback type...
+            lhs_.indicate_which(
+                  BOOST_MPL_AUX_VALUE_WKND(fallback_type_index_)::value
+                ); // nothrow
+        }
+
+        template <typename RhsT>
+        void assign_impl(
+              const RhsT& rhs_content
+            , mpl::false_ // has_nothrow_copy
+            , mpl::false_ // is_nothrow_move_constructible
+            , mpl::true_ // has_fallback_type
+            ) const
+        {
+            // Destroy lhs's content...
+            lhs_.destroy_content(); // nothrow
+
+            BOOST_TRY
+            {
+                // ...and attempt to copy rhs's content into lhs's storage:
+                new(lhs_.storage_.address())
+                    RhsT( rhs_content );
+            }
+            BOOST_CATCH (...)
+            {
+                construct_fallback();
+
+                // ...and rethrow:
+                BOOST_RETHROW;
+            }
+            BOOST_CATCH_END
+
+            // In the event of success, indicate new content type:
+            lhs_.indicate_which(rhs_which_); // nothrow
+        }
+
+        template <typename RhsT>
+        void assign_impl(
+              const RhsT& rhs_content
+            , mpl::false_ // has_nothrow_copy
+            , mpl::false_ // is_nothrow_move_constructible
+            , mpl::false_ // has_fallback_type
+            ) const
+        {
+            detail::variant::backup_assigner<wknd_self_t>
+                visitor(lhs_, rhs_which_, rhs_content);
+            lhs_.internal_apply_visitor(visitor);
+        }
+
+    public: // internal visitor interfaces
+
+        template <typename RhsT>
+            BOOST_VARIANT_AUX_RETURN_VOID_TYPE
+        internal_visit(const RhsT& rhs_content, int) const
+        {
+            typedef typename has_nothrow_copy<RhsT>::type
+                nothrow_copy;
+            typedef typename mpl::or_< // reduces compile-time
+                  nothrow_copy
+                , is_nothrow_move_constructible<RhsT>
+                >::type nothrow_move_constructor;
+
+            assign_impl(
+                  rhs_content
+                , nothrow_copy()
+                , nothrow_move_constructor()
+                , has_fallback_type_()
+                );
+
+            BOOST_VARIANT_AUX_RETURN_VOID;
+        }
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
+    private:
+        // silence MSVC warning C4512: assignment operator could not be generated
+        assigner& operator= (assigner const&);
+#endif
+    };
+
+    friend class assigner;
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    // class move_assigner
+    //
+    // Internal visitor that "move assigns" the visited value to the given variant
+    // by appropriate destruction and move-construction.
+    //
+
+    class move_assigner
+        : public assigner
+    {
+    public: // structors
+
+        move_assigner(variant& lhs, int rhs_which) BOOST_NOEXCEPT
+            : assigner(lhs, rhs_which)
+        {
+        }
+
+    private: // helpers, for internal visitor interface (below)
+
+        template <typename RhsT, typename B2>
+        void assign_impl(
+              RhsT& rhs_content
+            , mpl::true_ // has_nothrow_copy
+            , mpl::false_ // is_nothrow_move_constructible
+            , B2 // has_fallback_type
+            ) const BOOST_NOEXCEPT
+        {
+            assigner::assign_impl(rhs_content, mpl::true_(), mpl::false_(), B2());
+        }
+
+        template <typename RhsT, typename B, typename B2>
+        void assign_impl(
+              RhsT& rhs_content
+            , B // has_nothrow_copy
+            , mpl::true_ // is_nothrow_move_constructible
+            , B2 // has_fallback_type
+            ) const BOOST_NOEXCEPT
+        {
+            // ...destroy lhs's content...
+            assigner::lhs_.destroy_content(); // nothrow
+
+            // ...move the rhs_content into lhs's storage...
+            new(assigner::lhs_.storage_.address())
+                RhsT( detail::variant::move(rhs_content) ); // nothrow
+
+            // ...and indicate new content type:
+            assigner::lhs_.indicate_which(assigner::rhs_which_); // nothrow
+        }
+
+        template <typename RhsT>
+        void assign_impl(
+              RhsT& rhs_content
+            , mpl::false_ // has_nothrow_copy
+            , mpl::false_ // is_nothrow_move_constructible
+            , mpl::true_ // has_fallback_type
+            ) const
+        {
+            // Destroy lhs's content...
+            assigner::lhs_.destroy_content(); // nothrow
+
+            BOOST_TRY
+            {
+                // ...and attempt to copy rhs's content into lhs's storage:
+                new(assigner::lhs_.storage_.address())
+                    RhsT( detail::variant::move(rhs_content) );
+            }
+            BOOST_CATCH (...)
+            {
+                assigner::construct_fallback();
+
+                // ...and rethrow:
+                BOOST_RETHROW;
+            }
+            BOOST_CATCH_END
+
+            // In the event of success, indicate new content type:
+            assigner::lhs_.indicate_which(assigner::rhs_which_); // nothrow
+        }
+
+        template <typename RhsT>
+        void assign_impl(
+              RhsT& rhs_content
+            , mpl::false_ // has_nothrow_copy
+            , mpl::false_ // is_nothrow_move_constructible
+            , mpl::false_ // has_fallback_type
+            ) const
+        {
+            assigner::assign_impl(rhs_content, mpl::false_(), mpl::false_(), mpl::false_());
+        }
+
+    public: // internal visitor interfaces
+
+        template <typename RhsT>
+            BOOST_VARIANT_AUX_RETURN_VOID_TYPE
+        internal_visit(RhsT& rhs_content, int) const
+        {
+            typedef typename is_nothrow_move_constructible<RhsT>::type
+                nothrow_move_constructor;
+            typedef typename mpl::or_< // reduces compile-time
+                  nothrow_move_constructor
+                , has_nothrow_copy<RhsT>
+                >::type nothrow_copy;
+
+            assign_impl(
+                  rhs_content
+                , nothrow_copy()
+                , nothrow_move_constructor()
+                , has_fallback_type_()
+                );
+
+            BOOST_VARIANT_AUX_RETURN_VOID;
+        }
+
+#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1600))
+    private:
+        // silence MSVC warning C4512: assignment operator could not be generated
+        move_assigner& operator= (move_assigner const&);
+#endif
+    };
+
+    friend class move_assigner;
+#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
+
+    void variant_assign(const variant& rhs)
+    {
+        // If the contained types are EXACTLY the same...
+        if (which_ == rhs.which_)
+        {
+            // ...then assign rhs's storage to lhs's content:
+            detail::variant::assign_storage visitor(rhs.storage_.address());
+            this->internal_apply_visitor(visitor);
+        }
+        else
+        {
+            // Otherwise, perform general (copy-based) variant assignment:
+            assigner visitor(*this, rhs.which());
+            rhs.internal_apply_visitor(visitor);
+        }
+    }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    void variant_assign(variant&& rhs)
+    {
+        // If the contained types are EXACTLY the same...
+        if (which_ == rhs.which_)
+        {
+            // ...then move rhs's storage to lhs's content:
+            detail::variant::move_storage visitor(rhs.storage_.address());
+            this->internal_apply_visitor(visitor);
+        }
+        else
+        {
+            // Otherwise, perform general (move-based) variant assignment:
+            move_assigner visitor(*this, rhs.which());
+            rhs.internal_apply_visitor(visitor);
+        }
+    }
+#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
+
+private: // helpers, for modifiers (below)
+
+    template <typename T>
+    void assign(const T& rhs)
+    {
+        // If direct T-to-T assignment is not possible...
+        detail::variant::direct_assigner<T> direct_assign(rhs);
+        if (this->apply_visitor(direct_assign) == false)
+        {
+            // ...then convert rhs to variant and assign:
+            //
+            // While potentially inefficient, the following construction of a
+            // variant allows T as any type convertible to one of the bounded
+            // types without excessive code redundancy.
+            //
+            variant temp(rhs);
+            variant_assign( detail::variant::move(temp) );
+        }
+    }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    template <typename T>
+    void move_assign(T&& rhs)
+    {
+        // If direct T-to-T move assignment is not possible...
+        detail::variant::direct_mover<T> direct_move(rhs);
+        if (this->apply_visitor(direct_move) == false)
+        {
+            // ...then convert rhs to variant and assign:
+            //
+            // While potentially inefficient, the following construction of a
+            // variant allows T as any type convertible to one of the bounded
+            // types without excessive code redundancy.
+            //
+            variant temp( detail::variant::move(rhs) );
+            variant_assign( detail::variant::move(temp) );
+        }
+    }
+#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
+
+public: // modifiers
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    template <class T>
+    typename boost::enable_if_c<boost::is_rvalue_reference<T&&>::value && !boost::is_const<T>::value, variant& >::type
+        operator=(T&& rhs)
+    {
+        move_assign( detail::variant::move(rhs) );
+        return *this;
+    }
+#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
+
+    template <typename T>
+    variant& operator=(const T& rhs)
+    {
+        assign(rhs);
+        return *this;
+    }
+
+    // [MSVC6 requires copy assign appear after templated operator=]
+    variant& operator=(const variant& rhs)
+    {
+        variant_assign(rhs);
+        return *this;
+    }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+    variant& operator=(variant&& rhs)
+#if !defined(__GNUC__) || (__GNUC__ != 4) || (__GNUC_MINOR__ > 6)
+        BOOST_NOEXCEPT_IF(variant_move_noexcept_constructible::type::value && variant_move_noexcept_assignable::type::value)
+#endif
+    {
+        variant_assign( detail::variant::move(rhs) );
+        return *this;
+    }
+#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
+
+    void swap(variant& rhs)
+    {
+        // If the contained types are the same...
+        if (which() == rhs.which())
+        {
+            // ...then swap the values directly:
+            detail::variant::swap_with<variant> visitor(rhs);
+            this->apply_visitor(visitor);
+        }
+        else
+        {
+            // ...otherwise, perform general variant swap:
+            variant tmp( detail::variant::move(rhs) );
+            rhs = detail::variant::move(*this);
+            *this = detail::variant::move(tmp);
+        }
+    }
+
+public: // queries
+
+    //
+    // NOTE: member which() defined above.
+    //
+
+    bool empty() const BOOST_NOEXCEPT
+    {
+        return false;
+    }
+
+    const boost::typeindex::type_info& type() const
+    {
+        detail::variant::reflect visitor;
+        return this->apply_visitor(visitor);
+    }
+
+public: // prevent comparison with foreign types
+
+// Obsolete. Remove.
+#   define BOOST_VARIANT_AUX_FAIL_COMPARISON_RETURN_TYPE \
+    void
+
+    template <typename U>
+    void operator==(const U&) const
+    {
+        BOOST_STATIC_ASSERT( false && sizeof(U) );
+    }
+
+    template <typename U>
+    void operator<(const U&) const
+    {
+        BOOST_STATIC_ASSERT( false && sizeof(U) );
+    }
+
+    template <typename U>
+    void operator!=(const U&) const
+    {
+        BOOST_STATIC_ASSERT( false && sizeof(U) );
+    }
+
+    template <typename U>
+    void operator>(const U&) const
+    {
+        BOOST_STATIC_ASSERT( false && sizeof(U) );
+    }
+
+    template <typename U>
+    void operator<=(const U&) const
+    {
+        BOOST_STATIC_ASSERT( false && sizeof(U) );
+    }
+
+    template <typename U>
+    void operator>=(const U&) const
+    {
+        BOOST_STATIC_ASSERT( false && sizeof(U) );
+    }
+
+public: // comparison operators
+
+    // [MSVC6 requires these operators appear after template operators]
+
+    bool operator==(const variant& rhs) const
+    {
+        if (this->which() != rhs.which())
+            return false;
+
+        detail::variant::comparer<
+              variant, detail::variant::equal_comp
+            > visitor(*this);
+        return rhs.apply_visitor(visitor);
+    }
+
+    bool operator<(const variant& rhs) const
+    {
+        //
+        // Dirk Schreib suggested this collating order.
+        //
+
+        if (this->which() != rhs.which())
+            return this->which() < rhs.which();
+
+        detail::variant::comparer<
+              variant, detail::variant::less_comp
+            > visitor(*this);
+        return rhs.apply_visitor(visitor);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////
+    // comparison operators != > <= >=
+    inline bool operator!=(const variant& rhs) const
+    {
+        return !(*this == rhs);
+    }
+
+    inline bool operator>(const variant& rhs) const
+    {
+        return rhs < *this;
+    }
+
+    inline bool operator<=(const variant& rhs) const
+    {
+        return !(*this > rhs);
+    }
+
+    inline bool operator>=(const variant& rhs) const
+    {
+        return !(*this < rhs);
+    }
+
+// helpers, for visitation support (below) -- private when possible
+#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
+
+    template < BOOST_VARIANT_ENUM_PARAMS(typename U) >
+    friend class variant;
+
+private:
+
+#else// defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
+
+public:
+
+#endif// !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
+
+    template <typename Visitor, typename VoidPtrCV>
+    static
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
+              typename Visitor::result_type
+            )
+    internal_apply_visitor_impl(
+          int internal_which
+        , int logical_which
+        , Visitor& visitor
+        , VoidPtrCV storage
+        )
+    {
+        typedef mpl::int_<0> first_which;
+        typedef typename mpl::begin<internal_types>::type first_it;
+        typedef typename mpl::end<internal_types>::type last_it;
+
+        typedef detail::variant::visitation_impl_step<
+              first_it, last_it
+            > first_step;
+
+        return detail::variant::visitation_impl(
+              internal_which, logical_which
+            , visitor, storage, mpl::false_()
+            , never_uses_backup_flag()
+            , static_cast<first_which*>(0), static_cast<first_step*>(0)
+            );
+    }
+
+    template <typename Visitor>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
+              typename Visitor::result_type
+            )
+    internal_apply_visitor(Visitor& visitor)
+    {
+        return internal_apply_visitor_impl(
+              which_, which(), visitor, storage_.address()
+            );
+    }
+
+    template <typename Visitor>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
+              typename Visitor::result_type
+            )
+    internal_apply_visitor(Visitor& visitor) const
+    {
+        return internal_apply_visitor_impl(
+              which_, which(), visitor, storage_.address()
+            );
+    }
+
+public: // visitation support
+
+    template <typename Visitor>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
+              typename Visitor::result_type
+            )
+    apply_visitor(Visitor& visitor)
+    {
+        detail::variant::invoke_visitor<Visitor> invoker(visitor);
+        return this->internal_apply_visitor(invoker);
+    }
+
+    template <typename Visitor>
+        BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(
+              typename Visitor::result_type
+            )
+    apply_visitor(Visitor& visitor) const
+    {
+        detail::variant::invoke_visitor<Visitor> invoker(visitor);
+        return this->internal_apply_visitor(invoker);
+    }
+
+}; // class variant
+
+///////////////////////////////////////////////////////////////////////////////
+// metafunction make_variant_over
+//
+// See docs and boost/variant/variant_fwd.hpp for more information.
+//
+template <typename Types>
+struct make_variant_over
+{
+private: // precondition assertions
+
+    BOOST_STATIC_ASSERT(( ::boost::mpl::is_sequence<Types>::value ));
+
+public: // metafunction result
+
+    typedef variant<
+          detail::variant::over_sequence< Types >
+        > type;
+
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// function template swap
+//
+// Swaps two variants of the same type (i.e., identical specification).
+//
+template < BOOST_VARIANT_ENUM_PARAMS(typename T) >
+inline void swap(
+      variant< BOOST_VARIANT_ENUM_PARAMS(T) >& lhs
+    , variant< BOOST_VARIANT_ENUM_PARAMS(T) >& rhs
+    )
+{
+    lhs.swap(rhs);
+}
+
+} // namespace boost
+
+// implementation additions
+
+#if !defined(BOOST_NO_IOSTREAM)
+#include "boost/variant/detail/variant_io.hpp"
+#endif // BOOST_NO_IOSTREAM
+
+#endif // BOOST_VARIANT_VARIANT_HPP
diff --git a/third_party/boost/boost/variant/variant_fwd.hpp b/third_party/boost/boost/variant/variant_fwd.hpp
new file mode 100644
index 0000000..381dc92
--- /dev/null
+++ b/third_party/boost/boost/variant/variant_fwd.hpp
@@ -0,0 +1,333 @@
+//-----------------------------------------------------------------------------
+// boost variant/variant_fwd.hpp header file
+// See http://www.boost.org for updates, documentation, and revision history.
+//-----------------------------------------------------------------------------
+//
+// Copyright (c) 2003 Eric Friedman, Itay Maman
+// Copyright (c) 2013 Antony Polukhin
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_VARIANT_VARIANT_FWD_HPP
+#define BOOST_VARIANT_VARIANT_FWD_HPP
+
+#include "boost/variant/detail/config.hpp"
+
+#include "boost/blank_fwd.hpp"
+#include "boost/mpl/arg.hpp"
+#include "boost/mpl/limits/arity.hpp"
+#include "boost/mpl/aux_/na.hpp"
+#include "boost/preprocessor/cat.hpp"
+#include "boost/preprocessor/enum.hpp"
+#include "boost/preprocessor/enum_params.hpp"
+#include "boost/preprocessor/enum_shifted_params.hpp"
+#include "boost/preprocessor/repeat.hpp"
+
+///////////////////////////////////////////////////////////////////////////////
+// macro BOOST_VARIANT_NO_REFERENCE_SUPPORT
+//
+// Defined if variant does not support references as bounded types.
+//
+#if defined(BOOST_VARIANT_AUX_BROKEN_CONSTRUCTOR_TEMPLATE_ORDERING) \
+ && !defined(BOOST_VARIANT_AUX_HAS_CONSTRUCTOR_TEMPLATE_ORDERING_SFINAE_WKND) \
+ && !defined(BOOST_VARIANT_NO_REFERENCE_SUPPORT)
+#   define BOOST_VARIANT_NO_REFERENCE_SUPPORT
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// macro BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT
+//
+// Defined if variant does not support make_variant_over (see below).
+//
+#if defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
+#   define BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// macro BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT
+//
+// Defined if make_recursive_variant cannot be supported as documented.
+//
+// Note: Currently, MPL lambda facility is used as workaround if defined, and
+// so only types declared w/ MPL lambda workarounds will work.
+//
+
+#include "boost/variant/detail/substitute_fwd.hpp"
+
+#if defined(BOOST_VARIANT_DETAIL_NO_SUBSTITUTE) \
+  && !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
+#   define BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////
+// macro BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
+//
+
+/*
+    GCC before 4.0 had no variadic tempaltes;
+    GCC 4.6 has incomplete implementation of variadic templates.
+
+    MSVC2013 has variadic templates, but they have issues.
+
+    NOTE: Clang compiler defines __GNUC__
+*/
+#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) \
+  || (!defined(__clang__) && defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7)) \
+  || (defined(_MSC_VER) && (_MSC_VER <= 1900)) \
+  || defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE) \
+  || defined (BOOST_VARIANT_NO_TYPE_SEQUENCE_SUPPORT)
+
+#ifndef BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
+#   define BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES
+#endif
+
+#endif
+
+#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
+#include <boost/preprocessor/seq/size.hpp>
+
+#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_class class)(
+#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_typename typename)(
+
+#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_class class...
+#define BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_typename typename...
+
+#define ARGS_VARIADER_1(x) x ## N...
+#define ARGS_VARIADER_2(x) BOOST_VARIANT_CLASS_OR_TYPENAME_TO_VARIADIC_ ## x ## N
+
+#define BOOST_VARIANT_MAKE_VARIADIC(sequence, x)        BOOST_VARIANT_MAKE_VARIADIC_I(BOOST_PP_SEQ_SIZE(sequence), x)
+#define BOOST_VARIANT_MAKE_VARIADIC_I(argscount, x)     BOOST_VARIANT_MAKE_VARIADIC_II(argscount, x)
+#define BOOST_VARIANT_MAKE_VARIADIC_II(argscount, orig) ARGS_VARIADER_ ## argscount(orig)
+
+///////////////////////////////////////////////////////////////////////////////
+// BOOST_VARIANT_ENUM_PARAMS and BOOST_VARIANT_ENUM_SHIFTED_PARAMS
+//
+// Convenience macro for enumeration of variant params.
+// When variadic templates are available expands:
+//      BOOST_VARIANT_ENUM_PARAMS(class Something)      => class Something0, class... SomethingN
+//      BOOST_VARIANT_ENUM_PARAMS(typename Something)   => typename Something0, typename... SomethingN
+//      BOOST_VARIANT_ENUM_PARAMS(Something)            => Something0, SomethingN...
+//      BOOST_VARIANT_ENUM_PARAMS(Something)            => Something0, SomethingN...
+//      BOOST_VARIANT_ENUM_SHIFTED_PARAMS(class Something)      => class... SomethingN
+//      BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename Something)   => typename... SomethingN
+//      BOOST_VARIANT_ENUM_SHIFTED_PARAMS(Something)            => SomethingN...
+//      BOOST_VARIANT_ENUM_SHIFTED_PARAMS(Something)            => SomethingN...
+//
+// Rationale: Cleaner, simpler code for clients of variant library. Minimal
+// code modifications to move from C++03 to C++11.
+//
+// With BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES defined
+// will be used BOOST_VARIANT_ENUM_PARAMS and BOOST_VARIANT_ENUM_SHIFTED_PARAMS from below `#else`
+//
+
+#define BOOST_VARIANT_ENUM_PARAMS(x) \
+    x ## 0, \
+    BOOST_VARIANT_MAKE_VARIADIC( (BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_ ## x), x) \
+    /**/
+
+#define BOOST_VARIANT_ENUM_SHIFTED_PARAMS(x) \
+    BOOST_VARIANT_MAKE_VARIADIC( (BOOST_VARIANT_CLASS_OR_TYPENAME_TO_SEQ_ ## x), x) \
+    /**/
+
+#else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
+
+///////////////////////////////////////////////////////////////////////////////
+// macro BOOST_VARIANT_LIMIT_TYPES
+//
+// Implementation-defined preprocessor symbol describing the actual
+// length of variant's pseudo-variadic template parameter list.
+//
+#include "boost/mpl/limits/list.hpp"
+#define BOOST_VARIANT_LIMIT_TYPES \
+    BOOST_MPL_LIMIT_LIST_SIZE
+
+///////////////////////////////////////////////////////////////////////////////
+// macro BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY
+//
+// Exposes maximum allowed arity of class templates with recursive_variant
+// arguments. That is,
+//   make_recursive_variant< ..., T<[1], recursive_variant_, ... [N]> >.
+//
+#include "boost/mpl/limits/arity.hpp"
+#define BOOST_VARIANT_RECURSIVE_VARIANT_MAX_ARITY \
+    BOOST_MPL_LIMIT_METAFUNCTION_ARITY
+
+///////////////////////////////////////////////////////////////////////////////
+// macro BOOST_VARIANT_ENUM_PARAMS
+//
+// Convenience macro for enumeration of BOOST_VARIANT_LIMIT_TYPES params.
+//
+// Rationale: Cleaner, simpler code for clients of variant library.
+//
+#define BOOST_VARIANT_ENUM_PARAMS( param )  \
+    BOOST_PP_ENUM_PARAMS(BOOST_VARIANT_LIMIT_TYPES, param)
+
+///////////////////////////////////////////////////////////////////////////////
+// macro BOOST_VARIANT_ENUM_SHIFTED_PARAMS
+//
+// Convenience macro for enumeration of BOOST_VARIANT_LIMIT_TYPES-1 params.
+//
+#define BOOST_VARIANT_ENUM_SHIFTED_PARAMS( param )  \
+    BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_VARIANT_LIMIT_TYPES, param)
+
+#endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround
+
+
+namespace boost {
+
+namespace detail { namespace variant {
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) class void_ and class template convert_void
+//
+// Provides the mechanism by which void(NN) types are converted to
+// mpl::void_ (and thus can be passed to mpl::list).
+//
+// Rationale: This is particularly needed for the using-declarations
+// workaround (below), but also to avoid associating mpl namespace with
+// variant in argument dependent lookups (which used to happen because of
+// defaulting of template parameters to mpl::void_).
+//
+
+struct void_;
+
+template <typename T>
+struct convert_void
+{
+    typedef T type;
+};
+
+template <>
+struct convert_void< void_ >
+{
+    typedef mpl::na type;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// (workaround) BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE
+//
+// Needed to work around compilers that don't support using-declaration
+// overloads. (See the variant::initializer workarounds below.)
+//
+
+#if defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
+// (detail) tags voidNN -- NN defined on [0, BOOST_VARIANT_LIMIT_TYPES)
+//
+// Defines void types that are each unique and specializations of
+// convert_void that yields mpl::na for each voidNN type.
+//
+
+#define BOOST_VARIANT_DETAIL_DEFINE_VOID_N(z,N,_)          \
+    struct BOOST_PP_CAT(void,N);                           \
+                                                           \
+    template <>                                            \
+    struct convert_void< BOOST_PP_CAT(void,N) >            \
+    {                                                      \
+        typedef mpl::na type;                              \
+    };                                                     \
+    /**/
+
+BOOST_PP_REPEAT(
+      BOOST_VARIANT_LIMIT_TYPES
+    , BOOST_VARIANT_DETAIL_DEFINE_VOID_N
+    , _
+    )
+
+#undef BOOST_VARIANT_DETAIL_DEFINE_VOID_N
+
+#endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround
+
+}} // namespace detail::variant
+
+#if !defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
+#   define BOOST_VARIANT_AUX_DECLARE_PARAMS BOOST_VARIANT_ENUM_PARAMS(typename T)
+#else // defined(BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES)
+
+///////////////////////////////////////////////////////////////////////////////
+// (detail) macro BOOST_VARIANT_AUX_DECLARE_PARAM
+//
+// Template parameter list for variant and recursive_variant declarations.
+//
+
+#if !defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
+
+#   define BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL(z, N, T) \
+    typename BOOST_PP_CAT(T,N) = detail::variant::void_ \
+    /**/
+
+#else // defined(BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE)
+
+#   define BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL(z, N, T) \
+    typename BOOST_PP_CAT(T,N) = BOOST_PP_CAT(detail::variant::void,N) \
+    /**/
+
+#endif // BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE workaround
+
+#define BOOST_VARIANT_AUX_DECLARE_PARAMS \
+    BOOST_PP_ENUM( \
+          BOOST_VARIANT_LIMIT_TYPES \
+        , BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL \
+        , T \
+        ) \
+    /**/
+
+#endif // BOOST_VARIANT_DO_NOT_USE_VARIADIC_TEMPLATES workaround
+
+///////////////////////////////////////////////////////////////////////////////
+// class template variant (concept inspired by Andrei Alexandrescu)
+//
+// Efficient, type-safe bounded discriminated union.
+//
+// Preconditions:
+//  - Each type must be unique.
+//  - No type may be const-qualified.
+//
+// Proper declaration form:
+//   variant<types>    (where types is a type-sequence)
+// or
+//   variant<T0,T1,...,Tn>  (where T0 is NOT a type-sequence)
+//
+template < BOOST_VARIANT_AUX_DECLARE_PARAMS > class variant;
+
+///////////////////////////////////////////////////////////////////////////////
+// metafunction make_recursive_variant
+//
+// Exposes a boost::variant with recursive_variant_ tags (below) substituted
+// with the variant itself (wrapped as needed with boost::recursive_wrapper).
+//
+template < BOOST_VARIANT_AUX_DECLARE_PARAMS > struct make_recursive_variant;
+
+#undef BOOST_VARIANT_AUX_DECLARE_PARAMS_IMPL
+#undef BOOST_VARIANT_AUX_DECLARE_PARAMS
+
+///////////////////////////////////////////////////////////////////////////////
+// type recursive_variant_
+//
+// Tag type indicates where recursive variant substitution should occur.
+//
+#if !defined(BOOST_VARIANT_NO_FULL_RECURSIVE_VARIANT_SUPPORT)
+    struct recursive_variant_ {};
+#else
+    typedef mpl::arg<1> recursive_variant_;
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// metafunction make_variant_over
+//
+// Result is a variant w/ types of the specified type sequence.
+//
+template <typename Types> struct make_variant_over;
+
+///////////////////////////////////////////////////////////////////////////////
+// metafunction make_recursive_variant_over
+//
+// Result is a recursive variant w/ types of the specified type sequence.
+//
+template <typename Types> struct make_recursive_variant_over;
+
+} // namespace boost
+
+#endif // BOOST_VARIANT_VARIANT_FWD_HPP
diff --git a/third_party/boost/boost/version.hpp b/third_party/boost/boost/version.hpp
new file mode 100644
index 0000000..fce02ec
--- /dev/null
+++ b/third_party/boost/boost/version.hpp
@@ -0,0 +1,32 @@
+//  Boost version.hpp configuration header file  ------------------------------//
+
+//  (C) Copyright John maddock 1999. Distributed under the Boost
+//  Software License, Version 1.0. (See accompanying file
+//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//  See http://www.boost.org/libs/config for documentation
+
+#ifndef BOOST_VERSION_HPP
+#define BOOST_VERSION_HPP
+
+//
+//  Caution: this is the only Boost header that is guaranteed
+//  to change with every Boost release. Including this header
+//  will cause a recompile every time a new Boost version is
+//  used.
+//
+//  BOOST_VERSION % 100 is the patch level
+//  BOOST_VERSION / 100 % 1000 is the minor version
+//  BOOST_VERSION / 100000 is the major version
+
+#define BOOST_VERSION 106000
+
+//
+//  BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION
+//  but as a *string* in the form "x_y[_z]" where x is the major version
+//  number, y is the minor version number, and z is the patch level if not 0.
+//  This is used by <config/auto_link.hpp> to select which library version to link to.
+
+#define BOOST_LIB_VERSION "1_60"
+
+#endif
diff --git a/third_party/boost/boost/visit_each.hpp b/third_party/boost/boost/visit_each.hpp
new file mode 100644
index 0000000..6463ca9
--- /dev/null
+++ b/third_party/boost/boost/visit_each.hpp
@@ -0,0 +1,27 @@
+// Boost.Signals library
+
+// Copyright Douglas Gregor 2001-2003. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// For more information, see http://www.boost.org/libs/signals
+
+#ifndef BOOST_VISIT_EACH_HPP
+#define BOOST_VISIT_EACH_HPP
+
+namespace boost {
+  template<typename Visitor, typename T>
+  inline void visit_each(Visitor& visitor, const T& t, long)
+  {
+    visitor(t);
+  }
+
+  template<typename Visitor, typename T>
+  inline void visit_each(Visitor& visitor, const T& t)
+  {
+    visit_each(visitor, t, 0);
+  }
+}
+
+#endif // BOOST_VISIT_EACH_HPP
diff --git a/third_party/boost/boost/weak_ptr.hpp b/third_party/boost/boost/weak_ptr.hpp
new file mode 100644
index 0000000..dd26869
--- /dev/null
+++ b/third_party/boost/boost/weak_ptr.hpp
@@ -0,0 +1,18 @@
+#ifndef BOOST_WEAK_PTR_HPP_INCLUDED
+#define BOOST_WEAK_PTR_HPP_INCLUDED
+
+//
+//  weak_ptr.hpp
+//
+//  Copyright (c) 2001, 2002, 2003 Peter Dimov
+//
+//  Distributed under the Boost Software License, Version 1.0.
+//  See accompanying file LICENSE_1_0.txt or copy at
+//  http://www.boost.org/LICENSE_1_0.txt
+//
+//  See http://www.boost.org/libs/smart_ptr/weak_ptr.htm for documentation.
+//
+
+#include <boost/smart_ptr/weak_ptr.hpp>
+
+#endif  // #ifndef BOOST_WEAK_PTR_HPP_INCLUDED
diff --git a/third_party/fgetln/LICENSE b/third_party/fgetln/LICENSE
new file mode 100644
index 0000000..5f85958
--- /dev/null
+++ b/third_party/fgetln/LICENSE
@@ -0,0 +1,26 @@
+MIT License
+===========
+
+Copyright (C) 2012 Robert Quattlebaum
+
+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/third_party/fgetln/README.google b/third_party/fgetln/README.google
new file mode 100644
index 0000000..c2da529
--- /dev/null
+++ b/third_party/fgetln/README.google
@@ -0,0 +1,12 @@
+URL: https://raw.githubusercontent.com/darconeous/smcp/47e863a8f91458ed01d133dc2a9b913defc56f6b/src/missing/fgetln.h
+Version: 47e863a8f91458ed01d133dc2a9b913defc56f6b
+License: MIT
+License File: LICENSE
+
+Description:
+Provides an implementation of the BSD `fgetln()` call for platforms
+where it is not present (like Linux).
+
+Local Modifications:
+LICENSE file has been created for compliance purposes. Not included
+in original distribution.
diff --git a/third_party/fgetln/fgetln.h b/third_party/fgetln/fgetln.h
new file mode 100644
index 0000000..7048eba
--- /dev/null
+++ b/third_party/fgetln/fgetln.h
@@ -0,0 +1,69 @@
+/*	@file fgetln.h
+**	@author Robert Quattlebaum <darco@deepdarc.com>
+**
+**	Copyright (C) 2012 Robert Quattlebaum
+**
+**	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.
+**
+**	-------------------------------------------------------------------
+**
+**	This is a simple implementation of the BSD function `fgetln()`,
+**	for use on operating systems which do not have a copy.
+**
+**	Man page URL: <http://www.openbsd.org/cgi-bin/man.cgi?query=fgetln>
+**
+**	NOTE: This implementation is *NOT* thread safe!
+*/
+
+#define	_WITH_GETLINE 1
+
+#include <stdio.h>
+
+#if !defined(HAVE_FGETLN)
+#define HAVE_FGETLN \
+	defined(__DARWIN_C_LEVEL) && \
+	(__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
+#endif
+
+#if !defined(fgetln) && !HAVE_FGETLN
+static char *
+fgetln_(
+    FILE *stream, size_t *len
+    )
+{
+	static char* linep = NULL;
+	static size_t linecap = 0;
+	ssize_t length = getline(&linep, &linecap, stream);
+
+	if (length == -1) {
+		free(linep);
+		linep = NULL;
+		linecap = 0;
+		length = 0;
+	}
+	if (len)
+		*len = length;
+	return linep;
+}
+#define fgetln  fgetln_
+#endif
diff --git a/third_party/openthread/CONTRIBUTING.md b/third_party/openthread/CONTRIBUTING.md
new file mode 100644
index 0000000..2a78c3b
--- /dev/null
+++ b/third_party/openthread/CONTRIBUTING.md
@@ -0,0 +1,37 @@
+Want to contribute? Great! First, read this page (including the small print at the end).
+
+### Before you contribute
+Before we can use your code, you must sign the
+[Google Individual Contributor License Agreement]
+(https://cla.developers.google.com/about/google-individual)
+(CLA), which you can do online. The CLA is necessary mainly because you own the
+copyright to your changes, even after your contribution becomes part of our
+codebase, so we need your permission to use and distribute your code. We also
+need to be sure of various other things—for instance that you'll tell us if you
+know that your code infringes on other people's patents. You don't have to sign
+the CLA until after you've submitted your code for review and a member has
+approved it, but you must do it before we can put your code into our codebase.
+Before you start working on a larger contribution, you should get in touch with
+us first through the issue tracker with your idea so that we can help out and
+possibly guide you. Coordinating up front makes it much easier to avoid
+frustration later on.
+
+### Code reviews
+All submissions, including submissions by project members, require review. We
+use Github pull requests for this purpose.
+
+### Code style
+Before submitting a pull request make sure to run:
+
+	make pretty
+	
+This will format the source code according to the OpenThread code style. This
+command requires the `astyle` tool. Please refer to your operating system 
+documentation to find information on how to install `astyle`.
+
+### The small print
+Contributions made by corporations are covered by a different agreement than
+the one above, the
+[Software Grant and Corporate Contributor License Agreement]
+(https://cla.developers.google.com/about/google-corporate).
+
diff --git a/third_party/openthread/LICENSE b/third_party/openthread/LICENSE
new file mode 100644
index 0000000..8417008
--- /dev/null
+++ b/third_party/openthread/LICENSE
@@ -0,0 +1,25 @@
+Copyright (c) 2016, The OpenThread Authors.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the copyright holder nor the
+   names of its contributors may be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/openthread/NOTICE b/third_party/openthread/NOTICE
new file mode 100644
index 0000000..6c1dad8
--- /dev/null
+++ b/third_party/openthread/NOTICE
@@ -0,0 +1,19 @@
+OpenThread is an open source implementation of the Thread 1.0.1 Final Specification.
+The Thread 1.0.1 Final Specification is promulgated by the Thread Group. The Thread
+Group is a non-profit organization formed for the purposes of defining one or
+more specifications, best practices, reference architectures, implementation
+guidelines and certification programs to promote the availability of compliant
+implementations of the Thread protocol. Information on becoming a Member, including
+information about the benefits thereof, can be found at http://threadgroup.org.
+
+OpenThread is not affiliated with or endorsed by the Thread Group. Implementation
+of this OpenThread code does not assure compliance with the Thread 1.0.1 Final
+Specification and does not convey the right to identify any final product as Thread
+certified. Members of the Thread Group may hold patents and other intellectual
+property rights relating to the Thread 1.0.1 Final Specification, ownership and
+licenses of which are subject to the Thread Group’s IP Policies, and not this license.
+
+The included copyright to the OpenThread code is subject to the license in the
+LICENSE file, and all other rights and licenses are expressly reserved.
+No warranty or assurance is made with respect to additional rights that may be
+required to implement this code.
diff --git a/third_party/openthread/README.google b/third_party/openthread/README.google
new file mode 100644
index 0000000..d515d6f
--- /dev/null
+++ b/third_party/openthread/README.google
@@ -0,0 +1,13 @@
+URL: https://github.com/openthread/openthread/tree/b1c19ed091b3faec71d4382a8edbec20b25086d9
+Version: b1c19ed091b3faec71d4382a8edbec20b25086d9
+License: BSD-3
+License File: LICENSE
+
+Description:
+OpenThread is an open-source implementation of the Thread networking
+protocol. With OpenThread, Nest is making the technology used in Nest
+products more broadly available to accelerate the development of
+products for the connected home.
+
+Local Modifications:
+Stripped all unused files.
diff --git a/third_party/openthread/README.md b/third_party/openthread/README.md
new file mode 100644
index 0000000..9052f86
--- /dev/null
+++ b/third_party/openthread/README.md
@@ -0,0 +1,126 @@
+[![OpenThread][ot-logo]][ot-repo]  
+[![Build Status][ot-travis-svg]][ot-travis]
+[![Build Status][ot-appveyor-svg]][ot-appveyor]
+[![Coverage Status][ot-codecov-svg]][ot-codecov]
+
+---
+
+OpenThread is an open-source implementation of the [Thread][thread]
+networking protocol. Nest has released OpenThread to make the technology
+used in Nest products more broadly available to developers to accelerate 
+the development of products for the connected home.
+
+The Thread specification defines an IPv6-based reliable, secure and
+low-power wireless device-to-device communication protocol for home
+applications. More information about Thread can be found on
+[threadgroup.org](http://threadgroup.org/).
+
+[thread]: http://threadgroup.org/technology/ourtechnology
+[ot-repo]: https://github.com/openthread/openthread
+[ot-logo]: doc/images/openthread_logo.png
+[ot-travis]: https://travis-ci.org/openthread/openthread
+[ot-travis-svg]: https://travis-ci.org/openthread/openthread.svg?branch=master
+[ot-appveyor]: https://ci.appveyor.com/project/jwhui/openthread
+[ot-appveyor-svg]: https://ci.appveyor.com/api/projects/status/r5qwyhn9p26nmfk3?svg=true
+[ot-codecov]: https://codecov.io/gh/openthread/openthread
+[ot-codecov-svg]: https://codecov.io/gh/openthread/openthread/branch/master/graph/badge.svg
+
+## Features ##
+
+ *  Highly portable: OS and platform agnostic with a radio
+    abstraction layer
+ *  Implements the End Device, Router, Leader and Border Router roles
+ *  Small memory footprint
+
+OpenThread implements all Thread networking layers including IPv6,
+6LoWPAN, IEEE 802.15.4 with MAC security, Mesh Link Establishment, and
+Mesh Routing.
+
+
+# Who is supporting OpenThread #
+
+![OpenThread Contributor Logos](doc/images/openthread_contrib.png)
+
+Nest, along with ARM, Atmel, a subsidiary of Microchip Technology,
+Dialog Semiconductor, Microsoft Corporation, Nordic Semiconductor,
+Qualcomm Technologies, Inc. (a subsidiary of Qualcomm Incorporated),
+and Texas Instruments Incorporated are contributing to the ongoing
+development of OpenThread.
+
+
+# Getting started #
+
+The easiest way to get started is to run the CLI example in
+`/examples/apps/cli`. See the
+[CLI example README](examples/apps/cli/README.md)
+for more details.
+
+
+## What's included ##
+
+In the repo you'll find the following directories and files:
+
+File/Folder   | Provides
+--------------|----------------------------------------------------------------
+`doc`         | Doxygen docs
+`examples`    | Sample applications demonstrating OpenThread
+`include`     | Public API header files
+`src`         | Core implementation of the Thread standard and related add-ons
+`tests`       | Unit and Thread conformance tests
+`third_party` | Third-party code used by OpenThread
+`tools`       | Helpful utilities related to the OpenThread project
+
+
+## Documentation ##
+
+The Doxygen reference docs are [hosted online][ot-docs] and generated
+as part of the build.
+
+[ot-docs]: http://openthread.github.io/openthread/
+
+
+# Getting help #
+
+Submit bugs and feature requests to [issue tracker][ot-issues]. Usage
+questions? Post your questions to [Stack Overflow][stackoverflow] using the
+[`openthread` tag][ot-tag]. We also use Google Groups for discussion
+and announcements:
+
+ *  [openthread-announce](https://groups.google.com/forum/#!forum/openthread-announce)
+    \- subscribe for release notes and new updates on OpenThread
+ *  [openthread-users](https://groups.google.com/forum/#!forum/openthread-users)
+    \- the best place for users to discuss OpenThread and interact with
+    the OpenThread team
+ *  [openthread-devel](https://groups.google.com/forum/#!forum/openthread-devel)
+    \- team members discuss the on-going development of OpenThread
+
+[ot-issues]: https://github.com/openthread/openthread/issues
+[stackoverflow]: http://stackoverflow.com/
+[ot-tag]: http://stackoverflow.com/questions/tagged/openthread
+
+
+# Versioning #
+
+OpenThread follows [the Semantic Versioning guidelines][semver] for
+release cycle transparency and to maintain backwards compatibility.
+OpenThread's versioning is independent of the Thread protocol
+specification version but will clearly indicate which version of the
+specification it currently supports.
+
+[semver]: http://semver.org/
+
+
+# Contributing #
+
+See the [`CONTRIBUTING.md`](CONTRIBUTING.md) file for more information.
+
+
+# License #
+
+OpenThread is released under the [BSD 3-Clause license](LICENSE). See
+the [`LICENSE`](LICENSE) file for more information.
+
+Please only use the OpenThread name and marks when accurately
+referencing this software distribution. Do not use the marks in
+a way that suggests you are endorsed by or otherwise affiliated with
+Nest, Google, or The Thread Group.
diff --git a/third_party/openthread/src/ncp/PROTOCOL.md b/third_party/openthread/src/ncp/PROTOCOL.md
new file mode 100644
index 0000000..f5aff68
--- /dev/null
+++ b/third_party/openthread/src/ncp/PROTOCOL.md
@@ -0,0 +1,7 @@
+Spinel NCP Protocol Documentation
+=================================
+
+This document has moved into the top level `doc` folder and renamed
+[`draft-spinel-protocol.txt`](../../doc/draft-spinel-protocol.txt)
+and [`draft-spinel-protocol.html`](../../doc/draft-spinel-protocol.html).
+
diff --git a/third_party/openthread/src/ncp/spinel.c b/third_party/openthread/src/ncp/spinel.c
new file mode 100644
index 0000000..0c1cb85
--- /dev/null
+++ b/third_party/openthread/src/ncp/spinel.c
@@ -0,0 +1,1576 @@
+/*
+ *    Copyright (c) 2016, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ *  -------------------------------------------------------------------
+ *
+ *  ## Unit Test ##
+ *
+ *  This file includes its own unit test. To compile the unit test,
+ *  simply compile this file with the macro SPINEL_SELF_TEST set to 1.
+ *  For example:
+ *
+ *      cc spinel.c -Wall -DSPINEL_SELF_TEST=1 -o spinel
+ *
+ *  -------------------------------------------------------------------
+ */
+
+// ----------------------------------------------------------------------------
+// MARK: -
+// MARK: Headers
+
+#include "spinel.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+// IAR's errno.h apparently doesn't define EOVERFLOW.
+#ifndef EOVERFLOW
+// There is no real good choice for what to set
+// errno to in this case, so we just pick the
+// value '1' somewhat arbitrarily.
+#define EOVERFLOW 1
+#endif
+
+// IAR's errno.h apparently doesn't define EINVAL.
+#ifndef EINVAL
+// There is no real good choice for what to set
+// errno to in this case, so we just pick the
+// value '1' somewhat arbitrarily.
+#define EINVAL 1
+#endif
+
+#ifdef _KERNEL_MODE
+#define va_copy(destination, source) ((destination) = (source))
+#undef errno
+#define assert_printf(fmt, ...)
+#endif
+
+#if defined(errno) && SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
+#error "SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR is set but errno is already defined."
+#endif
+
+// Work-around for platforms that don't implement the `errno` variable.
+#if !defined(errno) && SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
+static int spinel_errno_workaround_;
+#define errno spinel_errno_workaround_
+#endif // SPINEL_PLATFORM_DOESNT_IMPLEMENT_ERRNO_VAR
+
+#ifndef assert_printf
+#if SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF
+#define assert_printf(fmt, ...) \
+    printf(__FILE__ ":%d: " fmt "\n", __LINE__, __VA_ARGS__)
+#else // if SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF
+#define assert_printf(fmt, ...) \
+    fprintf(stderr, __FILE__ ":%d: " fmt "\n", __LINE__, __VA_ARGS__)
+#endif // else SPINEL_PLATFORM_DOESNT_IMPLEMENT_FPRINTF
+#endif
+
+#if !HAVE_STRNLEN
+// Provide a working strnlen if the platform doesn't have one.
+static size_t spinel_strnlen_(const char *s, size_t maxlen)
+{
+    size_t ret;
+    for (ret = 0; (ret < maxlen) && (s[ret] != 0); ret++)
+    {
+        // Empty loop.
+    }
+    return ret;
+}
+#define strnlen spinel_strnlen_
+#endif
+
+#ifndef require_action
+#if SPINEL_PLATFORM_SHOULD_LOG_ASSERTS
+#define require_action(c, l, a) \
+    do { if (!(c)) { \
+        assert_printf("Requirement Failed (%s)", # c); \
+        a; \
+        goto l; \
+    } } while (0)
+#else // if DEBUG
+#define require_action(c, l, a) \
+    do { if (!(c)) { \
+        a; \
+        goto l; \
+    } } while (0)
+#endif // else DEBUG
+#endif // ifndef require_action
+
+#ifndef require
+#define require(c, l)   require_action(c, l, {})
+#endif
+
+
+typedef struct {
+    va_list obj;
+} va_list_obj;
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+spinel_ssize_t
+spinel_packed_uint_decode(const uint8_t *bytes, spinel_size_t len, unsigned int *value_ptr)
+{
+    spinel_ssize_t ret = 0;
+    unsigned int value = 0;
+
+    int i = 0;
+
+    do
+    {
+        if (len < sizeof(uint8_t))
+        {
+            ret = -1;
+            break;
+        }
+
+        value |= (unsigned int)((bytes[0] & 0x7F) << i);
+        i += 7;
+        ret += sizeof(uint8_t);
+        bytes += sizeof(uint8_t);
+        len -= sizeof(uint8_t);
+    }
+    while ((bytes[-1] & 0x80) == 0x80);
+
+    if ((ret > 0) && (value_ptr != NULL))
+    {
+        *value_ptr = value;
+    }
+
+    return ret;
+}
+
+spinel_ssize_t
+spinel_packed_uint_size(unsigned int value)
+{
+    spinel_ssize_t ret;
+
+    if (value < (1 << 7))
+    {
+        ret = 1;
+    }
+    else if (value < (1 << 14))
+    {
+        ret = 2;
+    }
+    else if (value < (1 << 21))
+    {
+        ret = 3;
+    }
+    else if (value < (1 << 28))
+    {
+        ret = 4;
+    }
+    else
+    {
+        ret = 5;
+    }
+
+    return ret;
+}
+
+spinel_ssize_t
+spinel_packed_uint_encode(uint8_t *bytes, spinel_size_t len, unsigned int value)
+{
+    const spinel_ssize_t encoded_size = spinel_packed_uint_size(value);
+
+    if ((spinel_ssize_t)len >= encoded_size)
+    {
+        spinel_ssize_t i;
+
+        for (i = 0; i != encoded_size - 1; ++i)
+        {
+            *bytes++ = (value & 0x7F) | 0x80;
+            value = (value >> 7);
+        }
+
+        *bytes++ = (value & 0x7F);
+    }
+
+    return encoded_size;
+}
+
+const char *
+spinel_next_packed_datatype(const char *pack_format)
+{
+    int depth = 0;
+
+    do
+    {
+        switch (*++pack_format)
+        {
+        case '(':
+            depth++;
+            break;
+
+        case ')':
+            depth--;
+
+            if (depth == 0)
+            {
+                pack_format++;
+            }
+
+            break;
+        }
+    }
+    while ((depth > 0) && *pack_format != 0);
+
+    return pack_format;
+}
+
+static spinel_ssize_t
+spinel_datatype_vunpack_(const uint8_t *data_ptr, spinel_size_t data_len, const char *pack_format, va_list_obj *args)
+{
+    spinel_ssize_t ret = 0;
+
+    for (; *pack_format != 0; pack_format = spinel_next_packed_datatype(pack_format))
+    {
+        if (*pack_format == ')')
+        {
+            // Don't go past the end of a struct.
+            break;
+        }
+
+        switch ((spinel_datatype_t)pack_format[0])
+        {
+        case SPINEL_DATATYPE_BOOL_C:
+        {
+            bool *arg_ptr = va_arg(args->obj, bool *);
+            require_action(data_len >= sizeof(uint8_t), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (arg_ptr)
+            {
+                *arg_ptr = data_ptr[0];
+            }
+
+            ret += sizeof(uint8_t);
+            data_ptr += sizeof(uint8_t);
+            data_len -= sizeof(uint8_t);
+            break;
+        }
+
+        case SPINEL_DATATYPE_INT8_C:
+        case SPINEL_DATATYPE_UINT8_C:
+        {
+            uint8_t *arg_ptr = va_arg(args->obj, uint8_t *);
+            require_action(data_len >= sizeof(uint8_t), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (arg_ptr)
+            {
+                *arg_ptr = data_ptr[0];
+            }
+
+            ret += sizeof(uint8_t);
+            data_ptr += sizeof(uint8_t);
+            data_len -= sizeof(uint8_t);
+            break;
+        }
+
+        case SPINEL_DATATYPE_INT16_C:
+        case SPINEL_DATATYPE_UINT16_C:
+        {
+            uint16_t *arg_ptr = va_arg(args->obj, uint16_t *);
+            require_action(data_len >= sizeof(uint16_t), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (arg_ptr)
+            {
+                *arg_ptr = (uint16_t)((data_ptr[1] << 8) | data_ptr[0]);
+            }
+
+            ret += sizeof(uint16_t);
+            data_ptr += sizeof(uint16_t);
+            data_len -= sizeof(uint16_t);
+            break;
+        }
+
+        case SPINEL_DATATYPE_INT32_C:
+        case SPINEL_DATATYPE_UINT32_C:
+        {
+            uint32_t *arg_ptr = va_arg(args->obj, uint32_t *);
+            require_action(data_len >= sizeof(uint32_t), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (arg_ptr)
+            {
+                *arg_ptr = (uint32_t)((data_ptr[3] << 24) | (data_ptr[2] << 16) | (data_ptr[1] << 8) | data_ptr[0]);
+            }
+
+            ret += sizeof(uint32_t);
+            data_ptr += sizeof(uint32_t);
+            data_len -= sizeof(uint32_t);
+            break;
+        }
+
+        case SPINEL_DATATYPE_IPv6ADDR_C:
+        {
+            spinel_ipv6addr_t **arg_ptr = va_arg(args->obj, spinel_ipv6addr_t **);
+            require_action(data_len >= sizeof(spinel_ipv6addr_t), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (arg_ptr)
+            {
+                *arg_ptr = (spinel_ipv6addr_t *)data_ptr;
+            }
+
+            ret += sizeof(spinel_ipv6addr_t);
+            data_ptr += sizeof(spinel_ipv6addr_t);
+            data_len -= sizeof(spinel_ipv6addr_t);
+            break;
+        }
+
+        case SPINEL_DATATYPE_EUI64_C:
+        {
+            spinel_eui64_t **arg_ptr = va_arg(args->obj, spinel_eui64_t **);
+            require_action(data_len >= sizeof(spinel_eui64_t), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (arg_ptr)
+            {
+                *arg_ptr = (spinel_eui64_t *)data_ptr;
+            }
+
+            ret += sizeof(spinel_eui64_t);
+            data_ptr += sizeof(spinel_eui64_t);
+            data_len -= sizeof(spinel_eui64_t);
+            break;
+        }
+
+        case SPINEL_DATATYPE_EUI48_C:
+        {
+            spinel_eui48_t **arg_ptr = va_arg(args->obj, spinel_eui48_t **);
+            require_action(data_len >= sizeof(spinel_eui48_t), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (arg_ptr)
+            {
+                *arg_ptr = (spinel_eui48_t *)data_ptr;
+            }
+
+            ret += sizeof(spinel_eui48_t);
+            data_ptr += sizeof(spinel_eui48_t);
+            data_len -= sizeof(spinel_eui48_t);
+            break;
+        }
+
+        case SPINEL_DATATYPE_UINT_PACKED_C:
+        {
+            unsigned int *arg_ptr = va_arg(args->obj, unsigned int *);
+            spinel_ssize_t pui_len = spinel_packed_uint_decode(data_ptr, data_len, arg_ptr);
+
+            require(pui_len > 0, bail);
+
+            require(pui_len <= (spinel_ssize_t)data_len, bail);
+
+            ret += pui_len;
+            data_ptr += pui_len;
+            data_len -= (spinel_size_t)pui_len;
+            break;
+        }
+
+        case SPINEL_DATATYPE_UTF8_C:
+        {
+            const char **arg_ptr = va_arg(args->obj, const char **);
+            size_t len = strnlen((const char *)data_ptr, data_len) + 1;
+
+            require_action((len <= data_len) || (data_ptr[data_len - 1] != 0), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (arg_ptr)
+            {
+                *arg_ptr = (const char *)data_ptr;
+            }
+
+            ret += (spinel_size_t)len;
+            data_ptr += len;
+            data_len -= (spinel_size_t)len;
+            break;
+        }
+
+        case SPINEL_DATATYPE_DATA_C:
+        {
+            spinel_ssize_t pui_len = 0;
+            uint16_t block_len = 0;
+            const uint8_t *block_ptr = data_ptr;
+            const uint8_t **block_ptr_ptr =  va_arg(args->obj, const uint8_t **);
+            unsigned int *block_len_ptr = va_arg(args->obj, unsigned int *);
+            char nextformat = *spinel_next_packed_datatype(pack_format);
+
+            if ((nextformat != 0) && (nextformat != ')'))
+            {
+                pui_len = spinel_datatype_unpack(data_ptr, data_len, SPINEL_DATATYPE_UINT16_S, &block_len);
+                //pui_len = spinel_packed_uint_decode(data_ptr, data_len, &block_len);
+                block_ptr += pui_len;
+
+                require(pui_len > 0, bail);
+                require(block_len < SPINEL_FRAME_MAX_SIZE, bail);
+            }
+            else
+            {
+                block_len = (uint16_t)data_len;
+                pui_len = 0;
+            }
+
+            require_action((spinel_ssize_t)data_len >= (block_len + pui_len), bail, (ret = -1, errno = EOVERFLOW));
+
+            if (NULL != block_ptr_ptr)
+            {
+                *block_ptr_ptr = block_ptr;
+            }
+
+            if (NULL != block_len_ptr)
+            {
+                *block_len_ptr = block_len;
+            }
+
+            block_len += (uint16_t)pui_len;
+            ret += block_len;
+            data_ptr += block_len;
+            data_len -= block_len;
+            break;
+        }
+
+        case SPINEL_DATATYPE_STRUCT_C:
+        {
+            spinel_ssize_t pui_len = 0;
+            uint16_t block_len = 0;
+            spinel_ssize_t actual_len = 0;
+            const uint8_t *block_ptr = data_ptr;
+            char nextformat = *spinel_next_packed_datatype(pack_format);
+
+            if ((nextformat != 0) && (nextformat != ')'))
+            {
+                pui_len = spinel_datatype_unpack(data_ptr, data_len, SPINEL_DATATYPE_UINT16_S, &block_len);
+                block_ptr += pui_len;
+
+                require(pui_len > 0, bail);
+                require(block_len < SPINEL_FRAME_MAX_SIZE, bail);
+            }
+            else
+            {
+                block_len = (uint16_t)data_len;
+                pui_len = 0;
+            }
+
+            require_action((spinel_ssize_t)data_len >= (block_len + pui_len), bail, (ret = -1, errno = EOVERFLOW));
+
+            actual_len = spinel_datatype_vunpack_(block_ptr, block_len, pack_format + 2, args);
+
+            require_action(actual_len > -1, bail, (ret = -1, errno = EOVERFLOW));
+
+            if (pui_len)
+            {
+                block_len += (uint16_t)pui_len;
+            }
+            else
+            {
+                block_len = (uint16_t)actual_len;
+            }
+
+            ret += block_len;
+            data_ptr += block_len;
+            data_len -= block_len;
+            break;
+        }
+
+        case '.':
+            // Skip.
+            break;
+
+        case SPINEL_DATATYPE_ARRAY_C:
+        default:
+            // Unsupported Type!
+            ret = -1;
+            errno = EINVAL;
+            goto bail;
+        }
+    }
+
+    return ret;
+
+bail:
+    return ret;
+}
+
+spinel_ssize_t
+spinel_datatype_unpack(const uint8_t *data_ptr, spinel_size_t data_len, const char *pack_format, ...)
+{
+    spinel_ssize_t ret;
+    va_list_obj args;
+    va_start(args.obj, pack_format);
+
+    ret = spinel_datatype_vunpack_(data_ptr, data_len, pack_format, &args);
+
+    va_end(args.obj);
+    return ret;
+}
+
+
+spinel_ssize_t
+spinel_datatype_vunpack(const uint8_t *data_ptr, spinel_size_t data_len, const char *pack_format, va_list args)
+{
+    spinel_ssize_t ret;
+    va_list_obj args_obj;
+    va_copy(args_obj.obj, args);
+
+    ret = spinel_datatype_vunpack_(data_ptr, data_len, pack_format, &args_obj);
+
+    va_end(args_obj.obj);
+    return ret;
+}
+
+static spinel_ssize_t
+spinel_datatype_vpack_(uint8_t *data_ptr, spinel_size_t data_len_max, const char *pack_format, va_list_obj *args)
+{
+    spinel_ssize_t ret = 0;
+
+    for (; *pack_format != 0; pack_format = spinel_next_packed_datatype(pack_format))
+    {
+        if (*pack_format == ')')
+        {
+            // Don't go past the end of a struct.
+            break;
+        }
+
+        switch ((spinel_datatype_t)*pack_format)
+        {
+        case SPINEL_DATATYPE_BOOL_C:
+        {
+            bool arg = (bool)va_arg(args->obj, int);
+            ret += sizeof(uint8_t);
+
+            if (data_len_max >= sizeof(uint8_t))
+            {
+                data_ptr[0] = (arg != false);
+                data_ptr += sizeof(uint8_t);
+                data_len_max -= sizeof(uint8_t);
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_INT8_C:
+        case SPINEL_DATATYPE_UINT8_C:
+        {
+            uint8_t arg = (uint8_t)va_arg(args->obj, int);
+            ret += sizeof(uint8_t);
+
+            if (data_len_max >= sizeof(uint8_t))
+            {
+                data_ptr[0] = arg;
+                data_ptr += sizeof(uint8_t);
+                data_len_max -= sizeof(uint8_t);
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_INT16_C:
+        case SPINEL_DATATYPE_UINT16_C:
+        {
+            uint16_t arg = (uint16_t)va_arg(args->obj, int);
+            ret += sizeof(uint16_t);
+
+            if (data_len_max >= sizeof(uint16_t))
+            {
+                data_ptr[1] = (arg >> 8) & 0xff;
+                data_ptr[0] = (arg >> 0) & 0xff;
+                data_ptr += sizeof(uint16_t);
+                data_len_max -= sizeof(uint16_t);
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_INT32_C:
+        case SPINEL_DATATYPE_UINT32_C:
+        {
+            uint32_t arg = (uint32_t)va_arg(args->obj, int);
+            ret += sizeof(uint32_t);
+
+            if (data_len_max >= sizeof(uint32_t))
+            {
+                data_ptr[3] = (arg >> 24) & 0xff;
+                data_ptr[2] = (arg >> 16) & 0xff;
+                data_ptr[1] = (arg >> 8) & 0xff;
+                data_ptr[0] = (arg >> 0) & 0xff;
+                data_ptr += sizeof(uint32_t);
+                data_len_max -= sizeof(uint32_t);
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_IPv6ADDR_C:
+        {
+            spinel_ipv6addr_t *arg = va_arg(args->obj, spinel_ipv6addr_t *);
+            ret += sizeof(spinel_ipv6addr_t);
+
+            if (data_len_max >= sizeof(spinel_ipv6addr_t))
+            {
+                *(spinel_ipv6addr_t *)data_ptr = *arg;
+                data_ptr += sizeof(spinel_ipv6addr_t);
+                data_len_max -= sizeof(spinel_ipv6addr_t);
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_EUI48_C:
+        {
+            spinel_eui48_t *arg = va_arg(args->obj, spinel_eui48_t *);
+            ret += sizeof(spinel_eui48_t);
+
+            if (data_len_max >= sizeof(spinel_eui48_t))
+            {
+                *(spinel_eui48_t *)data_ptr = *arg;
+                data_ptr += sizeof(spinel_eui48_t);
+                data_len_max -= sizeof(spinel_eui48_t);
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_EUI64_C:
+        {
+            spinel_eui64_t *arg = va_arg(args->obj, spinel_eui64_t *);
+            ret += sizeof(spinel_eui64_t);
+
+            if (data_len_max >= sizeof(spinel_eui64_t))
+            {
+                *(spinel_eui64_t *)data_ptr = *arg;
+                data_ptr += sizeof(spinel_eui64_t);
+                data_len_max -= sizeof(spinel_eui64_t);
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_UINT_PACKED_C:
+        {
+            uint32_t arg = va_arg(args->obj, uint32_t);
+            spinel_ssize_t encoded_size = spinel_packed_uint_encode(data_ptr, data_len_max, arg);
+            ret += encoded_size;
+
+            if ((spinel_ssize_t)data_len_max >= encoded_size)
+            {
+                data_ptr += encoded_size;
+                data_len_max -= (spinel_size_t)encoded_size;
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_UTF8_C:
+        {
+            const char *string_arg = va_arg(args->obj, const char *);
+            size_t string_arg_len = 0;
+
+            if (string_arg)
+            {
+                string_arg_len = strlen(string_arg) + 1;
+            }
+            else
+            {
+                string_arg = "";
+                string_arg_len = 1;
+            }
+
+            ret += (spinel_size_t)string_arg_len;
+
+            if (data_len_max >= string_arg_len)
+            {
+                memcpy(data_ptr, string_arg, string_arg_len);
+
+                data_ptr += string_arg_len;
+                data_len_max -= (spinel_size_t)string_arg_len;
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_DATA_C:
+        {
+            const uint8_t *arg = va_arg(args->obj, const uint8_t *);
+            uint32_t data_size_arg = va_arg(args->obj, uint32_t);
+            spinel_ssize_t size_len = 0;
+            char nextformat = *spinel_next_packed_datatype(pack_format);
+
+            if (nextformat != 0 && nextformat != ')')
+            {
+                size_len = spinel_datatype_pack(data_ptr, data_len_max, SPINEL_DATATYPE_UINT16_S, data_size_arg);
+                require_action(size_len > 0, bail, {ret = -1; errno = EINVAL;});
+            }
+
+            ret += (spinel_size_t)size_len + data_size_arg;
+
+            if (data_len_max >= (spinel_size_t)size_len + data_size_arg)
+            {
+                data_ptr += size_len;
+                data_len_max -= (spinel_size_t)size_len;
+
+                memcpy(data_ptr, arg, data_size_arg);
+
+                data_ptr += data_size_arg;
+                data_len_max -= data_size_arg;
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case SPINEL_DATATYPE_STRUCT_C:
+        {
+            spinel_ssize_t struct_len = 0;
+            spinel_ssize_t size_len = 0;
+            char nextformat = *spinel_next_packed_datatype(pack_format);
+
+            require_action(pack_format[1] == '(', bail, {ret = -1; errno = EINVAL;});
+
+            // First we figure out the size of the struct
+            {
+                va_list_obj subargs;
+                va_copy(subargs.obj, args->obj);
+                struct_len = spinel_datatype_vpack_(NULL, 0, pack_format + 2, &subargs);
+                va_end(subargs.obj);
+            }
+
+            if (nextformat != 0 && nextformat != ')')
+            {
+                size_len = spinel_datatype_pack(data_ptr, data_len_max, SPINEL_DATATYPE_UINT16_S, struct_len);
+                require_action(size_len > 0, bail, {ret = -1; errno = EINVAL;});
+            }
+
+            ret += size_len + struct_len;
+
+            if (struct_len + size_len <= (spinel_ssize_t)data_len_max)
+            {
+                data_ptr += size_len;
+                data_len_max -= (spinel_size_t)size_len;
+
+                struct_len = spinel_datatype_vpack_(data_ptr, data_len_max, pack_format + 2, args);
+
+                data_ptr += struct_len;
+                data_len_max -= (spinel_size_t)struct_len;
+            }
+            else
+            {
+                data_len_max = 0;
+            }
+
+            break;
+        }
+
+        case '.':
+            // Skip.
+            break;
+
+        default:
+            // Unsupported Type!
+            ret = -1;
+            errno = EINVAL;
+            goto bail;
+
+        }
+    }
+
+bail:
+    return ret;
+}
+
+spinel_ssize_t
+spinel_datatype_pack(uint8_t *data_ptr, spinel_size_t data_len_max, const char *pack_format, ...)
+{
+    int ret;
+    va_list_obj args;
+    va_start(args.obj, pack_format);
+
+    ret = spinel_datatype_vpack_(data_ptr, data_len_max, pack_format, &args);
+
+    va_end(args.obj);
+    return ret;
+}
+
+
+spinel_ssize_t
+spinel_datatype_vpack(uint8_t *data_ptr, spinel_size_t data_len_max, const char *pack_format, va_list args)
+{
+    int ret;
+    va_list_obj args_obj;
+    va_copy(args_obj.obj, args);
+
+    ret = spinel_datatype_vpack_(data_ptr, data_len_max, pack_format, &args_obj);
+
+    va_end(args_obj.obj);
+    return ret;
+}
+
+
+// ----------------------------------------------------------------------------
+// MARK: -
+
+// **** LCOV_EXCL_START ****
+
+const char *
+spinel_prop_key_to_cstr(spinel_prop_key_t prop_key)
+{
+    const char *ret = "UNKNOWN";
+
+    switch (prop_key)
+    {
+    case SPINEL_PROP_LAST_STATUS:
+        ret = "PROP_LAST_STATUS";
+        break;
+
+    case SPINEL_PROP_PROTOCOL_VERSION:
+        ret = "PROP_PROTOCOL_VERSION";
+        break;
+
+    case SPINEL_PROP_INTERFACE_TYPE:
+        ret = "PROP_INTERFACE_TYPE";
+        break;
+
+    case SPINEL_PROP_VENDOR_ID:
+        ret = "PROP_VENDOR_ID";
+        break;
+
+    case SPINEL_PROP_CAPS:
+        ret = "PROP_CAPS";
+        break;
+
+    case SPINEL_PROP_NCP_VERSION:
+        ret = "PROP_NCP_VERSION";
+        break;
+
+    case SPINEL_PROP_INTERFACE_COUNT:
+        ret = "PROP_INTERFACE_COUNT";
+        break;
+
+    case SPINEL_PROP_POWER_STATE:
+        ret = "PROP_POWER_STATE";
+        break;
+
+    case SPINEL_PROP_HWADDR:
+        ret = "PROP_HWADDR";
+        break;
+
+    case SPINEL_PROP_LOCK:
+        ret = "PROP_LOCK";
+        break;
+
+    case SPINEL_PROP_HBO_MEM_MAX:
+        ret = "PROP_HBO_MEM_MAX";
+        break;
+
+    case SPINEL_PROP_HBO_BLOCK_MAX:
+        ret = "PROP_HBO_BLOCK_MAX";
+        break;
+
+    case SPINEL_PROP_STREAM_DEBUG:
+        ret = "PROP_STREAM_DEBUG";
+        break;
+
+    case SPINEL_PROP_STREAM_RAW:
+        ret = "PROP_STREAM_RAW";
+        break;
+
+    case SPINEL_PROP_STREAM_NET:
+        ret = "PROP_STREAM_NET";
+        break;
+
+    case SPINEL_PROP_STREAM_NET_INSECURE:
+        ret = "PROP_STREAM_NET_INSECURE";
+        break;
+
+    case SPINEL_PROP_PHY_ENABLED:
+        ret = "PROP_PHY_ENABLED";
+        break;
+
+    case SPINEL_PROP_PHY_CHAN:
+        ret = "PROP_PHY_CHAN";
+        break;
+
+    case SPINEL_PROP_PHY_CHAN_SUPPORTED:
+        ret = "PROP_PHY_CHAN_SUPPORTED";
+        break;
+
+    case SPINEL_PROP_PHY_FREQ:
+        ret = "PROP_PHY_FREQ";
+        break;
+
+    case SPINEL_PROP_PHY_CCA_THRESHOLD:
+        ret = "PROP_PHY_CCA_THRESHOLD";
+        break;
+
+    case SPINEL_PROP_PHY_TX_POWER:
+        ret = "PROP_PHY_TX_POWER";
+        break;
+
+    case SPINEL_PROP_PHY_RSSI:
+        ret = "PROP_PHY_RSSI";
+        break;
+
+    case SPINEL_PROP_MAC_RAW_STREAM_ENABLED:
+        ret = "PROP_MAC_RAW_STREAM_ENABLED";
+        break;
+
+    case SPINEL_PROP_MAC_PROMISCUOUS_MODE:
+        ret = "PROP_MAC_PROMISCUOUS_MODE";
+        break;
+
+    case SPINEL_PROP_MAC_SCAN_STATE:
+        ret = "PROP_MAC_SCAN_STATE";
+        break;
+
+    case SPINEL_PROP_MAC_SCAN_MASK:
+        ret = "PROP_MAC_SCAN_MASK";
+        break;
+
+    case SPINEL_PROP_MAC_SCAN_BEACON:
+        ret = "PROP_MAC_SCAN_BEACON";
+        break;
+
+    case SPINEL_PROP_MAC_ENERGY_SCAN_RESULT:
+        ret = "PROP_MAC_SCAN_ENERGY_SCAN_RESULT";
+        break;
+
+    case SPINEL_PROP_MAC_SCAN_PERIOD:
+        ret = "PROP_MAC_SCAN_PERIOD";
+        break;
+
+    case SPINEL_PROP_MAC_15_4_LADDR:
+        ret = "PROP_MAC_15_4_LADDR";
+        break;
+
+    case SPINEL_PROP_MAC_15_4_SADDR:
+        ret = "PROP_MAC_15_4_SADDR";
+        break;
+
+    case SPINEL_PROP_MAC_15_4_PANID:
+        ret = "PROP_MAC_15_4_PANID";
+        break;
+
+    case SPINEL_PROP_NET_SAVED:
+        ret = "PROP_NET_SAVED";
+        break;
+
+    case SPINEL_PROP_NET_IF_UP:
+        ret = "PROP_NET_IF_UP";
+        break;
+
+    case SPINEL_PROP_NET_STACK_UP:
+        ret = "PROP_NET_STACK_UP";
+        break;
+
+    case SPINEL_PROP_NET_ROLE:
+        ret = "PROP_NET_ROLE";
+        break;
+
+    case SPINEL_PROP_NET_NETWORK_NAME:
+        ret = "PROP_NET_NETWORK_NAME";
+        break;
+
+    case SPINEL_PROP_NET_XPANID:
+        ret = "PROP_NET_XPANID";
+        break;
+
+    case SPINEL_PROP_NET_MASTER_KEY:
+        ret = "PROP_NET_MASTER_KEY";
+        break;
+
+    case SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER:
+        ret = "PROP_NET_KEY_SEQUENCE_COUNTER";
+        break;
+
+    case SPINEL_PROP_NET_PARTITION_ID:
+        ret = "PROP_NET_PARTITION_ID";
+        break;
+
+    case SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME:
+        ret = "PROP_NET_KEY_SWITCH_GUARDTIME";
+        break;
+
+    case SPINEL_PROP_THREAD_LEADER_ADDR:
+        ret = "PROP_THREAD_LEADER_ADDR";
+        break;
+
+    case SPINEL_PROP_THREAD_LEADER_RID:
+        ret = "PROP_THREAD_LEADER_RID";
+        break;
+
+    case SPINEL_PROP_THREAD_LEADER_WEIGHT:
+        ret = "PROP_THREAD_LEADER_WEIGHT";
+        break;
+
+    case SPINEL_PROP_THREAD_LOCAL_LEADER_WEIGHT:
+        ret = "PROP_THREAD_LOCAL_LEADER_WEIGHT";
+        break;
+
+    case SPINEL_PROP_THREAD_NETWORK_DATA_VERSION:
+        ret = "PROP_THREAD_NETWORK_DATA_VERSION";
+        break;
+
+    case SPINEL_PROP_THREAD_STABLE_NETWORK_DATA_VERSION:
+        ret = "PROP_THREAD_STABLE_NETWORK_DATA_VERSION";
+        break;
+
+    case SPINEL_PROP_THREAD_NETWORK_DATA:
+        ret = "PROP_THREAD_NETWORK_DATA";
+        break;
+
+    case SPINEL_PROP_THREAD_CHILD_TABLE:
+        ret = "PROP_THREAD_CHILD_TABLE";
+        break;
+
+    case SPINEL_PROP_IPV6_LL_ADDR:
+        ret = "PROP_IPV6_LL_ADDR";
+        break;
+
+    case SPINEL_PROP_IPV6_ML_ADDR:
+        ret = "PROP_IPV6_ML_ADDR";
+        break;
+
+    case SPINEL_PROP_IPV6_ML_PREFIX:
+        ret = "PROP_IPV6_ML_PREFIX";
+        break;
+
+    case SPINEL_PROP_IPV6_ADDRESS_TABLE:
+        ret = "PROP_IPV6_ADDRESS_TABLE";
+        break;
+
+    case SPINEL_PROP_IPV6_ROUTE_TABLE:
+        ret = "PROP_IPV6_ROUTE_TABLE";
+        break;
+
+    case SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD:
+        ret = "SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD";
+        break;
+
+    case SPINEL_PROP_THREAD_PARENT:
+        ret = "SPINEL_PROP_THREAD_PARENT";
+        break;
+
+    case SPINEL_PROP_THREAD_STABLE_NETWORK_DATA:
+        ret = "SPINEL_PROP_THREAD_STABLE_NETWORK_DATA";
+        break;
+
+    case SPINEL_PROP_THREAD_LEADER_NETWORK_DATA:
+        ret = "SPINEL_PROP_THREAD_LEADER_NETWORK_DATA";
+        break;
+
+    case SPINEL_PROP_THREAD_STABLE_LEADER_NETWORK_DATA:
+        ret = "SPINEL_PROP_THREAD_STABLE_LEADER_NETWORK_DATA";
+        break;
+
+    case SPINEL_PROP_THREAD_ON_MESH_NETS:
+        ret = "SPINEL_PROP_THREAD_ON_MESH_NETS";
+        break;
+
+    case SPINEL_PROP_THREAD_LOCAL_ROUTES:
+        ret = "PROP_THREAD_LOCAL_ROUTES";
+        break;
+
+    case SPINEL_PROP_THREAD_ASSISTING_PORTS:
+        ret = "PROP_THREAD_ASSISTING_PORTS";
+        break;
+
+    case SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE:
+        ret = "SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE";
+        break;
+
+    case SPINEL_PROP_THREAD_RLOC16_DEBUG_PASSTHRU:
+        ret = "SPINEL_PROP_THREAD_RLOC16_DEBUG_PASSTHRU";
+        break;
+
+    case SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED:
+        ret = "SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED";
+        break;
+
+    case SPINEL_PROP_THREAD_ROUTER_UPGRADE_THRESHOLD:
+        ret = "PROP_THREAD_ROUTER_UPGRADE_THRESHOLD";
+        break;
+
+    case SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY:
+        ret = "PROP_THREAD_CONTEXT_REUSE_DELAY";
+        break;
+
+    case SPINEL_PROP_MAC_WHITELIST:
+        ret = "PROP_MAC_WHITELIST";
+        break;
+
+    case SPINEL_PROP_MAC_WHITELIST_ENABLED:
+        ret = "PROP_MAC_WHITELIST_ENABLED";
+        break;
+
+    case SPINEL_PROP_THREAD_MODE:
+        ret = "PROP_THREAD_MODE";
+        break;
+
+    case SPINEL_PROP_THREAD_CHILD_TIMEOUT:
+        ret = "PROP_THREAD_CHILD_TIMEOUT";
+        break;
+
+
+    case SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING:
+        ret = "PROP_NET_REQUIRE_JOIN_EXISTING";
+        break;
+
+    case SPINEL_PROP_NEST_STREAM_MFG:
+        ret = "PROP_NEST_STREAM_MFG";
+        break;
+
+    case SPINEL_PROP_THREAD_NETWORK_ID_TIMEOUT:
+        ret = "PROP_THREAD_NETWORK_ID_TIMEOUT";
+        break;
+
+    case SPINEL_PROP_THREAD_ACTIVE_ROUTER_IDS:
+        ret = "PROP_THREAD_ACTIVE_ROUTER_IDS";
+        break;
+
+    case SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD:
+        ret = "PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD";
+        break;
+
+    case SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER:
+        ret = "PROP_THREAD_ROUTER_SELECTION_JITTER";
+        break;
+
+    case SPINEL_PROP_THREAD_PREFERRED_ROUTER_ID:
+        ret = "PROP_THREAD_PREFERRED_ROUTER_ID";
+        break;
+
+    case SPINEL_PROP_THREAD_NEIGHBOR_TABLE:
+        ret = "PROP_THREAD_NEIGHBOR_TABLE";
+        break;
+
+    case SPINEL_PROP_JAM_DETECT_ENABLE:
+        ret = "PROP_JAM_DETECT_ENABLE";
+        break;
+
+    case SPINEL_PROP_JAM_DETECTED:
+        ret = "PROP_JAM_DETECTED";
+        break;
+
+    case SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD:
+        ret = "PROP_JAM_DETECT_RSSI_THRESHOLD";
+        break;
+
+    case SPINEL_PROP_JAM_DETECT_WINDOW:
+        ret = "PROP_JAM_DETECT_WINDOW";
+        break;
+
+    case SPINEL_PROP_JAM_DETECT_HISTORY_BITMAP:
+        ret = "SPINEL_PROP_JAM_DETECT_HISTORY_BITMAP";
+        break;
+
+    case SPINEL_PROP_GPIO_CONFIG:
+        ret = "PROP_GPIO_CONFIG";
+        break;
+
+    case SPINEL_PROP_GPIO_STATE:
+        ret = "PROP_GPIO_STATE";
+        break;
+
+    case SPINEL_PROP_GPIO_STATE_SET:
+        ret = "PROP_GPIO_STATE_SET";
+        break;
+
+    case SPINEL_PROP_GPIO_STATE_CLEAR:
+        ret = "PROP_GPIO_STATE_CLEAR";
+        break;
+
+    default:
+        break;
+    }
+
+    return ret;
+}
+
+const char *spinel_net_role_to_cstr(uint8_t net_role)
+{
+    const char *ret = "NET_ROLE_UNKNONW";
+
+    switch (net_role)
+    {
+    case SPINEL_NET_ROLE_DETACHED:
+        ret = "NET_ROLE_DETACHED";
+        break;
+
+    case SPINEL_NET_ROLE_CHILD:
+        ret = "NET_ROLE_CHILD";
+        break;
+
+    case SPINEL_NET_ROLE_ROUTER:
+        ret = "NET_ROLE_ROUTER";
+        break;
+
+    case SPINEL_NET_ROLE_LEADER:
+        ret = "NET_ROLE_LEADER";
+        break;
+
+    default:
+        break;
+    }
+
+    return ret;
+}
+
+const char *spinel_status_to_cstr(spinel_status_t status)
+{
+    const char *ret = "UNKNOWN";
+
+    switch (status)
+    {
+    case SPINEL_STATUS_OK:
+        ret = "STATUS_OK";
+        break;
+
+    case SPINEL_STATUS_FAILURE:
+        ret = "STATUS_FAILURE";
+        break;
+
+    case SPINEL_STATUS_UNIMPLEMENTED:
+        ret = "STATUS_UNIMPLEMENTED";
+        break;
+
+    case SPINEL_STATUS_INVALID_ARGUMENT:
+        ret = "STATUS_INVALID_ARGUMENT";
+        break;
+
+    case SPINEL_STATUS_INVALID_STATE:
+        ret = "STATUS_INVALID_STATE";
+        break;
+
+    case SPINEL_STATUS_INVALID_COMMAND:
+        ret = "STATUS_INVALID_COMMAND";
+        break;
+
+    case SPINEL_STATUS_INVALID_INTERFACE:
+        ret = "STATUS_INVALID_INTERFACE";
+        break;
+
+    case SPINEL_STATUS_INTERNAL_ERROR:
+        ret = "STATUS_INTERNAL_ERROR";
+        break;
+
+    case SPINEL_STATUS_SECURITY_ERROR:
+        ret = "STATUS_SECURITY_ERROR";
+        break;
+
+    case SPINEL_STATUS_PARSE_ERROR:
+        ret = "STATUS_PARSE_ERROR";
+        break;
+
+    case SPINEL_STATUS_IN_PROGRESS:
+        ret = "STATUS_IN_PROGRESS";
+        break;
+
+    case SPINEL_STATUS_NOMEM:
+        ret = "STATUS_NOMEM";
+        break;
+
+    case SPINEL_STATUS_BUSY:
+        ret = "STATUS_BUSY";
+        break;
+
+    case SPINEL_STATUS_PROP_NOT_FOUND:
+        ret = "STATUS_PROP_NOT_FOUND";
+        break;
+
+    case SPINEL_STATUS_DROPPED:
+        ret = "STATUS_DROPPED";
+        break;
+
+    case SPINEL_STATUS_EMPTY:
+        ret = "STATUS_EMPTY";
+        break;
+
+    case SPINEL_STATUS_CMD_TOO_BIG:
+        ret = "STATUS_CMD_TOO_BIG";
+        break;
+
+    case SPINEL_STATUS_NO_ACK:
+        ret = "STATUS_NO_ACK";
+        break;
+
+    case SPINEL_STATUS_CCA_FAILURE:
+        ret = "STATUS_CCA_FAILURE";
+        break;
+
+    case SPINEL_STATUS_ALREADY:
+        ret = "STATUS_ALREADY";
+        break;
+
+    case SPINEL_STATUS_ITEM_NOT_FOUND:
+        ret = "STATUS_ITEM_NOT_FOUND";
+        break;
+
+    case SPINEL_STATUS_JOIN_FAILURE:
+        ret = "STATUS_JOIN_FAILURE";
+        break;
+
+    case SPINEL_STATUS_JOIN_SECURITY:
+        ret = "STATUS_JOIN_SECURITY";
+        break;
+
+    case SPINEL_STATUS_JOIN_NO_PEERS:
+        ret = "STATUS_JOIN_NO_PEERS";
+        break;
+
+    case SPINEL_STATUS_JOIN_INCOMPATIBLE:
+        ret = "STATUS_JOIN_INCOMPATIBLE";
+        break;
+
+    case SPINEL_STATUS_RESET_POWER_ON:
+        ret = "STATUS_RESET_POWER_ON";
+        break;
+
+    case SPINEL_STATUS_RESET_EXTERNAL:
+        ret = "STATUS_RESET_EXTERNAL";
+        break;
+
+    case SPINEL_STATUS_RESET_SOFTWARE:
+        ret = "STATUS_RESET_SOFTWARE";
+        break;
+
+    case SPINEL_STATUS_RESET_FAULT:
+        ret = "STATUS_RESET_FAULT";
+        break;
+
+    case SPINEL_STATUS_RESET_CRASH:
+        ret = "STATUS_RESET_CRASH";
+        break;
+
+    case SPINEL_STATUS_RESET_ASSERT:
+        ret = "STATUS_RESET_ASSERT";
+        break;
+
+    case SPINEL_STATUS_RESET_OTHER:
+        ret = "STATUS_RESET_OTHER";
+        break;
+
+    case SPINEL_STATUS_RESET_UNKNOWN:
+        ret = "STATUS_RESET_UNKNOWN";
+        break;
+
+    case SPINEL_STATUS_RESET_WATCHDOG:
+        ret = "STATUS_RESET_WATCHDOG";
+        break;
+
+    default:
+        break;
+    }
+
+    return ret;
+}
+
+// **** LCOV_EXCL_STOP ****
+
+/* -------------------------------------------------------------------------- */
+
+#if SPINEL_SELF_TEST
+
+#include <stdlib.h>
+#include <string.h>
+
+
+int
+main(void)
+{
+    int ret = -1;
+
+    const char static_string[] = "static_string";
+    uint8_t buffer[1024];
+    ssize_t len;
+
+    len = spinel_datatype_pack(buffer, sizeof(buffer), "CiiLU", 0x88, 9, 0xA3, 0xDEADBEEF, static_string);
+
+    if (len != 22)
+    {
+        printf("error:%d: len != 22; (%d)\n", __LINE__, (int)len);
+        goto bail;
+    }
+
+    {
+        uint8_t c = 0;
+        unsigned int i1 = 0;
+        unsigned int i2 = 0;
+        uint32_t l = 0;
+        const char *str = NULL;
+
+        len = spinel_datatype_unpack(buffer, (spinel_size_t)len, "CiiLU", &c, &i1, &i2, &l, &str);
+
+        if (len != 22)
+        {
+            printf("error:%d: len != 22; (%d)\n", __LINE__, (int)len);
+            goto bail;
+        }
+
+        if (c != 0x88)
+        {
+            printf("error: x != 0x88; (%d)\n", c);
+            goto bail;
+        }
+
+        if (i1 != 9)
+        {
+            printf("error: i1 != 9; (%d)\n", i1);
+            goto bail;
+        }
+
+        if (i2 != 0xA3)
+        {
+            printf("error: i2 != 0xA3; (0x%02X)\n", i2);
+            goto bail;
+        }
+
+        if (l != 0xDEADBEEF)
+        {
+            printf("error: l != 0xDEADBEEF; (0x%08X)\n", (unsigned int)l);
+            goto bail;
+        }
+
+        if (strcmp(str, static_string) != 0)
+        {
+            printf("error:%d: strcmp(str,static_string) != 0\n", __LINE__);
+            goto bail;
+        }
+    }
+
+    // -----------------------------------
+
+    memset(buffer, 0xAA, sizeof(buffer));
+
+    len = spinel_datatype_pack(buffer, sizeof(buffer), "CiT(iL)U", 0x88, 9, 0xA3, 0xDEADBEEF, static_string);
+
+    if (len != 24)
+    {
+        printf("error:%d: len != 24; (%d)\n", __LINE__, (int)len);
+        goto bail;
+    }
+
+
+
+    {
+        uint8_t c = 0;
+        unsigned int i1 = 0;
+        unsigned int i2 = 0;
+        uint32_t l = 0;
+        const char *str = NULL;
+
+        len = spinel_datatype_unpack(buffer, (spinel_size_t)len, "CiT(iL)U", &c, &i1, &i2, &l, &str);
+
+        if (len != 24)
+        {
+            printf("error:%d: len != 24; (%d)\n", __LINE__, (int)len);
+            goto bail;
+        }
+
+        if (c != 0x88)
+        {
+            printf("error: x != 0x88; (%d)\n", c);
+            goto bail;
+        }
+
+        if (i1 != 9)
+        {
+            printf("error: i1 != 9; (%d)\n", i1);
+            goto bail;
+        }
+
+        if (i2 != 0xA3)
+        {
+            printf("error: i2 != 0xA3; (0x%02X)\n", i2);
+            goto bail;
+        }
+
+        if (l != 0xDEADBEEF)
+        {
+            printf("error: l != 0xDEADBEEF; (0x%08X)\n", (unsigned int)l);
+            goto bail;
+        }
+
+        if (strcmp(str, static_string) != 0)
+        {
+            printf("error:%d: strcmp(str,static_string) != 0\n", __LINE__);
+            goto bail;
+        }
+    }
+
+
+
+    printf("OK\n");
+    ret = 0;
+    return ret;
+
+bail:
+    printf("FAILURE\n");
+    return ret;
+}
+
+#endif // #if SPINEL_SELF_TEST
diff --git a/third_party/openthread/src/ncp/spinel.h b/third_party/openthread/src/ncp/spinel.h
new file mode 100644
index 0000000..db5fedc
--- /dev/null
+++ b/third_party/openthread/src/ncp/spinel.h
@@ -0,0 +1,1171 @@
+/*
+ *    Copyright (c) 2016, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SPINEL_HEADER_INCLUDED
+#define SPINEL_HEADER_INCLUDED 1
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+// ----------------------------------------------------------------------------
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+# if defined(__GNUC__)
+#  define SPINEL_API_EXTERN              extern __attribute__ ((visibility ("default")))
+#  define SPINEL_API_NONNULL_ALL         __attribute__((nonnull))
+#  define SPINEL_API_WARN_UNUSED_RESULT  __attribute__((warn_unused_result))
+# endif // ifdef __GNUC__
+
+# if !defined(__BEGIN_DECLS) || !defined(__END_DECLS)
+#  if defined(__cplusplus)
+#   define __BEGIN_DECLS   extern "C" {
+#   define __END_DECLS     }
+#  else // if defined(__cplusplus)
+#   define __BEGIN_DECLS
+#   define __END_DECLS
+#  endif // else defined(__cplusplus)
+# endif // if !defined(__BEGIN_DECLS) || !defined(__END_DECLS)
+
+#endif // ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+#ifndef SPINEL_API_EXTERN
+# define SPINEL_API_EXTERN               extern
+#endif
+
+#ifndef SPINEL_API_NONNULL_ALL
+# define SPINEL_API_NONNULL_ALL
+#endif
+
+#ifndef SPINEL_API_WARN_UNUSED_RESULT
+# define SPINEL_API_WARN_UNUSED_RESULT
+#endif
+
+// ----------------------------------------------------------------------------
+
+#define SPINEL_PROTOCOL_VERSION_THREAD_MAJOR    4
+#define SPINEL_PROTOCOL_VERSION_THREAD_MINOR    2
+
+#define SPINEL_FRAME_MAX_SIZE                   1300
+
+/// Macro for generating bit masks using bit index from the spec
+#define SPINEL_BIT_MASK(bit_index,field_bit_count) \
+    ( (1 << ((field_bit_count) - 1)) >> (bit_index))
+
+// ----------------------------------------------------------------------------
+
+__BEGIN_DECLS
+
+typedef enum
+{
+    SPINEL_STATUS_OK                = 0, ///< Operation has completed successfully.
+    SPINEL_STATUS_FAILURE           = 1, ///< Operation has failed for some undefined reason.
+
+    SPINEL_STATUS_UNIMPLEMENTED     = 2, ///< Given operation has not been implemented.
+    SPINEL_STATUS_INVALID_ARGUMENT  = 3, ///< An argument to the operation is invalid.
+    SPINEL_STATUS_INVALID_STATE     = 4, ///< This operation is invalid for the current device state.
+    SPINEL_STATUS_INVALID_COMMAND   = 5, ///< This command is not recognized.
+    SPINEL_STATUS_INVALID_INTERFACE = 6, ///< This interface is not supported.
+    SPINEL_STATUS_INTERNAL_ERROR    = 7, ///< An internal runtime error has occured.
+    SPINEL_STATUS_SECURITY_ERROR    = 8, ///< A security/authentication error has occured.
+    SPINEL_STATUS_PARSE_ERROR       = 9, ///< A error has occured while parsing the command.
+    SPINEL_STATUS_IN_PROGRESS       = 10, ///< This operation is in progress.
+    SPINEL_STATUS_NOMEM             = 11, ///< Operation prevented due to memory pressure.
+    SPINEL_STATUS_BUSY              = 12, ///< The device is currently performing a mutually exclusive operation
+    SPINEL_STATUS_PROP_NOT_FOUND    = 13, ///< The given property is not recognized.
+    SPINEL_STATUS_DROPPED           = 14, ///< A/The packet was dropped.
+    SPINEL_STATUS_EMPTY             = 15, ///< The result of the operation is empty.
+    SPINEL_STATUS_CMD_TOO_BIG       = 16, ///< The command was too large to fit in the internal buffer.
+    SPINEL_STATUS_NO_ACK            = 17, ///< The packet was not acknowledged.
+    SPINEL_STATUS_CCA_FAILURE       = 18, ///< The packet was not sent due to a CCA failure.
+    SPINEL_STATUS_ALREADY           = 19, ///< The operation is already in progress.
+    SPINEL_STATUS_ITEM_NOT_FOUND    = 20, ///< The given item could not be found.
+
+    SPINEL_STATUS_JOIN__BEGIN       = 104,
+
+    /// Generic failure to associate with other peers.
+    /**
+     *  This status error should not be used by implementors if
+     *  enough information is available to determine that one of the
+     *  later join failure status codes would be more accurate.
+     *
+     *  \sa SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING
+     */
+    SPINEL_STATUS_JOIN_FAILURE      = SPINEL_STATUS_JOIN__BEGIN + 0,
+
+    /// The node found other peers but was unable to decode their packets.
+    /**
+     *  Typically this error code indicates that the network
+     *  key has been set incorrectly.
+     *
+     *  \sa SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING
+     */
+    SPINEL_STATUS_JOIN_SECURITY     = SPINEL_STATUS_JOIN__BEGIN + 1,
+
+    /// The node was unable to find any other peers on the network.
+    /**
+     *  \sa SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING
+     */
+    SPINEL_STATUS_JOIN_NO_PEERS     = SPINEL_STATUS_JOIN__BEGIN + 2,
+
+    /// The only potential peer nodes found are incompatible.
+    /**
+     *  \sa SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING
+     */
+    SPINEL_STATUS_JOIN_INCOMPATIBLE = SPINEL_STATUS_JOIN__BEGIN + 3,
+
+    SPINEL_STATUS_JOIN__END         = 112,
+
+    SPINEL_STATUS_RESET__BEGIN      = 112,
+    SPINEL_STATUS_RESET_POWER_ON    = SPINEL_STATUS_RESET__BEGIN + 0,
+    SPINEL_STATUS_RESET_EXTERNAL    = SPINEL_STATUS_RESET__BEGIN + 1,
+    SPINEL_STATUS_RESET_SOFTWARE    = SPINEL_STATUS_RESET__BEGIN + 2,
+    SPINEL_STATUS_RESET_FAULT       = SPINEL_STATUS_RESET__BEGIN + 3,
+    SPINEL_STATUS_RESET_CRASH       = SPINEL_STATUS_RESET__BEGIN + 4,
+    SPINEL_STATUS_RESET_ASSERT      = SPINEL_STATUS_RESET__BEGIN + 5,
+    SPINEL_STATUS_RESET_OTHER       = SPINEL_STATUS_RESET__BEGIN + 6,
+    SPINEL_STATUS_RESET_UNKNOWN     = SPINEL_STATUS_RESET__BEGIN + 7,
+    SPINEL_STATUS_RESET_WATCHDOG    = SPINEL_STATUS_RESET__BEGIN + 8,
+    SPINEL_STATUS_RESET__END        = 128,
+
+    SPINEL_STATUS_VENDOR__BEGIN     = 15360,
+    SPINEL_STATUS_VENDOR__END       = 16384,
+
+    SPINEL_STATUS_STACK_NATIVE__BEGIN = 16384,
+    SPINEL_STATUS_STACK_NATIVE__END   = 81920,
+
+    SPINEL_STATUS_EXPERIMENTAL__BEGIN = 2000000,
+    SPINEL_STATUS_EXPERIMENTAL__END   = 2097152,
+} spinel_status_t;
+
+typedef enum
+{
+    SPINEL_NET_ROLE_DETACHED   = 0,
+    SPINEL_NET_ROLE_CHILD      = 1,
+    SPINEL_NET_ROLE_ROUTER     = 2,
+    SPINEL_NET_ROLE_LEADER     = 3,
+} spinel_net_role_t;
+
+typedef enum
+{
+    SPINEL_SCAN_STATE_IDLE     = 0,
+    SPINEL_SCAN_STATE_BEACON   = 1,
+    SPINEL_SCAN_STATE_ENERGY   = 2,
+} spinel_scan_state_t;
+
+typedef enum
+{
+    SPINEL_POWER_STATE_OFFLINE    = 0,
+    SPINEL_POWER_STATE_DEEP_SLEEP = 1,
+    SPINEL_POWER_STATE_STANDBY    = 2,
+    SPINEL_POWER_STATE_LOW_POWER  = 3,
+    SPINEL_POWER_STATE_ONLINE     = 4,
+} spinel_power_state_t;
+
+enum {
+    SPINEL_NET_FLAG_ON_MESH           = (1 << 0),
+    SPINEL_NET_FLAG_DEFAULT_ROUTE     = (1 << 1),
+    SPINEL_NET_FLAG_CONFIGURE         = (1 << 2),
+    SPINEL_NET_FLAG_DHCP              = (1 << 3),
+    SPINEL_NET_FLAG_SLAAC             = (1 << 4),
+    SPINEL_NET_FLAG_PREFERRED         = (1 << 5),
+
+    SPINEL_NET_FLAG_PREFERENCE_OFFSET = 6,
+    SPINEL_NET_FLAG_PREFERENCE_MASK   = (3 << SPINEL_NET_FLAG_PREFERENCE_OFFSET),
+};
+
+enum {
+    SPINEL_GPIO_FLAG_DIR_INPUT        = 0,
+    SPINEL_GPIO_FLAG_DIR_OUTPUT       = SPINEL_BIT_MASK(0, 8),
+    SPINEL_GPIO_FLAG_PULL_UP          = SPINEL_BIT_MASK(1, 8),
+    SPINEL_GPIO_FLAG_PULL_DOWN        = SPINEL_BIT_MASK(2, 8),
+    SPINEL_GPIO_FLAG_OPEN_DRAIN       = SPINEL_BIT_MASK(2, 8),
+    SPINEL_GPIO_FLAG_TRIGGER_NONE     = 0,
+    SPINEL_GPIO_FLAG_TRIGGER_RISING   = SPINEL_BIT_MASK(3, 8),
+    SPINEL_GPIO_FLAG_TRIGGER_FALLING  = SPINEL_BIT_MASK(4, 8),
+    SPINEL_GPIO_FLAG_TRIGGER_ANY      = SPINEL_GPIO_FLAG_TRIGGER_RISING
+                                      | SPINEL_GPIO_FLAG_TRIGGER_FALLING,
+};
+
+enum
+{
+    SPINEL_PROTOCOL_TYPE_BOOTLOADER = 0,
+    SPINEL_PROTOCOL_TYPE_ZIGBEE_IP  = 2,
+    SPINEL_PROTOCOL_TYPE_THREAD     = 3,
+};
+
+enum
+{
+    SPINEL_MAC_PROMISCUOUS_MODE_OFF      = 0, ///< Normal MAC filtering is in place.
+    SPINEL_MAC_PROMISCUOUS_MODE_NETWORK  = 1, ///< All MAC packets matching network are passed up the stack.
+    SPINEL_MAC_PROMISCUOUS_MODE_FULL     = 2, ///< All decoded MAC packets are passed up the stack.
+};
+
+typedef struct
+{
+    uint8_t bytes[8];
+} spinel_eui64_t;
+
+typedef struct
+{
+    uint8_t bytes[8];
+} spinel_net_xpanid_t;
+
+typedef struct
+{
+    uint8_t bytes[6];
+} spinel_eui48_t;
+
+typedef struct
+{
+    uint8_t bytes[16];
+} spinel_ipv6addr_t;
+
+typedef int spinel_ssize_t;
+typedef unsigned int spinel_size_t;
+typedef uint8_t spinel_tid_t;
+typedef unsigned int spinel_cid_t;
+
+enum
+{
+    SPINEL_MD_FLAG_TX               = 0x0001, //!< Packet was transmitted, not received.
+    SPINEL_MD_FLAG_BAD_FCS          = 0x0004, //!< Packet was received with bad FCS
+    SPINEL_MD_FLAG_DUPE             = 0x0008, //!< Packet seems to be a duplicate
+    SPINEL_MD_FLAG_RESERVED         = 0xFFF2, //!< Flags reserved for future use.
+};
+
+enum
+{
+    SPINEL_CMD_NOOP                 = 0,
+    SPINEL_CMD_RESET                = 1,
+    SPINEL_CMD_PROP_VALUE_GET       = 2,
+    SPINEL_CMD_PROP_VALUE_SET       = 3,
+    SPINEL_CMD_PROP_VALUE_INSERT    = 4,
+    SPINEL_CMD_PROP_VALUE_REMOVE    = 5,
+    SPINEL_CMD_PROP_VALUE_IS        = 6,
+    SPINEL_CMD_PROP_VALUE_INSERTED  = 7,
+    SPINEL_CMD_PROP_VALUE_REMOVED   = 8,
+
+    SPINEL_CMD_NET_SAVE             = 9,
+    SPINEL_CMD_NET_CLEAR            = 10,
+    SPINEL_CMD_NET_RECALL           = 11,
+
+    SPINEL_CMD_HBO_OFFLOAD          = 12,
+    SPINEL_CMD_HBO_RECLAIM          = 13,
+    SPINEL_CMD_HBO_DROP             = 14,
+    SPINEL_CMD_HBO_OFFLOADED        = 15,
+    SPINEL_CMD_HBO_RECLAIMED        = 16,
+    SPINEL_CMD_HBO_DROPED           = 17,
+
+    SPINEL_CMD_PEEK                 = 18,
+    SPINEL_CMD_PEEK_RET             = 19,
+    SPINEL_CMD_POKE                 = 20,
+
+    SPINEL_CMD_NEST__BEGIN          = 15296,
+    SPINEL_CMD_NEST__END            = 15360,
+
+    SPINEL_CMD_VENDOR__BEGIN        = 15360,
+    SPINEL_CMD_VENDOR__END          = 16384,
+
+    SPINEL_CMD_EXPERIMENTAL__BEGIN  = 2000000,
+    SPINEL_CMD_EXPERIMENTAL__END    = 2097152,
+};
+
+enum
+{
+    SPINEL_CAP_LOCK                  = 1,
+    SPINEL_CAP_NET_SAVE              = 2,
+    SPINEL_CAP_HBO                   = 3,
+    SPINEL_CAP_POWER_SAVE            = 4,
+
+    SPINEL_CAP_COUNTERS              = 5,
+    SPINEL_CAP_JAM_DETECT            = 6,
+
+    SPINEL_CAP_PEEK_POKE             = 7,
+
+    SPINEL_CAP_WRITABLE_RAW_STREAM   = 8,
+    SPINEL_CAP_GPIO                  = 9,
+    SPINEL_CAP_TRNG                  = 10,
+
+    SPINEL_CAP_802_15_4__BEGIN        = 16,
+    SPINEL_CAP_802_15_4_2003          = (SPINEL_CAP_802_15_4__BEGIN + 0),
+    SPINEL_CAP_802_15_4_2006          = (SPINEL_CAP_802_15_4__BEGIN + 1),
+    SPINEL_CAP_802_15_4_2011          = (SPINEL_CAP_802_15_4__BEGIN + 2),
+    SPINEL_CAP_802_15_4_PIB           = (SPINEL_CAP_802_15_4__BEGIN + 5),
+    SPINEL_CAP_802_15_4_2450MHZ_OQPSK = (SPINEL_CAP_802_15_4__BEGIN + 8),
+    SPINEL_CAP_802_15_4_915MHZ_OQPSK  = (SPINEL_CAP_802_15_4__BEGIN + 9),
+    SPINEL_CAP_802_15_4_868MHZ_OQPSK  = (SPINEL_CAP_802_15_4__BEGIN + 10),
+    SPINEL_CAP_802_15_4_915MHZ_BPSK   = (SPINEL_CAP_802_15_4__BEGIN + 11),
+    SPINEL_CAP_802_15_4_868MHZ_BPSK   = (SPINEL_CAP_802_15_4__BEGIN + 12),
+    SPINEL_CAP_802_15_4_915MHZ_ASK    = (SPINEL_CAP_802_15_4__BEGIN + 13),
+    SPINEL_CAP_802_15_4_868MHZ_ASK    = (SPINEL_CAP_802_15_4__BEGIN + 14),
+    SPINEL_CAP_802_15_4__END          = 32,
+
+    SPINEL_CAP_ROLE__BEGIN           = 48,
+    SPINEL_CAP_ROLE_ROUTER           = (SPINEL_CAP_ROLE__BEGIN + 0),
+    SPINEL_CAP_ROLE_SLEEPY           = (SPINEL_CAP_ROLE__BEGIN + 1),
+    SPINEL_CAP_ROLE__END             = 52,
+
+    SPINEL_CAP_NET__BEGIN            = 52,
+    SPINEL_CAP_NET_THREAD_1_0        = (SPINEL_CAP_NET__BEGIN + 0),
+    SPINEL_CAP_NET__END              = 64,
+
+    SPINEL_CAP_OPENTHREAD__BEGIN     = 512,
+    SPINEL_CAP_MAC_WHITELIST         = (SPINEL_CAP_OPENTHREAD__BEGIN + 0),
+    SPINEL_CAP_OPENTHREAD__END       = 640,
+
+    SPINEL_CAP_NEST__BEGIN           = 15296,
+    SPINEL_CAP_NEST_LEGACY_INTERFACE = (SPINEL_CAP_NEST__BEGIN + 0),
+    SPINEL_CAP_NEST_LEGACY_NET_WAKE  = (SPINEL_CAP_NEST__BEGIN + 1),
+    SPINEL_CAP_NEST_TRANSMIT_HOOK    = (SPINEL_CAP_NEST__BEGIN + 2),
+    SPINEL_CAP_NEST__END             = 15360,
+
+    SPINEL_CAP_VENDOR__BEGIN         = 15360,
+    SPINEL_CAP_VENDOR__END           = 16384,
+
+    SPINEL_CAP_EXPERIMENTAL__BEGIN   = 2000000,
+    SPINEL_CAP_EXPERIMENTAL__END     = 2097152,
+};
+
+typedef enum
+{
+    SPINEL_PROP_LAST_STATUS             = 0,        ///< status [i]
+    SPINEL_PROP_PROTOCOL_VERSION        = 1,        ///< major, minor [i,i]
+    SPINEL_PROP_NCP_VERSION             = 2,        ///< version string [U]
+    SPINEL_PROP_INTERFACE_TYPE          = 3,        ///< [i]
+    SPINEL_PROP_VENDOR_ID               = 4,        ///< [i]
+    SPINEL_PROP_CAPS                    = 5,        ///< capability list [A(i)]
+    SPINEL_PROP_INTERFACE_COUNT         = 6,        ///< Interface count [C]
+    SPINEL_PROP_POWER_STATE             = 7,        ///< PowerState [C]
+    SPINEL_PROP_HWADDR                  = 8,        ///< PermEUI64 [E]
+    SPINEL_PROP_LOCK                    = 9,        ///< PropLock [b]
+    SPINEL_PROP_HBO_MEM_MAX             = 10,       ///< Max offload mem [S]
+    SPINEL_PROP_HBO_BLOCK_MAX           = 11,       ///< Max offload block [S]
+
+    SPINEL_PROP_BASE_EXT__BEGIN         = 0x1000,
+
+    /// GPIO Configuration
+    /** Format: `A(CCU)`
+     *  Type: Read-Only (Optionally Read-write using `CMD_PROP_VALUE_INSERT`)
+     *
+     * An array of structures which contain the following fields:
+     *
+     * *   `C`: GPIO Number
+     * *   `C`: GPIO Configuration Flags
+     * *   `U`: Human-readable GPIO name
+     *
+     * GPIOs which do not have a corresponding entry are not supported.
+     *
+     * The configuration parameter contains the configuration flags for the
+     * GPIO:
+     *
+     *       0   1   2   3   4   5   6   7
+     *     +---+---+---+---+---+---+---+---+
+     *     |DIR|PUP|PDN|TRIGGER|  RESERVED |
+     *     +---+---+---+---+---+---+---+---+
+     *             |O/D|
+     *             +---+
+     *
+     * *   `DIR`: Pin direction. Clear (0) for input, set (1) for output.
+     * *   `PUP`: Pull-up enabled flag.
+     * *   `PDN`/`O/D`: Flag meaning depends on pin direction:
+     *     *   Input: Pull-down enabled.
+     *     *   Output: Output is an open-drain.
+     * *   `TRIGGER`: Enumeration describing how pin changes generate
+     *     asynchronous notification commands (TBD) from the NCP to the host.
+     *     *   0: Feature disabled for this pin
+     *     *   1: Trigger on falling edge
+     *     *   2: Trigger on rising edge
+     *     *   3: Trigger on level change
+     * *   `RESERVED`: Bits reserved for future use. Always cleared to zero
+     *     and ignored when read.
+     *
+     * As an optional feature, the configuration of individual pins may be
+     * modified using the `CMD_PROP_VALUE_INSERT` command. Only the GPIO
+     * number and flags fields MUST be present, the GPIO name (if present)
+     * would be ignored. This command can only be used to modify the
+     * configuration of GPIOs which are already exposed---it cannot be used
+     * by the host to add addional GPIOs.
+     */
+    SPINEL_PROP_GPIO_CONFIG             = SPINEL_PROP_BASE_EXT__BEGIN + 0,
+
+    /// GPIO State Bitmask
+    /** Format: `D`
+     *  Type: Read-Write
+     *
+     * Contains a bit field identifying the state of the GPIOs. The length of
+     * the data associated with these properties depends on the number of
+     * GPIOs. If you have 10 GPIOs, you'd have two bytes. GPIOs are numbered
+     * from most significant bit to least significant bit, so 0x80 is GPIO 0,
+     * 0x40 is GPIO 1, etc.
+     *
+     * For GPIOs configured as inputs:
+     *
+     * *   `CMD_PROP_VAUE_GET`: The value of the associated bit describes the
+     *     logic level read from the pin.
+     * *   `CMD_PROP_VALUE_SET`: The value of the associated bit is ignored
+     *     for these pins.
+     *
+     * For GPIOs configured as outputs:
+     *
+     * *   `CMD_PROP_VAUE_GET`: The value of the associated bit is
+     *     implementation specific.
+     * *   `CMD_PROP_VALUE_SET`: The value of the associated bit determines
+     *     the new logic level of the output. If this pin is configured as an
+     *     open-drain, setting the associated bit to 1 will cause the pin to
+     *     enter a Hi-Z state.
+     *
+     * For GPIOs which are not specified in `PROP_GPIO_CONFIG`:
+     *
+     * *   `CMD_PROP_VAUE_GET`: The value of the associated bit is
+     *     implementation specific.
+     * *   `CMD_PROP_VALUE_SET`: The value of the associated bit MUST be
+     *     ignored by the NCP.
+     *
+     * When writing, unspecified bits are assumed to be zero.
+     */
+    SPINEL_PROP_GPIO_STATE              = SPINEL_PROP_BASE_EXT__BEGIN + 2,
+
+    /// GPIO State Set-Only Bitmask
+    /** Format: `D`
+     *  Type: Write-Only
+     *
+     * Allows for the state of various output GPIOs to be set without affecting
+     * other GPIO states. Contains a bit field identifying the output GPIOs that
+     * should have their state set to 1.
+     *
+     * When writing, unspecified bits are assumed to be zero. The value of
+     * any bits for GPIOs which are not specified in `PROP_GPIO_CONFIG` MUST
+     * be ignored.
+     */
+    SPINEL_PROP_GPIO_STATE_SET          = SPINEL_PROP_BASE_EXT__BEGIN + 3,
+
+    /// GPIO State Clear-Only Bitmask
+    /** Format: `D`
+     *  Type: Write-Only
+     *
+     * Allows for the state of various output GPIOs to be cleared without affecting
+     * other GPIO states. Contains a bit field identifying the output GPIOs that
+     * should have their state cleared to 0.
+     *
+     * When writing, unspecified bits are assumed to be zero. The value of
+     * any bits for GPIOs which are not specified in `PROP_GPIO_CONFIG` MUST
+     * be ignored.
+     */
+    SPINEL_PROP_GPIO_STATE_CLEAR        = SPINEL_PROP_BASE_EXT__BEGIN + 4,
+
+    /// 32-bit random number from TRNG, ready-to-use.
+    SPINEL_PROP_TRNG_32                 = SPINEL_PROP_BASE_EXT__BEGIN + 5,
+
+    /// 16 random bytes from TRNG, ready-to-use.
+    SPINEL_PROP_TRNG_128                = SPINEL_PROP_BASE_EXT__BEGIN + 6,
+
+    /// Raw samples from TRNG entropy source representing 32 bits of entropy.
+    SPINEL_PROP_TRNG_RAW_32             = SPINEL_PROP_BASE_EXT__BEGIN + 7,
+
+    SPINEL_PROP_BASE_EXT__END           = 0x1100,
+
+    SPINEL_PROP_PHY__BEGIN              = 0x20,
+    SPINEL_PROP_PHY_ENABLED             = SPINEL_PROP_PHY__BEGIN + 0, ///< [b]
+    SPINEL_PROP_PHY_CHAN                = SPINEL_PROP_PHY__BEGIN + 1, ///< [C]
+    SPINEL_PROP_PHY_CHAN_SUPPORTED      = SPINEL_PROP_PHY__BEGIN + 2, ///< [A(C)]
+    SPINEL_PROP_PHY_FREQ                = SPINEL_PROP_PHY__BEGIN + 3, ///< kHz [L]
+    SPINEL_PROP_PHY_CCA_THRESHOLD       = SPINEL_PROP_PHY__BEGIN + 4, ///< dBm [c]
+    SPINEL_PROP_PHY_TX_POWER            = SPINEL_PROP_PHY__BEGIN + 5, ///< [c]
+    SPINEL_PROP_PHY_RSSI                = SPINEL_PROP_PHY__BEGIN + 6, ///< dBm [c]
+    SPINEL_PROP_PHY__END                = 0x30,
+
+    SPINEL_PROP_PHY_EXT__BEGIN          = 0x1200,
+
+    /// Signal Jamming Detection Enable
+    /** Format: `b`
+     *
+     * Indicates if jamming detection is enabled or disabled. Set to true
+     * to enable jamming detection.
+     */
+    SPINEL_PROP_JAM_DETECT_ENABLE       = SPINEL_PROP_PHY_EXT__BEGIN + 0,
+
+    /// Signal Jamming Detected Indicator
+    /** Format: `b` (Read-Only)
+     *
+     * Set to true if radio jamming is detected. Set to false otherwise.
+     *
+     * When jamming detection is enabled, changes to the value of this
+     * property are emitted asynchronously via `CMD_PROP_VALUE_IS`.
+     */
+    SPINEL_PROP_JAM_DETECTED            = SPINEL_PROP_PHY_EXT__BEGIN + 1,
+
+    /// Jamming detection RSSI threshold
+    /** Format: `c`
+     *  Units: dBm
+     *
+     * This parameter describes the threshold RSSI level (measured in
+     * dBm) above which the jamming detection will consider the
+     * channel blocked.
+     */
+    SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD
+                                        = SPINEL_PROP_PHY_EXT__BEGIN + 2,
+
+    /// Jamming detection window size
+    /** Format: `C`
+     *  Units: Seconds (1-63)
+     *
+     * This parameter describes the window period for signal jamming
+     * detection.
+     */
+    SPINEL_PROP_JAM_DETECT_WINDOW       = SPINEL_PROP_PHY_EXT__BEGIN + 3,
+
+    /// Jamming detection busy period
+    /** Format: `C`
+     *  Units: Seconds (1-63)
+     *
+     * This parameter describes the number of aggregate seconds within
+     * the detection window where the RSSI must be above
+     * `PROP_JAM_DETECT_RSSI_THRESHOLD` to trigger detection.
+     *
+     * The behavior of the jamming detection feature when `PROP_JAM_DETECT_BUSY`
+     * is larger than `PROP_JAM_DETECT_WINDOW` is undefined.
+     */
+    SPINEL_PROP_JAM_DETECT_BUSY         = SPINEL_PROP_PHY_EXT__BEGIN + 4,
+
+    /// Jamming detection history bitmap (for debugging)
+    /** Format: `LL` (read-only)
+     *
+     * This value provides information about current state of jamming detection
+     * module for monitoring/debugging purpose. It returns a 64-bit value where
+     * each bit corresponds to one second interval starting with bit 0 for the
+     * most recent interval and bit 63 for the oldest intervals (63 sec earlier).
+     * The bit is set to 1 if the jamming detection module observed/detected
+     * high signal level during the corresponding one second interval.
+     *
+     * The value is read-only and is encoded as two uint32 values in
+     * little-endian format (first uint32 gives the lower bits corresponding to
+     * more recent history).
+     */
+    SPINEL_PROP_JAM_DETECT_HISTORY_BITMAP
+                                        = SPINEL_PROP_PHY_EXT__BEGIN + 5,
+
+    SPINEL_PROP_PHY_EXT__END            = 0x1300,
+
+    SPINEL_PROP_MAC__BEGIN             = 0x30,
+    SPINEL_PROP_MAC_SCAN_STATE         = SPINEL_PROP_MAC__BEGIN + 0, ///< [C]
+    SPINEL_PROP_MAC_SCAN_MASK          = SPINEL_PROP_MAC__BEGIN + 1, ///< [A(C)]
+    SPINEL_PROP_MAC_SCAN_PERIOD        = SPINEL_PROP_MAC__BEGIN + 2, ///< ms-per-channel [S]
+    SPINEL_PROP_MAC_SCAN_BEACON        = SPINEL_PROP_MAC__BEGIN + 3, ///< chan,rssi,(laddr,saddr,panid,lqi),(proto,xtra) [CcT(ESSC.)T(i).]
+    SPINEL_PROP_MAC_15_4_LADDR         = SPINEL_PROP_MAC__BEGIN + 4, ///< [E]
+    SPINEL_PROP_MAC_15_4_SADDR         = SPINEL_PROP_MAC__BEGIN + 5, ///< [S]
+    SPINEL_PROP_MAC_15_4_PANID         = SPINEL_PROP_MAC__BEGIN + 6, ///< [S]
+    SPINEL_PROP_MAC_RAW_STREAM_ENABLED = SPINEL_PROP_MAC__BEGIN + 7, ///< [C]
+    SPINEL_PROP_MAC_PROMISCUOUS_MODE   = SPINEL_PROP_MAC__BEGIN + 8, ///< [C]
+    SPINEL_PROP_MAC_ENERGY_SCAN_RESULT = SPINEL_PROP_MAC__BEGIN + 9, ///< chan,maxRssi [Cc]
+    SPINEL_PROP_MAC__END               = 0x40,
+
+    SPINEL_PROP_MAC_EXT__BEGIN         = 0x1300,
+    /// MAC Whitelist
+    /** Format: `A(T(Ec))`
+     *
+     * Structure Parameters:
+     *
+     * * `E`: EUI64 address of node
+     * * `c`: Optional fixed RSSI. 127 means not set.
+     */
+    SPINEL_PROP_MAC_WHITELIST          = SPINEL_PROP_MAC_EXT__BEGIN + 0,
+
+    /// MAC Whitelist Enabled Flag
+    /** Format: `b`
+     */
+    SPINEL_PROP_MAC_WHITELIST_ENABLED  = SPINEL_PROP_MAC_EXT__BEGIN + 1,
+
+    /// MAC Extended Address
+    /** Format: `E`
+     *
+     *  Specified by Thread. Randomly-chosen, but non-volatile EUI-64.
+     */
+    SPINEL_PROP_MAC_EXTENDED_ADDR      = SPINEL_PROP_MAC_EXT__BEGIN + 2,
+    SPINEL_PROP_MAC_EXT__END           = 0x1400,
+
+    SPINEL_PROP_NET__BEGIN           = 0x40,
+    SPINEL_PROP_NET_SAVED            = SPINEL_PROP_NET__BEGIN + 0, ///< [b]
+    SPINEL_PROP_NET_IF_UP            = SPINEL_PROP_NET__BEGIN + 1, ///< [b]
+    SPINEL_PROP_NET_STACK_UP         = SPINEL_PROP_NET__BEGIN + 2, ///< [b]
+    SPINEL_PROP_NET_ROLE             = SPINEL_PROP_NET__BEGIN + 3, ///< [C]
+    SPINEL_PROP_NET_NETWORK_NAME     = SPINEL_PROP_NET__BEGIN + 4, ///< [U]
+    SPINEL_PROP_NET_XPANID           = SPINEL_PROP_NET__BEGIN + 5, ///< [D]
+    SPINEL_PROP_NET_MASTER_KEY       = SPINEL_PROP_NET__BEGIN + 6, ///< [D]
+    SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER
+                                     = SPINEL_PROP_NET__BEGIN + 7, ///< [L]
+    SPINEL_PROP_NET_PARTITION_ID     = SPINEL_PROP_NET__BEGIN + 8, ///< [L]
+
+    /// Require Join Existing
+    /** Format: `b`
+     *  Default Value: `false`
+     *
+     * This flag is typically used for nodes that are associating with an
+     * existing network for the first time. If this is set to `true` before
+     * `PROP_NET_STACK_UP` is set to `true`, the
+     * creation of a new partition at association is prevented. If the node
+     * cannot associate with an existing partition, `PROP_LAST_STATUS` will
+     * emit a status that indicates why the association failed and
+     * `PROP_NET_STACK_UP` will automatically revert to `false`.
+     *
+     * Once associated with an existing partition, this flag automatically
+     * reverts to `false`.
+     *
+     * The behavior of this property being set to `true` when
+     * `PROP_NET_STACK_UP` is already set to `true` is undefined.
+     */
+    SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING
+                                     = SPINEL_PROP_NET__BEGIN + 9,
+
+    SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME
+                                     = SPINEL_PROP_NET__BEGIN + 10, ///< [L]
+
+    SPINEL_PROP_NET__END             = 0x50,
+
+    SPINEL_PROP_THREAD__BEGIN          = 0x50,
+    SPINEL_PROP_THREAD_LEADER_ADDR     = SPINEL_PROP_THREAD__BEGIN + 0, ///< [6]
+    SPINEL_PROP_THREAD_PARENT          = SPINEL_PROP_THREAD__BEGIN + 1, ///< LADDR, SADDR [ES]
+    SPINEL_PROP_THREAD_CHILD_TABLE     = SPINEL_PROP_THREAD__BEGIN + 2, ///< array(EUI64,rloc16,timeout,age,netDataVer,inLqi,aveRSS,mode) [A(T(ESLLCCcC))]
+    SPINEL_PROP_THREAD_LEADER_RID      = SPINEL_PROP_THREAD__BEGIN + 3, ///< [C]
+    SPINEL_PROP_THREAD_LEADER_WEIGHT   = SPINEL_PROP_THREAD__BEGIN + 4, ///< [C]
+    SPINEL_PROP_THREAD_LOCAL_LEADER_WEIGHT
+                                       = SPINEL_PROP_THREAD__BEGIN + 5, ///< [C]
+    SPINEL_PROP_THREAD_NETWORK_DATA    = SPINEL_PROP_THREAD__BEGIN + 6, ///< [D]
+    SPINEL_PROP_THREAD_NETWORK_DATA_VERSION
+                                       = SPINEL_PROP_THREAD__BEGIN + 7, ///< [S]
+    SPINEL_PROP_THREAD_STABLE_NETWORK_DATA
+                                       = SPINEL_PROP_THREAD__BEGIN + 8, ///< [D]
+    SPINEL_PROP_THREAD_STABLE_NETWORK_DATA_VERSION
+                                       = SPINEL_PROP_THREAD__BEGIN + 9,  ///< [S]
+    SPINEL_PROP_THREAD_ON_MESH_NETS    = SPINEL_PROP_THREAD__BEGIN + 10, ///< array(ipv6prefix,prefixlen,stable,flags) [A(T(6CbC))]
+    SPINEL_PROP_THREAD_LOCAL_ROUTES    = SPINEL_PROP_THREAD__BEGIN + 11, ///< array(ipv6prefix,prefixlen,stable,flags) [A(T(6CbC))]
+    SPINEL_PROP_THREAD_ASSISTING_PORTS = SPINEL_PROP_THREAD__BEGIN + 12, ///< array(portn) [A(S)]
+    SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE
+                                       = SPINEL_PROP_THREAD__BEGIN + 13, ///< [b]
+
+    /// Thread Mode
+    /** Format: `C`
+     *
+     *  This property contains the value of the mode
+     *  TLV for this node. The meaning of the bits in this
+     *  bitfield are defined by section 4.5.2 of the Thread
+     *  specification.
+     */
+    SPINEL_PROP_THREAD_MODE            = SPINEL_PROP_THREAD__BEGIN + 14,
+    SPINEL_PROP_THREAD__END            = 0x60,
+
+    SPINEL_PROP_THREAD_EXT__BEGIN      = 0x1500,
+
+    /// Thread Child Timeout
+    /** Format: `L`
+     *
+     *  Used when operating in the Child role.
+     */
+    SPINEL_PROP_THREAD_CHILD_TIMEOUT   = SPINEL_PROP_THREAD_EXT__BEGIN + 0,
+
+    /// Thread RLOC16
+    /** Format: `S`
+     */
+    SPINEL_PROP_THREAD_RLOC16          = SPINEL_PROP_THREAD_EXT__BEGIN + 1,
+
+    /// Thread Router Upgrade Threshold
+    /** Format: `C`
+     */
+    SPINEL_PROP_THREAD_ROUTER_UPGRADE_THRESHOLD
+                                       = SPINEL_PROP_THREAD_EXT__BEGIN + 2,
+
+    /// Thread Context Reuse Delay
+    /** Format: `L`
+     */
+    SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY
+                                       = SPINEL_PROP_THREAD_EXT__BEGIN + 3,
+
+    /// Thread Network ID Timeout
+    /** Format: `C`
+     */
+    SPINEL_PROP_THREAD_NETWORK_ID_TIMEOUT
+                                       = SPINEL_PROP_THREAD_EXT__BEGIN + 4,
+
+    /// List of active thread router ids
+    /** Format: `A(C)`
+     *
+     * Note that some implementations may not support CMD_GET_VALUE
+     * routerids, but may support CMD_REMOVE_VALUE when the node is
+     * a leader.
+     */
+    SPINEL_PROP_THREAD_ACTIVE_ROUTER_IDS
+                                       = SPINEL_PROP_THREAD_EXT__BEGIN + 5,
+
+    /// Forward IPv6 packets that use RLOC16 addresses to HOST.
+    /** Format: `b`
+     */
+    SPINEL_PROP_THREAD_RLOC16_DEBUG_PASSTHRU
+                                       = SPINEL_PROP_THREAD_EXT__BEGIN + 6,
+
+    /// This property indicates whether or not the `Router Role` is enabled.
+    /** Format `b`
+     */
+    SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED
+                                       = SPINEL_PROP_THREAD_EXT__BEGIN + 7,
+
+    /// Thread Router Downgrade Threshold
+    /** Format: `C`
+     */
+    SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD
+                                       = SPINEL_PROP_THREAD_EXT__BEGIN + 8,
+
+    /// Thread Router Selection Jitter
+    /** Format: `C`
+     */
+    SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER
+                                       = SPINEL_PROP_THREAD_EXT__BEGIN + 9,
+
+    /// Thread Preferred Router Id
+    /** Format: `C` - Write only
+     */
+    SPINEL_PROP_THREAD_PREFERRED_ROUTER_ID
+                                       = SPINEL_PROP_THREAD_EXT__BEGIN + 10,
+
+    /// Thread Neighbor Table
+    /** Format: `A(T(ESLCcCbLL))`
+     *  eui64, rloc16, age, inLqi ,aveRSS, mode, isChild. linkFrameCounter, mleCounter
+     */
+    SPINEL_PROP_THREAD_NEIGHBOR_TABLE  = SPINEL_PROP_THREAD_EXT__BEGIN + 11,
+
+    /// Thread Max Child Count
+    /** Format: `C`
+     */
+    SPINEL_PROP_THREAD_CHILD_COUNT_MAX = SPINEL_PROP_THREAD_EXT__BEGIN + 12,
+
+    /// Leader network data
+    /** Format: `D` - Read only
+     */
+    SPINEL_PROP_THREAD_LEADER_NETWORK_DATA
+                                       = SPINEL_PROP_THREAD_EXT__BEGIN + 13,
+
+    /// Stable leader network data
+    /** Format: `D` - Read only
+     */
+    SPINEL_PROP_THREAD_STABLE_LEADER_NETWORK_DATA
+                                       = SPINEL_PROP_THREAD_EXT__BEGIN + 14,
+
+    SPINEL_PROP_THREAD_EXT__END        = 0x1600,
+
+    SPINEL_PROP_IPV6__BEGIN          = 0x60,
+    SPINEL_PROP_IPV6_LL_ADDR         = SPINEL_PROP_IPV6__BEGIN + 0, ///< [6]
+    SPINEL_PROP_IPV6_ML_ADDR         = SPINEL_PROP_IPV6__BEGIN + 1, ///< [6C]
+    SPINEL_PROP_IPV6_ML_PREFIX       = SPINEL_PROP_IPV6__BEGIN + 2, ///< [6C]
+    SPINEL_PROP_IPV6_ADDRESS_TABLE   = SPINEL_PROP_IPV6__BEGIN + 3, ///< array(ipv6addr,prefixlen,valid,preferred,flags) [A(T(6CLLC))]
+    SPINEL_PROP_IPV6_ROUTE_TABLE     = SPINEL_PROP_IPV6__BEGIN + 4, ///< array(ipv6prefix,prefixlen,iface,flags) [A(T(6CCC))]
+
+
+    /// IPv6 ICMP Ping Offload
+    /** Format: `b`
+     *
+     * Allow the NCP to directly respond to ICMP ping requests. If this is
+     * turned on, ping request ICMP packets will not be passed to the host.
+     *
+     * Default value is `false`.
+     */
+    SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD = SPINEL_PROP_IPV6__BEGIN + 5, ///< [b]
+
+    SPINEL_PROP_IPV6__END            = 0x70,
+
+    SPINEL_PROP_STREAM__BEGIN       = 0x70,
+    SPINEL_PROP_STREAM_DEBUG        = SPINEL_PROP_STREAM__BEGIN + 0, ///< [U]
+    SPINEL_PROP_STREAM_RAW          = SPINEL_PROP_STREAM__BEGIN + 1, ///< [D]
+    SPINEL_PROP_STREAM_NET          = SPINEL_PROP_STREAM__BEGIN + 2, ///< [D]
+    SPINEL_PROP_STREAM_NET_INSECURE = SPINEL_PROP_STREAM__BEGIN + 3, ///< [D]
+    SPINEL_PROP_STREAM__END         = 0x80,
+
+
+    /// UART Bitrate
+    /** Format: `L`
+     *
+     *  If the NCP is using a UART to communicate with the host,
+     *  this property allows the host to change the bitrate
+     *  of the serial connection. The value encoding is `L`,
+     *  which is a little-endian 32-bit unsigned integer.
+     *  The host should not assume that all possible numeric values
+     *  are supported.
+     *
+     *  If implemented by the NCP, this property should be persistent
+     *  across software resets and forgotten upon hardware resets.
+     *
+     *  This property is only implemented when a UART is being
+     *  used for Spinel. This property is optional.
+     *
+     *  When changing the bitrate, all frames will be received
+     *  at the previous bitrate until the response frame to this command
+     *  is received. Once a successful response frame is received by
+     *  the host, all further frames will be transmitted at the new
+     *  bitrate.
+     */
+    SPINEL_PROP_UART_BITRATE    = 0x100,
+
+    /// UART Software Flow Control
+    /** Format: `b`
+     *
+     *  If the NCP is using a UART to communicate with the host,
+     *  this property allows the host to determine if software flow
+     *  control (XON/XOFF style) should be used and (optionally) to
+     *  turn it on or off.
+     *
+     *  This property is only implemented when a UART is being
+     *  used for Spinel. This property is optional.
+     */
+    SPINEL_PROP_UART_XON_XOFF   = 0x101,
+
+    SPINEL_PROP_15_4_PIB__BEGIN     = 1024,
+    // For direct access to the 802.15.4 PID.
+    // Individual registers are fetched using
+    // `SPINEL_PROP_15_4_PIB__BEGIN+[PIB_IDENTIFIER]`
+    // Only supported if SPINEL_CAP_15_4_PIB is set.
+    //
+    // For brevity, the entire 802.15.4 PIB space is
+    // not defined here, but a few choice attributes
+    // are defined for illustration and convenience.
+    SPINEL_PROP_15_4_PIB_PHY_CHANNELS_SUPPORTED = SPINEL_PROP_15_4_PIB__BEGIN + 0x01, ///< [A(L)]
+    SPINEL_PROP_15_4_PIB_MAC_PROMISCUOUS_MODE   = SPINEL_PROP_15_4_PIB__BEGIN + 0x51, ///< [b]
+    SPINEL_PROP_15_4_PIB_MAC_SECURITY_ENABLED   = SPINEL_PROP_15_4_PIB__BEGIN + 0x5d, ///< [b]
+    SPINEL_PROP_15_4_PIB__END       = 1280,
+
+    SPINEL_PROP_CNTR__BEGIN        = 1280,
+
+    /// Counter reset behavior
+    /** Format: `C`
+     *  Writing a '1' to this property will reset
+     *  all of the counters to zero. */
+    SPINEL_PROP_CNTR_RESET             = SPINEL_PROP_CNTR__BEGIN + 0,
+
+    /// The total number of transmissions.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_TOTAL      = SPINEL_PROP_CNTR__BEGIN + 1,
+
+    /// The number of transmissions with ack request.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_ACK_REQ    = SPINEL_PROP_CNTR__BEGIN + 2,
+
+    /// The number of transmissions that were acked.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_ACKED      = SPINEL_PROP_CNTR__BEGIN + 3,
+
+    /// The number of transmissions without ack request.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_NO_ACK_REQ = SPINEL_PROP_CNTR__BEGIN + 4,
+
+    /// The number of transmitted data.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_DATA       = SPINEL_PROP_CNTR__BEGIN + 5,
+
+    /// The number of transmitted data poll.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_DATA_POLL  = SPINEL_PROP_CNTR__BEGIN + 6,
+
+    /// The number of transmitted beacon.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_BEACON     = SPINEL_PROP_CNTR__BEGIN + 7,
+
+    /// The number of transmitted beacon request.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_BEACON_REQ = SPINEL_PROP_CNTR__BEGIN + 8,
+
+    /// The number of transmitted other types of frames.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_OTHER      = SPINEL_PROP_CNTR__BEGIN + 9,
+
+    /// The number of retransmission times.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_RETRY      = SPINEL_PROP_CNTR__BEGIN + 10,
+
+    /// The number of CCA failure times.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_ERR_CCA        = SPINEL_PROP_CNTR__BEGIN + 11,
+
+    /// The number of unicast packets transmitted.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_UNICAST    = SPINEL_PROP_CNTR__BEGIN + 12,
+
+    /// The number of broadcast packets transmitted.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_PKT_BROADCAST  = SPINEL_PROP_CNTR__BEGIN + 13,
+
+    /// The number of frame transmission failures due to abort error.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_ERR_ABORT      = SPINEL_PROP_CNTR__BEGIN + 14,
+
+    /// The total number of received packets.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_TOTAL      = SPINEL_PROP_CNTR__BEGIN + 100,
+
+    /// The number of received data.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_DATA       = SPINEL_PROP_CNTR__BEGIN + 101,
+
+    /// The number of received data poll.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_DATA_POLL  = SPINEL_PROP_CNTR__BEGIN + 102,
+
+    /// The number of received beacon.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_BEACON     = SPINEL_PROP_CNTR__BEGIN + 103,
+
+    /// The number of received beacon request.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_BEACON_REQ = SPINEL_PROP_CNTR__BEGIN + 104,
+
+    /// The number of received other types of frames.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_OTHER      = SPINEL_PROP_CNTR__BEGIN + 105,
+
+    /// The number of received packets filtered by whitelist.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_FILT_WL    = SPINEL_PROP_CNTR__BEGIN + 106,
+
+    /// The number of received packets filtered by destination check.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_FILT_DA    = SPINEL_PROP_CNTR__BEGIN + 107,
+
+    /// The number of received packets that are empty.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_ERR_EMPTY      = SPINEL_PROP_CNTR__BEGIN + 108,
+
+    /// The number of received packets from an unknown neighbor.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_ERR_UKWN_NBR   = SPINEL_PROP_CNTR__BEGIN + 109,
+
+    /// The number of received packets whose source address is invalid.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_ERR_NVLD_SADDR = SPINEL_PROP_CNTR__BEGIN + 110,
+
+    /// The number of received packets with a security error.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_ERR_SECURITY   = SPINEL_PROP_CNTR__BEGIN + 111,
+
+    /// The number of received packets with a checksum error.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_ERR_BAD_FCS    = SPINEL_PROP_CNTR__BEGIN + 112,
+
+    /// The number of received packets with other errors.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_ERR_OTHER      = SPINEL_PROP_CNTR__BEGIN + 113,
+
+    /// The number of received duplicated.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_DUP        = SPINEL_PROP_CNTR__BEGIN + 114,
+
+    /// The number of unicast packets recived.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_UNICAST    = SPINEL_PROP_CNTR__BEGIN + 115,
+
+    /// The number of broadcast packets recived.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_PKT_BROADCAST  = SPINEL_PROP_CNTR__BEGIN + 116,
+
+    /// The total number of secure transmitted IP messages.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_IP_SEC_TOTAL   = SPINEL_PROP_CNTR__BEGIN + 200,
+
+    /// The total number of insecure transmitted IP messages.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_IP_INSEC_TOTAL = SPINEL_PROP_CNTR__BEGIN + 201,
+
+    /// The number of dropped (not transmitted) IP messages.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_IP_DROPPED     = SPINEL_PROP_CNTR__BEGIN + 202,
+
+    /// The total number of secure received IP message.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_IP_SEC_TOTAL   = SPINEL_PROP_CNTR__BEGIN + 203,
+
+    /// The total number of insecure received IP message.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_IP_INSEC_TOTAL = SPINEL_PROP_CNTR__BEGIN + 204,
+
+    /// The number of dropped received IP messages.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_IP_DROPPED     = SPINEL_PROP_CNTR__BEGIN + 205,
+
+    /// The number of transmitted spinel frames.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_TX_SPINEL_TOTAL   = SPINEL_PROP_CNTR__BEGIN + 300,
+
+    /// The number of received spinel frames.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_SPINEL_TOTAL   = SPINEL_PROP_CNTR__BEGIN + 301,
+
+    /// The number of received spinel frames with error.
+    /** Format: `L` (Read-only) */
+    SPINEL_PROP_CNTR_RX_SPINEL_ERR     = SPINEL_PROP_CNTR__BEGIN + 302,
+
+
+
+    /// The message buffer counter info
+    /** Format: `T(SSSSSSSSSSSSSSSS)` (Read-only)
+     *  `T(`
+     *      `S`, (TotalBuffers)           The number of buffers in the pool.
+     *      `S`, (FreeBuffers)            The number of free message buffers.
+     *      `S`, (6loSendMessages)        The number of messages in the 6lo send queue.
+     *      `S`, (6loSendBuffers)         The number of buffers in the 6lo send queue.
+     *      `S`, (6loReassemblyMessages)  The number of messages in the 6LoWPAN reassembly queue.
+     *      `S`, (6loReassemblyBuffers)   The number of buffers in the 6LoWPAN reassembly queue.
+     *      `S`, (Ip6Messages)            The number of messages in the IPv6 send queue.
+     *      `S`, (Ip6Buffers)             The number of buffers in the IPv6 send queue.
+     *      `S`, (MplMessages)            The number of messages in the MPL send queue.
+     *      `S`, (MplBuffers)             The number of buffers in the MPL send queue.
+     *      `S`, (MleMessages)            The number of messages in the MLE send queue.
+     *      `S`, (MleBuffers)             The number of buffers in the MLE send queue.
+     *      `S`, (ArpMessages)            The number of messages in the ARP send queue.
+     *      `S`, (ArpBuffers)             The number of buffers in the ARP send queue.
+     *      `S`, (CoapClientMessages)     The number of messages in the CoAP client send queue.
+     *      `S`, (CoapClientBuffers)      The number of buffers in the CoAP client send queue.
+     *  `)`
+     */
+    SPINEL_PROP_MSG_BUFFER_COUNTERS    = SPINEL_PROP_CNTR__BEGIN + 400,
+
+    SPINEL_PROP_CNTR__END       = 2048,
+
+    SPINEL_PROP_NEST__BEGIN         = 15296,
+    SPINEL_PROP_NEST_STREAM_MFG     = SPINEL_PROP_NEST__BEGIN + 0,
+
+    /// The legacy network ULA prefix (8 bytes)
+    /** Format: 'D' */
+    SPINEL_PROP_NEST_LEGACY_ULA_PREFIX
+                                    = SPINEL_PROP_NEST__BEGIN + 1,
+
+    /// A (newly) joined legacy node (this is signaled from NCP)
+    /** Format: 'E' */
+    SPINEL_PROP_NEST_LEGACY_JOINED_NODE
+                                    = SPINEL_PROP_NEST__BEGIN + 2,
+
+    SPINEL_PROP_NEST__END           = 15360,
+
+    SPINEL_PROP_VENDOR__BEGIN       = 15360,
+    SPINEL_PROP_VENDOR__END         = 16384,
+
+    SPINEL_PROP_EXPERIMENTAL__BEGIN = 2000000,
+    SPINEL_PROP_EXPERIMENTAL__END   = 2097152,
+} spinel_prop_key_t;
+
+// ----------------------------------------------------------------------------
+
+#define SPINEL_HEADER_FLAG               0x80
+
+#define SPINEL_HEADER_TID_SHIFT          0
+#define SPINEL_HEADER_TID_MASK           (15 << SPINEL_HEADER_TID_SHIFT)
+
+#define SPINEL_HEADER_IID_SHIFT          4
+#define SPINEL_HEADER_IID_MASK           (3 << SPINEL_HEADER_IID_SHIFT)
+
+#define SPINEL_HEADER_IID_0              (0 << SPINEL_HEADER_IID_SHIFT)
+#define SPINEL_HEADER_IID_1              (1 << SPINEL_HEADER_IID_SHIFT)
+#define SPINEL_HEADER_IID_2              (2 << SPINEL_HEADER_IID_SHIFT)
+#define SPINEL_HEADER_IID_3              (3 << SPINEL_HEADER_IID_SHIFT)
+
+#define SPINEL_HEADER_GET_IID(x)            (((x) & SPINEL_HEADER_IID_MASK) >> SPINEL_HEADER_IID_SHIFT)
+#define SPINEL_HEADER_GET_TID(x)            (spinel_tid_t)(((x)&SPINEL_HEADER_TID_MASK)>>SPINEL_HEADER_TID_SHIFT)
+
+#define SPINEL_GET_NEXT_TID(x)      (spinel_tid_t)((x)>=0xF?1:(x)+1)
+
+#define SPINEL_BEACON_THREAD_FLAG_VERSION_SHIFT 4
+#define SPINEL_BEACON_THREAD_FLAG_VERSION_MASK  (0xf << SPINEL_BEACON_THREAD_FLAG_VERSION_SHIFT)
+#define SPINEL_BEACON_THREAD_FLAG_JOINABLE      (1 << 0)
+#define SPINEL_BEACON_THREAD_FLAG_NATIVE        (1 << 3)
+
+// ----------------------------------------------------------------------------
+
+enum
+{
+    SPINEL_DATATYPE_NULL_C        = 0,
+    SPINEL_DATATYPE_VOID_C        = '.',
+    SPINEL_DATATYPE_BOOL_C        = 'b',
+    SPINEL_DATATYPE_UINT8_C       = 'C',
+    SPINEL_DATATYPE_INT8_C        = 'c',
+    SPINEL_DATATYPE_UINT16_C      = 'S',
+    SPINEL_DATATYPE_INT16_C       = 's',
+    SPINEL_DATATYPE_UINT32_C      = 'L',
+    SPINEL_DATATYPE_INT32_C       = 'l',
+    SPINEL_DATATYPE_UINT_PACKED_C = 'i',
+    SPINEL_DATATYPE_IPv6ADDR_C    = '6',
+    SPINEL_DATATYPE_EUI64_C       = 'E',
+    SPINEL_DATATYPE_EUI48_C       = 'e',
+    SPINEL_DATATYPE_DATA_C        = 'D',
+    SPINEL_DATATYPE_UTF8_C        = 'U', //!< Zero-Terminated UTF8-Encoded String
+    SPINEL_DATATYPE_STRUCT_C      = 'T',
+    SPINEL_DATATYPE_ARRAY_C       = 'A',
+};
+
+typedef char spinel_datatype_t;
+
+#define SPINEL_DATATYPE_NULL_S        ""
+#define SPINEL_DATATYPE_VOID_S        "."
+#define SPINEL_DATATYPE_BOOL_S        "b"
+#define SPINEL_DATATYPE_UINT8_S       "C"
+#define SPINEL_DATATYPE_INT8_S        "c"
+#define SPINEL_DATATYPE_UINT16_S      "S"
+#define SPINEL_DATATYPE_INT16_S       "s"
+#define SPINEL_DATATYPE_UINT32_S      "L"
+#define SPINEL_DATATYPE_INT32_S       "l"
+#define SPINEL_DATATYPE_UINT_PACKED_S "i"
+#define SPINEL_DATATYPE_IPv6ADDR_S    "6"
+#define SPINEL_DATATYPE_EUI64_S       "E"
+#define SPINEL_DATATYPE_EUI48_S       "e"
+#define SPINEL_DATATYPE_DATA_S        "D"
+#define SPINEL_DATATYPE_UTF8_S        "U" //!< Zero-Terminated UTF8-Encoded String
+#define SPINEL_DATATYPE_STRUCT_S      "T"
+#define SPINEL_DATATYPE_ARRAY_S       "A"
+
+SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_pack(uint8_t *data_out, spinel_size_t data_len,
+                                                      const char *pack_format, ...);
+SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_vpack(uint8_t *data_out, spinel_size_t data_len,
+                                                       const char *pack_format, va_list args);
+SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_unpack(const uint8_t *data_in, spinel_size_t data_len,
+                                                        const char *pack_format, ...);
+SPINEL_API_EXTERN spinel_ssize_t spinel_datatype_vunpack(const uint8_t *data_in, spinel_size_t data_len,
+                                                         const char *pack_format, va_list args);
+
+SPINEL_API_EXTERN spinel_ssize_t spinel_packed_uint_decode(const uint8_t *bytes, spinel_size_t len,
+                                                           unsigned int *value);
+SPINEL_API_EXTERN spinel_ssize_t spinel_packed_uint_encode(uint8_t *bytes, spinel_size_t len, unsigned int value);
+SPINEL_API_EXTERN spinel_ssize_t spinel_packed_uint_size(unsigned int value);
+
+SPINEL_API_EXTERN const char *spinel_next_packed_datatype(const char *pack_format);
+
+// ----------------------------------------------------------------------------
+
+SPINEL_API_EXTERN const char *spinel_prop_key_to_cstr(spinel_prop_key_t prop_key);
+
+SPINEL_API_EXTERN const char *spinel_net_role_to_cstr(uint8_t net_role);
+
+SPINEL_API_EXTERN const char *spinel_status_to_cstr(spinel_status_t status);
+
+// ----------------------------------------------------------------------------
+
+__END_DECLS
+
+#endif /* defined(SPINEL_HEADER_INCLUDED) */
diff --git a/third_party/openthread/tools/spi-hdlc-adapter/.gitignore b/third_party/openthread/tools/spi-hdlc-adapter/.gitignore
new file mode 100644
index 0000000..38124e8
--- /dev/null
+++ b/third_party/openthread/tools/spi-hdlc-adapter/.gitignore
@@ -0,0 +1 @@
+spi-hdlc-adapter
diff --git a/third_party/openthread/tools/spi-hdlc-adapter/README.md b/third_party/openthread/tools/spi-hdlc-adapter/README.md
new file mode 100644
index 0000000..fe2c4da
--- /dev/null
+++ b/third_party/openthread/tools/spi-hdlc-adapter/README.md
@@ -0,0 +1,60 @@
+SPI/HDLC Adaptor
+================
+
+`spi-hdlc-adapter` is an adapter tool for using a SPI interface as if
+it were an HDLC-lite encoded bidirectional asynchronous serial stream.
+It uses the SPI protocol outlined in [Appendix A.2][1] of the Spinel
+protocol document.
+
+[1]: https://goo.gl/gt18O4
+
+## Syntax ##
+
+    spi-hdlc-adapter [options] <spi-device-path>
+
+## Options ##
+
+*   `--stdio`: Use `stdin` and `stdout` for HDLC input/output. Useful
+    when directly started by the program that will be using it.
+*   `--pty`: Create a pseudo terminal for HDLC input/output. The path
+    of the newly-created PTY will be written to `stdout`, followed by
+    a newline.
+*   `--gpio-int[=gpio-path]`: Specify a path to the Linux
+    sysfs-exported GPIO directory for the `IÌ…NÌ…TÌ…` pin. If not
+    specified, `spi-hdlc-adapter` will fall back to polling, which is
+    inefficient.
+*   `--gpio-reset[=gpio-path]`: Specify a path to the Linux
+    sysfs-exported GPIO directory for the `RÌ…EÌ…SÌ…` pin.
+*   `--spi-mode[=mode]`: Specify the SPI mode to use (0-3).
+*   `--spi-speed[=hertz]`: Specify the SPI speed in hertz.
+*   `--spi-cs-delay[=usec]`: Specify the delay after CÌ…SÌ… assertion, in
+    microseconds.
+*   `--verbose`: Increase debug verbosity.
+*   `--help`: Print out usage information to `stdout` and exit.
+
+`spi-device-path` is a required argument since it indicates which SPI
+device to use. An example path might be `/dev/spidev1.0`.
+
+The GPIO paths are to the top-level directory for that GPIO. They must
+be already be exported before `spi-hdlc-adapter` can use them.
+
+## Behavior ##
+
+If an MCU reset is detected by the reset bit being set on a SPI frame,
+the special vendor-specific HDLC-lite symbol `0xF8` is emitted. If
+`--gpio-reset` is specified, the HDLC client can trigger an MCU reset
+by sending the symbols `0x7E 0x13 0x11 0x7E` or by sending `SIGUSR1`.
+
+When started, `spi-hdlc-adapter` will configure the following
+properties on the GPIOs:
+
+1.  Set `IÌ…NÌ…TÌ…/direction` to `in`.
+2.  Set `IÌ…NÌ…TÌ…/edge` to `falling`.
+3.  Set `RÌ…EÌ…SÌ…/direction` to `high`.
+
+When resetting the slave device, `spi-hdlc` performs the following
+procedure:
+
+1.  Set `RÌ…EÌ…SÌ…/direction` to `low`.
+2.  Sleep for 30ms.
+3.  Set `RÌ…EÌ…SÌ…/direction` to `high`.
diff --git a/third_party/openthread/tools/spi-hdlc-adapter/spi-hdlc-adapter.c b/third_party/openthread/tools/spi-hdlc-adapter/spi-hdlc-adapter.c
new file mode 100644
index 0000000..11e0ad4
--- /dev/null
+++ b/third_party/openthread/tools/spi-hdlc-adapter/spi-hdlc-adapter.c
@@ -0,0 +1,1702 @@
+/*
+ *    Copyright (c) 2016, The OpenThread Authors.
+ *    All rights reserved.
+ *
+ *    Redistribution and use in source and binary forms, with or without
+ *    modification, are permitted provided that the following conditions are met:
+ *    1. Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *    2. Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *    3. Neither the name of the copyright holder nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
+ *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define _GNU_SOURCE 1
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <syslog.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/select.h>
+#include <sys/ucontext.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+
+#include <linux/spi/spidev.h>
+
+#if HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
+
+#if HAVE_PTY_H
+#include <pty.h>
+#endif
+
+#if HAVE_UTIL_H
+#include <util.h>
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* MARK: Macros and Constants */
+
+#define SPI_HDLC_VERSION                "0.03"
+
+#define MAX_FRAME_SIZE                  2048
+#define HEADER_LEN                      5
+#define SPI_HEADER_RESET_FLAG           0x80
+#define SPI_HEADER_CRC_FLAG             0x40
+#define SPI_HEADER_PATTERN_VALUE        0x02
+#define SPI_HEADER_PATTERN_MASK         0x03
+
+#define EXIT_QUIT                       65535
+
+#ifndef MSEC_PER_SEC
+#define MSEC_PER_SEC                    1000
+#endif
+
+#ifndef USEC_PER_MSEC
+#define USEC_PER_MSEC                   1000
+#endif
+
+#ifndef USEC_PER_SEC
+#define USEC_PER_SEC                    (USEC_PER_MSEC * MSEC_PER_SEC)
+#endif
+
+#define SPI_POLL_PERIOD_MSEC            (MSEC_PER_SEC/30)
+
+#define GPIO_INT_ASSERT_STATE           0 // IÌ…NÌ…TÌ… is asserted low
+#define GPIO_RES_ASSERT_STATE           0 // RÌ…EÌ…SÌ… is asserted low
+
+#define SPI_RX_ALIGN_ALLOWANCE_MAX      3
+
+#define SOCKET_DEBUG_BYTES_PER_LINE     16
+
+#ifndef AUTO_PRINT_BACKTRACE
+#define AUTO_PRINT_BACKTRACE            (HAVE_EXECINFO_H || __APPLE__)
+#endif
+
+#define AUTO_PRINT_BACKTRACE_STACK_DEPTH     20
+
+static const uint8_t kHdlcResetSignal[] = { 0x7E, 0x13, 0x11, 0x7E };
+static const uint16_t kHdlcCrcCheckValue = 0xf0b8;
+static const uint16_t kHdlcCrcResetValue = 0xffff;
+
+enum {
+    MODE_STDIO = 0,
+    MODE_PTY = 1,
+};
+
+// Ignores return value from function 's'
+#define IGNORE_RETURN_VALUE(s)  do { if (s){} } while (0)
+
+/* ------------------------------------------------------------------------- */
+/* MARK: Global State */
+
+#if HAVE_OPENPTY
+static int sMode = MODE_PTY;
+#else
+static int sMode = MODE_STDIO;
+#endif
+
+static const char* sSpiDevPath     = NULL;
+static const char* sIntGpioDevPath = NULL;
+static const char* sResGpioDevPath = NULL;
+
+static int sVerbose             = LOG_NOTICE;
+
+static int sSpiDevFd            = -1;
+static int sResGpioValueFd      = -1;
+static int sIntGpioValueFd      = -1;
+
+static int sHdlcInputFd         = -1;
+static int sHdlcOutputFd        = -1;
+
+static int sSpiSpeed            = 1000000; // in Hz (default: 1MHz)
+static uint8_t sSpiMode         = 0;
+static int sSpiCsDelay          = 20;      // in microseconds
+static int sSpiTransactionDelay = 200;     // in microseconds
+
+static uint16_t sSpiRxPayloadSize;
+static uint8_t sSpiRxFrameBuffer[MAX_FRAME_SIZE + SPI_RX_ALIGN_ALLOWANCE_MAX];
+
+static uint16_t sSpiTxPayloadSize;
+static bool sSpiTxIsReady = false;
+static bool sSpiTxFlowControl = false;
+static uint8_t sSpiTxFrameBuffer[MAX_FRAME_SIZE + SPI_RX_ALIGN_ALLOWANCE_MAX];
+
+static int sSpiRxAlignAllowance = 0;
+
+static uint32_t sSpiFrameCount = 0;
+static uint32_t sSpiValidFrameCount = 0;
+
+static bool sSlaveDidReset = false;
+
+static int sRet = 0;
+
+static sig_t sPreviousHandlerForSIGINT;
+static sig_t sPreviousHandlerForSIGTERM;
+
+/* ------------------------------------------------------------------------- */
+/* MARK: Signal Handlers */
+
+static void signal_SIGINT(int sig)
+{
+    static const char message[] = "\nCaught SIGINT!\n";
+
+    sRet = EXIT_QUIT;
+
+    // Can't use syslog() because it isn't async signal safe.
+    // So we write to stderr
+    IGNORE_RETURN_VALUE(write(STDERR_FILENO, message, sizeof(message)-1));
+
+    // Restore the previous handler so that if we end up getting
+    // this signal again we peform the system default action.
+    signal(SIGINT, sPreviousHandlerForSIGINT);
+    sPreviousHandlerForSIGINT = NULL;
+
+    (void)sig;
+}
+
+static void signal_SIGTERM(int sig)
+{
+    static const char message[] = "\nCaught SIGTERM!\n";
+
+    sRet = EXIT_QUIT;
+
+    // Can't use syslog() because it isn't async signal safe.
+    // So we write to stderr
+    IGNORE_RETURN_VALUE(write(STDERR_FILENO, message, sizeof(message)-1));
+
+    // Restore the previous handler so that if we end up getting
+    // this signal again we perform the system default action.
+    signal(SIGTERM, sPreviousHandlerForSIGTERM);
+    sPreviousHandlerForSIGTERM = NULL;
+    (void) sig;
+}
+
+static void signal_SIGHUP(int sig)
+{
+    static const char message[] = "\nCaught SIGHUP!\n";
+
+    sRet = EXIT_FAILURE;
+
+    // Can't use syslog() because it isn't async signal safe.
+    // So we write to stderr
+    IGNORE_RETURN_VALUE(write(STDERR_FILENO, message, sizeof(message)-1));
+
+    // We don't restore the "previous handler"
+    // because we always want to let the main
+    // loop decide what to do for hangups.
+
+    (void) sig;
+}
+
+#if AUTO_PRINT_BACKTRACE
+static void signal_critical(int sig, siginfo_t * info, void * ucontext)
+{
+    // This is the last hurah for this process.
+    // We dump the stack, because that's all we can do.
+
+    void *stack_mem[AUTO_PRINT_BACKTRACE_STACK_DEPTH];
+    void **stack = stack_mem;
+    char **stack_symbols;
+    int stack_depth, i;
+    ucontext_t *uc = (ucontext_t*)ucontext;
+
+    // Shut up compiler warning.
+    (void)uc;
+    (void)info;
+
+    // We call some functions here which aren't async-signal-safe,
+    // but this function isn't really useful without those calls.
+    // Since we are making a gamble (and we deadlock if we loose),
+    // we are going to set up a two-second watchdog to make sure
+    // we end up terminating like we should. The choice of a two
+    // second timeout is entirely arbitrary, and may be changed
+    // if needs warrant.
+    alarm(2);
+    signal(SIGALRM, SIG_DFL);
+
+    fprintf(stderr, " *** FATAL ERROR: Caught signal %d (%s):\n", sig, strsignal(sig));
+
+    stack_depth = backtrace(stack, AUTO_PRINT_BACKTRACE_STACK_DEPTH);
+
+    // Here are are trying to update the pointer in the backtrace
+    // to be the actual location of the fault.
+#if defined(__x86_64__)
+    stack[1] = (void *) uc->uc_mcontext.gregs[REG_RIP];
+#elif defined(__i386__)
+    stack[1] = (void *) uc->uc_mcontext.gregs[REG_EIP];
+#elif defined(__arm__)
+    stack[1] = (void *) uc->uc_mcontext.arm_ip;
+#else
+#warning TODO: Add this arch to signal_critical
+#endif
+
+    // Now dump the symbols to stderr, in case syslog barfs.
+    backtrace_symbols_fd(stack, stack_depth, STDERR_FILENO);
+
+    // Load up the symbols individually, so we can output to syslog, too.
+    stack_symbols = backtrace_symbols(stack, stack_depth);
+
+    syslog(LOG_CRIT, " *** FATAL ERROR: Caught signal %d (%s):", sig, strsignal(sig));
+
+    for (i = 0; i != stack_depth; i++)
+    {
+        syslog(LOG_CRIT, "[BT] %2d: %s", i, stack_symbols[i]);
+    }
+
+    free(stack_symbols);
+
+    exit(EXIT_FAILURE);
+}
+#endif // if AUTO_PRINT_BACKTRACE
+
+static void log_debug_buffer(const char* desc, const uint8_t* buffer_ptr, int buffer_len)
+{
+    int i = 0;
+
+    if (sVerbose < LOG_DEBUG)
+    {
+        return;
+    }
+
+    while (i < buffer_len)
+    {
+        int j;
+        char dump_string[SOCKET_DEBUG_BYTES_PER_LINE*3+1];
+
+        for (j = 0; i < buffer_len && j < SOCKET_DEBUG_BYTES_PER_LINE; i++, j++)
+        {
+            sprintf(dump_string+j*3, "%02X ", buffer_ptr[i]);
+        }
+
+        syslog(LOG_DEBUG, "%s: %s%s", desc, dump_string, (i < buffer_len)?" ...":"");
+    }
+}
+
+/* ------------------------------------------------------------------------- */
+/* MARK: SPI Transfer Functions */
+
+static void spi_header_set_flag_byte(uint8_t *header, uint8_t value)
+{
+    header[0] = value;
+}
+
+static void spi_header_set_accept_len(uint8_t *header, uint16_t len)
+{
+    header[1] = ((len >> 0) & 0xFF);
+    header[2] = ((len >> 8) & 0xFF);
+}
+
+static void spi_header_set_data_len(uint8_t *header, uint16_t len)
+{
+    header[3] = ((len >> 0) & 0xFF);
+    header[4] = ((len >> 8) & 0xFF);
+}
+
+static uint8_t spi_header_get_flag_byte(const uint8_t *header)
+{
+    return header[0];
+}
+
+static uint16_t spi_header_get_accept_len(const uint8_t *header)
+{
+    return ( header[1] + (uint16_t)(header[2] << 8) );
+}
+
+static uint16_t spi_header_get_data_len(const uint8_t *header)
+{
+    return ( header[3] + (uint16_t)(header[4] << 8) );
+}
+
+static uint8_t* get_real_rx_frame_start(void)
+{
+    uint8_t* ret = sSpiRxFrameBuffer;
+    int i = 0;
+
+    for (i = 0; i < sSpiRxAlignAllowance; i++)
+    {
+        if (ret[0] != 0xFF)
+        {
+            break;
+        }
+        ret++;
+    }
+
+    return ret;
+}
+
+static int do_spi_xfer(int len)
+ {
+    int ret;
+
+    struct spi_ioc_transfer xfer[2] =
+    {
+        {   // This part is the delay between CÌ…SÌ… being
+            // asserted and the SPI clock starting. This
+            // is not supported by all Linux SPI drivers.
+            .tx_buf = 0,
+            .rx_buf = 0,
+            .len = 0,
+            .delay_usecs = (uint16_t)sSpiCsDelay,
+            .speed_hz = (uint32_t)sSpiSpeed,
+            .bits_per_word = 8,
+            .cs_change = false,
+        },
+        {   // This part is the actual SPI transfer.
+            .tx_buf = (unsigned long)sSpiTxFrameBuffer,
+            .rx_buf = (unsigned long)sSpiRxFrameBuffer,
+            .len = (uint32_t)(len + HEADER_LEN + sSpiRxAlignAllowance),
+            .delay_usecs = 0,
+            .speed_hz = (uint32_t)sSpiSpeed,
+            .bits_per_word = 8,
+            .cs_change = false,
+        }
+    };
+
+    if (sSpiCsDelay > 0)
+    {
+        // A CÌ…SÌ… delay has been specified. Start transactions
+        // with both parts.
+        ret = ioctl(sSpiDevFd, SPI_IOC_MESSAGE(2), &xfer[0]);
+    }
+    else
+    {
+        // No CÌ…SÌ… delay has been specified, so we skip the first
+        // part because it causes some SPI drivers to croak.
+        ret = ioctl(sSpiDevFd, SPI_IOC_MESSAGE(1), &xfer[1]);
+    }
+
+    if (ret != -1)
+    {
+        log_debug_buffer("SPI-TX", sSpiTxFrameBuffer, (int)xfer[1].len);
+        log_debug_buffer("SPI-RX", sSpiRxFrameBuffer, (int)xfer[1].len);
+
+        if (spi_header_get_flag_byte(sSpiRxFrameBuffer) != 0xFF)
+        {
+            if (spi_header_get_flag_byte(sSpiRxFrameBuffer) & SPI_HEADER_RESET_FLAG)
+            {
+                sSlaveDidReset = true;
+            }
+        }
+
+        sSpiFrameCount++;
+    }
+
+    return ret;
+}
+
+static void debug_spi_header(const char* hint)
+{
+    if (sVerbose >= LOG_DEBUG)
+    {
+        const uint8_t* spiRxFrameBuffer = get_real_rx_frame_start();
+
+        syslog(LOG_DEBUG, "%s-TX: H:%02X ACCEPT:%d DATA:%0d\n",
+            hint,
+            spi_header_get_flag_byte(sSpiTxFrameBuffer),
+            spi_header_get_accept_len(sSpiTxFrameBuffer),
+            spi_header_get_data_len(sSpiTxFrameBuffer)
+        );
+
+        syslog(LOG_DEBUG, "%s-RX: H:%02X ACCEPT:%d DATA:%0d\n",
+            hint,
+            spi_header_get_flag_byte(spiRxFrameBuffer),
+            spi_header_get_accept_len(spiRxFrameBuffer),
+            spi_header_get_data_len(spiRxFrameBuffer)
+        );
+    }
+}
+
+static int push_pull_spi(void)
+{
+    int ret;
+    uint8_t slave_header;
+    uint16_t slave_max_rx;
+    uint16_t slave_data_len;
+    uint16_t spi_xfer_bytes = 5;
+    const uint8_t* spiRxFrameBuffer = NULL;
+
+    sSpiTxFlowControl = false;
+
+    /// -- FIRST TRANSACTION --------------------------------------------------
+
+    // The purpose of the first transaction is to attempt to
+    // send any transactions we have queued and fetch the slave's
+    // buffer sizes.
+
+    if (sSpiValidFrameCount == 0)
+    {
+        spi_header_set_flag_byte(sSpiTxFrameBuffer, SPI_HEADER_RESET_FLAG|SPI_HEADER_PATTERN_VALUE);
+    }
+    else
+    {
+        spi_header_set_flag_byte(sSpiTxFrameBuffer, SPI_HEADER_PATTERN_VALUE);
+    }
+
+    // Zero out our max rx and data len
+    // so that the slave doesn't think
+    // we are actually trying to transfer
+    // data.
+    spi_header_set_accept_len(sSpiTxFrameBuffer, 0);
+    spi_header_set_data_len(sSpiTxFrameBuffer, 0);
+
+    if (sSpiTxIsReady)
+    {
+        // Go ahead and try to immediately send a frame if we have it queued up.
+        spi_header_set_data_len(sSpiTxFrameBuffer, sSpiTxPayloadSize);
+
+        if (sSpiTxPayloadSize > spi_xfer_bytes)
+        {
+            spi_xfer_bytes = sSpiTxPayloadSize;
+        }
+    }
+
+    // If we aren't already processing a received frame, we
+    // can also handle receiving the next frame if its length
+    // is equal to or less than the size of what we are
+    // trying to transmit above.
+    if (sSpiRxPayloadSize == 0) {
+        spi_header_set_accept_len(sSpiTxFrameBuffer, spi_xfer_bytes);
+    }
+
+    // Perform the first SPI transaction.
+    ret = do_spi_xfer(spi_xfer_bytes);
+    if (ret < 0)
+    {
+        perror("do_spi_xfer");
+
+        // Print out a helpful error message for
+        // a common error.
+        if ( (sSpiCsDelay != 0)
+          && (errno == EINVAL)
+        ) {
+            syslog(LOG_ERR, "SPI ioctl failed with EINVAL. Try adding `--spi-cs-delay=0` to command line arguments.");
+        }
+        goto bail;
+    }
+
+    // Account for misalignment (0xFF bytes at the start)
+    spiRxFrameBuffer = get_real_rx_frame_start();
+
+    debug_spi_header("push_pull_1");
+
+    slave_header = spi_header_get_flag_byte(spiRxFrameBuffer);
+
+    if ((slave_header == 0xFF) || (slave_header == 0x00))
+    {
+        // Device is off or in a bad state.
+        sSpiTxFlowControl = true;
+
+        syslog(LOG_DEBUG, "Discarded frame. (1)");
+        goto bail;
+    }
+
+    slave_max_rx = spi_header_get_accept_len(spiRxFrameBuffer);
+    slave_data_len = spi_header_get_data_len(spiRxFrameBuffer);
+
+    if ( ((slave_header & SPI_HEADER_PATTERN_MASK) != SPI_HEADER_PATTERN_VALUE)
+      || (slave_max_rx > MAX_FRAME_SIZE)
+      || (slave_data_len > MAX_FRAME_SIZE)
+    )
+    {
+        sSpiTxFlowControl = true;
+        syslog(
+            LOG_INFO,
+            "Gibberish in header (h:0x%02X, max_rx:0x%04X, data_len:0x%04X)",
+            slave_header,
+            slave_max_rx,
+            slave_data_len
+        );
+        goto bail;
+    }
+
+    sSpiValidFrameCount++;
+
+    // Handle received packet, if any.
+    if ( (sSpiRxPayloadSize == 0)
+      && (slave_data_len != 0)
+      && (slave_data_len <= spi_header_get_accept_len(sSpiTxFrameBuffer))
+    ) {
+        // We have received a packet. Set sSpiRxPayloadSize so that
+        // the packet will eventually get queued up by push_hdlc().
+        sSpiRxPayloadSize = slave_data_len;
+
+        slave_data_len = 0;
+    }
+
+    if (sSpiTxIsReady)
+    {
+        // Handle transmitted packet.
+        if (spi_header_get_data_len(sSpiTxFrameBuffer) <= slave_max_rx)
+        {
+            // Outbound packet has been successfully transmitted. Clear
+            // sSpiTxPayloadSize and sSpiTxIsReady so that pull_hdlc() can
+            // pull another packet for us to send.
+            sSpiTxIsReady = false;
+            sSpiTxPayloadSize = 0;
+            spi_header_set_data_len(sSpiTxFrameBuffer, 0);
+            spi_xfer_bytes = 0;
+        } else {
+            // The slave Wasn't ready for what we had to
+            // send them. Turn on rate limiting so that we
+            // don't waste a ton of CPU bombarding them
+            // with useless SPI transfers.
+            sSpiTxFlowControl = true;
+        }
+    }
+
+    if (slave_data_len == 0)
+    {
+        // Nothing else to do.
+        goto bail;
+    }
+
+    /// -- SECOND TRANSACTION ------------------------------------------------
+
+    // The purpose of the second transaction is to attempt to
+    // fetch any packets that the slave has for us that didn't
+    // fit in the first transaction.
+
+    spi_header_set_flag_byte(sSpiTxFrameBuffer, SPI_HEADER_PATTERN_VALUE);
+    spi_header_set_accept_len(sSpiTxFrameBuffer, 0);
+
+    if (sSpiTxIsReady)
+    {
+        spi_xfer_bytes = sSpiTxPayloadSize;
+        spi_header_set_data_len(sSpiTxFrameBuffer, sSpiTxPayloadSize);
+
+    } else {
+        spi_xfer_bytes = 0;
+    }
+
+    if ( (slave_data_len != 0)
+      && (sSpiRxPayloadSize == 0)
+    )
+    {
+        spi_header_set_accept_len(sSpiTxFrameBuffer, slave_data_len);
+        if (slave_data_len > spi_xfer_bytes)
+        {
+            spi_xfer_bytes = slave_data_len;
+        }
+    }
+
+    // Optionally delay a short period to give
+    // the slave time to get its affairs in order.
+    usleep((unsigned int)sSpiTransactionDelay);
+
+    // Perform the second SPI transaction.
+    ret = do_spi_xfer(spi_xfer_bytes);
+    if (ret < 0)
+    {
+        perror("do_spi_xfer");
+
+        // Print out a helpful error message for
+        // a common error.
+        if ( (sSpiCsDelay != 0)
+          && (errno == EINVAL)
+        ) {
+            syslog(LOG_ERR, "SPI ioctl failed with EINVAL. Try adding `--spi-cs-delay=0` to command line arguments.");
+        }
+        goto bail;
+    }
+
+    // Account for misalignment (0xFF bytes at the start)
+    spiRxFrameBuffer = get_real_rx_frame_start();
+
+    debug_spi_header("push_pull_2");
+
+    slave_header = spi_header_get_flag_byte(spiRxFrameBuffer);
+
+    if ((slave_header == 0xFF) || (slave_header == 0x00))
+    {
+        // Device is off or in a bad state.
+        sSpiTxFlowControl = true;
+
+        syslog(LOG_DEBUG, "Discarded frame. (2)");
+        goto bail;
+    }
+
+    slave_max_rx = spi_header_get_accept_len(spiRxFrameBuffer);
+    slave_data_len = spi_header_get_data_len(spiRxFrameBuffer);
+
+    if ( (slave_header != SPI_HEADER_PATTERN_VALUE)
+      || (slave_max_rx > MAX_FRAME_SIZE)
+      || (slave_data_len > MAX_FRAME_SIZE)
+    )
+    {
+        sSpiTxFlowControl = true;
+        syslog(
+            LOG_INFO,
+            "Gibberish in header (h:0x%02X, max_rx:0x%04X, data_len:0x%04X) (2)",
+            slave_header,
+            slave_max_rx,
+            slave_data_len
+        );
+        goto bail;
+    }
+
+    sSpiValidFrameCount++;
+
+    if ( (sSpiRxPayloadSize == 0)
+      && (slave_data_len <= spi_header_get_accept_len(sSpiTxFrameBuffer))
+    ) {
+        // We have received a packet. Set sSpiRxPayloadSize so that
+        // the packet will eventually get queued up by push_hdlc().
+        sSpiRxPayloadSize = slave_data_len;
+    }
+
+    if ( (sSpiTxPayloadSize == spi_header_get_data_len(sSpiTxFrameBuffer))
+      && (spi_header_get_data_len(sSpiTxFrameBuffer) <= slave_max_rx)
+    ) {
+        // Out outbound packet has been successfully transmitted. Clear
+        // sSpiTxPayloadSize and sSpiTxIsReady so that pull_hdlc() can
+        // pull another packet for us to send.
+        sSpiTxIsReady = false;
+        sSpiTxPayloadSize = 0;
+        sSpiTxFlowControl = false;
+    }
+
+bail:
+    return ret;
+}
+
+static bool check_and_clear_interrupt(void)
+{
+    char value[5] = "";
+    ssize_t len;
+
+    lseek(sIntGpioValueFd, 0, SEEK_SET);
+
+    len = read(sIntGpioValueFd, value, sizeof(value)-1);
+
+    if (len < 0)
+    {
+        perror("check_and_clear_interrupt");
+        sRet = EXIT_FAILURE;
+    }
+
+    // The interrupt pin is active low.
+    return GPIO_INT_ASSERT_STATE == atoi(value);
+}
+
+/* ------------------------------------------------------------------------- */
+/* MARK: HDLC Transfer Functions */
+
+#define HDLC_BYTE_FLAG             0x7E
+#define HDLC_BYTE_ESC              0x7D
+#define HDLC_BYTE_XON              0x11
+#define HDLC_BYTE_XOFF             0x13
+#define HDLC_BYTE_SPECIAL          0xF8
+#define HDLC_ESCAPE_XFORM          0x20
+
+static uint16_t hdlc_crc16(uint16_t aFcs, uint8_t aByte)
+{
+#if 1
+    // CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-CCITT
+    // width=16 poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 check=0x2189 name="KERMIT"
+    // http://reveng.sourceforge.net/crc-catalogue/16.htm#crc.cat.kermit
+    static const uint16_t sFcsTable[256] =
+    {
+        0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
+        0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
+        0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
+        0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
+        0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
+        0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
+        0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
+        0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
+        0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
+        0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
+        0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
+        0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
+        0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
+        0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
+        0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
+        0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
+        0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
+        0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
+        0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
+        0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
+        0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
+        0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
+        0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
+        0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
+        0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
+        0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
+        0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
+        0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
+        0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
+        0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
+        0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
+        0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
+    };
+    return (aFcs >> 8) ^ sFcsTable[(aFcs ^ aByte) & 0xff];
+#else
+    // CRC-16/CCITT-FALSE, same CRC as 802.15.4
+    // width=16 poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 name="CRC-16/CCITT-FALSE"
+    // http://reveng.sourceforge.net/crc-catalogue/16.htm#crc.cat.crc-16-ccitt-false
+    aFcs = (uint16_t)((aFcs >> 8) | (aFcs << 8));
+    aFcs ^= aByte;
+    aFcs ^= ((aFcs & 0xff) >> 4);
+    aFcs ^= (aFcs << 12);
+    aFcs ^= ((aFcs & 0xff) << 5);
+    return aFcs;
+#endif
+}
+
+static bool hdlc_byte_needs_escape(uint8_t byte)
+{
+    switch(byte)
+    {
+    case HDLC_BYTE_SPECIAL:
+    case HDLC_BYTE_ESC:
+    case HDLC_BYTE_FLAG:
+    case HDLC_BYTE_XOFF:
+    case HDLC_BYTE_XON:
+        return true;
+
+    default:
+        return false;
+    }
+}
+
+static int push_hdlc(void)
+{
+    int ret = 0;
+    const uint8_t* spiRxFrameBuffer = get_real_rx_frame_start();
+    static uint8_t escaped_frame_buffer[MAX_FRAME_SIZE*2];
+    static uint16_t escaped_frame_len;
+    static uint16_t escaped_frame_sent;
+
+    if (escaped_frame_len == 0)
+    {
+        if (sSlaveDidReset)
+        {
+            // Indicate an MCU reset.
+            memcpy(escaped_frame_buffer, kHdlcResetSignal, sizeof(kHdlcResetSignal));
+            escaped_frame_len = sizeof(kHdlcResetSignal);
+            sSlaveDidReset = false;
+        }
+        else if (sSpiRxPayloadSize != 0)
+        {
+            // Escape the frame.
+            uint8_t c;
+            uint16_t fcs = kHdlcCrcResetValue;
+            uint16_t i;
+
+            for (i = 0; i < sSpiRxPayloadSize; i++)
+            {
+                c = spiRxFrameBuffer[i + HEADER_LEN];
+                fcs = hdlc_crc16(fcs, c);
+                if (hdlc_byte_needs_escape(c))
+                {
+                    escaped_frame_buffer[escaped_frame_len++] = HDLC_BYTE_ESC;
+                    escaped_frame_buffer[escaped_frame_len++] = c ^ HDLC_ESCAPE_XFORM;
+                }
+                else
+                {
+                    escaped_frame_buffer[escaped_frame_len++] = c;
+                }
+            }
+
+            fcs ^= 0xFFFF;
+
+            c = fcs & 0xFF;
+            if (hdlc_byte_needs_escape(c))
+            {
+                escaped_frame_buffer[escaped_frame_len++] = HDLC_BYTE_ESC;
+                escaped_frame_buffer[escaped_frame_len++] = c ^ HDLC_ESCAPE_XFORM;
+            }
+            else
+            {
+                escaped_frame_buffer[escaped_frame_len++] = c;
+            }
+
+            c = (fcs >> 8) & 0xFF;
+            if (hdlc_byte_needs_escape(c))
+            {
+                escaped_frame_buffer[escaped_frame_len++] = HDLC_BYTE_ESC;
+                escaped_frame_buffer[escaped_frame_len++] = c ^ HDLC_ESCAPE_XFORM;
+            }
+            else
+            {
+                escaped_frame_buffer[escaped_frame_len++] = c;
+            }
+
+            escaped_frame_buffer[escaped_frame_len++] = HDLC_BYTE_FLAG;
+            escaped_frame_sent = 0;
+            sSpiRxPayloadSize = 0;
+
+        }
+        else
+        {
+            // Nothing to do.
+            goto bail;
+        }
+    }
+
+    ret = (int)write(
+        sHdlcOutputFd,
+        escaped_frame_buffer + escaped_frame_sent,
+        escaped_frame_len    - escaped_frame_sent
+    );
+
+    if (ret < 0)
+    {
+        if (errno == EAGAIN)
+        {
+            ret = 0;
+        }
+        else
+        {
+            perror("push_hdlc:write");
+            syslog(LOG_ERR, "push_hdlc:write: errno=%d (%s)", errno, strerror(errno));
+        }
+        goto bail;
+    }
+
+    escaped_frame_sent += ret;
+
+    // Reset state once we have sent the entire frame.
+    if (escaped_frame_len == escaped_frame_sent)
+    {
+        escaped_frame_len = escaped_frame_sent = 0;
+    }
+
+    ret = 0;
+
+bail:
+    return ret;
+}
+
+static int pull_hdlc(void)
+{
+    int ret = 0;
+    static uint16_t fcs;
+    static bool unescape_next_byte = false;
+
+    if (!sSpiTxIsReady)
+    {
+        uint8_t byte;
+        while ((ret = (int)read(sHdlcInputFd, &byte, 1)) == 1)
+        {
+            if (sSpiTxPayloadSize >= (MAX_FRAME_SIZE - HEADER_LEN))
+            {
+                syslog(LOG_WARNING, "HDLC frame was too big");
+                unescape_next_byte = false;
+                sSpiTxPayloadSize = 0;
+                fcs = kHdlcCrcResetValue;
+
+            }
+            else if (byte == HDLC_BYTE_FLAG)
+            {
+                if (sSpiTxPayloadSize <= 2)
+                {
+                    unescape_next_byte = false;
+                    sSpiTxPayloadSize = 0;
+                    fcs = kHdlcCrcResetValue;
+                    continue;
+
+                }
+                else if (fcs != kHdlcCrcCheckValue)
+                {
+                    syslog(LOG_WARNING, "HDLC frame with bad CRC (LEN:%d, FCS:0x%04X)", sSpiTxPayloadSize, fcs);
+                    unescape_next_byte = false;
+                    sSpiTxPayloadSize = 0;
+                    fcs = kHdlcCrcResetValue;
+                    continue;
+                }
+
+                // Clip off the CRC
+                sSpiTxPayloadSize -= 2;
+
+                // Indicate that a frame is ready to go out
+                sSpiTxIsReady = true;
+
+                // Clean up for the next frame
+                unescape_next_byte = false;
+                fcs = kHdlcCrcResetValue;
+                break;
+
+            }
+            else if (byte == HDLC_BYTE_ESC)
+            {
+                unescape_next_byte = true;
+                continue;
+
+            }
+            else if (hdlc_byte_needs_escape(byte))
+            {
+                // Skip all other control codes.
+                continue;
+
+            }
+            else if (unescape_next_byte)
+            {
+                byte = byte ^ HDLC_ESCAPE_XFORM;
+                unescape_next_byte = false;
+            }
+
+            fcs = hdlc_crc16(fcs, byte);
+            sSpiTxFrameBuffer[HEADER_LEN + sSpiTxPayloadSize++] = byte;
+        }
+    }
+
+    if (ret < 0)
+    {
+        if (errno == EAGAIN)
+        {
+            ret = 0;
+        }
+        else
+        {
+            perror("pull_hdlc:read");
+            syslog(LOG_ERR, "pull_hdlc:read: errno=%d (%s)", errno, strerror(errno));
+        }
+    }
+
+    return ret < 0
+        ? ret
+        : 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* MARK: Setup Functions */
+
+static bool update_spi_mode(int x)
+{
+    sSpiMode = (uint8_t)x;
+
+    if ( (sSpiDevFd >= 0)
+      && (ioctl(sSpiDevFd, SPI_IOC_WR_MODE, &sSpiMode) < 0)
+    )
+    {
+        perror("ioctl(SPI_IOC_WR_MODE)");
+        return false;
+    }
+
+    return true;
+}
+
+static bool update_spi_speed(int x)
+{
+    sSpiSpeed = x;
+
+    if ( (sSpiDevFd >= 0)
+      && (ioctl(sSpiDevFd, SPI_IOC_WR_MAX_SPEED_HZ, &sSpiSpeed) < 0)
+    )
+    {
+        perror("ioctl(SPI_IOC_WR_MAX_SPEED_HZ)");
+        return false;
+    }
+
+    return true;
+}
+
+
+static bool setup_spi_dev(const char* path)
+{
+    int fd = -1;
+    const uint8_t spi_word_bits = 8;
+    int ret;
+    sSpiDevPath = path;
+
+    fd = open(path, O_RDWR);
+    if (fd < 0)
+    {
+        perror("open");
+        goto bail;
+    }
+
+    // Set the SPI mode.
+    ret = ioctl(fd, SPI_IOC_WR_MODE, &sSpiMode);
+    if (ret < 0)
+    {
+        perror("ioctl(SPI_IOC_WR_MODE)");
+        goto bail;
+    }
+
+    // Set the SPI clock speed.
+    ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &sSpiSpeed);
+    if (ret < 0)
+    {
+        perror("ioctl(SPI_IOC_WR_MAX_SPEED_HZ)");
+        goto bail;
+    }
+
+    // Set the SPI word size.
+    ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &spi_word_bits);
+    if (ret < 0)
+    {
+        perror("ioctl(SPI_IOC_WR_BITS_PER_WORD)");
+        goto bail;
+    }
+
+    // Lock the file descriptor
+    if (flock(fd, LOCK_EX | LOCK_NB) < 0)
+    {
+        perror("flock");
+        goto bail;
+    }
+
+    sSpiDevFd = fd;
+    fd = -1;
+
+bail:
+    if (fd >= 0)
+    {
+        close(fd);
+    }
+    return sSpiDevFd >= 0;
+}
+
+static bool setup_res_gpio(const char* path)
+{
+    int setup_fd = -1;
+    char* dir_path = NULL;
+    char* value_path = NULL;
+    int len;
+
+    sResGpioDevPath = path;
+
+    len = asprintf(&dir_path, "%s/direction", path);
+
+    if (len < 0)
+    {
+        perror("asprintf");
+        goto bail;
+    }
+
+    len = asprintf(&value_path, "%s/value", path);
+
+    if (len < 0)
+    {
+        perror("asprintf");
+        goto bail;
+    }
+
+    setup_fd = open(dir_path, O_WRONLY);
+
+    if (setup_fd >= 0)
+    {
+        if (-1 == write(setup_fd, "high\n", 5))
+        {
+            perror("set_res_direction");
+            goto bail;
+        }
+    }
+
+    sResGpioValueFd = open(value_path, O_WRONLY);
+
+bail:
+
+    if (setup_fd >= 0)
+    {
+        close(setup_fd);
+    }
+
+    if (dir_path)
+    {
+        free(dir_path);
+    }
+
+    if (value_path)
+    {
+        free(value_path);
+    }
+
+    return sResGpioValueFd >= 0;
+}
+
+static void trigger_reset(void)
+{
+    if (sResGpioValueFd >= 0)
+    {
+        char str[] = { '0' + GPIO_RES_ASSERT_STATE, '\n' };
+
+        lseek(sResGpioValueFd, 0, SEEK_SET);
+        if (write(sResGpioValueFd, str, sizeof(str)) == -1)
+        {
+            syslog(LOG_ERR, "trigger_reset(): error on write: %d (%s)", errno, strerror(errno));
+        }
+
+        usleep(10 * USEC_PER_MSEC);
+
+        // Set the string to switch to the not-asserted state.
+        str[0] = '0' + !GPIO_RES_ASSERT_STATE;
+
+        lseek(sResGpioValueFd, 0, SEEK_SET);
+        if (write(sResGpioValueFd, str, sizeof(str)) == -1)
+        {
+            syslog(LOG_ERR, "trigger_reset(): error on write: %d (%s)", errno, strerror(errno));
+        }
+
+        syslog(LOG_NOTICE, "Triggered hardware reset");
+    }
+}
+
+static bool setup_int_gpio(const char* path)
+{
+    char* edge_path = NULL;
+    char* dir_path = NULL;
+    char* value_path = NULL;
+    ssize_t len;
+    int setup_fd = -1;
+
+    sIntGpioValueFd = -1;
+
+    sIntGpioDevPath = path;
+
+    len = asprintf(&dir_path, "%s/direction", path);
+
+    if (len < 0)
+    {
+        perror("asprintf");
+        goto bail;
+    }
+
+    len = asprintf(&edge_path, "%s/edge", path);
+
+    if (len < 0)
+    {
+        perror("asprintf");
+        goto bail;
+    }
+
+    len = asprintf(&value_path, "%s/value", path);
+
+    if (len < 0)
+    {
+        perror("asprintf");
+        goto bail;
+    }
+
+    setup_fd = open(dir_path, O_WRONLY);
+
+    if (setup_fd >= 0)
+    {
+        len = write(setup_fd, "in", 2);
+        if (len < 0)
+        {
+            perror("write");
+            goto bail;
+        }
+
+        close(setup_fd);
+    }
+
+    setup_fd = open(edge_path, O_WRONLY);
+
+    if (setup_fd >= 0)
+    {
+        len = write(setup_fd, "falling", 7);
+
+        if (len < 0)
+        {
+            perror("write");
+            goto bail;
+        }
+
+        close(setup_fd);
+
+        setup_fd = -1;
+    }
+
+    sIntGpioValueFd = open(value_path, O_RDONLY);
+
+bail:
+
+    if (setup_fd >= 0)
+    {
+        close(setup_fd);
+    }
+
+    if (edge_path)
+    {
+        free(edge_path);
+    }
+
+    if (dir_path)
+    {
+        free(dir_path);
+    }
+
+    if (value_path)
+    {
+        free(value_path);
+    }
+
+    return sIntGpioValueFd >= 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* MARK: Help */
+
+static void print_version(void)
+{
+    printf("spi-hdlc " SPI_HDLC_VERSION "(" __TIME__ " " __DATE__ ")\n");
+    printf("Copyright (c) 2016 The OpenThread Authors, All Rights Reserved\n");
+}
+
+static void print_help(void)
+{
+    print_version();
+    const char* help =
+    "\n"
+    "Syntax:\n"
+    "\n"
+    "    spi-hdlc [options] <spi-device-path>\n"
+    "\n"
+    "Options:\n"
+    "\n"
+    "    --stdio ...................... Use `stdin` and `stdout` for HDLC input and\n"
+    "                                   output. Useful when directly started by the\n"
+    "                                   program that will be using it.\n"
+#if HAVE_OPENPTY
+    "    --pty ........................ Create a pseudoterminal for HDLC input and\n"
+    "                                   output. The path of the newly-created PTY\n"
+    "                                   will be written to `stdout`, followed by a\n"
+    "                                   newline.\n"
+#endif // HAVE_OPENPTY
+    "    -i/--gpio-int[=gpio-path] .... Specify a path to the Linux sysfs-exported\n"
+    "                                   GPIO directory for the `IÌ…NÌ…TÌ…` pin. If not\n"
+    "                                   specified, `spi-hdlc` will fall back to\n"
+    "                                   polling, which is inefficient.\n"
+    "    -r/--gpio-reset[=gpio-path] .. Specify a path to the Linux sysfs-exported\n"
+    "                                   GPIO directory for the `RÌ…EÌ…SÌ…` pin.\n"
+    "    --spi-mode[=mode] ............ Specify the SPI mode to use (0-3).\n"
+    "    --spi-speed[=hertz] .......... Specify the SPI speed in hertz.\n"
+    "    --spi-cs-delay[=usec] ........ Specify the delay after CÌ…SÌ… assertion, in usec\n"
+    "    --spi-align-allowance[=n] .... Specify the the maximum number of FF bytes to\n"
+    "                                   clip from start of RX frame.\n"
+    "    -v/--verbose ................. Increase debug verbosity. (Repeatable)\n"
+    "    -h/-?/--help ................. Print out usage information and exit.\n"
+    "\n";
+
+    printf("%s", help);
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* MARK: Main Loop */
+
+int main(int argc, char *argv[])
+{
+    int i = 0;
+    const char* prog = argv[0];
+    static fd_set read_set;
+    static fd_set write_set;
+    static fd_set error_set;
+    struct timeval timeout;
+    int max_fd = -1;
+    bool did_print_rate_limit_log = false;
+
+#if AUTO_PRINT_BACKTRACE
+    struct sigaction sigact;
+#endif // if AUTO_PRINT_BACKTRACE
+
+    enum {
+        ARG_SPI_MODE = 1001,
+        ARG_SPI_SPEED = 1002,
+        ARG_VERBOSE = 1003,
+        ARG_SPI_CS_DELAY = 1004,
+        ARG_SPI_ALIGN_ALLOWANCE = 1005,
+    };
+
+    static struct option options[] = {
+        { "stdio",      no_argument,       &sMode, MODE_STDIO    },
+        { "pty",        no_argument,       &sMode, MODE_PTY      },
+        { "gpio-int",   required_argument, NULL,   'i'           },
+        { "gpio-res",   required_argument, NULL,   'r'           },
+        { "verbose",    optional_argument, NULL,   ARG_VERBOSE   },
+        { "version",    no_argument,       NULL,   'V'           },
+        { "help",       no_argument,       NULL,   'h'           },
+        { "spi-mode",   required_argument, NULL,   ARG_SPI_MODE  },
+        { "spi-speed",  required_argument, NULL,   ARG_SPI_SPEED },
+        { "spi-cs-delay",required_argument,NULL,   ARG_SPI_CS_DELAY },
+        { "spi-align-allowance", required_argument, NULL, ARG_SPI_ALIGN_ALLOWANCE },
+        { NULL,         0,                 NULL,   0             },
+    };
+
+    if (argc < 2)
+    {
+        print_help();
+        exit(EXIT_FAILURE);
+    }
+
+
+    // ========================================================================
+    // INITIALIZATION
+
+    sPreviousHandlerForSIGINT = signal(SIGINT, &signal_SIGINT);
+    sPreviousHandlerForSIGTERM = signal(SIGTERM, &signal_SIGTERM);
+    signal(SIGHUP, &signal_SIGHUP);
+
+#if AUTO_PRINT_BACKTRACE
+    sigact.sa_sigaction = &signal_critical;
+    sigact.sa_flags = SA_RESTART | SA_SIGINFO | SA_NOCLDWAIT;
+
+    sigaction(SIGSEGV, &sigact, (struct sigaction *)NULL);
+    sigaction(SIGBUS, &sigact, (struct sigaction *)NULL);
+    sigaction(SIGILL, &sigact, (struct sigaction *)NULL);
+    sigaction(SIGABRT, &sigact, (struct sigaction *)NULL);
+#endif // if AUTO_PRINT_BACKTRACE
+
+    // ========================================================================
+    // ARGUMENT PARSING
+
+    openlog(basename(prog), LOG_PERROR | LOG_PID | LOG_CONS, LOG_DAEMON);
+
+    setlogmask(setlogmask(0) & LOG_UPTO(sVerbose));
+
+    while (1)
+    {
+        int c = getopt_long(argc, argv, "i:r:vVh?", options, NULL);
+        if (c == -1)
+        {
+            break;
+        }
+        else
+        {
+            switch (c)
+            {
+            case 'i':
+                if (!setup_int_gpio(optarg))
+                {
+                    syslog(LOG_ERR, "Unable to setup INT GPIO \"%s\", %s", optarg, strerror(errno));
+                    exit(EXIT_FAILURE);
+                }
+                break;
+
+            case ARG_SPI_ALIGN_ALLOWANCE:
+                errno = 0;
+                sSpiRxAlignAllowance = atoi(optarg);
+                if (errno != 0 || (sSpiRxAlignAllowance > SPI_RX_ALIGN_ALLOWANCE_MAX))
+                {
+                    syslog(LOG_ERR, "Invalid SPI RX Align Allowance \"%s\" (MAX: %d)", optarg, SPI_RX_ALIGN_ALLOWANCE_MAX);
+                    exit(EXIT_FAILURE);
+                }
+                break;
+
+            case ARG_SPI_MODE:
+                if (!update_spi_mode(atoi(optarg)))
+                {
+                    syslog(LOG_ERR, "Unable to set SPI mode to \"%s\", %s", optarg, strerror(errno));
+                    exit(EXIT_FAILURE);
+                }
+                break;
+
+            case ARG_SPI_SPEED:
+                if (!update_spi_speed(atoi(optarg)))
+                {
+                    syslog(LOG_ERR, "Unable to set SPI speed to \"%s\", %s", optarg, strerror(errno));
+                    exit(EXIT_FAILURE);
+                }
+                break;
+
+            case ARG_SPI_CS_DELAY:
+                sSpiCsDelay = atoi(optarg);
+                syslog(LOG_NOTICE, "SPI CS Delay set to %d usec", sSpiCsDelay);
+                break;
+
+            case 'r':
+                if (!setup_res_gpio(optarg))
+                {
+                    syslog(LOG_ERR, "Unable to setup RES GPIO \"%s\", %s", optarg, strerror(errno));
+                    exit(EXIT_FAILURE);
+                }
+                break;
+
+            case 'v':
+            case ARG_VERBOSE:
+                if (sVerbose < LOG_DEBUG)
+                {
+                    if (optarg)
+                    {
+                        sVerbose += atoi(optarg);
+                    }
+                    else
+                    {
+                        sVerbose++;
+                    }
+                    setlogmask(setlogmask(0) | LOG_UPTO(sVerbose));
+                    syslog(sVerbose, "Verbosity set to level %d", sVerbose);
+                }
+                break;
+
+            case 'V':
+                print_version();
+                exit(EXIT_SUCCESS);
+                break;
+
+            case 'h':
+            case '?':
+                print_help();
+                exit(EXIT_SUCCESS);
+                break;
+            }
+        }
+    }
+
+    argc -= optind;
+    argv += optind;
+
+    if (argc >= 1)
+    {
+        if (!setup_spi_dev(argv[0]))
+        {
+            syslog(LOG_ERR, "%s: Unable to open SPI device \"%s\", %s", prog, argv[0], strerror(errno));
+            exit(EXIT_FAILURE);
+        }
+        argc--;
+        argv++;
+    }
+
+    if (argc >= 1)
+    {
+        fprintf(stderr, "%s: Unexpected argument \"%s\"\n", prog, argv[0]);
+        exit(EXIT_FAILURE);
+    }
+
+    if (sSpiDevPath == NULL)
+    {
+        fprintf(stderr, "%s: Missing SPI device path\n", prog);
+        exit(EXIT_FAILURE);
+    }
+
+    if (sMode == MODE_STDIO)
+    {
+        sHdlcInputFd = dup(STDIN_FILENO);
+        sHdlcOutputFd = dup(STDOUT_FILENO);
+        close(STDIN_FILENO);
+        close(STDOUT_FILENO);
+
+    }
+    else if (sMode == MODE_PTY)
+    {
+#if HAVE_OPENPTY
+
+        static int pty_slave_fd = -1;
+        char pty_name[1024];
+        sRet = openpty(&sHdlcInputFd, &pty_slave_fd, pty_name, NULL, NULL);
+
+        if (sRet != 0)
+        {
+            perror("openpty");
+            goto bail;
+        }
+
+        sHdlcOutputFd = dup(sHdlcInputFd);
+
+        printf("%s\n", pty_name);
+
+        close(STDOUT_FILENO);
+
+#else // if HAVE_OPENPTY
+
+        syslog(LOG_ERR, "Not built with support for `--pty`.");
+        sRet = EXIT_FAILURE;
+        goto bail;
+
+#endif // else HAVE_OPENPTY
+
+    }
+    else
+    {
+        sRet = EXIT_FAILURE;
+        goto bail;
+    }
+
+    // Set up sHdlcInputFd for non-blocking I/O
+    if (-1 == (i = fcntl(sHdlcInputFd, F_GETFL, 0)))
+    {
+        i = 0;
+    }
+    fcntl(sHdlcInputFd, F_SETFL, i | O_NONBLOCK);
+
+    // Since there are so few file descriptors in
+    // this program, we calcualte `max_fd` once
+    // instead of trying to optimize its value
+    // at every iteration.
+    max_fd = sHdlcInputFd;
+
+    if (max_fd < sHdlcOutputFd)
+    {
+        max_fd = sHdlcOutputFd;
+    }
+
+    if (max_fd < sIntGpioValueFd)
+    {
+        max_fd = sIntGpioValueFd;
+    }
+
+    if (sIntGpioValueFd < 0)
+    {
+        syslog(LOG_WARNING, "Interrupt pin was not set, must poll SPI. Performance will suffer.");
+    }
+
+    trigger_reset();
+
+    // ========================================================================
+    // MAIN LOOP
+
+    while (sRet == 0)
+    {
+        int timeout_ms = MSEC_PER_SEC * 60 * 60 * 24; // 24 hours
+
+        FD_ZERO(&read_set);
+        FD_ZERO(&write_set);
+        FD_ZERO(&error_set);
+
+        if (!sSpiTxIsReady)
+        {
+            FD_SET(sHdlcInputFd, &read_set);
+
+        }
+        else if (sSpiTxFlowControl)
+        {
+            // We are being rate-limited by the NCP. This is
+            // fairly normal behavior. We poll because we
+            // won't get an interrupt unless the NCP happens
+            // to be trying to send us something.
+            timeout_ms = SPI_POLL_PERIOD_MSEC;
+
+            if (!did_print_rate_limit_log) {
+                // Avoid printing out this message over and over.
+                syslog(LOG_INFO, "NCP is rate limiting transactions");
+                did_print_rate_limit_log = true;
+            }
+        }
+        else
+        {
+            // We have data to send to the slave. Since we
+            // are not being rate-limited, proceed immediately.
+            timeout_ms = 0;
+            did_print_rate_limit_log = false;
+        }
+
+        if (sSpiRxPayloadSize != 0)
+        {
+            // We have data that we are waiting to send out
+            // of the HDLC descriptor, so we need to wait
+            // for that to clear out before we can do anything
+            // else.
+            FD_SET(sHdlcOutputFd, &write_set);
+
+        }
+        else if (sIntGpioValueFd >= 0)
+        {
+            if (check_and_clear_interrupt())
+            {
+                // Interrupt pin is asserted,
+                // set the timeout to be 0.
+                timeout_ms = 0;
+
+                syslog(LOG_DEBUG, "Interrupt.");
+            }
+            else
+            {
+                // The interrupt pin was not asserted,
+                // so we wait for the interrupt pin to
+                // be asserted by adding it to the error
+                // set.
+                FD_SET(sIntGpioValueFd, &error_set);
+            }
+
+        }
+        else if (timeout_ms > SPI_POLL_PERIOD_MSEC)
+        {
+            // In this case we don't have an interrupt, so
+            // we revert to SPI polling.
+            timeout_ms = SPI_POLL_PERIOD_MSEC;
+        }
+
+        // Calculate the timeout value.
+        timeout.tv_sec = timeout_ms / MSEC_PER_SEC;
+        timeout.tv_usec = (timeout_ms % MSEC_PER_SEC) * USEC_PER_MSEC;
+
+        // Wait for something to happen.
+        select(max_fd + 1, &read_set, &write_set, &error_set, &timeout);
+
+        // Handle serial input.
+        if (FD_ISSET(sHdlcInputFd, &read_set))
+        {
+            // Read in the data.
+            if (pull_hdlc() < 0)
+            {
+                sRet = EXIT_FAILURE;
+                break;
+            }
+        }
+
+        // Handle serial output.
+        if (FD_ISSET(sHdlcOutputFd, &write_set))
+        {
+            // Write out the data.
+            if (push_hdlc() < 0)
+            {
+                sRet = EXIT_FAILURE;
+                break;
+            }
+        }
+
+        // Service the SPI port if we can receive
+        // a packet or we have a packet to be sent.
+        if ((sSpiRxPayloadSize == 0) || sSpiTxIsReady)
+        {
+            if (push_pull_spi() < 0)
+            {
+                sRet = EXIT_FAILURE;
+            }
+        }
+    }
+
+
+    // ========================================================================
+    // SHUTDOWN
+
+bail:
+    syslog(LOG_NOTICE, "Shutdown. (sRet = %d)", sRet);
+
+    if (sRet == EXIT_QUIT)
+    {
+        sRet = EXIT_SUCCESS;
+    }
+    else if (sRet == -1)
+    {
+        sRet = EXIT_FAILURE;
+    }
+
+    return sRet;
+}
diff --git a/third_party/pt/LICENSE b/third_party/pt/LICENSE
new file mode 100644
index 0000000..4b9d77f
--- /dev/null
+++ b/third_party/pt/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name of the Institute nor the names of its contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+Author: Adam Dunkels <adam@sics.se>
diff --git a/third_party/pt/Makefile b/third_party/pt/Makefile
new file mode 100644
index 0000000..ff573ef
--- /dev/null
+++ b/third_party/pt/Makefile
@@ -0,0 +1,9 @@
+CFLAGS=-O -Wuninitialized -Werror
+
+all: example-codelock example-buffer example-small
+
+example-codelock: example-codelock.c pt.h lc.h
+
+example-buffer: example-buffer.c pt.h lc.h
+
+example-small: example-small.c pt.h lc.h
diff --git a/third_party/pt/README b/third_party/pt/README
new file mode 100644
index 0000000..54d8627
--- /dev/null
+++ b/third_party/pt/README
@@ -0,0 +1,51 @@
+Protothreads are extremely lightweight stackless threads designed for
+severely memory constrained systems such as small embedded systems or
+sensor network nodes. Protothreads can be used with or without an
+underlying operating system.
+
+Protothreads provides a blocking context on top of an event-driven
+system, without the overhead of per-thread stacks. The purpose of
+protothreads is to implement sequential flow of control without
+complex state machines or full multi-threading.
+
+Main features:
+
+    * No machine specific code - the protothreads library is pure C
+    * Does not use error-prone functions such as longjmp()
+    * Very small RAM overhead - only two bytes per protothread
+    * Can be used with or without an OS
+    * Provides blocking wait without full multi-threading or
+      stack-switching
+    * Freely available under a BSD-like open source license
+
+Example applications:
+
+    * Memory constrained systems
+    * Event-driven protocol stacks
+    * Small embedded systems
+    * Sensor network nodes
+
+The protothreads library is released under an open source BSD-style
+license that allows for both non-commercial and commercial usage. The
+only requirement is that credit is given.
+
+The protothreads library was written by Adam Dunkels <adam@sics.se>
+with support from Oliver Schmidt <ol.sc@web.de>.
+
+More information and new versions can be found at the protothreads
+homepage:
+		     http://www.sics.se/~adam/pt/
+
+Documentation can be found in the doc/ subdirectory.
+
+Two example programs illustrating the use of protothreads can be found
+in this directory:
+
+   example-small.c         A small example showing how to use protothreads
+   example-buffer.c        The bounded buffer problem with protothreads
+   example-codelock.c	   A code lock with simulated key input
+
+To compile the examples, simply run "make".
+
+
+Adam Dunkels, 3 June 2006
diff --git a/third_party/pt/README-VISUAL-C++.txt b/third_party/pt/README-VISUAL-C++.txt
new file mode 100644
index 0000000..3b09a69
--- /dev/null
+++ b/third_party/pt/README-VISUAL-C++.txt
@@ -0,0 +1,5 @@
+Protothreads can in some cases fail to compile under Visual C++
+version 6.0 due to a bug in the compiler. See the following page for a
+solution to the problem:
+
+http://support.microsoft.com/default.aspx?scid=kb;en-us;199057
diff --git a/third_party/pt/README.google b/third_party/pt/README.google
new file mode 100644
index 0000000..79082a5
--- /dev/null
+++ b/third_party/pt/README.google
@@ -0,0 +1,17 @@
+URL: http://dunkels.com/adam/download/pt-1.4.tar.gz
+Version: 1.4
+License: BSD-3
+License File: LICENSE
+
+Description:
+Protothreads are extremely lightweight stackless threads designed for severely
+memory constrained systems, such as small embedded systems or wireless sensor
+network nodes. Protothreads provide linear code execution for event-driven
+systems implemented in C. Protothreads can be used with or without an underlying
+operating system to provide blocking event-handlers. Protothreads provide
+sequential flow of control without complex state machines or full
+multi-threading.
+
+Local Modifications:
+LICENSE file has been created for compliance purposes. Not included in original
+distribution. Removed html and pt-refman.pdf from documentation folder.
diff --git a/third_party/pt/doc/Doxyfile b/third_party/pt/doc/Doxyfile
new file mode 100644
index 0000000..27b4b75
--- /dev/null
+++ b/third_party/pt/doc/Doxyfile
@@ -0,0 +1,229 @@
+# Doxyfile 1.4.6
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = "The Protothreads Library 1.4"
+PROJECT_NUMBER         =
+OUTPUT_DIRECTORY       = .
+CREATE_SUBDIRS         = NO
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = NO
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       =
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = YES
+STRIP_FROM_PATH        = ../
+STRIP_FROM_INC_PATH    =
+SHORT_NAMES            = YES
+JAVADOC_AUTOBRIEF      = YES
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = YES
+INHERIT_DOCS           = YES
+SEPARATE_MEMBER_PAGES  = NO
+TAB_SIZE               = 8
+ALIASES                =
+OPTIMIZE_OUTPUT_FOR_C  = YES
+OPTIMIZE_OUTPUT_JAVA   = NO
+BUILTIN_STL_SUPPORT    = NO
+DISTRIBUTE_GROUP_DOC   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = NO
+EXTRACT_PRIVATE        = NO
+EXTRACT_STATIC         = NO
+EXTRACT_LOCAL_CLASSES  = NO
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = YES
+HIDE_UNDOC_CLASSES     = YES
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = NO
+GENERATE_DEPRECATEDLIST= NO
+ENABLED_SECTIONS       =
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = NO
+SHOW_DIRECTORIES       = NO
+FILE_VERSION_FILTER    =
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_NO_PARAMDOC       = NO
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           =
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = pt-mainpage.txt \
+                         pt-doc.txt \
+                         ../pt.h \
+                         ../pt-sem.h \
+                         ../lc.h \
+                         ../lc-switch.h \
+                         ../lc-addrlabels.h
+FILE_PATTERNS          =
+RECURSIVE              = NO
+EXCLUDE                =
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       =
+EXAMPLE_PATH           = ..
+EXAMPLE_PATTERNS       =
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             =
+INPUT_FILTER           =
+FILTER_PATTERNS        =
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = YES
+INLINE_SOURCES         = YES
+STRIP_CODE_COMMENTS    = NO
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+USE_HTAGS              = NO
+VERBATIM_HEADERS       = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          =
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            =
+HTML_FOOTER            =
+HTML_STYLESHEET        =
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = YES
+CHM_FILE               =
+HHC_LOCATION           =
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = YES
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = YES
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = YES
+PAPER_TYPE             = a4
+EXTRA_PACKAGES         =
+LATEX_HEADER           = header.tex
+PDF_HYPERLINKS         = YES
+USE_PDFLATEX           = YES
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    =
+RTF_EXTENSIONS_FILE    =
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             =
+XML_DTD                =
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           =
+INCLUDE_FILE_PATTERNS  =
+PREDEFINED             = DOXYGEN
+EXPAND_AS_DEFINED      =
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+TAGFILES               =
+GENERATE_TAGFILE       =
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = NO
+HIDE_UNDOC_RELATIONS   = NO
+HAVE_DOT               = NO
+CLASS_GRAPH            = NO
+COLLABORATION_GRAPH    = YES
+GROUP_GRAPHS           = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = NO
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = YES
+GRAPHICAL_HIERARCHY    = YES
+DIRECTORY_GRAPH        = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               =
+DOTFILE_DIRS           =
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 0
+DOT_TRANSPARENT        = NO
+DOT_MULTI_TARGETS      = NO
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
diff --git a/third_party/pt/doc/Makefile b/third_party/pt/doc/Makefile
new file mode 100644
index 0000000..39328b4
--- /dev/null
+++ b/third_party/pt/doc/Makefile
@@ -0,0 +1,7 @@
+dox:
+	doxygen Doxyfile
+
+
+pdf:	dox
+	(cd latex; $(MAKE) refman.pdf)
+	mv latex/refman.pdf pt-refman.pdf
diff --git a/third_party/pt/doc/header.tex b/third_party/pt/doc/header.tex
new file mode 100644
index 0000000..5899653
--- /dev/null
+++ b/third_party/pt/doc/header.tex
@@ -0,0 +1,52 @@
+\documentclass[a4paper]{article}
+\usepackage{a4wide}
+\usepackage{makeidx}
+\usepackage{fancyhdr}
+\usepackage{graphicx}
+\usepackage{multicol}
+\usepackage{float}
+\usepackage{textcomp}
+\usepackage{alltt}
+\usepackage{times}
+\usepackage{epsfig}
+\ifx\pdfoutput\undefined
+\usepackage[ps2pdf,
+            pagebackref=true,
+            colorlinks=true,
+            linkcolor=blue
+           ]{hyperref}
+\usepackage{pspicture}
+\else
+\usepackage[pdftex,
+            pagebackref=true,
+            colorlinks=true,
+            linkcolor=blue
+           ]{hyperref}
+\fi
+\usepackage{doxygen}
+\makeindex
+\setcounter{tocdepth}{1}
+\renewcommand{\footrulewidth}{0.4pt}
+\begin{document}
+\begin{titlepage}
+\vspace*{5cm}
+\begin{center}
+{\Huge Protothreads}\\
+\vspace*{1cm}
+{\LARGE The Protothreads Library 1.3 Reference Manual}\\
+\vspace*{3cm}
+{\Large June 2006}\\
+\vspace*{2cm}
+\includegraphics[width=6cm]{../sicslogo.pdf}\\
+\vspace*{1cm}
+{\Large Adam Dunkels}\\
+{\Large \texttt{adam@sics.se}}\\
+\vspace*{1cm}
+{\LARGE Swedish Institute of Computer Science}\\
+\vspace*{0.5cm}
+
+\end{center}
+\end{titlepage}
+\pagenumbering{roman}
+\tableofcontents
+\pagenumbering{arabic}
diff --git a/third_party/pt/doc/pt-doc.txt b/third_party/pt/doc/pt-doc.txt
new file mode 100644
index 0000000..b0885aa
--- /dev/null
+++ b/third_party/pt/doc/pt-doc.txt
@@ -0,0 +1,58 @@
+/**
+\defgroup pt Protothreads
+@{
+Protothreads are implemented in a single header file, pt.h, which
+includes the local continuations header file, lc.h. This file in turn
+includes the actual implementation of local continuations, which
+typically also is contained in a single header file.
+
+*/
+
+/** @} */
+
+/**
+\defgroup examples Examples
+@{
+
+\section example-small A small example
+
+This first example shows a very simple program: two protothreads
+waiting for each other to toggle two flags. The code illustrates how
+to write protothreads code, how to initialize protothreads, and how to
+schedule them.
+
+\include example-small.c
+
+
+\section example-code-lock A code-lock
+This example shows how to implement a simple code lock - the kind of
+device that is placed next to doors and that you have to push a four
+digit number into in order to unlock the door.
+
+The code lock waits for key presses from a numeric keyboard and if the
+correct code is entered, the lock is unlocked. There is a maximum time
+of one second between each key press, and after the correct code has
+been entered, no more keys must be pressed for 0.5 seconds before the
+lock is opened.
+
+\include example-codelock.c
+
+\section example-buffer The bounded buffer with protothread semaphores
+
+The following example shows how to implement the bounded buffer
+problem using the protothreads semaphore library. The example uses
+three protothreads: one producer() protothread that produces items,
+one consumer() protothread that consumes items, and one
+driver_thread() that schedules the producer and consumer protothreads.
+
+Note that there is no need for a mutex to guard the add_to_buffer()
+and get_from_buffer() functions because of the implicit locking
+semantics of protothreads - a protothread will never be preempted and
+will never block except in an explicit PT_WAIT statement.
+
+\include example-buffer.c
+
+*/
+
+
+/** @} */
diff --git a/third_party/pt/doc/pt-mainpage.txt b/third_party/pt/doc/pt-mainpage.txt
new file mode 100644
index 0000000..269570b
--- /dev/null
+++ b/third_party/pt/doc/pt-mainpage.txt
@@ -0,0 +1,156 @@
+/**
+
+\mainpage The Protothreads Library
+
+\author Adam Dunkels <adam@sics.se>
+
+Protothreads are a type of lightweight stackless threads designed for
+severly memory constrained systems such as deeply embedded systems or
+sensor network nodes. Protothreads provides linear code execution for
+event-driven systems implemented in C. Protothreads can be used with
+or without an RTOS.
+
+Protothreads are a extremely lightweight, stackless type of threads
+that provides a blocking context on top of an event-driven system,
+without the overhead of per-thread stacks. The purpose of protothreads
+is to implement sequential flow of control without complex state
+machines or full multi-threading. Protothreads provides conditional
+blocking inside C functions.
+
+Main features:
+
+    - No machine specific code - the protothreads library is pure C
+
+    - Does not use error-prone functions such as longjmp()
+
+    - Very small RAM overhead - only two bytes per protothread
+
+    - Can be used with or without an OS
+
+    - Provides blocking wait without full multi-threading or
+      stack-switching
+
+Examples applications:
+
+    - Memory constrained systems
+
+    - Event-driven protocol stacks
+
+    - Deeply embedded systems
+
+    - Sensor network nodes
+
+
+\sa \ref examples "Example programs"
+\sa \ref pt "Protothreads API documentation"
+
+The protothreads library is released under a BSD-style license that
+allows for both non-commercial and commercial usage. The only
+requirement is that credit is given.
+
+More information and new version of the code can be found at the
+Protothreads homepage:
+
+		     http://www.sics.se/~adam/pt/
+
+\section authors Authors
+
+The protothreads library was written by Adam Dunkels <adam@sics.se>
+with support from Oliver Schmidt <ol.sc@web.de>.
+
+\section using Using protothreads
+
+Using protothreads in a project is easy: simply copy the files pt.h,
+lc.h and lc-switch.h into the include files directory of the project,
+and \#include "pt.h" in all files that should use protothreads.
+
+\section pt-desc Protothreads
+
+Protothreads are a extremely lightweight, stackless threads that
+provides a blocking context on top of an event-driven system, without
+the overhead of per-thread stacks. The purpose of protothreads is to
+implement sequential flow of control without using complex state
+machines or full multi-threading. Protothreads provides conditional
+blocking inside a C function.
+
+In memory constrained systems, such as deeply embedded systems,
+traditional multi-threading may have a too large memory overhead. In
+traditional multi-threading, each thread requires its own stack, that
+typically is over-provisioned. The stacks may use large parts of the
+available memory.
+
+The main advantage of protothreads over ordinary threads is that
+protothreads are very lightweight: a protothread does not require its
+own stack. Rather, all protothreads run on the same stack and context
+switching is done by stack rewinding. This is advantageous in memory
+constrained systems, where a stack for a thread might use a large part
+of the available memory. A protothread only requires only two bytes of
+memory per protothread. Moreover, protothreads are implemented in pure
+C and do not require any machine-specific assembler code.
+
+A protothread runs within a single C function and cannot span over
+other functions. A protothread may call normal C functions, but cannot
+block inside a called function. Blocking inside nested function calls
+is instead made by spawning a separate protothread for each
+potentially blocking function. The advantage of this approach is that
+blocking is explicit: the programmer knows exactly which functions
+that block that which functions the never blocks.
+
+Protothreads are similar to asymmetric co-routines. The main
+difference is that co-routines uses a separate stack for each
+co-routine, whereas protothreads are stackless. The most similar
+mechanism to protothreads are Python generators. These are also
+stackless constructs, but have a different purpose. Protothreads
+provides blocking contexts inside a C function, whereas Python
+generators provide multiple exit points from a generator function.
+
+\section pt-autovars Local variables
+
+\note
+Because protothreads do not save the stack context across a blocking
+call, local variables are not preserved when the protothread
+blocks. This means that local variables should be used with utmost
+care - if in doubt, do not use local variables inside a protothread!
+
+\section pt-scheduling Scheduling
+
+A protothread is driven by repeated calls to the function in which the
+protothread is running. Each time the function is called, the
+protothread will run until it blocks or exits. Thus the scheduling of
+protothreads is done by the application that uses protothreads.
+
+\section pt-impl Implementation
+
+Protothreads are implemented using local continuations. A local
+continuation represents the current state of execution at a particular
+place in the program, but does not provide any call history or local
+variables. A local continuation can be set in a specific function to
+capture the state of the function. After a local continuation has been
+set can be resumed in order to restore the state of the function at
+the point where the local continuation was set.
+
+
+Local continuations can be implemented in a variety of ways:
+
+   -# by using machine specific assembler code,
+   -# by using standard C constructs, or
+   -# by using compiler extensions.
+
+The first way works by saving and restoring the processor state,
+except for stack pointers, and requires between 16 and 32 bytes of
+memory per protothread. The exact amount of memory required depends on
+the architecture.
+
+The standard C implementation requires only two bytes of state per
+protothread and utilizes the C switch() statement in a non-obvious way
+that is similar to Duff's device. This implementation does, however,
+impose a slight restriction to the code that uses protothreads: a
+protothread cannot perform a blocking wait (PT_WAIT_UNTIL() or
+PT_YIELD()) inside a switch() statement.
+
+Certain compilers has C extensions that can be used to implement
+protothreads. GCC supports label pointers that can be used for this
+purpose. With this implementation, protothreads require 4 bytes of RAM
+per protothread.
+
+*/
diff --git a/third_party/pt/doc/sicslogo.pdf b/third_party/pt/doc/sicslogo.pdf
new file mode 100644
index 0000000..239a1bf
--- /dev/null
+++ b/third_party/pt/doc/sicslogo.pdf
Binary files differ
diff --git a/third_party/pt/example-buffer.c b/third_party/pt/example-buffer.c
new file mode 100644
index 0000000..3845824
--- /dev/null
+++ b/third_party/pt/example-buffer.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the protothreads library.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: example-buffer.c,v 1.5 2005/10/07 05:21:33 adam Exp $
+ */
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <unistd.h>
+#endif
+#include <stdio.h>
+
+#include "pt-sem.h"
+
+#define NUM_ITEMS 32
+#define BUFSIZE 8
+
+static int buffer[BUFSIZE];
+static int bufptr;
+
+static void
+add_to_buffer(int item)
+{
+  printf("Item %d added to buffer at place %d\n", item, bufptr);
+  buffer[bufptr] = item;
+  bufptr = (bufptr + 1) % BUFSIZE;
+}
+static int
+get_from_buffer(void)
+{
+  int item;
+  item = buffer[bufptr];
+  printf("Item %d retrieved from buffer at place %d\n",
+	 item, bufptr);
+  bufptr = (bufptr + 1) % BUFSIZE;
+  return item;
+}
+
+static int
+produce_item(void)
+{
+  static int item = 0;
+  printf("Item %d produced\n", item);
+  return item++;
+}
+
+static void
+consume_item(int item)
+{
+  printf("Item %d consumed\n", item);
+}
+
+static struct pt_sem full, empty;
+
+static
+PT_THREAD(producer(struct pt *pt))
+{
+  static int produced;
+
+  PT_BEGIN(pt);
+
+  for(produced = 0; produced < NUM_ITEMS; ++produced) {
+
+    PT_SEM_WAIT(pt, &full);
+
+    add_to_buffer(produce_item());
+
+    PT_SEM_SIGNAL(pt, &empty);
+  }
+
+  PT_END(pt);
+}
+
+static
+PT_THREAD(consumer(struct pt *pt))
+{
+  static int consumed;
+
+  PT_BEGIN(pt);
+
+  for(consumed = 0; consumed < NUM_ITEMS; ++consumed) {
+
+    PT_SEM_WAIT(pt, &empty);
+
+    consume_item(get_from_buffer());
+
+    PT_SEM_SIGNAL(pt, &full);
+  }
+
+  PT_END(pt);
+}
+
+static
+PT_THREAD(driver_thread(struct pt *pt))
+{
+  static struct pt pt_producer, pt_consumer;
+
+  PT_BEGIN(pt);
+
+  PT_SEM_INIT(&empty, 0);
+  PT_SEM_INIT(&full, BUFSIZE);
+
+  PT_INIT(&pt_producer);
+  PT_INIT(&pt_consumer);
+
+  PT_WAIT_THREAD(pt, producer(&pt_producer) &
+		     consumer(&pt_consumer));
+
+  PT_END(pt);
+}
+
+
+int
+main(void)
+{
+  struct pt driver_pt;
+
+  PT_INIT(&driver_pt);
+
+  while(PT_SCHEDULE(driver_thread(&driver_pt))) {
+
+    /*
+     * When running this example on a multitasking system, we must
+     * give other processes a chance to run too and therefore we call
+     * usleep() resp. Sleep() here. On a dedicated embedded system,
+     * we usually do not need to do this.
+     */
+#ifdef _WIN32
+    Sleep(0);
+#else
+    usleep(10);
+#endif
+  }
+  return 0;
+}
diff --git a/third_party/pt/example-codelock.c b/third_party/pt/example-codelock.c
new file mode 100644
index 0000000..6df6fb0
--- /dev/null
+++ b/third_party/pt/example-codelock.c
@@ -0,0 +1,414 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the protothreads library.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: example-codelock.c,v 1.5 2005/10/06 07:57:08 adam Exp $
+ */
+
+/*
+ *
+ * This example shows how to implement a simple code lock. The code
+ * lock waits for key presses from a numeric keyboard and if the
+ * correct code is entered, the lock is unlocked. There is a maximum
+ * time of one second between each key press, and after the correct
+ * code has been entered, no more keys must be pressed for 0.5 seconds
+ * before the lock is opened.
+ *
+ * This is an example that shows two things:
+ * - how to implement a code lock key input mechanism, and
+ * - how to implement a sequential timed routine.
+ *
+ * The program consists of two protothreads, one that implements the
+ * code lock reader and one that implements simulated keyboard input.
+ *
+ *
+ */
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <unistd.h>
+#include <sys/time.h>
+#endif
+#include <stdio.h>
+
+#include "pt.h"
+
+/*---------------------------------------------------------------------------*/
+/*
+ * The following definitions are just for the simple timer library
+ * used in this example. The actual implementation of the functions
+ * can be found at the end of this file.
+ */
+struct timer { int start, interval; };
+static int  timer_expired(struct timer *t);
+static void timer_set(struct timer *t, int usecs);
+/*---------------------------------------------------------------------------*/
+/*
+ * This example uses two timers: one for the code lock protothread and
+ * one for the simulated key input protothread.
+ */
+static struct timer codelock_timer, input_timer;
+/*---------------------------------------------------------------------------*/
+/*
+ * This is the code that has to be entered.
+ */
+static const char code[4] = {'1', '4', '2', '3'};
+/*---------------------------------------------------------------------------*/
+/*
+ * This example has two protothread and therefor has two protothread
+ * control structures of type struct pt. These are initialized with
+ * PT_INIT() in the main() function below.
+ */
+static struct pt codelock_pt, input_pt;
+/*---------------------------------------------------------------------------*/
+/*
+ * The following code implements a simple key input. Input is made
+ * with the press_key() function, and the function key_pressed()
+ * checks if a key has been pressed. The variable "key" holds the
+ * latest key that was pressed. The variable "key_pressed_flag" is set
+ * when a key is pressed and cleared when a key press is checked.
+ */
+static char key, key_pressed_flag;
+
+static void
+press_key(char k)
+{
+  printf("--- Key '%c' pressed\n", k);
+  key = k;
+  key_pressed_flag = 1;
+}
+
+static int
+key_pressed(void)
+{
+  if(key_pressed_flag != 0) {
+    key_pressed_flag = 0;
+    return 1;
+  }
+  return 0;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ * Declaration of the protothread function implementing the code lock
+ * logic. The protothread function is declared using the PT_THREAD()
+ * macro. The function is declared with the "static" keyword since it
+ * is local to this file. The name of the function is codelock_thread
+ * and it takes one argument, pt, of the type struct pt.
+ *
+ */
+static
+PT_THREAD(codelock_thread(struct pt *pt))
+{
+  /* This is a local variable that holds the number of keys that have
+   * been pressed. Note that it is declared with the "static" keyword
+   * to make sure that the variable is *not* allocated on the stack.
+   */
+  static int keys;
+
+  /*
+   * Declare the beginning of the protothread.
+   */
+  PT_BEGIN(pt);
+
+  /*
+   * We'll let the protothread loop until the protothread is
+   * expliticly exited with PT_EXIT().
+   */
+  while(1) {
+
+    /*
+     * We'll be reading key presses until we get the right amount of
+     * correct keys.
+     */
+    for(keys = 0; keys < sizeof(code); ++keys) {
+
+      /*
+       * If we haven't gotten any keypresses, we'll simply wait for one.
+       */
+      if(keys == 0) {
+
+	/*
+	 * The PT_WAIT_UNTIL() function will block until the condition
+	 * key_pressed() is true.
+	 */
+	PT_WAIT_UNTIL(pt, key_pressed());
+      } else {
+
+	/*
+	 * If the "key" variable was larger than zero, we have already
+	 * gotten at least one correct key press. If so, we'll not
+	 * only wait for the next key, but we'll also set a timer that
+	 * expires in one second. This gives the person pressing the
+	 * keys one second to press the next key in the code.
+	 */
+	timer_set(&codelock_timer, 1000);
+
+	/*
+	 * The following statement shows how complex blocking
+	 * conditions can be easily expressed with protothreads and
+	 * the PT_WAIT_UNTIL() function.
+	 */
+	PT_WAIT_UNTIL(pt, key_pressed() || timer_expired(&codelock_timer));
+
+	/*
+	 * If the timer expired, we should break out of the for() loop
+	 * and start reading keys from the beginning of the while(1)
+	 * loop instead.
+	 */
+	if(timer_expired(&codelock_timer)) {
+	  printf("Code lock timer expired.\n");
+
+	  /*
+	   * Break out from the for() loop and start from the
+	   * beginning of the while(1) loop.
+	   */
+	  break;
+	}
+      }
+
+      /*
+       * Check if the pressed key was correct.
+       */
+      if(key != code[keys]) {
+	printf("Incorrect key '%c' found\n", key);
+	/*
+	 * Break out of the for() loop since the key was incorrect.
+	 */
+	break;
+      } else {
+	printf("Correct key '%c' found\n", key);
+      }
+    }
+
+    /*
+     * Check if we have gotten all keys.
+     */
+    if(keys == sizeof(code)) {
+      printf("Correct code entered, waiting for 500 ms before unlocking.\n");
+
+      /*
+       * Ok, we got the correct code. But to make sure that the code
+       * was not just a fluke of luck by an intruder, but the correct
+       * code entered by a person that knows the correct code, we'll
+       * wait for half a second before opening the lock. If another
+       * key is pressed during this time, we'll assume that it was a
+       * fluke of luck that the correct code was entered the first
+       * time.
+       */
+      timer_set(&codelock_timer, 500);
+      PT_WAIT_UNTIL(pt, key_pressed() || timer_expired(&codelock_timer));
+
+      /*
+       * If we continued from the PT_WAIT_UNTIL() statement without
+       * the timer expired, we don't open the lock.
+       */
+      if(!timer_expired(&codelock_timer)) {
+	printf("Key pressed during final wait, code lock locked again.\n");
+      } else {
+
+	/*
+	 * If the timer expired, we'll open the lock and exit from the
+	 * protothread.
+	 */
+	printf("Code lock unlocked.\n");
+	PT_EXIT(pt);
+      }
+    }
+  }
+
+  /*
+   * Finally, we'll mark the end of the protothread.
+   */
+  PT_END(pt);
+}
+/*---------------------------------------------------------------------------*/
+/*
+ * This is the second protothread in this example. It implements a
+ * simulated user pressing the keys. This illustrates how a linear
+ * sequence of timed instructions can be implemented with
+ * protothreads.
+ */
+static
+PT_THREAD(input_thread(struct pt *pt))
+{
+  PT_BEGIN(pt);
+
+  printf("Waiting 1 second before entering first key.\n");
+
+  timer_set(&input_timer, 1000);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  press_key('1');
+
+  timer_set(&input_timer, 100);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  press_key('2');
+
+  timer_set(&input_timer, 100);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  press_key('3');
+
+  timer_set(&input_timer, 2000);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  press_key('1');
+
+  timer_set(&input_timer, 200);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  press_key('4');
+
+  timer_set(&input_timer, 200);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  press_key('2');
+
+  timer_set(&input_timer, 2000);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  press_key('3');
+
+  timer_set(&input_timer, 200);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  press_key('1');
+
+  timer_set(&input_timer, 200);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  press_key('4');
+
+  timer_set(&input_timer, 200);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  press_key('2');
+
+  timer_set(&input_timer, 100);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  press_key('3');
+
+  timer_set(&input_timer, 100);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  press_key('4');
+
+  timer_set(&input_timer, 1500);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  press_key('1');
+
+  timer_set(&input_timer, 300);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  press_key('4');
+
+  timer_set(&input_timer, 400);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  press_key('2');
+
+  timer_set(&input_timer, 500);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  press_key('3');
+
+  timer_set(&input_timer, 2000);
+  PT_WAIT_UNTIL(pt, timer_expired(&input_timer));
+
+  PT_END(pt);
+}
+/*---------------------------------------------------------------------------*/
+/*
+ * This is the main function. It initializes the two protothread
+ * control structures and schedules the two protothreads. The main
+ * function returns when the protothread the runs the code lock exits.
+ */
+int
+main(void)
+{
+  /*
+   * Initialize the two protothread control structures.
+   */
+  PT_INIT(&input_pt);
+  PT_INIT(&codelock_pt);
+
+  /*
+   * Schedule the two protothreads until the codelock_thread() exits.
+   */
+  while(PT_SCHEDULE(codelock_thread(&codelock_pt))) {
+    PT_SCHEDULE(input_thread(&input_pt));
+
+    /*
+     * When running this example on a multitasking system, we must
+     * give other processes a chance to run too and therefore we call
+     * usleep() resp. Sleep() here. On a dedicated embedded system,
+     * we usually do not need to do this.
+     */
+#ifdef _WIN32
+    Sleep(0);
+#else
+    usleep(10);
+#endif
+  }
+
+  return 0;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ * Finally, the implementation of the simple timer library follows.
+ */
+#ifdef _WIN32
+
+static int clock_time(void)
+{ return (int)GetTickCount(); }
+
+#else /* _WIN32 */
+
+static int clock_time(void)
+{
+  struct timeval tv;
+  struct timezone tz;
+  gettimeofday(&tv, &tz);
+  return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+}
+
+#endif /* _WIN32 */
+
+static int timer_expired(struct timer *t)
+{ return (int)(clock_time() - t->start) >= (int)t->interval; }
+
+static void timer_set(struct timer *t, int interval)
+{ t->interval = interval; t->start = clock_time(); }
+/*---------------------------------------------------------------------------*/
diff --git a/third_party/pt/example-small.c b/third_party/pt/example-small.c
new file mode 100644
index 0000000..f65836c
--- /dev/null
+++ b/third_party/pt/example-small.c
@@ -0,0 +1,97 @@
+/**
+ * This is a very small example that shows how to use
+ * protothreads. The program consists of two protothreads that wait
+ * for each other to toggle a variable.
+ */
+
+/* We must always include pt.h in our protothreads code. */
+#include "pt.h"
+
+#include <stdio.h> /* For printf(). */
+
+/* Two flags that the two protothread functions use. */
+static int protothread1_flag, protothread2_flag;
+
+/**
+ * The first protothread function. A protothread function must always
+ * return an integer, but must never explicitly return - returning is
+ * performed inside the protothread statements.
+ *
+ * The protothread function is driven by the main loop further down in
+ * the code.
+ */
+static int
+protothread1(struct pt *pt)
+{
+  /* A protothread function must begin with PT_BEGIN() which takes a
+     pointer to a struct pt. */
+  PT_BEGIN(pt);
+
+  /* We loop forever here. */
+  while(1) {
+    /* Wait until the other protothread has set its flag. */
+    PT_WAIT_UNTIL(pt, protothread2_flag != 0);
+    printf("Protothread 1 running\n");
+
+    /* We then reset the other protothread's flag, and set our own
+       flag so that the other protothread can run. */
+    protothread2_flag = 0;
+    protothread1_flag = 1;
+
+    /* And we loop. */
+  }
+
+  /* All protothread functions must end with PT_END() which takes a
+     pointer to a struct pt. */
+  PT_END(pt);
+}
+
+/**
+ * The second protothread function. This is almost the same as the
+ * first one.
+ */
+static int
+protothread2(struct pt *pt)
+{
+  PT_BEGIN(pt);
+
+  while(1) {
+    /* Let the other protothread run. */
+    protothread2_flag = 1;
+
+    /* Wait until the other protothread has set its flag. */
+    PT_WAIT_UNTIL(pt, protothread1_flag != 0);
+    printf("Protothread 2 running\n");
+
+    /* We then reset the other protothread's flag. */
+    protothread1_flag = 0;
+
+    /* And we loop. */
+  }
+  PT_END(pt);
+}
+
+/**
+ * Finally, we have the main loop. Here is where the protothreads are
+ * initialized and scheduled. First, however, we define the
+ * protothread state variables pt1 and pt2, which hold the state of
+ * the two protothreads.
+ */
+static struct pt pt1, pt2;
+int
+main(void)
+{
+  /* Initialize the protothread state variables with PT_INIT(). */
+  PT_INIT(&pt1);
+  PT_INIT(&pt2);
+
+  /*
+   * Then we schedule the two protothreads by repeatedly calling their
+   * protothread functions and passing a pointer to the protothread
+   * state variables as arguments.
+   */
+  while(1) {
+    protothread1(&pt1);
+    protothread2(&pt2);
+  }
+}
diff --git a/third_party/pt/lc-addrlabels.h b/third_party/pt/lc-addrlabels.h
new file mode 100644
index 0000000..3e6474e
--- /dev/null
+++ b/third_party/pt/lc-addrlabels.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc-addrlabels.h,v 1.4 2006/06/03 11:29:43 adam Exp $
+ */
+
+/**
+ * \addtogroup lc
+ * @{
+ */
+
+/**
+ * \file
+ * Implementation of local continuations based on the "Labels as
+ * values" feature of gcc
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ * This implementation of local continuations is based on a special
+ * feature of the GCC C compiler called "labels as values". This
+ * feature allows assigning pointers with the address of the code
+ * corresponding to a particular C label.
+ *
+ * For more information, see the GCC documentation:
+ * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
+ *
+ */
+
+#ifndef __LC_ADDRLABELS_H__
+#define __LC_ADDRLABELS_H__
+
+/** \hideinitializer */
+typedef void * lc_t;
+
+#define LC_INIT(s) s = NULL
+
+#define LC_RESUME(s)				\
+  do {						\
+    if(s != NULL) {				\
+      goto *s;					\
+    }						\
+  } while(0)
+
+#define LC_CONCAT2(s1, s2) s1##s2
+#define LC_CONCAT(s1, s2) LC_CONCAT2(s1, s2)
+
+#define LC_SET(s)				\
+  do {						\
+    LC_CONCAT(LC_LABEL, __LINE__):   	        \
+    (s) = &&LC_CONCAT(LC_LABEL, __LINE__);	\
+  } while(0)
+
+#define LC_END(s)
+
+#endif /* __LC_ADDRLABELS_H__ */
+/** @} */
diff --git a/third_party/pt/lc-switch.h b/third_party/pt/lc-switch.h
new file mode 100644
index 0000000..dbdde01
--- /dev/null
+++ b/third_party/pt/lc-switch.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc-switch.h,v 1.4 2006/06/03 11:29:43 adam Exp $
+ */
+
+/**
+ * \addtogroup lc
+ * @{
+ */
+
+/**
+ * \file
+ * Implementation of local continuations based on switch() statment
+ * \author Adam Dunkels <adam@sics.se>
+ *
+ * This implementation of local continuations uses the C switch()
+ * statement to resume execution of a function somewhere inside the
+ * function's body. The implementation is based on the fact that
+ * switch() statements are able to jump directly into the bodies of
+ * control structures such as if() or while() statmenets.
+ *
+ * This implementation borrows heavily from Simon Tatham's coroutines
+ * implementation in C:
+ * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
+ */
+
+#ifndef __LC_SWITCH_H__
+#define __LC_SWITCH_H__
+
+/* WARNING! lc implementation using switch() does not work if an
+   LC_SET() is done within another switch() statement! */
+
+/** \hideinitializer */
+typedef unsigned short lc_t;
+
+#define LC_INIT(s) s = 0;
+
+#define LC_RESUME(s) switch(s) { case 0:
+
+#define LC_SET(s) s = __LINE__; case __LINE__:
+
+#define LC_END(s) }
+
+#endif /* __LC_SWITCH_H__ */
+
+/** @} */
diff --git a/third_party/pt/lc.h b/third_party/pt/lc.h
new file mode 100644
index 0000000..0cf57e0
--- /dev/null
+++ b/third_party/pt/lc.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the protothreads library.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc.h,v 1.2 2005/02/24 10:36:59 adam Exp $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \defgroup lc Local continuations
+ * @{
+ *
+ * Local continuations form the basis for implementing protothreads. A
+ * local continuation can be <i>set</i> in a specific function to
+ * capture the state of the function. After a local continuation has
+ * been set can be <i>resumed</i> in order to restore the state of the
+ * function at the point where the local continuation was set.
+ *
+ *
+ */
+
+/**
+ * \file lc.h
+ * Local continuations
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifdef DOXYGEN
+/**
+ * Initialize a local continuation.
+ *
+ * This operation initializes the local continuation, thereby
+ * unsetting any previously set continuation state.
+ *
+ * \hideinitializer
+ */
+#define LC_INIT(lc)
+
+/**
+ * Set a local continuation.
+ *
+ * The set operation saves the state of the function at the point
+ * where the operation is executed. As far as the set operation is
+ * concerned, the state of the function does <b>not</b> include the
+ * call-stack or local (automatic) variables, but only the program
+ * counter and such CPU registers that needs to be saved.
+ *
+ * \hideinitializer
+ */
+#define LC_SET(lc)
+
+/**
+ * Resume a local continuation.
+ *
+ * The resume operation resumes a previously set local continuation, thus
+ * restoring the state in which the function was when the local
+ * continuation was set. If the local continuation has not been
+ * previously set, the resume operation does nothing.
+ *
+ * \hideinitializer
+ */
+#define LC_RESUME(lc)
+
+/**
+ * Mark the end of local continuation usage.
+ *
+ * The end operation signifies that local continuations should not be
+ * used any more in the function. This operation is not needed for
+ * most implementations of local continuation, but is required by a
+ * few implementations.
+ *
+ * \hideinitializer
+ */
+#define LC_END(lc)
+
+/**
+ * \var typedef lc_t;
+ *
+ * The local continuation type.
+ *
+ * \hideinitializer
+ */
+#endif /* DOXYGEN */
+
+#ifndef __LC_H__
+#define __LC_H__
+
+
+#ifdef LC_INCLUDE
+#include LC_INCLUDE
+#else
+#include "lc-switch.h"
+#endif /* LC_INCLUDE */
+
+#endif /* __LC_H__ */
+
+/** @} */
+/** @} */
diff --git a/third_party/pt/pt-sem.h b/third_party/pt/pt-sem.h
new file mode 100644
index 0000000..5180dc6
--- /dev/null
+++ b/third_party/pt/pt-sem.h
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the protothreads library.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: pt-sem.h,v 1.2 2005/02/24 10:36:59 adam Exp $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \defgroup ptsem Protothread semaphores
+ * @{
+ *
+ * This module implements counting semaphores on top of
+ * protothreads. Semaphores are a synchronization primitive that
+ * provide two operations: "wait" and "signal". The "wait" operation
+ * checks the semaphore counter and blocks the thread if the counter
+ * is zero. The "signal" operation increases the semaphore counter but
+ * does not block. If another thread has blocked waiting for the
+ * semaphore that is signalled, the blocked thread will become
+ * runnable again.
+ *
+ * Semaphores can be used to implement other, more structured,
+ * synchronization primitives such as monitors and message
+ * queues/bounded buffers (see below).
+ *
+ * The following example shows how the producer-consumer problem, also
+ * known as the bounded buffer problem, can be solved using
+ * protothreads and semaphores. Notes on the program follow after the
+ * example.
+ *
+ \code
+#include "pt-sem.h"
+
+#define NUM_ITEMS 32
+#define BUFSIZE 8
+
+static struct pt_sem mutex, full, empty;
+
+PT_THREAD(producer(struct pt *pt))
+{
+  static int produced;
+
+  PT_BEGIN(pt);
+
+  for(produced = 0; produced < NUM_ITEMS; ++produced) {
+
+    PT_SEM_WAIT(pt, &full);
+
+    PT_SEM_WAIT(pt, &mutex);
+    add_to_buffer(produce_item());
+    PT_SEM_SIGNAL(pt, &mutex);
+
+    PT_SEM_SIGNAL(pt, &empty);
+  }
+
+  PT_END(pt);
+}
+
+PT_THREAD(consumer(struct pt *pt))
+{
+  static int consumed;
+
+  PT_BEGIN(pt);
+
+  for(consumed = 0; consumed < NUM_ITEMS; ++consumed) {
+
+    PT_SEM_WAIT(pt, &empty);
+
+    PT_SEM_WAIT(pt, &mutex);
+    consume_item(get_from_buffer());
+    PT_SEM_SIGNAL(pt, &mutex);
+
+    PT_SEM_SIGNAL(pt, &full);
+  }
+
+  PT_END(pt);
+}
+
+PT_THREAD(driver_thread(struct pt *pt))
+{
+  static struct pt pt_producer, pt_consumer;
+
+  PT_BEGIN(pt);
+
+  PT_SEM_INIT(&empty, 0);
+  PT_SEM_INIT(&full, BUFSIZE);
+  PT_SEM_INIT(&mutex, 1);
+
+  PT_INIT(&pt_producer);
+  PT_INIT(&pt_consumer);
+
+  PT_WAIT_THREAD(pt, producer(&pt_producer) &
+		     consumer(&pt_consumer));
+
+  PT_END(pt);
+}
+ \endcode
+ *
+ * The program uses three protothreads: one protothread that
+ * implements the consumer, one thread that implements the producer,
+ * and one protothread that drives the two other protothreads. The
+ * program uses three semaphores: "full", "empty" and "mutex". The
+ * "mutex" semaphore is used to provide mutual exclusion for the
+ * buffer, the "empty" semaphore is used to block the consumer is the
+ * buffer is empty, and the "full" semaphore is used to block the
+ * producer is the buffer is full.
+ *
+ * The "driver_thread" holds two protothread state variables,
+ * "pt_producer" and "pt_consumer". It is important to note that both
+ * these variables are declared as <i>static</i>. If the static
+ * keyword is not used, both variables are stored on the stack. Since
+ * protothreads do not store the stack, these variables may be
+ * overwritten during a protothread wait operation. Similarly, both
+ * the "consumer" and "producer" protothreads declare their local
+ * variables as static, to avoid them being stored on the stack.
+ *
+ *
+ */
+
+/**
+ * \file
+ * Couting semaphores implemented on protothreads
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __PT_SEM_H__
+#define __PT_SEM_H__
+
+#include "pt.h"
+
+struct pt_sem {
+  unsigned int count;
+};
+
+/**
+ * Initialize a semaphore
+ *
+ * This macro initializes a semaphore with a value for the
+ * counter. Internally, the semaphores use an "unsigned int" to
+ * represent the counter, and therefore the "count" argument should be
+ * within range of an unsigned int.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \param c (unsigned int) The initial count of the semaphore.
+ * \hideinitializer
+ */
+#define PT_SEM_INIT(s, c) (s)->count = c
+
+/**
+ * Wait for a semaphore
+ *
+ * This macro carries out the "wait" operation on the semaphore. The
+ * wait operation causes the protothread to block while the counter is
+ * zero. When the counter reaches a value larger than zero, the
+ * protothread will continue.
+ *
+ * \param pt (struct pt *) A pointer to the protothread (struct pt) in
+ * which the operation is executed.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \hideinitializer
+ */
+#define PT_SEM_WAIT(pt, s)	\
+  do {						\
+    PT_WAIT_UNTIL(pt, (s)->count > 0);		\
+    --(s)->count;				\
+  } while(0)
+
+/**
+ * Signal a semaphore
+ *
+ * This macro carries out the "signal" operation on the semaphore. The
+ * signal operation increments the counter inside the semaphore, which
+ * eventually will cause waiting protothreads to continue executing.
+ *
+ * \param pt (struct pt *) A pointer to the protothread (struct pt) in
+ * which the operation is executed.
+ *
+ * \param s (struct pt_sem *) A pointer to the pt_sem struct
+ * representing the semaphore
+ *
+ * \hideinitializer
+ */
+#define PT_SEM_SIGNAL(pt, s) ++(s)->count
+
+#endif /* __PT_SEM_H__ */
+
+/** @} */
+/** @} */
diff --git a/third_party/pt/pt.h b/third_party/pt/pt.h
new file mode 100644
index 0000000..92856cb
--- /dev/null
+++ b/third_party/pt/pt.h
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the Contiki operating system.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: pt.h,v 1.7 2006/10/02 07:52:56 adam Exp $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \file
+ * Protothreads implementation.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __PT_H__
+#define __PT_H__
+
+#include "lc.h"
+
+struct pt {
+  lc_t lc;
+};
+
+#define PT_WAITING 0
+#define PT_YIELDED 1
+#define PT_EXITED  2
+#define PT_ENDED   3
+
+/**
+ * \name Initialization
+ * @{
+ */
+
+/**
+ * Initialize a protothread.
+ *
+ * Initializes a protothread. Initialization must be done prior to
+ * starting to execute the protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_INIT(pt)   LC_INIT((pt)->lc)
+
+/** @} */
+
+/**
+ * \name Declaration and definition
+ * @{
+ */
+
+/**
+ * Declaration of a protothread.
+ *
+ * This macro is used to declare a protothread. All protothreads must
+ * be declared with this macro.
+ *
+ * \param name_args The name and arguments of the C function
+ * implementing the protothread.
+ *
+ * \hideinitializer
+ */
+#define PT_THREAD(name_args) char name_args
+
+/**
+ * Declare the start of a protothread inside the C function
+ * implementing the protothread.
+ *
+ * This macro is used to declare the starting point of a
+ * protothread. It should be placed at the start of the function in
+ * which the protothread runs. All C statements above the PT_BEGIN()
+ * invokation will be executed each time the protothread is scheduled.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
+
+/**
+ * Declare the end of a protothread.
+ *
+ * This macro is used for declaring that a protothread ends. It must
+ * always be used together with a matching PT_BEGIN() macro.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
+                   PT_INIT(pt); return PT_ENDED; }
+
+/** @} */
+
+/**
+ * \name Blocked wait
+ * @{
+ */
+
+/**
+ * Block and wait until condition is true.
+ *
+ * This macro blocks the protothread until the specified condition is
+ * true.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param condition The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_UNTIL(pt, condition)	        \
+  do {						\
+    LC_SET((pt)->lc);				\
+    if(!(condition)) {				\
+      return PT_WAITING;			\
+    }						\
+  } while(0)
+
+/**
+ * Block and wait while condition is true.
+ *
+ * This function blocks and waits while condition is true. See
+ * PT_WAIT_UNTIL().
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_WHILE(pt, cond)  PT_WAIT_UNTIL((pt), !(cond))
+
+/** @} */
+
+/**
+ * \name Hierarchical protothreads
+ * @{
+ */
+
+/**
+ * Block and wait until a child protothread completes.
+ *
+ * This macro schedules a child protothread. The current protothread
+ * will block until the child protothread completes.
+ *
+ * \note The child protothread must be manually initialized with the
+ * PT_INIT() function before this function is used.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
+
+/**
+ * Spawn a child protothread and wait until it exits.
+ *
+ * This macro spawns a child protothread and waits until it exits. The
+ * macro can only be used within a protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param child A pointer to the child protothread's control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \hideinitializer
+ */
+#define PT_SPAWN(pt, child, thread)		\
+  do {						\
+    PT_INIT((child));				\
+    PT_WAIT_THREAD((pt), (thread));		\
+  } while(0)
+
+/** @} */
+
+/**
+ * \name Exiting and restarting
+ * @{
+ */
+
+/**
+ * Restart the protothread.
+ *
+ * This macro will block and cause the running protothread to restart
+ * its execution at the place of the PT_BEGIN() call.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_RESTART(pt)				\
+  do {						\
+    PT_INIT(pt);				\
+    return PT_WAITING;			\
+  } while(0)
+
+/**
+ * Exit the protothread.
+ *
+ * This macro causes the protothread to exit. If the protothread was
+ * spawned by another protothread, the parent protothread will become
+ * unblocked and can continue to run.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_EXIT(pt)				\
+  do {						\
+    PT_INIT(pt);				\
+    return PT_EXITED;			\
+  } while(0)
+
+/** @} */
+
+/**
+ * \name Calling a protothread
+ * @{
+ */
+
+/**
+ * Schedule a protothread.
+ *
+ * This function shedules a protothread. The return value of the
+ * function is non-zero if the protothread is running or zero if the
+ * protothread has exited.
+ *
+ * \param f The call to the C function implementing the protothread to
+ * be scheduled
+ *
+ * \hideinitializer
+ */
+#define PT_SCHEDULE(f) ((f) < PT_EXITED)
+
+/** @} */
+
+/**
+ * \name Yielding from a protothread
+ * @{
+ */
+
+/**
+ * Yield from the current protothread.
+ *
+ * This function will yield the protothread, thereby allowing other
+ * processing to take place in the system.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD(pt)				\
+  do {						\
+    PT_YIELD_FLAG = 0;				\
+    LC_SET((pt)->lc);				\
+    if(PT_YIELD_FLAG == 0) {			\
+      return PT_YIELDED;			\
+    }						\
+  } while(0)
+
+/**
+ * \brief      Yield from the protothread until a condition occurs.
+ * \param pt   A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ *             This function will yield the protothread, until the
+ *             specified condition evaluates to true.
+ *
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD_UNTIL(pt, cond)		\
+  do {						\
+    PT_YIELD_FLAG = 0;				\
+    LC_SET((pt)->lc);				\
+    if((PT_YIELD_FLAG == 0) || !(cond)) {	\
+      return PT_YIELDED;			\
+    }						\
+  } while(0)
+
+/** @} */
+
+#endif /* __PT_H__ */
+
+/** @} */