diff --git a/.waf-tools/boost.py b/.waf-tools/boost.py
new file mode 100644
index 0000000..9feba3a
--- /dev/null
+++ b/.waf-tools/boost.py
@@ -0,0 +1,533 @@
+#!/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-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
+from waflib.TaskGen import feature, after_method
+
+BOOST_LIBS = ['/usr/lib', '/usr/local/lib', '/opt/local/lib', '/sw/lib', '/lib']
+BOOST_INCLUDES = ['/usr/include', '/usr/local/include', '/opt/local/include', '/sw/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_ERROR_CODE = '''
+#include <boost/system/error_code.hpp>
+int main() { boost::system::error_code c; }
+'''
+
+PTHREAD_CODE = '''
+#include <pthread.h>
+static void* f(void*) { return 0; }
+int main() {
+	pthread_t th;
+	pthread_attr_t attr;
+	pthread_attr_init(&attr);
+	pthread_create(&th, &attr, &f, 0);
+	pthread_join(th, 0);
+	pthread_cleanup_push(0, 0);
+	pthread_cleanup_pop(0);
+	pthread_attr_destroy(&attr);
+}
+'''
+
+BOOST_THREAD_CODE = '''
+#include <boost/thread.hpp>
+int main() { boost::thread t; }
+'''
+
+BOOST_LOG_CODE = '''
+#include <boost/log/trivial.hpp>
+int main() { BOOST_LOG_TRIVIAL(info) << "boost_log is working"; }
+'''
+
+BOOST_LOG_SETUP_CODE = '''
+#include <boost/log/trivial.hpp>
+#include <boost/log/utility/setup/console.hpp>
+#include <boost/log/utility/setup/common_attributes.hpp>
+int main() {
+	using namespace boost::log;
+	add_common_attributes();
+	add_console_log(std::clog, keywords::format = "%Message%");
+	BOOST_LOG_TRIVIAL(info) << "boost_log_setup is working";
+}
+'''
+
+# 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-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 (gd for debug, static is automatically added),
+				   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):
+	if not d:
+		return None
+	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 EnvironmentError:
+			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 self.environ.get('INCLUDE', '').split(';') + BOOST_INCLUDES:
+		if self.__boost_get_version_file(d):
+			return d
+	if includes:
+		self.end_msg('headers not found in %s' % includes, 'YELLOW')
+		self.fatal('The configuration failed')
+	else:
+		self.end_msg('headers not found, please provide a --boost-includes argument (see help)', 'YELLOW')
+		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 self.environ.get('LIB', '').split(';') + BOOST_LIBS:
+			if not d:
+				continue
+			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, 'YELLOW')
+			self.fatal('The configuration failed')
+		else:
+			self.end_msg('libs not found, please provide a --boost-libs argument (see help)', 'YELLOW')
+			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)
+	files = sorted(files, key=lambda f: (len(f.name), f.name), reverse=True)
+	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('.')]
+
+	def match_libs(lib_names, is_static):
+		libs = []
+		lib_names = Utils.to_list(lib_names)
+		if not lib_names:
+			return libs
+		t = []
+		if kw.get('mt', False):
+			t.append('-mt')
+		if kw.get('abi', None):
+			t.append('%s%s' % (is_static and '-s' or '-', kw['abi']))
+		elif is_static:
+			t.append('-s')
+		tags_pat = t and ''.join(t) or ''
+		ext = is_static and self.env.cxxstlib_PATTERN or self.env.cxxshlib_PATTERN
+		ext = ext.partition('%s')[2] # remove '%s' or 'lib%s' from PATTERN
+
+		for lib in lib_names:
+			if lib == 'python':
+				# for instance, with python='27',
+				# accepts '-py27', '-py2', '27' and '2'
+				# but will reject '-py3', '-py26', '26' and '3'
+				tags = '({0})?((-py{2})|(-py{1}(?=[^0-9]))|({2})|({1}(?=[^0-9]))|(?=[^0-9])(?!-py))'.format(tags_pat, kw['python'][0], kw['python'])
+			else:
+				tags = tags_pat
+			# Trying libraries, from most strict match to least one
+			for pattern in ['boost_%s%s%s%s%s$' % (lib, toolset_pat, tags, version, ext),
+							'boost_%s%s%s%s$' % (lib, tags, version, ext),
+							# Give up trying to find the right version
+							'boost_%s%s%s%s$' % (lib, toolset_pat, tags, ext),
+							'boost_%s%s%s$' % (lib, tags, ext),
+							'boost_%s%s$' % (lib, ext),
+							'boost_%s' % lib]:
+				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()), 'YELLOW')
+				self.fatal('The configuration failed')
+		return libs
+
+	return  path.abspath(), match_libs(kw.get('lib', None), False), match_libs(kw.get('stlib', None), True)
+
+@conf
+def _check_pthread_flag(self, *k, **kw):
+	'''
+	Computes which flags should be added to CXXFLAGS and LINKFLAGS to compile in multi-threading mode
+
+	Yes, we *need* to put the -pthread thing in CPPFLAGS because with GCC3,
+	boost/thread.hpp will trigger a #error if -pthread isn't used:
+	  boost/config/requires_threads.hpp:47:5: #error "Compiler threading support
+	  is not turned on. Please set the correct command line options for
+	  threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)"
+
+	Based on _BOOST_PTHREAD_FLAG(): https://github.com/tsuna/boost.m4/blob/master/build-aux/boost.m4
+    '''
+
+	var = kw.get('uselib_store', 'BOOST')
+
+	self.start_msg('Checking the flags needed to use pthreads')
+
+	# The ordering *is* (sometimes) important.  Some notes on the
+	# individual items follow:
+	# (none): in case threads are in libc; should be tried before -Kthread and
+	#       other compiler flags to prevent continual compiler warnings
+	# -lpthreads: AIX (must check this before -lpthread)
+	# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+	# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+	# -llthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+	# -pthread: GNU Linux/GCC (kernel threads), BSD/GCC (userland threads)
+	# -pthreads: Solaris/GCC
+	# -mthreads: MinGW32/GCC, Lynx/GCC
+	# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+	#      doesn't hurt to check since this sometimes defines pthreads too;
+	#      also defines -D_REENTRANT)
+	#      ... -mt is also the pthreads flag for HP/aCC
+	# -lpthread: GNU Linux, etc.
+	# --thread-safe: KAI C++
+	if Utils.unversioned_sys_platform() == 'sunos':
+		# On Solaris (at least, for some versions), libc contains stubbed
+		# (non-functional) versions of the pthreads routines, so link-based
+		# tests will erroneously succeed.  (We need to link with -pthreads/-mt/
+		# -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+		# a function called by this macro, so we could check for that, but
+		# who knows whether they'll stub that too in a future libc.)  So,
+		# we'll just look for -pthreads and -lpthread first:
+		boost_pthread_flags = ['-pthreads', '-lpthread', '-mt', '-pthread']
+	else:
+		boost_pthread_flags = ['', '-lpthreads', '-Kthread', '-kthread', '-llthread', '-pthread',
+							   '-pthreads', '-mthreads', '-lpthread', '--thread-safe', '-mt']
+
+	for boost_pthread_flag in boost_pthread_flags:
+		try:
+			self.env.stash()
+			self.env['CXXFLAGS_%s' % var] += [boost_pthread_flag]
+			self.env['LINKFLAGS_%s' % var] += [boost_pthread_flag]
+			self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False, quiet=True)
+			self.end_msg(boost_pthread_flag)
+			return
+		except self.errors.ConfigurationError:
+			self.env.revert()
+	self.end_msg('none')
+
+@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),
+		'stlib': kw.get('stlib', 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')
+
+	if not self.env.DONE_FIND_BOOST_COMMON:
+		self.find_program('dpkg-architecture', var='DPKG_ARCHITECTURE', mandatory=False)
+		if self.env.DPKG_ARCHITECTURE:
+			deb_host_multiarch = self.cmd_and_log([self.env.DPKG_ARCHITECTURE[0], '-qDEB_HOST_MULTIARCH'])
+			BOOST_LIBS.insert(0, '/usr/lib/%s' % deb_host_multiarch.strip())
+
+		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])
+
+		self.env.DONE_FIND_BOOST_COMMON = True
+
+	if not params['lib'] and not params['stlib']:
+		return
+	if 'static' in kw or 'static' in params:
+		Logs.warn('boost: static parameter is deprecated, use stlib instead.')
+	self.start_msg('Checking boost libs')
+	path, libs, stlibs = self.boost_get_libs(**params)
+	self.env['LIBPATH_%s' % var] = [path]
+	self.env['STLIBPATH_%s' % var] = [path]
+	self.env['LIB_%s' % var] = libs
+	self.env['STLIB_%s' % var] = stlibs
+	self.end_msg(' '.join(libs + stlibs))
+	if Logs.verbose:
+		Logs.pprint('CYAN', '	path : %s' % path)
+		Logs.pprint('CYAN', '	shared libs : %s' % libs)
+		Logs.pprint('CYAN', '	static libs : %s' % stlibs)
+
+	def has_shlib(lib):
+		return params['lib'] and lib in params['lib']
+	def has_stlib(lib):
+		return params['stlib'] and lib in params['stlib']
+	def has_lib(lib):
+		return has_shlib(lib) or has_stlib(lib)
+	if has_lib('thread'):
+		# not inside try_link to make check visible in the output
+		self._check_pthread_flag(k, kw)
+
+	def try_link():
+		if has_lib('system'):
+			self.check_cxx(fragment=BOOST_ERROR_CODE, use=var, execute=False)
+		if has_lib('thread'):
+			self.check_cxx(fragment=BOOST_THREAD_CODE, use=var, execute=False)
+		if has_lib('log') or has_lib('log_setup'):
+			if not has_lib('thread'):
+				self.env['DEFINES_%s' % var] += ['BOOST_LOG_NO_THREADS']
+			if has_shlib('log') or has_shlib('log_setup'):
+				self.env['DEFINES_%s' % var] += ['BOOST_LOG_DYN_LINK']
+			if has_lib('log_setup'):
+				self.check_cxx(fragment=BOOST_LOG_SETUP_CODE, use=var, execute=False)
+			else:
+				self.check_cxx(fragment=BOOST_LOG_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]))
+					exc = None
+					break
+				except Errors.ConfigurationError as e:
+					self.env.revert()
+					exc = e
+
+			if exc is not None:
+				self.end_msg('Could not auto-detect boost linking flags combination, you may report it to boost.py author', ex=exc)
+				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', 'YELLOW')
+			self.fatal('The configuration failed')
+		self.end_msg('ok')
+
+
+@feature('cxx')
+@after_method('apply_link')
+def install_boost(self):
+	if install_boost.done or not Utils.is_win32 or not self.bld.cmd.startswith('install'):
+		return
+	install_boost.done = True
+	inst_to = getattr(self, 'install_path', '${BINDIR}')
+	for lib in self.env.LIB_BOOST:
+		try:
+			file = self.bld.find_file(self.env.cxxshlib_PATTERN % lib, self.env.LIBPATH_BOOST)
+			self.bld.install_files(inst_to, self.bld.root.find_node(file))
+		except:
+			continue
+install_boost.done = False
\ No newline at end of file
diff --git a/.waf-tools/cryptopp.py b/.waf-tools/cryptopp.py
new file mode 100644
index 0000000..b61c0bf
--- /dev/null
+++ b/.waf-tools/cryptopp.py
@@ -0,0 +1,77 @@
+#! /usr/bin/env python
+# encoding: utf-8
+
+'''
+
+When using this tool, the wscript will look like:
+
+	def options(opt):
+	        opt.tool_options('cryptopp', tooldir=["waf-tools"])
+
+	def configure(conf):
+		conf.load('compiler_cxx cryptopp')
+
+	def build(bld):
+		bld(source='main.cpp', target='app', use='CRYPTOPP')
+
+Options are generated, in order to specify the location of cryptopp includes/libraries.
+
+
+'''
+import sys
+import re
+from waflib import Utils,Logs,Errors
+from waflib.Configure import conf
+CRYPTOPP_DIR=['/usr','/usr/local','/opt/local','/sw']
+CRYPTOPP_VERSION_FILE='config.h'
+CRYPTOPP_VERSION_CODE='''
+#include <iostream>
+#include <cryptopp/config.h>
+int main() { std::cout << CRYPTOPP_VERSION; }
+'''
+
+def options(opt):
+	opt.add_option('--cryptopp',type='string',default='',dest='cryptopp_dir',help='''path to where cryptopp is installed, e.g. /opt/local''')
+@conf
+def __cryptopp_get_version_file(self,dir):
+	try:
+		return self.root.find_dir(dir).find_node('%s/%s' % ('include/cryptopp', CRYPTOPP_VERSION_FILE))
+	except:
+		return None
+@conf
+def cryptopp_get_version(self,dir):
+	val=self.check_cxx(fragment=CRYPTOPP_VERSION_CODE,includes=['%s/%s' % (dir, 'include')], execute=True, define_ret = True, mandatory=True)
+	return val
+@conf
+def cryptopp_get_root(self,*k,**kw):
+	root=k and k[0]or kw.get('path',None)
+	# Logs.pprint ('RED', '   %s' %root)
+	if root and self.__cryptopp_get_version_file(root):
+		return root
+	for dir in CRYPTOPP_DIR:
+		if self.__cryptopp_get_version_file(dir):
+			return dir
+	if root:
+		self.fatal('CryptoPP not found in %s'%root)
+	else:
+		self.fatal('CryptoPP not found, please provide a --cryptopp argument (see help)')
+@conf
+def check_cryptopp(self,*k,**kw):
+	if not self.env['CXX']:
+		self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
+
+	var=kw.get('uselib_store','CRYPTOPP')
+	self.start_msg('Checking CRYPTOPP')
+	root = self.cryptopp_get_root(*k,**kw)
+	self.env.CRYPTOPP_VERSION=self.cryptopp_get_version(root)
+
+	self.env['INCLUDES_%s'%var]= '%s/%s' % (root, "include")
+	self.env['LIB_%s'%var] = "cryptopp"
+	self.env['LIBPATH_%s'%var] = '%s/%s' % (root, "lib")
+
+	self.end_msg(self.env.CRYPTOPP_VERSION)
+	if Logs.verbose:
+		Logs.pprint('CYAN','	CRYPTOPP include : %s'%self.env['INCLUDES_%s'%var])
+		Logs.pprint('CYAN','	CRYPTOPP lib     : %s'%self.env['LIB_%s'%var])
+		Logs.pprint('CYAN','	CRYPTOPP libpath : %s'%self.env['LIBPATH_%s'%var])
+
diff --git a/.waf-tools/default-compiler-flags.py b/.waf-tools/default-compiler-flags.py
new file mode 100644
index 0000000..7a317b1
--- /dev/null
+++ b/.waf-tools/default-compiler-flags.py
@@ -0,0 +1,228 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+import platform
+from waflib import Configure, Logs, Utils
+
+def options(opt):
+    opt.add_option('--debug', '--with-debug', action='store_true', default=False,
+                   help='Compile in debugging mode with minimal optimizations (-Og)')
+
+def configure(conf):
+    conf.start_msg('Checking C++ compiler version')
+
+    cxx = conf.env.CXX_NAME # generic name of the compiler
+    ccver = tuple(int(i) for i in conf.env.CC_VERSION)
+    ccverstr = '.'.join(conf.env.CC_VERSION)
+    errmsg = ''
+    warnmsg = ''
+    if cxx == 'gcc':
+        if ccver < (5, 3, 0):
+            errmsg = ('The version of gcc you are using is too old.\n'
+                      'The minimum supported gcc version is 7.4.0.')
+        elif ccver < (7, 4, 0):
+            warnmsg = ('Using a version of gcc older than 7.4.0 is not '
+                       'officially supported and may result in build failures.')
+        conf.flags = GccFlags()
+    elif cxx == 'clang':
+        if Utils.unversioned_sys_platform() == 'darwin' and ccver < (9, 0, 0):
+            errmsg = ('The version of Xcode you are using is too old.\n'
+                      'The minimum supported Xcode version is 9.0.')
+        elif ccver < (4, 0, 0):
+            errmsg = ('The version of clang you are using is too old.\n'
+                      'The minimum supported clang version is 4.0.')
+        conf.flags = ClangFlags()
+    else:
+        warnmsg = '%s compiler is unsupported' % cxx
+        conf.flags = CompilerFlags()
+
+    if errmsg:
+        conf.end_msg(ccverstr, color='RED')
+        conf.fatal(errmsg)
+    elif warnmsg:
+        conf.end_msg(ccverstr, color='YELLOW')
+        Logs.warn('WARNING: ' + warnmsg)
+    else:
+        conf.end_msg(ccverstr)
+
+    conf.areCustomCxxflagsPresent = (len(conf.env.CXXFLAGS) > 0)
+
+    # General flags are always applied (e.g., selecting C++ language standard)
+    generalFlags = conf.flags.getGeneralFlags(conf)
+    conf.add_supported_cxxflags(generalFlags['CXXFLAGS'])
+    conf.add_supported_linkflags(generalFlags['LINKFLAGS'])
+    conf.env.DEFINES += generalFlags['DEFINES']
+
+@Configure.conf
+def check_compiler_flags(conf):
+    # Debug or optimized CXXFLAGS and LINKFLAGS are applied only if the
+    # corresponding environment variables are not set.
+    # DEFINES are always applied.
+    if conf.options.debug:
+        extraFlags = conf.flags.getDebugFlags(conf)
+        if conf.areCustomCxxflagsPresent:
+            missingFlags = [x for x in extraFlags['CXXFLAGS'] if x not in conf.env.CXXFLAGS]
+            if missingFlags:
+                Logs.warn('Selected debug mode, but CXXFLAGS is set to a custom value "%s"'
+                          % ' '.join(conf.env.CXXFLAGS))
+                Logs.warn('Default flags "%s" will not be used' % ' '.join(missingFlags))
+    else:
+        extraFlags = conf.flags.getOptimizedFlags(conf)
+
+    if not conf.areCustomCxxflagsPresent:
+        conf.add_supported_cxxflags(extraFlags['CXXFLAGS'])
+        conf.add_supported_linkflags(extraFlags['LINKFLAGS'])
+
+    conf.env.DEFINES += extraFlags['DEFINES']
+
+@Configure.conf
+def add_supported_cxxflags(self, cxxflags):
+    """
+    Check which cxxflags are supported by compiler and add them to env.CXXFLAGS variable
+    """
+    if len(cxxflags) == 0:
+        return
+
+    self.start_msg('Checking supported CXXFLAGS')
+
+    supportedFlags = []
+    for flags in cxxflags:
+        flags = Utils.to_list(flags)
+        if self.check_cxx(cxxflags=['-Werror'] + flags, mandatory=False):
+            supportedFlags += flags
+
+    self.end_msg(' '.join(supportedFlags))
+    self.env.prepend_value('CXXFLAGS', supportedFlags)
+
+@Configure.conf
+def add_supported_linkflags(self, linkflags):
+    """
+    Check which linkflags are supported by compiler and add them to env.LINKFLAGS variable
+    """
+    if len(linkflags) == 0:
+        return
+
+    self.start_msg('Checking supported LINKFLAGS')
+
+    supportedFlags = []
+    for flags in linkflags:
+        flags = Utils.to_list(flags)
+        if self.check_cxx(linkflags=['-Werror'] + flags, mandatory=False):
+            supportedFlags += flags
+
+    self.end_msg(' '.join(supportedFlags))
+    self.env.prepend_value('LINKFLAGS', supportedFlags)
+
+
+class CompilerFlags(object):
+    def getCompilerVersion(self, conf):
+        return tuple(int(i) for i in conf.env.CC_VERSION)
+
+    def getGeneralFlags(self, conf):
+        """Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are always needed"""
+        return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': []}
+
+    def getDebugFlags(self, conf):
+        """Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in debug mode"""
+        return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': ['_DEBUG']}
+
+    def getOptimizedFlags(self, conf):
+        """Get dict of CXXFLAGS, LINKFLAGS, and DEFINES that are needed only in optimized mode"""
+        return {'CXXFLAGS': [], 'LINKFLAGS': [], 'DEFINES': ['NDEBUG']}
+
+class GccBasicFlags(CompilerFlags):
+    """
+    This class defines basic flags that work for both gcc and clang compilers
+    """
+    def getGeneralFlags(self, conf):
+        flags = super(GccBasicFlags, self).getGeneralFlags(conf)
+        flags['CXXFLAGS'] += ['-std=c++14']
+        if Utils.unversioned_sys_platform() == 'linux':
+            flags['LINKFLAGS'] += ['-fuse-ld=gold']
+        elif Utils.unversioned_sys_platform() == 'freebsd':
+            flags['LINKFLAGS'] += ['-fuse-ld=lld']
+        return flags
+
+    def getDebugFlags(self, conf):
+        flags = super(GccBasicFlags, self).getDebugFlags(conf)
+        flags['CXXFLAGS'] += ['-Og',
+                              '-g3',
+                              '-pedantic',
+                              '-Wall',
+                              '-Wextra',
+                              '-Werror',
+                              '-Wcatch-value=2',
+                              # '-Wextra-semi', # prevent noisy output with Qt5
+                              '-Wnon-virtual-dtor',
+                              '-Wno-error=deprecated-declarations', # Bug #3795
+                              '-Wno-error=maybe-uninitialized', # Bug #1615
+                              '-Wno-unused-parameter',
+                              '-Wno-error=deprecated-copy', # Qt5
+                              ]
+        flags['LINKFLAGS'] += ['-Wl,-O1']
+        return flags
+
+    def getOptimizedFlags(self, conf):
+        flags = super(GccBasicFlags, self).getOptimizedFlags(conf)
+        flags['CXXFLAGS'] += ['-O2',
+                              '-g',
+                              '-pedantic',
+                              '-Wall',
+                              '-Wextra',
+                              '-Wcatch-value=2',
+                              '-Wextra-semi',
+                              '-Wnon-virtual-dtor',
+                              '-Wno-unused-parameter',
+                              ]
+        flags['LINKFLAGS'] += ['-Wl,-O1']
+        return flags
+
+class GccFlags(GccBasicFlags):
+    def getDebugFlags(self, conf):
+        flags = super(GccFlags, self).getDebugFlags(conf)
+        flags['CXXFLAGS'] += ['-fdiagnostics-color',
+                              '-Wredundant-tags',
+                              ]
+        if platform.machine() == 'armv7l' and self.getCompilerVersion(conf) >= (7, 1, 0):
+            flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
+        return flags
+
+    def getOptimizedFlags(self, conf):
+        flags = super(GccFlags, self).getOptimizedFlags(conf)
+        flags['CXXFLAGS'] += ['-fdiagnostics-color',
+                              '-Wredundant-tags',
+                              ]
+        if platform.machine() == 'armv7l' and self.getCompilerVersion(conf) >= (7, 1, 0):
+            flags['CXXFLAGS'] += ['-Wno-psabi'] # Bug #5106
+        return flags
+
+class ClangFlags(GccBasicFlags):
+    def getGeneralFlags(self, conf):
+        flags = super(ClangFlags, self).getGeneralFlags(conf)
+        if Utils.unversioned_sys_platform() == 'darwin':
+            # Bug #4296
+            flags['CXXFLAGS'] += [['-isystem', '/usr/local/include'], # for Homebrew
+                                  ['-isystem', '/opt/local/include']] # for MacPorts
+        elif Utils.unversioned_sys_platform() == 'freebsd':
+            # Bug #4790
+            flags['CXXFLAGS'] += [['-isystem', '/usr/local/include']]
+        return flags
+
+    def getDebugFlags(self, conf):
+        flags = super(ClangFlags, self).getDebugFlags(conf)
+        flags['CXXFLAGS'] += ['-fcolor-diagnostics',
+                              '-Wundefined-func-template',
+                              '-Wno-unused-local-typedef', # Bugs #2657 and #3209
+                              ]
+        if self.getCompilerVersion(conf) < (6, 0, 0):
+            flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
+        return flags
+
+    def getOptimizedFlags(self, conf):
+        flags = super(ClangFlags, self).getOptimizedFlags(conf)
+        flags['CXXFLAGS'] += ['-fcolor-diagnostics',
+                              '-Wundefined-func-template',
+                              '-Wno-unused-local-typedef', # Bugs #2657 and #3209
+                              ]
+        if self.getCompilerVersion(conf) < (6, 0, 0):
+            flags['CXXFLAGS'] += ['-Wno-missing-braces'] # Bug #4721
+        return flags
\ No newline at end of file
diff --git a/.waf-tools/doxygen.py b/.waf-tools/doxygen.py
new file mode 100644
index 0000000..85e0828
--- /dev/null
+++ b/.waf-tools/doxygen.py
@@ -0,0 +1,214 @@
+#! /usr/bin/env python
+# encoding: UTF-8
+# Thomas Nagy 2008-2010 (ita)
+
+"""
+
+Doxygen support
+
+Variables passed to bld():
+* doxyfile -- the Doxyfile to use
+
+When using this tool, the wscript will look like:
+
+	def options(opt):
+		opt.load('doxygen')
+
+	def configure(conf):
+		conf.load('doxygen')
+		# check conf.env.DOXYGEN, if it is mandatory
+
+	def build(bld):
+		if bld.env.DOXYGEN:
+			bld(features="doxygen", doxyfile='Doxyfile', ...)
+
+        def doxygen(bld):
+		if bld.env.DOXYGEN:
+			bld(features="doxygen", doxyfile='Doxyfile', ...)
+"""
+
+from fnmatch import fnmatchcase
+import os, os.path, re, stat
+from waflib import Task, Utils, Node, Logs, Errors, Build
+from waflib.TaskGen import feature
+
+DOXY_STR = '"${DOXYGEN}" - '
+DOXY_FMTS = 'html latex man rft xml'.split()
+DOXY_FILE_PATTERNS = '*.' + ' *.'.join('''
+c cc cxx cpp c++ java ii ixx ipp i++ inl h hh hxx hpp h++ idl odl cs php php3
+inc m mm py f90c cc cxx cpp c++ java ii ixx ipp i++ inl h hh hxx
+'''.split())
+
+re_rl = re.compile('\\\\\r*\n', re.MULTILINE)
+re_nl = re.compile('\r*\n', re.M)
+def parse_doxy(txt):
+	tbl = {}
+	txt   = re_rl.sub('', txt)
+	lines = re_nl.split(txt)
+	for x in lines:
+		x = x.strip()
+		if not x or x.startswith('#') or x.find('=') < 0:
+			continue
+		if x.find('+=') >= 0:
+			tmp = x.split('+=')
+			key = tmp[0].strip()
+			if key in tbl:
+				tbl[key] += ' ' + '+='.join(tmp[1:]).strip()
+			else:
+				tbl[key] = '+='.join(tmp[1:]).strip()
+		else:
+			tmp = x.split('=')
+			tbl[tmp[0].strip()] = '='.join(tmp[1:]).strip()
+	return tbl
+
+class doxygen(Task.Task):
+	vars  = ['DOXYGEN', 'DOXYFLAGS']
+	color = 'BLUE'
+
+	def runnable_status(self):
+		'''
+		self.pars are populated in runnable_status - because this function is being
+		run *before* both self.pars "consumers" - scan() and run()
+
+		set output_dir (node) for the output
+		'''
+
+		for x in self.run_after:
+			if not x.hasrun:
+				return Task.ASK_LATER
+
+		if not getattr(self, 'pars', None):
+			txt = self.inputs[0].read()
+			self.pars = parse_doxy(txt)
+			if not self.pars.get('OUTPUT_DIRECTORY'):
+				self.pars['OUTPUT_DIRECTORY'] = self.inputs[0].parent.get_bld().abspath()
+
+			# Override with any parameters passed to the task generator
+			if getattr(self.generator, 'pars', None):
+				for k, v in self.generator.pars.items():
+					self.pars[k] = v
+
+			self.doxy_inputs = getattr(self, 'doxy_inputs', [])
+			if not self.pars.get('INPUT'):
+				self.doxy_inputs.append(self.inputs[0].parent)
+			else:
+				for i in self.pars.get('INPUT').split():
+					if os.path.isabs(i):
+						node = self.generator.bld.root.find_node(i)
+					else:
+						node = self.generator.path.find_node(i)
+					if not node:
+						self.generator.bld.fatal('Could not find the doxygen input %r' % i)
+					self.doxy_inputs.append(node)
+
+		if not getattr(self, 'output_dir', None):
+			bld = self.generator.bld
+			# First try to find an absolute path, then find or declare a relative path
+			self.output_dir = bld.root.find_dir(self.pars['OUTPUT_DIRECTORY'])
+			if not self.output_dir:
+				self.output_dir = bld.path.find_or_declare(self.pars['OUTPUT_DIRECTORY'])
+
+		self.signature()
+		return Task.Task.runnable_status(self)
+
+	def scan(self):
+		exclude_patterns = self.pars.get('EXCLUDE_PATTERNS','').split()
+		file_patterns = self.pars.get('FILE_PATTERNS','').split()
+		if not file_patterns:
+			file_patterns = DOXY_FILE_PATTERNS
+		if self.pars.get('RECURSIVE') == 'YES':
+			file_patterns = ["**/%s" % pattern for pattern in file_patterns]
+		nodes = []
+		names = []
+		for node in self.doxy_inputs:
+			if os.path.isdir(node.abspath()):
+				for m in node.ant_glob(incl=file_patterns, excl=exclude_patterns):
+					nodes.append(m)
+			else:
+				nodes.append(node)
+		return (nodes, names)
+
+	def run(self):
+		dct = self.pars.copy()
+		dct['INPUT'] = ' '.join(['"%s"' % x.abspath() for x in self.doxy_inputs])
+		code = '\n'.join(['%s = %s' % (x, dct[x]) for x in self.pars])
+		code = code.encode() # for python 3
+		#fmt = DOXY_STR % (self.inputs[0].parent.abspath())
+		cmd = Utils.subst_vars(DOXY_STR, self.env)
+		env = self.env.env or None
+		proc = Utils.subprocess.Popen(cmd, shell=True, stdin=Utils.subprocess.PIPE, env=env, cwd=self.generator.bld.path.get_bld().abspath())
+		proc.communicate(code)
+		return proc.returncode
+
+	def post_run(self):
+		nodes = self.output_dir.ant_glob('**/*', quiet=True)
+		for x in nodes:
+			x.sig = Utils.h_file(x.abspath())
+		self.outputs += nodes
+		return Task.Task.post_run(self)
+
+class tar(Task.Task):
+	"quick tar creation"
+	run_str = '${TAR} ${TAROPTS} ${TGT} ${SRC}'
+	color   = 'RED'
+	after   = ['doxygen']
+	def runnable_status(self):
+		for x in getattr(self, 'input_tasks', []):
+			if not x.hasrun:
+				return Task.ASK_LATER
+
+		if not getattr(self, 'tar_done_adding', None):
+			# execute this only once
+			self.tar_done_adding = True
+			for x in getattr(self, 'input_tasks', []):
+				self.set_inputs(x.outputs)
+			if not self.inputs:
+				return Task.SKIP_ME
+		return Task.Task.runnable_status(self)
+
+	def __str__(self):
+		tgt_str = ' '.join([a.nice_path(self.env) for a in self.outputs])
+		return '%s: %s\n' % (self.__class__.__name__, tgt_str)
+
+@feature('doxygen')
+def process_doxy(self):
+	if not getattr(self, 'doxyfile', None):
+		self.generator.bld.fatal('no doxyfile??')
+
+	node = self.doxyfile
+	if not isinstance(node, Node.Node):
+		node = self.path.find_resource(node)
+	if not node:
+		raise ValueError('doxygen file not found')
+
+	# the task instance
+	dsk = self.create_task('doxygen', node)
+
+	if getattr(self, 'doxy_tar', None):
+		tsk = self.create_task('tar')
+		tsk.input_tasks = [dsk]
+		tsk.set_outputs(self.path.find_or_declare(self.doxy_tar))
+		if self.doxy_tar.endswith('bz2'):
+			tsk.env['TAROPTS'] = ['cjf']
+		elif self.doxy_tar.endswith('gz'):
+			tsk.env['TAROPTS'] = ['czf']
+		else:
+			tsk.env['TAROPTS'] = ['cf']
+
+def configure(conf):
+	'''
+	Check if doxygen and tar commands are present in the system
+
+	If the commands are present, then conf.env.DOXYGEN and conf.env.TAR
+	variables will be set. Detection can be controlled by setting DOXYGEN and
+	TAR environmental variables.
+	'''
+
+	conf.find_program('doxygen', var='DOXYGEN', mandatory=False)
+	conf.find_program('tar', var='TAR', mandatory=False)
+
+# doxygen docs
+from waflib.Build import BuildContext
+class doxy(BuildContext):
+    cmd = "doxygen"
+    fun = "doxygen"
\ No newline at end of file
diff --git a/.waf-tools/qt5_custom.py b/.waf-tools/qt5_custom.py
new file mode 100644
index 0000000..47d0d4c
--- /dev/null
+++ b/.waf-tools/qt5_custom.py
@@ -0,0 +1,816 @@
+#!/usr/bin/env python
+# encoding: utf-8
+# Thomas Nagy, 2006-2018 (ita)
+
+"""
+This tool helps with finding Qt5 tools and libraries,
+and also provides syntactic sugar for using Qt5 tools.
+
+The following snippet illustrates the tool usage::
+
+	def options(opt):
+		opt.load('compiler_cxx qt5')
+
+	def configure(conf):
+		conf.load('compiler_cxx qt5')
+
+	def build(bld):
+		bld(
+			features = 'qt5 cxx cxxprogram',
+			uselib   = 'QT5CORE QT5GUI QT5OPENGL QT5SVG',
+			source   = 'main.cpp textures.qrc aboutDialog.ui',
+			target   = 'window',
+		)
+
+Here, the UI description and resource files will be processed
+to generate code.
+
+Usage
+=====
+
+Load the "qt5" tool.
+
+You also need to edit your sources accordingly:
+
+- the normal way of doing things is to have your C++ files
+  include the .moc file.
+  This is regarded as the best practice (and provides much faster
+  compilations).
+  It also implies that the include paths have beenset properly.
+
+- to have the include paths added automatically, use the following::
+
+     from waflib.TaskGen import feature, before_method, after_method
+     @feature('cxx')
+     @after_method('process_source')
+     @before_method('apply_incpaths')
+     def add_includes_paths(self):
+        incs = set(self.to_list(getattr(self, 'includes', '')))
+        for x in self.compiled_tasks:
+            incs.add(x.inputs[0].parent.path_from(self.path))
+        self.includes = sorted(incs)
+
+Note: another tool provides Qt processing that does not require
+.moc includes, see 'playground/slow_qt/'.
+
+A few options (--qt{dir,bin,...}) and environment variables
+(QT5_{ROOT,DIR,MOC,UIC,XCOMPILE}) allow finer tuning of the tool,
+tool path selection, etc; please read the source for more info.
+
+The detection uses pkg-config on Linux by default. The list of
+libraries to be requested to pkg-config is formulated by scanning
+in the QTLIBS directory (that can be passed via --qtlibs or by
+setting the environment variable QT5_LIBDIR otherwise is derived
+by querying qmake for QT_INSTALL_LIBS directory) for shared/static
+libraries present.
+Alternatively the list of libraries to be requested via pkg-config
+can be set using the qt5_vars attribute, ie:
+
+      conf.qt5_vars = ['Qt5Core', 'Qt5Gui', 'Qt5Widgets', 'Qt5Test'];
+
+This can speed up configuration phase if needed libraries are
+known beforehand, can improve detection on systems with a
+sparse QT5 libraries installation (ie. NIX) and can improve
+detection of some header-only Qt modules (ie. Qt5UiPlugin).
+
+To force static library detection use:
+QT5_XCOMPILE=1 QT5_FORCE_STATIC=1 waf configure
+"""
+
+from __future__ import with_statement
+
+try:
+	from xml.sax import make_parser
+	from xml.sax.handler import ContentHandler
+except ImportError:
+	has_xml = False
+	ContentHandler = object
+else:
+	has_xml = True
+
+import os, sys, re
+from waflib.Tools import cxx
+from waflib import Build, Task, Utils, Options, Errors, Context
+from waflib.TaskGen import feature, after_method, extension, before_method
+from waflib.Configure import conf
+from waflib import Logs
+
+MOC_H = ['.h', '.hpp', '.hxx', '.hh']
+"""
+File extensions associated to .moc files
+"""
+
+EXT_RCC = ['.qrc']
+"""
+File extension for the resource (.qrc) files
+"""
+
+EXT_UI  = ['.ui']
+"""
+File extension for the user interface (.ui) files
+"""
+
+EXT_QT5 = ['.cpp', '.cc', '.cxx', '.C']
+"""
+File extensions of C++ files that may require a .moc processing
+"""
+
+class qxx(Task.classes['cxx']):
+	"""
+	Each C++ file can have zero or several .moc files to create.
+	They are known only when the files are scanned (preprocessor)
+	To avoid scanning the c++ files each time (parsing C/C++), the results
+	are retrieved from the task cache (bld.node_deps/bld.raw_deps).
+	The moc tasks are also created *dynamically* during the build.
+	"""
+
+	def __init__(self, *k, **kw):
+		Task.Task.__init__(self, *k, **kw)
+		self.moc_done = 0
+
+	def runnable_status(self):
+		"""
+		Compute the task signature to make sure the scanner was executed. Create the
+		moc tasks by using :py:meth:`waflib.Tools.qt5.qxx.add_moc_tasks` (if necessary),
+		then postpone the task execution (there is no need to recompute the task signature).
+		"""
+		if self.moc_done:
+			return Task.Task.runnable_status(self)
+		else:
+			for t in self.run_after:
+				if not t.hasrun:
+					return Task.ASK_LATER
+			self.add_moc_tasks()
+			return Task.Task.runnable_status(self)
+
+	def create_moc_task(self, h_node, m_node):
+		"""
+		If several libraries use the same classes, it is possible that moc will run several times (Issue 1318)
+		It is not possible to change the file names, but we can assume that the moc transformation will be identical,
+		and the moc tasks can be shared in a global cache.
+		"""
+		try:
+			moc_cache = self.generator.bld.moc_cache
+		except AttributeError:
+			moc_cache = self.generator.bld.moc_cache = {}
+
+		try:
+			return moc_cache[h_node]
+		except KeyError:
+			tsk = moc_cache[h_node] = Task.classes['moc'](env=self.env, generator=self.generator)
+			tsk.set_inputs(h_node)
+			tsk.set_outputs(m_node)
+			tsk.env.append_unique('MOC_FLAGS', '-i')
+
+			if self.generator:
+				self.generator.tasks.append(tsk)
+
+			# direct injection in the build phase (safe because called from the main thread)
+			gen = self.generator.bld.producer
+			gen.outstanding.append(tsk)
+			gen.total += 1
+
+			return tsk
+
+		else:
+			# remove the signature, it must be recomputed with the moc task
+			delattr(self, 'cache_sig')
+
+	def add_moc_tasks(self):
+		"""
+		Creates moc tasks by looking in the list of file dependencies ``bld.raw_deps[self.uid()]``
+		"""
+		node = self.inputs[0]
+		bld = self.generator.bld
+
+		# skip on uninstall due to generated files
+		if bld.is_install == Build.UNINSTALL:
+			return
+
+		try:
+			# compute the signature once to know if there is a moc file to create
+			self.signature()
+		except KeyError:
+			# the moc file may be referenced somewhere else
+			pass
+		else:
+			# remove the signature, it must be recomputed with the moc task
+			delattr(self, 'cache_sig')
+
+		include_nodes = [node.parent] + self.generator.includes_nodes
+
+		moctasks = []
+		mocfiles = set()
+		for d in bld.raw_deps.get(self.uid(), []):
+			if not d.endswith('.moc'):
+				continue
+
+			# process that base.moc only once
+			if d in mocfiles:
+				continue
+			mocfiles.add(d)
+
+			# find the source associated with the moc file
+			h_node = None
+			base2 = d[:-4]
+
+			# foo.moc from foo.cpp
+			prefix = node.name[:node.name.rfind('.')]
+			if base2 == prefix and False:
+				h_node = node
+			else:
+				# this deviates from the standard
+				# if bar.cpp includes foo.moc, then assume it is from foo.h
+				for x in include_nodes:
+					for e in MOC_H:
+						h_node = x.find_node(base2 + e)
+						if h_node:
+							break
+					else:
+						continue
+					break
+			if h_node:
+				m_node = h_node.change_ext('.moc')
+			else:
+				raise Errors.WafError('No source found for %r which is a moc file' % d)
+
+			# create the moc task
+			task = self.create_moc_task(h_node, m_node)
+			moctasks.append(task)
+
+		# simple scheduler dependency: run the moc task before others
+		self.run_after.update(set(moctasks))
+		self.moc_done = 1
+
+class trans_update(Task.Task):
+	"""Updates a .ts files from a list of C++ files"""
+	run_str = '${QT_LUPDATE} ${SRC} -ts ${TGT}'
+	color   = 'BLUE'
+
+class XMLHandler(ContentHandler):
+	"""
+	Parses ``.qrc`` files
+	"""
+	def __init__(self):
+		ContentHandler.__init__(self)
+		self.buf = []
+		self.files = []
+	def startElement(self, name, attrs):
+		if name == 'file':
+			self.buf = []
+	def endElement(self, name):
+		if name == 'file':
+			self.files.append(str(''.join(self.buf)))
+	def characters(self, cars):
+		self.buf.append(cars)
+
+@extension(*EXT_RCC)
+def create_rcc_task(self, node):
+	"Creates rcc and cxx tasks for ``.qrc`` files"
+	rcnode = node.change_ext('_rc.%d.cpp' % self.idx)
+	self.create_task('rcc', node, rcnode)
+	cpptask = self.create_task('cxx', rcnode, rcnode.change_ext('.o'))
+	try:
+		self.compiled_tasks.append(cpptask)
+	except AttributeError:
+		self.compiled_tasks = [cpptask]
+	return cpptask
+
+@extension(*EXT_UI)
+def create_uic_task(self, node):
+	"Create uic tasks for user interface ``.ui`` definition files"
+
+	"""
+	If UIC file is used in more than one bld, we would have a conflict in parallel execution
+	It is not possible to change the file names (like .self.idx. as for objects) as they have
+	to be referenced by the source file, but we can assume that the transformation will be identical
+	and the tasks can be shared in a global cache.
+	"""
+	try:
+		uic_cache = self.bld.uic_cache
+	except AttributeError:
+		uic_cache = self.bld.uic_cache = {}
+
+	if node not in uic_cache:
+		uictask = uic_cache[node] = self.create_task('ui5', node)
+		uictask.outputs = [node.parent.find_or_declare(self.env.ui_PATTERN % node.name[:-3])]
+
+@extension('.ts')
+def add_lang(self, node):
+	"""Adds all the .ts file into ``self.lang``"""
+	self.lang = self.to_list(getattr(self, 'lang', [])) + [node]
+
+@feature('qt5')
+@before_method('process_source')
+def process_mocs(self):
+	"""
+	Processes MOC files included in headers::
+
+		def build(bld):
+			bld.program(features='qt5', source='main.cpp', target='app', use='QT5CORE', moc='foo.h')
+
+	The build will run moc on foo.h to create moc_foo.n.cpp. The number in the file name
+	is provided to avoid name clashes when the same headers are used by several targets.
+	"""
+	lst = self.to_nodes(getattr(self, 'moc', []))
+	self.source = self.to_list(getattr(self, 'source', []))
+	for x in lst:
+		prefix = x.name[:x.name.rfind('.')] # foo.h -> foo
+		moc_target = 'moc_%s.%d.cpp' % (prefix, self.idx)
+		moc_node = x.parent.find_or_declare(moc_target)
+		self.source.append(moc_node)
+
+		self.create_task('moc', x, moc_node)
+
+@feature('qt5')
+@after_method('apply_link')
+def apply_qt5(self):
+	"""
+	Adds MOC_FLAGS which may be necessary for moc::
+
+		def build(bld):
+			bld.program(features='qt5', source='main.cpp', target='app', use='QT5CORE')
+
+	The additional parameters are:
+
+	:param lang: list of translation files (\\*.ts) to process
+	:type lang: list of :py:class:`waflib.Node.Node` or string without the .ts extension
+	:param update: whether to process the C++ files to update the \\*.ts files (use **waf --translate**)
+	:type update: bool
+	:param langname: if given, transform the \\*.ts files into a .qrc files to include in the binary file
+	:type langname: :py:class:`waflib.Node.Node` or string without the .qrc extension
+	"""
+	if getattr(self, 'lang', None):
+		qmtasks = []
+		for x in self.to_list(self.lang):
+			if isinstance(x, str):
+				x = self.path.find_resource(x + '.ts')
+			qmtasks.append(self.create_task('ts2qm', x, x.change_ext('.%d.qm' % self.idx)))
+
+		if getattr(self, 'update', None) and Options.options.trans_qt5:
+			cxxnodes = [a.inputs[0] for a in self.compiled_tasks] + [
+				a.inputs[0] for a in self.tasks if a.inputs and a.inputs[0].name.endswith('.ui')]
+			for x in qmtasks:
+				self.create_task('trans_update', cxxnodes, x.inputs)
+
+		if getattr(self, 'langname', None):
+			qmnodes = [x.outputs[0] for x in qmtasks]
+			rcnode = self.langname
+			if isinstance(rcnode, str):
+				rcnode = self.path.find_or_declare(rcnode + ('.%d.qrc' % self.idx))
+			t = self.create_task('qm2rcc', qmnodes, rcnode)
+			k = create_rcc_task(self, t.outputs[0])
+			self.link_task.inputs.append(k.outputs[0])
+
+	lst = []
+	for flag in self.to_list(self.env.CXXFLAGS):
+		if len(flag) < 2:
+			continue
+		f = flag[0:2]
+		if f in ('-D', '-I', '/D', '/I'):
+			if (f[0] == '/'):
+				lst.append('-' + flag[1:])
+			else:
+				lst.append(flag)
+	self.env.append_value('MOC_FLAGS', lst)
+
+@extension(*EXT_QT5)
+def cxx_hook(self, node):
+	"""
+	Re-maps C++ file extensions to the :py:class:`waflib.Tools.qt5.qxx` task.
+	"""
+	return self.create_compiled_task('qxx', node)
+
+class rcc(Task.Task):
+	"""
+	Processes ``.qrc`` files
+	"""
+	color   = 'BLUE'
+	run_str = '${QT_RCC} -name ${tsk.rcname()} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}'
+	ext_out = ['.h']
+
+	def rcname(self):
+		return os.path.splitext(self.inputs[0].name)[0]
+
+	def scan(self):
+		"""Parse the *.qrc* files"""
+		if not has_xml:
+			Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!')
+			return ([], [])
+
+		parser = make_parser()
+		curHandler = XMLHandler()
+		parser.setContentHandler(curHandler)
+		with open(self.inputs[0].abspath(), 'r') as f:
+			parser.parse(f)
+
+		nodes = []
+		names = []
+		root = self.inputs[0].parent
+		for x in curHandler.files:
+			nd = root.find_resource(x)
+			if nd:
+				nodes.append(nd)
+			else:
+				names.append(x)
+		return (nodes, names)
+
+	def quote_flag(self, x):
+		"""
+		Override Task.quote_flag. QT parses the argument files
+		differently than cl.exe and link.exe
+
+		:param x: flag
+		:type x: string
+		:return: quoted flag
+		:rtype: string
+		"""
+		return x
+
+
+class moc(Task.Task):
+	"""
+	Creates ``.moc`` files
+	"""
+	color   = 'BLUE'
+	run_str = '${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}'
+
+	def quote_flag(self, x):
+		"""
+		Override Task.quote_flag. QT parses the argument files
+		differently than cl.exe and link.exe
+
+		:param x: flag
+		:type x: string
+		:return: quoted flag
+		:rtype: string
+		"""
+		return x
+
+
+class ui5(Task.Task):
+	"""
+	Processes ``.ui`` files
+	"""
+	color   = 'BLUE'
+	run_str = '${QT_UIC} ${SRC} -o ${TGT}'
+	ext_out = ['.h']
+
+class ts2qm(Task.Task):
+	"""
+	Generates ``.qm`` files from ``.ts`` files
+	"""
+	color   = 'BLUE'
+	run_str = '${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}'
+
+class qm2rcc(Task.Task):
+	"""
+	Generates ``.qrc`` files from ``.qm`` files
+	"""
+	color = 'BLUE'
+	after = 'ts2qm'
+	def run(self):
+		"""Create a qrc file including the inputs"""
+		txt = '\n'.join(['<file>%s</file>' % k.path_from(self.outputs[0].parent) for k in self.inputs])
+		code = '<!DOCTYPE RCC><RCC version="1.0">\n<qresource>\n%s\n</qresource>\n</RCC>' % txt
+		self.outputs[0].write(code)
+
+def configure(self):
+	"""
+	Besides the configuration options, the environment variable QT5_ROOT may be used
+	to give the location of the qt5 libraries (absolute path).
+
+	The detection uses the program ``pkg-config`` through :py:func:`waflib.Tools.config_c.check_cfg`
+	"""
+	if 'COMPILER_CXX' not in self.env:
+		self.fatal('No CXX compiler defined: did you forget to configure compiler_cxx first?')
+
+	self.find_qt5_binaries()
+	self.set_qt5_libs_dir()
+	self.set_qt5_libs_to_check()
+	self.set_qt5_defines()
+	self.find_qt5_libraries()
+	self.add_qt5_rpath()
+	self.simplify_qt5_libs()
+
+	# warn about this during the configuration too
+	if not has_xml:
+		Logs.error('No xml.sax support was found, rcc dependencies will be incomplete!')
+
+	# Qt5 may be compiled with '-reduce-relocations' which requires dependent programs to have -fPIE or -fPIC?
+	frag = '#include <QMap>\nint main(int argc, char **argv) {QMap<int,int> m;return m.keys().size();}\n'
+	uses = 'QT5CORE'
+	for flag in [[], '-fPIE', '-fPIC', '-std=c++14' , ['-std=c++14', '-fPIE'], ['-std=c++14', '-fPIC']]:
+		msg = 'See if Qt files compile '
+		if flag:
+			msg += 'with %s' % flag
+		try:
+			self.check(features='qt5 cxx', use=uses, uselib_store='qt5', cxxflags=flag, fragment=frag, msg=msg)
+		except self.errors.ConfigurationError:
+			pass
+		else:
+			break
+	else:
+		self.fatal('Could not build a simple Qt application')
+
+	# FreeBSD does not add /usr/local/lib and the pkg-config files do not provide it either :-/
+	if Utils.unversioned_sys_platform() == 'freebsd':
+		frag = '#include <QMap>\nint main(int argc, char **argv) {QMap<int,int> m;return m.keys().size();}\n'
+		try:
+			self.check(features='qt5 cxx cxxprogram', use=uses, fragment=frag, msg='Can we link Qt programs on FreeBSD directly?')
+		except self.errors.ConfigurationError:
+			self.check(features='qt5 cxx cxxprogram', use=uses, uselib_store='qt5', libpath='/usr/local/lib', fragment=frag, msg='Is /usr/local/lib required?')
+
+@conf
+def find_qt5_binaries(self):
+	"""
+	Detects Qt programs such as qmake, moc, uic, lrelease
+	"""
+	env = self.env
+	opt = Options.options
+
+	qtdir = getattr(opt, 'qtdir', '')
+	qtbin = getattr(opt, 'qtbin', '')
+
+	paths = []
+
+	if qtdir:
+		qtbin = os.path.join(qtdir, 'bin')
+
+	# the qt directory has been given from QT5_ROOT - deduce the qt binary path
+	if not qtdir:
+		qtdir = self.environ.get('QT5_ROOT', '')
+		qtbin = self.environ.get('QT5_BIN') or os.path.join(qtdir, 'bin')
+
+	if qtbin:
+		paths = [qtbin]
+
+	# no qtdir, look in the path and in /usr/local/Trolltech
+	if not qtdir:
+		paths = self.environ.get('PATH', '').split(os.pathsep)
+		paths.extend(['/usr/share/qt5/bin', '/usr/local/lib/qt5/bin'])
+		try:
+			lst = Utils.listdir('/usr/local/Trolltech/')
+		except OSError:
+			pass
+		else:
+			if lst:
+				lst.sort()
+				lst.reverse()
+
+				# keep the highest version
+				qtdir = '/usr/local/Trolltech/%s/' % lst[0]
+				qtbin = os.path.join(qtdir, 'bin')
+				paths.append(qtbin)
+
+	# at the end, try to find qmake in the paths given
+	# keep the one with the highest version
+	cand = None
+	prev_ver = ['5', '0', '0']
+	for qmk in ('qmake-qt5', 'qmake5', 'qmake'):
+		try:
+			qmake = self.find_program(qmk, path_list=paths)
+		except self.errors.ConfigurationError:
+			pass
+		else:
+			try:
+				version = self.cmd_and_log(qmake + ['-query', 'QT_VERSION']).strip()
+			except self.errors.WafError:
+				pass
+			else:
+				if version:
+					new_ver = version.split('.')
+					if new_ver > prev_ver:
+						cand = qmake
+						prev_ver = new_ver
+
+	# qmake could not be found easily, rely on qtchooser
+	if not cand:
+		try:
+			self.find_program('qtchooser')
+		except self.errors.ConfigurationError:
+			pass
+		else:
+			cmd = self.env.QTCHOOSER + ['-qt=5', '-run-tool=qmake']
+			try:
+				version = self.cmd_and_log(cmd + ['-query', 'QT_VERSION'])
+			except self.errors.WafError:
+				pass
+			else:
+				cand = cmd
+
+	if cand:
+		self.env.QMAKE = cand
+	else:
+		self.fatal('Could not find qmake for qt5')
+
+	self.env.QT_HOST_BINS = qtbin = self.cmd_and_log(self.env.QMAKE + ['-query', 'QT_HOST_BINS']).strip()
+	paths.insert(0, qtbin)
+
+	def find_bin(lst, var):
+		if var in env:
+			return
+		for f in lst:
+			try:
+				ret = self.find_program(f, path_list=paths)
+			except self.errors.ConfigurationError:
+				pass
+			else:
+				env[var]=ret
+				break
+
+	find_bin(['uic-qt5', 'uic'], 'QT_UIC')
+	if not env.QT_UIC:
+		self.fatal('cannot find the uic compiler for qt5')
+
+	self.start_msg('Checking for uic version')
+	uicver = self.cmd_and_log(env.QT_UIC + ['-version'], output=Context.BOTH)
+	uicver = ''.join(uicver).strip()
+	uicver = uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt', '')
+	self.end_msg(uicver)
+	if uicver.find(' 3.') != -1 or uicver.find(' 4.') != -1:
+		self.fatal('this uic compiler is for qt3 or qt4, add uic for qt5 to your path')
+
+	find_bin(['moc-qt5', 'moc'], 'QT_MOC')
+	find_bin(['rcc-qt5', 'rcc'], 'QT_RCC')
+	find_bin(['lrelease-qt5', 'lrelease'], 'QT_LRELEASE')
+	find_bin(['lupdate-qt5', 'lupdate'], 'QT_LUPDATE')
+
+	env.UIC_ST = '%s -o %s'
+	env.MOC_ST = '-o'
+	env.ui_PATTERN = 'ui_%s.h'
+	env.QT_LRELEASE_FLAGS = ['-silent']
+	env.MOCCPPPATH_ST = '-I%s'
+	env.MOCDEFINES_ST = '-D%s'
+
+@conf
+def set_qt5_libs_dir(self):
+	env = self.env
+	qtlibs = getattr(Options.options, 'qtlibs', None) or self.environ.get('QT5_LIBDIR')
+	if not qtlibs:
+		try:
+			qtlibs = self.cmd_and_log(env.QMAKE + ['-query', 'QT_INSTALL_LIBS']).strip()
+		except Errors.WafError:
+			qtdir = self.cmd_and_log(env.QMAKE + ['-query', 'QT_INSTALL_PREFIX']).strip()
+			qtlibs = os.path.join(qtdir, 'lib')
+	self.msg('Found the Qt5 library path', qtlibs)
+	env.QTLIBS = qtlibs
+
+@conf
+def find_single_qt5_lib(self, name, uselib, qtlibs, qtincludes, force_static):
+	env = self.env
+	if force_static:
+		exts = ('.a', '.lib')
+		prefix = 'STLIB'
+	else:
+		exts = ('.so', '.lib')
+		prefix = 'LIB'
+
+	def lib_names():
+		for x in exts:
+			for k in ('', '5') if Utils.is_win32 else ['']:
+				for p in ('lib', ''):
+					yield (p, name, k, x)
+
+	for tup in lib_names():
+		k = ''.join(tup)
+		path = os.path.join(qtlibs, k)
+		if os.path.exists(path):
+			if env.DEST_OS == 'win32':
+				libval = ''.join(tup[:-1])
+			else:
+				libval = name
+			env.append_unique(prefix + '_' + uselib, libval)
+			env.append_unique('%sPATH_%s' % (prefix, uselib), qtlibs)
+			env.append_unique('INCLUDES_' + uselib, qtincludes)
+			env.append_unique('INCLUDES_' + uselib, os.path.join(qtincludes, name.replace('Qt5', 'Qt')))
+			return k
+	return False
+
+@conf
+def find_qt5_libraries(self):
+	env = self.env
+
+	qtincludes =  self.environ.get('QT5_INCLUDES') or self.cmd_and_log(env.QMAKE + ['-query', 'QT_INSTALL_HEADERS']).strip()
+	force_static = self.environ.get('QT5_FORCE_STATIC')
+	try:
+		if self.environ.get('QT5_XCOMPILE'):
+			self.fatal('QT5_XCOMPILE Disables pkg-config detection')
+		self.check_cfg(atleast_pkgconfig_version='0.1')
+	except self.errors.ConfigurationError:
+		for i in self.qt5_vars:
+			uselib = i.upper()
+			if Utils.unversioned_sys_platform() == 'darwin':
+				# Since at least qt 4.7.3 each library locates in separate directory
+				fwk = i.replace('Qt5', 'Qt')
+				frameworkName = fwk + '.framework'
+
+				qtDynamicLib = os.path.join(env.QTLIBS, frameworkName, fwk)
+				if os.path.exists(qtDynamicLib):
+					env.append_unique('FRAMEWORK_' + uselib, fwk)
+					env.append_unique('FRAMEWORKPATH_' + uselib, env.QTLIBS)
+					self.msg('Checking for %s' % i, qtDynamicLib, 'GREEN')
+				else:
+					self.msg('Checking for %s' % i, False, 'YELLOW')
+				env.append_unique('INCLUDES_' + uselib, os.path.join(env.QTLIBS, frameworkName, 'Headers'))
+			else:
+				ret = self.find_single_qt5_lib(i, uselib, env.QTLIBS, qtincludes, force_static)
+				if not force_static and not ret:
+					ret = self.find_single_qt5_lib(i, uselib, env.QTLIBS, qtincludes, True)
+				self.msg('Checking for %s' % i, ret, 'GREEN' if ret else 'YELLOW')
+	else:
+		path = '%s:%s:%s/pkgconfig:/usr/lib/qt5/lib/pkgconfig:/opt/qt5/lib/pkgconfig:/usr/lib/qt5/lib:/opt/qt5/lib' % (
+			self.environ.get('PKG_CONFIG_PATH', ''), env.QTLIBS, env.QTLIBS)
+		for i in self.qt5_vars:
+			self.check_cfg(package=i, args='--cflags --libs', mandatory=False, force_static=force_static, pkg_config_path=path)
+
+@conf
+def simplify_qt5_libs(self):
+	"""
+	Since library paths make really long command-lines,
+	and since everything depends on qtcore, remove the qtcore ones from qtgui, etc
+	"""
+	env = self.env
+	def process_lib(vars_, coreval):
+		for d in vars_:
+			var = d.upper()
+			if var == 'QTCORE':
+				continue
+
+			value = env['LIBPATH_'+var]
+			if value:
+				core = env[coreval]
+				accu = []
+				for lib in value:
+					if lib in core:
+						continue
+					accu.append(lib)
+				env['LIBPATH_'+var] = accu
+	process_lib(self.qt5_vars,       'LIBPATH_QTCORE')
+
+@conf
+def add_qt5_rpath(self):
+	"""
+	Defines rpath entries for Qt libraries
+	"""
+	env = self.env
+	if getattr(Options.options, 'want_rpath', False):
+		def process_rpath(vars_, coreval):
+			for d in vars_:
+				var = d.upper()
+				value = env['LIBPATH_' + var]
+				if value:
+					core = env[coreval]
+					accu = []
+					for lib in value:
+						if var != 'QTCORE':
+							if lib in core:
+								continue
+						accu.append('-Wl,--rpath='+lib)
+					env['RPATH_' + var] = accu
+		process_rpath(self.qt5_vars,       'LIBPATH_QTCORE')
+
+@conf
+def set_qt5_libs_to_check(self):
+	self.qt5_vars = Utils.to_list(getattr(self, 'qt5_vars', []))
+	if not self.qt5_vars:
+		dirlst = Utils.listdir(self.env.QTLIBS)
+
+		pat = self.env.cxxshlib_PATTERN
+		if Utils.is_win32:
+			pat = pat.replace('.dll', '.lib')
+		if self.environ.get('QT5_FORCE_STATIC'):
+			pat = self.env.cxxstlib_PATTERN
+		if Utils.unversioned_sys_platform() == 'darwin':
+			pat = r"%s\.framework"
+		re_qt = re.compile(pat%'Qt5?(?P<name>.*)'+'$')
+		for x in dirlst:
+			m = re_qt.match(x)
+			if m:
+				self.qt5_vars.append("Qt5%s" % m.group('name'))
+		if not self.qt5_vars:
+			self.fatal('cannot find any Qt5 library (%r)' % self.env.QTLIBS)
+
+	qtextralibs = getattr(Options.options, 'qtextralibs', None)
+	if qtextralibs:
+		self.qt5_vars.extend(qtextralibs.split(','))
+
+@conf
+def set_qt5_defines(self):
+	if sys.platform != 'win32':
+		return
+	for x in self.qt5_vars:
+		y=x.replace('Qt5', 'Qt')[2:].upper()
+		self.env.append_unique('DEFINES_%s' % x.upper(), 'QT_%s_LIB' % y)
+
+def options(opt):
+	"""
+	Command-line options
+	"""
+	opt.add_option('--want-rpath', action='store_true', default=False, dest='want_rpath', help='enable the rpath for qt libraries')
+	for i in 'qtdir qtbin qtlibs'.split():
+		opt.add_option('--'+i, type='string', default='', dest=i)
+
+	opt.add_option('--translate', action='store_true', help='collect translation strings', dest='trans_qt5', default=False)
+	opt.add_option('--qtextralibs', type='string', default='', dest='qtextralibs', help='additional qt libraries on the system to add to default ones, comma separated')
+
diff --git a/.waf-tools/sphinx_build.py b/.waf-tools/sphinx_build.py
new file mode 100644
index 0000000..b44a54f
--- /dev/null
+++ b/.waf-tools/sphinx_build.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+# encoding: utf-8
+
+# inspired by code by Hans-Martin von Gaudecker, 2012
+
+import os
+from waflib import Node, Task, TaskGen, Errors, Logs, Build, Utils
+
+class sphinx_build(Task.Task):
+    color = 'BLUE'
+    run_str = '${SPHINX_BUILD} -D ${VERSION} -D ${RELEASE} -q -b ${BUILDERNAME} -d ${DOCTREEDIR} ${SRCDIR} ${OUTDIR}'
+
+    def __str__(self):
+        env = self.env
+        src_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.inputs])
+        tgt_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.outputs])
+        if self.outputs: sep = ' -> '
+        else: sep = ''
+        return'%s [%s]: %s%s%s\n'%(self.__class__.__name__.replace('_task',''),
+                                   self.env['BUILDERNAME'], src_str, sep, tgt_str)
+
+@TaskGen.extension('.py', '.rst')
+def sig_hook(self, node):
+    node.sig=Utils.h_file(node.abspath())
+
+@TaskGen.feature("sphinx")
+@TaskGen.before_method("process_source")
+def apply_sphinx(self):
+    """Set up the task generator with a Sphinx instance and create a task."""
+
+    inputs = []
+    for i in Utils.to_list(self.source):
+        if not isinstance(i, Node.Node):
+            node = self.path.find_node(node)
+        else:
+            node = i
+        if not node:
+            raise ValueError('[%s] file not found' % i)
+        inputs.append(node)
+
+    task = self.create_task('sphinx_build', inputs)
+
+    conf = self.path.find_node(self.config)
+    task.inputs.append(conf)
+
+    confdir = conf.parent.abspath()
+    buildername = getattr(self, 'builder', 'html')
+    srcdir = getattr(self, 'srcdir', confdir)
+    outdir = self.path.find_or_declare(getattr(self, 'outdir', buildername)).get_bld()
+    doctreedir = getattr(self, 'doctreedir', os.path.join(outdir.abspath(), '.doctrees'))
+
+    task.env['BUILDERNAME'] = buildername
+    task.env['SRCDIR'] = srcdir
+    task.env['DOCTREEDIR'] = doctreedir
+    task.env['OUTDIR'] = outdir.abspath()
+    task.env['VERSION'] = 'version=%s' % self.version
+    task.env['RELEASE'] = 'release=%s' % getattr(self, 'release', self.version)
+
+    import imp
+    confData = imp.load_source('sphinx_conf', conf.abspath())
+
+    if buildername == 'man':
+        for i in confData.man_pages:
+            target = outdir.find_or_declare('%s.%d' % (i[1], i[4]))
+            task.outputs.append(target)
+
+            if self.install_path:
+                self.bld.install_files('%s/man%d/' % (self.install_path, i[4]), target)
+    else:
+        task.outputs.append(outdir)
+
+def configure(conf):
+    conf.find_program('sphinx-build', var='SPHINX_BUILD', mandatory=False)
+
+# sphinx docs
+from waflib.Build import BuildContext
+class sphinx(BuildContext):
+    cmd = "sphinx"
+    fun = "sphinx"
