diff --git a/.waf-tools/boost.py b/.waf-tools/boost.py
new file mode 100644
index 0000000..dedb9d8
--- /dev/null
+++ b/.waf-tools/boost.py
@@ -0,0 +1,378 @@
+#!/usr/bin/env python
+# encoding: utf-8
+#
+# partially based on boost.py written by Gernot Vormayr
+# written by Ruediger Sonderfeld <ruediger@c-plusplus.de>, 2008
+# modified by Bjoern Michaelsen, 2008
+# modified by Luca Fossati, 2008
+# rewritten for waf 1.5.1, Thomas Nagy, 2008
+# rewritten for waf 1.6.2, Sylvain Rouquette, 2011
+
+'''
+
+This is an extra tool, not bundled with the default waf binary.
+To add the boost tool to the waf file:
+$ ./waf-light --tools=compat15,boost
+    or, if you have waf >= 1.6.2
+$ ./waf update --files=boost
+
+When using this tool, the wscript will look like:
+
+    def options(opt):
+        opt.load('compiler_cxx boost')
+
+    def configure(conf):
+        conf.load('compiler_cxx boost')
+        conf.check_boost(lib='system filesystem')
+
+    def build(bld):
+        bld(source='main.cpp', target='app', use='BOOST')
+
+Options are generated, in order to specify the location of boost includes/libraries.
+The `check_boost` configuration function allows to specify the used boost libraries.
+It can also provide default arguments to the --boost-static and --boost-mt command-line arguments.
+Everything will be packaged together in a BOOST component that you can use.
+
+When using MSVC, a lot of compilation flags need to match your BOOST build configuration:
+ - you may have to add /EHsc to your CXXFLAGS or define boost::throw_exception if BOOST_NO_EXCEPTIONS is defined.
+   Errors: C4530
+ - boost libraries will try to be smart and use the (pretty but often not useful) auto-linking feature of MSVC
+   So before calling `conf.check_boost` you might want to disabling by adding:
+       conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB']
+   Errors:
+ - boost might also be compiled with /MT, which links the runtime statically.
+   If you have problems with redefined symbols,
+        self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB']
+        self.env['CXXFLAGS_%s' % var] += ['/MD', '/EHsc']
+Passing `--boost-linkage_autodetect` might help ensuring having a correct linkage in some basic cases.
+
+'''
+
+import sys
+import re
+from waflib import Utils, Logs, Errors
+from waflib.Configure import conf
+
+BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib', '/usr/lib/x86_64-linux-gnu', '/usr/lib/i386-linux-gnu', '/usr/local/ndn/lib']
+BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/include', '/usr/local/ndn/include']
+BOOST_VERSION_FILE = 'boost/version.hpp'
+BOOST_VERSION_CODE = '''
+#include <iostream>
+#include <boost/version.hpp>
+int main() { std::cout << BOOST_LIB_VERSION << ":" << BOOST_VERSION << std::endl; }
+'''
+BOOST_SYSTEM_CODE = '''
+#include <boost/system/error_code.hpp>
+int main() { boost::system::error_code c; }
+'''
+BOOST_THREAD_CODE = '''
+#include <boost/thread.hpp>
+int main() { boost::thread t; }
+'''
+
+# toolsets from {boost_dir}/tools/build/v2/tools/common.jam
+PLATFORM = Utils.unversioned_sys_platform()
+detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il'
+detect_clang = lambda env: (PLATFORM == 'darwin') and 'clang-darwin' or 'clang'
+detect_mingw = lambda env: (re.search('MinGW', env.CXX[0])) and 'mgw' or 'gcc'
+BOOST_TOOLSETS = {
+    'borland':  'bcb',
+    'clang':    detect_clang,
+    'como':     'como',
+    'cw':       'cw',
+    'darwin':   'xgcc',
+    'edg':      'edg',
+    'g++':      detect_mingw,
+    'gcc':      detect_mingw,
+    'icpc':     detect_intel,
+    'intel':    detect_intel,
+    'kcc':      'kcc',
+    'kylix':    'bck',
+    'mipspro':  'mp',
+    'mingw':    'mgw',
+    'msvc':     'vc',
+    'qcc':      'qcc',
+    'sun':      'sw',
+    'sunc++':   'sw',
+    'tru64cxx': 'tru',
+    'vacpp':    'xlc'
+}
+
+
+def options(opt):
+    opt = opt.add_option_group('Boost Options')
+
+    opt.add_option('--boost-includes', type='string',
+                   default='', dest='boost_includes',
+                   help='''path to the directory where the boost includes are, e.g., /path/to/boost_1_55_0/stage/include''')
+    opt.add_option('--boost-libs', type='string',
+                   default='', dest='boost_libs',
+                   help='''path to the directory where the boost libs are, e.g., /path/to/boost_1_55_0/stage/lib''')
+    opt.add_option('--boost-static', action='store_true',
+                   default=False, dest='boost_static',
+                   help='link with static boost libraries (.lib/.a)')
+    opt.add_option('--boost-mt', action='store_true',
+                   default=False, dest='boost_mt',
+                   help='select multi-threaded libraries')
+    opt.add_option('--boost-abi', type='string', default='', dest='boost_abi',
+                   help='''select libraries with tags (dgsyp, d for debug), see doc Boost, Getting Started, chapter 6.1''')
+    opt.add_option('--boost-linkage_autodetect', action="store_true", dest='boost_linkage_autodetect',
+                   help="auto-detect boost linkage options (don't get used to it / might break other stuff)")
+    opt.add_option('--boost-toolset', type='string',
+                   default='', dest='boost_toolset',
+                   help='force a toolset e.g. msvc, vc90, gcc, mingw, mgw45 (default: auto)')
+    py_version = '%d%d' % (sys.version_info[0], sys.version_info[1])
+    opt.add_option('--boost-python', type='string',
+                   default=py_version, dest='boost_python',
+                   help='select the lib python with this version (default: %s)' % py_version)
+
+
+@conf
+def __boost_get_version_file(self, d):
+    dnode = self.root.find_dir(d)
+    if dnode:
+        return dnode.find_node(BOOST_VERSION_FILE)
+    return None
+
+@conf
+def boost_get_version(self, d):
+    """silently retrieve the boost version number"""
+    node = self.__boost_get_version_file(d)
+    if node:
+        try:
+            txt = node.read()
+        except (OSError, IOError):
+            Logs.error("Could not read the file %r" % node.abspath())
+        else:
+            re_but1 = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.+)"', re.M)
+            m1 = re_but1.search(txt)
+
+            re_but2 = re.compile('^#define\\s+BOOST_VERSION\\s+(\\d+)', re.M)
+            m2 = re_but2.search(txt)
+
+            if m1 and m2:
+                return (m1.group(1), m2.group(1))
+
+    return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(":")
+
+@conf
+def boost_get_includes(self, *k, **kw):
+    includes = k and k[0] or kw.get('includes', None)
+    if includes and self.__boost_get_version_file(includes):
+        return includes
+    for d in Utils.to_list(self.environ.get('INCLUDE', '')) + BOOST_INCLUDES:
+        if self.__boost_get_version_file(d):
+            return d
+    if includes:
+        self.end_msg('headers not found in %s' % includes)
+        self.fatal('The configuration failed')
+    else:
+        self.end_msg('headers not found, please provide a --boost-includes argument (see help)')
+        self.fatal('The configuration failed')
+
+
+@conf
+def boost_get_toolset(self, cc):
+    toolset = cc
+    if not cc:
+        build_platform = Utils.unversioned_sys_platform()
+        if build_platform in BOOST_TOOLSETS:
+            cc = build_platform
+        else:
+            cc = self.env.CXX_NAME
+    if cc in BOOST_TOOLSETS:
+        toolset = BOOST_TOOLSETS[cc]
+    return isinstance(toolset, str) and toolset or toolset(self.env)
+
+
+@conf
+def __boost_get_libs_path(self, *k, **kw):
+    ''' return the lib path and all the files in it '''
+    if 'files' in kw:
+        return self.root.find_dir('.'), Utils.to_list(kw['files'])
+    libs = k and k[0] or kw.get('libs', None)
+    if libs:
+        path = self.root.find_dir(libs)
+        files = path.ant_glob('*boost_*')
+    if not libs or not files:
+        for d in Utils.to_list(self.environ.get('LIB', [])) + BOOST_LIBS:
+            path = self.root.find_dir(d)
+            if path:
+                files = path.ant_glob('*boost_*')
+                if files:
+                    break
+            path = self.root.find_dir(d + '64')
+            if path:
+                files = path.ant_glob('*boost_*')
+                if files:
+                    break
+    if not path:
+        if libs:
+            self.end_msg('libs not found in %s' % libs)
+            self.fatal('The configuration failed')
+        else:
+            self.end_msg('libs not found, please provide a --boost-libs argument (see help)')
+            self.fatal('The configuration failed')
+
+    self.to_log('Found the boost path in %r with the libraries:' % path)
+    for x in files:
+        self.to_log('    %r' % x)
+    return path, files
+
+@conf
+def boost_get_libs(self, *k, **kw):
+    '''
+    return the lib path and the required libs
+    according to the parameters
+    '''
+    path, files = self.__boost_get_libs_path(**kw)
+    t = []
+    if kw.get('mt', False):
+        t.append('mt')
+    if kw.get('abi', None):
+        t.append(kw['abi'])
+    tags = t and '(-%s)+' % '-'.join(t) or ''
+    toolset = self.boost_get_toolset(kw.get('toolset', ''))
+    toolset_pat = '(-%s[0-9]{0,3})+' % toolset
+    version = '(-%s)+' % self.env.BOOST_VERSION
+
+    def find_lib(re_lib, files):
+        for file in files:
+            if re_lib.search(file.name):
+                self.to_log('Found boost lib %s' % file)
+                return file
+        return None
+
+    def format_lib_name(name):
+        if name.startswith('lib') and self.env.CC_NAME != 'msvc':
+            name = name[3:]
+        return name[:name.rfind('.')]
+
+    libs = []
+    for lib in Utils.to_list(k and k[0] or kw.get('lib', None)):
+        py = (lib == 'python') and '(-py%s)+' % kw['python'] or ''
+        # Trying libraries, from most strict match to least one
+        for pattern in ['boost_%s%s%s%s%s' % (lib, toolset_pat, tags, py, version),
+                        'boost_%s%s%s%s' % (lib, tags, py, version),
+                        'boost_%s%s%s' % (lib, tags, version),
+                        # Give up trying to find the right version
+                        'boost_%s%s%s%s' % (lib, toolset_pat, tags, py),
+                        'boost_%s%s%s' % (lib, tags, py),
+                        'boost_%s%s' % (lib, tags)]:
+            self.to_log('Trying pattern %s' % pattern)
+            file = find_lib(re.compile(pattern), files)
+            if file:
+                libs.append(format_lib_name(file.name))
+                break
+        else:
+            self.end_msg('lib %s not found in %s' % (lib, path.abspath()))
+            self.fatal('The configuration failed')
+
+    return path.abspath(), libs
+
+
+@conf
+def check_boost(self, *k, **kw):
+    """
+    Initialize boost libraries to be used.
+
+    Keywords: you can pass the same parameters as with the command line (without "--boost-").
+    Note that the command line has the priority, and should preferably be used.
+    """
+    if not self.env['CXX']:
+        self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
+
+    params = {'lib': k and k[0] or kw.get('lib', None)}
+    for key, value in self.options.__dict__.items():
+        if not key.startswith('boost_'):
+            continue
+        key = key[len('boost_'):]
+        params[key] = value and value or kw.get(key, '')
+
+    var = kw.get('uselib_store', 'BOOST')
+
+    self.start_msg('Checking boost includes')
+    self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params)
+    versions = self.boost_get_version(inc)
+    self.env.BOOST_VERSION = versions[0]
+    self.env.BOOST_VERSION_NUMBER = int(versions[1])
+    self.end_msg("%d.%d.%d" % (int(versions[1]) / 100000,
+                   int(versions[1]) / 100 % 1000,
+                   int(versions[1]) % 100))
+    if Logs.verbose:
+        Logs.pprint('CYAN', '    path : %s' % self.env['INCLUDES_%s' % var])
+
+    if not params['lib']:
+        return
+    self.start_msg('Checking boost libs')
+    suffix = params.get('static', None) and 'ST' or ''
+    path, libs = self.boost_get_libs(**params)
+    self.env['%sLIBPATH_%s' % (suffix, var)] = [path]
+    self.env['%sLIB_%s' % (suffix, var)] = libs
+    self.end_msg('ok')
+    if Logs.verbose:
+        Logs.pprint('CYAN', '    path : %s' % path)
+        Logs.pprint('CYAN', '    libs : %s' % libs)
+
+
+    def try_link():
+        if 'system' in params['lib']:
+            self.check_cxx(
+             fragment=BOOST_SYSTEM_CODE,
+             use=var,
+             execute=False,
+            )
+        if 'thread' in params['lib']:
+            self.check_cxx(
+             fragment=BOOST_THREAD_CODE,
+             use=var,
+             execute=False,
+            )
+
+    if params.get('linkage_autodetect', False):
+        self.start_msg("Attempting to detect boost linkage flags")
+        toolset = self.boost_get_toolset(kw.get('toolset', ''))
+        if toolset in ['vc']:
+            # disable auto-linking feature, causing error LNK1181
+            # because the code wants to be linked against
+            self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB']
+
+            # if no dlls are present, we guess the .lib files are not stubs
+            has_dlls = False
+            for x in Utils.listdir(path):
+                if x.endswith(self.env.cxxshlib_PATTERN % ''):
+                    has_dlls = True
+                    break
+            if not has_dlls:
+                self.env['STLIBPATH_%s' % var] = [path]
+                self.env['STLIB_%s' % var] = libs
+                del self.env['LIB_%s' % var]
+                del self.env['LIBPATH_%s' % var]
+
+            # we attempt to play with some known-to-work CXXFLAGS combinations
+            for cxxflags in (['/MD', '/EHsc'], []):
+                self.env.stash()
+                self.env["CXXFLAGS_%s" % var] += cxxflags
+                try:
+                    try_link()
+                    self.end_msg("ok: winning cxxflags combination: %s" % (self.env["CXXFLAGS_%s" % var]))
+                    e = None
+                    break
+                except Errors.ConfigurationError as exc:
+                    self.env.revert()
+                    e = exc
+
+            if e is not None:
+                self.end_msg("Could not auto-detect boost linking flags combination, you may report it to boost.py author", ex=e)
+                self.fatal('The configuration failed')
+        else:
+            self.end_msg("Boost linkage flags auto-detection not implemented (needed ?) for this toolchain")
+            self.fatal('The configuration failed')
+    else:
+        self.start_msg('Checking for boost linkage')
+        try:
+            try_link()
+        except Errors.ConfigurationError as e:
+            self.end_msg("Could not link against boost libraries using supplied options")
+            self.fatal('The configuration failed')
+        self.end_msg('ok')
