diff --git a/src/.lock-waf_darwin_build b/src/.lock-waf_darwin_build
new file mode 100644
index 0000000..6cd7839
--- /dev/null
+++ b/src/.lock-waf_darwin_build
@@ -0,0 +1,8 @@
+argv = ['./waf', 'configure']
+environ = {'TERM_SESSION_ID': 'E52FE51C-C95A-494C-857C-55A20A902838', 'SSH_AUTH_SOCK': '/tmp/launch-QMd9Vp/Listeners', 'TERM_PROGRAM_VERSION': '309', 'SHELL': '/bin/bash', 'LOGNAME': 'akmhoque', 'USER': 'akmhoque', 'HOME': '/Users/akmhoque', 'PKG_CONFIG_PATH': '/opt/local/pkgconfig:/usr/local/lib/pkgconfig:/usr/lib/pkgconfig', 'PATH': '/usr/local/ndn/bin:/usr/local/ndn/sbin:/usr/local/ndn/bin:/usr/local/ndn/sbin:/usr/local/ndn/bin:/usr/local/ndn/sbin:/usr/local/ndn/bin:/usr/local/ndn/sbin:/Library/Frameworks/Python.framework/Versions/2.7/bin:/opt/local/bin:/opt/local/sbin:/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin', 'DISPLAY': '/tmp/launch-akopgf/org.macosforge.xquartz:0', '_': './waf', 'TERM_PROGRAM': 'Apple_Terminal', 'LANG': 'en_US.UTF-8', 'TERM': 'xterm-256color', 'Apple_PubSub_Socket_Render': '/tmp/launch-Aca5Aa/Render', 'SHLVL': '1', 'OLDPWD': '/Users/akmhoque/Development', 'SECURITYSESSIONID': '186a4', '__CF_USER_TEXT_ENCODING': '0x1F5:0:0', 'Apple_Ubiquity_Message': '/tmp/launch-jpsxl4/Apple_Ubiquity_Message', 'PWD': '/Users/akmhoque/Development/CertTool', 'TMPDIR': '/var/folders/lg/h72gk679087gz9scbvnpfq_m0000gn/T/', 'COMMAND_MODE': 'unix2003'}
+files = ['/Users/akmhoque/Development/CertTool/wscript']
+hash = 2343082860908231459
+options = {'force': False, 'verbose': 0, 'boost_python': '27', 'SHAREDSTATEDIR': '', 'destdir': '', 'zones': '', 'prefix': '/usr/local/', 'download': False, 'boost_mt': False, 'targets': '', 'MANDIR': '', 'boost_libs': '', 'INFODIR': '', 'nocache': False, 'progress_bar': 0, 'EXEC_PREFIX': '', 'top': '', 'LOCALSTATEDIR': '', 'INCLUDEDIR': '', 'LIBEXECDIR': '', 'out': '', 'check_cxx_compiler': 'g++', 'PSDIR': '', 'BINDIR': '', 'files': '', 'DOCDIR': '', 'SYSCONFDIR': '', 'jobs': 2, 'DATAROOTDIR': '', 'boost_toolset': '', 'distcheck_args': None, 'boost_includes': '', 'PDFDIR': '', 'DATADIR': '', 'LIBDIR': '', 'SBINDIR': '', 'boost_abi': '', 'boost_linkage_autodetect': None, 'boost_static': False, 'HTMLDIR': '', 'LOCALEDIR': '', 'keep': 0, 'debug': False, 'DVIDIR': '', 'check_c_compiler': 'gcc', 'OLDINCLUDEDIR': ''}
+out_dir = '/Users/akmhoque/Development/CertTool/build'
+run_dir = '/Users/akmhoque/Development/CertTool'
+top_dir = '/Users/akmhoque/Development/CertTool'
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Build.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Build.py
new file mode 100644
index 0000000..f76933a
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Build.py
@@ -0,0 +1,758 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,errno,re,shutil
+try:
+	import cPickle
+except ImportError:
+	import pickle as cPickle
+from waflib import Runner,TaskGen,Utils,ConfigSet,Task,Logs,Options,Context,Errors
+import waflib.Node
+CACHE_DIR='c4che'
+CACHE_SUFFIX='_cache.py'
+INSTALL=1337
+UNINSTALL=-1337
+SAVED_ATTRS='root node_deps raw_deps task_sigs'.split()
+CFG_FILES='cfg_files'
+POST_AT_ONCE=0
+POST_LAZY=1
+POST_BOTH=2
+class BuildContext(Context.Context):
+	'''executes the build'''
+	cmd='build'
+	variant=''
+	def __init__(self,**kw):
+		super(BuildContext,self).__init__(**kw)
+		self.is_install=0
+		self.top_dir=kw.get('top_dir',Context.top_dir)
+		self.run_dir=kw.get('run_dir',Context.run_dir)
+		self.post_mode=POST_AT_ONCE
+		self.out_dir=kw.get('out_dir',Context.out_dir)
+		self.cache_dir=kw.get('cache_dir',None)
+		if not self.cache_dir:
+			self.cache_dir=self.out_dir+os.sep+CACHE_DIR
+		self.all_envs={}
+		self.task_sigs={}
+		self.node_deps={}
+		self.raw_deps={}
+		self.cache_dir_contents={}
+		self.task_gen_cache_names={}
+		self.launch_dir=Context.launch_dir
+		self.jobs=Options.options.jobs
+		self.targets=Options.options.targets
+		self.keep=Options.options.keep
+		self.cache_global=Options.cache_global
+		self.nocache=Options.options.nocache
+		self.progress_bar=Options.options.progress_bar
+		self.deps_man=Utils.defaultdict(list)
+		self.current_group=0
+		self.groups=[]
+		self.group_names={}
+	def get_variant_dir(self):
+		if not self.variant:
+			return self.out_dir
+		return os.path.join(self.out_dir,self.variant)
+	variant_dir=property(get_variant_dir,None)
+	def __call__(self,*k,**kw):
+		kw['bld']=self
+		ret=TaskGen.task_gen(*k,**kw)
+		self.task_gen_cache_names={}
+		self.add_to_group(ret,group=kw.get('group',None))
+		return ret
+	def rule(self,*k,**kw):
+		def f(rule):
+			ret=self(*k,**kw)
+			ret.rule=rule
+			return ret
+		return f
+	def __copy__(self):
+		raise Errors.WafError('build contexts are not supposed to be copied')
+	def install_files(self,*k,**kw):
+		pass
+	def install_as(self,*k,**kw):
+		pass
+	def symlink_as(self,*k,**kw):
+		pass
+	def load_envs(self):
+		node=self.root.find_node(self.cache_dir)
+		if not node:
+			raise Errors.WafError('The project was not configured: run "waf configure" first!')
+		lst=node.ant_glob('**/*%s'%CACHE_SUFFIX,quiet=True)
+		if not lst:
+			raise Errors.WafError('The cache directory is empty: reconfigure the project')
+		for x in lst:
+			name=x.path_from(node).replace(CACHE_SUFFIX,'').replace('\\','/')
+			env=ConfigSet.ConfigSet(x.abspath())
+			self.all_envs[name]=env
+			for f in env[CFG_FILES]:
+				newnode=self.root.find_resource(f)
+				try:
+					h=Utils.h_file(newnode.abspath())
+				except(IOError,AttributeError):
+					Logs.error('cannot find %r'%f)
+					h=Utils.SIG_NIL
+				newnode.sig=h
+	def init_dirs(self):
+		if not(os.path.isabs(self.top_dir)and os.path.isabs(self.out_dir)):
+			raise Errors.WafError('The project was not configured: run "waf configure" first!')
+		self.path=self.srcnode=self.root.find_dir(self.top_dir)
+		self.bldnode=self.root.make_node(self.variant_dir)
+		self.bldnode.mkdir()
+	def execute(self):
+		self.restore()
+		if not self.all_envs:
+			self.load_envs()
+		self.execute_build()
+	def execute_build(self):
+		Logs.info("Waf: Entering directory `%s'"%self.variant_dir)
+		self.recurse([self.run_dir])
+		self.pre_build()
+		self.timer=Utils.Timer()
+		if self.progress_bar:
+			sys.stderr.write(Logs.colors.cursor_off)
+		try:
+			self.compile()
+		finally:
+			if self.progress_bar==1:
+				c=len(self.returned_tasks)or 1
+				self.to_log(self.progress_line(c,c,Logs.colors.BLUE,Logs.colors.NORMAL))
+				print('')
+				sys.stdout.flush()
+				sys.stderr.write(Logs.colors.cursor_on)
+			Logs.info("Waf: Leaving directory `%s'"%self.variant_dir)
+		self.post_build()
+	def restore(self):
+		try:
+			env=ConfigSet.ConfigSet(os.path.join(self.cache_dir,'build.config.py'))
+		except(IOError,OSError):
+			pass
+		else:
+			if env['version']<Context.HEXVERSION:
+				raise Errors.WafError('Version mismatch! reconfigure the project')
+			for t in env['tools']:
+				self.setup(**t)
+		dbfn=os.path.join(self.variant_dir,Context.DBFILE)
+		try:
+			data=Utils.readf(dbfn,'rb')
+		except(IOError,EOFError):
+			Logs.debug('build: Could not load the build cache %s (missing)'%dbfn)
+		else:
+			try:
+				waflib.Node.pickle_lock.acquire()
+				waflib.Node.Nod3=self.node_class
+				try:
+					data=cPickle.loads(data)
+				except Exception ,e:
+					Logs.debug('build: Could not pickle the build cache %s: %r'%(dbfn,e))
+				else:
+					for x in SAVED_ATTRS:
+						setattr(self,x,data[x])
+			finally:
+				waflib.Node.pickle_lock.release()
+		self.init_dirs()
+	def store(self):
+		data={}
+		for x in SAVED_ATTRS:
+			data[x]=getattr(self,x)
+		db=os.path.join(self.variant_dir,Context.DBFILE)
+		try:
+			waflib.Node.pickle_lock.acquire()
+			waflib.Node.Nod3=self.node_class
+			x=cPickle.dumps(data,-1)
+		finally:
+			waflib.Node.pickle_lock.release()
+		Utils.writef(db+'.tmp',x,m='wb')
+		try:
+			st=os.stat(db)
+			os.remove(db)
+			if not Utils.is_win32:
+				os.chown(db+'.tmp',st.st_uid,st.st_gid)
+		except(AttributeError,OSError):
+			pass
+		os.rename(db+'.tmp',db)
+	def compile(self):
+		Logs.debug('build: compile()')
+		self.producer=Runner.Parallel(self,self.jobs)
+		self.producer.biter=self.get_build_iterator()
+		self.returned_tasks=[]
+		try:
+			self.producer.start()
+		except KeyboardInterrupt:
+			self.store()
+			raise
+		else:
+			if self.producer.dirty:
+				self.store()
+		if self.producer.error:
+			raise Errors.BuildError(self.producer.error)
+	def setup(self,tool,tooldir=None,funs=None):
+		if isinstance(tool,list):
+			for i in tool:self.setup(i,tooldir)
+			return
+		module=Context.load_tool(tool,tooldir)
+		if hasattr(module,"setup"):module.setup(self)
+	def get_env(self):
+		try:
+			return self.all_envs[self.variant]
+		except KeyError:
+			return self.all_envs['']
+	def set_env(self,val):
+		self.all_envs[self.variant]=val
+	env=property(get_env,set_env)
+	def add_manual_dependency(self,path,value):
+		if path is None:
+			raise ValueError('Invalid input')
+		if isinstance(path,waflib.Node.Node):
+			node=path
+		elif os.path.isabs(path):
+			node=self.root.find_resource(path)
+		else:
+			node=self.path.find_resource(path)
+		if isinstance(value,list):
+			self.deps_man[id(node)].extend(value)
+		else:
+			self.deps_man[id(node)].append(value)
+	def launch_node(self):
+		try:
+			return self.p_ln
+		except AttributeError:
+			self.p_ln=self.root.find_dir(self.launch_dir)
+			return self.p_ln
+	def hash_env_vars(self,env,vars_lst):
+		if not env.table:
+			env=env.parent
+			if not env:
+				return Utils.SIG_NIL
+		idx=str(id(env))+str(vars_lst)
+		try:
+			cache=self.cache_env
+		except AttributeError:
+			cache=self.cache_env={}
+		else:
+			try:
+				return self.cache_env[idx]
+			except KeyError:
+				pass
+		lst=[env[a]for a in vars_lst]
+		ret=Utils.h_list(lst)
+		Logs.debug('envhash: %s %r',Utils.to_hex(ret),lst)
+		cache[idx]=ret
+		return ret
+	def get_tgen_by_name(self,name):
+		cache=self.task_gen_cache_names
+		if not cache:
+			for g in self.groups:
+				for tg in g:
+					try:
+						cache[tg.name]=tg
+					except AttributeError:
+						pass
+		try:
+			return cache[name]
+		except KeyError:
+			raise Errors.WafError('Could not find a task generator for the name %r'%name)
+	def progress_line(self,state,total,col1,col2):
+		n=len(str(total))
+		Utils.rot_idx+=1
+		ind=Utils.rot_chr[Utils.rot_idx%4]
+		pc=(100.*state)/total
+		eta=str(self.timer)
+		fs="[%%%dd/%%%dd][%%s%%2d%%%%%%s][%s]["%(n,n,ind)
+		left=fs%(state,total,col1,pc,col2)
+		right='][%s%s%s]'%(col1,eta,col2)
+		cols=Logs.get_term_cols()-len(left)-len(right)+2*len(col1)+2*len(col2)
+		if cols<7:cols=7
+		ratio=((cols*state)//total)-1
+		bar=('='*ratio+'>').ljust(cols)
+		msg=Utils.indicator%(left,bar,right)
+		return msg
+	def declare_chain(self,*k,**kw):
+		return TaskGen.declare_chain(*k,**kw)
+	def pre_build(self):
+		for m in getattr(self,'pre_funs',[]):
+			m(self)
+	def post_build(self):
+		for m in getattr(self,'post_funs',[]):
+			m(self)
+	def add_pre_fun(self,meth):
+		try:
+			self.pre_funs.append(meth)
+		except AttributeError:
+			self.pre_funs=[meth]
+	def add_post_fun(self,meth):
+		try:
+			self.post_funs.append(meth)
+		except AttributeError:
+			self.post_funs=[meth]
+	def get_group(self,x):
+		if not self.groups:
+			self.add_group()
+		if x is None:
+			return self.groups[self.current_group]
+		if x in self.group_names:
+			return self.group_names[x]
+		return self.groups[x]
+	def add_to_group(self,tgen,group=None):
+		assert(isinstance(tgen,TaskGen.task_gen)or isinstance(tgen,Task.TaskBase))
+		tgen.bld=self
+		self.get_group(group).append(tgen)
+	def get_group_name(self,g):
+		if not isinstance(g,list):
+			g=self.groups[g]
+		for x in self.group_names:
+			if id(self.group_names[x])==id(g):
+				return x
+		return''
+	def get_group_idx(self,tg):
+		se=id(tg)
+		for i in range(len(self.groups)):
+			for t in self.groups[i]:
+				if id(t)==se:
+					return i
+		return None
+	def add_group(self,name=None,move=True):
+		if name and name in self.group_names:
+			Logs.error('add_group: name %s already present'%name)
+		g=[]
+		self.group_names[name]=g
+		self.groups.append(g)
+		if move:
+			self.current_group=len(self.groups)-1
+	def set_group(self,idx):
+		if isinstance(idx,str):
+			g=self.group_names[idx]
+			for i in range(len(self.groups)):
+				if id(g)==id(self.groups[i]):
+					self.current_group=i
+		else:
+			self.current_group=idx
+	def total(self):
+		total=0
+		for group in self.groups:
+			for tg in group:
+				try:
+					total+=len(tg.tasks)
+				except AttributeError:
+					total+=1
+		return total
+	def get_targets(self):
+		to_post=[]
+		min_grp=0
+		for name in self.targets.split(','):
+			tg=self.get_tgen_by_name(name)
+			if not tg:
+				raise Errors.WafError('target %r does not exist'%name)
+			m=self.get_group_idx(tg)
+			if m>min_grp:
+				min_grp=m
+				to_post=[tg]
+			elif m==min_grp:
+				to_post.append(tg)
+		return(min_grp,to_post)
+	def get_all_task_gen(self):
+		lst=[]
+		for g in self.groups:
+			lst.extend(g)
+		return lst
+	def post_group(self):
+		if self.targets=='*':
+			for tg in self.groups[self.cur]:
+				try:
+					f=tg.post
+				except AttributeError:
+					pass
+				else:
+					f()
+		elif self.targets:
+			if self.cur<self._min_grp:
+				for tg in self.groups[self.cur]:
+					try:
+						f=tg.post
+					except AttributeError:
+						pass
+					else:
+						f()
+			else:
+				for tg in self._exact_tg:
+					tg.post()
+		else:
+			ln=self.launch_node()
+			if ln.is_child_of(self.bldnode):
+				Logs.warn('Building from the build directory, forcing --targets=*')
+				ln=self.srcnode
+			elif not ln.is_child_of(self.srcnode):
+				Logs.warn('CWD %s is not under %s, forcing --targets=* (run distclean?)'%(ln.abspath(),self.srcnode.abspath()))
+				ln=self.srcnode
+			for tg in self.groups[self.cur]:
+				try:
+					f=tg.post
+				except AttributeError:
+					pass
+				else:
+					if tg.path.is_child_of(ln):
+						f()
+	def get_tasks_group(self,idx):
+		tasks=[]
+		for tg in self.groups[idx]:
+			try:
+				tasks.extend(tg.tasks)
+			except AttributeError:
+				tasks.append(tg)
+		return tasks
+	def get_build_iterator(self):
+		self.cur=0
+		if self.targets and self.targets!='*':
+			(self._min_grp,self._exact_tg)=self.get_targets()
+		global lazy_post
+		if self.post_mode!=POST_LAZY:
+			while self.cur<len(self.groups):
+				self.post_group()
+				self.cur+=1
+			self.cur=0
+		while self.cur<len(self.groups):
+			if self.post_mode!=POST_AT_ONCE:
+				self.post_group()
+			tasks=self.get_tasks_group(self.cur)
+			Task.set_file_constraints(tasks)
+			Task.set_precedence_constraints(tasks)
+			self.cur_tasks=tasks
+			self.cur+=1
+			if not tasks:
+				continue
+			yield tasks
+		while 1:
+			yield[]
+class inst(Task.Task):
+	color='CYAN'
+	def uid(self):
+		lst=[self.dest,self.path]+self.source
+		return Utils.h_list(repr(lst))
+	def post(self):
+		buf=[]
+		for x in self.source:
+			if isinstance(x,waflib.Node.Node):
+				y=x
+			else:
+				y=self.path.find_resource(x)
+				if not y:
+					if Logs.verbose:
+						Logs.warn('Could not find %s immediately (may cause broken builds)'%x)
+					idx=self.generator.bld.get_group_idx(self)
+					for tg in self.generator.bld.groups[idx]:
+						if not isinstance(tg,inst)and id(tg)!=id(self):
+							tg.post()
+						y=self.path.find_resource(x)
+						if y:
+							break
+					else:
+						raise Errors.WafError('Could not find %r in %r'%(x,self.path))
+			buf.append(y)
+		self.inputs=buf
+	def runnable_status(self):
+		ret=super(inst,self).runnable_status()
+		if ret==Task.SKIP_ME:
+			return Task.RUN_ME
+		return ret
+	def __str__(self):
+		return''
+	def run(self):
+		return self.generator.exec_task()
+	def get_install_path(self,destdir=True):
+		dest=Utils.subst_vars(self.dest,self.env)
+		dest=dest.replace('/',os.sep)
+		if destdir and Options.options.destdir:
+			dest=os.path.join(Options.options.destdir,os.path.splitdrive(dest)[1].lstrip(os.sep))
+		return dest
+	def exec_install_files(self):
+		destpath=self.get_install_path()
+		if not destpath:
+			raise Errors.WafError('unknown installation path %r'%self.generator)
+		for x,y in zip(self.source,self.inputs):
+			if self.relative_trick:
+				destfile=os.path.join(destpath,y.path_from(self.path))
+			else:
+				destfile=os.path.join(destpath,y.name)
+			self.generator.bld.do_install(y.abspath(),destfile,self.chmod)
+	def exec_install_as(self):
+		destfile=self.get_install_path()
+		self.generator.bld.do_install(self.inputs[0].abspath(),destfile,self.chmod)
+	def exec_symlink_as(self):
+		destfile=self.get_install_path()
+		src=self.link
+		if self.relative_trick:
+			src=os.path.relpath(src,os.path.dirname(destfile))
+		self.generator.bld.do_link(src,destfile)
+class InstallContext(BuildContext):
+	'''installs the targets on the system'''
+	cmd='install'
+	def __init__(self,**kw):
+		super(InstallContext,self).__init__(**kw)
+		self.uninstall=[]
+		self.is_install=INSTALL
+	def do_install(self,src,tgt,chmod=Utils.O644):
+		d,_=os.path.split(tgt)
+		if not d:
+			raise Errors.WafError('Invalid installation given %r->%r'%(src,tgt))
+		Utils.check_dir(d)
+		srclbl=src.replace(self.srcnode.abspath()+os.sep,'')
+		if not Options.options.force:
+			try:
+				st1=os.stat(tgt)
+				st2=os.stat(src)
+			except OSError:
+				pass
+			else:
+				if st1.st_mtime+2>=st2.st_mtime and st1.st_size==st2.st_size:
+					if not self.progress_bar:
+						Logs.info('- install %s (from %s)'%(tgt,srclbl))
+					return False
+		if not self.progress_bar:
+			Logs.info('+ install %s (from %s)'%(tgt,srclbl))
+		try:
+			os.remove(tgt)
+		except OSError:
+			pass
+		try:
+			shutil.copy2(src,tgt)
+			os.chmod(tgt,chmod)
+		except IOError:
+			try:
+				os.stat(src)
+			except(OSError,IOError):
+				Logs.error('File %r does not exist'%src)
+			raise Errors.WafError('Could not install the file %r'%tgt)
+	def do_link(self,src,tgt):
+		d,_=os.path.split(tgt)
+		Utils.check_dir(d)
+		link=False
+		if not os.path.islink(tgt):
+			link=True
+		elif os.readlink(tgt)!=src:
+			link=True
+		if link:
+			try:os.remove(tgt)
+			except OSError:pass
+			if not self.progress_bar:
+				Logs.info('+ symlink %s (to %s)'%(tgt,src))
+			os.symlink(src,tgt)
+		else:
+			if not self.progress_bar:
+				Logs.info('- symlink %s (to %s)'%(tgt,src))
+	def run_task_now(self,tsk,postpone):
+		tsk.post()
+		if not postpone:
+			if tsk.runnable_status()==Task.ASK_LATER:
+				raise self.WafError('cannot post the task %r'%tsk)
+			tsk.run()
+	def install_files(self,dest,files,env=None,chmod=Utils.O644,relative_trick=False,cwd=None,add=True,postpone=True):
+		tsk=inst(env=env or self.env)
+		tsk.bld=self
+		tsk.path=cwd or self.path
+		tsk.chmod=chmod
+		if isinstance(files,waflib.Node.Node):
+			tsk.source=[files]
+		else:
+			tsk.source=Utils.to_list(files)
+		tsk.dest=dest
+		tsk.exec_task=tsk.exec_install_files
+		tsk.relative_trick=relative_trick
+		if add:self.add_to_group(tsk)
+		self.run_task_now(tsk,postpone)
+		return tsk
+	def install_as(self,dest,srcfile,env=None,chmod=Utils.O644,cwd=None,add=True,postpone=True):
+		tsk=inst(env=env or self.env)
+		tsk.bld=self
+		tsk.path=cwd or self.path
+		tsk.chmod=chmod
+		tsk.source=[srcfile]
+		tsk.dest=dest
+		tsk.exec_task=tsk.exec_install_as
+		if add:self.add_to_group(tsk)
+		self.run_task_now(tsk,postpone)
+		return tsk
+	def symlink_as(self,dest,src,env=None,cwd=None,add=True,postpone=True,relative_trick=False):
+		if Utils.is_win32:
+			return
+		tsk=inst(env=env or self.env)
+		tsk.bld=self
+		tsk.dest=dest
+		tsk.path=cwd or self.path
+		tsk.source=[]
+		tsk.link=src
+		tsk.relative_trick=relative_trick
+		tsk.exec_task=tsk.exec_symlink_as
+		if add:self.add_to_group(tsk)
+		self.run_task_now(tsk,postpone)
+		return tsk
+class UninstallContext(InstallContext):
+	'''removes the targets installed'''
+	cmd='uninstall'
+	def __init__(self,**kw):
+		super(UninstallContext,self).__init__(**kw)
+		self.is_install=UNINSTALL
+	def do_install(self,src,tgt,chmod=Utils.O644):
+		if not self.progress_bar:
+			Logs.info('- remove %s'%tgt)
+		self.uninstall.append(tgt)
+		try:
+			os.remove(tgt)
+		except OSError ,e:
+			if e.errno!=errno.ENOENT:
+				if not getattr(self,'uninstall_error',None):
+					self.uninstall_error=True
+					Logs.warn('build: some files could not be uninstalled (retry with -vv to list them)')
+				if Logs.verbose>1:
+					Logs.warn('Could not remove %s (error code %r)'%(e.filename,e.errno))
+		while tgt:
+			tgt=os.path.dirname(tgt)
+			try:
+				os.rmdir(tgt)
+			except OSError:
+				break
+	def do_link(self,src,tgt):
+		try:
+			if not self.progress_bar:
+				Logs.info('- remove %s'%tgt)
+			os.remove(tgt)
+		except OSError:
+			pass
+		while tgt:
+			tgt=os.path.dirname(tgt)
+			try:
+				os.rmdir(tgt)
+			except OSError:
+				break
+	def execute(self):
+		try:
+			def runnable_status(self):
+				return Task.SKIP_ME
+			setattr(Task.Task,'runnable_status_back',Task.Task.runnable_status)
+			setattr(Task.Task,'runnable_status',runnable_status)
+			super(UninstallContext,self).execute()
+		finally:
+			setattr(Task.Task,'runnable_status',Task.Task.runnable_status_back)
+class CleanContext(BuildContext):
+	'''cleans the project'''
+	cmd='clean'
+	def execute(self):
+		self.restore()
+		if not self.all_envs:
+			self.load_envs()
+		self.recurse([self.run_dir])
+		try:
+			self.clean()
+		finally:
+			self.store()
+	def clean(self):
+		Logs.debug('build: clean called')
+		if self.bldnode!=self.srcnode:
+			lst=[]
+			for e in self.all_envs.values():
+				lst.extend(self.root.find_or_declare(f)for f in e[CFG_FILES])
+			for n in self.bldnode.ant_glob('**/*',excl='.lock* *conf_check_*/** config.log c4che/*',quiet=True):
+				if n in lst:
+					continue
+				n.delete()
+		self.root.children={}
+		for v in'node_deps task_sigs raw_deps'.split():
+			setattr(self,v,{})
+class ListContext(BuildContext):
+	'''lists the targets to execute'''
+	cmd='list'
+	def execute(self):
+		self.restore()
+		if not self.all_envs:
+			self.load_envs()
+		self.recurse([self.run_dir])
+		self.pre_build()
+		self.timer=Utils.Timer()
+		for g in self.groups:
+			for tg in g:
+				try:
+					f=tg.post
+				except AttributeError:
+					pass
+				else:
+					f()
+		try:
+			self.get_tgen_by_name('')
+		except Exception:
+			pass
+		lst=list(self.task_gen_cache_names.keys())
+		lst.sort()
+		for k in lst:
+			Logs.pprint('GREEN',k)
+class StepContext(BuildContext):
+	'''executes tasks in a step-by-step fashion, for debugging'''
+	cmd='step'
+	def __init__(self,**kw):
+		super(StepContext,self).__init__(**kw)
+		self.files=Options.options.files
+	def compile(self):
+		if not self.files:
+			Logs.warn('Add a pattern for the debug build, for example "waf step --files=main.c,app"')
+			BuildContext.compile(self)
+			return
+		targets=None
+		if self.targets and self.targets!='*':
+			targets=self.targets.split(',')
+		for g in self.groups:
+			for tg in g:
+				if targets and tg.name not in targets:
+					continue
+				try:
+					f=tg.post
+				except AttributeError:
+					pass
+				else:
+					f()
+			for pat in self.files.split(','):
+				matcher=self.get_matcher(pat)
+				for tg in g:
+					if isinstance(tg,Task.TaskBase):
+						lst=[tg]
+					else:
+						lst=tg.tasks
+					for tsk in lst:
+						do_exec=False
+						for node in getattr(tsk,'inputs',[]):
+							if matcher(node,output=False):
+								do_exec=True
+								break
+						for node in getattr(tsk,'outputs',[]):
+							if matcher(node,output=True):
+								do_exec=True
+								break
+						if do_exec:
+							ret=tsk.run()
+							Logs.info('%s -> exit %r'%(str(tsk),ret))
+	def get_matcher(self,pat):
+		inn=True
+		out=True
+		if pat.startswith('in:'):
+			out=False
+			pat=pat.replace('in:','')
+		elif pat.startswith('out:'):
+			inn=False
+			pat=pat.replace('out:','')
+		anode=self.root.find_node(pat)
+		pattern=None
+		if not anode:
+			if not pat.startswith('^'):
+				pat='^.+?%s'%pat
+			if not pat.endswith('$'):
+				pat='%s$'%pat
+			pattern=re.compile(pat)
+		def match(node,output):
+			if output==True and not out:
+				return False
+			if output==False and not inn:
+				return False
+			if anode:
+				return anode==node
+			else:
+				return pattern.match(node.abspath())
+		return match
+BuildContext.store=Utils.nogc(BuildContext.store)
+BuildContext.restore=Utils.nogc(BuildContext.restore)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Build.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Build.pyc
new file mode 100644
index 0000000..46ac850
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Build.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/ConfigSet.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/ConfigSet.py
new file mode 100644
index 0000000..f9fdcc7
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/ConfigSet.py
@@ -0,0 +1,152 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import copy,re,os
+from waflib import Logs,Utils
+re_imp=re.compile('^(#)*?([^#=]*?)\ =\ (.*?)$',re.M)
+class ConfigSet(object):
+	__slots__=('table','parent')
+	def __init__(self,filename=None):
+		self.table={}
+		if filename:
+			self.load(filename)
+	def __contains__(self,key):
+		if key in self.table:return True
+		try:return self.parent.__contains__(key)
+		except AttributeError:return False
+	def keys(self):
+		keys=set()
+		cur=self
+		while cur:
+			keys.update(cur.table.keys())
+			cur=getattr(cur,'parent',None)
+		keys=list(keys)
+		keys.sort()
+		return keys
+	def __str__(self):
+		return"\n".join(["%r %r"%(x,self.__getitem__(x))for x in self.keys()])
+	def __getitem__(self,key):
+		try:
+			while 1:
+				x=self.table.get(key,None)
+				if not x is None:
+					return x
+				self=self.parent
+		except AttributeError:
+			return[]
+	def __setitem__(self,key,value):
+		self.table[key]=value
+	def __delitem__(self,key):
+		self[key]=[]
+	def __getattr__(self,name):
+		if name in self.__slots__:
+			return object.__getattr__(self,name)
+		else:
+			return self[name]
+	def __setattr__(self,name,value):
+		if name in self.__slots__:
+			object.__setattr__(self,name,value)
+		else:
+			self[name]=value
+	def __delattr__(self,name):
+		if name in self.__slots__:
+			object.__delattr__(self,name)
+		else:
+			del self[name]
+	def derive(self):
+		newenv=ConfigSet()
+		newenv.parent=self
+		return newenv
+	def detach(self):
+		tbl=self.get_merged_dict()
+		try:
+			delattr(self,'parent')
+		except AttributeError:
+			pass
+		else:
+			keys=tbl.keys()
+			for x in keys:
+				tbl[x]=copy.deepcopy(tbl[x])
+			self.table=tbl
+	def get_flat(self,key):
+		s=self[key]
+		if isinstance(s,str):return s
+		return' '.join(s)
+	def _get_list_value_for_modification(self,key):
+		try:
+			value=self.table[key]
+		except KeyError:
+			try:value=self.parent[key]
+			except AttributeError:value=[]
+			if isinstance(value,list):
+				value=value[:]
+			else:
+				value=[value]
+		else:
+			if not isinstance(value,list):
+				value=[value]
+		self.table[key]=value
+		return value
+	def append_value(self,var,val):
+		current_value=self._get_list_value_for_modification(var)
+		if isinstance(val,str):
+			val=[val]
+		current_value.extend(val)
+	def prepend_value(self,var,val):
+		if isinstance(val,str):
+			val=[val]
+		self.table[var]=val+self._get_list_value_for_modification(var)
+	def append_unique(self,var,val):
+		if isinstance(val,str):
+			val=[val]
+		current_value=self._get_list_value_for_modification(var)
+		for x in val:
+			if x not in current_value:
+				current_value.append(x)
+	def get_merged_dict(self):
+		table_list=[]
+		env=self
+		while 1:
+			table_list.insert(0,env.table)
+			try:env=env.parent
+			except AttributeError:break
+		merged_table={}
+		for table in table_list:
+			merged_table.update(table)
+		return merged_table
+	def store(self,filename):
+		try:
+			os.makedirs(os.path.split(filename)[0])
+		except OSError:
+			pass
+		buf=[]
+		merged_table=self.get_merged_dict()
+		keys=list(merged_table.keys())
+		keys.sort()
+		try:
+			fun=ascii
+		except NameError:
+			fun=repr
+		for k in keys:
+			if k!='undo_stack':
+				buf.append('%s = %s\n'%(k,fun(merged_table[k])))
+		Utils.writef(filename,''.join(buf))
+	def load(self,filename):
+		tbl=self.table
+		code=Utils.readf(filename,m='rU')
+		for m in re_imp.finditer(code):
+			g=m.group
+			tbl[g(2)]=eval(g(3))
+		Logs.debug('env: %s'%str(self.table))
+	def update(self,d):
+		for k,v in d.items():
+			self[k]=v
+	def stash(self):
+		orig=self.table
+		tbl=self.table=self.table.copy()
+		for x in tbl.keys():
+			tbl[x]=copy.deepcopy(tbl[x])
+		self.undo_stack=self.undo_stack+[orig]
+	def revert(self):
+		self.table=self.undo_stack.pop(-1)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/ConfigSet.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/ConfigSet.pyc
new file mode 100644
index 0000000..df80b8e
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/ConfigSet.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Configure.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Configure.py
new file mode 100644
index 0000000..4be13bb
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Configure.py
@@ -0,0 +1,318 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,shlex,sys,time
+from waflib import ConfigSet,Utils,Options,Logs,Context,Build,Errors
+try:
+	from urllib import request
+except ImportError:
+	from urllib import urlopen
+else:
+	urlopen=request.urlopen
+BREAK='break'
+CONTINUE='continue'
+WAF_CONFIG_LOG='config.log'
+autoconfig=False
+conf_template='''# project %(app)s configured on %(now)s by
+# waf %(wafver)s (abi %(abi)s, python %(pyver)x on %(systype)s)
+# using %(args)s
+#'''
+def download_check(node):
+	pass
+def download_tool(tool,force=False,ctx=None):
+	for x in Utils.to_list(Context.remote_repo):
+		for sub in Utils.to_list(Context.remote_locs):
+			url='/'.join((x,sub,tool+'.py'))
+			try:
+				web=urlopen(url)
+				try:
+					if web.getcode()!=200:
+						continue
+				except AttributeError:
+					pass
+			except Exception:
+				continue
+			else:
+				tmp=ctx.root.make_node(os.sep.join((Context.waf_dir,'waflib','extras',tool+'.py')))
+				tmp.write(web.read(),'wb')
+				Logs.warn('Downloaded %s from %s'%(tool,url))
+				download_check(tmp)
+				try:
+					module=Context.load_tool(tool)
+				except Exception:
+					Logs.warn('The tool %s from %s is unusable'%(tool,url))
+					try:
+						tmp.delete()
+					except Exception:
+						pass
+					continue
+				return module
+	raise Errors.WafError('Could not load the Waf tool')
+class ConfigurationContext(Context.Context):
+	'''configures the project'''
+	cmd='configure'
+	error_handlers=[]
+	def __init__(self,**kw):
+		super(ConfigurationContext,self).__init__(**kw)
+		self.environ=dict(os.environ)
+		self.all_envs={}
+		self.top_dir=None
+		self.out_dir=None
+		self.tools=[]
+		self.hash=0
+		self.files=[]
+		self.tool_cache=[]
+		self.setenv('')
+	def setenv(self,name,env=None):
+		if name not in self.all_envs or env:
+			if not env:
+				env=ConfigSet.ConfigSet()
+				self.prepare_env(env)
+			else:
+				env=env.derive()
+			self.all_envs[name]=env
+		self.variant=name
+	def get_env(self):
+		return self.all_envs[self.variant]
+	def set_env(self,val):
+		self.all_envs[self.variant]=val
+	env=property(get_env,set_env)
+	def init_dirs(self):
+		top=self.top_dir
+		if not top:
+			top=Options.options.top
+		if not top:
+			top=getattr(Context.g_module,Context.TOP,None)
+		if not top:
+			top=self.path.abspath()
+		top=os.path.abspath(top)
+		self.srcnode=(os.path.isabs(top)and self.root or self.path).find_dir(top)
+		assert(self.srcnode)
+		out=self.out_dir
+		if not out:
+			out=Options.options.out
+		if not out:
+			out=getattr(Context.g_module,Context.OUT,None)
+		if not out:
+			out=Options.lockfile.replace('.lock-waf_%s_'%sys.platform,'').replace('.lock-waf','')
+		self.bldnode=(os.path.isabs(out)and self.root or self.path).make_node(out)
+		self.bldnode.mkdir()
+		if not os.path.isdir(self.bldnode.abspath()):
+			conf.fatal('Could not create the build directory %s'%self.bldnode.abspath())
+	def execute(self):
+		self.init_dirs()
+		self.cachedir=self.bldnode.make_node(Build.CACHE_DIR)
+		self.cachedir.mkdir()
+		path=os.path.join(self.bldnode.abspath(),WAF_CONFIG_LOG)
+		self.logger=Logs.make_logger(path,'cfg')
+		app=getattr(Context.g_module,'APPNAME','')
+		if app:
+			ver=getattr(Context.g_module,'VERSION','')
+			if ver:
+				app="%s (%s)"%(app,ver)
+		now=time.ctime()
+		pyver=sys.hexversion
+		systype=sys.platform
+		args=" ".join(sys.argv)
+		wafver=Context.WAFVERSION
+		abi=Context.ABI
+		self.to_log(conf_template%vars())
+		self.msg('Setting top to',self.srcnode.abspath())
+		self.msg('Setting out to',self.bldnode.abspath())
+		if id(self.srcnode)==id(self.bldnode):
+			Logs.warn('Setting top == out (remember to use "update_outputs")')
+		elif id(self.path)!=id(self.srcnode):
+			if self.srcnode.is_child_of(self.path):
+				Logs.warn('Are you certain that you do not want to set top="." ?')
+		super(ConfigurationContext,self).execute()
+		self.store()
+		Context.top_dir=self.srcnode.abspath()
+		Context.out_dir=self.bldnode.abspath()
+		env=ConfigSet.ConfigSet()
+		env['argv']=sys.argv
+		env['options']=Options.options.__dict__
+		env.run_dir=Context.run_dir
+		env.top_dir=Context.top_dir
+		env.out_dir=Context.out_dir
+		env['hash']=self.hash
+		env['files']=self.files
+		env['environ']=dict(self.environ)
+		if not self.env.NO_LOCK_IN_RUN:
+			env.store(Context.run_dir+os.sep+Options.lockfile)
+		if not self.env.NO_LOCK_IN_TOP:
+			env.store(Context.top_dir+os.sep+Options.lockfile)
+		if not self.env.NO_LOCK_IN_OUT:
+			env.store(Context.out_dir+os.sep+Options.lockfile)
+	def prepare_env(self,env):
+		if not env.PREFIX:
+			if Options.options.prefix or Utils.is_win32:
+				env.PREFIX=os.path.abspath(os.path.expanduser(Options.options.prefix))
+			else:
+				env.PREFIX=''
+		if not env.BINDIR:
+			env.BINDIR=Utils.subst_vars('${PREFIX}/bin',env)
+		if not env.LIBDIR:
+			env.LIBDIR=Utils.subst_vars('${PREFIX}/lib',env)
+	def store(self):
+		n=self.cachedir.make_node('build.config.py')
+		n.write('version = 0x%x\ntools = %r\n'%(Context.HEXVERSION,self.tools))
+		if not self.all_envs:
+			self.fatal('nothing to store in the configuration context!')
+		for key in self.all_envs:
+			tmpenv=self.all_envs[key]
+			tmpenv.store(os.path.join(self.cachedir.abspath(),key+Build.CACHE_SUFFIX))
+	def load(self,input,tooldir=None,funs=None,download=True):
+		tools=Utils.to_list(input)
+		if tooldir:tooldir=Utils.to_list(tooldir)
+		for tool in tools:
+			mag=(tool,id(self.env),funs)
+			if mag in self.tool_cache:
+				self.to_log('(tool %s is already loaded, skipping)'%tool)
+				continue
+			self.tool_cache.append(mag)
+			module=None
+			try:
+				module=Context.load_tool(tool,tooldir)
+			except ImportError ,e:
+				if Options.options.download:
+					module=download_tool(tool,ctx=self)
+					if not module:
+						self.fatal('Could not load the Waf tool %r or download a suitable replacement from the repository (sys.path %r)\n%s'%(tool,sys.path,e))
+				else:
+					self.fatal('Could not load the Waf tool %r from %r (try the --download option?):\n%s'%(tool,sys.path,e))
+			except Exception ,e:
+				self.to_log('imp %r (%r & %r)'%(tool,tooldir,funs))
+				self.to_log(Utils.ex_stack())
+				raise
+			if funs is not None:
+				self.eval_rules(funs)
+			else:
+				func=getattr(module,'configure',None)
+				if func:
+					if type(func)is type(Utils.readf):func(self)
+					else:self.eval_rules(func)
+			self.tools.append({'tool':tool,'tooldir':tooldir,'funs':funs})
+	def post_recurse(self,node):
+		super(ConfigurationContext,self).post_recurse(node)
+		self.hash=hash((self.hash,node.read('rb')))
+		self.files.append(node.abspath())
+	def eval_rules(self,rules):
+		self.rules=Utils.to_list(rules)
+		for x in self.rules:
+			f=getattr(self,x)
+			if not f:self.fatal("No such method '%s'."%x)
+			try:
+				f()
+			except Exception ,e:
+				ret=self.err_handler(x,e)
+				if ret==BREAK:
+					break
+				elif ret==CONTINUE:
+					continue
+				else:
+					raise
+	def err_handler(self,fun,error):
+		pass
+def conf(f):
+	def fun(*k,**kw):
+		mandatory=True
+		if'mandatory'in kw:
+			mandatory=kw['mandatory']
+			del kw['mandatory']
+		try:
+			return f(*k,**kw)
+		except Errors.ConfigurationError:
+			if mandatory:
+				raise
+	setattr(ConfigurationContext,f.__name__,fun)
+	setattr(Build.BuildContext,f.__name__,fun)
+	return f
+@conf
+def add_os_flags(self,var,dest=None):
+	try:self.env.append_value(dest or var,shlex.split(self.environ[var]))
+	except KeyError:pass
+@conf
+def cmd_to_list(self,cmd):
+	if isinstance(cmd,str)and cmd.find(' '):
+		try:
+			os.stat(cmd)
+		except OSError:
+			return shlex.split(cmd)
+		else:
+			return[cmd]
+	return cmd
+@conf
+def check_waf_version(self,mini='1.6.99',maxi='1.8.0'):
+	self.start_msg('Checking for waf version in %s-%s'%(str(mini),str(maxi)))
+	ver=Context.HEXVERSION
+	if Utils.num2ver(mini)>ver:
+		self.fatal('waf version should be at least %r (%r found)'%(Utils.num2ver(mini),ver))
+	if Utils.num2ver(maxi)<ver:
+		self.fatal('waf version should be at most %r (%r found)'%(Utils.num2ver(maxi),ver))
+	self.end_msg('ok')
+@conf
+def find_file(self,filename,path_list=[]):
+	for n in Utils.to_list(filename):
+		for d in Utils.to_list(path_list):
+			p=os.path.join(d,n)
+			if os.path.exists(p):
+				return p
+	self.fatal('Could not find %r'%filename)
+@conf
+def find_program(self,filename,**kw):
+	exts=kw.get('exts',Utils.is_win32 and'.exe,.com,.bat,.cmd'or',.sh,.pl,.py')
+	environ=kw.get('environ',os.environ)
+	ret=''
+	filename=Utils.to_list(filename)
+	var=kw.get('var','')
+	if not var:
+		var=filename[0].upper()
+	if self.env[var]:
+		ret=self.env[var]
+	elif var in environ:
+		ret=environ[var]
+	path_list=kw.get('path_list','')
+	if not ret:
+		if path_list:
+			path_list=Utils.to_list(path_list)
+		else:
+			path_list=environ.get('PATH','').split(os.pathsep)
+		if not isinstance(filename,list):
+			filename=[filename]
+		for a in exts.split(','):
+			if ret:
+				break
+			for b in filename:
+				if ret:
+					break
+				for c in path_list:
+					if ret:
+						break
+					x=os.path.expanduser(os.path.join(c,b+a))
+					if os.path.isfile(x):
+						ret=x
+	if not ret and Utils.winreg:
+		ret=Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER,filename)
+	if not ret and Utils.winreg:
+		ret=Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE,filename)
+	display_name=kw.get('display_name',', '.join(filename))
+	self.msg('Checking for program %s'%display_name,ret or False)
+	self.to_log('find program=%r paths=%r var=%r -> %r'%(filename,path_list,var,ret))
+	if not ret:
+		self.fatal(kw.get('errmsg','')or'Could not find the program %s'%','.join(filename))
+	if var:
+		self.env[var]=ret
+	return ret
+@conf
+def find_perl_program(self,filename,path_list=[],var=None,environ=None,exts=''):
+	try:
+		app=self.find_program(filename,path_list=path_list,var=var,environ=environ,exts=exts)
+	except Exception:
+		self.find_program('perl',var='PERL')
+		app=self.find_file(filename,os.environ['PATH'].split(os.pathsep))
+		if not app:
+			raise
+		if var:
+			self.env[var]=Utils.to_list(self.env['PERL'])+[app]
+	self.msg('Checking for %r'%filename,app)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Configure.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Configure.pyc
new file mode 100644
index 0000000..744ea93
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Configure.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Context.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Context.py
new file mode 100644
index 0000000..c11f10f
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Context.py
@@ -0,0 +1,319 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,imp,sys
+from waflib import Utils,Errors,Logs
+import waflib.Node
+HEXVERSION=0x1070b00
+WAFVERSION="1.7.11"
+WAFREVISION="50f631bc5e00bdda966c68094229b99be9a21084"
+ABI=98
+DBFILE='.wafpickle-%s-%d-%d'%(sys.platform,sys.hexversion,ABI)
+APPNAME='APPNAME'
+VERSION='VERSION'
+TOP='top'
+OUT='out'
+WSCRIPT_FILE='wscript'
+launch_dir=''
+run_dir=''
+top_dir=''
+out_dir=''
+waf_dir=''
+local_repo=''
+remote_repo='http://waf.googlecode.com/git/'
+remote_locs=['waflib/extras','waflib/Tools']
+g_module=None
+STDOUT=1
+STDERR=-1
+BOTH=0
+classes=[]
+def create_context(cmd_name,*k,**kw):
+	global classes
+	for x in classes:
+		if x.cmd==cmd_name:
+			return x(*k,**kw)
+	ctx=Context(*k,**kw)
+	ctx.fun=cmd_name
+	return ctx
+class store_context(type):
+	def __init__(cls,name,bases,dict):
+		super(store_context,cls).__init__(name,bases,dict)
+		name=cls.__name__
+		if name=='ctx'or name=='Context':
+			return
+		try:
+			cls.cmd
+		except AttributeError:
+			raise Errors.WafError('Missing command for the context class %r (cmd)'%name)
+		if not getattr(cls,'fun',None):
+			cls.fun=cls.cmd
+		global classes
+		classes.insert(0,cls)
+ctx=store_context('ctx',(object,),{})
+class Context(ctx):
+	errors=Errors
+	tools={}
+	def __init__(self,**kw):
+		try:
+			rd=kw['run_dir']
+		except KeyError:
+			global run_dir
+			rd=run_dir
+		class node_class(waflib.Node.Node):
+			pass
+		self.node_class=node_class
+		self.node_class.__module__="waflib.Node"
+		self.node_class.__name__="Nod3"
+		self.node_class.ctx=self
+		self.root=self.node_class('',None)
+		self.cur_script=None
+		self.path=self.root.find_dir(rd)
+		self.stack_path=[]
+		self.exec_dict={'ctx':self,'conf':self,'bld':self,'opt':self}
+		self.logger=None
+	def __hash__(self):
+		return id(self)
+	def load(self,tool_list,*k,**kw):
+		tools=Utils.to_list(tool_list)
+		path=Utils.to_list(kw.get('tooldir',''))
+		for t in tools:
+			module=load_tool(t,path)
+			fun=getattr(module,kw.get('name',self.fun),None)
+			if fun:
+				fun(self)
+	def execute(self):
+		global g_module
+		self.recurse([os.path.dirname(g_module.root_path)])
+	def pre_recurse(self,node):
+		self.stack_path.append(self.cur_script)
+		self.cur_script=node
+		self.path=node.parent
+	def post_recurse(self,node):
+		self.cur_script=self.stack_path.pop()
+		if self.cur_script:
+			self.path=self.cur_script.parent
+	def recurse(self,dirs,name=None,mandatory=True,once=True):
+		try:
+			cache=self.recurse_cache
+		except AttributeError:
+			cache=self.recurse_cache={}
+		for d in Utils.to_list(dirs):
+			if not os.path.isabs(d):
+				d=os.path.join(self.path.abspath(),d)
+			WSCRIPT=os.path.join(d,WSCRIPT_FILE)
+			WSCRIPT_FUN=WSCRIPT+'_'+(name or self.fun)
+			node=self.root.find_node(WSCRIPT_FUN)
+			if node and(not once or node not in cache):
+				cache[node]=True
+				self.pre_recurse(node)
+				try:
+					function_code=node.read('rU')
+					exec(compile(function_code,node.abspath(),'exec'),self.exec_dict)
+				finally:
+					self.post_recurse(node)
+			elif not node:
+				node=self.root.find_node(WSCRIPT)
+				tup=(node,name or self.fun)
+				if node and(not once or tup not in cache):
+					cache[tup]=True
+					self.pre_recurse(node)
+					try:
+						wscript_module=load_module(node.abspath())
+						user_function=getattr(wscript_module,(name or self.fun),None)
+						if not user_function:
+							if not mandatory:
+								continue
+							raise Errors.WafError('No function %s defined in %s'%(name or self.fun,node.abspath()))
+						user_function(self)
+					finally:
+						self.post_recurse(node)
+				elif not node:
+					if not mandatory:
+						continue
+					raise Errors.WafError('No wscript file in directory %s'%d)
+	def exec_command(self,cmd,**kw):
+		subprocess=Utils.subprocess
+		kw['shell']=isinstance(cmd,str)
+		Logs.debug('runner: %r'%cmd)
+		Logs.debug('runner_env: kw=%s'%kw)
+		if self.logger:
+			self.logger.info(cmd)
+		if'stdout'not in kw:
+			kw['stdout']=subprocess.PIPE
+		if'stderr'not in kw:
+			kw['stderr']=subprocess.PIPE
+		try:
+			if kw['stdout']or kw['stderr']:
+				p=subprocess.Popen(cmd,**kw)
+				(out,err)=p.communicate()
+				ret=p.returncode
+			else:
+				out,err=(None,None)
+				ret=subprocess.Popen(cmd,**kw).wait()
+		except Exception ,e:
+			raise Errors.WafError('Execution failure: %s'%str(e),ex=e)
+		if out:
+			if not isinstance(out,str):
+				out=out.decode(sys.stdout.encoding or'iso8859-1')
+			if self.logger:
+				self.logger.debug('out: %s'%out)
+			else:
+				sys.stdout.write(out)
+		if err:
+			if not isinstance(err,str):
+				err=err.decode(sys.stdout.encoding or'iso8859-1')
+			if self.logger:
+				self.logger.error('err: %s'%err)
+			else:
+				sys.stderr.write(err)
+		return ret
+	def cmd_and_log(self,cmd,**kw):
+		subprocess=Utils.subprocess
+		kw['shell']=isinstance(cmd,str)
+		Logs.debug('runner: %r'%cmd)
+		if'quiet'in kw:
+			quiet=kw['quiet']
+			del kw['quiet']
+		else:
+			quiet=None
+		if'output'in kw:
+			to_ret=kw['output']
+			del kw['output']
+		else:
+			to_ret=STDOUT
+		kw['stdout']=kw['stderr']=subprocess.PIPE
+		if quiet is None:
+			self.to_log(cmd)
+		try:
+			p=subprocess.Popen(cmd,**kw)
+			(out,err)=p.communicate()
+		except Exception ,e:
+			raise Errors.WafError('Execution failure: %s'%str(e),ex=e)
+		if not isinstance(out,str):
+			out=out.decode(sys.stdout.encoding or'iso8859-1')
+		if not isinstance(err,str):
+			err=err.decode(sys.stdout.encoding or'iso8859-1')
+		if out and quiet!=STDOUT and quiet!=BOTH:
+			self.to_log('out: %s'%out)
+		if err and quiet!=STDERR and quiet!=BOTH:
+			self.to_log('err: %s'%err)
+		if p.returncode:
+			e=Errors.WafError('Command %r returned %r'%(cmd,p.returncode))
+			e.returncode=p.returncode
+			e.stderr=err
+			e.stdout=out
+			raise e
+		if to_ret==BOTH:
+			return(out,err)
+		elif to_ret==STDERR:
+			return err
+		return out
+	def fatal(self,msg,ex=None):
+		if self.logger:
+			self.logger.info('from %s: %s'%(self.path.abspath(),msg))
+		try:
+			msg='%s\n(complete log in %s)'%(msg,self.logger.handlers[0].baseFilename)
+		except Exception:
+			pass
+		raise self.errors.ConfigurationError(msg,ex=ex)
+	def to_log(self,msg):
+		if not msg:
+			return
+		if self.logger:
+			self.logger.info(msg)
+		else:
+			sys.stderr.write(str(msg))
+			sys.stderr.flush()
+	def msg(self,msg,result,color=None):
+		self.start_msg(msg)
+		if not isinstance(color,str):
+			color=result and'GREEN'or'YELLOW'
+		self.end_msg(result,color)
+	def start_msg(self,msg):
+		try:
+			if self.in_msg:
+				self.in_msg+=1
+				return
+		except AttributeError:
+			self.in_msg=0
+		self.in_msg+=1
+		try:
+			self.line_just=max(self.line_just,len(msg))
+		except AttributeError:
+			self.line_just=max(40,len(msg))
+		for x in(self.line_just*'-',msg):
+			self.to_log(x)
+		Logs.pprint('NORMAL',"%s :"%msg.ljust(self.line_just),sep='')
+	def end_msg(self,result,color=None):
+		self.in_msg-=1
+		if self.in_msg:
+			return
+		defcolor='GREEN'
+		if result==True:
+			msg='ok'
+		elif result==False:
+			msg='not found'
+			defcolor='YELLOW'
+		else:
+			msg=str(result)
+		self.to_log(msg)
+		Logs.pprint(color or defcolor,msg)
+	def load_special_tools(self,var,ban=[]):
+		global waf_dir
+		lst=self.root.find_node(waf_dir).find_node('waflib/extras').ant_glob(var)
+		for x in lst:
+			if not x.name in ban:
+				load_tool(x.name.replace('.py',''))
+cache_modules={}
+def load_module(path):
+	try:
+		return cache_modules[path]
+	except KeyError:
+		pass
+	module=imp.new_module(WSCRIPT_FILE)
+	try:
+		code=Utils.readf(path,m='rU')
+	except(IOError,OSError):
+		raise Errors.WafError('Could not read the file %r'%path)
+	module_dir=os.path.dirname(path)
+	sys.path.insert(0,module_dir)
+	exec(compile(code,path,'exec'),module.__dict__)
+	sys.path.remove(module_dir)
+	cache_modules[path]=module
+	return module
+def load_tool(tool,tooldir=None):
+	if tool=='java':
+		tool='javaw'
+	elif tool=='compiler_cc':
+		tool='compiler_c'
+	else:
+		tool=tool.replace('++','xx')
+	if tooldir:
+		assert isinstance(tooldir,list)
+		sys.path=tooldir+sys.path
+		try:
+			__import__(tool)
+			ret=sys.modules[tool]
+			Context.tools[tool]=ret
+			return ret
+		finally:
+			for d in tooldir:
+				sys.path.remove(d)
+	else:
+		global waf_dir
+		try:
+			os.stat(os.path.join(waf_dir,'waflib','extras',tool+'.py'))
+		except OSError:
+			try:
+				os.stat(os.path.join(waf_dir,'waflib','Tools',tool+'.py'))
+			except OSError:
+				d=tool
+			else:
+				d='waflib.Tools.%s'%tool
+		else:
+			d='waflib.extras.%s'%tool
+		__import__(d)
+		ret=sys.modules[d]
+		Context.tools[tool]=ret
+		return ret
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Context.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Context.pyc
new file mode 100644
index 0000000..2c8d7f1
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Context.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Errors.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Errors.py
new file mode 100644
index 0000000..aacc1a9
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Errors.py
@@ -0,0 +1,37 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import traceback,sys
+class WafError(Exception):
+	def __init__(self,msg='',ex=None):
+		self.msg=msg
+		assert not isinstance(msg,Exception)
+		self.stack=[]
+		if ex:
+			if not msg:
+				self.msg=str(ex)
+			if isinstance(ex,WafError):
+				self.stack=ex.stack
+			else:
+				self.stack=traceback.extract_tb(sys.exc_info()[2])
+		self.stack+=traceback.extract_stack()[:-1]
+		self.verbose_msg=''.join(traceback.format_list(self.stack))
+	def __str__(self):
+		return str(self.msg)
+class BuildError(WafError):
+	def __init__(self,error_tasks=[]):
+		self.tasks=error_tasks
+		WafError.__init__(self,self.format_error())
+	def format_error(self):
+		lst=['Build failed']
+		for tsk in self.tasks:
+			txt=tsk.format_error()
+			if txt:lst.append(txt)
+		return'\n'.join(lst)
+class ConfigurationError(WafError):
+	pass
+class TaskRescan(WafError):
+	pass
+class TaskNotReady(WafError):
+	pass
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Errors.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Errors.pyc
new file mode 100644
index 0000000..1dd47f5
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Errors.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Logs.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Logs.py
new file mode 100644
index 0000000..d6d4ddd
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Logs.py
@@ -0,0 +1,176 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,re,traceback,sys
+try:
+	import threading
+except ImportError:
+	pass
+else:
+	wlock=threading.Lock()
+	class sync_stream(object):
+		def __init__(self,stream):
+			self.stream=stream
+			self.encoding=self.stream.encoding
+		def write(self,txt):
+			try:
+				wlock.acquire()
+				self.stream.write(txt)
+				self.stream.flush()
+			finally:
+				wlock.release()
+		def fileno(self):
+			return self.stream.fileno()
+		def flush(self):
+			self.stream.flush()
+		def isatty(self):
+			return self.stream.isatty()
+	_nocolor=os.environ.get('NOCOLOR','no')not in('no','0','false')
+	try:
+		if not _nocolor:
+			import waflib.ansiterm
+	except ImportError:
+		pass
+	if not os.environ.get('NOSYNC',False):
+		if id(sys.stdout)==id(sys.__stdout__):
+			sys.stdout=sync_stream(sys.stdout)
+			sys.stderr=sync_stream(sys.stderr)
+import logging
+LOG_FORMAT="%(asctime)s %(c1)s%(zone)s%(c2)s %(message)s"
+HOUR_FORMAT="%H:%M:%S"
+zones=''
+verbose=0
+colors_lst={'USE':True,'BOLD':'\x1b[01;1m','RED':'\x1b[01;31m','GREEN':'\x1b[32m','YELLOW':'\x1b[33m','PINK':'\x1b[35m','BLUE':'\x1b[01;34m','CYAN':'\x1b[36m','NORMAL':'\x1b[0m','cursor_on':'\x1b[?25h','cursor_off':'\x1b[?25l',}
+got_tty=not os.environ.get('TERM','dumb')in['dumb','emacs']
+if got_tty:
+	try:
+		got_tty=sys.stderr.isatty()and sys.stdout.isatty()
+	except AttributeError:
+		got_tty=False
+if(not got_tty and os.environ.get('TERM','dumb')!='msys')or _nocolor:
+	colors_lst['USE']=False
+def get_term_cols():
+	return 80
+try:
+	import struct,fcntl,termios
+except ImportError:
+	pass
+else:
+	if got_tty:
+		def get_term_cols_real():
+			dummy_lines,cols=struct.unpack("HHHH",fcntl.ioctl(sys.stderr.fileno(),termios.TIOCGWINSZ,struct.pack("HHHH",0,0,0,0)))[:2]
+			return cols
+		try:
+			get_term_cols_real()
+		except Exception:
+			pass
+		else:
+			get_term_cols=get_term_cols_real
+get_term_cols.__doc__="""
+	Get the console width in characters.
+
+	:return: the number of characters per line
+	:rtype: int
+	"""
+def get_color(cl):
+	if not colors_lst['USE']:return''
+	return colors_lst.get(cl,'')
+class color_dict(object):
+	def __getattr__(self,a):
+		return get_color(a)
+	def __call__(self,a):
+		return get_color(a)
+colors=color_dict()
+re_log=re.compile(r'(\w+): (.*)',re.M)
+class log_filter(logging.Filter):
+	def __init__(self,name=None):
+		pass
+	def filter(self,rec):
+		rec.c1=colors.PINK
+		rec.c2=colors.NORMAL
+		rec.zone=rec.module
+		if rec.levelno>=logging.INFO:
+			if rec.levelno>=logging.ERROR:
+				rec.c1=colors.RED
+			elif rec.levelno>=logging.WARNING:
+				rec.c1=colors.YELLOW
+			else:
+				rec.c1=colors.GREEN
+			return True
+		m=re_log.match(rec.msg)
+		if m:
+			rec.zone=m.group(1)
+			rec.msg=m.group(2)
+		if zones:
+			return getattr(rec,'zone','')in zones or'*'in zones
+		elif not verbose>2:
+			return False
+		return True
+class formatter(logging.Formatter):
+	def __init__(self):
+		logging.Formatter.__init__(self,LOG_FORMAT,HOUR_FORMAT)
+	def format(self,rec):
+		if rec.levelno>=logging.WARNING or rec.levelno==logging.INFO:
+			try:
+				msg=rec.msg.decode('utf-8')
+			except Exception:
+				msg=rec.msg
+			return'%s%s%s'%(rec.c1,msg,rec.c2)
+		return logging.Formatter.format(self,rec)
+log=None
+def debug(*k,**kw):
+	if verbose:
+		k=list(k)
+		k[0]=k[0].replace('\n',' ')
+		global log
+		log.debug(*k,**kw)
+def error(*k,**kw):
+	global log
+	log.error(*k,**kw)
+	if verbose>2:
+		st=traceback.extract_stack()
+		if st:
+			st=st[:-1]
+			buf=[]
+			for filename,lineno,name,line in st:
+				buf.append('  File "%s", line %d, in %s'%(filename,lineno,name))
+				if line:
+					buf.append('	%s'%line.strip())
+			if buf:log.error("\n".join(buf))
+def warn(*k,**kw):
+	global log
+	log.warn(*k,**kw)
+def info(*k,**kw):
+	global log
+	log.info(*k,**kw)
+def init_log():
+	global log
+	log=logging.getLogger('waflib')
+	log.handlers=[]
+	log.filters=[]
+	hdlr=logging.StreamHandler()
+	hdlr.setFormatter(formatter())
+	log.addHandler(hdlr)
+	log.addFilter(log_filter())
+	log.setLevel(logging.DEBUG)
+def make_logger(path,name):
+	logger=logging.getLogger(name)
+	hdlr=logging.FileHandler(path,'w')
+	formatter=logging.Formatter('%(message)s')
+	hdlr.setFormatter(formatter)
+	logger.addHandler(hdlr)
+	logger.setLevel(logging.DEBUG)
+	return logger
+def make_mem_logger(name,to_log,size=10000):
+	from logging.handlers import MemoryHandler
+	logger=logging.getLogger(name)
+	hdlr=MemoryHandler(size,target=to_log)
+	formatter=logging.Formatter('%(message)s')
+	hdlr.setFormatter(formatter)
+	logger.addHandler(hdlr)
+	logger.memhandler=hdlr
+	logger.setLevel(logging.DEBUG)
+	return logger
+def pprint(col,str,label='',sep='\n'):
+	sys.stderr.write("%s%s%s %s%s"%(colors(col),str,colors.NORMAL,label,sep))
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Logs.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Logs.pyc
new file mode 100644
index 0000000..e9a8c2f
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Logs.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Node.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Node.py
new file mode 100644
index 0000000..64c4977
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Node.py
@@ -0,0 +1,467 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,re,sys,shutil
+from waflib import Utils,Errors
+exclude_regs='''
+**/*~
+**/#*#
+**/.#*
+**/%*%
+**/._*
+**/CVS
+**/CVS/**
+**/.cvsignore
+**/SCCS
+**/SCCS/**
+**/vssver.scc
+**/.svn
+**/.svn/**
+**/BitKeeper
+**/.git
+**/.git/**
+**/.gitignore
+**/.bzr
+**/.bzrignore
+**/.bzr/**
+**/.hg
+**/.hg/**
+**/_MTN
+**/_MTN/**
+**/.arch-ids
+**/{arch}
+**/_darcs
+**/_darcs/**
+**/.intlcache
+**/.DS_Store'''
+def split_path(path):
+	return path.split('/')
+def split_path_cygwin(path):
+	if path.startswith('//'):
+		ret=path.split('/')[2:]
+		ret[0]='/'+ret[0]
+		return ret
+	return path.split('/')
+re_sp=re.compile('[/\\\\]')
+def split_path_win32(path):
+	if path.startswith('\\\\'):
+		ret=re.split(re_sp,path)[2:]
+		ret[0]='\\'+ret[0]
+		return ret
+	return re.split(re_sp,path)
+if sys.platform=='cygwin':
+	split_path=split_path_cygwin
+elif Utils.is_win32:
+	split_path=split_path_win32
+class Node(object):
+	__slots__=('name','sig','children','parent','cache_abspath','cache_isdir','cache_sig')
+	def __init__(self,name,parent):
+		self.name=name
+		self.parent=parent
+		if parent:
+			if name in parent.children:
+				raise Errors.WafError('node %s exists in the parent files %r already'%(name,parent))
+			parent.children[name]=self
+	def __setstate__(self,data):
+		self.name=data[0]
+		self.parent=data[1]
+		if data[2]is not None:
+			self.children=data[2]
+		if data[3]is not None:
+			self.sig=data[3]
+	def __getstate__(self):
+		return(self.name,self.parent,getattr(self,'children',None),getattr(self,'sig',None))
+	def __str__(self):
+		return self.name
+	def __repr__(self):
+		return self.abspath()
+	def __hash__(self):
+		return id(self)
+	def __eq__(self,node):
+		return id(self)==id(node)
+	def __copy__(self):
+		raise Errors.WafError('nodes are not supposed to be copied')
+	def read(self,flags='r',encoding='ISO8859-1'):
+		return Utils.readf(self.abspath(),flags,encoding)
+	def write(self,data,flags='w',encoding='ISO8859-1'):
+		Utils.writef(self.abspath(),data,flags,encoding)
+	def chmod(self,val):
+		os.chmod(self.abspath(),val)
+	def delete(self):
+		try:
+			if hasattr(self,'children'):
+				shutil.rmtree(self.abspath())
+			else:
+				os.remove(self.abspath())
+		except OSError:
+			pass
+		self.evict()
+	def evict(self):
+		del self.parent.children[self.name]
+	def suffix(self):
+		k=max(0,self.name.rfind('.'))
+		return self.name[k:]
+	def height(self):
+		d=self
+		val=-1
+		while d:
+			d=d.parent
+			val+=1
+		return val
+	def listdir(self):
+		lst=Utils.listdir(self.abspath())
+		lst.sort()
+		return lst
+	def mkdir(self):
+		if getattr(self,'cache_isdir',None):
+			return
+		try:
+			self.parent.mkdir()
+		except OSError:
+			pass
+		if self.name:
+			try:
+				os.makedirs(self.abspath())
+			except OSError:
+				pass
+			if not os.path.isdir(self.abspath()):
+				raise Errors.WafError('Could not create the directory %s'%self.abspath())
+			try:
+				self.children
+			except AttributeError:
+				self.children={}
+		self.cache_isdir=True
+	def find_node(self,lst):
+		if isinstance(lst,str):
+			lst=[x for x in split_path(lst)if x and x!='.']
+		cur=self
+		for x in lst:
+			if x=='..':
+				cur=cur.parent or cur
+				continue
+			try:
+				ch=cur.children
+			except AttributeError:
+				cur.children={}
+			else:
+				try:
+					cur=cur.children[x]
+					continue
+				except KeyError:
+					pass
+			cur=self.__class__(x,cur)
+			try:
+				os.stat(cur.abspath())
+			except OSError:
+				cur.evict()
+				return None
+		ret=cur
+		try:
+			os.stat(ret.abspath())
+		except OSError:
+			ret.evict()
+			return None
+		try:
+			while not getattr(cur.parent,'cache_isdir',None):
+				cur=cur.parent
+				cur.cache_isdir=True
+		except AttributeError:
+			pass
+		return ret
+	def make_node(self,lst):
+		if isinstance(lst,str):
+			lst=[x for x in split_path(lst)if x and x!='.']
+		cur=self
+		for x in lst:
+			if x=='..':
+				cur=cur.parent or cur
+				continue
+			if getattr(cur,'children',{}):
+				if x in cur.children:
+					cur=cur.children[x]
+					continue
+			else:
+				cur.children={}
+			cur=self.__class__(x,cur)
+		return cur
+	def search_node(self,lst):
+		if isinstance(lst,str):
+			lst=[x for x in split_path(lst)if x and x!='.']
+		cur=self
+		for x in lst:
+			if x=='..':
+				cur=cur.parent or cur
+			else:
+				try:
+					cur=cur.children[x]
+				except(AttributeError,KeyError):
+					return None
+		return cur
+	def path_from(self,node):
+		c1=self
+		c2=node
+		c1h=c1.height()
+		c2h=c2.height()
+		lst=[]
+		up=0
+		while c1h>c2h:
+			lst.append(c1.name)
+			c1=c1.parent
+			c1h-=1
+		while c2h>c1h:
+			up+=1
+			c2=c2.parent
+			c2h-=1
+		while id(c1)!=id(c2):
+			lst.append(c1.name)
+			up+=1
+			c1=c1.parent
+			c2=c2.parent
+		for i in range(up):
+			lst.append('..')
+		lst.reverse()
+		return os.sep.join(lst)or'.'
+	def abspath(self):
+		try:
+			return self.cache_abspath
+		except AttributeError:
+			pass
+		if os.sep=='/':
+			if not self.parent:
+				val=os.sep
+			elif not self.parent.name:
+				val=os.sep+self.name
+			else:
+				val=self.parent.abspath()+os.sep+self.name
+		else:
+			if not self.parent:
+				val=''
+			elif not self.parent.name:
+				val=self.name+os.sep
+			else:
+				val=self.parent.abspath().rstrip(os.sep)+os.sep+self.name
+		self.cache_abspath=val
+		return val
+	def is_child_of(self,node):
+		p=self
+		diff=self.height()-node.height()
+		while diff>0:
+			diff-=1
+			p=p.parent
+		return id(p)==id(node)
+	def ant_iter(self,accept=None,maxdepth=25,pats=[],dir=False,src=True,remove=True):
+		dircont=self.listdir()
+		dircont.sort()
+		try:
+			lst=set(self.children.keys())
+		except AttributeError:
+			self.children={}
+		else:
+			if remove:
+				for x in lst-set(dircont):
+					self.children[x].evict()
+		for name in dircont:
+			npats=accept(name,pats)
+			if npats and npats[0]:
+				accepted=[]in npats[0]
+				node=self.make_node([name])
+				isdir=os.path.isdir(node.abspath())
+				if accepted:
+					if isdir:
+						if dir:
+							yield node
+					else:
+						if src:
+							yield node
+				if getattr(node,'cache_isdir',None)or isdir:
+					node.cache_isdir=True
+					if maxdepth:
+						for k in node.ant_iter(accept=accept,maxdepth=maxdepth-1,pats=npats,dir=dir,src=src,remove=remove):
+							yield k
+		raise StopIteration
+	def ant_glob(self,*k,**kw):
+		src=kw.get('src',True)
+		dir=kw.get('dir',False)
+		excl=kw.get('excl',exclude_regs)
+		incl=k and k[0]or kw.get('incl','**')
+		reflags=kw.get('ignorecase',0)and re.I
+		def to_pat(s):
+			lst=Utils.to_list(s)
+			ret=[]
+			for x in lst:
+				x=x.replace('\\','/').replace('//','/')
+				if x.endswith('/'):
+					x+='**'
+				lst2=x.split('/')
+				accu=[]
+				for k in lst2:
+					if k=='**':
+						accu.append(k)
+					else:
+						k=k.replace('.','[.]').replace('*','.*').replace('?','.').replace('+','\\+')
+						k='^%s$'%k
+						try:
+							accu.append(re.compile(k,flags=reflags))
+						except Exception ,e:
+							raise Errors.WafError("Invalid pattern: %s"%k,e)
+				ret.append(accu)
+			return ret
+		def filtre(name,nn):
+			ret=[]
+			for lst in nn:
+				if not lst:
+					pass
+				elif lst[0]=='**':
+					ret.append(lst)
+					if len(lst)>1:
+						if lst[1].match(name):
+							ret.append(lst[2:])
+					else:
+						ret.append([])
+				elif lst[0].match(name):
+					ret.append(lst[1:])
+			return ret
+		def accept(name,pats):
+			nacc=filtre(name,pats[0])
+			nrej=filtre(name,pats[1])
+			if[]in nrej:
+				nacc=[]
+			return[nacc,nrej]
+		ret=[x for x in self.ant_iter(accept=accept,pats=[to_pat(incl),to_pat(excl)],maxdepth=25,dir=dir,src=src,remove=kw.get('remove',True))]
+		if kw.get('flat',False):
+			return' '.join([x.path_from(self)for x in ret])
+		return ret
+	def is_src(self):
+		cur=self
+		x=id(self.ctx.srcnode)
+		y=id(self.ctx.bldnode)
+		while cur.parent:
+			if id(cur)==y:
+				return False
+			if id(cur)==x:
+				return True
+			cur=cur.parent
+		return False
+	def is_bld(self):
+		cur=self
+		y=id(self.ctx.bldnode)
+		while cur.parent:
+			if id(cur)==y:
+				return True
+			cur=cur.parent
+		return False
+	def get_src(self):
+		cur=self
+		x=id(self.ctx.srcnode)
+		y=id(self.ctx.bldnode)
+		lst=[]
+		while cur.parent:
+			if id(cur)==y:
+				lst.reverse()
+				return self.ctx.srcnode.make_node(lst)
+			if id(cur)==x:
+				return self
+			lst.append(cur.name)
+			cur=cur.parent
+		return self
+	def get_bld(self):
+		cur=self
+		x=id(self.ctx.srcnode)
+		y=id(self.ctx.bldnode)
+		lst=[]
+		while cur.parent:
+			if id(cur)==y:
+				return self
+			if id(cur)==x:
+				lst.reverse()
+				return self.ctx.bldnode.make_node(lst)
+			lst.append(cur.name)
+			cur=cur.parent
+		lst.reverse()
+		if lst and Utils.is_win32 and len(lst[0])==2 and lst[0].endswith(':'):
+			lst[0]=lst[0][0]
+		return self.ctx.bldnode.make_node(['__root__']+lst)
+	def find_resource(self,lst):
+		if isinstance(lst,str):
+			lst=[x for x in split_path(lst)if x and x!='.']
+		node=self.get_bld().search_node(lst)
+		if not node:
+			self=self.get_src()
+			node=self.find_node(lst)
+		if node:
+			if os.path.isdir(node.abspath()):
+				return None
+		return node
+	def find_or_declare(self,lst):
+		if isinstance(lst,str):
+			lst=[x for x in split_path(lst)if x and x!='.']
+		node=self.get_bld().search_node(lst)
+		if node:
+			if not os.path.isfile(node.abspath()):
+				node.sig=None
+				node.parent.mkdir()
+			return node
+		self=self.get_src()
+		node=self.find_node(lst)
+		if node:
+			if not os.path.isfile(node.abspath()):
+				node.sig=None
+				node.parent.mkdir()
+			return node
+		node=self.get_bld().make_node(lst)
+		node.parent.mkdir()
+		return node
+	def find_dir(self,lst):
+		if isinstance(lst,str):
+			lst=[x for x in split_path(lst)if x and x!='.']
+		node=self.find_node(lst)
+		try:
+			if not os.path.isdir(node.abspath()):
+				return None
+		except(OSError,AttributeError):
+			return None
+		return node
+	def change_ext(self,ext,ext_in=None):
+		name=self.name
+		if ext_in is None:
+			k=name.rfind('.')
+			if k>=0:
+				name=name[:k]+ext
+			else:
+				name=name+ext
+		else:
+			name=name[:-len(ext_in)]+ext
+		return self.parent.find_or_declare([name])
+	def nice_path(self,env=None):
+		return self.path_from(self.ctx.launch_node())
+	def bldpath(self):
+		return self.path_from(self.ctx.bldnode)
+	def srcpath(self):
+		return self.path_from(self.ctx.srcnode)
+	def relpath(self):
+		cur=self
+		x=id(self.ctx.bldnode)
+		while cur.parent:
+			if id(cur)==x:
+				return self.bldpath()
+			cur=cur.parent
+		return self.srcpath()
+	def bld_dir(self):
+		return self.parent.bldpath()
+	def bld_base(self):
+		s=os.path.splitext(self.name)[0]
+		return self.bld_dir()+os.sep+s
+	def get_bld_sig(self):
+		try:
+			return self.cache_sig
+		except AttributeError:
+			pass
+		if not self.is_bld()or self.ctx.bldnode is self.ctx.srcnode:
+			self.sig=Utils.h_file(self.abspath())
+		self.cache_sig=ret=self.sig
+		return ret
+	search=search_node
+pickle_lock=Utils.threading.Lock()
+class Nod3(Node):
+	pass
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Node.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Node.pyc
new file mode 100644
index 0000000..0ee620d
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Node.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Options.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Options.py
new file mode 100644
index 0000000..21f4254
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Options.py
@@ -0,0 +1,135 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,tempfile,optparse,sys,re
+from waflib import Logs,Utils,Context
+cmds='distclean configure build install clean uninstall check dist distcheck'.split()
+options={}
+commands=[]
+lockfile=os.environ.get('WAFLOCK','.lock-waf_%s_build'%sys.platform)
+try:cache_global=os.path.abspath(os.environ['WAFCACHE'])
+except KeyError:cache_global=''
+platform=Utils.unversioned_sys_platform()
+class opt_parser(optparse.OptionParser):
+	def __init__(self,ctx):
+		optparse.OptionParser.__init__(self,conflict_handler="resolve",version='waf %s (%s)'%(Context.WAFVERSION,Context.WAFREVISION))
+		self.formatter.width=Logs.get_term_cols()
+		p=self.add_option
+		self.ctx=ctx
+		jobs=ctx.jobs()
+		p('-j','--jobs',dest='jobs',default=jobs,type='int',help='amount of parallel jobs (%r)'%jobs)
+		p('-k','--keep',dest='keep',default=0,action='count',help='keep running happily even if errors are found')
+		p('-v','--verbose',dest='verbose',default=0,action='count',help='verbosity level -v -vv or -vvv [default: 0]')
+		p('--nocache',dest='nocache',default=False,action='store_true',help='ignore the WAFCACHE (if set)')
+		p('--zones',dest='zones',default='',action='store',help='debugging zones (task_gen, deps, tasks, etc)')
+		gr=optparse.OptionGroup(self,'configure options')
+		self.add_option_group(gr)
+		gr.add_option('-o','--out',action='store',default='',help='build dir for the project',dest='out')
+		gr.add_option('-t','--top',action='store',default='',help='src dir for the project',dest='top')
+		default_prefix=os.environ.get('PREFIX')
+		if not default_prefix:
+			if platform=='win32':
+				d=tempfile.gettempdir()
+				default_prefix=d[0].upper()+d[1:]
+			else:
+				default_prefix='/usr/local/'
+		gr.add_option('--prefix',dest='prefix',default=default_prefix,help='installation prefix [default: %r]'%default_prefix)
+		gr.add_option('--download',dest='download',default=False,action='store_true',help='try to download the tools if missing')
+		gr=optparse.OptionGroup(self,'build and install options')
+		self.add_option_group(gr)
+		gr.add_option('-p','--progress',dest='progress_bar',default=0,action='count',help='-p: progress bar; -pp: ide output')
+		gr.add_option('--targets',dest='targets',default='',action='store',help='task generators, e.g. "target1,target2"')
+		gr=optparse.OptionGroup(self,'step options')
+		self.add_option_group(gr)
+		gr.add_option('--files',dest='files',default='',action='store',help='files to process, by regexp, e.g. "*/main.c,*/test/main.o"')
+		default_destdir=os.environ.get('DESTDIR','')
+		gr=optparse.OptionGroup(self,'install/uninstall options')
+		self.add_option_group(gr)
+		gr.add_option('--destdir',help='installation root [default: %r]'%default_destdir,default=default_destdir,dest='destdir')
+		gr.add_option('-f','--force',dest='force',default=False,action='store_true',help='force file installation')
+		gr.add_option('--distcheck-args',help='arguments to pass to distcheck',default=None,action='store')
+	def get_usage(self):
+		cmds_str={}
+		for cls in Context.classes:
+			if not cls.cmd or cls.cmd=='options':
+				continue
+			s=cls.__doc__ or''
+			cmds_str[cls.cmd]=s
+		if Context.g_module:
+			for(k,v)in Context.g_module.__dict__.items():
+				if k in['options','init','shutdown']:
+					continue
+				if type(v)is type(Context.create_context):
+					if v.__doc__ and not k.startswith('_'):
+						cmds_str[k]=v.__doc__
+		just=0
+		for k in cmds_str:
+			just=max(just,len(k))
+		lst=['  %s: %s'%(k.ljust(just),v)for(k,v)in cmds_str.items()]
+		lst.sort()
+		ret='\n'.join(lst)
+		return'''waf [commands] [options]
+
+Main commands (example: ./waf build -j4)
+%s
+'''%ret
+class OptionsContext(Context.Context):
+	cmd='options'
+	fun='options'
+	def __init__(self,**kw):
+		super(OptionsContext,self).__init__(**kw)
+		self.parser=opt_parser(self)
+		self.option_groups={}
+	def jobs(self):
+		count=int(os.environ.get('JOBS',0))
+		if count<1:
+			if'NUMBER_OF_PROCESSORS'in os.environ:
+				count=int(os.environ.get('NUMBER_OF_PROCESSORS',1))
+			else:
+				if hasattr(os,'sysconf_names'):
+					if'SC_NPROCESSORS_ONLN'in os.sysconf_names:
+						count=int(os.sysconf('SC_NPROCESSORS_ONLN'))
+					elif'SC_NPROCESSORS_CONF'in os.sysconf_names:
+						count=int(os.sysconf('SC_NPROCESSORS_CONF'))
+				if not count and os.name not in('nt','java'):
+					try:
+						tmp=self.cmd_and_log(['sysctl','-n','hw.ncpu'],quiet=0)
+					except Exception:
+						pass
+					else:
+						if re.match('^[0-9]+$',tmp):
+							count=int(tmp)
+		if count<1:
+			count=1
+		elif count>1024:
+			count=1024
+		return count
+	def add_option(self,*k,**kw):
+		return self.parser.add_option(*k,**kw)
+	def add_option_group(self,*k,**kw):
+		try:
+			gr=self.option_groups[k[0]]
+		except KeyError:
+			gr=self.parser.add_option_group(*k,**kw)
+		self.option_groups[k[0]]=gr
+		return gr
+	def get_option_group(self,opt_str):
+		try:
+			return self.option_groups[opt_str]
+		except KeyError:
+			for group in self.parser.option_groups:
+				if group.title==opt_str:
+					return group
+			return None
+	def parse_args(self,_args=None):
+		global options,commands
+		(options,leftover_args)=self.parser.parse_args(args=_args)
+		commands=leftover_args
+		if options.destdir:
+			options.destdir=os.path.abspath(os.path.expanduser(options.destdir))
+		if options.verbose>=1:
+			self.load('errcheck')
+	def execute(self):
+		super(OptionsContext,self).execute()
+		self.parse_args()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Options.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Options.pyc
new file mode 100644
index 0000000..b7f7afe
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Options.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Runner.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Runner.py
new file mode 100644
index 0000000..15b6a27
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Runner.py
@@ -0,0 +1,197 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import random,atexit
+try:
+	from queue import Queue
+except ImportError:
+	from Queue import Queue
+from waflib import Utils,Task,Errors,Logs
+GAP=10
+class TaskConsumer(Utils.threading.Thread):
+	def __init__(self):
+		Utils.threading.Thread.__init__(self)
+		self.ready=Queue()
+		self.setDaemon(1)
+		self.start()
+	def run(self):
+		try:
+			self.loop()
+		except Exception:
+			pass
+	def loop(self):
+		while 1:
+			tsk=self.ready.get()
+			if not isinstance(tsk,Task.TaskBase):
+				tsk(self)
+			else:
+				tsk.process()
+pool=Queue()
+def get_pool():
+	try:
+		return pool.get(False)
+	except Exception:
+		return TaskConsumer()
+def put_pool(x):
+	pool.put(x)
+def _free_resources():
+	global pool
+	lst=[]
+	while pool.qsize():
+		lst.append(pool.get())
+	for x in lst:
+		x.ready.put(None)
+	for x in lst:
+		x.join()
+	pool=None
+atexit.register(_free_resources)
+class Parallel(object):
+	def __init__(self,bld,j=2):
+		self.numjobs=j
+		self.bld=bld
+		self.outstanding=[]
+		self.frozen=[]
+		self.out=Queue(0)
+		self.count=0
+		self.processed=1
+		self.stop=False
+		self.error=[]
+		self.biter=None
+		self.dirty=False
+	def get_next_task(self):
+		if not self.outstanding:
+			return None
+		return self.outstanding.pop(0)
+	def postpone(self,tsk):
+		if random.randint(0,1):
+			self.frozen.insert(0,tsk)
+		else:
+			self.frozen.append(tsk)
+	def refill_task_list(self):
+		while self.count>self.numjobs*GAP:
+			self.get_out()
+		while not self.outstanding:
+			if self.count:
+				self.get_out()
+			elif self.frozen:
+				try:
+					cond=self.deadlock==self.processed
+				except AttributeError:
+					pass
+				else:
+					if cond:
+						msg='check the build order for the tasks'
+						for tsk in self.frozen:
+							if not tsk.run_after:
+								msg='check the methods runnable_status'
+								break
+						lst=[]
+						for tsk in self.frozen:
+							lst.append('%s\t-> %r'%(repr(tsk),[id(x)for x in tsk.run_after]))
+						raise Errors.WafError('Deadlock detected: %s%s'%(msg,''.join(lst)))
+				self.deadlock=self.processed
+			if self.frozen:
+				self.outstanding+=self.frozen
+				self.frozen=[]
+			elif not self.count:
+				self.outstanding.extend(self.biter.next())
+				self.total=self.bld.total()
+				break
+	def add_more_tasks(self,tsk):
+		if getattr(tsk,'more_tasks',None):
+			self.outstanding+=tsk.more_tasks
+			self.total+=len(tsk.more_tasks)
+	def get_out(self):
+		tsk=self.out.get()
+		if not self.stop:
+			self.add_more_tasks(tsk)
+		self.count-=1
+		self.dirty=True
+		return tsk
+	def error_handler(self,tsk):
+		if not self.bld.keep:
+			self.stop=True
+		self.error.append(tsk)
+	def add_task(self,tsk):
+		try:
+			self.pool
+		except AttributeError:
+			self.init_task_pool()
+		self.ready.put(tsk)
+	def init_task_pool(self):
+		pool=self.pool=[get_pool()for i in range(self.numjobs)]
+		self.ready=Queue(0)
+		def setq(consumer):
+			consumer.ready=self.ready
+		for x in pool:
+			x.ready.put(setq)
+		return pool
+	def free_task_pool(self):
+		def setq(consumer):
+			consumer.ready=Queue(0)
+			self.out.put(self)
+		try:
+			pool=self.pool
+		except AttributeError:
+			pass
+		else:
+			for x in pool:
+				self.ready.put(setq)
+			for x in pool:
+				self.get_out()
+			for x in pool:
+				put_pool(x)
+			self.pool=[]
+	def start(self):
+		self.total=self.bld.total()
+		while not self.stop:
+			self.refill_task_list()
+			tsk=self.get_next_task()
+			if not tsk:
+				if self.count:
+					continue
+				else:
+					break
+			if tsk.hasrun:
+				self.processed+=1
+				continue
+			if self.stop:
+				break
+			try:
+				st=tsk.runnable_status()
+			except Exception:
+				self.processed+=1
+				tsk.err_msg=Utils.ex_stack()
+				if not self.stop and self.bld.keep:
+					tsk.hasrun=Task.SKIPPED
+					if self.bld.keep==1:
+						if Logs.verbose>1 or not self.error:
+							self.error.append(tsk)
+						self.stop=True
+					else:
+						if Logs.verbose>1:
+							self.error.append(tsk)
+					continue
+				tsk.hasrun=Task.EXCEPTION
+				self.error_handler(tsk)
+				continue
+			if st==Task.ASK_LATER:
+				self.postpone(tsk)
+			elif st==Task.SKIP_ME:
+				self.processed+=1
+				tsk.hasrun=Task.SKIPPED
+				self.add_more_tasks(tsk)
+			else:
+				tsk.position=(self.processed,self.total)
+				self.count+=1
+				tsk.master=self
+				self.processed+=1
+				if self.numjobs==1:
+					tsk.process()
+				else:
+					self.add_task(tsk)
+		while self.error and self.count:
+			self.get_out()
+		assert(self.count==0 or self.stop)
+		self.free_task_pool()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Runner.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Runner.pyc
new file mode 100644
index 0000000..de6e464
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Runner.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Scripting.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Scripting.py
new file mode 100644
index 0000000..fe5c30c
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Scripting.py
@@ -0,0 +1,373 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,shlex,shutil,traceback,errno,sys,stat
+from waflib import Utils,Configure,Logs,Options,ConfigSet,Context,Errors,Build,Node
+build_dir_override=None
+no_climb_commands=['configure']
+default_cmd="build"
+def waf_entry_point(current_directory,version,wafdir):
+	Logs.init_log()
+	if Context.WAFVERSION!=version:
+		Logs.error('Waf script %r and library %r do not match (directory %r)'%(version,Context.WAFVERSION,wafdir))
+		sys.exit(1)
+	if'--version'in sys.argv:
+		Context.run_dir=current_directory
+		ctx=Context.create_context('options')
+		ctx.curdir=current_directory
+		ctx.parse_args()
+		sys.exit(0)
+	Context.waf_dir=wafdir
+	Context.launch_dir=current_directory
+	no_climb=os.environ.get('NOCLIMB',None)
+	if not no_climb:
+		for k in no_climb_commands:
+			if k in sys.argv:
+				no_climb=True
+				break
+	cur=current_directory
+	while cur:
+		lst=os.listdir(cur)
+		if Options.lockfile in lst:
+			env=ConfigSet.ConfigSet()
+			try:
+				env.load(os.path.join(cur,Options.lockfile))
+				ino=os.stat(cur)[stat.ST_INO]
+			except Exception:
+				pass
+			else:
+				for x in[env.run_dir,env.top_dir,env.out_dir]:
+					if Utils.is_win32:
+						if cur==x:
+							load=True
+							break
+					else:
+						try:
+							ino2=os.stat(x)[stat.ST_INO]
+						except OSError:
+							pass
+						else:
+							if ino==ino2:
+								load=True
+								break
+				else:
+					Logs.warn('invalid lock file in %s'%cur)
+					load=False
+				if load:
+					Context.run_dir=env.run_dir
+					Context.top_dir=env.top_dir
+					Context.out_dir=env.out_dir
+					break
+		if not Context.run_dir:
+			if Context.WSCRIPT_FILE in lst:
+				Context.run_dir=cur
+		next=os.path.dirname(cur)
+		if next==cur:
+			break
+		cur=next
+		if no_climb:
+			break
+	if not Context.run_dir:
+		if'-h'in sys.argv or'--help'in sys.argv:
+			Logs.warn('No wscript file found: the help message may be incomplete')
+			Context.run_dir=current_directory
+			ctx=Context.create_context('options')
+			ctx.curdir=current_directory
+			ctx.parse_args()
+			sys.exit(0)
+		Logs.error('Waf: Run from a directory containing a file named %r'%Context.WSCRIPT_FILE)
+		sys.exit(1)
+	try:
+		os.chdir(Context.run_dir)
+	except OSError:
+		Logs.error('Waf: The folder %r is unreadable'%Context.run_dir)
+		sys.exit(1)
+	try:
+		set_main_module(Context.run_dir+os.sep+Context.WSCRIPT_FILE)
+	except Errors.WafError ,e:
+		Logs.pprint('RED',e.verbose_msg)
+		Logs.error(str(e))
+		sys.exit(1)
+	except Exception ,e:
+		Logs.error('Waf: The wscript in %r is unreadable'%Context.run_dir,e)
+		traceback.print_exc(file=sys.stdout)
+		sys.exit(2)
+	try:
+		run_commands()
+	except Errors.WafError ,e:
+		if Logs.verbose>1:
+			Logs.pprint('RED',e.verbose_msg)
+		Logs.error(e.msg)
+		sys.exit(1)
+	except SystemExit:
+		raise
+	except Exception ,e:
+		traceback.print_exc(file=sys.stdout)
+		sys.exit(2)
+	except KeyboardInterrupt:
+		Logs.pprint('RED','Interrupted')
+		sys.exit(68)
+def set_main_module(file_path):
+	Context.g_module=Context.load_module(file_path)
+	Context.g_module.root_path=file_path
+	def set_def(obj):
+		name=obj.__name__
+		if not name in Context.g_module.__dict__:
+			setattr(Context.g_module,name,obj)
+	for k in[update,dist,distclean,distcheck,update]:
+		set_def(k)
+	if not'init'in Context.g_module.__dict__:
+		Context.g_module.init=Utils.nada
+	if not'shutdown'in Context.g_module.__dict__:
+		Context.g_module.shutdown=Utils.nada
+	if not'options'in Context.g_module.__dict__:
+		Context.g_module.options=Utils.nada
+def parse_options():
+	Context.create_context('options').execute()
+	if not Options.commands:
+		Options.commands=[default_cmd]
+	Options.commands=[x for x in Options.commands if x!='options']
+	Logs.verbose=Options.options.verbose
+	Logs.init_log()
+	if Options.options.zones:
+		Logs.zones=Options.options.zones.split(',')
+		if not Logs.verbose:
+			Logs.verbose=1
+	elif Logs.verbose>0:
+		Logs.zones=['runner']
+	if Logs.verbose>2:
+		Logs.zones=['*']
+def run_command(cmd_name):
+	ctx=Context.create_context(cmd_name)
+	ctx.log_timer=Utils.Timer()
+	ctx.options=Options.options
+	ctx.cmd=cmd_name
+	ctx.execute()
+	return ctx
+def run_commands():
+	parse_options()
+	run_command('init')
+	while Options.commands:
+		cmd_name=Options.commands.pop(0)
+		ctx=run_command(cmd_name)
+		Logs.info('%r finished successfully (%s)'%(cmd_name,str(ctx.log_timer)))
+	run_command('shutdown')
+def _can_distclean(name):
+	for k in'.o .moc .exe'.split():
+		if name.endswith(k):
+			return True
+	return False
+def distclean_dir(dirname):
+	for(root,dirs,files)in os.walk(dirname):
+		for f in files:
+			if _can_distclean(f):
+				fname=root+os.sep+f
+				try:
+					os.remove(fname)
+				except OSError:
+					Logs.warn('Could not remove %r'%fname)
+	for x in[Context.DBFILE,'config.log']:
+		try:
+			os.remove(x)
+		except OSError:
+			pass
+	try:
+		shutil.rmtree('c4che')
+	except OSError:
+		pass
+def distclean(ctx):
+	'''removes the build directory'''
+	lst=os.listdir('.')
+	for f in lst:
+		if f==Options.lockfile:
+			try:
+				proj=ConfigSet.ConfigSet(f)
+			except IOError:
+				Logs.warn('Could not read %r'%f)
+				continue
+			if proj['out_dir']!=proj['top_dir']:
+				try:
+					shutil.rmtree(proj['out_dir'])
+				except IOError:
+					pass
+				except OSError ,e:
+					if e.errno!=errno.ENOENT:
+						Logs.warn('project %r cannot be removed'%proj[Context.OUT])
+			else:
+				distclean_dir(proj['out_dir'])
+			for k in(proj['out_dir'],proj['top_dir'],proj['run_dir']):
+				try:
+					os.remove(os.path.join(k,Options.lockfile))
+				except OSError ,e:
+					if e.errno!=errno.ENOENT:
+						Logs.warn('file %r cannot be removed'%f)
+		if f.startswith('.waf')and not Options.commands:
+			shutil.rmtree(f,ignore_errors=True)
+class Dist(Context.Context):
+	'''creates an archive containing the project source code'''
+	cmd='dist'
+	fun='dist'
+	algo='tar.bz2'
+	ext_algo={}
+	def execute(self):
+		self.recurse([os.path.dirname(Context.g_module.root_path)])
+		self.archive()
+	def archive(self):
+		import tarfile
+		arch_name=self.get_arch_name()
+		try:
+			self.base_path
+		except AttributeError:
+			self.base_path=self.path
+		node=self.base_path.make_node(arch_name)
+		try:
+			node.delete()
+		except Exception:
+			pass
+		files=self.get_files()
+		if self.algo.startswith('tar.'):
+			tar=tarfile.open(arch_name,'w:'+self.algo.replace('tar.',''))
+			for x in files:
+				self.add_tar_file(x,tar)
+			tar.close()
+		elif self.algo=='zip':
+			import zipfile
+			zip=zipfile.ZipFile(arch_name,'w',compression=zipfile.ZIP_DEFLATED)
+			for x in files:
+				archive_name=self.get_base_name()+'/'+x.path_from(self.base_path)
+				zip.write(x.abspath(),archive_name,zipfile.ZIP_DEFLATED)
+			zip.close()
+		else:
+			self.fatal('Valid algo types are tar.bz2, tar.gz or zip')
+		try:
+			from hashlib import sha1 as sha
+		except ImportError:
+			from sha import sha
+		try:
+			digest=" (sha=%r)"%sha(node.read()).hexdigest()
+		except Exception:
+			digest=''
+		Logs.info('New archive created: %s%s'%(self.arch_name,digest))
+	def get_tar_path(self,node):
+		return node.abspath()
+	def add_tar_file(self,x,tar):
+		p=self.get_tar_path(x)
+		tinfo=tar.gettarinfo(name=p,arcname=self.get_tar_prefix()+'/'+x.path_from(self.base_path))
+		tinfo.uid=0
+		tinfo.gid=0
+		tinfo.uname='root'
+		tinfo.gname='root'
+		fu=None
+		try:
+			fu=open(p,'rb')
+			tar.addfile(tinfo,fileobj=fu)
+		finally:
+			if fu:
+				fu.close()
+	def get_tar_prefix(self):
+		try:
+			return self.tar_prefix
+		except AttributeError:
+			return self.get_base_name()
+	def get_arch_name(self):
+		try:
+			self.arch_name
+		except AttributeError:
+			self.arch_name=self.get_base_name()+'.'+self.ext_algo.get(self.algo,self.algo)
+		return self.arch_name
+	def get_base_name(self):
+		try:
+			self.base_name
+		except AttributeError:
+			appname=getattr(Context.g_module,Context.APPNAME,'noname')
+			version=getattr(Context.g_module,Context.VERSION,'1.0')
+			self.base_name=appname+'-'+version
+		return self.base_name
+	def get_excl(self):
+		try:
+			return self.excl
+		except AttributeError:
+			self.excl=Node.exclude_regs+' **/waf-1.7.* **/.waf-1.7* **/waf3-1.7.* **/.waf3-1.7* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*'
+			nd=self.root.find_node(Context.out_dir)
+			if nd:
+				self.excl+=' '+nd.path_from(self.base_path)
+			return self.excl
+	def get_files(self):
+		try:
+			files=self.files
+		except AttributeError:
+			files=self.base_path.ant_glob('**/*',excl=self.get_excl())
+		return files
+def dist(ctx):
+	'''makes a tarball for redistributing the sources'''
+	pass
+class DistCheck(Dist):
+	fun='distcheck'
+	cmd='distcheck'
+	def execute(self):
+		self.recurse([os.path.dirname(Context.g_module.root_path)])
+		self.archive()
+		self.check()
+	def check(self):
+		import tempfile,tarfile
+		t=None
+		try:
+			t=tarfile.open(self.get_arch_name())
+			for x in t:
+				t.extract(x)
+		finally:
+			if t:
+				t.close()
+		cfg=[]
+		if Options.options.distcheck_args:
+			cfg=shlex.split(Options.options.distcheck_args)
+		else:
+			cfg=[x for x in sys.argv if x.startswith('-')]
+		instdir=tempfile.mkdtemp('.inst',self.get_base_name())
+		ret=Utils.subprocess.Popen([sys.executable,sys.argv[0],'configure','install','uninstall','--destdir='+instdir]+cfg,cwd=self.get_base_name()).wait()
+		if ret:
+			raise Errors.WafError('distcheck failed with code %i'%ret)
+		if os.path.exists(instdir):
+			raise Errors.WafError('distcheck succeeded, but files were left in %s'%instdir)
+		shutil.rmtree(self.get_base_name())
+def distcheck(ctx):
+	'''checks if the project compiles (tarball from 'dist')'''
+	pass
+def update(ctx):
+	'''updates the plugins from the *waflib/extras* directory'''
+	lst=Options.options.files.split(',')
+	if not lst:
+		lst=[x for x in Utils.listdir(Context.waf_dir+'/waflib/extras')if x.endswith('.py')]
+	for x in lst:
+		tool=x.replace('.py','')
+		try:
+			Configure.download_tool(tool,force=True,ctx=ctx)
+		except Errors.WafError:
+			Logs.error('Could not find the tool %s in the remote repository'%x)
+def autoconfigure(execute_method):
+	def execute(self):
+		if not Configure.autoconfig:
+			return execute_method(self)
+		env=ConfigSet.ConfigSet()
+		do_config=False
+		try:
+			env.load(os.path.join(Context.top_dir,Options.lockfile))
+		except Exception:
+			Logs.warn('Configuring the project')
+			do_config=True
+		else:
+			if env.run_dir!=Context.run_dir:
+				do_config=True
+			else:
+				h=0
+				for f in env['files']:
+					h=hash((h,Utils.readf(f,'rb')))
+				do_config=h!=env.hash
+		if do_config:
+			Options.commands.insert(0,self.cmd)
+			Options.commands.insert(0,'configure')
+			return
+		return execute_method(self)
+	return execute
+Build.BuildContext.execute=autoconfigure(Build.BuildContext.execute)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Scripting.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Scripting.pyc
new file mode 100644
index 0000000..57457bd
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Scripting.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Task.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Task.py
new file mode 100644
index 0000000..1b54a54
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Task.py
@@ -0,0 +1,677 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,shutil,re,tempfile
+from waflib import Utils,Logs,Errors
+NOT_RUN=0
+MISSING=1
+CRASHED=2
+EXCEPTION=3
+SKIPPED=8
+SUCCESS=9
+ASK_LATER=-1
+SKIP_ME=-2
+RUN_ME=-3
+COMPILE_TEMPLATE_SHELL='''
+def f(tsk):
+	env = tsk.env
+	gen = tsk.generator
+	bld = gen.bld
+	wd = getattr(tsk, 'cwd', None)
+	p = env.get_flat
+	tsk.last_cmd = cmd = \'\'\' %s \'\'\' % s
+	return tsk.exec_command(cmd, cwd=wd, env=env.env or None)
+'''
+COMPILE_TEMPLATE_NOSHELL='''
+def f(tsk):
+	env = tsk.env
+	gen = tsk.generator
+	bld = gen.bld
+	wd = getattr(tsk, 'cwd', None)
+	def to_list(xx):
+		if isinstance(xx, str): return [xx]
+		return xx
+	tsk.last_cmd = lst = []
+	%s
+	lst = [x for x in lst if x]
+	return tsk.exec_command(lst, cwd=wd, env=env.env or None)
+'''
+def cache_outputs(cls):
+	m1=cls.run
+	def run(self):
+		bld=self.generator.bld
+		if bld.cache_global and not bld.nocache:
+			if self.can_retrieve_cache():
+				return 0
+		return m1(self)
+	cls.run=run
+	m2=cls.post_run
+	def post_run(self):
+		bld=self.generator.bld
+		ret=m2(self)
+		if bld.cache_global and not bld.nocache:
+			self.put_files_cache()
+		return ret
+	cls.post_run=post_run
+	return cls
+classes={}
+class store_task_type(type):
+	def __init__(cls,name,bases,dict):
+		super(store_task_type,cls).__init__(name,bases,dict)
+		name=cls.__name__
+		if name.endswith('_task'):
+			name=name.replace('_task','')
+		if name!='evil'and name!='TaskBase':
+			global classes
+			if getattr(cls,'run_str',None):
+				(f,dvars)=compile_fun(cls.run_str,cls.shell)
+				cls.hcode=cls.run_str
+				cls.run_str=None
+				cls.run=f
+				cls.vars=list(set(cls.vars+dvars))
+				cls.vars.sort()
+			elif getattr(cls,'run',None)and not'hcode'in cls.__dict__:
+				cls.hcode=Utils.h_fun(cls.run)
+			if not getattr(cls,'nocache',None):
+				cls=cache_outputs(cls)
+			getattr(cls,'register',classes)[name]=cls
+evil=store_task_type('evil',(object,),{})
+class TaskBase(evil):
+	color='GREEN'
+	ext_in=[]
+	ext_out=[]
+	before=[]
+	after=[]
+	hcode=''
+	def __init__(self,*k,**kw):
+		self.hasrun=NOT_RUN
+		try:
+			self.generator=kw['generator']
+		except KeyError:
+			self.generator=self
+	def __repr__(self):
+		return'\n\t{task %r: %s %s}'%(self.__class__.__name__,id(self),str(getattr(self,'fun','')))
+	def __str__(self):
+		if hasattr(self,'fun'):
+			return'executing: %s\n'%self.fun.__name__
+		return self.__class__.__name__+'\n'
+	def __hash__(self):
+		return id(self)
+	def exec_command(self,cmd,**kw):
+		bld=self.generator.bld
+		try:
+			if not kw.get('cwd',None):
+				kw['cwd']=bld.cwd
+		except AttributeError:
+			bld.cwd=kw['cwd']=bld.variant_dir
+		return bld.exec_command(cmd,**kw)
+	def runnable_status(self):
+		return RUN_ME
+	def process(self):
+		m=self.master
+		if m.stop:
+			m.out.put(self)
+			return
+		try:
+			del self.generator.bld.task_sigs[self.uid()]
+		except KeyError:
+			pass
+		try:
+			self.generator.bld.returned_tasks.append(self)
+			self.log_display(self.generator.bld)
+			ret=self.run()
+		except Exception:
+			self.err_msg=Utils.ex_stack()
+			self.hasrun=EXCEPTION
+			m.error_handler(self)
+			m.out.put(self)
+			return
+		if ret:
+			self.err_code=ret
+			self.hasrun=CRASHED
+		else:
+			try:
+				self.post_run()
+			except Errors.WafError:
+				pass
+			except Exception:
+				self.err_msg=Utils.ex_stack()
+				self.hasrun=EXCEPTION
+			else:
+				self.hasrun=SUCCESS
+		if self.hasrun!=SUCCESS:
+			m.error_handler(self)
+		m.out.put(self)
+	def run(self):
+		if hasattr(self,'fun'):
+			return self.fun(self)
+		return 0
+	def post_run(self):
+		pass
+	def log_display(self,bld):
+		bld.to_log(self.display())
+	def display(self):
+		col1=Logs.colors(self.color)
+		col2=Logs.colors.NORMAL
+		master=self.master
+		def cur():
+			tmp=-1
+			if hasattr(master,'ready'):
+				tmp-=master.ready.qsize()
+			return master.processed+tmp
+		if self.generator.bld.progress_bar==1:
+			return self.generator.bld.progress_line(cur(),master.total,col1,col2)
+		if self.generator.bld.progress_bar==2:
+			ela=str(self.generator.bld.timer)
+			try:
+				ins=','.join([n.name for n in self.inputs])
+			except AttributeError:
+				ins=''
+			try:
+				outs=','.join([n.name for n in self.outputs])
+			except AttributeError:
+				outs=''
+			return'|Total %s|Current %s|Inputs %s|Outputs %s|Time %s|\n'%(master.total,cur(),ins,outs,ela)
+		s=str(self)
+		if not s:
+			return None
+		total=master.total
+		n=len(str(total))
+		fs='[%%%dd/%%%dd] %%s%%s%%s'%(n,n)
+		return fs%(cur(),total,col1,s,col2)
+	def attr(self,att,default=None):
+		ret=getattr(self,att,self)
+		if ret is self:return getattr(self.__class__,att,default)
+		return ret
+	def hash_constraints(self):
+		cls=self.__class__
+		tup=(str(cls.before),str(cls.after),str(cls.ext_in),str(cls.ext_out),cls.__name__,cls.hcode)
+		h=hash(tup)
+		return h
+	def format_error(self):
+		msg=getattr(self,'last_cmd','')
+		name=getattr(self.generator,'name','')
+		if getattr(self,"err_msg",None):
+			return self.err_msg
+		elif not self.hasrun:
+			return'task in %r was not executed for some reason: %r'%(name,self)
+		elif self.hasrun==CRASHED:
+			try:
+				return' -> task in %r failed (exit status %r): %r\n%r'%(name,self.err_code,self,msg)
+			except AttributeError:
+				return' -> task in %r failed: %r\n%r'%(name,self,msg)
+		elif self.hasrun==MISSING:
+			return' -> missing files in %r: %r\n%r'%(name,self,msg)
+		else:
+			return'invalid status for task in %r: %r'%(name,self.hasrun)
+	def colon(self,var1,var2):
+		tmp=self.env[var1]
+		if isinstance(var2,str):
+			it=self.env[var2]
+		else:
+			it=var2
+		if isinstance(tmp,str):
+			return[tmp%x for x in it]
+		else:
+			if Logs.verbose and not tmp and it:
+				Logs.warn('Missing env variable %r for task %r (generator %r)'%(var1,self,self.generator))
+			lst=[]
+			for y in it:
+				lst.extend(tmp)
+				lst.append(y)
+			return lst
+class Task(TaskBase):
+	vars=[]
+	shell=False
+	def __init__(self,*k,**kw):
+		TaskBase.__init__(self,*k,**kw)
+		self.env=kw['env']
+		self.inputs=[]
+		self.outputs=[]
+		self.dep_nodes=[]
+		self.run_after=set([])
+	def __str__(self):
+		env=self.env
+		src_str=' '.join([a.nice_path()for a in self.inputs])
+		tgt_str=' '.join([a.nice_path()for a in self.outputs])
+		if self.outputs:sep=' -> '
+		else:sep=''
+		return'%s: %s%s%s\n'%(self.__class__.__name__.replace('_task',''),src_str,sep,tgt_str)
+	def __repr__(self):
+		try:
+			ins=",".join([x.name for x in self.inputs])
+			outs=",".join([x.name for x in self.outputs])
+		except AttributeError:
+			ins=",".join([str(x)for x in self.inputs])
+			outs=",".join([str(x)for x in self.outputs])
+		return"".join(['\n\t{task %r: '%id(self),self.__class__.__name__," ",ins," -> ",outs,'}'])
+	def uid(self):
+		try:
+			return self.uid_
+		except AttributeError:
+			m=Utils.md5()
+			up=m.update
+			up(self.__class__.__name__)
+			for x in self.inputs+self.outputs:
+				up(x.abspath())
+			self.uid_=m.digest()
+			return self.uid_
+	def set_inputs(self,inp):
+		if isinstance(inp,list):self.inputs+=inp
+		else:self.inputs.append(inp)
+	def set_outputs(self,out):
+		if isinstance(out,list):self.outputs+=out
+		else:self.outputs.append(out)
+	def set_run_after(self,task):
+		assert isinstance(task,TaskBase)
+		self.run_after.add(task)
+	def signature(self):
+		try:return self.cache_sig
+		except AttributeError:pass
+		self.m=Utils.md5()
+		self.m.update(self.hcode)
+		self.sig_explicit_deps()
+		self.sig_vars()
+		if self.scan:
+			try:
+				self.sig_implicit_deps()
+			except Errors.TaskRescan:
+				return self.signature()
+		ret=self.cache_sig=self.m.digest()
+		return ret
+	def runnable_status(self):
+		for t in self.run_after:
+			if not t.hasrun:
+				return ASK_LATER
+		bld=self.generator.bld
+		try:
+			new_sig=self.signature()
+		except Errors.TaskNotReady:
+			return ASK_LATER
+		key=self.uid()
+		try:
+			prev_sig=bld.task_sigs[key]
+		except KeyError:
+			Logs.debug("task: task %r must run as it was never run before or the task code changed"%self)
+			return RUN_ME
+		for node in self.outputs:
+			try:
+				if node.sig!=new_sig:
+					return RUN_ME
+			except AttributeError:
+				Logs.debug("task: task %r must run as the output nodes do not exist"%self)
+				return RUN_ME
+		if new_sig!=prev_sig:
+			return RUN_ME
+		return SKIP_ME
+	def post_run(self):
+		bld=self.generator.bld
+		sig=self.signature()
+		for node in self.outputs:
+			try:
+				os.stat(node.abspath())
+			except OSError:
+				self.hasrun=MISSING
+				self.err_msg='-> missing file: %r'%node.abspath()
+				raise Errors.WafError(self.err_msg)
+			node.sig=sig
+		bld.task_sigs[self.uid()]=self.cache_sig
+	def sig_explicit_deps(self):
+		bld=self.generator.bld
+		upd=self.m.update
+		for x in self.inputs+self.dep_nodes:
+			try:
+				upd(x.get_bld_sig())
+			except(AttributeError,TypeError):
+				raise Errors.WafError('Missing node signature for %r (required by %r)'%(x,self))
+		if bld.deps_man:
+			additional_deps=bld.deps_man
+			for x in self.inputs+self.outputs:
+				try:
+					d=additional_deps[id(x)]
+				except KeyError:
+					continue
+				for v in d:
+					if isinstance(v,bld.root.__class__):
+						try:
+							v=v.get_bld_sig()
+						except AttributeError:
+							raise Errors.WafError('Missing node signature for %r (required by %r)'%(v,self))
+					elif hasattr(v,'__call__'):
+						v=v()
+					upd(v)
+		return self.m.digest()
+	def sig_vars(self):
+		bld=self.generator.bld
+		env=self.env
+		upd=self.m.update
+		act_sig=bld.hash_env_vars(env,self.__class__.vars)
+		upd(act_sig)
+		dep_vars=getattr(self,'dep_vars',None)
+		if dep_vars:
+			upd(bld.hash_env_vars(env,dep_vars))
+		return self.m.digest()
+	scan=None
+	def sig_implicit_deps(self):
+		bld=self.generator.bld
+		key=self.uid()
+		prev=bld.task_sigs.get((key,'imp'),[])
+		if prev:
+			try:
+				if prev==self.compute_sig_implicit_deps():
+					return prev
+			except Exception:
+				for x in bld.node_deps.get(self.uid(),[]):
+					if x.is_child_of(bld.srcnode):
+						try:
+							os.stat(x.abspath())
+						except OSError:
+							try:
+								del x.parent.children[x.name]
+							except KeyError:
+								pass
+			del bld.task_sigs[(key,'imp')]
+			raise Errors.TaskRescan('rescan')
+		(nodes,names)=self.scan()
+		if Logs.verbose:
+			Logs.debug('deps: scanner for %s returned %s %s'%(str(self),str(nodes),str(names)))
+		bld.node_deps[key]=nodes
+		bld.raw_deps[key]=names
+		self.are_implicit_nodes_ready()
+		try:
+			bld.task_sigs[(key,'imp')]=sig=self.compute_sig_implicit_deps()
+		except Exception:
+			if Logs.verbose:
+				for k in bld.node_deps.get(self.uid(),[]):
+					try:
+						k.get_bld_sig()
+					except Exception:
+						Logs.warn('Missing signature for node %r (may cause rebuilds)'%k)
+		else:
+			return sig
+	def compute_sig_implicit_deps(self):
+		upd=self.m.update
+		bld=self.generator.bld
+		self.are_implicit_nodes_ready()
+		for k in bld.node_deps.get(self.uid(),[]):
+			upd(k.get_bld_sig())
+		return self.m.digest()
+	def are_implicit_nodes_ready(self):
+		bld=self.generator.bld
+		try:
+			cache=bld.dct_implicit_nodes
+		except AttributeError:
+			bld.dct_implicit_nodes=cache={}
+		try:
+			dct=cache[bld.cur]
+		except KeyError:
+			dct=cache[bld.cur]={}
+			for tsk in bld.cur_tasks:
+				for x in tsk.outputs:
+					dct[x]=tsk
+		modified=False
+		for x in bld.node_deps.get(self.uid(),[]):
+			if x in dct:
+				self.run_after.add(dct[x])
+				modified=True
+		if modified:
+			for tsk in self.run_after:
+				if not tsk.hasrun:
+					raise Errors.TaskNotReady('not ready')
+	def can_retrieve_cache(self):
+		if not getattr(self,'outputs',None):
+			return None
+		sig=self.signature()
+		ssig=Utils.to_hex(self.uid())+Utils.to_hex(sig)
+		dname=os.path.join(self.generator.bld.cache_global,ssig)
+		try:
+			t1=os.stat(dname).st_mtime
+		except OSError:
+			return None
+		for node in self.outputs:
+			orig=os.path.join(dname,node.name)
+			try:
+				shutil.copy2(orig,node.abspath())
+				os.utime(orig,None)
+			except(OSError,IOError):
+				Logs.debug('task: failed retrieving file')
+				return None
+		try:
+			t2=os.stat(dname).st_mtime
+		except OSError:
+			return None
+		if t1!=t2:
+			return None
+		for node in self.outputs:
+			node.sig=sig
+			if self.generator.bld.progress_bar<1:
+				self.generator.bld.to_log('restoring from cache %r\n'%node.abspath())
+		self.cached=True
+		return True
+	def put_files_cache(self):
+		if getattr(self,'cached',None):
+			return None
+		if not getattr(self,'outputs',None):
+			return None
+		sig=self.signature()
+		ssig=Utils.to_hex(self.uid())+Utils.to_hex(sig)
+		dname=os.path.join(self.generator.bld.cache_global,ssig)
+		tmpdir=tempfile.mkdtemp(prefix=self.generator.bld.cache_global+os.sep+'waf')
+		try:
+			shutil.rmtree(dname)
+		except Exception:
+			pass
+		try:
+			for node in self.outputs:
+				dest=os.path.join(tmpdir,node.name)
+				shutil.copy2(node.abspath(),dest)
+		except(OSError,IOError):
+			try:
+				shutil.rmtree(tmpdir)
+			except Exception:
+				pass
+		else:
+			try:
+				os.rename(tmpdir,dname)
+			except OSError:
+				try:
+					shutil.rmtree(tmpdir)
+				except Exception:
+					pass
+			else:
+				try:
+					os.chmod(dname,Utils.O755)
+				except Exception:
+					pass
+def is_before(t1,t2):
+	to_list=Utils.to_list
+	for k in to_list(t2.ext_in):
+		if k in to_list(t1.ext_out):
+			return 1
+	if t1.__class__.__name__ in to_list(t2.after):
+		return 1
+	if t2.__class__.__name__ in to_list(t1.before):
+		return 1
+	return 0
+def set_file_constraints(tasks):
+	ins=Utils.defaultdict(set)
+	outs=Utils.defaultdict(set)
+	for x in tasks:
+		for a in getattr(x,'inputs',[])+getattr(x,'dep_nodes',[]):
+			ins[id(a)].add(x)
+		for a in getattr(x,'outputs',[]):
+			outs[id(a)].add(x)
+	links=set(ins.keys()).intersection(outs.keys())
+	for k in links:
+		for a in ins[k]:
+			a.run_after.update(outs[k])
+def set_precedence_constraints(tasks):
+	cstr_groups=Utils.defaultdict(list)
+	for x in tasks:
+		h=x.hash_constraints()
+		cstr_groups[h].append(x)
+	keys=list(cstr_groups.keys())
+	maxi=len(keys)
+	for i in range(maxi):
+		t1=cstr_groups[keys[i]][0]
+		for j in range(i+1,maxi):
+			t2=cstr_groups[keys[j]][0]
+			if is_before(t1,t2):
+				a=i
+				b=j
+			elif is_before(t2,t1):
+				a=j
+				b=i
+			else:
+				continue
+			aval=set(cstr_groups[keys[a]])
+			for x in cstr_groups[keys[b]]:
+				x.run_after.update(aval)
+def funex(c):
+	dc={}
+	exec(c,dc)
+	return dc['f']
+reg_act=re.compile(r"(?P<backslash>\\)|(?P<dollar>\$\$)|(?P<subst>\$\{(?P<var>\w+)(?P<code>.*?)\})",re.M)
+def compile_fun_shell(line):
+	extr=[]
+	def repl(match):
+		g=match.group
+		if g('dollar'):return"$"
+		elif g('backslash'):return'\\\\'
+		elif g('subst'):extr.append((g('var'),g('code')));return"%s"
+		return None
+	line=reg_act.sub(repl,line)or line
+	parm=[]
+	dvars=[]
+	app=parm.append
+	for(var,meth)in extr:
+		if var=='SRC':
+			if meth:app('tsk.inputs%s'%meth)
+			else:app('" ".join([a.path_from(bld.bldnode) for a in tsk.inputs])')
+		elif var=='TGT':
+			if meth:app('tsk.outputs%s'%meth)
+			else:app('" ".join([a.path_from(bld.bldnode) for a in tsk.outputs])')
+		elif meth:
+			if meth.startswith(':'):
+				m=meth[1:]
+				if m=='SRC':
+					m='[a.path_from(bld.bldnode) for a in tsk.inputs]'
+				elif m=='TGT':
+					m='[a.path_from(bld.bldnode) for a in tsk.outputs]'
+				elif m[:3]not in('tsk','gen','bld'):
+					dvars.extend([var,meth[1:]])
+					m='%r'%m
+				app('" ".join(tsk.colon(%r, %s))'%(var,m))
+			else:
+				app('%s%s'%(var,meth))
+		else:
+			if not var in dvars:dvars.append(var)
+			app("p('%s')"%var)
+	if parm:parm="%% (%s) "%(',\n\t\t'.join(parm))
+	else:parm=''
+	c=COMPILE_TEMPLATE_SHELL%(line,parm)
+	Logs.debug('action: %s'%c.strip().splitlines())
+	return(funex(c),dvars)
+def compile_fun_noshell(line):
+	extr=[]
+	def repl(match):
+		g=match.group
+		if g('dollar'):return"$"
+		elif g('subst'):extr.append((g('var'),g('code')));return"<<|@|>>"
+		return None
+	line2=reg_act.sub(repl,line)
+	params=line2.split('<<|@|>>')
+	assert(extr)
+	buf=[]
+	dvars=[]
+	app=buf.append
+	for x in range(len(extr)):
+		params[x]=params[x].strip()
+		if params[x]:
+			app("lst.extend(%r)"%params[x].split())
+		(var,meth)=extr[x]
+		if var=='SRC':
+			if meth:app('lst.append(tsk.inputs%s)'%meth)
+			else:app("lst.extend([a.path_from(bld.bldnode) for a in tsk.inputs])")
+		elif var=='TGT':
+			if meth:app('lst.append(tsk.outputs%s)'%meth)
+			else:app("lst.extend([a.path_from(bld.bldnode) for a in tsk.outputs])")
+		elif meth:
+			if meth.startswith(':'):
+				m=meth[1:]
+				if m=='SRC':
+					m='[a.path_from(bld.bldnode) for a in tsk.inputs]'
+				elif m=='TGT':
+					m='[a.path_from(bld.bldnode) for a in tsk.outputs]'
+				elif m[:3]not in('tsk','gen','bld'):
+					dvars.extend([var,m])
+					m='%r'%m
+				app('lst.extend(tsk.colon(%r, %s))'%(var,m))
+			else:
+				app('lst.extend(gen.to_list(%s%s))'%(var,meth))
+		else:
+			app('lst.extend(to_list(env[%r]))'%var)
+			if not var in dvars:dvars.append(var)
+	if extr:
+		if params[-1]:
+			app("lst.extend(%r)"%params[-1].split())
+	fun=COMPILE_TEMPLATE_NOSHELL%"\n\t".join(buf)
+	Logs.debug('action: %s'%fun.strip().splitlines())
+	return(funex(fun),dvars)
+def compile_fun(line,shell=False):
+	if line.find('<')>0 or line.find('>')>0 or line.find('&&')>0:
+		shell=True
+	if shell:
+		return compile_fun_shell(line)
+	else:
+		return compile_fun_noshell(line)
+def task_factory(name,func=None,vars=None,color='GREEN',ext_in=[],ext_out=[],before=[],after=[],shell=False,scan=None):
+	params={'vars':vars or[],'color':color,'name':name,'ext_in':Utils.to_list(ext_in),'ext_out':Utils.to_list(ext_out),'before':Utils.to_list(before),'after':Utils.to_list(after),'shell':shell,'scan':scan,}
+	if isinstance(func,str):
+		params['run_str']=func
+	else:
+		params['run']=func
+	cls=type(Task)(name,(Task,),params)
+	global classes
+	classes[name]=cls
+	return cls
+def always_run(cls):
+	old=cls.runnable_status
+	def always(self):
+		ret=old(self)
+		if ret==SKIP_ME:
+			ret=RUN_ME
+		return ret
+	cls.runnable_status=always
+	return cls
+def update_outputs(cls):
+	old_post_run=cls.post_run
+	def post_run(self):
+		old_post_run(self)
+		for node in self.outputs:
+			node.sig=Utils.h_file(node.abspath())
+			self.generator.bld.task_sigs[node.abspath()]=self.uid()
+	cls.post_run=post_run
+	old_runnable_status=cls.runnable_status
+	def runnable_status(self):
+		status=old_runnable_status(self)
+		if status!=RUN_ME:
+			return status
+		try:
+			bld=self.generator.bld
+			prev_sig=bld.task_sigs[self.uid()]
+			if prev_sig==self.signature():
+				for x in self.outputs:
+					if not x.sig or bld.task_sigs[x.abspath()]!=self.uid():
+						return RUN_ME
+				return SKIP_ME
+		except KeyError:
+			pass
+		except IndexError:
+			pass
+		except AttributeError:
+			pass
+		return RUN_ME
+	cls.runnable_status=runnable_status
+	return cls
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Task.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Task.pyc
new file mode 100644
index 0000000..59008e8
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Task.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/TaskGen.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/TaskGen.py
new file mode 100644
index 0000000..4e04239
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/TaskGen.py
@@ -0,0 +1,404 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import copy,re,os
+from waflib import Task,Utils,Logs,Errors,ConfigSet,Node
+feats=Utils.defaultdict(set)
+class task_gen(object):
+	mappings={}
+	prec=Utils.defaultdict(list)
+	def __init__(self,*k,**kw):
+		self.source=''
+		self.target=''
+		self.meths=[]
+		self.prec=Utils.defaultdict(list)
+		self.mappings={}
+		self.features=[]
+		self.tasks=[]
+		if not'bld'in kw:
+			self.env=ConfigSet.ConfigSet()
+			self.idx=0
+			self.path=None
+		else:
+			self.bld=kw['bld']
+			self.env=self.bld.env.derive()
+			self.path=self.bld.path
+			try:
+				self.idx=self.bld.idx[id(self.path)]=self.bld.idx.get(id(self.path),0)+1
+			except AttributeError:
+				self.bld.idx={}
+				self.idx=self.bld.idx[id(self.path)]=1
+		for key,val in kw.items():
+			setattr(self,key,val)
+	def __str__(self):
+		return"<task_gen %r declared in %s>"%(self.name,self.path.abspath())
+	def __repr__(self):
+		lst=[]
+		for x in self.__dict__.keys():
+			if x not in['env','bld','compiled_tasks','tasks']:
+				lst.append("%s=%s"%(x,repr(getattr(self,x))))
+		return"bld(%s) in %s"%(", ".join(lst),self.path.abspath())
+	def get_name(self):
+		try:
+			return self._name
+		except AttributeError:
+			if isinstance(self.target,list):
+				lst=[str(x)for x in self.target]
+				name=self._name=','.join(lst)
+			else:
+				name=self._name=str(self.target)
+			return name
+	def set_name(self,name):
+		self._name=name
+	name=property(get_name,set_name)
+	def to_list(self,val):
+		if isinstance(val,str):return val.split()
+		else:return val
+	def post(self):
+		if getattr(self,'posted',None):
+			return False
+		self.posted=True
+		keys=set(self.meths)
+		self.features=Utils.to_list(self.features)
+		for x in self.features+['*']:
+			st=feats[x]
+			if not st:
+				if not x in Task.classes:
+					Logs.warn('feature %r does not exist - bind at least one method to it'%x)
+			keys.update(list(st))
+		prec={}
+		prec_tbl=self.prec or task_gen.prec
+		for x in prec_tbl:
+			if x in keys:
+				prec[x]=prec_tbl[x]
+		tmp=[]
+		for a in keys:
+			for x in prec.values():
+				if a in x:break
+			else:
+				tmp.append(a)
+		tmp.sort()
+		out=[]
+		while tmp:
+			e=tmp.pop()
+			if e in keys:out.append(e)
+			try:
+				nlst=prec[e]
+			except KeyError:
+				pass
+			else:
+				del prec[e]
+				for x in nlst:
+					for y in prec:
+						if x in prec[y]:
+							break
+					else:
+						tmp.append(x)
+		if prec:
+			raise Errors.WafError('Cycle detected in the method execution %r'%prec)
+		out.reverse()
+		self.meths=out
+		Logs.debug('task_gen: posting %s %d'%(self,id(self)))
+		for x in out:
+			try:
+				v=getattr(self,x)
+			except AttributeError:
+				raise Errors.WafError('%r is not a valid task generator method'%x)
+			Logs.debug('task_gen: -> %s (%d)'%(x,id(self)))
+			v()
+		Logs.debug('task_gen: posted %s'%self.name)
+		return True
+	def get_hook(self,node):
+		name=node.name
+		for k in self.mappings:
+			if name.endswith(k):
+				return self.mappings[k]
+		for k in task_gen.mappings:
+			if name.endswith(k):
+				return task_gen.mappings[k]
+		raise Errors.WafError("File %r has no mapping in %r (did you forget to load a waf tool?)"%(node,task_gen.mappings.keys()))
+	def create_task(self,name,src=None,tgt=None):
+		task=Task.classes[name](env=self.env.derive(),generator=self)
+		if src:
+			task.set_inputs(src)
+		if tgt:
+			task.set_outputs(tgt)
+		self.tasks.append(task)
+		return task
+	def clone(self,env):
+		newobj=self.bld()
+		for x in self.__dict__:
+			if x in['env','bld']:
+				continue
+			elif x in['path','features']:
+				setattr(newobj,x,getattr(self,x))
+			else:
+				setattr(newobj,x,copy.copy(getattr(self,x)))
+		newobj.posted=False
+		if isinstance(env,str):
+			newobj.env=self.bld.all_envs[env].derive()
+		else:
+			newobj.env=env.derive()
+		return newobj
+def declare_chain(name='',rule=None,reentrant=None,color='BLUE',ext_in=[],ext_out=[],before=[],after=[],decider=None,scan=None,install_path=None,shell=False):
+	ext_in=Utils.to_list(ext_in)
+	ext_out=Utils.to_list(ext_out)
+	if not name:
+		name=rule
+	cls=Task.task_factory(name,rule,color=color,ext_in=ext_in,ext_out=ext_out,before=before,after=after,scan=scan,shell=shell)
+	def x_file(self,node):
+		ext=decider and decider(self,node)or cls.ext_out
+		if ext_in:
+			_ext_in=ext_in[0]
+		tsk=self.create_task(name,node)
+		cnt=0
+		keys=list(self.mappings.keys())+list(self.__class__.mappings.keys())
+		for x in ext:
+			k=node.change_ext(x,ext_in=_ext_in)
+			tsk.outputs.append(k)
+			if reentrant!=None:
+				if cnt<int(reentrant):
+					self.source.append(k)
+			else:
+				for y in keys:
+					if k.name.endswith(y):
+						self.source.append(k)
+						break
+			cnt+=1
+		if install_path:
+			self.bld.install_files(install_path,tsk.outputs)
+		return tsk
+	for x in cls.ext_in:
+		task_gen.mappings[x]=x_file
+	return x_file
+def taskgen_method(func):
+	setattr(task_gen,func.__name__,func)
+	return func
+def feature(*k):
+	def deco(func):
+		setattr(task_gen,func.__name__,func)
+		for name in k:
+			feats[name].update([func.__name__])
+		return func
+	return deco
+def before_method(*k):
+	def deco(func):
+		setattr(task_gen,func.__name__,func)
+		for fun_name in k:
+			if not func.__name__ in task_gen.prec[fun_name]:
+				task_gen.prec[fun_name].append(func.__name__)
+		return func
+	return deco
+before=before_method
+def after_method(*k):
+	def deco(func):
+		setattr(task_gen,func.__name__,func)
+		for fun_name in k:
+			if not fun_name in task_gen.prec[func.__name__]:
+				task_gen.prec[func.__name__].append(fun_name)
+		return func
+	return deco
+after=after_method
+def extension(*k):
+	def deco(func):
+		setattr(task_gen,func.__name__,func)
+		for x in k:
+			task_gen.mappings[x]=func
+		return func
+	return deco
+@taskgen_method
+def to_nodes(self,lst,path=None):
+	tmp=[]
+	path=path or self.path
+	find=path.find_resource
+	if isinstance(lst,self.path.__class__):
+		lst=[lst]
+	for x in Utils.to_list(lst):
+		if isinstance(x,str):
+			node=find(x)
+		else:
+			node=x
+		if not node:
+			raise Errors.WafError("source not found: %r in %r"%(x,self))
+		tmp.append(node)
+	return tmp
+@feature('*')
+def process_source(self):
+	self.source=self.to_nodes(getattr(self,'source',[]))
+	for node in self.source:
+		self.get_hook(node)(self,node)
+@feature('*')
+@before_method('process_source')
+def process_rule(self):
+	if not getattr(self,'rule',None):
+		return
+	name=str(getattr(self,'name',None)or self.target or getattr(self.rule,'__name__',self.rule))
+	try:
+		cache=self.bld.cache_rule_attr
+	except AttributeError:
+		cache=self.bld.cache_rule_attr={}
+	cls=None
+	if getattr(self,'cache_rule','True'):
+		try:
+			cls=cache[(name,self.rule)]
+		except KeyError:
+			pass
+	if not cls:
+		cls=Task.task_factory(name,self.rule,getattr(self,'vars',[]),shell=getattr(self,'shell',True),color=getattr(self,'color','BLUE'),scan=getattr(self,'scan',None))
+		if getattr(self,'scan',None):
+			cls.scan=self.scan
+		elif getattr(self,'deps',None):
+			def scan(self):
+				nodes=[]
+				for x in self.generator.to_list(getattr(self.generator,'deps',None)):
+					node=self.generator.path.find_resource(x)
+					if not node:
+						self.generator.bld.fatal('Could not find %r (was it declared?)'%x)
+					nodes.append(node)
+				return[nodes,[]]
+			cls.scan=scan
+		if getattr(self,'update_outputs',None):
+			Task.update_outputs(cls)
+		if getattr(self,'always',None):
+			Task.always_run(cls)
+		for x in['after','before','ext_in','ext_out']:
+			setattr(cls,x,getattr(self,x,[]))
+		if getattr(self,'cache_rule','True'):
+			cache[(name,self.rule)]=cls
+	tsk=self.create_task(name)
+	if getattr(self,'target',None):
+		if isinstance(self.target,str):
+			self.target=self.target.split()
+		if not isinstance(self.target,list):
+			self.target=[self.target]
+		for x in self.target:
+			if isinstance(x,str):
+				tsk.outputs.append(self.path.find_or_declare(x))
+			else:
+				x.parent.mkdir()
+				tsk.outputs.append(x)
+		if getattr(self,'install_path',None):
+			self.bld.install_files(self.install_path,tsk.outputs)
+	if getattr(self,'source',None):
+		tsk.inputs=self.to_nodes(self.source)
+		self.source=[]
+	if getattr(self,'cwd',None):
+		tsk.cwd=self.cwd
+@feature('seq')
+def sequence_order(self):
+	if self.meths and self.meths[-1]!='sequence_order':
+		self.meths.append('sequence_order')
+		return
+	if getattr(self,'seq_start',None):
+		return
+	if getattr(self.bld,'prev',None):
+		self.bld.prev.post()
+		for x in self.bld.prev.tasks:
+			for y in self.tasks:
+				y.set_run_after(x)
+	self.bld.prev=self
+re_m4=re.compile('@(\w+)@',re.M)
+class subst_pc(Task.Task):
+	def run(self):
+		if getattr(self.generator,'is_copy',None):
+			self.outputs[0].write(self.inputs[0].read('rb'),'wb')
+			if getattr(self.generator,'chmod',None):
+				os.chmod(self.outputs[0].abspath(),self.generator.chmod)
+			return None
+		if getattr(self.generator,'fun',None):
+			self.generator.fun(self)
+		code=self.inputs[0].read(encoding=getattr(self.generator,'encoding','ISO8859-1'))
+		if getattr(self.generator,'subst_fun',None):
+			code=self.generator.subst_fun(self,code)
+			if code:
+				self.outputs[0].write(code,encoding=getattr(self.generator,'encoding','ISO8859-1'))
+			return
+		code=code.replace('%','%%')
+		lst=[]
+		def repl(match):
+			g=match.group
+			if g(1):
+				lst.append(g(1))
+				return"%%(%s)s"%g(1)
+			return''
+		code=re_m4.sub(repl,code)
+		try:
+			d=self.generator.dct
+		except AttributeError:
+			d={}
+			for x in lst:
+				tmp=getattr(self.generator,x,'')or self.env.get_flat(x)or self.env.get_flat(x.upper())
+				d[x]=str(tmp)
+		code=code%d
+		self.outputs[0].write(code,encoding=getattr(self.generator,'encoding','ISO8859-1'))
+		self.generator.bld.raw_deps[self.uid()]=self.dep_vars=lst
+		try:delattr(self,'cache_sig')
+		except AttributeError:pass
+		if getattr(self.generator,'chmod',None):
+			os.chmod(self.outputs[0].abspath(),self.generator.chmod)
+	def sig_vars(self):
+		bld=self.generator.bld
+		env=self.env
+		upd=self.m.update
+		if getattr(self.generator,'fun',None):
+			upd(Utils.h_fun(self.generator.fun))
+		if getattr(self.generator,'subst_fun',None):
+			upd(Utils.h_fun(self.generator.subst_fun))
+		vars=self.generator.bld.raw_deps.get(self.uid(),[])
+		act_sig=bld.hash_env_vars(env,vars)
+		upd(act_sig)
+		lst=[getattr(self.generator,x,'')for x in vars]
+		upd(Utils.h_list(lst))
+		return self.m.digest()
+@extension('.pc.in')
+def add_pcfile(self,node):
+	tsk=self.create_task('subst_pc',node,node.change_ext('.pc','.pc.in'))
+	self.bld.install_files(getattr(self,'install_path','${LIBDIR}/pkgconfig/'),tsk.outputs)
+class subst(subst_pc):
+	pass
+@feature('subst')
+@before_method('process_source','process_rule')
+def process_subst(self):
+	src=Utils.to_list(getattr(self,'source',[]))
+	if isinstance(src,Node.Node):
+		src=[src]
+	tgt=Utils.to_list(getattr(self,'target',[]))
+	if isinstance(tgt,Node.Node):
+		tgt=[tgt]
+	if len(src)!=len(tgt):
+		raise Errors.WafError('invalid number of source/target for %r'%self)
+	for x,y in zip(src,tgt):
+		if not x or not y:
+			raise Errors.WafError('null source or target for %r'%self)
+		a,b=None,None
+		if isinstance(x,str)and isinstance(y,str)and x==y:
+			a=self.path.find_node(x)
+			b=self.path.get_bld().make_node(y)
+			if not os.path.isfile(b.abspath()):
+				b.sig=None
+				b.parent.mkdir()
+		else:
+			if isinstance(x,str):
+				a=self.path.find_resource(x)
+			elif isinstance(x,Node.Node):
+				a=x
+			if isinstance(y,str):
+				b=self.path.find_or_declare(y)
+			elif isinstance(y,Node.Node):
+				b=y
+		if not a:
+			raise Errors.WafError('cound not find %r for %r'%(x,self))
+		has_constraints=False
+		tsk=self.create_task('subst',a,b)
+		for k in('after','before','ext_in','ext_out'):
+			val=getattr(self,k,None)
+			if val:
+				has_constraints=True
+				setattr(tsk,k,val)
+		if not has_constraints and b.name.endswith('.h'):
+			tsk.before=[k for k in('c','cxx')if k in Task.classes]
+		inst_to=getattr(self,'install_path',None)
+		if inst_to:
+			self.bld.install_files(inst_to,b,chmod=getattr(self,'chmod',Utils.O644))
+	self.source=[]
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/TaskGen.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/TaskGen.pyc
new file mode 100644
index 0000000..1ffb5ad
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/TaskGen.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/__init__.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/__init__.py
new file mode 100644
index 0000000..efeed79
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/__init__.py
@@ -0,0 +1,4 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/__init__.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/__init__.pyc
new file mode 100644
index 0000000..066aed3
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/__init__.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ar.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ar.py
new file mode 100644
index 0000000..7a16dfe
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ar.py
@@ -0,0 +1,11 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib.Configure import conf
+@conf
+def find_ar(conf):
+	conf.load('ar')
+def configure(conf):
+	conf.find_program('ar',var='AR')
+	conf.env.ARFLAGS='rcs'
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ar.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ar.pyc
new file mode 100644
index 0000000..2c1968b
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ar.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/asm.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/asm.py
new file mode 100644
index 0000000..b9ed5f4
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/asm.py
@@ -0,0 +1,25 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib import Task,Utils
+import waflib.Task
+from waflib.Tools.ccroot import link_task,stlink_task
+from waflib.TaskGen import extension,feature
+class asm(Task.Task):
+	color='BLUE'
+	run_str='${AS} ${ASFLAGS} ${ASMPATH_ST:INCPATHS} ${AS_SRC_F}${SRC} ${AS_TGT_F}${TGT}'
+@extension('.s','.S','.asm','.ASM','.spp','.SPP')
+def asm_hook(self,node):
+	return self.create_compiled_task('asm',node)
+class asmprogram(link_task):
+	run_str='${ASLINK} ${ASLINKFLAGS} ${ASLNK_TGT_F}${TGT} ${ASLNK_SRC_F}${SRC}'
+	ext_out=['.bin']
+	inst_to='${BINDIR}'
+class asmshlib(asmprogram):
+	inst_to='${LIBDIR}'
+class asmstlib(stlink_task):
+	pass
+def configure(conf):
+	conf.env['ASMPATH_ST']='-I%s'
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/bison.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/bison.py
new file mode 100644
index 0000000..6ae7898
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/bison.py
@@ -0,0 +1,28 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Task
+from waflib.TaskGen import extension
+class bison(Task.Task):
+	color='BLUE'
+	run_str='${BISON} ${BISONFLAGS} ${SRC[0].abspath()} -o ${TGT[0].name}'
+	ext_out=['.h']
+@extension('.y','.yc','.yy')
+def big_bison(self,node):
+	has_h='-d'in self.env['BISONFLAGS']
+	outs=[]
+	if node.name.endswith('.yc'):
+		outs.append(node.change_ext('.tab.cc'))
+		if has_h:
+			outs.append(node.change_ext('.tab.hh'))
+	else:
+		outs.append(node.change_ext('.tab.c'))
+		if has_h:
+			outs.append(node.change_ext('.tab.h'))
+	tsk=self.create_task('bison',node,outs)
+	tsk.cwd=node.parent.get_bld().abspath()
+	self.source.append(outs[0])
+def configure(conf):
+	conf.find_program('bison',var='BISON')
+	conf.env.BISONFLAGS=['-d']
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c.py
new file mode 100644
index 0000000..4d8cbd5
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c.py
@@ -0,0 +1,24 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import TaskGen,Task,Utils
+from waflib.Tools import c_preproc
+from waflib.Tools.ccroot import link_task,stlink_task
+@TaskGen.extension('.c')
+def c_hook(self,node):
+	return self.create_compiled_task('c',node)
+class c(Task.Task):
+	run_str='${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT}'
+	vars=['CCDEPS']
+	ext_in=['.h']
+	scan=c_preproc.scan
+class cprogram(link_task):
+	run_str='${LINK_CC} ${LINKFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB}'
+	ext_out=['.bin']
+	vars=['LINKDEPS']
+	inst_to='${BINDIR}'
+class cshlib(cprogram):
+	inst_to='${LIBDIR}'
+class cstlib(stlink_task):
+	pass
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c.pyc
new file mode 100644
index 0000000..f40f66b
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_aliases.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_aliases.py
new file mode 100644
index 0000000..a3a2bb9
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_aliases.py
@@ -0,0 +1,55 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,re
+from waflib import Utils,Build
+from waflib.Configure import conf
+def get_extensions(lst):
+	ret=[]
+	for x in Utils.to_list(lst):
+		try:
+			if not isinstance(x,str):
+				x=x.name
+			ret.append(x[x.rfind('.')+1:])
+		except Exception:
+			pass
+	return ret
+def sniff_features(**kw):
+	exts=get_extensions(kw['source'])
+	type=kw['_type']
+	feats=[]
+	if'cxx'in exts or'cpp'in exts or'c++'in exts or'cc'in exts or'C'in exts:
+		feats.append('cxx')
+	if'c'in exts or'vala'in exts:
+		feats.append('c')
+	if'd'in exts:
+		feats.append('d')
+	if'java'in exts:
+		feats.append('java')
+	if'java'in exts:
+		return'java'
+	if type in['program','shlib','stlib']:
+		for x in feats:
+			if x in['cxx','d','c']:
+				feats.append(x+type)
+	return feats
+def set_features(kw,_type):
+	kw['_type']=_type
+	kw['features']=Utils.to_list(kw.get('features',[]))+Utils.to_list(sniff_features(**kw))
+@conf
+def program(bld,*k,**kw):
+	set_features(kw,'program')
+	return bld(*k,**kw)
+@conf
+def shlib(bld,*k,**kw):
+	set_features(kw,'shlib')
+	return bld(*k,**kw)
+@conf
+def stlib(bld,*k,**kw):
+	set_features(kw,'stlib')
+	return bld(*k,**kw)
+@conf
+def objects(bld,*k,**kw):
+	set_features(kw,'objects')
+	return bld(*k,**kw)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_aliases.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_aliases.pyc
new file mode 100644
index 0000000..8f3eb0c
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_aliases.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_config.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_config.py
new file mode 100755
index 0000000..690aa65
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_config.py
@@ -0,0 +1,729 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,re,shlex,sys
+from waflib import Build,Utils,Task,Options,Logs,Errors,ConfigSet,Runner
+from waflib.TaskGen import after_method,feature
+from waflib.Configure import conf
+WAF_CONFIG_H='config.h'
+DEFKEYS='define_key'
+INCKEYS='include_key'
+cfg_ver={'atleast-version':'>=','exact-version':'==','max-version':'<=',}
+SNIP_FUNCTION='''
+int main(int argc, char **argv) {
+	void *p;
+	(void)argc; (void)argv;
+	p=(void*)(%s);
+	return 0;
+}
+'''
+SNIP_TYPE='''
+int main(int argc, char **argv) {
+	(void)argc; (void)argv;
+	if ((%(type_name)s *) 0) return 0;
+	if (sizeof (%(type_name)s)) return 0;
+	return 1;
+}
+'''
+SNIP_EMPTY_PROGRAM='''
+int main(int argc, char **argv) {
+	(void)argc; (void)argv;
+	return 0;
+}
+'''
+SNIP_FIELD='''
+int main(int argc, char **argv) {
+	char *off;
+	(void)argc; (void)argv;
+	off = (char*) &((%(type_name)s*)0)->%(field_name)s;
+	return (size_t) off < sizeof(%(type_name)s);
+}
+'''
+MACRO_TO_DESTOS={'__linux__':'linux','__GNU__':'gnu','__FreeBSD__':'freebsd','__NetBSD__':'netbsd','__OpenBSD__':'openbsd','__sun':'sunos','__hpux':'hpux','__sgi':'irix','_AIX':'aix','__CYGWIN__':'cygwin','__MSYS__':'msys','_UWIN':'uwin','_WIN64':'win32','_WIN32':'win32','__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__':'darwin','__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__':'darwin','__QNX__':'qnx','__native_client__':'nacl'}
+MACRO_TO_DEST_CPU={'__x86_64__':'x86_64','__amd64__':'x86_64','__i386__':'x86','__ia64__':'ia','__mips__':'mips','__sparc__':'sparc','__alpha__':'alpha','__aarch64__':'aarch64','__thumb__':'thumb','__arm__':'arm','__hppa__':'hppa','__powerpc__':'powerpc','__ppc__':'powerpc','__convex__':'convex','__m68k__':'m68k','__s390x__':'s390x','__s390__':'s390','__sh__':'sh',}
+@conf
+def parse_flags(self,line,uselib_store,env=None,force_static=False):
+	assert(isinstance(line,str))
+	env=env or self.env
+	app=env.append_value
+	appu=env.append_unique
+	lex=shlex.shlex(line,posix=False)
+	lex.whitespace_split=True
+	lex.commenters=''
+	lst=list(lex)
+	uselib=uselib_store
+	while lst:
+		x=lst.pop(0)
+		st=x[:2]
+		ot=x[2:]
+		if st=='-I'or st=='/I':
+			if not ot:ot=lst.pop(0)
+			appu('INCLUDES_'+uselib,[ot])
+		elif st=='-include':
+			tmp=[x,lst.pop(0)]
+			app('CFLAGS',tmp)
+			app('CXXFLAGS',tmp)
+		elif st=='-D'or(env.CXX_NAME=='msvc'and st=='/D'):
+			if not ot:ot=lst.pop(0)
+			app('DEFINES_'+uselib,[ot])
+		elif st=='-l':
+			if not ot:ot=lst.pop(0)
+			prefix=force_static and'STLIB_'or'LIB_'
+			appu(prefix+uselib,[ot])
+		elif st=='-L':
+			if not ot:ot=lst.pop(0)
+			appu('LIBPATH_'+uselib,[ot])
+		elif x.startswith('/LIBPATH:'):
+			appu('LIBPATH_'+uselib,[x.replace('/LIBPATH:','')])
+		elif x=='-pthread'or x.startswith('+')or x.startswith('-std'):
+			app('CFLAGS_'+uselib,[x])
+			app('CXXFLAGS_'+uselib,[x])
+			app('LINKFLAGS_'+uselib,[x])
+		elif x=='-framework':
+			appu('FRAMEWORK_'+uselib,[lst.pop(0)])
+		elif x.startswith('-F'):
+			appu('FRAMEWORKPATH_'+uselib,[x[2:]])
+		elif x.startswith('-Wl'):
+			app('LINKFLAGS_'+uselib,[x])
+		elif x.startswith('-m')or x.startswith('-f')or x.startswith('-dynamic'):
+			app('CFLAGS_'+uselib,[x])
+			app('CXXFLAGS_'+uselib,[x])
+		elif x.startswith('-bundle'):
+			app('LINKFLAGS_'+uselib,[x])
+		elif x.startswith('-undefined'):
+			arg=lst.pop(0)
+			app('LINKFLAGS_'+uselib,[x,arg])
+		elif x.startswith('-arch')or x.startswith('-isysroot'):
+			tmp=[x,lst.pop(0)]
+			app('CFLAGS_'+uselib,tmp)
+			app('CXXFLAGS_'+uselib,tmp)
+			app('LINKFLAGS_'+uselib,tmp)
+		elif x.endswith('.a')or x.endswith('.so')or x.endswith('.dylib')or x.endswith('.lib'):
+			appu('LINKFLAGS_'+uselib,[x])
+@conf
+def ret_msg(self,f,kw):
+	if isinstance(f,str):
+		return f
+	return f(kw)
+@conf
+def validate_cfg(self,kw):
+	if not'path'in kw:
+		if not self.env.PKGCONFIG:
+			self.find_program('pkg-config',var='PKGCONFIG')
+		kw['path']=self.env.PKGCONFIG
+	if'atleast_pkgconfig_version'in kw:
+		if not'msg'in kw:
+			kw['msg']='Checking for pkg-config version >= %r'%kw['atleast_pkgconfig_version']
+		return
+	if not'okmsg'in kw:
+		kw['okmsg']='yes'
+	if not'errmsg'in kw:
+		kw['errmsg']='not found'
+	if'modversion'in kw:
+		if not'msg'in kw:
+			kw['msg']='Checking for %r version'%kw['modversion']
+		return
+	for x in cfg_ver.keys():
+		y=x.replace('-','_')
+		if y in kw:
+			if not'package'in kw:
+				raise ValueError('%s requires a package'%x)
+			if not'msg'in kw:
+				kw['msg']='Checking for %r %s %s'%(kw['package'],cfg_ver[x],kw[y])
+			return
+	if not'msg'in kw:
+		kw['msg']='Checking for %r'%(kw['package']or kw['path'])
+@conf
+def exec_cfg(self,kw):
+	def define_it():
+		self.define(self.have_define(kw.get('uselib_store',kw['package'])),1,0)
+	env=kw.get('env',self.env)
+	run_env=env.env or os.environ
+	if'atleast_pkgconfig_version'in kw:
+		cmd=[kw['path'],'--atleast-pkgconfig-version=%s'%kw['atleast_pkgconfig_version']]
+		self.cmd_and_log(cmd,env=run_env)
+		if not'okmsg'in kw:
+			kw['okmsg']='yes'
+		return
+	for x in cfg_ver:
+		y=x.replace('-','_')
+		if y in kw:
+			self.cmd_and_log([kw['path'],'--%s=%s'%(x,kw[y]),kw['package']],env=run_env)
+			if not'okmsg'in kw:
+				kw['okmsg']='yes'
+			define_it()
+			break
+	if'modversion'in kw:
+		version=self.cmd_and_log([kw['path'],'--modversion',kw['modversion']],env=run_env).strip()
+		self.define('%s_VERSION'%Utils.quote_define_name(kw.get('uselib_store',kw['modversion'])),version)
+		return version
+	lst=[kw['path']]
+	defi=kw.get('define_variable',None)
+	if not defi:
+		defi=self.env.PKG_CONFIG_DEFINES or{}
+	for key,val in defi.items():
+		lst.append('--define-variable=%s=%s'%(key,val))
+	if'variables'in kw:
+		uselib=kw.get('uselib_store',kw['package'].upper())
+		vars=Utils.to_list(kw['variables'])
+		for v in vars:
+			val=self.cmd_and_log(lst+['--variable='+v],env=run_env).strip()
+			var='%s_%s'%(uselib,v)
+			env[var]=val
+		if not'okmsg'in kw:
+			kw['okmsg']='yes'
+		return
+	static=False
+	if'args'in kw:
+		args=Utils.to_list(kw['args'])
+		if'--static'in args or'--static-libs'in args:
+			static=True
+		lst+=args
+	lst.extend(Utils.to_list(kw['package']))
+	ret=self.cmd_and_log(lst,env=run_env)
+	if not'okmsg'in kw:
+		kw['okmsg']='yes'
+	define_it()
+	self.parse_flags(ret,kw.get('uselib_store',kw['package'].upper()),kw.get('env',self.env),force_static=static)
+	return ret
+@conf
+def check_cfg(self,*k,**kw):
+	if k:
+		lst=k[0].split()
+		kw['package']=lst[0]
+		kw['args']=' '.join(lst[1:])
+	self.validate_cfg(kw)
+	if'msg'in kw:
+		self.start_msg(kw['msg'])
+	ret=None
+	try:
+		ret=self.exec_cfg(kw)
+	except self.errors.WafError:
+		if'errmsg'in kw:
+			self.end_msg(kw['errmsg'],'YELLOW')
+		if Logs.verbose>1:
+			raise
+		else:
+			self.fatal('The configuration failed')
+	else:
+		kw['success']=ret
+		if'okmsg'in kw:
+			self.end_msg(self.ret_msg(kw['okmsg'],kw))
+	return ret
+@conf
+def validate_c(self,kw):
+	if not'env'in kw:
+		kw['env']=self.env.derive()
+	env=kw['env']
+	if not'compiler'in kw and not'features'in kw:
+		kw['compiler']='c'
+		if env['CXX_NAME']and Task.classes.get('cxx',None):
+			kw['compiler']='cxx'
+			if not self.env['CXX']:
+				self.fatal('a c++ compiler is required')
+		else:
+			if not self.env['CC']:
+				self.fatal('a c compiler is required')
+	if not'compile_mode'in kw:
+		kw['compile_mode']='c'
+		if'cxx'in Utils.to_list(kw.get('features',[]))or kw.get('compiler','')=='cxx':
+			kw['compile_mode']='cxx'
+	if not'type'in kw:
+		kw['type']='cprogram'
+	if not'features'in kw:
+		kw['features']=[kw['compile_mode'],kw['type']]
+	else:
+		kw['features']=Utils.to_list(kw['features'])
+	if not'compile_filename'in kw:
+		kw['compile_filename']='test.c'+((kw['compile_mode']=='cxx')and'pp'or'')
+	def to_header(dct):
+		if'header_name'in dct:
+			dct=Utils.to_list(dct['header_name'])
+			return''.join(['#include <%s>\n'%x for x in dct])
+		return''
+	if'framework_name'in kw:
+		fwkname=kw['framework_name']
+		if not'uselib_store'in kw:
+			kw['uselib_store']=fwkname.upper()
+		if not kw.get('no_header',False):
+			if not'header_name'in kw:
+				kw['header_name']=[]
+			fwk='%s/%s.h'%(fwkname,fwkname)
+			if kw.get('remove_dot_h',None):
+				fwk=fwk[:-2]
+			kw['header_name']=Utils.to_list(kw['header_name'])+[fwk]
+		kw['msg']='Checking for framework %s'%fwkname
+		kw['framework']=fwkname
+	if'function_name'in kw:
+		fu=kw['function_name']
+		if not'msg'in kw:
+			kw['msg']='Checking for function %s'%fu
+		kw['code']=to_header(kw)+SNIP_FUNCTION%fu
+		if not'uselib_store'in kw:
+			kw['uselib_store']=fu.upper()
+		if not'define_name'in kw:
+			kw['define_name']=self.have_define(fu)
+	elif'type_name'in kw:
+		tu=kw['type_name']
+		if not'header_name'in kw:
+			kw['header_name']='stdint.h'
+		if'field_name'in kw:
+			field=kw['field_name']
+			kw['code']=to_header(kw)+SNIP_FIELD%{'type_name':tu,'field_name':field}
+			if not'msg'in kw:
+				kw['msg']='Checking for field %s in %s'%(field,tu)
+			if not'define_name'in kw:
+				kw['define_name']=self.have_define((tu+'_'+field).upper())
+		else:
+			kw['code']=to_header(kw)+SNIP_TYPE%{'type_name':tu}
+			if not'msg'in kw:
+				kw['msg']='Checking for type %s'%tu
+			if not'define_name'in kw:
+				kw['define_name']=self.have_define(tu.upper())
+	elif'header_name'in kw:
+		if not'msg'in kw:
+			kw['msg']='Checking for header %s'%kw['header_name']
+		l=Utils.to_list(kw['header_name'])
+		assert len(l)>0,'list of headers in header_name is empty'
+		kw['code']=to_header(kw)+SNIP_EMPTY_PROGRAM
+		if not'uselib_store'in kw:
+			kw['uselib_store']=l[0].upper()
+		if not'define_name'in kw:
+			kw['define_name']=self.have_define(l[0])
+	if'lib'in kw:
+		if not'msg'in kw:
+			kw['msg']='Checking for library %s'%kw['lib']
+		if not'uselib_store'in kw:
+			kw['uselib_store']=kw['lib'].upper()
+	if'stlib'in kw:
+		if not'msg'in kw:
+			kw['msg']='Checking for static library %s'%kw['stlib']
+		if not'uselib_store'in kw:
+			kw['uselib_store']=kw['stlib'].upper()
+	if'fragment'in kw:
+		kw['code']=kw['fragment']
+		if not'msg'in kw:
+			kw['msg']='Checking for code snippet'
+		if not'errmsg'in kw:
+			kw['errmsg']='no'
+	for(flagsname,flagstype)in[('cxxflags','compiler'),('cflags','compiler'),('linkflags','linker')]:
+		if flagsname in kw:
+			if not'msg'in kw:
+				kw['msg']='Checking for %s flags %s'%(flagstype,kw[flagsname])
+			if not'errmsg'in kw:
+				kw['errmsg']='no'
+	if not'execute'in kw:
+		kw['execute']=False
+	if kw['execute']:
+		kw['features'].append('test_exec')
+	if not'errmsg'in kw:
+		kw['errmsg']='not found'
+	if not'okmsg'in kw:
+		kw['okmsg']='yes'
+	if not'code'in kw:
+		kw['code']=SNIP_EMPTY_PROGRAM
+	if self.env[INCKEYS]:
+		kw['code']='\n'.join(['#include <%s>'%x for x in self.env[INCKEYS]])+'\n'+kw['code']
+	if not kw.get('success'):kw['success']=None
+	if'define_name'in kw:
+		self.undefine(kw['define_name'])
+	assert'msg'in kw,'invalid parameters, read http://freehackers.org/~tnagy/wafbook/single.html#config_helpers_c'
+@conf
+def post_check(self,*k,**kw):
+	is_success=0
+	if kw['execute']:
+		if kw['success']is not None:
+			if kw.get('define_ret',False):
+				is_success=kw['success']
+			else:
+				is_success=(kw['success']==0)
+	else:
+		is_success=(kw['success']==0)
+	if'define_name'in kw:
+		if'header_name'in kw or'function_name'in kw or'type_name'in kw or'fragment'in kw:
+			if kw['execute']and kw.get('define_ret',None)and isinstance(is_success,str):
+				self.define(kw['define_name'],is_success,quote=kw.get('quote',1))
+			else:
+				self.define_cond(kw['define_name'],is_success)
+		else:
+			self.define_cond(kw['define_name'],is_success)
+	if'header_name'in kw:
+		if kw.get('auto_add_header_name',False):
+			self.env.append_value(INCKEYS,Utils.to_list(kw['header_name']))
+	if is_success and'uselib_store'in kw:
+		from waflib.Tools import ccroot
+		_vars=set([])
+		for x in kw['features']:
+			if x in ccroot.USELIB_VARS:
+				_vars|=ccroot.USELIB_VARS[x]
+		for k in _vars:
+			lk=k.lower()
+			if k=='INCLUDES':lk='includes'
+			if k=='DEFINES':lk='defines'
+			if lk in kw:
+				val=kw[lk]
+				if isinstance(val,str):
+					val=val.rstrip(os.path.sep)
+				self.env.append_unique(k+'_'+kw['uselib_store'],val)
+	return is_success
+@conf
+def check(self,*k,**kw):
+	self.validate_c(kw)
+	self.start_msg(kw['msg'])
+	ret=None
+	try:
+		ret=self.run_c_code(*k,**kw)
+	except self.errors.ConfigurationError:
+		self.end_msg(kw['errmsg'],'YELLOW')
+		if Logs.verbose>1:
+			raise
+		else:
+			self.fatal('The configuration failed')
+	else:
+		kw['success']=ret
+	ret=self.post_check(*k,**kw)
+	if not ret:
+		self.end_msg(kw['errmsg'],'YELLOW')
+		self.fatal('The configuration failed %r'%ret)
+	else:
+		self.end_msg(self.ret_msg(kw['okmsg'],kw))
+	return ret
+class test_exec(Task.Task):
+	color='PINK'
+	def run(self):
+		if getattr(self.generator,'rpath',None):
+			if getattr(self.generator,'define_ret',False):
+				self.generator.bld.retval=self.generator.bld.cmd_and_log([self.inputs[0].abspath()])
+			else:
+				self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()])
+		else:
+			env=self.env.env or{}
+			env.update(dict(os.environ))
+			for var in('LD_LIBRARY_PATH','DYLD_LIBRARY_PATH','PATH'):
+				env[var]=self.inputs[0].parent.abspath()+os.path.pathsep+env.get(var,'')
+			if getattr(self.generator,'define_ret',False):
+				self.generator.bld.retval=self.generator.bld.cmd_and_log([self.inputs[0].abspath()],env=env)
+			else:
+				self.generator.bld.retval=self.generator.bld.exec_command([self.inputs[0].abspath()],env=env)
+@feature('test_exec')
+@after_method('apply_link')
+def test_exec_fun(self):
+	self.create_task('test_exec',self.link_task.outputs[0])
+CACHE_RESULTS=1
+COMPILE_ERRORS=2
+@conf
+def run_c_code(self,*k,**kw):
+	lst=[str(v)for(p,v)in kw.items()if p!='env']
+	h=Utils.h_list(lst)
+	dir=self.bldnode.abspath()+os.sep+(not Utils.is_win32 and'.'or'')+'conf_check_'+Utils.to_hex(h)
+	try:
+		os.makedirs(dir)
+	except OSError:
+		pass
+	try:
+		os.stat(dir)
+	except OSError:
+		self.fatal('cannot use the configuration test folder %r'%dir)
+	cachemode=getattr(Options.options,'confcache',None)
+	if cachemode==CACHE_RESULTS:
+		try:
+			proj=ConfigSet.ConfigSet(os.path.join(dir,'cache_run_c_code'))
+		except OSError:
+			pass
+		else:
+			ret=proj['cache_run_c_code']
+			if isinstance(ret,str)and ret.startswith('Test does not build'):
+				self.fatal(ret)
+			return ret
+	bdir=os.path.join(dir,'testbuild')
+	if not os.path.exists(bdir):
+		os.makedirs(bdir)
+	self.test_bld=bld=Build.BuildContext(top_dir=dir,out_dir=bdir)
+	bld.init_dirs()
+	bld.progress_bar=0
+	bld.targets='*'
+	if kw['compile_filename']:
+		node=bld.srcnode.make_node(kw['compile_filename'])
+		node.write(kw['code'])
+	bld.logger=self.logger
+	bld.all_envs.update(self.all_envs)
+	bld.env=kw['env']
+	o=bld(features=kw['features'],source=kw['compile_filename'],target='testprog')
+	for k,v in kw.items():
+		setattr(o,k,v)
+	self.to_log("==>\n%s\n<=="%kw['code'])
+	bld.targets='*'
+	ret=-1
+	try:
+		try:
+			bld.compile()
+		except Errors.WafError:
+			ret='Test does not build: %s'%Utils.ex_stack()
+			self.fatal(ret)
+		else:
+			ret=getattr(bld,'retval',0)
+	finally:
+		proj=ConfigSet.ConfigSet()
+		proj['cache_run_c_code']=ret
+		proj.store(os.path.join(dir,'cache_run_c_code'))
+	return ret
+@conf
+def check_cxx(self,*k,**kw):
+	kw['compiler']='cxx'
+	return self.check(*k,**kw)
+@conf
+def check_cc(self,*k,**kw):
+	kw['compiler']='c'
+	return self.check(*k,**kw)
+@conf
+def define(self,key,val,quote=True):
+	assert key and isinstance(key,str)
+	if val is True:
+		val=1
+	elif val in(False,None):
+		val=0
+	if isinstance(val,int)or isinstance(val,float):
+		s='%s=%s'
+	else:
+		s=quote and'%s="%s"'or'%s=%s'
+	app=s%(key,str(val))
+	ban=key+'='
+	lst=self.env['DEFINES']
+	for x in lst:
+		if x.startswith(ban):
+			lst[lst.index(x)]=app
+			break
+	else:
+		self.env.append_value('DEFINES',app)
+	self.env.append_unique(DEFKEYS,key)
+@conf
+def undefine(self,key):
+	assert key and isinstance(key,str)
+	ban=key+'='
+	lst=[x for x in self.env['DEFINES']if not x.startswith(ban)]
+	self.env['DEFINES']=lst
+	self.env.append_unique(DEFKEYS,key)
+@conf
+def define_cond(self,key,val):
+	assert key and isinstance(key,str)
+	if val:
+		self.define(key,1)
+	else:
+		self.undefine(key)
+@conf
+def is_defined(self,key):
+	assert key and isinstance(key,str)
+	ban=key+'='
+	for x in self.env['DEFINES']:
+		if x.startswith(ban):
+			return True
+	return False
+@conf
+def get_define(self,key):
+	assert key and isinstance(key,str)
+	ban=key+'='
+	for x in self.env['DEFINES']:
+		if x.startswith(ban):
+			return x[len(ban):]
+	return None
+@conf
+def have_define(self,key):
+	return(self.env.HAVE_PAT or'HAVE_%s')%Utils.quote_define_name(key)
+@conf
+def write_config_header(self,configfile='',guard='',top=False,env=None,defines=True,headers=False,remove=True,define_prefix=''):
+	if env:
+		Logs.warn('Cannot pass env to write_config_header')
+	if not configfile:configfile=WAF_CONFIG_H
+	waf_guard=guard or'W_%s_WAF'%Utils.quote_define_name(configfile)
+	node=top and self.bldnode or self.path.get_bld()
+	node=node.make_node(configfile)
+	node.parent.mkdir()
+	lst=['/* WARNING! All changes made to this file will be lost! */\n']
+	lst.append('#ifndef %s\n#define %s\n'%(waf_guard,waf_guard))
+	lst.append(self.get_config_header(defines,headers,define_prefix=define_prefix))
+	lst.append('\n#endif /* %s */\n'%waf_guard)
+	node.write('\n'.join(lst))
+	self.env.append_unique(Build.CFG_FILES,[node.abspath()])
+	if remove:
+		for key in self.env[DEFKEYS]:
+			self.undefine(key)
+		self.env[DEFKEYS]=[]
+@conf
+def get_config_header(self,defines=True,headers=False,define_prefix=''):
+	lst=[]
+	if headers:
+		for x in self.env[INCKEYS]:
+			lst.append('#include <%s>'%x)
+	if defines:
+		for x in self.env[DEFKEYS]:
+			if self.is_defined(x):
+				val=self.get_define(x)
+				lst.append('#define %s %s'%(define_prefix+x,val))
+			else:
+				lst.append('/* #undef %s */'%(define_prefix+x))
+	return"\n".join(lst)
+@conf
+def cc_add_flags(conf):
+	conf.add_os_flags('CPPFLAGS','CFLAGS')
+	conf.add_os_flags('CFLAGS')
+@conf
+def cxx_add_flags(conf):
+	conf.add_os_flags('CPPFLAGS','CXXFLAGS')
+	conf.add_os_flags('CXXFLAGS')
+@conf
+def link_add_flags(conf):
+	conf.add_os_flags('LINKFLAGS')
+	conf.add_os_flags('LDFLAGS','LINKFLAGS')
+@conf
+def cc_load_tools(conf):
+	if not conf.env.DEST_OS:
+		conf.env.DEST_OS=Utils.unversioned_sys_platform()
+	conf.load('c')
+@conf
+def cxx_load_tools(conf):
+	if not conf.env.DEST_OS:
+		conf.env.DEST_OS=Utils.unversioned_sys_platform()
+	conf.load('cxx')
+@conf
+def get_cc_version(conf,cc,gcc=False,icc=False):
+	cmd=cc+['-dM','-E','-']
+	env=conf.env.env or None
+	try:
+		p=Utils.subprocess.Popen(cmd,stdin=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE,stderr=Utils.subprocess.PIPE,env=env)
+		p.stdin.write('\n')
+		out=p.communicate()[0]
+	except Exception:
+		conf.fatal('Could not determine the compiler version %r'%cmd)
+	if not isinstance(out,str):
+		out=out.decode(sys.stdout.encoding or'iso8859-1')
+	if gcc:
+		if out.find('__INTEL_COMPILER')>=0:
+			conf.fatal('The intel compiler pretends to be gcc')
+		if out.find('__GNUC__')<0 and out.find('__clang__')<0:
+			conf.fatal('Could not determine the compiler type')
+	if icc and out.find('__INTEL_COMPILER')<0:
+		conf.fatal('Not icc/icpc')
+	k={}
+	if icc or gcc:
+		out=out.splitlines()
+		for line in out:
+			lst=shlex.split(line)
+			if len(lst)>2:
+				key=lst[1]
+				val=lst[2]
+				k[key]=val
+		def isD(var):
+			return var in k
+		def isT(var):
+			return var in k and k[var]!='0'
+		if not conf.env.DEST_OS:
+			conf.env.DEST_OS=''
+		for i in MACRO_TO_DESTOS:
+			if isD(i):
+				conf.env.DEST_OS=MACRO_TO_DESTOS[i]
+				break
+		else:
+			if isD('__APPLE__')and isD('__MACH__'):
+				conf.env.DEST_OS='darwin'
+			elif isD('__unix__'):
+				conf.env.DEST_OS='generic'
+		if isD('__ELF__'):
+			conf.env.DEST_BINFMT='elf'
+		elif isD('__WINNT__')or isD('__CYGWIN__')or isD('_WIN32'):
+			conf.env.DEST_BINFMT='pe'
+			conf.env.LIBDIR=conf.env.BINDIR
+		elif isD('__APPLE__'):
+			conf.env.DEST_BINFMT='mac-o'
+		if not conf.env.DEST_BINFMT:
+			conf.env.DEST_BINFMT=Utils.destos_to_binfmt(conf.env.DEST_OS)
+		for i in MACRO_TO_DEST_CPU:
+			if isD(i):
+				conf.env.DEST_CPU=MACRO_TO_DEST_CPU[i]
+				break
+		Logs.debug('ccroot: dest platform: '+' '.join([conf.env[x]or'?'for x in('DEST_OS','DEST_BINFMT','DEST_CPU')]))
+		if icc:
+			ver=k['__INTEL_COMPILER']
+			conf.env['CC_VERSION']=(ver[:-2],ver[-2],ver[-1])
+		else:
+			if isD('__clang__'):
+				conf.env['CC_VERSION']=(k['__clang_major__'],k['__clang_minor__'],k['__clang_patchlevel__'])
+			else:
+				conf.env['CC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
+	return k
+@conf
+def get_xlc_version(conf,cc):
+	cmd=cc+['-qversion']
+	try:
+		out,err=conf.cmd_and_log(cmd,output=0)
+	except Errors.WafError:
+		conf.fatal('Could not find xlc %r'%cmd)
+	for v in(r"IBM XL C/C\+\+.* V(?P<major>\d*)\.(?P<minor>\d*)",):
+		version_re=re.compile(v,re.I).search
+		match=version_re(out or err)
+		if match:
+			k=match.groupdict()
+			conf.env['CC_VERSION']=(k['major'],k['minor'])
+			break
+	else:
+		conf.fatal('Could not determine the XLC version.')
+@conf
+def add_as_needed(self):
+	if self.env.DEST_BINFMT=='elf'and'gcc'in(self.env.CXX_NAME,self.env.CC_NAME):
+		self.env.append_unique('LINKFLAGS','--as-needed')
+class cfgtask(Task.TaskBase):
+	def display(self):
+		return''
+	def runnable_status(self):
+		return Task.RUN_ME
+	def uid(self):
+		return Utils.SIG_NIL
+	def run(self):
+		conf=self.conf
+		bld=Build.BuildContext(top_dir=conf.srcnode.abspath(),out_dir=conf.bldnode.abspath())
+		bld.env=conf.env
+		bld.init_dirs()
+		bld.in_msg=1
+		bld.logger=self.logger
+		try:
+			bld.check(**self.args)
+		except Exception:
+			return 1
+@conf
+def multicheck(self,*k,**kw):
+	self.start_msg(kw.get('msg','Executing %d configuration tests'%len(k)))
+	class par(object):
+		def __init__(self):
+			self.keep=False
+			self.cache_global=Options.cache_global
+			self.nocache=Options.options.nocache
+			self.returned_tasks=[]
+			self.task_sigs={}
+		def total(self):
+			return len(tasks)
+		def to_log(self,*k,**kw):
+			return
+	bld=par()
+	tasks=[]
+	for dct in k:
+		x=cfgtask(bld=bld)
+		tasks.append(x)
+		x.args=dct
+		x.bld=bld
+		x.conf=self
+		x.args=dct
+		x.logger=Logs.make_mem_logger(str(id(x)),self.logger)
+	def it():
+		yield tasks
+		while 1:
+			yield[]
+	p=Runner.Parallel(bld,Options.options.jobs)
+	p.biter=it()
+	p.start()
+	for x in tasks:
+		x.logger.memhandler.flush()
+	for x in tasks:
+		if x.hasrun!=Task.SUCCESS:
+			self.end_msg(kw.get('errmsg','no'),color='YELLOW')
+			self.fatal(kw.get('fatalmsg',None)or'One of the tests has failed, see the config.log for more information')
+	self.end_msg('ok')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_config.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_config.pyc
new file mode 100644
index 0000000..ff3de86
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_config.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_osx.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_osx.py
new file mode 100644
index 0000000..579b2a7
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_osx.py
@@ -0,0 +1,120 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,shutil,sys,platform
+from waflib import TaskGen,Task,Build,Options,Utils,Errors
+from waflib.TaskGen import taskgen_method,feature,after_method,before_method
+app_info='''
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleGetInfoString</key>
+	<string>Created by Waf</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>NOTE</key>
+	<string>THIS IS A GENERATED FILE, DO NOT MODIFY</string>
+	<key>CFBundleExecutable</key>
+	<string>%s</string>
+</dict>
+</plist>
+'''
+@feature('c','cxx')
+def set_macosx_deployment_target(self):
+	if self.env['MACOSX_DEPLOYMENT_TARGET']:
+		os.environ['MACOSX_DEPLOYMENT_TARGET']=self.env['MACOSX_DEPLOYMENT_TARGET']
+	elif'MACOSX_DEPLOYMENT_TARGET'not in os.environ:
+		if Utils.unversioned_sys_platform()=='darwin':
+			os.environ['MACOSX_DEPLOYMENT_TARGET']='.'.join(platform.mac_ver()[0].split('.')[:2])
+@taskgen_method
+def create_bundle_dirs(self,name,out):
+	bld=self.bld
+	dir=out.parent.find_or_declare(name)
+	dir.mkdir()
+	macos=dir.find_or_declare(['Contents','MacOS'])
+	macos.mkdir()
+	return dir
+def bundle_name_for_output(out):
+	name=out.name
+	k=name.rfind('.')
+	if k>=0:
+		name=name[:k]+'.app'
+	else:
+		name=name+'.app'
+	return name
+@feature('cprogram','cxxprogram')
+@after_method('apply_link')
+def create_task_macapp(self):
+	if self.env['MACAPP']or getattr(self,'mac_app',False):
+		out=self.link_task.outputs[0]
+		name=bundle_name_for_output(out)
+		dir=self.create_bundle_dirs(name,out)
+		n1=dir.find_or_declare(['Contents','MacOS',out.name])
+		self.apptask=self.create_task('macapp',self.link_task.outputs,n1)
+		inst_to=getattr(self,'install_path','/Applications')+'/%s/Contents/MacOS/'%name
+		self.bld.install_files(inst_to,n1,chmod=Utils.O755)
+		if getattr(self,'mac_resources',None):
+			res_dir=n1.parent.parent.make_node('Resources')
+			inst_to=getattr(self,'install_path','/Applications')+'/%s/Resources'%name
+			for x in self.to_list(self.mac_resources):
+				node=self.path.find_node(x)
+				if not node:
+					raise Errors.WafError('Missing mac_resource %r in %r'%(x,self))
+				parent=node.parent
+				if os.path.isdir(node.abspath()):
+					nodes=node.ant_glob('**')
+				else:
+					nodes=[node]
+				for node in nodes:
+					rel=node.path_from(parent)
+					tsk=self.create_task('macapp',node,res_dir.make_node(rel))
+					self.bld.install_as(inst_to+'/%s'%rel,node)
+		if getattr(self.bld,'is_install',None):
+			self.install_task.hasrun=Task.SKIP_ME
+@feature('cprogram','cxxprogram')
+@after_method('apply_link')
+def create_task_macplist(self):
+	if self.env['MACAPP']or getattr(self,'mac_app',False):
+		out=self.link_task.outputs[0]
+		name=bundle_name_for_output(out)
+		dir=self.create_bundle_dirs(name,out)
+		n1=dir.find_or_declare(['Contents','Info.plist'])
+		self.plisttask=plisttask=self.create_task('macplist',[],n1)
+		if getattr(self,'mac_plist',False):
+			node=self.path.find_resource(self.mac_plist)
+			if node:
+				plisttask.inputs.append(node)
+			else:
+				plisttask.code=self.mac_plist
+		else:
+			plisttask.code=app_info%self.link_task.outputs[0].name
+		inst_to=getattr(self,'install_path','/Applications')+'/%s/Contents/'%name
+		self.bld.install_files(inst_to,n1)
+@feature('cshlib','cxxshlib')
+@before_method('apply_link','propagate_uselib_vars')
+def apply_bundle(self):
+	if self.env['MACBUNDLE']or getattr(self,'mac_bundle',False):
+		self.env['LINKFLAGS_cshlib']=self.env['LINKFLAGS_cxxshlib']=[]
+		self.env['cshlib_PATTERN']=self.env['cxxshlib_PATTERN']=self.env['macbundle_PATTERN']
+		use=self.use=self.to_list(getattr(self,'use',[]))
+		if not'MACBUNDLE'in use:
+			use.append('MACBUNDLE')
+app_dirs=['Contents','Contents/MacOS','Contents/Resources']
+class macapp(Task.Task):
+	color='PINK'
+	def run(self):
+		self.outputs[0].parent.mkdir()
+		shutil.copy2(self.inputs[0].srcpath(),self.outputs[0].abspath())
+class macplist(Task.Task):
+	color='PINK'
+	ext_in=['.bin']
+	def run(self):
+		if getattr(self,'code',None):
+			txt=self.code
+		else:
+			txt=self.inputs[0].read()
+		self.outputs[0].write(txt)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_osx.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_osx.pyc
new file mode 100644
index 0000000..9684318
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_osx.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_preproc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_preproc.py
new file mode 100644
index 0000000..dc6453b
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_preproc.py
@@ -0,0 +1,604 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re,string,traceback
+from waflib import Logs,Utils,Errors
+from waflib.Logs import debug,error
+class PreprocError(Errors.WafError):
+	pass
+POPFILE='-'
+recursion_limit=150
+go_absolute=False
+standard_includes=['/usr/include']
+if Utils.is_win32:
+	standard_includes=[]
+use_trigraphs=0
+strict_quotes=0
+g_optrans={'not':'!','and':'&&','bitand':'&','and_eq':'&=','or':'||','bitor':'|','or_eq':'|=','xor':'^','xor_eq':'^=','compl':'~',}
+re_lines=re.compile('^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$',re.IGNORECASE|re.MULTILINE)
+re_mac=re.compile("^[a-zA-Z_]\w*")
+re_fun=re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]')
+re_pragma_once=re.compile('^\s*once\s*',re.IGNORECASE)
+re_nl=re.compile('\\\\\r*\n',re.MULTILINE)
+re_cpp=re.compile(r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',re.DOTALL|re.MULTILINE)
+trig_def=[('??'+a,b)for a,b in zip("=-/!'()<>",r'#~\|^[]{}')]
+chr_esc={'0':0,'a':7,'b':8,'t':9,'n':10,'f':11,'v':12,'r':13,'\\':92,"'":39}
+NUM='i'
+OP='O'
+IDENT='T'
+STR='s'
+CHAR='c'
+tok_types=[NUM,STR,IDENT,OP]
+exp_types=[r"""0[xX](?P<hex>[a-fA-F0-9]+)(?P<qual1>[uUlL]*)|L*?'(?P<char>(\\.|[^\\'])+)'|(?P<n1>\d+)[Ee](?P<exp0>[+-]*?\d+)(?P<float0>[fFlL]*)|(?P<n2>\d*\.\d+)([Ee](?P<exp1>[+-]*?\d+))?(?P<float1>[fFlL]*)|(?P<n4>\d+\.\d*)([Ee](?P<exp2>[+-]*?\d+))?(?P<float2>[fFlL]*)|(?P<oct>0*)(?P<n0>\d+)(?P<qual2>[uUlL]*)""",r'L?"([^"\\]|\\.)*"',r'[a-zA-Z_]\w*',r'%:%:|<<=|>>=|\.\.\.|<<|<%|<:|<=|>>|>=|\+\+|\+=|--|->|-=|\*=|/=|%:|%=|%>|==|&&|&=|\|\||\|=|\^=|:>|!=|##|[\(\)\{\}\[\]<>\?\|\^\*\+&=:!#;,%/\-\?\~\.]',]
+re_clexer=re.compile('|'.join(["(?P<%s>%s)"%(name,part)for name,part in zip(tok_types,exp_types)]),re.M)
+accepted='a'
+ignored='i'
+undefined='u'
+skipped='s'
+def repl(m):
+	s=m.group(0)
+	if s.startswith('/'):
+		return' '
+	return s
+def filter_comments(filename):
+	code=Utils.readf(filename)
+	if use_trigraphs:
+		for(a,b)in trig_def:code=code.split(a).join(b)
+	code=re_nl.sub('',code)
+	code=re_cpp.sub(repl,code)
+	return[(m.group(2),m.group(3))for m in re.finditer(re_lines,code)]
+prec={}
+ops=['* / %','+ -','<< >>','< <= >= >','== !=','& | ^','&& ||',',']
+for x in range(len(ops)):
+	syms=ops[x]
+	for u in syms.split():
+		prec[u]=x
+def trimquotes(s):
+	if not s:return''
+	s=s.rstrip()
+	if s[0]=="'"and s[-1]=="'":return s[1:-1]
+	return s
+def reduce_nums(val_1,val_2,val_op):
+	try:a=0+val_1
+	except TypeError:a=int(val_1)
+	try:b=0+val_2
+	except TypeError:b=int(val_2)
+	d=val_op
+	if d=='%':c=a%b
+	elif d=='+':c=a+b
+	elif d=='-':c=a-b
+	elif d=='*':c=a*b
+	elif d=='/':c=a/b
+	elif d=='^':c=a^b
+	elif d=='|':c=a|b
+	elif d=='||':c=int(a or b)
+	elif d=='&':c=a&b
+	elif d=='&&':c=int(a and b)
+	elif d=='==':c=int(a==b)
+	elif d=='!=':c=int(a!=b)
+	elif d=='<=':c=int(a<=b)
+	elif d=='<':c=int(a<b)
+	elif d=='>':c=int(a>b)
+	elif d=='>=':c=int(a>=b)
+	elif d=='^':c=int(a^b)
+	elif d=='<<':c=a<<b
+	elif d=='>>':c=a>>b
+	else:c=0
+	return c
+def get_num(lst):
+	if not lst:raise PreprocError("empty list for get_num")
+	(p,v)=lst[0]
+	if p==OP:
+		if v=='(':
+			count_par=1
+			i=1
+			while i<len(lst):
+				(p,v)=lst[i]
+				if p==OP:
+					if v==')':
+						count_par-=1
+						if count_par==0:
+							break
+					elif v=='(':
+						count_par+=1
+				i+=1
+			else:
+				raise PreprocError("rparen expected %r"%lst)
+			(num,_)=get_term(lst[1:i])
+			return(num,lst[i+1:])
+		elif v=='+':
+			return get_num(lst[1:])
+		elif v=='-':
+			num,lst=get_num(lst[1:])
+			return(reduce_nums('-1',num,'*'),lst)
+		elif v=='!':
+			num,lst=get_num(lst[1:])
+			return(int(not int(num)),lst)
+		elif v=='~':
+			num,lst=get_num(lst[1:])
+			return(~int(num),lst)
+		else:
+			raise PreprocError("Invalid op token %r for get_num"%lst)
+	elif p==NUM:
+		return v,lst[1:]
+	elif p==IDENT:
+		return 0,lst[1:]
+	else:
+		raise PreprocError("Invalid token %r for get_num"%lst)
+def get_term(lst):
+	if not lst:raise PreprocError("empty list for get_term")
+	num,lst=get_num(lst)
+	if not lst:
+		return(num,[])
+	(p,v)=lst[0]
+	if p==OP:
+		if v==',':
+			return get_term(lst[1:])
+		elif v=='?':
+			count_par=0
+			i=1
+			while i<len(lst):
+				(p,v)=lst[i]
+				if p==OP:
+					if v==')':
+						count_par-=1
+					elif v=='(':
+						count_par+=1
+					elif v==':':
+						if count_par==0:
+							break
+				i+=1
+			else:
+				raise PreprocError("rparen expected %r"%lst)
+			if int(num):
+				return get_term(lst[1:i])
+			else:
+				return get_term(lst[i+1:])
+		else:
+			num2,lst=get_num(lst[1:])
+			if not lst:
+				num2=reduce_nums(num,num2,v)
+				return get_term([(NUM,num2)]+lst)
+			p2,v2=lst[0]
+			if p2!=OP:
+				raise PreprocError("op expected %r"%lst)
+			if prec[v2]>=prec[v]:
+				num2=reduce_nums(num,num2,v)
+				return get_term([(NUM,num2)]+lst)
+			else:
+				num3,lst=get_num(lst[1:])
+				num3=reduce_nums(num2,num3,v2)
+				return get_term([(NUM,num),(p,v),(NUM,num3)]+lst)
+	raise PreprocError("cannot reduce %r"%lst)
+def reduce_eval(lst):
+	num,lst=get_term(lst)
+	return(NUM,num)
+def stringize(lst):
+	lst=[str(v2)for(p2,v2)in lst]
+	return"".join(lst)
+def paste_tokens(t1,t2):
+	p1=None
+	if t1[0]==OP and t2[0]==OP:
+		p1=OP
+	elif t1[0]==IDENT and(t2[0]==IDENT or t2[0]==NUM):
+		p1=IDENT
+	elif t1[0]==NUM and t2[0]==NUM:
+		p1=NUM
+	if not p1:
+		raise PreprocError('tokens do not make a valid paste %r and %r'%(t1,t2))
+	return(p1,t1[1]+t2[1])
+def reduce_tokens(lst,defs,ban=[]):
+	i=0
+	while i<len(lst):
+		(p,v)=lst[i]
+		if p==IDENT and v=="defined":
+			del lst[i]
+			if i<len(lst):
+				(p2,v2)=lst[i]
+				if p2==IDENT:
+					if v2 in defs:
+						lst[i]=(NUM,1)
+					else:
+						lst[i]=(NUM,0)
+				elif p2==OP and v2=='(':
+					del lst[i]
+					(p2,v2)=lst[i]
+					del lst[i]
+					if v2 in defs:
+						lst[i]=(NUM,1)
+					else:
+						lst[i]=(NUM,0)
+				else:
+					raise PreprocError("Invalid define expression %r"%lst)
+		elif p==IDENT and v in defs:
+			if isinstance(defs[v],str):
+				a,b=extract_macro(defs[v])
+				defs[v]=b
+			macro_def=defs[v]
+			to_add=macro_def[1]
+			if isinstance(macro_def[0],list):
+				del lst[i]
+				accu=to_add[:]
+				reduce_tokens(accu,defs,ban+[v])
+				for x in range(len(accu)):
+					lst.insert(i,accu[x])
+					i+=1
+			else:
+				args=[]
+				del lst[i]
+				if i>=len(lst):
+					raise PreprocError("expected '(' after %r (got nothing)"%v)
+				(p2,v2)=lst[i]
+				if p2!=OP or v2!='(':
+					raise PreprocError("expected '(' after %r"%v)
+				del lst[i]
+				one_param=[]
+				count_paren=0
+				while i<len(lst):
+					p2,v2=lst[i]
+					del lst[i]
+					if p2==OP and count_paren==0:
+						if v2=='(':
+							one_param.append((p2,v2))
+							count_paren+=1
+						elif v2==')':
+							if one_param:args.append(one_param)
+							break
+						elif v2==',':
+							if not one_param:raise PreprocError("empty param in funcall %s"%p)
+							args.append(one_param)
+							one_param=[]
+						else:
+							one_param.append((p2,v2))
+					else:
+						one_param.append((p2,v2))
+						if v2=='(':count_paren+=1
+						elif v2==')':count_paren-=1
+				else:
+					raise PreprocError('malformed macro')
+				accu=[]
+				arg_table=macro_def[0]
+				j=0
+				while j<len(to_add):
+					(p2,v2)=to_add[j]
+					if p2==OP and v2=='#':
+						if j+1<len(to_add)and to_add[j+1][0]==IDENT and to_add[j+1][1]in arg_table:
+							toks=args[arg_table[to_add[j+1][1]]]
+							accu.append((STR,stringize(toks)))
+							j+=1
+						else:
+							accu.append((p2,v2))
+					elif p2==OP and v2=='##':
+						if accu and j+1<len(to_add):
+							t1=accu[-1]
+							if to_add[j+1][0]==IDENT and to_add[j+1][1]in arg_table:
+								toks=args[arg_table[to_add[j+1][1]]]
+								if toks:
+									accu[-1]=paste_tokens(t1,toks[0])
+									accu.extend(toks[1:])
+								else:
+									accu.append((p2,v2))
+									accu.extend(toks)
+							elif to_add[j+1][0]==IDENT and to_add[j+1][1]=='__VA_ARGS__':
+								va_toks=[]
+								st=len(macro_def[0])
+								pt=len(args)
+								for x in args[pt-st+1:]:
+									va_toks.extend(x)
+									va_toks.append((OP,','))
+								if va_toks:va_toks.pop()
+								if len(accu)>1:
+									(p3,v3)=accu[-1]
+									(p4,v4)=accu[-2]
+									if v3=='##':
+										accu.pop()
+										if v4==','and pt<st:
+											accu.pop()
+								accu+=va_toks
+							else:
+								accu[-1]=paste_tokens(t1,to_add[j+1])
+							j+=1
+						else:
+							accu.append((p2,v2))
+					elif p2==IDENT and v2 in arg_table:
+						toks=args[arg_table[v2]]
+						reduce_tokens(toks,defs,ban+[v])
+						accu.extend(toks)
+					else:
+						accu.append((p2,v2))
+					j+=1
+				reduce_tokens(accu,defs,ban+[v])
+				for x in range(len(accu)-1,-1,-1):
+					lst.insert(i,accu[x])
+		i+=1
+def eval_macro(lst,defs):
+	reduce_tokens(lst,defs,[])
+	if not lst:raise PreprocError("missing tokens to evaluate")
+	(p,v)=reduce_eval(lst)
+	return int(v)!=0
+def extract_macro(txt):
+	t=tokenize(txt)
+	if re_fun.search(txt):
+		p,name=t[0]
+		p,v=t[1]
+		if p!=OP:raise PreprocError("expected open parenthesis")
+		i=1
+		pindex=0
+		params={}
+		prev='('
+		while 1:
+			i+=1
+			p,v=t[i]
+			if prev=='(':
+				if p==IDENT:
+					params[v]=pindex
+					pindex+=1
+					prev=p
+				elif p==OP and v==')':
+					break
+				else:
+					raise PreprocError("unexpected token (3)")
+			elif prev==IDENT:
+				if p==OP and v==',':
+					prev=v
+				elif p==OP and v==')':
+					break
+				else:
+					raise PreprocError("comma or ... expected")
+			elif prev==',':
+				if p==IDENT:
+					params[v]=pindex
+					pindex+=1
+					prev=p
+				elif p==OP and v=='...':
+					raise PreprocError("not implemented (1)")
+				else:
+					raise PreprocError("comma or ... expected (2)")
+			elif prev=='...':
+				raise PreprocError("not implemented (2)")
+			else:
+				raise PreprocError("unexpected else")
+		return(name,[params,t[i+1:]])
+	else:
+		(p,v)=t[0]
+		return(v,[[],t[1:]])
+re_include=re.compile('^\s*(<(?P<a>.*)>|"(?P<b>.*)")')
+def extract_include(txt,defs):
+	m=re_include.search(txt)
+	if m:
+		if m.group('a'):return'<',m.group('a')
+		if m.group('b'):return'"',m.group('b')
+	toks=tokenize(txt)
+	reduce_tokens(toks,defs,['waf_include'])
+	if not toks:
+		raise PreprocError("could not parse include %s"%txt)
+	if len(toks)==1:
+		if toks[0][0]==STR:
+			return'"',toks[0][1]
+	else:
+		if toks[0][1]=='<'and toks[-1][1]=='>':
+			return stringize(toks).lstrip('<').rstrip('>')
+	raise PreprocError("could not parse include %s."%txt)
+def parse_char(txt):
+	if not txt:raise PreprocError("attempted to parse a null char")
+	if txt[0]!='\\':
+		return ord(txt)
+	c=txt[1]
+	if c=='x':
+		if len(txt)==4 and txt[3]in string.hexdigits:return int(txt[2:],16)
+		return int(txt[2:],16)
+	elif c.isdigit():
+		if c=='0'and len(txt)==2:return 0
+		for i in 3,2,1:
+			if len(txt)>i and txt[1:1+i].isdigit():
+				return(1+i,int(txt[1:1+i],8))
+	else:
+		try:return chr_esc[c]
+		except KeyError:raise PreprocError("could not parse char literal '%s'"%txt)
+def tokenize(s):
+	return tokenize_private(s)[:]
+@Utils.run_once
+def tokenize_private(s):
+	ret=[]
+	for match in re_clexer.finditer(s):
+		m=match.group
+		for name in tok_types:
+			v=m(name)
+			if v:
+				if name==IDENT:
+					try:v=g_optrans[v];name=OP
+					except KeyError:
+						if v.lower()=="true":
+							v=1
+							name=NUM
+						elif v.lower()=="false":
+							v=0
+							name=NUM
+				elif name==NUM:
+					if m('oct'):v=int(v,8)
+					elif m('hex'):v=int(m('hex'),16)
+					elif m('n0'):v=m('n0')
+					else:
+						v=m('char')
+						if v:v=parse_char(v)
+						else:v=m('n2')or m('n4')
+				elif name==OP:
+					if v=='%:':v='#'
+					elif v=='%:%:':v='##'
+				elif name==STR:
+					v=v[1:-1]
+				ret.append((name,v))
+				break
+	return ret
+@Utils.run_once
+def define_name(line):
+	return re_mac.match(line).group(0)
+class c_parser(object):
+	def __init__(self,nodepaths=None,defines=None):
+		self.lines=[]
+		if defines is None:
+			self.defs={}
+		else:
+			self.defs=dict(defines)
+		self.state=[]
+		self.count_files=0
+		self.currentnode_stack=[]
+		self.nodepaths=nodepaths or[]
+		self.nodes=[]
+		self.names=[]
+		self.curfile=''
+		self.ban_includes=set([])
+	def cached_find_resource(self,node,filename):
+		try:
+			nd=node.ctx.cache_nd
+		except AttributeError:
+			nd=node.ctx.cache_nd={}
+		tup=(node,filename)
+		try:
+			return nd[tup]
+		except KeyError:
+			ret=node.find_resource(filename)
+			if ret:
+				if getattr(ret,'children',None):
+					ret=None
+				elif ret.is_child_of(node.ctx.bldnode):
+					tmp=node.ctx.srcnode.search_node(ret.path_from(node.ctx.bldnode))
+					if tmp and getattr(tmp,'children',None):
+						ret=None
+			nd[tup]=ret
+			return ret
+	def tryfind(self,filename):
+		self.curfile=filename
+		found=self.cached_find_resource(self.currentnode_stack[-1],filename)
+		for n in self.nodepaths:
+			if found:
+				break
+			found=self.cached_find_resource(n,filename)
+		if found and not found in self.ban_includes:
+			self.nodes.append(found)
+			if filename[-4:]!='.moc':
+				self.addlines(found)
+		else:
+			if not filename in self.names:
+				self.names.append(filename)
+		return found
+	def addlines(self,node):
+		self.currentnode_stack.append(node.parent)
+		filepath=node.abspath()
+		self.count_files+=1
+		if self.count_files>recursion_limit:
+			raise PreprocError("recursion limit exceeded")
+		pc=self.parse_cache
+		debug('preproc: reading file %r',filepath)
+		try:
+			lns=pc[filepath]
+		except KeyError:
+			pass
+		else:
+			self.lines.extend(lns)
+			return
+		try:
+			lines=filter_comments(filepath)
+			lines.append((POPFILE,''))
+			lines.reverse()
+			pc[filepath]=lines
+			self.lines.extend(lines)
+		except IOError:
+			raise PreprocError("could not read the file %s"%filepath)
+		except Exception:
+			if Logs.verbose>0:
+				error("parsing %s failed"%filepath)
+				traceback.print_exc()
+	def start(self,node,env):
+		debug('preproc: scanning %s (in %s)',node.name,node.parent.name)
+		bld=node.ctx
+		try:
+			self.parse_cache=bld.parse_cache
+		except AttributeError:
+			bld.parse_cache={}
+			self.parse_cache=bld.parse_cache
+		self.current_file=node
+		self.addlines(node)
+		if env['DEFINES']:
+			try:
+				lst=['%s %s'%(x[0],trimquotes('='.join(x[1:])))for x in[y.split('=')for y in env['DEFINES']]]
+				lst.reverse()
+				self.lines.extend([('define',x)for x in lst])
+			except AttributeError:
+				pass
+		while self.lines:
+			(token,line)=self.lines.pop()
+			if token==POPFILE:
+				self.count_files-=1
+				self.currentnode_stack.pop()
+				continue
+			try:
+				ve=Logs.verbose
+				if ve:debug('preproc: line is %s - %s state is %s',token,line,self.state)
+				state=self.state
+				if token[:2]=='if':
+					state.append(undefined)
+				elif token=='endif':
+					state.pop()
+				if token[0]!='e':
+					if skipped in self.state or ignored in self.state:
+						continue
+				if token=='if':
+					ret=eval_macro(tokenize(line),self.defs)
+					if ret:state[-1]=accepted
+					else:state[-1]=ignored
+				elif token=='ifdef':
+					m=re_mac.match(line)
+					if m and m.group(0)in self.defs:state[-1]=accepted
+					else:state[-1]=ignored
+				elif token=='ifndef':
+					m=re_mac.match(line)
+					if m and m.group(0)in self.defs:state[-1]=ignored
+					else:state[-1]=accepted
+				elif token=='include'or token=='import':
+					(kind,inc)=extract_include(line,self.defs)
+					if ve:debug('preproc: include found %s    (%s) ',inc,kind)
+					if kind=='"'or not strict_quotes:
+						self.current_file=self.tryfind(inc)
+						if token=='import':
+							self.ban_includes.add(self.current_file)
+				elif token=='elif':
+					if state[-1]==accepted:
+						state[-1]=skipped
+					elif state[-1]==ignored:
+						if eval_macro(tokenize(line),self.defs):
+							state[-1]=accepted
+				elif token=='else':
+					if state[-1]==accepted:state[-1]=skipped
+					elif state[-1]==ignored:state[-1]=accepted
+				elif token=='define':
+					try:
+						self.defs[define_name(line)]=line
+					except Exception:
+						raise PreprocError("Invalid define line %s"%line)
+				elif token=='undef':
+					m=re_mac.match(line)
+					if m and m.group(0)in self.defs:
+						self.defs.__delitem__(m.group(0))
+				elif token=='pragma':
+					if re_pragma_once.match(line.lower()):
+						self.ban_includes.add(self.current_file)
+			except Exception ,e:
+				if Logs.verbose:
+					debug('preproc: line parsing failed (%s): %s %s',e,line,Utils.ex_stack())
+def scan(task):
+	global go_absolute
+	try:
+		incn=task.generator.includes_nodes
+	except AttributeError:
+		raise Errors.WafError('%r is missing a feature such as "c", "cxx" or "includes": '%task.generator)
+	if go_absolute:
+		nodepaths=incn+[task.generator.bld.root.find_dir(x)for x in standard_includes]
+	else:
+		nodepaths=[x for x in incn if x.is_child_of(x.ctx.srcnode)or x.is_child_of(x.ctx.bldnode)]
+	tmp=c_parser(nodepaths)
+	tmp.start(task.inputs[0],task.env)
+	if Logs.verbose:
+		debug('deps: deps for %r: %r; unresolved %r'%(task.inputs,tmp.nodes,tmp.names))
+	return(tmp.nodes,tmp.names)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_preproc.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_preproc.pyc
new file mode 100644
index 0000000..c375610
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_preproc.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_tests.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_tests.py
new file mode 100644
index 0000000..f275977
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_tests.py
@@ -0,0 +1,153 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Task
+from waflib.Configure import conf
+from waflib.TaskGen import feature,before_method,after_method
+import sys
+LIB_CODE='''
+#ifdef _MSC_VER
+#define testEXPORT __declspec(dllexport)
+#else
+#define testEXPORT
+#endif
+testEXPORT int lib_func(void) { return 9; }
+'''
+MAIN_CODE='''
+#ifdef _MSC_VER
+#define testEXPORT __declspec(dllimport)
+#else
+#define testEXPORT
+#endif
+testEXPORT int lib_func(void);
+int main(int argc, char **argv) {
+	(void)argc; (void)argv;
+	return !(lib_func() == 9);
+}
+'''
+@feature('link_lib_test')
+@before_method('process_source')
+def link_lib_test_fun(self):
+	def write_test_file(task):
+		task.outputs[0].write(task.generator.code)
+	rpath=[]
+	if getattr(self,'add_rpath',False):
+		rpath=[self.bld.path.get_bld().abspath()]
+	mode=self.mode
+	m='%s %s'%(mode,mode)
+	ex=self.test_exec and'test_exec'or''
+	bld=self.bld
+	bld(rule=write_test_file,target='test.'+mode,code=LIB_CODE)
+	bld(rule=write_test_file,target='main.'+mode,code=MAIN_CODE)
+	bld(features='%sshlib'%m,source='test.'+mode,target='test')
+	bld(features='%sprogram %s'%(m,ex),source='main.'+mode,target='app',use='test',rpath=rpath)
+@conf
+def check_library(self,mode=None,test_exec=True):
+	if not mode:
+		mode='c'
+		if self.env.CXX:
+			mode='cxx'
+	self.check(compile_filename=[],features='link_lib_test',msg='Checking for libraries',mode=mode,test_exec=test_exec,)
+INLINE_CODE='''
+typedef int foo_t;
+static %s foo_t static_foo () {return 0; }
+%s foo_t foo () {
+	return 0;
+}
+'''
+INLINE_VALUES=['inline','__inline__','__inline']
+@conf
+def check_inline(self,**kw):
+	self.start_msg('Checking for inline')
+	if not'define_name'in kw:
+		kw['define_name']='INLINE_MACRO'
+	if not'features'in kw:
+		if self.env.CXX:
+			kw['features']=['cxx']
+		else:
+			kw['features']=['c']
+	for x in INLINE_VALUES:
+		kw['fragment']=INLINE_CODE%(x,x)
+		try:
+			self.check(**kw)
+		except self.errors.ConfigurationError:
+			continue
+		else:
+			self.end_msg(x)
+			if x!='inline':
+				self.define('inline',x,quote=False)
+			return x
+	self.fatal('could not use inline functions')
+LARGE_FRAGMENT='''#include <unistd.h>
+int main(int argc, char **argv) {
+	(void)argc; (void)argv;
+	return !(sizeof(off_t) >= 8);
+}
+'''
+@conf
+def check_large_file(self,**kw):
+	if not'define_name'in kw:
+		kw['define_name']='HAVE_LARGEFILE'
+	if not'execute'in kw:
+		kw['execute']=True
+	if not'features'in kw:
+		if self.env.CXX:
+			kw['features']=['cxx','cxxprogram']
+		else:
+			kw['features']=['c','cprogram']
+	kw['fragment']=LARGE_FRAGMENT
+	kw['msg']='Checking for large file support'
+	ret=True
+	try:
+		if self.env.DEST_BINFMT!='pe':
+			ret=self.check(**kw)
+	except self.errors.ConfigurationError:
+		pass
+	else:
+		if ret:
+			return True
+	kw['msg']='Checking for -D_FILE_OFFSET_BITS=64'
+	kw['defines']=['_FILE_OFFSET_BITS=64']
+	try:
+		ret=self.check(**kw)
+	except self.errors.ConfigurationError:
+		pass
+	else:
+		self.define('_FILE_OFFSET_BITS',64)
+		return ret
+	self.fatal('There is no support for large files')
+ENDIAN_FRAGMENT='''
+short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+int use_ascii (int i) {
+	return ascii_mm[i] + ascii_ii[i];
+}
+short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+int use_ebcdic (int i) {
+	return ebcdic_mm[i] + ebcdic_ii[i];
+}
+extern int foo;
+'''
+class grep_for_endianness(Task.Task):
+	color='PINK'
+	def run(self):
+		txt=self.inputs[0].read(flags='rb').decode('iso8859-1')
+		if txt.find('LiTTleEnDian')>-1:
+			self.generator.tmp.append('little')
+		elif txt.find('BIGenDianSyS')>-1:
+			self.generator.tmp.append('big')
+		else:
+			return-1
+@feature('grep_for_endianness')
+@after_method('process_source')
+def grep_for_endianness_fun(self):
+	self.create_task('grep_for_endianness',self.compiled_tasks[0].outputs[0])
+@conf
+def check_endianness(self):
+	tmp=[]
+	def check_msg(self):
+		return tmp[0]
+	self.check(fragment=ENDIAN_FRAGMENT,features='c grep_for_endianness',msg="Checking for endianness",define='ENDIANNESS',tmp=tmp,okmsg=check_msg)
+	return tmp[0]
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_tests.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_tests.pyc
new file mode 100644
index 0000000..ed42588
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/c_tests.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ccroot.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ccroot.py
new file mode 100644
index 0000000..3fa7084
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ccroot.py
@@ -0,0 +1,396 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,re
+from waflib import Task,Utils,Node,Errors
+from waflib.TaskGen import after_method,before_method,feature,taskgen_method,extension
+from waflib.Tools import c_aliases,c_preproc,c_config,c_osx,c_tests
+from waflib.Configure import conf
+SYSTEM_LIB_PATHS=['/usr/lib64','/usr/lib','/usr/local/lib64','/usr/local/lib']
+USELIB_VARS=Utils.defaultdict(set)
+USELIB_VARS['c']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CCDEPS','CFLAGS','ARCH'])
+USELIB_VARS['cxx']=set(['INCLUDES','FRAMEWORKPATH','DEFINES','CPPFLAGS','CXXDEPS','CXXFLAGS','ARCH'])
+USELIB_VARS['d']=set(['INCLUDES','DFLAGS'])
+USELIB_VARS['includes']=set(['INCLUDES','FRAMEWORKPATH','ARCH'])
+USELIB_VARS['cprogram']=USELIB_VARS['cxxprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH'])
+USELIB_VARS['cshlib']=USELIB_VARS['cxxshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS','FRAMEWORK','FRAMEWORKPATH','ARCH'])
+USELIB_VARS['cstlib']=USELIB_VARS['cxxstlib']=set(['ARFLAGS','LINKDEPS'])
+USELIB_VARS['dprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+USELIB_VARS['dshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+USELIB_VARS['dstlib']=set(['ARFLAGS','LINKDEPS'])
+USELIB_VARS['asm']=set(['ASFLAGS'])
+@taskgen_method
+def create_compiled_task(self,name,node):
+	out='%s.%d.o'%(node.name,self.idx)
+	task=self.create_task(name,node,node.parent.find_or_declare(out))
+	try:
+		self.compiled_tasks.append(task)
+	except AttributeError:
+		self.compiled_tasks=[task]
+	return task
+@taskgen_method
+def to_incnodes(self,inlst):
+	lst=[]
+	seen=set([])
+	for x in self.to_list(inlst):
+		if x in seen or not x:
+			continue
+		seen.add(x)
+		if isinstance(x,Node.Node):
+			lst.append(x)
+		else:
+			if os.path.isabs(x):
+				lst.append(self.bld.root.make_node(x)or x)
+			else:
+				if x[0]=='#':
+					p=self.bld.bldnode.make_node(x[1:])
+					v=self.bld.srcnode.make_node(x[1:])
+				else:
+					p=self.path.get_bld().make_node(x)
+					v=self.path.make_node(x)
+				if p.is_child_of(self.bld.bldnode):
+					p.mkdir()
+				lst.append(p)
+				lst.append(v)
+	return lst
+@feature('c','cxx','d','asm','fc','includes')
+@after_method('propagate_uselib_vars','process_source')
+def apply_incpaths(self):
+	lst=self.to_incnodes(self.to_list(getattr(self,'includes',[]))+self.env['INCLUDES'])
+	self.includes_nodes=lst
+	self.env['INCPATHS']=[x.abspath()for x in lst]
+class link_task(Task.Task):
+	color='YELLOW'
+	inst_to=None
+	chmod=Utils.O755
+	def add_target(self,target):
+		if isinstance(target,str):
+			pattern=self.env[self.__class__.__name__+'_PATTERN']
+			if not pattern:
+				pattern='%s'
+			folder,name=os.path.split(target)
+			if self.__class__.__name__.find('shlib')>0:
+				if self.env.DEST_BINFMT=='pe'and getattr(self.generator,'vnum',None):
+					name=name+'-'+self.generator.vnum.split('.')[0]
+			tmp=folder+os.sep+pattern%name
+			target=self.generator.path.find_or_declare(tmp)
+		self.set_outputs(target)
+class stlink_task(link_task):
+	run_str='${AR} ${ARFLAGS} ${AR_TGT_F}${TGT} ${AR_SRC_F}${SRC}'
+def rm_tgt(cls):
+	old=cls.run
+	def wrap(self):
+		try:os.remove(self.outputs[0].abspath())
+		except OSError:pass
+		return old(self)
+	setattr(cls,'run',wrap)
+rm_tgt(stlink_task)
+@feature('c','cxx','d','fc','asm')
+@after_method('process_source')
+def apply_link(self):
+	for x in self.features:
+		if x=='cprogram'and'cxx'in self.features:
+			x='cxxprogram'
+		elif x=='cshlib'and'cxx'in self.features:
+			x='cxxshlib'
+		if x in Task.classes:
+			if issubclass(Task.classes[x],link_task):
+				link=x
+				break
+	else:
+		return
+	objs=[t.outputs[0]for t in getattr(self,'compiled_tasks',[])]
+	self.link_task=self.create_task(link,objs)
+	self.link_task.add_target(self.target)
+	try:
+		inst_to=self.install_path
+	except AttributeError:
+		inst_to=self.link_task.__class__.inst_to
+	if inst_to:
+		self.install_task=self.bld.install_files(inst_to,self.link_task.outputs[:],env=self.env,chmod=self.link_task.chmod)
+@taskgen_method
+def use_rec(self,name,**kw):
+	if name in self.tmp_use_not or name in self.tmp_use_seen:
+		return
+	try:
+		y=self.bld.get_tgen_by_name(name)
+	except Errors.WafError:
+		self.uselib.append(name)
+		self.tmp_use_not.add(name)
+		return
+	self.tmp_use_seen.append(name)
+	y.post()
+	y.tmp_use_objects=objects=kw.get('objects',True)
+	y.tmp_use_stlib=stlib=kw.get('stlib',True)
+	try:
+		link_task=y.link_task
+	except AttributeError:
+		y.tmp_use_var=''
+	else:
+		objects=False
+		if not isinstance(link_task,stlink_task):
+			stlib=False
+			y.tmp_use_var='LIB'
+		else:
+			y.tmp_use_var='STLIB'
+	p=self.tmp_use_prec
+	for x in self.to_list(getattr(y,'use',[])):
+		try:
+			p[x].append(name)
+		except KeyError:
+			p[x]=[name]
+		self.use_rec(x,objects=objects,stlib=stlib)
+@feature('c','cxx','d','use','fc')
+@before_method('apply_incpaths','propagate_uselib_vars')
+@after_method('apply_link','process_source')
+def process_use(self):
+	use_not=self.tmp_use_not=set([])
+	self.tmp_use_seen=[]
+	use_prec=self.tmp_use_prec={}
+	self.uselib=self.to_list(getattr(self,'uselib',[]))
+	self.includes=self.to_list(getattr(self,'includes',[]))
+	names=self.to_list(getattr(self,'use',[]))
+	for x in names:
+		self.use_rec(x)
+	for x in use_not:
+		if x in use_prec:
+			del use_prec[x]
+	out=[]
+	tmp=[]
+	for x in self.tmp_use_seen:
+		for k in use_prec.values():
+			if x in k:
+				break
+		else:
+			tmp.append(x)
+	while tmp:
+		e=tmp.pop()
+		out.append(e)
+		try:
+			nlst=use_prec[e]
+		except KeyError:
+			pass
+		else:
+			del use_prec[e]
+			for x in nlst:
+				for y in use_prec:
+					if x in use_prec[y]:
+						break
+				else:
+					tmp.append(x)
+	if use_prec:
+		raise Errors.WafError('Cycle detected in the use processing %r'%use_prec)
+	out.reverse()
+	link_task=getattr(self,'link_task',None)
+	for x in out:
+		y=self.bld.get_tgen_by_name(x)
+		var=y.tmp_use_var
+		if var and link_task:
+			if var=='LIB'or y.tmp_use_stlib:
+				self.env.append_value(var,[y.target[y.target.rfind(os.sep)+1:]])
+				self.link_task.dep_nodes.extend(y.link_task.outputs)
+				tmp_path=y.link_task.outputs[0].parent.path_from(self.bld.bldnode)
+				self.env.append_value(var+'PATH',[tmp_path])
+		else:
+			if y.tmp_use_objects:
+				self.add_objects_from_tgen(y)
+		if getattr(y,'export_includes',None):
+			self.includes.extend(y.to_incnodes(y.export_includes))
+		if getattr(y,'export_defines',None):
+			self.env.append_value('DEFINES',self.to_list(y.export_defines))
+	for x in names:
+		try:
+			y=self.bld.get_tgen_by_name(x)
+		except Exception:
+			if not self.env['STLIB_'+x]and not x in self.uselib:
+				self.uselib.append(x)
+		else:
+			for k in self.to_list(getattr(y,'uselib',[])):
+				if not self.env['STLIB_'+k]and not k in self.uselib:
+					self.uselib.append(k)
+@taskgen_method
+def accept_node_to_link(self,node):
+	return not node.name.endswith('.pdb')
+@taskgen_method
+def add_objects_from_tgen(self,tg):
+	try:
+		link_task=self.link_task
+	except AttributeError:
+		pass
+	else:
+		for tsk in getattr(tg,'compiled_tasks',[]):
+			for x in tsk.outputs:
+				if self.accept_node_to_link(x):
+					link_task.inputs.append(x)
+@taskgen_method
+def get_uselib_vars(self):
+	_vars=set([])
+	for x in self.features:
+		if x in USELIB_VARS:
+			_vars|=USELIB_VARS[x]
+	return _vars
+@feature('c','cxx','d','fc','javac','cs','uselib','asm')
+@after_method('process_use')
+def propagate_uselib_vars(self):
+	_vars=self.get_uselib_vars()
+	env=self.env
+	for x in _vars:
+		y=x.lower()
+		env.append_unique(x,self.to_list(getattr(self,y,[])))
+	for x in self.features:
+		for var in _vars:
+			compvar='%s_%s'%(var,x)
+			env.append_value(var,env[compvar])
+	for x in self.to_list(getattr(self,'uselib',[])):
+		for v in _vars:
+			env.append_value(v,env[v+'_'+x])
+@feature('cshlib','cxxshlib','fcshlib')
+@after_method('apply_link')
+def apply_implib(self):
+	if not self.env.DEST_BINFMT=='pe':
+		return
+	dll=self.link_task.outputs[0]
+	if isinstance(self.target,Node.Node):
+		name=self.target.name
+	else:
+		name=os.path.split(self.target)[1]
+	implib=self.env['implib_PATTERN']%name
+	implib=dll.parent.find_or_declare(implib)
+	self.env.append_value('LINKFLAGS',self.env['IMPLIB_ST']%implib.bldpath())
+	self.link_task.outputs.append(implib)
+	if getattr(self,'defs',None)and self.env.DEST_BINFMT=='pe':
+		node=self.path.find_resource(self.defs)
+		if not node:
+			raise Errors.WafError('invalid def file %r'%self.defs)
+		if'msvc'in(self.env.CC_NAME,self.env.CXX_NAME):
+			self.env.append_value('LINKFLAGS','/def:%s'%node.path_from(self.bld.bldnode))
+			self.link_task.dep_nodes.append(node)
+		else:
+			self.link_task.inputs.append(node)
+	try:
+		inst_to=self.install_path
+	except AttributeError:
+		inst_to=self.link_task.__class__.inst_to
+	if not inst_to:
+		return
+	self.implib_install_task=self.bld.install_as('${LIBDIR}/%s'%implib.name,implib,self.env)
+re_vnum=re.compile('^([1-9]\\d*|0)[.]([1-9]\\d*|0)[.]([1-9]\\d*|0)$')
+@feature('cshlib','cxxshlib','dshlib','fcshlib','vnum')
+@after_method('apply_link','propagate_uselib_vars')
+def apply_vnum(self):
+	if not getattr(self,'vnum','')or os.name!='posix'or self.env.DEST_BINFMT not in('elf','mac-o'):
+		return
+	link=self.link_task
+	if not re_vnum.match(self.vnum):
+		raise Errors.WafError('Invalid version %r for %r'%(self.vnum,self))
+	nums=self.vnum.split('.')
+	node=link.outputs[0]
+	libname=node.name
+	if libname.endswith('.dylib'):
+		name3=libname.replace('.dylib','.%s.dylib'%self.vnum)
+		name2=libname.replace('.dylib','.%s.dylib'%nums[0])
+	else:
+		name3=libname+'.'+self.vnum
+		name2=libname+'.'+nums[0]
+	if self.env.SONAME_ST:
+		v=self.env.SONAME_ST%name2
+		self.env.append_value('LINKFLAGS',v.split())
+	self.create_task('vnum',node,[node.parent.find_or_declare(name2),node.parent.find_or_declare(name3)])
+	if getattr(self,'install_task',None):
+		self.install_task.hasrun=Task.SKIP_ME
+		bld=self.bld
+		path=self.install_task.dest
+		t1=bld.install_as(path+os.sep+name3,node,env=self.env,chmod=self.link_task.chmod)
+		t2=bld.symlink_as(path+os.sep+name2,name3)
+		t3=bld.symlink_as(path+os.sep+libname,name3)
+		self.vnum_install_task=(t1,t2,t3)
+	if'-dynamiclib'in self.env['LINKFLAGS']:
+		try:
+			inst_to=self.install_path
+		except AttributeError:
+			inst_to=self.link_task.__class__.inst_to
+		if inst_to:
+			p=Utils.subst_vars(inst_to,self.env)
+			path=os.path.join(p,self.link_task.outputs[0].name)
+			self.env.append_value('LINKFLAGS',['-install_name',path])
+class vnum(Task.Task):
+	color='CYAN'
+	quient=True
+	ext_in=['.bin']
+	def run(self):
+		for x in self.outputs:
+			path=x.abspath()
+			try:
+				os.remove(path)
+			except OSError:
+				pass
+			try:
+				os.symlink(self.inputs[0].name,path)
+			except OSError:
+				return 1
+class fake_shlib(link_task):
+	def runnable_status(self):
+		for t in self.run_after:
+			if not t.hasrun:
+				return Task.ASK_LATER
+		for x in self.outputs:
+			x.sig=Utils.h_file(x.abspath())
+		return Task.SKIP_ME
+class fake_stlib(stlink_task):
+	def runnable_status(self):
+		for t in self.run_after:
+			if not t.hasrun:
+				return Task.ASK_LATER
+		for x in self.outputs:
+			x.sig=Utils.h_file(x.abspath())
+		return Task.SKIP_ME
+@conf
+def read_shlib(self,name,paths=[],export_includes=[],export_defines=[]):
+	return self(name=name,features='fake_lib',lib_paths=paths,lib_type='shlib',export_includes=export_includes,export_defines=export_defines)
+@conf
+def read_stlib(self,name,paths=[],export_includes=[],export_defines=[]):
+	return self(name=name,features='fake_lib',lib_paths=paths,lib_type='stlib',export_includes=export_includes,export_defines=export_defines)
+lib_patterns={'shlib':['lib%s.so','%s.so','lib%s.dylib','lib%s.dll','%s.dll'],'stlib':['lib%s.a','%s.a','lib%s.dll','%s.dll','lib%s.lib','%s.lib'],}
+@feature('fake_lib')
+def process_lib(self):
+	node=None
+	names=[x%self.name for x in lib_patterns[self.lib_type]]
+	for x in self.lib_paths+[self.path]+SYSTEM_LIB_PATHS:
+		if not isinstance(x,Node.Node):
+			x=self.bld.root.find_node(x)or self.path.find_node(x)
+			if not x:
+				continue
+		for y in names:
+			node=x.find_node(y)
+			if node:
+				node.sig=Utils.h_file(node.abspath())
+				break
+		else:
+			continue
+		break
+	else:
+		raise Errors.WafError('could not find library %r'%self.name)
+	self.link_task=self.create_task('fake_%s'%self.lib_type,[],[node])
+	self.target=self.name
+class fake_o(Task.Task):
+	def runnable_status(self):
+		return Task.SKIP_ME
+@extension('.o','.obj')
+def add_those_o_files(self,node):
+	tsk=self.create_task('fake_o',[],node)
+	try:
+		self.compiled_tasks.append(tsk)
+	except AttributeError:
+		self.compiled_tasks=[tsk]
+@feature('fake_obj')
+@before_method('process_source')
+def process_objs(self):
+	for node in self.to_nodes(self.source):
+		self.add_those_o_files(node)
+	self.source=[]
+@conf
+def read_object(self,obj):
+	if not isinstance(obj,self.path.__class__):
+		obj=self.path.find_resource(obj)
+	return self(features='fake_obj',source=obj,name=obj.name)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ccroot.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ccroot.pyc
new file mode 100644
index 0000000..e13e91d
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ccroot.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_c.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_c.py
new file mode 100644
index 0000000..04504fa
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_c.py
@@ -0,0 +1,39 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,imp,types
+from waflib.Tools import ccroot
+from waflib import Utils,Configure
+from waflib.Logs import debug
+c_compiler={'win32':['msvc','gcc'],'cygwin':['gcc'],'darwin':['gcc'],'aix':['xlc','gcc'],'linux':['gcc','icc'],'sunos':['suncc','gcc'],'irix':['gcc','irixcc'],'hpux':['gcc'],'gnu':['gcc'],'java':['gcc','msvc','icc'],'default':['gcc'],}
+def configure(conf):
+	try:test_for_compiler=conf.options.check_c_compiler
+	except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_c')")
+	for compiler in test_for_compiler.split():
+		conf.env.stash()
+		conf.start_msg('Checking for %r (c compiler)'%compiler)
+		try:
+			conf.load(compiler)
+		except conf.errors.ConfigurationError ,e:
+			conf.env.revert()
+			conf.end_msg(False)
+			debug('compiler_c: %r'%e)
+		else:
+			if conf.env['CC']:
+				conf.end_msg(conf.env.get_flat('CC'))
+				conf.env['COMPILER_CC']=compiler
+				break
+			conf.end_msg(False)
+	else:
+		conf.fatal('could not configure a c compiler!')
+def options(opt):
+	opt.load_special_tools('c_*.py',ban=['c_dumbpreproc.py'])
+	global c_compiler
+	build_platform=Utils.unversioned_sys_platform()
+	possible_compiler_list=c_compiler[build_platform in c_compiler and build_platform or'default']
+	test_for_compiler=' '.join(possible_compiler_list)
+	cc_compiler_opts=opt.add_option_group("C Compiler Options")
+	cc_compiler_opts.add_option('--check-c-compiler',default="%s"%test_for_compiler,help='On this platform (%s) the following C-Compiler will be checked by default: "%s"'%(build_platform,test_for_compiler),dest="check_c_compiler")
+	for x in test_for_compiler.split():
+		opt.load('%s'%x)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_c.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_c.pyc
new file mode 100644
index 0000000..7b68f35
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_c.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_cxx.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_cxx.py
new file mode 100644
index 0000000..14b7c7d
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_cxx.py
@@ -0,0 +1,39 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,imp,types
+from waflib.Tools import ccroot
+from waflib import Utils,Configure
+from waflib.Logs import debug
+cxx_compiler={'win32':['msvc','g++'],'cygwin':['g++'],'darwin':['g++'],'aix':['xlc++','g++'],'linux':['g++','icpc'],'sunos':['sunc++','g++'],'irix':['g++'],'hpux':['g++'],'gnu':['g++'],'java':['g++','msvc','icpc'],'default':['g++']}
+def configure(conf):
+	try:test_for_compiler=conf.options.check_cxx_compiler
+	except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_cxx')")
+	for compiler in test_for_compiler.split():
+		conf.env.stash()
+		conf.start_msg('Checking for %r (c++ compiler)'%compiler)
+		try:
+			conf.load(compiler)
+		except conf.errors.ConfigurationError ,e:
+			conf.env.revert()
+			conf.end_msg(False)
+			debug('compiler_cxx: %r'%e)
+		else:
+			if conf.env['CXX']:
+				conf.end_msg(conf.env.get_flat('CXX'))
+				conf.env['COMPILER_CXX']=compiler
+				break
+			conf.end_msg(False)
+	else:
+		conf.fatal('could not configure a c++ compiler!')
+def options(opt):
+	opt.load_special_tools('cxx_*.py')
+	global cxx_compiler
+	build_platform=Utils.unversioned_sys_platform()
+	possible_compiler_list=cxx_compiler[build_platform in cxx_compiler and build_platform or'default']
+	test_for_compiler=' '.join(possible_compiler_list)
+	cxx_compiler_opts=opt.add_option_group('C++ Compiler Options')
+	cxx_compiler_opts.add_option('--check-cxx-compiler',default="%s"%test_for_compiler,help='On this platform (%s) the following C++ Compiler will be checked by default: "%s"'%(build_platform,test_for_compiler),dest="check_cxx_compiler")
+	for x in test_for_compiler.split():
+		opt.load('%s'%x)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_cxx.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_cxx.pyc
new file mode 100644
index 0000000..ad9679e
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_cxx.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_d.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_d.py
new file mode 100644
index 0000000..ee173e1
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_d.py
@@ -0,0 +1,29 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,imp,types
+from waflib import Utils,Configure,Options,Logs
+def configure(conf):
+	for compiler in conf.options.dcheck.split(','):
+		conf.env.stash()
+		conf.start_msg('Checking for %r (d compiler)'%compiler)
+		try:
+			conf.load(compiler)
+		except conf.errors.ConfigurationError ,e:
+			conf.env.revert()
+			conf.end_msg(False)
+			Logs.debug('compiler_d: %r'%e)
+		else:
+			if conf.env.D:
+				conf.end_msg(conf.env.get_flat('D'))
+				conf.env['COMPILER_D']=compiler
+				break
+			conf.end_msg(False)
+	else:
+		conf.fatal('no suitable d compiler was found')
+def options(opt):
+	d_compiler_opts=opt.add_option_group('D Compiler Options')
+	d_compiler_opts.add_option('--check-d-compiler',default='gdc,dmd,ldc2',action='store',help='check for the compiler [Default:gdc,dmd,ldc2]',dest='dcheck')
+	for d_compiler in['gdc','dmd','ldc2']:
+		opt.load('%s'%d_compiler)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_fc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_fc.py
new file mode 100644
index 0000000..ec5d2ea
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/compiler_fc.py
@@ -0,0 +1,43 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,imp,types
+from waflib import Utils,Configure,Options,Logs,Errors
+from waflib.Tools import fc
+fc_compiler={'win32':['gfortran','ifort'],'darwin':['gfortran','g95','ifort'],'linux':['gfortran','g95','ifort'],'java':['gfortran','g95','ifort'],'default':['gfortran'],'aix':['gfortran']}
+def __list_possible_compiler(platform):
+	try:
+		return fc_compiler[platform]
+	except KeyError:
+		return fc_compiler["default"]
+def configure(conf):
+	try:test_for_compiler=conf.options.check_fc
+	except AttributeError:conf.fatal("Add options(opt): opt.load('compiler_fc')")
+	for compiler in test_for_compiler.split():
+		conf.env.stash()
+		conf.start_msg('Checking for %r (fortran compiler)'%compiler)
+		try:
+			conf.load(compiler)
+		except conf.errors.ConfigurationError ,e:
+			conf.env.revert()
+			conf.end_msg(False)
+			Logs.debug('compiler_fortran: %r'%e)
+		else:
+			if conf.env['FC']:
+				conf.end_msg(conf.env.get_flat('FC'))
+				conf.env.COMPILER_FORTRAN=compiler
+				break
+			conf.end_msg(False)
+	else:
+		conf.fatal('could not configure a fortran compiler!')
+def options(opt):
+	opt.load_special_tools('fc_*.py')
+	build_platform=Utils.unversioned_sys_platform()
+	detected_platform=Options.platform
+	possible_compiler_list=__list_possible_compiler(detected_platform)
+	test_for_compiler=' '.join(possible_compiler_list)
+	fortran_compiler_opts=opt.add_option_group("Fortran Compiler Options")
+	fortran_compiler_opts.add_option('--check-fortran-compiler',default="%s"%test_for_compiler,help='On this platform (%s) the following Fortran Compiler will be checked by default: "%s"'%(detected_platform,test_for_compiler),dest="check_fc")
+	for compiler in test_for_compiler.split():
+		opt.load('%s'%compiler)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cs.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cs.py
new file mode 100644
index 0000000..ee4d319
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cs.py
@@ -0,0 +1,132 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Utils,Task,Options,Logs,Errors
+from waflib.TaskGen import before_method,after_method,feature
+from waflib.Tools import ccroot
+from waflib.Configure import conf
+import os,tempfile
+ccroot.USELIB_VARS['cs']=set(['CSFLAGS','ASSEMBLIES','RESOURCES'])
+ccroot.lib_patterns['csshlib']=['%s']
+@feature('cs')
+@before_method('process_source')
+def apply_cs(self):
+	cs_nodes=[]
+	no_nodes=[]
+	for x in self.to_nodes(self.source):
+		if x.name.endswith('.cs'):
+			cs_nodes.append(x)
+		else:
+			no_nodes.append(x)
+	self.source=no_nodes
+	bintype=getattr(self,'bintype',self.gen.endswith('.dll')and'library'or'exe')
+	self.cs_task=tsk=self.create_task('mcs',cs_nodes,self.path.find_or_declare(self.gen))
+	tsk.env.CSTYPE='/target:%s'%bintype
+	tsk.env.OUT='/out:%s'%tsk.outputs[0].abspath()
+	self.env.append_value('CSFLAGS','/platform:%s'%getattr(self,'platform','anycpu'))
+	inst_to=getattr(self,'install_path',bintype=='exe'and'${BINDIR}'or'${LIBDIR}')
+	if inst_to:
+		mod=getattr(self,'chmod',bintype=='exe'and Utils.O755 or Utils.O644)
+		self.install_task=self.bld.install_files(inst_to,self.cs_task.outputs[:],env=self.env,chmod=mod)
+@feature('cs')
+@after_method('apply_cs')
+def use_cs(self):
+	names=self.to_list(getattr(self,'use',[]))
+	get=self.bld.get_tgen_by_name
+	for x in names:
+		try:
+			y=get(x)
+		except Errors.WafError:
+			self.env.append_value('CSFLAGS','/reference:%s'%x)
+			continue
+		y.post()
+		tsk=getattr(y,'cs_task',None)or getattr(y,'link_task',None)
+		if not tsk:
+			self.bld.fatal('cs task has no link task for use %r'%self)
+		self.cs_task.dep_nodes.extend(tsk.outputs)
+		self.cs_task.set_run_after(tsk)
+		self.env.append_value('CSFLAGS','/reference:%s'%tsk.outputs[0].abspath())
+@feature('cs')
+@after_method('apply_cs','use_cs')
+def debug_cs(self):
+	csdebug=getattr(self,'csdebug',self.env.CSDEBUG)
+	if not csdebug:
+		return
+	node=self.cs_task.outputs[0]
+	if self.env.CS_NAME=='mono':
+		out=node.parent.find_or_declare(node.name+'.mdb')
+	else:
+		out=node.change_ext('.pdb')
+	self.cs_task.outputs.append(out)
+	try:
+		self.install_task.source.append(out)
+	except AttributeError:
+		pass
+	if csdebug=='pdbonly':
+		val=['/debug+','/debug:pdbonly']
+	elif csdebug=='full':
+		val=['/debug+','/debug:full']
+	else:
+		val=['/debug-']
+	self.env.append_value('CSFLAGS',val)
+class mcs(Task.Task):
+	color='YELLOW'
+	run_str='${MCS} ${CSTYPE} ${CSFLAGS} ${ASS_ST:ASSEMBLIES} ${RES_ST:RESOURCES} ${OUT} ${SRC}'
+	def exec_command(self,cmd,**kw):
+		bld=self.generator.bld
+		try:
+			if not kw.get('cwd',None):
+				kw['cwd']=bld.cwd
+		except AttributeError:
+			bld.cwd=kw['cwd']=bld.variant_dir
+		try:
+			tmp=None
+			if isinstance(cmd,list)and len(' '.join(cmd))>=8192:
+				program=cmd[0]
+				cmd=[self.quote_response_command(x)for x in cmd]
+				(fd,tmp)=tempfile.mkstemp()
+				os.write(fd,'\r\n'.join(i.replace('\\','\\\\')for i in cmd[1:]))
+				os.close(fd)
+				cmd=[program,'@'+tmp]
+			ret=self.generator.bld.exec_command(cmd,**kw)
+		finally:
+			if tmp:
+				try:
+					os.remove(tmp)
+				except OSError:
+					pass
+		return ret
+	def quote_response_command(self,flag):
+		if flag.lower()=='/noconfig':
+			return''
+		if flag.find(' ')>-1:
+			for x in('/r:','/reference:','/resource:','/lib:','/out:'):
+				if flag.startswith(x):
+					flag='%s"%s"'%(x,flag[len(x):])
+					break
+			else:
+				flag='"%s"'%flag
+		return flag
+def configure(conf):
+	csc=getattr(Options.options,'cscbinary',None)
+	if csc:
+		conf.env.MCS=csc
+	conf.find_program(['csc','mcs','gmcs'],var='MCS')
+	conf.env.ASS_ST='/r:%s'
+	conf.env.RES_ST='/resource:%s'
+	conf.env.CS_NAME='csc'
+	if str(conf.env.MCS).lower().find('mcs')>-1:
+		conf.env.CS_NAME='mono'
+def options(opt):
+	opt.add_option('--with-csc-binary',type='string',dest='cscbinary')
+class fake_csshlib(Task.Task):
+	color='YELLOW'
+	inst_to=None
+	def runnable_status(self):
+		for x in self.outputs:
+			x.sig=Utils.h_file(x.abspath())
+		return Task.SKIP_ME
+@conf
+def read_csshlib(self,name,paths=[]):
+	return self(name=name,features='fake_lib',lib_paths=paths,lib_type='csshlib')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cxx.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cxx.py
new file mode 100644
index 0000000..b744a8d
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cxx.py
@@ -0,0 +1,26 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import TaskGen,Task,Utils
+from waflib.Tools import c_preproc
+from waflib.Tools.ccroot import link_task,stlink_task
+@TaskGen.extension('.cpp','.cc','.cxx','.C','.c++')
+def cxx_hook(self,node):
+	return self.create_compiled_task('cxx',node)
+if not'.c'in TaskGen.task_gen.mappings:
+	TaskGen.task_gen.mappings['.c']=TaskGen.task_gen.mappings['.cpp']
+class cxx(Task.Task):
+	run_str='${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT}'
+	vars=['CXXDEPS']
+	ext_in=['.h']
+	scan=c_preproc.scan
+class cxxprogram(link_task):
+	run_str='${LINK_CXX} ${LINKFLAGS} ${CXXLNK_SRC_F}${SRC} ${CXXLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${FRAMEWORK_ST:FRAMEWORK} ${ARCH_ST:ARCH} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${SHLIB_MARKER} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB}'
+	vars=['LINKDEPS']
+	ext_out=['.bin']
+	inst_to='${BINDIR}'
+class cxxshlib(cxxprogram):
+	inst_to='${LIBDIR}'
+class cxxstlib(stlink_task):
+	pass
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cxx.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cxx.pyc
new file mode 100644
index 0000000..3edb2e0
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/cxx.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d.py
new file mode 100644
index 0000000..1838740
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d.py
@@ -0,0 +1,54 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Utils,Task,Errors
+from waflib.TaskGen import taskgen_method,feature,extension
+from waflib.Tools import d_scan,d_config
+from waflib.Tools.ccroot import link_task,stlink_task
+class d(Task.Task):
+	color='GREEN'
+	run_str='${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_SRC_F:SRC} ${D_TGT_F:TGT}'
+	scan=d_scan.scan
+class d_with_header(d):
+	run_str='${D} ${DFLAGS} ${DINC_ST:INCPATHS} ${D_HDR_F:tgt.outputs[1].bldpath()} ${D_SRC_F:SRC} ${D_TGT_F:tgt.outputs[0].bldpath()}'
+class d_header(Task.Task):
+	color='BLUE'
+	run_str='${D} ${D_HEADER} ${SRC}'
+class dprogram(link_task):
+	run_str='${D_LINKER} ${LINKFLAGS} ${DLNK_SRC_F}${SRC} ${DLNK_TGT_F:TGT} ${RPATH_ST:RPATH} ${DSTLIB_MARKER} ${DSTLIBPATH_ST:STLIBPATH} ${DSTLIB_ST:STLIB} ${DSHLIB_MARKER} ${DLIBPATH_ST:LIBPATH} ${DSHLIB_ST:LIB}'
+	inst_to='${BINDIR}'
+class dshlib(dprogram):
+	inst_to='${LIBDIR}'
+class dstlib(stlink_task):
+	pass
+@extension('.d','.di','.D')
+def d_hook(self,node):
+	ext=Utils.destos_to_binfmt(self.env.DEST_OS)=='pe'and'obj'or'o'
+	out='%s.%d.%s'%(node.name,self.idx,ext)
+	def create_compiled_task(self,name,node):
+		task=self.create_task(name,node,node.parent.find_or_declare(out))
+		try:
+			self.compiled_tasks.append(task)
+		except AttributeError:
+			self.compiled_tasks=[task]
+		return task
+	if getattr(self,'generate_headers',None):
+		tsk=create_compiled_task(self,'d_with_header',node)
+		tsk.outputs.append(node.change_ext(self.env['DHEADER_ext']))
+	else:
+		tsk=create_compiled_task(self,'d',node)
+	return tsk
+@taskgen_method
+def generate_header(self,filename):
+	try:
+		self.header_lst.append([filename,self.install_path])
+	except AttributeError:
+		self.header_lst=[[filename,self.install_path]]
+@feature('d')
+def process_header(self):
+	for i in getattr(self,'header_lst',[]):
+		node=self.path.find_resource(i[0])
+		if not node:
+			raise Errors.WafError('file %r not found on d obj'%i[0])
+		self.create_task('d_header',node,node.change_ext('.di'))
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d_config.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d_config.py
new file mode 100644
index 0000000..50660ea
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d_config.py
@@ -0,0 +1,52 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Utils
+from waflib.Configure import conf
+@conf
+def d_platform_flags(self):
+	v=self.env
+	if not v.DEST_OS:
+		v.DEST_OS=Utils.unversioned_sys_platform()
+	binfmt=Utils.destos_to_binfmt(self.env.DEST_OS)
+	if binfmt=='pe':
+		v['dprogram_PATTERN']='%s.exe'
+		v['dshlib_PATTERN']='lib%s.dll'
+		v['dstlib_PATTERN']='lib%s.a'
+	elif binfmt=='mac-o':
+		v['dprogram_PATTERN']='%s'
+		v['dshlib_PATTERN']='lib%s.dylib'
+		v['dstlib_PATTERN']='lib%s.a'
+	else:
+		v['dprogram_PATTERN']='%s'
+		v['dshlib_PATTERN']='lib%s.so'
+		v['dstlib_PATTERN']='lib%s.a'
+DLIB='''
+version(D_Version2) {
+	import std.stdio;
+	int main() {
+		writefln("phobos2");
+		return 0;
+	}
+} else {
+	version(Tango) {
+		import tango.stdc.stdio;
+		int main() {
+			printf("tango");
+			return 0;
+		}
+	} else {
+		import std.stdio;
+		int main() {
+			writefln("phobos1");
+			return 0;
+		}
+	}
+}
+'''
+@conf
+def check_dlibrary(self,execute=True):
+	ret=self.check_cc(features='d dprogram',fragment=DLIB,compile_filename='test.d',execute=execute,define_ret=True)
+	if execute:
+		self.env.DLIBRARY=ret.strip()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d_scan.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d_scan.py
new file mode 100644
index 0000000..ee80c5f
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/d_scan.py
@@ -0,0 +1,133 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils,Logs
+def filter_comments(filename):
+	txt=Utils.readf(filename)
+	i=0
+	buf=[]
+	max=len(txt)
+	begin=0
+	while i<max:
+		c=txt[i]
+		if c=='"'or c=="'":
+			buf.append(txt[begin:i])
+			delim=c
+			i+=1
+			while i<max:
+				c=txt[i]
+				if c==delim:break
+				elif c=='\\':
+					i+=1
+				i+=1
+			i+=1
+			begin=i
+		elif c=='/':
+			buf.append(txt[begin:i])
+			i+=1
+			if i==max:break
+			c=txt[i]
+			if c=='+':
+				i+=1
+				nesting=1
+				c=None
+				while i<max:
+					prev=c
+					c=txt[i]
+					if prev=='/'and c=='+':
+						nesting+=1
+						c=None
+					elif prev=='+'and c=='/':
+						nesting-=1
+						if nesting==0:break
+						c=None
+					i+=1
+			elif c=='*':
+				i+=1
+				c=None
+				while i<max:
+					prev=c
+					c=txt[i]
+					if prev=='*'and c=='/':break
+					i+=1
+			elif c=='/':
+				i+=1
+				while i<max and txt[i]!='\n':
+					i+=1
+			else:
+				begin=i-1
+				continue
+			i+=1
+			begin=i
+			buf.append(' ')
+		else:
+			i+=1
+	buf.append(txt[begin:])
+	return buf
+class d_parser(object):
+	def __init__(self,env,incpaths):
+		self.allnames=[]
+		self.re_module=re.compile("module\s+([^;]+)")
+		self.re_import=re.compile("import\s+([^;]+)")
+		self.re_import_bindings=re.compile("([^:]+):(.*)")
+		self.re_import_alias=re.compile("[^=]+=(.+)")
+		self.env=env
+		self.nodes=[]
+		self.names=[]
+		self.incpaths=incpaths
+	def tryfind(self,filename):
+		found=0
+		for n in self.incpaths:
+			found=n.find_resource(filename.replace('.','/')+'.d')
+			if found:
+				self.nodes.append(found)
+				self.waiting.append(found)
+				break
+		if not found:
+			if not filename in self.names:
+				self.names.append(filename)
+	def get_strings(self,code):
+		self.module=''
+		lst=[]
+		mod_name=self.re_module.search(code)
+		if mod_name:
+			self.module=re.sub('\s+','',mod_name.group(1))
+		import_iterator=self.re_import.finditer(code)
+		if import_iterator:
+			for import_match in import_iterator:
+				import_match_str=re.sub('\s+','',import_match.group(1))
+				bindings_match=self.re_import_bindings.match(import_match_str)
+				if bindings_match:
+					import_match_str=bindings_match.group(1)
+				matches=import_match_str.split(',')
+				for match in matches:
+					alias_match=self.re_import_alias.match(match)
+					if alias_match:
+						match=alias_match.group(1)
+					lst.append(match)
+		return lst
+	def start(self,node):
+		self.waiting=[node]
+		while self.waiting:
+			nd=self.waiting.pop(0)
+			self.iter(nd)
+	def iter(self,node):
+		path=node.abspath()
+		code="".join(filter_comments(path))
+		names=self.get_strings(code)
+		for x in names:
+			if x in self.allnames:continue
+			self.allnames.append(x)
+			self.tryfind(x)
+def scan(self):
+	env=self.env
+	gruik=d_parser(env,self.generator.includes_nodes)
+	node=self.inputs[0]
+	gruik.start(node)
+	nodes=gruik.nodes
+	names=gruik.names
+	if Logs.verbose:
+		Logs.debug('deps: deps for %s: %r; unresolved %r'%(str(node),nodes,names))
+	return(nodes,names)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/dbus.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/dbus.py
new file mode 100644
index 0000000..ccea278
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/dbus.py
@@ -0,0 +1,29 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib import Task,Errors
+from waflib.TaskGen import taskgen_method,before_method
+@taskgen_method
+def add_dbus_file(self,filename,prefix,mode):
+	if not hasattr(self,'dbus_lst'):
+		self.dbus_lst=[]
+	if not'process_dbus'in self.meths:
+		self.meths.append('process_dbus')
+	self.dbus_lst.append([filename,prefix,mode])
+@before_method('apply_core')
+def process_dbus(self):
+	for filename,prefix,mode in getattr(self,'dbus_lst',[]):
+		node=self.path.find_resource(filename)
+		if not node:
+			raise Errors.WafError('file not found '+filename)
+		tsk=self.create_task('dbus_binding_tool',node,node.change_ext('.h'))
+		tsk.env.DBUS_BINDING_TOOL_PREFIX=prefix
+		tsk.env.DBUS_BINDING_TOOL_MODE=mode
+class dbus_binding_tool(Task.Task):
+	color='BLUE'
+	ext_out=['.h']
+	run_str='${DBUS_BINDING_TOOL} --prefix=${DBUS_BINDING_TOOL_PREFIX} --mode=${DBUS_BINDING_TOOL_MODE} --output=${TGT} ${SRC}'
+	shell=True
+def configure(conf):
+	dbus_binding_tool=conf.find_program('dbus-binding-tool',var='DBUS_BINDING_TOOL')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/dmd.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/dmd.py
new file mode 100644
index 0000000..b6e3303
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/dmd.py
@@ -0,0 +1,51 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+from waflib.Tools import ar,d
+from waflib.Configure import conf
+@conf
+def find_dmd(conf):
+	conf.find_program(['dmd','dmd2','ldc'],var='D')
+	out=conf.cmd_and_log([conf.env.D,'--help'])
+	if out.find("D Compiler v")==-1:
+		out=conf.cmd_and_log([conf.env.D,'-version'])
+		if out.find("based on DMD v1.")==-1:
+			conf.fatal("detected compiler is not dmd/ldc")
+@conf
+def common_flags_ldc(conf):
+	v=conf.env
+	v['DFLAGS']=['-d-version=Posix']
+	v['LINKFLAGS']=[]
+	v['DFLAGS_dshlib']=['-relocation-model=pic']
+@conf
+def common_flags_dmd(conf):
+	v=conf.env
+	v['D_SRC_F']=['-c']
+	v['D_TGT_F']='-of%s'
+	v['D_LINKER']=v['D']
+	v['DLNK_SRC_F']=''
+	v['DLNK_TGT_F']='-of%s'
+	v['DINC_ST']='-I%s'
+	v['DSHLIB_MARKER']=v['DSTLIB_MARKER']=''
+	v['DSTLIB_ST']=v['DSHLIB_ST']='-L-l%s'
+	v['DSTLIBPATH_ST']=v['DLIBPATH_ST']='-L-L%s'
+	v['LINKFLAGS_dprogram']=['-quiet']
+	v['DFLAGS_dshlib']=['-fPIC']
+	v['LINKFLAGS_dshlib']=['-L-shared']
+	v['DHEADER_ext']='.di'
+	v.DFLAGS_d_with_header=['-H','-Hf']
+	v['D_HDR_F']='%s'
+def configure(conf):
+	conf.find_dmd()
+	if sys.platform=='win32':
+		out=conf.cmd_and_log([conf.env.D,'--help'])
+		if out.find("D Compiler v2.")>-1:
+			conf.fatal('dmd2 on Windows is not supported, use gdc or ldc2 instead')
+	conf.load('ar')
+	conf.load('d')
+	conf.common_flags_dmd()
+	conf.d_platform_flags()
+	if str(conf.env.D).find('ldc')>-1:
+		conf.common_flags_ldc()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/errcheck.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/errcheck.py
new file mode 100644
index 0000000..3b06493
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/errcheck.py
@@ -0,0 +1,161 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+typos={'feature':'features','sources':'source','targets':'target','include':'includes','export_include':'export_includes','define':'defines','importpath':'includes','installpath':'install_path','iscopy':'is_copy',}
+meths_typos=['__call__','program','shlib','stlib','objects']
+from waflib import Logs,Build,Node,Task,TaskGen,ConfigSet,Errors,Utils
+import waflib.Tools.ccroot
+def check_same_targets(self):
+	mp=Utils.defaultdict(list)
+	uids={}
+	def check_task(tsk):
+		if not isinstance(tsk,Task.Task):
+			return
+		for node in tsk.outputs:
+			mp[node].append(tsk)
+		try:
+			uids[tsk.uid()].append(tsk)
+		except KeyError:
+			uids[tsk.uid()]=[tsk]
+	for g in self.groups:
+		for tg in g:
+			try:
+				for tsk in tg.tasks:
+					check_task(tsk)
+			except AttributeError:
+				check_task(tg)
+	dupe=False
+	for(k,v)in mp.items():
+		if len(v)>1:
+			dupe=True
+			msg='* Node %r is created more than once%s. The task generators are:'%(k,Logs.verbose==1 and" (full message on 'waf -v -v')"or"")
+			Logs.error(msg)
+			for x in v:
+				if Logs.verbose>1:
+					Logs.error('  %d. %r'%(1+v.index(x),x.generator))
+				else:
+					Logs.error('  %d. %r in %r'%(1+v.index(x),x.generator.name,getattr(x.generator,'path',None)))
+	if not dupe:
+		for(k,v)in uids.items():
+			if len(v)>1:
+				Logs.error('* Several tasks use the same identifier. Please check the information on\n   http://docs.waf.googlecode.com/git/apidocs_16/Task.html#waflib.Task.Task.uid')
+				for tsk in v:
+					Logs.error('  - object %r (%r) defined in %r'%(tsk.__class__.__name__,tsk,tsk.generator))
+def check_invalid_constraints(self):
+	feat=set([])
+	for x in list(TaskGen.feats.values()):
+		feat.union(set(x))
+	for(x,y)in TaskGen.task_gen.prec.items():
+		feat.add(x)
+		feat.union(set(y))
+	ext=set([])
+	for x in TaskGen.task_gen.mappings.values():
+		ext.add(x.__name__)
+	invalid=ext&feat
+	if invalid:
+		Logs.error('The methods %r have invalid annotations:  @extension <-> @feature/@before_method/@after_method'%list(invalid))
+	for cls in list(Task.classes.values()):
+		for x in('before','after'):
+			for y in Utils.to_list(getattr(cls,x,[])):
+				if not Task.classes.get(y,None):
+					Logs.error('Erroneous order constraint %r=%r on task class %r'%(x,y,cls.__name__))
+		if getattr(cls,'rule',None):
+			Logs.error('Erroneous attribute "rule" on task class %r (rename to "run_str")'%cls.__name__)
+def replace(m):
+	oldcall=getattr(Build.BuildContext,m)
+	def call(self,*k,**kw):
+		ret=oldcall(self,*k,**kw)
+		for x in typos:
+			if x in kw:
+				if x=='iscopy'and'subst'in getattr(self,'features',''):
+					continue
+				err=True
+				Logs.error('Fix the typo %r -> %r on %r'%(x,typos[x],ret))
+		return ret
+	setattr(Build.BuildContext,m,call)
+def enhance_lib():
+	for m in meths_typos:
+		replace(m)
+	def ant_glob(self,*k,**kw):
+		if k:
+			lst=Utils.to_list(k[0])
+			for pat in lst:
+				if'..'in pat.split('/'):
+					Logs.error("In ant_glob pattern %r: '..' means 'two dots', not 'parent directory'"%k[0])
+		if kw.get('remove',True):
+			try:
+				if self.is_child_of(self.ctx.bldnode)and not kw.get('quiet',False):
+					Logs.error('Using ant_glob on the build folder (%r) is dangerous (quiet=True to disable this warning)'%self)
+			except AttributeError:
+				pass
+		return self.old_ant_glob(*k,**kw)
+	Node.Node.old_ant_glob=Node.Node.ant_glob
+	Node.Node.ant_glob=ant_glob
+	old=Task.is_before
+	def is_before(t1,t2):
+		ret=old(t1,t2)
+		if ret and old(t2,t1):
+			Logs.error('Contradictory order constraints in classes %r %r'%(t1,t2))
+		return ret
+	Task.is_before=is_before
+	def check_err_features(self):
+		lst=self.to_list(self.features)
+		if'shlib'in lst:
+			Logs.error('feature shlib -> cshlib, dshlib or cxxshlib')
+		for x in('c','cxx','d','fc'):
+			if not x in lst and lst and lst[0]in[x+y for y in('program','shlib','stlib')]:
+				Logs.error('%r features is probably missing %r'%(self,x))
+	TaskGen.feature('*')(check_err_features)
+	def check_err_order(self):
+		if not hasattr(self,'rule')and not'subst'in Utils.to_list(self.features):
+			for x in('before','after','ext_in','ext_out'):
+				if hasattr(self,x):
+					Logs.warn('Erroneous order constraint %r on non-rule based task generator %r'%(x,self))
+		else:
+			for x in('before','after'):
+				for y in self.to_list(getattr(self,x,[])):
+					if not Task.classes.get(y,None):
+						Logs.error('Erroneous order constraint %s=%r on %r (no such class)'%(x,y,self))
+	TaskGen.feature('*')(check_err_order)
+	def check_compile(self):
+		check_invalid_constraints(self)
+		try:
+			ret=self.orig_compile()
+		finally:
+			check_same_targets(self)
+		return ret
+	Build.BuildContext.orig_compile=Build.BuildContext.compile
+	Build.BuildContext.compile=check_compile
+	def use_rec(self,name,**kw):
+		try:
+			y=self.bld.get_tgen_by_name(name)
+		except Errors.WafError:
+			pass
+		else:
+			idx=self.bld.get_group_idx(self)
+			odx=self.bld.get_group_idx(y)
+			if odx>idx:
+				msg="Invalid 'use' across build groups:"
+				if Logs.verbose>1:
+					msg+='\n  target %r\n  uses:\n  %r'%(self,y)
+				else:
+					msg+=" %r uses %r (try 'waf -v -v' for the full error)"%(self.name,name)
+				raise Errors.WafError(msg)
+		self.orig_use_rec(name,**kw)
+	TaskGen.task_gen.orig_use_rec=TaskGen.task_gen.use_rec
+	TaskGen.task_gen.use_rec=use_rec
+	def getattri(self,name,default=None):
+		if name=='append'or name=='add':
+			raise Errors.WafError('env.append and env.add do not exist: use env.append_value/env.append_unique')
+		elif name=='prepend':
+			raise Errors.WafError('env.prepend does not exist: use env.prepend_value')
+		if name in self.__slots__:
+			return object.__getattr__(self,name,default)
+		else:
+			return self[name]
+	ConfigSet.ConfigSet.__getattr__=getattri
+def options(opt):
+	enhance_lib()
+def configure(conf):
+	pass
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc.py
new file mode 100644
index 0000000..3589799
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc.py
@@ -0,0 +1,116 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils,Task,TaskGen,Logs
+from waflib.Tools import ccroot,fc_config,fc_scan
+from waflib.TaskGen import feature,before_method,after_method,extension
+from waflib.Configure import conf
+ccroot.USELIB_VARS['fc']=set(['FCFLAGS','DEFINES','INCLUDES'])
+ccroot.USELIB_VARS['fcprogram_test']=ccroot.USELIB_VARS['fcprogram']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+ccroot.USELIB_VARS['fcshlib']=set(['LIB','STLIB','LIBPATH','STLIBPATH','LINKFLAGS','RPATH','LINKDEPS'])
+ccroot.USELIB_VARS['fcstlib']=set(['ARFLAGS','LINKDEPS'])
+@feature('fcprogram','fcshlib','fcstlib','fcprogram_test')
+def dummy(self):
+	pass
+@extension('.f','.f90','.F','.F90','.for','.FOR')
+def fc_hook(self,node):
+	return self.create_compiled_task('fc',node)
+@conf
+def modfile(conf,name):
+	return{'lower':name.lower()+'.mod','lower.MOD':name.upper()+'.MOD','UPPER.mod':name.upper()+'.mod','UPPER':name.upper()+'.MOD'}[conf.env.FC_MOD_CAPITALIZATION or'lower']
+def get_fortran_tasks(tsk):
+	bld=tsk.generator.bld
+	tasks=bld.get_tasks_group(bld.get_group_idx(tsk.generator))
+	return[x for x in tasks if isinstance(x,fc)and not getattr(x,'nomod',None)and not getattr(x,'mod_fortran_done',None)]
+class fc(Task.Task):
+	color='GREEN'
+	run_str='${FC} ${FCFLAGS} ${FCINCPATH_ST:INCPATHS} ${FCDEFINES_ST:DEFINES} ${_FCMODOUTFLAGS} ${FC_TGT_F}${TGT[0].abspath()} ${FC_SRC_F}${SRC[0].abspath()}'
+	vars=["FORTRANMODPATHFLAG"]
+	def scan(self):
+		tmp=fc_scan.fortran_parser(self.generator.includes_nodes)
+		tmp.task=self
+		tmp.start(self.inputs[0])
+		if Logs.verbose:
+			Logs.debug('deps: deps for %r: %r; unresolved %r'%(self.inputs,tmp.nodes,tmp.names))
+		return(tmp.nodes,tmp.names)
+	def runnable_status(self):
+		if getattr(self,'mod_fortran_done',None):
+			return super(fc,self).runnable_status()
+		bld=self.generator.bld
+		lst=get_fortran_tasks(self)
+		for tsk in lst:
+			tsk.mod_fortran_done=True
+		for tsk in lst:
+			ret=tsk.runnable_status()
+			if ret==Task.ASK_LATER:
+				for x in lst:
+					x.mod_fortran_done=None
+				return Task.ASK_LATER
+		ins=Utils.defaultdict(set)
+		outs=Utils.defaultdict(set)
+		for tsk in lst:
+			key=tsk.uid()
+			for x in bld.raw_deps[key]:
+				if x.startswith('MOD@'):
+					name=bld.modfile(x.replace('MOD@',''))
+					node=bld.srcnode.find_or_declare(name)
+					tsk.set_outputs(node)
+					outs[id(node)].add(tsk)
+		for tsk in lst:
+			key=tsk.uid()
+			for x in bld.raw_deps[key]:
+				if x.startswith('USE@'):
+					name=bld.modfile(x.replace('USE@',''))
+					node=bld.srcnode.find_resource(name)
+					if node and node not in tsk.outputs:
+						if not node in bld.node_deps[key]:
+							bld.node_deps[key].append(node)
+						ins[id(node)].add(tsk)
+		for k in ins.keys():
+			for a in ins[k]:
+				a.run_after.update(outs[k])
+				tmp=[]
+				for t in outs[k]:
+					tmp.extend(t.outputs)
+				a.dep_nodes.extend(tmp)
+				a.dep_nodes.sort(key=lambda x:x.abspath())
+		for tsk in lst:
+			try:
+				delattr(tsk,'cache_sig')
+			except AttributeError:
+				pass
+		return super(fc,self).runnable_status()
+class fcprogram(ccroot.link_task):
+	color='YELLOW'
+	run_str='${FC} ${LINKFLAGS} ${FCLNK_SRC_F}${SRC} ${FCLNK_TGT_F}${TGT[0].abspath()} ${RPATH_ST:RPATH} ${FCSTLIB_MARKER} ${FCSTLIBPATH_ST:STLIBPATH} ${FCSTLIB_ST:STLIB} ${FCSHLIB_MARKER} ${FCLIBPATH_ST:LIBPATH} ${FCLIB_ST:LIB}'
+	inst_to='${BINDIR}'
+class fcshlib(fcprogram):
+	inst_to='${LIBDIR}'
+class fcprogram_test(fcprogram):
+	def can_retrieve_cache(self):
+		return False
+	def runnable_status(self):
+		ret=super(fcprogram_test,self).runnable_status()
+		if ret==Task.SKIP_ME:
+			ret=Task.RUN_ME
+		return ret
+	def exec_command(self,cmd,**kw):
+		bld=self.generator.bld
+		kw['shell']=isinstance(cmd,str)
+		kw['stdout']=kw['stderr']=Utils.subprocess.PIPE
+		kw['cwd']=bld.variant_dir
+		bld.out=bld.err=''
+		bld.to_log('command: %s\n'%cmd)
+		kw['output']=0
+		try:
+			(bld.out,bld.err)=bld.cmd_and_log(cmd,**kw)
+		except Exception ,e:
+			return-1
+		if bld.out:
+			bld.to_log("out: %s\n"%bld.out)
+		if bld.err:
+			bld.to_log("err: %s\n"%bld.err)
+class fcstlib(ccroot.stlink_task):
+	pass
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc_config.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc_config.py
new file mode 100644
index 0000000..580eac7
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc_config.py
@@ -0,0 +1,285 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re,shutil,os,sys,string,shlex
+from waflib.Configure import conf
+from waflib.TaskGen import feature,after_method,before_method
+from waflib import Build,Utils
+FC_FRAGMENT='        program main\n        end     program main\n'
+FC_FRAGMENT2='        PROGRAM MAIN\n        END\n'
+@conf
+def fc_flags(conf):
+	v=conf.env
+	v['FC_SRC_F']=[]
+	v['FC_TGT_F']=['-c','-o']
+	v['FCINCPATH_ST']='-I%s'
+	v['FCDEFINES_ST']='-D%s'
+	if not v['LINK_FC']:v['LINK_FC']=v['FC']
+	v['FCLNK_SRC_F']=[]
+	v['FCLNK_TGT_F']=['-o']
+	v['FCFLAGS_fcshlib']=['-fpic']
+	v['LINKFLAGS_fcshlib']=['-shared']
+	v['fcshlib_PATTERN']='lib%s.so'
+	v['fcstlib_PATTERN']='lib%s.a'
+	v['FCLIB_ST']='-l%s'
+	v['FCLIBPATH_ST']='-L%s'
+	v['FCSTLIB_ST']='-l%s'
+	v['FCSTLIBPATH_ST']='-L%s'
+	v['FCSTLIB_MARKER']='-Wl,-Bstatic'
+	v['FCSHLIB_MARKER']='-Wl,-Bdynamic'
+	v['SONAME_ST']='-Wl,-h,%s'
+@conf
+def fc_add_flags(conf):
+	conf.add_os_flags('FCFLAGS')
+	conf.add_os_flags('LDFLAGS','LINKFLAGS')
+@conf
+def check_fortran(self,*k,**kw):
+	self.check_cc(fragment=FC_FRAGMENT,compile_filename='test.f',features='fc fcprogram',msg='Compiling a simple fortran app')
+@conf
+def check_fc(self,*k,**kw):
+	kw['compiler']='fc'
+	if not'compile_mode'in kw:
+		kw['compile_mode']='fc'
+	if not'type'in kw:
+		kw['type']='fcprogram'
+	if not'compile_filename'in kw:
+		kw['compile_filename']='test.f90'
+	if not'code'in kw:
+		kw['code']=FC_FRAGMENT
+	return self.check(*k,**kw)
+@conf
+def fortran_modifier_darwin(conf):
+	v=conf.env
+	v['FCFLAGS_fcshlib']=['-fPIC']
+	v['LINKFLAGS_fcshlib']=['-dynamiclib','-Wl,-compatibility_version,1','-Wl,-current_version,1']
+	v['fcshlib_PATTERN']='lib%s.dylib'
+	v['FRAMEWORKPATH_ST']='-F%s'
+	v['FRAMEWORK_ST']='-framework %s'
+	v['LINKFLAGS_fcstlib']=[]
+	v['FCSHLIB_MARKER']=''
+	v['FCSTLIB_MARKER']=''
+	v['SONAME_ST']=''
+@conf
+def fortran_modifier_win32(conf):
+	v=conf.env
+	v['fcprogram_PATTERN']=v['fcprogram_test_PATTERN']='%s.exe'
+	v['fcshlib_PATTERN']='%s.dll'
+	v['implib_PATTERN']='lib%s.dll.a'
+	v['IMPLIB_ST']='-Wl,--out-implib,%s'
+	v['FCFLAGS_fcshlib']=[]
+	v.append_value('FCFLAGS_fcshlib',['-DDLL_EXPORT'])
+	v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
+@conf
+def fortran_modifier_cygwin(conf):
+	fortran_modifier_win32(conf)
+	v=conf.env
+	v['fcshlib_PATTERN']='cyg%s.dll'
+	v.append_value('LINKFLAGS_fcshlib',['-Wl,--enable-auto-image-base'])
+	v['FCFLAGS_fcshlib']=[]
+@conf
+def check_fortran_dummy_main(self,*k,**kw):
+	if not self.env.CC:
+		self.fatal('A c compiler is required for check_fortran_dummy_main')
+	lst=['MAIN__','__MAIN','_MAIN','MAIN_','MAIN']
+	lst.extend([m.lower()for m in lst])
+	lst.append('')
+	self.start_msg('Detecting whether we need a dummy main')
+	for main in lst:
+		kw['fortran_main']=main
+		try:
+			self.check_cc(fragment='int %s() { return 0; }\n'%(main or'test'),features='c fcprogram',mandatory=True)
+			if not main:
+				self.env.FC_MAIN=-1
+				self.end_msg('no')
+			else:
+				self.env.FC_MAIN=main
+				self.end_msg('yes %s'%main)
+			break
+		except self.errors.ConfigurationError:
+			pass
+	else:
+		self.end_msg('not found')
+		self.fatal('could not detect whether fortran requires a dummy main, see the config.log')
+GCC_DRIVER_LINE=re.compile('^Driving:')
+POSIX_STATIC_EXT=re.compile('\S+\.a')
+POSIX_LIB_FLAGS=re.compile('-l\S+')
+@conf
+def is_link_verbose(self,txt):
+	assert isinstance(txt,str)
+	for line in txt.splitlines():
+		if not GCC_DRIVER_LINE.search(line):
+			if POSIX_STATIC_EXT.search(line)or POSIX_LIB_FLAGS.search(line):
+				return True
+	return False
+@conf
+def check_fortran_verbose_flag(self,*k,**kw):
+	self.start_msg('fortran link verbose flag')
+	for x in['-v','--verbose','-verbose','-V']:
+		try:
+			self.check_cc(features='fc fcprogram_test',fragment=FC_FRAGMENT2,compile_filename='test.f',linkflags=[x],mandatory=True)
+		except self.errors.ConfigurationError:
+			pass
+		else:
+			if self.is_link_verbose(self.test_bld.err)or self.is_link_verbose(self.test_bld.out):
+				self.end_msg(x)
+				break
+	else:
+		self.end_msg('failure')
+		self.fatal('Could not obtain the fortran link verbose flag (see config.log)')
+	self.env.FC_VERBOSE_FLAG=x
+	return x
+LINKFLAGS_IGNORED=[r'-lang*',r'-lcrt[a-zA-Z0-9\.]*\.o',r'-lc$',r'-lSystem',r'-libmil',r'-LIST:*',r'-LNO:*']
+if os.name=='nt':
+	LINKFLAGS_IGNORED.extend([r'-lfrt*',r'-luser32',r'-lkernel32',r'-ladvapi32',r'-lmsvcrt',r'-lshell32',r'-lmingw',r'-lmoldname'])
+else:
+	LINKFLAGS_IGNORED.append(r'-lgcc*')
+RLINKFLAGS_IGNORED=[re.compile(f)for f in LINKFLAGS_IGNORED]
+def _match_ignore(line):
+	for i in RLINKFLAGS_IGNORED:
+		if i.match(line):
+			return True
+	return False
+def parse_fortran_link(lines):
+	final_flags=[]
+	for line in lines:
+		if not GCC_DRIVER_LINE.match(line):
+			_parse_flink_line(line,final_flags)
+	return final_flags
+SPACE_OPTS=re.compile('^-[LRuYz]$')
+NOSPACE_OPTS=re.compile('^-[RL]')
+def _parse_flink_line(line,final_flags):
+	lexer=shlex.shlex(line,posix=True)
+	lexer.whitespace_split=True
+	t=lexer.get_token()
+	tmp_flags=[]
+	while t:
+		def parse(token):
+			if _match_ignore(token):
+				pass
+			elif token.startswith('-lkernel32')and sys.platform=='cygwin':
+				tmp_flags.append(token)
+			elif SPACE_OPTS.match(token):
+				t=lexer.get_token()
+				if t.startswith('P,'):
+					t=t[2:]
+				for opt in t.split(os.pathsep):
+					tmp_flags.append('-L%s'%opt)
+			elif NOSPACE_OPTS.match(token):
+				tmp_flags.append(token)
+			elif POSIX_LIB_FLAGS.match(token):
+				tmp_flags.append(token)
+			else:
+				pass
+			t=lexer.get_token()
+			return t
+		t=parse(t)
+	final_flags.extend(tmp_flags)
+	return final_flags
+@conf
+def check_fortran_clib(self,autoadd=True,*k,**kw):
+	if not self.env.FC_VERBOSE_FLAG:
+		self.fatal('env.FC_VERBOSE_FLAG is not set: execute check_fortran_verbose_flag?')
+	self.start_msg('Getting fortran runtime link flags')
+	try:
+		self.check_cc(fragment=FC_FRAGMENT2,compile_filename='test.f',features='fc fcprogram_test',linkflags=[self.env.FC_VERBOSE_FLAG])
+	except Exception:
+		self.end_msg(False)
+		if kw.get('mandatory',True):
+			conf.fatal('Could not find the c library flags')
+	else:
+		out=self.test_bld.err
+		flags=parse_fortran_link(out.splitlines())
+		self.end_msg('ok (%s)'%' '.join(flags))
+		self.env.LINKFLAGS_CLIB=flags
+		return flags
+	return[]
+def getoutput(conf,cmd,stdin=False):
+	if stdin:
+		stdin=Utils.subprocess.PIPE
+	else:
+		stdin=None
+	env=conf.env.env or None
+	try:
+		p=Utils.subprocess.Popen(cmd,stdin=stdin,stdout=Utils.subprocess.PIPE,stderr=Utils.subprocess.PIPE,env=env)
+		if stdin:
+			p.stdin.write('\n')
+		out,err=p.communicate()
+	except Exception:
+		conf.fatal('could not determine the compiler version %r'%cmd)
+	if not isinstance(out,str):
+		out=out.decode(sys.stdout.encoding or'iso8859-1')
+	if not isinstance(err,str):
+		err=err.decode(sys.stdout.encoding or'iso8859-1')
+	return(out,err)
+ROUTINES_CODE="""\
+      subroutine foobar()
+      return
+      end
+      subroutine foo_bar()
+      return
+      end
+"""
+MAIN_CODE="""
+void %(dummy_func_nounder)s(void);
+void %(dummy_func_under)s(void);
+int %(main_func_name)s() {
+  %(dummy_func_nounder)s();
+  %(dummy_func_under)s();
+  return 0;
+}
+"""
+@feature('link_main_routines_func')
+@before_method('process_source')
+def link_main_routines_tg_method(self):
+	def write_test_file(task):
+		task.outputs[0].write(task.generator.code)
+	bld=self.bld
+	bld(rule=write_test_file,target='main.c',code=MAIN_CODE%self.__dict__)
+	bld(rule=write_test_file,target='test.f',code=ROUTINES_CODE)
+	bld(features='fc fcstlib',source='test.f',target='test')
+	bld(features='c fcprogram',source='main.c',target='app',use='test')
+def mangling_schemes():
+	for u in['_','']:
+		for du in['','_']:
+			for c in["lower","upper"]:
+				yield(u,du,c)
+def mangle_name(u,du,c,name):
+	return getattr(name,c)()+u+(name.find('_')!=-1 and du or'')
+@conf
+def check_fortran_mangling(self,*k,**kw):
+	if not self.env.CC:
+		self.fatal('A c compiler is required for link_main_routines')
+	if not self.env.FC:
+		self.fatal('A fortran compiler is required for link_main_routines')
+	if not self.env.FC_MAIN:
+		self.fatal('Checking for mangling requires self.env.FC_MAIN (execute "check_fortran_dummy_main" first?)')
+	self.start_msg('Getting fortran mangling scheme')
+	for(u,du,c)in mangling_schemes():
+		try:
+			self.check_cc(compile_filename=[],features='link_main_routines_func',msg='nomsg',errmsg='nomsg',mandatory=True,dummy_func_nounder=mangle_name(u,du,c,"foobar"),dummy_func_under=mangle_name(u,du,c,"foo_bar"),main_func_name=self.env.FC_MAIN)
+		except self.errors.ConfigurationError:
+			pass
+		else:
+			self.end_msg("ok ('%s', '%s', '%s-case')"%(u,du,c))
+			self.env.FORTRAN_MANGLING=(u,du,c)
+			break
+	else:
+		self.end_msg(False)
+		self.fatal('mangler not found')
+	return(u,du,c)
+@feature('pyext')
+@before_method('propagate_uselib_vars','apply_link')
+def set_lib_pat(self):
+	self.env['fcshlib_PATTERN']=self.env['pyext_PATTERN']
+@conf
+def detect_openmp(self):
+	for x in['-fopenmp','-openmp','-mp','-xopenmp','-omp','-qsmp=omp']:
+		try:
+			self.check_fc(msg='Checking for OpenMP flag %s'%x,fragment='program main\n  call omp_get_num_threads()\nend program main',fcflags=x,linkflags=x,uselib_store='OPENMP')
+		except self.errors.ConfigurationError:
+			pass
+		else:
+			break
+	else:
+		self.fatal('Could not find OpenMP')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc_scan.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc_scan.py
new file mode 100644
index 0000000..48e06b5
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/fc_scan.py
@@ -0,0 +1,68 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils,Task,TaskGen,Logs
+from waflib.TaskGen import feature,before_method,after_method,extension
+from waflib.Configure import conf
+INC_REGEX="""(?:^|['">]\s*;)\s*INCLUDE\s+(?:\w+_)?[<"'](.+?)(?=["'>])"""
+USE_REGEX="""(?:^|;)\s*USE(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)"""
+MOD_REGEX="""(?:^|;)\s*MODULE(?!\s*PROCEDURE)(?:\s+|(?:(?:\s*,\s*(?:NON_)?INTRINSIC)?\s*::))\s*(\w+)"""
+re_inc=re.compile(INC_REGEX,re.I)
+re_use=re.compile(USE_REGEX,re.I)
+re_mod=re.compile(MOD_REGEX,re.I)
+class fortran_parser(object):
+	def __init__(self,incpaths):
+		self.seen=[]
+		self.nodes=[]
+		self.names=[]
+		self.incpaths=incpaths
+	def find_deps(self,node):
+		txt=node.read()
+		incs=[]
+		uses=[]
+		mods=[]
+		for line in txt.splitlines():
+			m=re_inc.search(line)
+			if m:
+				incs.append(m.group(1))
+			m=re_use.search(line)
+			if m:
+				uses.append(m.group(1))
+			m=re_mod.search(line)
+			if m:
+				mods.append(m.group(1))
+		return(incs,uses,mods)
+	def start(self,node):
+		self.waiting=[node]
+		while self.waiting:
+			nd=self.waiting.pop(0)
+			self.iter(nd)
+	def iter(self,node):
+		path=node.abspath()
+		incs,uses,mods=self.find_deps(node)
+		for x in incs:
+			if x in self.seen:
+				continue
+			self.seen.append(x)
+			self.tryfind_header(x)
+		for x in uses:
+			name="USE@%s"%x
+			if not name in self.names:
+				self.names.append(name)
+		for x in mods:
+			name="MOD@%s"%x
+			if not name in self.names:
+				self.names.append(name)
+	def tryfind_header(self,filename):
+		found=None
+		for n in self.incpaths:
+			found=n.find_resource(filename)
+			if found:
+				self.nodes.append(found)
+				self.waiting.append(found)
+				break
+		if not found:
+			if not filename in self.names:
+				self.names.append(filename)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/flex.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/flex.py
new file mode 100644
index 0000000..13f6207
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/flex.py
@@ -0,0 +1,32 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import waflib.TaskGen,os,re
+def decide_ext(self,node):
+	if'cxx'in self.features:
+		return['.lex.cc']
+	return['.lex.c']
+def flexfun(tsk):
+	env=tsk.env
+	bld=tsk.generator.bld
+	wd=bld.variant_dir
+	def to_list(xx):
+		if isinstance(xx,str):return[xx]
+		return xx
+	tsk.last_cmd=lst=[]
+	lst.extend(to_list(env['FLEX']))
+	lst.extend(to_list(env['FLEXFLAGS']))
+	inputs=[a.path_from(bld.bldnode)for a in tsk.inputs]
+	if env.FLEX_MSYS:
+		inputs=[x.replace(os.sep,'/')for x in inputs]
+	lst.extend(inputs)
+	lst=[x for x in lst if x]
+	txt=bld.cmd_and_log(lst,cwd=wd,env=env.env or None,quiet=0)
+	tsk.outputs[0].write(txt.replace('\r\n','\n').replace('\r','\n'))
+waflib.TaskGen.declare_chain(name='flex',rule=flexfun,ext_in='.l',decider=decide_ext,)
+def configure(conf):
+	conf.find_program('flex',var='FLEX')
+	conf.env.FLEXFLAGS=['-t']
+	if re.search(r"\\msys\\[0-9.]+\\bin\\flex.exe$",conf.env.FLEX):
+		conf.env.FLEX_MSYS=True
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/g95.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/g95.py
new file mode 100644
index 0000000..9bc331a
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/g95.py
@@ -0,0 +1,55 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils
+from waflib.Tools import fc,fc_config,fc_scan,ar
+from waflib.Configure import conf
+@conf
+def find_g95(conf):
+	fc=conf.find_program('g95',var='FC')
+	fc=conf.cmd_to_list(fc)
+	conf.get_g95_version(fc)
+	conf.env.FC_NAME='G95'
+@conf
+def g95_flags(conf):
+	v=conf.env
+	v['FCFLAGS_fcshlib']=['-fPIC']
+	v['FORTRANMODFLAG']=['-fmod=','']
+	v['FCFLAGS_DEBUG']=['-Werror']
+@conf
+def g95_modifier_win32(conf):
+	fc_config.fortran_modifier_win32(conf)
+@conf
+def g95_modifier_cygwin(conf):
+	fc_config.fortran_modifier_cygwin(conf)
+@conf
+def g95_modifier_darwin(conf):
+	fc_config.fortran_modifier_darwin(conf)
+@conf
+def g95_modifier_platform(conf):
+	dest_os=conf.env['DEST_OS']or Utils.unversioned_sys_platform()
+	g95_modifier_func=getattr(conf,'g95_modifier_'+dest_os,None)
+	if g95_modifier_func:
+		g95_modifier_func()
+@conf
+def get_g95_version(conf,fc):
+	version_re=re.compile(r"g95\s*(?P<major>\d*)\.(?P<minor>\d*)").search
+	cmd=fc+['--version']
+	out,err=fc_config.getoutput(conf,cmd,stdin=False)
+	if out:
+		match=version_re(out)
+	else:
+		match=version_re(err)
+	if not match:
+		conf.fatal('cannot determine g95 version')
+	k=match.groupdict()
+	conf.env['FC_VERSION']=(k['major'],k['minor'])
+def configure(conf):
+	conf.find_g95()
+	conf.find_ar()
+	conf.fc_flags()
+	conf.fc_add_flags()
+	conf.g95_flags()
+	conf.g95_modifier_platform()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gas.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gas.py
new file mode 100644
index 0000000..b714ca1
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gas.py
@@ -0,0 +1,12 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import waflib.Tools.asm
+from waflib.Tools import ar
+def configure(conf):
+	conf.find_program(['gas','gcc'],var='AS')
+	conf.env.AS_TGT_F=['-c','-o']
+	conf.env.ASLNK_TGT_F=['-o']
+	conf.find_ar()
+	conf.load('asm')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gcc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gcc.py
new file mode 100644
index 0000000..da68d94
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gcc.py
@@ -0,0 +1,97 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib import Configure,Options,Utils
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_gcc(conf):
+	cc=conf.find_program(['gcc','cc'],var='CC')
+	cc=conf.cmd_to_list(cc)
+	conf.get_cc_version(cc,gcc=True)
+	conf.env.CC_NAME='gcc'
+	conf.env.CC=cc
+@conf
+def gcc_common_flags(conf):
+	v=conf.env
+	v['CC_SRC_F']=[]
+	v['CC_TGT_F']=['-c','-o']
+	if not v['LINK_CC']:v['LINK_CC']=v['CC']
+	v['CCLNK_SRC_F']=[]
+	v['CCLNK_TGT_F']=['-o']
+	v['CPPPATH_ST']='-I%s'
+	v['DEFINES_ST']='-D%s'
+	v['LIB_ST']='-l%s'
+	v['LIBPATH_ST']='-L%s'
+	v['STLIB_ST']='-l%s'
+	v['STLIBPATH_ST']='-L%s'
+	v['RPATH_ST']='-Wl,-rpath,%s'
+	v['SONAME_ST']='-Wl,-h,%s'
+	v['SHLIB_MARKER']='-Wl,-Bdynamic'
+	v['STLIB_MARKER']='-Wl,-Bstatic'
+	v['cprogram_PATTERN']='%s'
+	v['CFLAGS_cshlib']=['-fPIC']
+	v['LINKFLAGS_cshlib']=['-shared']
+	v['cshlib_PATTERN']='lib%s.so'
+	v['LINKFLAGS_cstlib']=['-Wl,-Bstatic']
+	v['cstlib_PATTERN']='lib%s.a'
+	v['LINKFLAGS_MACBUNDLE']=['-bundle','-undefined','dynamic_lookup']
+	v['CFLAGS_MACBUNDLE']=['-fPIC']
+	v['macbundle_PATTERN']='%s.bundle'
+@conf
+def gcc_modifier_win32(conf):
+	v=conf.env
+	v['cprogram_PATTERN']='%s.exe'
+	v['cshlib_PATTERN']='%s.dll'
+	v['implib_PATTERN']='lib%s.dll.a'
+	v['IMPLIB_ST']='-Wl,--out-implib,%s'
+	v['CFLAGS_cshlib']=[]
+	v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
+@conf
+def gcc_modifier_cygwin(conf):
+	gcc_modifier_win32(conf)
+	v=conf.env
+	v['cshlib_PATTERN']='cyg%s.dll'
+	v.append_value('LINKFLAGS_cshlib',['-Wl,--enable-auto-image-base'])
+	v['CFLAGS_cshlib']=[]
+@conf
+def gcc_modifier_darwin(conf):
+	v=conf.env
+	v['CFLAGS_cshlib']=['-fPIC']
+	v['LINKFLAGS_cshlib']=['-dynamiclib','-Wl,-compatibility_version,1','-Wl,-current_version,1']
+	v['cshlib_PATTERN']='lib%s.dylib'
+	v['FRAMEWORKPATH_ST']='-F%s'
+	v['FRAMEWORK_ST']=['-framework']
+	v['ARCH_ST']=['-arch']
+	v['LINKFLAGS_cstlib']=[]
+	v['SHLIB_MARKER']=[]
+	v['STLIB_MARKER']=[]
+	v['SONAME_ST']=[]
+@conf
+def gcc_modifier_aix(conf):
+	v=conf.env
+	v['LINKFLAGS_cprogram']=['-Wl,-brtl']
+	v['LINKFLAGS_cshlib']=['-shared','-Wl,-brtl,-bexpfull']
+	v['SHLIB_MARKER']=[]
+@conf
+def gcc_modifier_hpux(conf):
+	v=conf.env
+	v['SHLIB_MARKER']=[]
+	v['STLIB_MARKER']='-Bstatic'
+	v['CFLAGS_cshlib']=['-fPIC','-DPIC']
+	v['cshlib_PATTERN']='lib%s.sl'
+@conf
+def gcc_modifier_platform(conf):
+	gcc_modifier_func=getattr(conf,'gcc_modifier_'+conf.env.DEST_OS,None)
+	if gcc_modifier_func:
+		gcc_modifier_func()
+def configure(conf):
+	conf.find_gcc()
+	conf.find_ar()
+	conf.gcc_common_flags()
+	conf.gcc_modifier_platform()
+	conf.cc_load_tools()
+	conf.cc_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gcc.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gcc.pyc
new file mode 100644
index 0000000..2d7303f
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gcc.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gdc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gdc.py
new file mode 100644
index 0000000..da966ec
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gdc.py
@@ -0,0 +1,36 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+from waflib.Tools import ar,d
+from waflib.Configure import conf
+@conf
+def find_gdc(conf):
+	conf.find_program('gdc',var='D')
+	out=conf.cmd_and_log([conf.env.D,'--version'])
+	if out.find("gdc ")==-1:
+		conf.fatal("detected compiler is not gdc")
+@conf
+def common_flags_gdc(conf):
+	v=conf.env
+	v['DFLAGS']=[]
+	v['D_SRC_F']=['-c']
+	v['D_TGT_F']='-o%s'
+	v['D_LINKER']=v['D']
+	v['DLNK_SRC_F']=''
+	v['DLNK_TGT_F']='-o%s'
+	v['DINC_ST']='-I%s'
+	v['DSHLIB_MARKER']=v['DSTLIB_MARKER']=''
+	v['DSTLIB_ST']=v['DSHLIB_ST']='-l%s'
+	v['DSTLIBPATH_ST']=v['DLIBPATH_ST']='-L%s'
+	v['LINKFLAGS_dshlib']=['-shared']
+	v['DHEADER_ext']='.di'
+	v.DFLAGS_d_with_header='-fintfc'
+	v['D_HDR_F']='-fintfc-file=%s'
+def configure(conf):
+	conf.find_gdc()
+	conf.load('ar')
+	conf.load('d')
+	conf.common_flags_gdc()
+	conf.d_platform_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gfortran.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gfortran.py
new file mode 100644
index 0000000..854a93d
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gfortran.py
@@ -0,0 +1,69 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils
+from waflib.Tools import fc,fc_config,fc_scan,ar
+from waflib.Configure import conf
+@conf
+def find_gfortran(conf):
+	fc=conf.find_program(['gfortran','g77'],var='FC')
+	fc=conf.cmd_to_list(fc)
+	conf.get_gfortran_version(fc)
+	conf.env.FC_NAME='GFORTRAN'
+@conf
+def gfortran_flags(conf):
+	v=conf.env
+	v['FCFLAGS_fcshlib']=['-fPIC']
+	v['FORTRANMODFLAG']=['-J','']
+	v['FCFLAGS_DEBUG']=['-Werror']
+@conf
+def gfortran_modifier_win32(conf):
+	fc_config.fortran_modifier_win32(conf)
+@conf
+def gfortran_modifier_cygwin(conf):
+	fc_config.fortran_modifier_cygwin(conf)
+@conf
+def gfortran_modifier_darwin(conf):
+	fc_config.fortran_modifier_darwin(conf)
+@conf
+def gfortran_modifier_platform(conf):
+	dest_os=conf.env['DEST_OS']or Utils.unversioned_sys_platform()
+	gfortran_modifier_func=getattr(conf,'gfortran_modifier_'+dest_os,None)
+	if gfortran_modifier_func:
+		gfortran_modifier_func()
+@conf
+def get_gfortran_version(conf,fc):
+	version_re=re.compile(r"GNU\s*Fortran",re.I).search
+	cmd=fc+['--version']
+	out,err=fc_config.getoutput(conf,cmd,stdin=False)
+	if out:match=version_re(out)
+	else:match=version_re(err)
+	if not match:
+		conf.fatal('Could not determine the compiler type')
+	cmd=fc+['-dM','-E','-']
+	out,err=fc_config.getoutput(conf,cmd,stdin=True)
+	if out.find('__GNUC__')<0:
+		conf.fatal('Could not determine the compiler type')
+	k={}
+	out=out.split('\n')
+	import shlex
+	for line in out:
+		lst=shlex.split(line)
+		if len(lst)>2:
+			key=lst[1]
+			val=lst[2]
+			k[key]=val
+	def isD(var):
+		return var in k
+	def isT(var):
+		return var in k and k[var]!='0'
+	conf.env['FC_VERSION']=(k['__GNUC__'],k['__GNUC_MINOR__'],k['__GNUC_PATCHLEVEL__'])
+def configure(conf):
+	conf.find_gfortran()
+	conf.find_ar()
+	conf.fc_flags()
+	conf.fc_add_flags()
+	conf.gfortran_flags()
+	conf.gfortran_modifier_platform()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/glib2.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/glib2.py
new file mode 100644
index 0000000..1d75510
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/glib2.py
@@ -0,0 +1,173 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Task,Utils,Options,Errors,Logs
+from waflib.TaskGen import taskgen_method,before_method,after_method,feature
+@taskgen_method
+def add_marshal_file(self,filename,prefix):
+	if not hasattr(self,'marshal_list'):
+		self.marshal_list=[]
+	self.meths.append('process_marshal')
+	self.marshal_list.append((filename,prefix))
+@before_method('process_source')
+def process_marshal(self):
+	for f,prefix in getattr(self,'marshal_list',[]):
+		node=self.path.find_resource(f)
+		if not node:
+			raise Errors.WafError('file not found %r'%f)
+		h_node=node.change_ext('.h')
+		c_node=node.change_ext('.c')
+		task=self.create_task('glib_genmarshal',node,[h_node,c_node])
+		task.env.GLIB_GENMARSHAL_PREFIX=prefix
+	self.source=self.to_nodes(getattr(self,'source',[]))
+	self.source.append(c_node)
+class glib_genmarshal(Task.Task):
+	def run(self):
+		bld=self.inputs[0].__class__.ctx
+		get=self.env.get_flat
+		cmd1="%s %s --prefix=%s --header > %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[0].abspath())
+		ret=bld.exec_command(cmd1)
+		if ret:return ret
+		c='''#include "%s"\n'''%self.outputs[0].name
+		self.outputs[1].write(c)
+		cmd2="%s %s --prefix=%s --body >> %s"%(get('GLIB_GENMARSHAL'),self.inputs[0].srcpath(),get('GLIB_GENMARSHAL_PREFIX'),self.outputs[1].abspath())
+		return bld.exec_command(cmd2)
+	vars=['GLIB_GENMARSHAL_PREFIX','GLIB_GENMARSHAL']
+	color='BLUE'
+	ext_out=['.h']
+@taskgen_method
+def add_enums_from_template(self,source='',target='',template='',comments=''):
+	if not hasattr(self,'enums_list'):
+		self.enums_list=[]
+	self.meths.append('process_enums')
+	self.enums_list.append({'source':source,'target':target,'template':template,'file-head':'','file-prod':'','file-tail':'','enum-prod':'','value-head':'','value-prod':'','value-tail':'','comments':comments})
+@taskgen_method
+def add_enums(self,source='',target='',file_head='',file_prod='',file_tail='',enum_prod='',value_head='',value_prod='',value_tail='',comments=''):
+	if not hasattr(self,'enums_list'):
+		self.enums_list=[]
+	self.meths.append('process_enums')
+	self.enums_list.append({'source':source,'template':'','target':target,'file-head':file_head,'file-prod':file_prod,'file-tail':file_tail,'enum-prod':enum_prod,'value-head':value_head,'value-prod':value_prod,'value-tail':value_tail,'comments':comments})
+@before_method('process_source')
+def process_enums(self):
+	for enum in getattr(self,'enums_list',[]):
+		task=self.create_task('glib_mkenums')
+		env=task.env
+		inputs=[]
+		source_list=self.to_list(enum['source'])
+		if not source_list:
+			raise Errors.WafError('missing source '+str(enum))
+		source_list=[self.path.find_resource(k)for k in source_list]
+		inputs+=source_list
+		env['GLIB_MKENUMS_SOURCE']=[k.abspath()for k in source_list]
+		if not enum['target']:
+			raise Errors.WafError('missing target '+str(enum))
+		tgt_node=self.path.find_or_declare(enum['target'])
+		if tgt_node.name.endswith('.c'):
+			self.source.append(tgt_node)
+		env['GLIB_MKENUMS_TARGET']=tgt_node.abspath()
+		options=[]
+		if enum['template']:
+			template_node=self.path.find_resource(enum['template'])
+			options.append('--template %s'%(template_node.abspath()))
+			inputs.append(template_node)
+		params={'file-head':'--fhead','file-prod':'--fprod','file-tail':'--ftail','enum-prod':'--eprod','value-head':'--vhead','value-prod':'--vprod','value-tail':'--vtail','comments':'--comments'}
+		for param,option in params.items():
+			if enum[param]:
+				options.append('%s %r'%(option,enum[param]))
+		env['GLIB_MKENUMS_OPTIONS']=' '.join(options)
+		task.set_inputs(inputs)
+		task.set_outputs(tgt_node)
+class glib_mkenums(Task.Task):
+	run_str='${GLIB_MKENUMS} ${GLIB_MKENUMS_OPTIONS} ${GLIB_MKENUMS_SOURCE} > ${GLIB_MKENUMS_TARGET}'
+	color='PINK'
+	ext_out=['.h']
+@taskgen_method
+def add_settings_schemas(self,filename_list):
+	if not hasattr(self,'settings_schema_files'):
+		self.settings_schema_files=[]
+	if not isinstance(filename_list,list):
+		filename_list=[filename_list]
+	self.settings_schema_files.extend(filename_list)
+@taskgen_method
+def add_settings_enums(self,namespace,filename_list):
+	if hasattr(self,'settings_enum_namespace'):
+		raise Errors.WafError("Tried to add gsettings enums to '%s' more than once"%self.name)
+	self.settings_enum_namespace=namespace
+	if type(filename_list)!='list':
+		filename_list=[filename_list]
+	self.settings_enum_files=filename_list
+def r_change_ext(self,ext):
+	name=self.name
+	k=name.rfind('.')
+	if k>=0:
+		name=name[:k]+ext
+	else:
+		name=name+ext
+	return self.parent.find_or_declare([name])
+@feature('glib2')
+def process_settings(self):
+	enums_tgt_node=[]
+	install_files=[]
+	settings_schema_files=getattr(self,'settings_schema_files',[])
+	if settings_schema_files and not self.env['GLIB_COMPILE_SCHEMAS']:
+		raise Errors.WafError("Unable to process GSettings schemas - glib-compile-schemas was not found during configure")
+	if hasattr(self,'settings_enum_files'):
+		enums_task=self.create_task('glib_mkenums')
+		source_list=self.settings_enum_files
+		source_list=[self.path.find_resource(k)for k in source_list]
+		enums_task.set_inputs(source_list)
+		enums_task.env['GLIB_MKENUMS_SOURCE']=[k.abspath()for k in source_list]
+		target=self.settings_enum_namespace+'.enums.xml'
+		tgt_node=self.path.find_or_declare(target)
+		enums_task.set_outputs(tgt_node)
+		enums_task.env['GLIB_MKENUMS_TARGET']=tgt_node.abspath()
+		enums_tgt_node=[tgt_node]
+		install_files.append(tgt_node)
+		options='--comments "<!-- @comment@ -->" --fhead "<schemalist>" --vhead "  <@type@ id=\\"%s.@EnumName@\\">" --vprod "    <value nick=\\"@valuenick@\\" value=\\"@valuenum@\\"/>" --vtail "  </@type@>" --ftail "</schemalist>" '%(self.settings_enum_namespace)
+		enums_task.env['GLIB_MKENUMS_OPTIONS']=options
+	for schema in settings_schema_files:
+		schema_task=self.create_task('glib_validate_schema')
+		schema_node=self.path.find_resource(schema)
+		if not schema_node:
+			raise Errors.WafError("Cannot find the schema file '%s'"%schema)
+		install_files.append(schema_node)
+		source_list=enums_tgt_node+[schema_node]
+		schema_task.set_inputs(source_list)
+		schema_task.env['GLIB_COMPILE_SCHEMAS_OPTIONS']=[("--schema-file="+k.abspath())for k in source_list]
+		target_node=r_change_ext(schema_node,'.xml.valid')
+		schema_task.set_outputs(target_node)
+		schema_task.env['GLIB_VALIDATE_SCHEMA_OUTPUT']=target_node.abspath()
+	def compile_schemas_callback(bld):
+		if not bld.is_install:return
+		Logs.pprint('YELLOW','Updating GSettings schema cache')
+		command=Utils.subst_vars("${GLIB_COMPILE_SCHEMAS} ${GSETTINGSSCHEMADIR}",bld.env)
+		ret=self.bld.exec_command(command)
+	if self.bld.is_install:
+		if not self.env['GSETTINGSSCHEMADIR']:
+			raise Errors.WafError('GSETTINGSSCHEMADIR not defined (should have been set up automatically during configure)')
+		if install_files:
+			self.bld.install_files(self.env['GSETTINGSSCHEMADIR'],install_files)
+			if not hasattr(self.bld,'_compile_schemas_registered'):
+				self.bld.add_post_fun(compile_schemas_callback)
+				self.bld._compile_schemas_registered=True
+class glib_validate_schema(Task.Task):
+	run_str='rm -f ${GLIB_VALIDATE_SCHEMA_OUTPUT} && ${GLIB_COMPILE_SCHEMAS} --dry-run ${GLIB_COMPILE_SCHEMAS_OPTIONS} && touch ${GLIB_VALIDATE_SCHEMA_OUTPUT}'
+	color='PINK'
+def configure(conf):
+	conf.find_program('glib-genmarshal',var='GLIB_GENMARSHAL')
+	conf.find_perl_program('glib-mkenums',var='GLIB_MKENUMS')
+	conf.find_program('glib-compile-schemas',var='GLIB_COMPILE_SCHEMAS',mandatory=False)
+	def getstr(varname):
+		return getattr(Options.options,varname,getattr(conf.env,varname,''))
+	gsettingsschemadir=getstr('GSETTINGSSCHEMADIR')
+	if not gsettingsschemadir:
+		datadir=getstr('DATADIR')
+		if not datadir:
+			prefix=conf.env['PREFIX']
+			datadir=os.path.join(prefix,'share')
+		gsettingsschemadir=os.path.join(datadir,'glib-2.0','schemas')
+	conf.env['GSETTINGSSCHEMADIR']=gsettingsschemadir
+def options(opt):
+	opt.add_option('--gsettingsschemadir',help='GSettings schema location [Default: ${datadir}/glib-2.0/schemas]',default='',dest='GSETTINGSSCHEMADIR')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gnu_dirs.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gnu_dirs.py
new file mode 100644
index 0000000..9c8a304
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gnu_dirs.py
@@ -0,0 +1,65 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Utils,Options,Context
+_options=[x.split(', ')for x in'''
+bindir, user executables, ${EXEC_PREFIX}/bin
+sbindir, system admin executables, ${EXEC_PREFIX}/sbin
+libexecdir, program executables, ${EXEC_PREFIX}/libexec
+sysconfdir, read-only single-machine data, ${PREFIX}/etc
+sharedstatedir, modifiable architecture-independent data, ${PREFIX}/com
+localstatedir, modifiable single-machine data, ${PREFIX}/var
+libdir, object code libraries, ${EXEC_PREFIX}/lib
+includedir, C header files, ${PREFIX}/include
+oldincludedir, C header files for non-gcc, /usr/include
+datarootdir, read-only arch.-independent data root, ${PREFIX}/share
+datadir, read-only architecture-independent data, ${DATAROOTDIR}
+infodir, info documentation, ${DATAROOTDIR}/info
+localedir, locale-dependent data, ${DATAROOTDIR}/locale
+mandir, man documentation, ${DATAROOTDIR}/man
+docdir, documentation root, ${DATAROOTDIR}/doc/${PACKAGE}
+htmldir, html documentation, ${DOCDIR}
+dvidir, dvi documentation, ${DOCDIR}
+pdfdir, pdf documentation, ${DOCDIR}
+psdir, ps documentation, ${DOCDIR}
+'''.split('\n')if x]
+def configure(conf):
+	def get_param(varname,default):
+		return getattr(Options.options,varname,'')or default
+	env=conf.env
+	env.LIBDIR=env.BINDIR=[]
+	env.EXEC_PREFIX=get_param('EXEC_PREFIX',env.PREFIX)
+	env.PACKAGE=getattr(Context.g_module,'APPNAME',None)or env.PACKAGE
+	complete=False
+	iter=0
+	while not complete and iter<len(_options)+1:
+		iter+=1
+		complete=True
+		for name,help,default in _options:
+			name=name.upper()
+			if not env[name]:
+				try:
+					env[name]=Utils.subst_vars(get_param(name,default).replace('/',os.sep),env)
+				except TypeError:
+					complete=False
+	if not complete:
+		lst=[name for name,_,_ in _options if not env[name.upper()]]
+		raise conf.errors.WafError('Variable substitution failure %r'%lst)
+def options(opt):
+	inst_dir=opt.add_option_group('Installation directories','By default, "waf install" will put the files in\
+ "/usr/local/bin", "/usr/local/lib" etc. An installation prefix other\
+ than "/usr/local" can be given using "--prefix", for example "--prefix=$HOME"')
+	for k in('--prefix','--destdir'):
+		option=opt.parser.get_option(k)
+		if option:
+			opt.parser.remove_option(k)
+			inst_dir.add_option(option)
+	inst_dir.add_option('--exec-prefix',help='installation prefix [Default: ${PREFIX}]',default='',dest='EXEC_PREFIX')
+	dirs_options=opt.add_option_group('Pre-defined installation directories','')
+	for name,help,default in _options:
+		option_name='--'+name
+		str_default=default
+		str_help='%s [Default: %s]'%(help,str_default)
+		dirs_options.add_option(option_name,help=str_help,default='',dest=name.upper())
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gnu_dirs.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gnu_dirs.pyc
new file mode 100644
index 0000000..09c626d
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gnu_dirs.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gxx.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gxx.py
new file mode 100644
index 0000000..553e5ba
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gxx.py
@@ -0,0 +1,97 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib import Configure,Options,Utils
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_gxx(conf):
+	cxx=conf.find_program(['g++','c++'],var='CXX')
+	cxx=conf.cmd_to_list(cxx)
+	conf.get_cc_version(cxx,gcc=True)
+	conf.env.CXX_NAME='gcc'
+	conf.env.CXX=cxx
+@conf
+def gxx_common_flags(conf):
+	v=conf.env
+	v['CXX_SRC_F']=[]
+	v['CXX_TGT_F']=['-c','-o']
+	if not v['LINK_CXX']:v['LINK_CXX']=v['CXX']
+	v['CXXLNK_SRC_F']=[]
+	v['CXXLNK_TGT_F']=['-o']
+	v['CPPPATH_ST']='-I%s'
+	v['DEFINES_ST']='-D%s'
+	v['LIB_ST']='-l%s'
+	v['LIBPATH_ST']='-L%s'
+	v['STLIB_ST']='-l%s'
+	v['STLIBPATH_ST']='-L%s'
+	v['RPATH_ST']='-Wl,-rpath,%s'
+	v['SONAME_ST']='-Wl,-h,%s'
+	v['SHLIB_MARKER']='-Wl,-Bdynamic'
+	v['STLIB_MARKER']='-Wl,-Bstatic'
+	v['cxxprogram_PATTERN']='%s'
+	v['CXXFLAGS_cxxshlib']=['-fPIC']
+	v['LINKFLAGS_cxxshlib']=['-shared']
+	v['cxxshlib_PATTERN']='lib%s.so'
+	v['LINKFLAGS_cxxstlib']=['-Wl,-Bstatic']
+	v['cxxstlib_PATTERN']='lib%s.a'
+	v['LINKFLAGS_MACBUNDLE']=['-bundle','-undefined','dynamic_lookup']
+	v['CXXFLAGS_MACBUNDLE']=['-fPIC']
+	v['macbundle_PATTERN']='%s.bundle'
+@conf
+def gxx_modifier_win32(conf):
+	v=conf.env
+	v['cxxprogram_PATTERN']='%s.exe'
+	v['cxxshlib_PATTERN']='%s.dll'
+	v['implib_PATTERN']='lib%s.dll.a'
+	v['IMPLIB_ST']='-Wl,--out-implib,%s'
+	v['CXXFLAGS_cxxshlib']=[]
+	v.append_value('LINKFLAGS',['-Wl,--enable-auto-import'])
+@conf
+def gxx_modifier_cygwin(conf):
+	gxx_modifier_win32(conf)
+	v=conf.env
+	v['cxxshlib_PATTERN']='cyg%s.dll'
+	v.append_value('LINKFLAGS_cxxshlib',['-Wl,--enable-auto-image-base'])
+	v['CXXFLAGS_cxxshlib']=[]
+@conf
+def gxx_modifier_darwin(conf):
+	v=conf.env
+	v['CXXFLAGS_cxxshlib']=['-fPIC']
+	v['LINKFLAGS_cxxshlib']=['-dynamiclib','-Wl,-compatibility_version,1','-Wl,-current_version,1']
+	v['cxxshlib_PATTERN']='lib%s.dylib'
+	v['FRAMEWORKPATH_ST']='-F%s'
+	v['FRAMEWORK_ST']=['-framework']
+	v['ARCH_ST']=['-arch']
+	v['LINKFLAGS_cxxstlib']=[]
+	v['SHLIB_MARKER']=[]
+	v['STLIB_MARKER']=[]
+	v['SONAME_ST']=[]
+@conf
+def gxx_modifier_aix(conf):
+	v=conf.env
+	v['LINKFLAGS_cxxprogram']=['-Wl,-brtl']
+	v['LINKFLAGS_cxxshlib']=['-shared','-Wl,-brtl,-bexpfull']
+	v['SHLIB_MARKER']=[]
+@conf
+def gxx_modifier_hpux(conf):
+	v=conf.env
+	v['SHLIB_MARKER']=[]
+	v['STLIB_MARKER']='-Bstatic'
+	v['CFLAGS_cxxshlib']=['-fPIC','-DPIC']
+	v['cxxshlib_PATTERN']='lib%s.sl'
+@conf
+def gxx_modifier_platform(conf):
+	gxx_modifier_func=getattr(conf,'gxx_modifier_'+conf.env.DEST_OS,None)
+	if gxx_modifier_func:
+		gxx_modifier_func()
+def configure(conf):
+	conf.find_gxx()
+	conf.find_ar()
+	conf.gxx_common_flags()
+	conf.gxx_modifier_platform()
+	conf.cxx_load_tools()
+	conf.cxx_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gxx.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gxx.pyc
new file mode 100644
index 0000000..dd856a5
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/gxx.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/icc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/icc.py
new file mode 100644
index 0000000..7c75e18
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/icc.py
@@ -0,0 +1,30 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib.Tools import ccroot,ar,gcc
+from waflib.Configure import conf
+@conf
+def find_icc(conf):
+	if sys.platform=='cygwin':
+		conf.fatal('The Intel compiler does not work on Cygwin')
+	v=conf.env
+	cc=None
+	if v['CC']:cc=v['CC']
+	elif'CC'in conf.environ:cc=conf.environ['CC']
+	if not cc:cc=conf.find_program('icc',var='CC')
+	if not cc:cc=conf.find_program('ICL',var='CC')
+	if not cc:conf.fatal('Intel C Compiler (icc) was not found')
+	cc=conf.cmd_to_list(cc)
+	conf.get_cc_version(cc,icc=True)
+	v['CC']=cc
+	v['CC_NAME']='icc'
+def configure(conf):
+	conf.find_icc()
+	conf.find_ar()
+	conf.gcc_common_flags()
+	conf.gcc_modifier_platform()
+	conf.cc_load_tools()
+	conf.cc_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/icpc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/icpc.py
new file mode 100644
index 0000000..14a5325
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/icpc.py
@@ -0,0 +1,29 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib.Tools import ccroot,ar,gxx
+from waflib.Configure import conf
+@conf
+def find_icpc(conf):
+	if sys.platform=='cygwin':
+		conf.fatal('The Intel compiler does not work on Cygwin')
+	v=conf.env
+	cxx=None
+	if v['CXX']:cxx=v['CXX']
+	elif'CXX'in conf.environ:cxx=conf.environ['CXX']
+	if not cxx:cxx=conf.find_program('icpc',var='CXX')
+	if not cxx:conf.fatal('Intel C++ Compiler (icpc) was not found')
+	cxx=conf.cmd_to_list(cxx)
+	conf.get_cc_version(cxx,icc=True)
+	v['CXX']=cxx
+	v['CXX_NAME']='icc'
+def configure(conf):
+	conf.find_icpc()
+	conf.find_ar()
+	conf.gxx_common_flags()
+	conf.gxx_modifier_platform()
+	conf.cxx_load_tools()
+	conf.cxx_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ifort.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ifort.py
new file mode 100644
index 0000000..a9f2528
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ifort.py
@@ -0,0 +1,49 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re
+from waflib import Utils
+from waflib.Tools import fc,fc_config,fc_scan,ar
+from waflib.Configure import conf
+@conf
+def find_ifort(conf):
+	fc=conf.find_program('ifort',var='FC')
+	fc=conf.cmd_to_list(fc)
+	conf.get_ifort_version(fc)
+	conf.env.FC_NAME='IFORT'
+@conf
+def ifort_modifier_cygwin(conf):
+	raise NotImplementedError("Ifort on cygwin not yet implemented")
+@conf
+def ifort_modifier_win32(conf):
+	fc_config.fortran_modifier_win32(conf)
+@conf
+def ifort_modifier_darwin(conf):
+	fc_config.fortran_modifier_darwin(conf)
+@conf
+def ifort_modifier_platform(conf):
+	dest_os=conf.env['DEST_OS']or Utils.unversioned_sys_platform()
+	ifort_modifier_func=getattr(conf,'ifort_modifier_'+dest_os,None)
+	if ifort_modifier_func:
+		ifort_modifier_func()
+@conf
+def get_ifort_version(conf,fc):
+	version_re=re.compile(r"ifort\s*\(IFORT\)\s*(?P<major>\d*)\.(?P<minor>\d*)",re.I).search
+	cmd=fc+['--version']
+	out,err=fc_config.getoutput(conf,cmd,stdin=False)
+	if out:
+		match=version_re(out)
+	else:
+		match=version_re(err)
+	if not match:
+		conf.fatal('cannot determine ifort version.')
+	k=match.groupdict()
+	conf.env['FC_VERSION']=(k['major'],k['minor'])
+def configure(conf):
+	conf.find_ifort()
+	conf.find_program('xiar',var='AR')
+	conf.env.ARFLAGS='rcs'
+	conf.fc_flags()
+	conf.fc_add_flags()
+	conf.ifort_modifier_platform()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/intltool.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/intltool.py
new file mode 100644
index 0000000..d558674
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/intltool.py
@@ -0,0 +1,77 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,re
+from waflib import Configure,TaskGen,Task,Utils,Runner,Options,Build,Logs
+import waflib.Tools.ccroot
+from waflib.TaskGen import feature,before_method
+from waflib.Logs import error
+@before_method('process_source')
+@feature('intltool_in')
+def apply_intltool_in_f(self):
+	try:self.meths.remove('process_source')
+	except ValueError:pass
+	if not self.env.LOCALEDIR:
+		self.env.LOCALEDIR=self.env.PREFIX+'/share/locale'
+	for i in self.to_list(self.source):
+		node=self.path.find_resource(i)
+		podir=getattr(self,'podir','po')
+		podirnode=self.path.find_dir(podir)
+		if not podirnode:
+			error("could not find the podir %r"%podir)
+			continue
+		cache=getattr(self,'intlcache','.intlcache')
+		self.env['INTLCACHE']=os.path.join(self.path.bldpath(),podir,cache)
+		self.env['INTLPODIR']=podirnode.bldpath()
+		self.env['INTLFLAGS']=getattr(self,'flags',['-q','-u','-c'])
+		task=self.create_task('intltool',node,node.change_ext(''))
+		inst=getattr(self,'install_path','${LOCALEDIR}')
+		if inst:
+			self.bld.install_files(inst,task.outputs)
+@feature('intltool_po')
+def apply_intltool_po(self):
+	try:self.meths.remove('process_source')
+	except ValueError:pass
+	if not self.env.LOCALEDIR:
+		self.env.LOCALEDIR=self.env.PREFIX+'/share/locale'
+	appname=getattr(self,'appname','set_your_app_name')
+	podir=getattr(self,'podir','')
+	inst=getattr(self,'install_path','${LOCALEDIR}')
+	linguas=self.path.find_node(os.path.join(podir,'LINGUAS'))
+	if linguas:
+		file=open(linguas.abspath())
+		langs=[]
+		for line in file.readlines():
+			if not line.startswith('#'):
+				langs+=line.split()
+		file.close()
+		re_linguas=re.compile('[-a-zA-Z_@.]+')
+		for lang in langs:
+			if re_linguas.match(lang):
+				node=self.path.find_resource(os.path.join(podir,re_linguas.match(lang).group()+'.po'))
+				task=self.create_task('po',node,node.change_ext('.mo'))
+				if inst:
+					filename=task.outputs[0].name
+					(langname,ext)=os.path.splitext(filename)
+					inst_file=inst+os.sep+langname+os.sep+'LC_MESSAGES'+os.sep+appname+'.mo'
+					self.bld.install_as(inst_file,task.outputs[0],chmod=getattr(self,'chmod',Utils.O644),env=task.env)
+	else:
+		Logs.pprint('RED',"Error no LINGUAS file found in po directory")
+class po(Task.Task):
+	run_str='${MSGFMT} -o ${TGT} ${SRC}'
+	color='BLUE'
+class intltool(Task.Task):
+	run_str='${INTLTOOL} ${INTLFLAGS} ${INTLCACHE} ${INTLPODIR} ${SRC} ${TGT}'
+	color='BLUE'
+def configure(conf):
+	conf.find_program('msgfmt',var='MSGFMT')
+	conf.find_perl_program('intltool-merge',var='INTLTOOL')
+	prefix=conf.env.PREFIX
+	datadir=conf.env.DATADIR
+	if not datadir:
+		datadir=os.path.join(prefix,'share')
+	conf.define('LOCALEDIR',os.path.join(datadir,'locale').replace('\\','\\\\'))
+	conf.define('DATADIR',datadir.replace('\\','\\\\'))
+	if conf.env.CC or conf.env.CXX:
+		conf.check(header_name='locale.h')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/irixcc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/irixcc.py
new file mode 100644
index 0000000..8dbdfca
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/irixcc.py
@@ -0,0 +1,48 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Utils
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_irixcc(conf):
+	v=conf.env
+	cc=None
+	if v['CC']:cc=v['CC']
+	elif'CC'in conf.environ:cc=conf.environ['CC']
+	if not cc:cc=conf.find_program('cc',var='CC')
+	if not cc:conf.fatal('irixcc was not found')
+	cc=conf.cmd_to_list(cc)
+	try:
+		conf.cmd_and_log(cc+['-version'])
+	except Exception:
+		conf.fatal('%r -version could not be executed'%cc)
+	v['CC']=cc
+	v['CC_NAME']='irix'
+@conf
+def irixcc_common_flags(conf):
+	v=conf.env
+	v['CC_SRC_F']=''
+	v['CC_TGT_F']=['-c','-o']
+	v['CPPPATH_ST']='-I%s'
+	v['DEFINES_ST']='-D%s'
+	if not v['LINK_CC']:v['LINK_CC']=v['CC']
+	v['CCLNK_SRC_F']=''
+	v['CCLNK_TGT_F']=['-o']
+	v['LIB_ST']='-l%s'
+	v['LIBPATH_ST']='-L%s'
+	v['STLIB_ST']='-l%s'
+	v['STLIBPATH_ST']='-L%s'
+	v['cprogram_PATTERN']='%s'
+	v['cshlib_PATTERN']='lib%s.so'
+	v['cstlib_PATTERN']='lib%s.a'
+def configure(conf):
+	conf.find_irixcc()
+	conf.find_cpp()
+	conf.find_ar()
+	conf.irixcc_common_flags()
+	conf.cc_load_tools()
+	conf.cc_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/javaw.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/javaw.py
new file mode 100644
index 0000000..15f128c
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/javaw.py
@@ -0,0 +1,309 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,re,tempfile,shutil
+from waflib import TaskGen,Task,Utils,Options,Build,Errors,Node,Logs
+from waflib.Configure import conf
+from waflib.TaskGen import feature,before_method,after_method
+from waflib.Tools import ccroot
+ccroot.USELIB_VARS['javac']=set(['CLASSPATH','JAVACFLAGS'])
+SOURCE_RE='**/*.java'
+JAR_RE='**/*'
+class_check_source='''
+public class Test {
+	public static void main(String[] argv) {
+		Class lib;
+		if (argv.length < 1) {
+			System.err.println("Missing argument");
+			System.exit(77);
+		}
+		try {
+			lib = Class.forName(argv[0]);
+		} catch (ClassNotFoundException e) {
+			System.err.println("ClassNotFoundException");
+			System.exit(1);
+		}
+		lib = null;
+		System.exit(0);
+	}
+}
+'''
+@feature('javac')
+@before_method('process_source')
+def apply_java(self):
+	Utils.def_attrs(self,jarname='',classpath='',sourcepath='.',srcdir='.',jar_mf_attributes={},jar_mf_classpath=[])
+	nodes_lst=[]
+	outdir=getattr(self,'outdir',None)
+	if outdir:
+		if not isinstance(outdir,Node.Node):
+			outdir=self.path.get_bld().make_node(self.outdir)
+	else:
+		outdir=self.path.get_bld()
+	outdir.mkdir()
+	self.outdir=outdir
+	self.env['OUTDIR']=outdir.abspath()
+	self.javac_task=tsk=self.create_task('javac')
+	tmp=[]
+	srcdir=getattr(self,'srcdir','')
+	if isinstance(srcdir,Node.Node):
+		srcdir=[srcdir]
+	for x in Utils.to_list(srcdir):
+		if isinstance(x,Node.Node):
+			y=x
+		else:
+			y=self.path.find_dir(x)
+			if not y:
+				self.bld.fatal('Could not find the folder %s from %s'%(x,self.path))
+		tmp.append(y)
+	tsk.srcdir=tmp
+	if getattr(self,'compat',None):
+		tsk.env.append_value('JAVACFLAGS',['-source',self.compat])
+	if hasattr(self,'sourcepath'):
+		fold=[isinstance(x,Node.Node)and x or self.path.find_dir(x)for x in self.to_list(self.sourcepath)]
+		names=os.pathsep.join([x.srcpath()for x in fold])
+	else:
+		names=[x.srcpath()for x in tsk.srcdir]
+	if names:
+		tsk.env.append_value('JAVACFLAGS',['-sourcepath',names])
+@feature('javac')
+@after_method('apply_java')
+def use_javac_files(self):
+	lst=[]
+	self.uselib=self.to_list(getattr(self,'uselib',[]))
+	names=self.to_list(getattr(self,'use',[]))
+	get=self.bld.get_tgen_by_name
+	for x in names:
+		try:
+			y=get(x)
+		except Exception:
+			self.uselib.append(x)
+		else:
+			y.post()
+			lst.append(y.jar_task.outputs[0].abspath())
+			self.javac_task.set_run_after(y.jar_task)
+	if lst:
+		self.env.append_value('CLASSPATH',lst)
+@feature('javac')
+@after_method('apply_java','propagate_uselib_vars','use_javac_files')
+def set_classpath(self):
+	self.env.append_value('CLASSPATH',getattr(self,'classpath',[]))
+	for x in self.tasks:
+		x.env.CLASSPATH=os.pathsep.join(self.env.CLASSPATH)+os.pathsep
+@feature('jar')
+@after_method('apply_java','use_javac_files')
+@before_method('process_source')
+def jar_files(self):
+	destfile=getattr(self,'destfile','test.jar')
+	jaropts=getattr(self,'jaropts',[])
+	manifest=getattr(self,'manifest',None)
+	basedir=getattr(self,'basedir',None)
+	if basedir:
+		if not isinstance(self.basedir,Node.Node):
+			basedir=self.path.get_bld().make_node(basedir)
+	else:
+		basedir=self.path.get_bld()
+	if not basedir:
+		self.bld.fatal('Could not find the basedir %r for %r'%(self.basedir,self))
+	self.jar_task=tsk=self.create_task('jar_create')
+	if manifest:
+		jarcreate=getattr(self,'jarcreate','cfm')
+		node=self.path.find_node(manifest)
+		tsk.dep_nodes.append(node)
+		jaropts.insert(0,node.abspath())
+	else:
+		jarcreate=getattr(self,'jarcreate','cf')
+	if not isinstance(destfile,Node.Node):
+		destfile=self.path.find_or_declare(destfile)
+	if not destfile:
+		self.bld.fatal('invalid destfile %r for %r'%(destfile,self))
+	tsk.set_outputs(destfile)
+	tsk.basedir=basedir
+	jaropts.append('-C')
+	jaropts.append(basedir.bldpath())
+	jaropts.append('.')
+	tsk.env['JAROPTS']=jaropts
+	tsk.env['JARCREATE']=jarcreate
+	if getattr(self,'javac_task',None):
+		tsk.set_run_after(self.javac_task)
+@feature('jar')
+@after_method('jar_files')
+def use_jar_files(self):
+	lst=[]
+	self.uselib=self.to_list(getattr(self,'uselib',[]))
+	names=self.to_list(getattr(self,'use',[]))
+	get=self.bld.get_tgen_by_name
+	for x in names:
+		try:
+			y=get(x)
+		except Exception:
+			self.uselib.append(x)
+		else:
+			y.post()
+			self.jar_task.run_after.update(y.tasks)
+class jar_create(Task.Task):
+	color='GREEN'
+	run_str='${JAR} ${JARCREATE} ${TGT} ${JAROPTS}'
+	def runnable_status(self):
+		for t in self.run_after:
+			if not t.hasrun:
+				return Task.ASK_LATER
+		if not self.inputs:
+			global JAR_RE
+			try:
+				self.inputs=[x for x in self.basedir.ant_glob(JAR_RE,remove=False)if id(x)!=id(self.outputs[0])]
+			except Exception:
+				raise Errors.WafError('Could not find the basedir %r for %r'%(self.basedir,self))
+		return super(jar_create,self).runnable_status()
+class javac(Task.Task):
+	color='BLUE'
+	nocache=True
+	vars=['CLASSPATH','JAVACFLAGS','JAVAC','OUTDIR']
+	def runnable_status(self):
+		for t in self.run_after:
+			if not t.hasrun:
+				return Task.ASK_LATER
+		if not self.inputs:
+			global SOURCE_RE
+			self.inputs=[]
+			for x in self.srcdir:
+				self.inputs.extend(x.ant_glob(SOURCE_RE,remove=False))
+		return super(javac,self).runnable_status()
+	def run(self):
+		env=self.env
+		gen=self.generator
+		bld=gen.bld
+		wd=bld.bldnode.abspath()
+		def to_list(xx):
+			if isinstance(xx,str):return[xx]
+			return xx
+		cmd=[]
+		cmd.extend(to_list(env['JAVAC']))
+		cmd.extend(['-classpath'])
+		cmd.extend(to_list(env['CLASSPATH']))
+		cmd.extend(['-d'])
+		cmd.extend(to_list(env['OUTDIR']))
+		cmd.extend(to_list(env['JAVACFLAGS']))
+		files=[a.path_from(bld.bldnode)for a in self.inputs]
+		tmp=None
+		try:
+			if len(str(files))+len(str(cmd))>8192:
+				(fd,tmp)=tempfile.mkstemp(dir=bld.bldnode.abspath())
+				try:
+					os.write(fd,'\n'.join(files))
+				finally:
+					if tmp:
+						os.close(fd)
+				if Logs.verbose:
+					Logs.debug('runner: %r'%(cmd+files))
+				cmd.append('@'+tmp)
+			else:
+				cmd+=files
+			ret=self.exec_command(cmd,cwd=wd,env=env.env or None)
+		finally:
+			if tmp:
+				os.remove(tmp)
+		return ret
+	def post_run(self):
+		for n in self.generator.outdir.ant_glob('**/*.class'):
+			n.sig=Utils.h_file(n.abspath())
+		self.generator.bld.task_sigs[self.uid()]=self.cache_sig
+@feature('javadoc')
+@after_method('process_rule')
+def create_javadoc(self):
+	tsk=self.create_task('javadoc')
+	tsk.classpath=getattr(self,'classpath',[])
+	self.javadoc_package=Utils.to_list(self.javadoc_package)
+	if not isinstance(self.javadoc_output,Node.Node):
+		self.javadoc_output=self.bld.path.find_or_declare(self.javadoc_output)
+class javadoc(Task.Task):
+	color='BLUE'
+	def __str__(self):
+		return'%s: %s -> %s\n'%(self.__class__.__name__,self.generator.srcdir,self.generator.javadoc_output)
+	def run(self):
+		env=self.env
+		bld=self.generator.bld
+		wd=bld.bldnode.abspath()
+		srcpath=self.generator.path.abspath()+os.sep+self.generator.srcdir
+		srcpath+=os.pathsep
+		srcpath+=self.generator.path.get_bld().abspath()+os.sep+self.generator.srcdir
+		classpath=env.CLASSPATH
+		classpath+=os.pathsep
+		classpath+=os.pathsep.join(self.classpath)
+		classpath="".join(classpath)
+		self.last_cmd=lst=[]
+		lst.extend(Utils.to_list(env['JAVADOC']))
+		lst.extend(['-d',self.generator.javadoc_output.abspath()])
+		lst.extend(['-sourcepath',srcpath])
+		lst.extend(['-classpath',classpath])
+		lst.extend(['-subpackages'])
+		lst.extend(self.generator.javadoc_package)
+		lst=[x for x in lst if x]
+		self.generator.bld.cmd_and_log(lst,cwd=wd,env=env.env or None,quiet=0)
+	def post_run(self):
+		nodes=self.generator.javadoc_output.ant_glob('**')
+		for x in nodes:
+			x.sig=Utils.h_file(x.abspath())
+		self.generator.bld.task_sigs[self.uid()]=self.cache_sig
+def configure(self):
+	java_path=self.environ['PATH'].split(os.pathsep)
+	v=self.env
+	if'JAVA_HOME'in self.environ:
+		java_path=[os.path.join(self.environ['JAVA_HOME'],'bin')]+java_path
+		self.env['JAVA_HOME']=[self.environ['JAVA_HOME']]
+	for x in'javac java jar javadoc'.split():
+		self.find_program(x,var=x.upper(),path_list=java_path)
+		self.env[x.upper()]=self.cmd_to_list(self.env[x.upper()])
+	if'CLASSPATH'in self.environ:
+		v['CLASSPATH']=self.environ['CLASSPATH']
+	if not v['JAR']:self.fatal('jar is required for making java packages')
+	if not v['JAVAC']:self.fatal('javac is required for compiling java classes')
+	v['JARCREATE']='cf'
+	v['JAVACFLAGS']=[]
+@conf
+def check_java_class(self,classname,with_classpath=None):
+	javatestdir='.waf-javatest'
+	classpath=javatestdir
+	if self.env['CLASSPATH']:
+		classpath+=os.pathsep+self.env['CLASSPATH']
+	if isinstance(with_classpath,str):
+		classpath+=os.pathsep+with_classpath
+	shutil.rmtree(javatestdir,True)
+	os.mkdir(javatestdir)
+	Utils.writef(os.path.join(javatestdir,'Test.java'),class_check_source)
+	self.exec_command(self.env['JAVAC']+[os.path.join(javatestdir,'Test.java')],shell=False)
+	cmd=self.env['JAVA']+['-cp',classpath,'Test',classname]
+	self.to_log("%s\n"%str(cmd))
+	found=self.exec_command(cmd,shell=False)
+	self.msg('Checking for java class %s'%classname,not found)
+	shutil.rmtree(javatestdir,True)
+	return found
+@conf
+def check_jni_headers(conf):
+	if not conf.env.CC_NAME and not conf.env.CXX_NAME:
+		conf.fatal('load a compiler first (gcc, g++, ..)')
+	if not conf.env.JAVA_HOME:
+		conf.fatal('set JAVA_HOME in the system environment')
+	javaHome=conf.env['JAVA_HOME'][0]
+	dir=conf.root.find_dir(conf.env.JAVA_HOME[0]+'/include')
+	if dir is None:
+		dir=conf.root.find_dir(conf.env.JAVA_HOME[0]+'/../Headers')
+	if dir is None:
+		conf.fatal('JAVA_HOME does not seem to be set properly')
+	f=dir.ant_glob('**/(jni|jni_md).h')
+	incDirs=[x.parent.abspath()for x in f]
+	dir=conf.root.find_dir(conf.env.JAVA_HOME[0])
+	f=dir.ant_glob('**/*jvm.(so|dll|dylib)')
+	libDirs=[x.parent.abspath()for x in f]or[javaHome]
+	f=dir.ant_glob('**/*jvm.(lib)')
+	if f:
+		libDirs=[[x,y.parent.abspath()]for x in libDirs for y in f]
+	for d in libDirs:
+		try:
+			conf.check(header_name='jni.h',define_name='HAVE_JNI_H',lib='jvm',libpath=d,includes=incDirs,uselib_store='JAVA',uselib='JAVA')
+		except Exception:
+			pass
+		else:
+			break
+	else:
+		conf.fatal('could not find lib jvm in %r (see config.log)'%libDirs)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/kde4.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/kde4.py
new file mode 100644
index 0000000..cd51f5f
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/kde4.py
@@ -0,0 +1,48 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,re
+from waflib import Options,TaskGen,Task,Utils
+from waflib.TaskGen import feature,after_method
+@feature('msgfmt')
+def apply_msgfmt(self):
+	for lang in self.to_list(self.langs):
+		node=self.path.find_resource(lang+'.po')
+		task=self.create_task('msgfmt',node,node.change_ext('.mo'))
+		langname=lang.split('/')
+		langname=langname[-1]
+		inst=getattr(self,'install_path','${KDE4_LOCALE_INSTALL_DIR}')
+		self.bld.install_as(inst+os.sep+langname+os.sep+'LC_MESSAGES'+os.sep+getattr(self,'appname','set_your_appname')+'.mo',task.outputs[0],chmod=getattr(self,'chmod',Utils.O644))
+class msgfmt(Task.Task):
+	color='BLUE'
+	run_str='${MSGFMT} ${SRC} -o ${TGT}'
+def configure(self):
+	kdeconfig=self.find_program('kde4-config')
+	prefix=self.cmd_and_log('%s --prefix'%kdeconfig).strip()
+	fname='%s/share/apps/cmake/modules/KDELibsDependencies.cmake'%prefix
+	try:os.stat(fname)
+	except OSError:
+		fname='%s/share/kde4/apps/cmake/modules/KDELibsDependencies.cmake'%prefix
+		try:os.stat(fname)
+		except OSError:self.fatal('could not open %s'%fname)
+	try:
+		txt=Utils.readf(fname)
+	except(OSError,IOError):
+		self.fatal('could not read %s'%fname)
+	txt=txt.replace('\\\n','\n')
+	fu=re.compile('#(.*)\n')
+	txt=fu.sub('',txt)
+	setregexp=re.compile('([sS][eE][tT]\s*\()\s*([^\s]+)\s+\"([^"]+)\"\)')
+	found=setregexp.findall(txt)
+	for(_,key,val)in found:
+		self.env[key]=val
+	self.env['LIB_KDECORE']=['kdecore']
+	self.env['LIB_KDEUI']=['kdeui']
+	self.env['LIB_KIO']=['kio']
+	self.env['LIB_KHTML']=['khtml']
+	self.env['LIB_KPARTS']=['kparts']
+	self.env['LIBPATH_KDECORE']=[os.path.join(self.env.KDE4_LIB_INSTALL_DIR,'kde4','devel'),self.env.KDE4_LIB_INSTALL_DIR]
+	self.env['INCLUDES_KDECORE']=[self.env['KDE4_INCLUDE_INSTALL_DIR']]
+	self.env.append_value('INCLUDES_KDECORE',[self.env['KDE4_INCLUDE_INSTALL_DIR']+os.sep+'KDE'])
+	self.find_program('msgfmt',var='MSGFMT')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ldc2.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ldc2.py
new file mode 100644
index 0000000..25b99e5
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ldc2.py
@@ -0,0 +1,37 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys
+from waflib.Tools import ar,d
+from waflib.Configure import conf
+@conf
+def find_ldc2(conf):
+	conf.find_program(['ldc2'],var='D')
+	out=conf.cmd_and_log([conf.env.D,'-version'])
+	if out.find("based on DMD v2.")==-1:
+		conf.fatal("detected compiler is not ldc2")
+@conf
+def common_flags_ldc2(conf):
+	v=conf.env
+	v['D_SRC_F']=['-c']
+	v['D_TGT_F']='-of%s'
+	v['D_LINKER']=v['D']
+	v['DLNK_SRC_F']=''
+	v['DLNK_TGT_F']='-of%s'
+	v['DINC_ST']='-I%s'
+	v['DSHLIB_MARKER']=v['DSTLIB_MARKER']=''
+	v['DSTLIB_ST']=v['DSHLIB_ST']='-L-l%s'
+	v['DSTLIBPATH_ST']=v['DLIBPATH_ST']='-L-L%s'
+	v['LINKFLAGS_dshlib']=['-L-shared']
+	v['DHEADER_ext']='.di'
+	v['DFLAGS_d_with_header']=['-H','-Hf']
+	v['D_HDR_F']='%s'
+	v['LINKFLAGS']=[]
+	v['DFLAGS_dshlib']=['-relocation-model=pic']
+def configure(conf):
+	conf.find_ldc2()
+	conf.load('ar')
+	conf.load('d')
+	conf.common_flags_ldc2()
+	conf.d_platform_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/lua.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/lua.py
new file mode 100644
index 0000000..a0a35fc
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/lua.py
@@ -0,0 +1,18 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib.TaskGen import extension
+from waflib import Task,Utils
+@extension('.lua')
+def add_lua(self,node):
+	tsk=self.create_task('luac',node,node.change_ext('.luac'))
+	inst_to=getattr(self,'install_path',self.env.LUADIR and'${LUADIR}'or None)
+	if inst_to:
+		self.bld.install_files(inst_to,tsk.outputs)
+	return tsk
+class luac(Task.Task):
+	run_str='${LUAC} -s -o ${TGT} ${SRC}'
+	color='PINK'
+def configure(conf):
+	conf.find_program('luac',var='LUAC')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/msvc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/msvc.py
new file mode 100644
index 0000000..9ac0a59
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/msvc.py
@@ -0,0 +1,750 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,re,tempfile
+from waflib import Utils,Task,Logs,Options,Errors
+from waflib.Logs import debug,warn
+from waflib.TaskGen import after_method,feature
+from waflib.Configure import conf
+from waflib.Tools import ccroot,c,cxx,ar,winres
+g_msvc_systemlibs='''
+aclui activeds ad1 adptif adsiid advapi32 asycfilt authz bhsupp bits bufferoverflowu cabinet
+cap certadm certidl ciuuid clusapi comctl32 comdlg32 comsupp comsuppd comsuppw comsuppwd comsvcs
+credui crypt32 cryptnet cryptui d3d8thk daouuid dbgeng dbghelp dciman32 ddao35 ddao35d
+ddao35u ddao35ud delayimp dhcpcsvc dhcpsapi dlcapi dnsapi dsprop dsuiext dtchelp
+faultrep fcachdll fci fdi framedyd framedyn gdi32 gdiplus glauxglu32 gpedit gpmuuid
+gtrts32w gtrtst32hlink htmlhelp httpapi icm32 icmui imagehlp imm32 iphlpapi iprop
+kernel32 ksguid ksproxy ksuser libcmt libcmtd libcpmt libcpmtd loadperf lz32 mapi
+mapi32 mgmtapi minidump mmc mobsync mpr mprapi mqoa mqrt msacm32 mscms mscoree
+msdasc msimg32 msrating mstask msvcmrt msvcurt msvcurtd mswsock msxml2 mtx mtxdm
+netapi32 nmapinmsupp npptools ntdsapi ntdsbcli ntmsapi ntquery odbc32 odbcbcp
+odbccp32 oldnames ole32 oleacc oleaut32 oledb oledlgolepro32 opends60 opengl32
+osptk parser pdh penter pgobootrun pgort powrprof psapi ptrustm ptrustmd ptrustu
+ptrustud qosname rasapi32 rasdlg rassapi resutils riched20 rpcndr rpcns4 rpcrt4 rtm
+rtutils runtmchk scarddlg scrnsave scrnsavw secur32 sensapi setupapi sfc shell32
+shfolder shlwapi sisbkup snmpapi sporder srclient sti strsafe svcguid tapi32 thunk32
+traffic unicows url urlmon user32 userenv usp10 uuid uxtheme vcomp vcompd vdmdbg
+version vfw32 wbemuuid  webpost wiaguid wininet winmm winscard winspool winstrm
+wintrust wldap32 wmiutils wow32 ws2_32 wsnmp32 wsock32 wst wtsapi32 xaswitch xolehlp
+'''.split()
+all_msvc_platforms=[('x64','amd64'),('x86','x86'),('ia64','ia64'),('x86_amd64','amd64'),('x86_ia64','ia64'),('x86_arm','arm')]
+all_wince_platforms=[('armv4','arm'),('armv4i','arm'),('mipsii','mips'),('mipsii_fp','mips'),('mipsiv','mips'),('mipsiv_fp','mips'),('sh4','sh'),('x86','cex86')]
+all_icl_platforms=[('intel64','amd64'),('em64t','amd64'),('ia32','x86'),('Itanium','ia64')]
+def options(opt):
+	opt.add_option('--msvc_version',type='string',help='msvc version, eg: "msvc 10.0,msvc 9.0"',default='')
+	opt.add_option('--msvc_targets',type='string',help='msvc targets, eg: "x64,arm"',default='')
+def setup_msvc(conf,versions,arch=False):
+	platforms=getattr(Options.options,'msvc_targets','').split(',')
+	if platforms==['']:
+		platforms=Utils.to_list(conf.env['MSVC_TARGETS'])or[i for i,j in all_msvc_platforms+all_icl_platforms+all_wince_platforms]
+	desired_versions=getattr(Options.options,'msvc_version','').split(',')
+	if desired_versions==['']:
+		desired_versions=conf.env['MSVC_VERSIONS']or[v for v,_ in versions][::-1]
+	versiondict=dict(versions)
+	for version in desired_versions:
+		try:
+			targets=dict(versiondict[version])
+			for target in platforms:
+				try:
+					arch,(p1,p2,p3)=targets[target]
+					compiler,revision=version.rsplit(' ',1)
+					if arch:
+						return compiler,revision,p1,p2,p3,arch
+					else:
+						return compiler,revision,p1,p2,p3
+				except KeyError:continue
+		except KeyError:continue
+	conf.fatal('msvc: Impossible to find a valid architecture for building (in setup_msvc)')
+@conf
+def get_msvc_version(conf,compiler,version,target,vcvars):
+	debug('msvc: get_msvc_version: %r %r %r',compiler,version,target)
+	batfile=conf.bldnode.make_node('waf-print-msvc.bat')
+	batfile.write("""@echo off
+set INCLUDE=
+set LIB=
+call "%s" %s
+echo PATH=%%PATH%%
+echo INCLUDE=%%INCLUDE%%
+echo LIB=%%LIB%%;%%LIBPATH%%
+"""%(vcvars,target))
+	sout=conf.cmd_and_log(['cmd','/E:on','/V:on','/C',batfile.abspath()])
+	lines=sout.splitlines()
+	if not lines[0]:
+		lines.pop(0)
+	MSVC_PATH=MSVC_INCDIR=MSVC_LIBDIR=None
+	for line in lines:
+		if line.startswith('PATH='):
+			path=line[5:]
+			MSVC_PATH=path.split(';')
+		elif line.startswith('INCLUDE='):
+			MSVC_INCDIR=[i for i in line[8:].split(';')if i]
+		elif line.startswith('LIB='):
+			MSVC_LIBDIR=[i for i in line[4:].split(';')if i]
+	if None in(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR):
+		conf.fatal('msvc: Could not find a valid architecture for building (get_msvc_version_3)')
+	env=dict(os.environ)
+	env.update(PATH=path)
+	compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
+	cxx=conf.find_program(compiler_name,path_list=MSVC_PATH)
+	cxx=conf.cmd_to_list(cxx)
+	if'CL'in env:
+		del(env['CL'])
+	try:
+		try:
+			conf.cmd_and_log(cxx+['/help'],env=env)
+		except Exception ,e:
+			debug('msvc: get_msvc_version: %r %r %r -> failure'%(compiler,version,target))
+			debug(str(e))
+			conf.fatal('msvc: cannot run the compiler (in get_msvc_version)')
+		else:
+			debug('msvc: get_msvc_version: %r %r %r -> OK',compiler,version,target)
+	finally:
+		conf.env[compiler_name]=''
+	return(MSVC_PATH,MSVC_INCDIR,MSVC_LIBDIR)
+@conf
+def gather_wsdk_versions(conf,versions):
+	version_pattern=re.compile('^v..?.?\...?.?')
+	try:
+		all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Microsoft SDKs\\Windows')
+	except WindowsError:
+		try:
+			all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows')
+		except WindowsError:
+			return
+	index=0
+	while 1:
+		try:
+			version=Utils.winreg.EnumKey(all_versions,index)
+		except WindowsError:
+			break
+		index=index+1
+		if not version_pattern.match(version):
+			continue
+		try:
+			msvc_version=Utils.winreg.OpenKey(all_versions,version)
+			path,type=Utils.winreg.QueryValueEx(msvc_version,'InstallationFolder')
+		except WindowsError:
+			continue
+		if os.path.isfile(os.path.join(path,'bin','SetEnv.cmd')):
+			targets=[]
+			for target,arch in all_msvc_platforms:
+				try:
+					targets.append((target,(arch,conf.get_msvc_version('wsdk',version,'/'+target,os.path.join(path,'bin','SetEnv.cmd')))))
+				except conf.errors.ConfigurationError:
+					pass
+			versions.append(('wsdk '+version[1:],targets))
+def gather_wince_supported_platforms():
+	supported_wince_platforms=[]
+	try:
+		ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Microsoft\\Windows CE Tools\\SDKs')
+	except WindowsError:
+		try:
+			ce_sdk=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Microsoft\\Windows CE Tools\\SDKs')
+		except WindowsError:
+			ce_sdk=''
+	if not ce_sdk:
+		return supported_wince_platforms
+	ce_index=0
+	while 1:
+		try:
+			sdk_device=Utils.winreg.EnumKey(ce_sdk,ce_index)
+		except WindowsError:
+			break
+		ce_index=ce_index+1
+		sdk=Utils.winreg.OpenKey(ce_sdk,sdk_device)
+		try:
+			path,type=Utils.winreg.QueryValueEx(sdk,'SDKRootDir')
+		except WindowsError:
+			try:
+				path,type=Utils.winreg.QueryValueEx(sdk,'SDKInformation')
+				path,xml=os.path.split(path)
+			except WindowsError:
+				continue
+		path=str(path)
+		path,device=os.path.split(path)
+		if not device:
+			path,device=os.path.split(path)
+		for arch,compiler in all_wince_platforms:
+			platforms=[]
+			if os.path.isdir(os.path.join(path,device,'Lib',arch)):
+				platforms.append((arch,compiler,os.path.join(path,device,'Include',arch),os.path.join(path,device,'Lib',arch)))
+			if platforms:
+				supported_wince_platforms.append((device,platforms))
+	return supported_wince_platforms
+def gather_msvc_detected_versions():
+	version_pattern=re.compile('^(\d\d?\.\d\d?)(Exp)?$')
+	detected_versions=[]
+	for vcver,vcvar in[('VCExpress','Exp'),('VisualStudio','')]:
+		try:
+			prefix='SOFTWARE\\Wow6432node\\Microsoft\\'+vcver
+			all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
+		except WindowsError:
+			try:
+				prefix='SOFTWARE\\Microsoft\\'+vcver
+				all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,prefix)
+			except WindowsError:
+				continue
+		index=0
+		while 1:
+			try:
+				version=Utils.winreg.EnumKey(all_versions,index)
+			except WindowsError:
+				break
+			index=index+1
+			match=version_pattern.match(version)
+			if not match:
+				continue
+			else:
+				versionnumber=float(match.group(1))
+			detected_versions.append((versionnumber,version+vcvar,prefix+"\\"+version))
+	def fun(tup):
+		return tup[0]
+	detected_versions.sort(key=fun)
+	return detected_versions
+@conf
+def gather_msvc_targets(conf,versions,version,vc_path):
+	targets=[]
+	if os.path.isfile(os.path.join(vc_path,'vcvarsall.bat')):
+		for target,realtarget in all_msvc_platforms[::-1]:
+			try:
+				targets.append((target,(realtarget,conf.get_msvc_version('msvc',version,target,os.path.join(vc_path,'vcvarsall.bat')))))
+			except conf.errors.ConfigurationError:
+				pass
+	elif os.path.isfile(os.path.join(vc_path,'Common7','Tools','vsvars32.bat')):
+		try:
+			targets.append(('x86',('x86',conf.get_msvc_version('msvc',version,'x86',os.path.join(vc_path,'Common7','Tools','vsvars32.bat')))))
+		except conf.errors.ConfigurationError:
+			pass
+	elif os.path.isfile(os.path.join(vc_path,'Bin','vcvars32.bat')):
+		try:
+			targets.append(('x86',('x86',conf.get_msvc_version('msvc',version,'',os.path.join(vc_path,'Bin','vcvars32.bat')))))
+		except conf.errors.ConfigurationError:
+			pass
+	if targets:
+		versions.append(('msvc '+version,targets))
+@conf
+def gather_wince_targets(conf,versions,version,vc_path,vsvars,supported_platforms):
+	for device,platforms in supported_platforms:
+		cetargets=[]
+		for platform,compiler,include,lib in platforms:
+			winCEpath=os.path.join(vc_path,'ce')
+			if not os.path.isdir(winCEpath):
+				continue
+			try:
+				common_bindirs,_1,_2=conf.get_msvc_version('msvc',version,'x86',vsvars)
+			except conf.errors.ConfigurationError:
+				continue
+			if os.path.isdir(os.path.join(winCEpath,'lib',platform)):
+				bindirs=[os.path.join(winCEpath,'bin',compiler),os.path.join(winCEpath,'bin','x86_'+compiler)]+common_bindirs
+				incdirs=[os.path.join(winCEpath,'include'),os.path.join(winCEpath,'atlmfc','include'),include]
+				libdirs=[os.path.join(winCEpath,'lib',platform),os.path.join(winCEpath,'atlmfc','lib',platform),lib]
+				cetargets.append((platform,(platform,(bindirs,incdirs,libdirs))))
+		if cetargets:
+			versions.append((device+' '+version,cetargets))
+@conf
+def gather_winphone_targets(conf,versions,version,vc_path,vsvars):
+	targets=[]
+	for target,realtarget in all_msvc_platforms[::-1]:
+		try:
+			targets.append((target,(realtarget,conf.get_msvc_version('winphone',version,target,vsvars))))
+		except conf.errors.ConfigurationError ,e:
+			pass
+	if targets:
+		versions.append(('winphone '+version,targets))
+@conf
+def gather_msvc_versions(conf,versions):
+	vc_paths=[]
+	for(v,version,reg)in gather_msvc_detected_versions():
+		try:
+			try:
+				msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\VC")
+			except WindowsError:
+				msvc_version=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,reg+"\\Setup\\Microsoft Visual C++")
+			path,type=Utils.winreg.QueryValueEx(msvc_version,'ProductDir')
+			vc_paths.append((version,os.path.abspath(str(path))))
+		except WindowsError:
+			continue
+	wince_supported_platforms=gather_wince_supported_platforms()
+	for version,vc_path in vc_paths:
+		vs_path=os.path.dirname(vc_path)
+		vsvars=os.path.join(vs_path,'Common7','Tools','vsvars32.bat')
+		if wince_supported_platforms and os.path.isfile(vsvars):
+			conf.gather_wince_targets(versions,version,vc_path,vsvars,wince_supported_platforms)
+		vsvars=os.path.join(vs_path,'VC','WPSDK','WP80','vcvarsphoneall.bat')
+		if os.path.isfile(vsvars):
+			conf.gather_winphone_targets(versions,'8.0',vc_path,vsvars)
+	for version,vc_path in vc_paths:
+		vs_path=os.path.dirname(vc_path)
+		conf.gather_msvc_targets(versions,version,vc_path)
+@conf
+def gather_icl_versions(conf,versions):
+	version_pattern=re.compile('^...?.?\....?.?')
+	try:
+		all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Compilers\\C++')
+	except WindowsError:
+		try:
+			all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Compilers\\C++')
+		except WindowsError:
+			return
+	index=0
+	while 1:
+		try:
+			version=Utils.winreg.EnumKey(all_versions,index)
+		except WindowsError:
+			break
+		index=index+1
+		if not version_pattern.match(version):
+			continue
+		targets=[]
+		for target,arch in all_icl_platforms:
+			try:
+				if target=='intel64':targetDir='EM64T_NATIVE'
+				else:targetDir=target
+				Utils.winreg.OpenKey(all_versions,version+'\\'+targetDir)
+				icl_version=Utils.winreg.OpenKey(all_versions,version)
+				path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
+				batch_file=os.path.join(path,'bin','iclvars.bat')
+				if os.path.isfile(batch_file):
+					try:
+						targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file))))
+					except conf.errors.ConfigurationError:
+						pass
+			except WindowsError:
+				pass
+		for target,arch in all_icl_platforms:
+			try:
+				icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+target)
+				path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
+				batch_file=os.path.join(path,'bin','iclvars.bat')
+				if os.path.isfile(batch_file):
+					try:
+						targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file))))
+					except conf.errors.ConfigurationError:
+						pass
+			except WindowsError:
+				continue
+		major=version[0:2]
+		versions.append(('intel '+major,targets))
+@conf
+def gather_intel_composer_versions(conf,versions):
+	version_pattern=re.compile('^...?.?\...?.?.?')
+	try:
+		all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432node\\Intel\\Suites')
+	except WindowsError:
+		try:
+			all_versions=Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Intel\\Suites')
+		except WindowsError:
+			return
+	index=0
+	while 1:
+		try:
+			version=Utils.winreg.EnumKey(all_versions,index)
+		except WindowsError:
+			break
+		index=index+1
+		if not version_pattern.match(version):
+			continue
+		targets=[]
+		for target,arch in all_icl_platforms:
+			try:
+				if target=='intel64':targetDir='EM64T_NATIVE'
+				else:targetDir=target
+				try:
+					defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\'+targetDir)
+				except WindowsError:
+					if targetDir=='EM64T_NATIVE':
+						defaults=Utils.winreg.OpenKey(all_versions,version+'\\Defaults\\C++\\EM64T')
+					else:
+						raise WindowsError
+				uid,type=Utils.winreg.QueryValueEx(defaults,'SubKey')
+				Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++\\'+targetDir)
+				icl_version=Utils.winreg.OpenKey(all_versions,version+'\\'+uid+'\\C++')
+				path,type=Utils.winreg.QueryValueEx(icl_version,'ProductDir')
+				batch_file=os.path.join(path,'bin','iclvars.bat')
+				if os.path.isfile(batch_file):
+					try:
+						targets.append((target,(arch,conf.get_msvc_version('intel',version,target,batch_file))))
+					except conf.errors.ConfigurationError ,e:
+						pass
+				compilervars_warning_attr='_compilervars_warning_key'
+				if version[0:2]=='13'and getattr(conf,compilervars_warning_attr,True):
+					setattr(conf,compilervars_warning_attr,False)
+					patch_url='http://software.intel.com/en-us/forums/topic/328487'
+					compilervars_arch=os.path.join(path,'bin','compilervars_arch.bat')
+					for vscomntools in['VS110COMNTOOLS','VS100COMNTOOLS']:
+						if os.environ.has_key(vscomntools):
+							vs_express_path=os.environ[vscomntools]+r'..\IDE\VSWinExpress.exe'
+							dev_env_path=os.environ[vscomntools]+r'..\IDE\devenv.exe'
+							if(r'if exist "%VS110COMNTOOLS%..\IDE\VSWinExpress.exe"'in Utils.readf(compilervars_arch)and not os.path.exists(vs_express_path)and not os.path.exists(dev_env_path)):
+								Logs.warn(('The Intel compilervar_arch.bat only checks for one Visual Studio SKU ''(VSWinExpress.exe) but it does not seem to be installed at %r. ''The intel command line set up will fail to configure unless the file %r''is patched. See: %s')%(vs_express_path,compilervars_arch,patch_url))
+			except WindowsError:
+				pass
+		major=version[0:2]
+		versions.append(('intel '+major,targets))
+@conf
+def get_msvc_versions(conf):
+	if not conf.env['MSVC_INSTALLED_VERSIONS']:
+		lst=[]
+		conf.gather_icl_versions(lst)
+		conf.gather_intel_composer_versions(lst)
+		conf.gather_wsdk_versions(lst)
+		conf.gather_msvc_versions(lst)
+		conf.env['MSVC_INSTALLED_VERSIONS']=lst
+	return conf.env['MSVC_INSTALLED_VERSIONS']
+@conf
+def print_all_msvc_detected(conf):
+	for version,targets in conf.env['MSVC_INSTALLED_VERSIONS']:
+		Logs.info(version)
+		for target,l in targets:
+			Logs.info("\t"+target)
+@conf
+def detect_msvc(conf,arch=False):
+	versions=get_msvc_versions(conf)
+	return setup_msvc(conf,versions,arch)
+@conf
+def find_lt_names_msvc(self,libname,is_static=False):
+	lt_names=['lib%s.la'%libname,'%s.la'%libname,]
+	for path in self.env['LIBPATH']:
+		for la in lt_names:
+			laf=os.path.join(path,la)
+			dll=None
+			if os.path.exists(laf):
+				ltdict=Utils.read_la_file(laf)
+				lt_libdir=None
+				if ltdict.get('libdir',''):
+					lt_libdir=ltdict['libdir']
+				if not is_static and ltdict.get('library_names',''):
+					dllnames=ltdict['library_names'].split()
+					dll=dllnames[0].lower()
+					dll=re.sub('\.dll$','',dll)
+					return(lt_libdir,dll,False)
+				elif ltdict.get('old_library',''):
+					olib=ltdict['old_library']
+					if os.path.exists(os.path.join(path,olib)):
+						return(path,olib,True)
+					elif lt_libdir!=''and os.path.exists(os.path.join(lt_libdir,olib)):
+						return(lt_libdir,olib,True)
+					else:
+						return(None,olib,True)
+				else:
+					raise self.errors.WafError('invalid libtool object file: %s'%laf)
+	return(None,None,None)
+@conf
+def libname_msvc(self,libname,is_static=False):
+	lib=libname.lower()
+	lib=re.sub('\.lib$','',lib)
+	if lib in g_msvc_systemlibs:
+		return lib
+	lib=re.sub('^lib','',lib)
+	if lib=='m':
+		return None
+	(lt_path,lt_libname,lt_static)=self.find_lt_names_msvc(lib,is_static)
+	if lt_path!=None and lt_libname!=None:
+		if lt_static==True:
+			return os.path.join(lt_path,lt_libname)
+	if lt_path!=None:
+		_libpaths=[lt_path]+self.env['LIBPATH']
+	else:
+		_libpaths=self.env['LIBPATH']
+	static_libs=['lib%ss.lib'%lib,'lib%s.lib'%lib,'%ss.lib'%lib,'%s.lib'%lib,]
+	dynamic_libs=['lib%s.dll.lib'%lib,'lib%s.dll.a'%lib,'%s.dll.lib'%lib,'%s.dll.a'%lib,'lib%s_d.lib'%lib,'%s_d.lib'%lib,'%s.lib'%lib,]
+	libnames=static_libs
+	if not is_static:
+		libnames=dynamic_libs+static_libs
+	for path in _libpaths:
+		for libn in libnames:
+			if os.path.exists(os.path.join(path,libn)):
+				debug('msvc: lib found: %s'%os.path.join(path,libn))
+				return re.sub('\.lib$','',libn)
+	self.fatal("The library %r could not be found"%libname)
+	return re.sub('\.lib$','',libname)
+@conf
+def check_lib_msvc(self,libname,is_static=False,uselib_store=None):
+	libn=self.libname_msvc(libname,is_static)
+	if not uselib_store:
+		uselib_store=libname.upper()
+	if False and is_static:
+		self.env['STLIB_'+uselib_store]=[libn]
+	else:
+		self.env['LIB_'+uselib_store]=[libn]
+@conf
+def check_libs_msvc(self,libnames,is_static=False):
+	for libname in Utils.to_list(libnames):
+		self.check_lib_msvc(libname,is_static)
+def configure(conf):
+	conf.autodetect(True)
+	conf.find_msvc()
+	conf.msvc_common_flags()
+	conf.cc_load_tools()
+	conf.cxx_load_tools()
+	conf.cc_add_flags()
+	conf.cxx_add_flags()
+	conf.link_add_flags()
+	conf.visual_studio_add_flags()
+@conf
+def no_autodetect(conf):
+	conf.env.NO_MSVC_DETECT=1
+	configure(conf)
+@conf
+def autodetect(conf,arch=False):
+	v=conf.env
+	if v.NO_MSVC_DETECT:
+		return
+	if arch:
+		compiler,version,path,includes,libdirs,arch=conf.detect_msvc(True)
+		v['DEST_CPU']=arch
+	else:
+		compiler,version,path,includes,libdirs=conf.detect_msvc()
+	v['PATH']=path
+	v['INCLUDES']=includes
+	v['LIBPATH']=libdirs
+	v['MSVC_COMPILER']=compiler
+	try:
+		v['MSVC_VERSION']=float(version)
+	except Exception:
+		v['MSVC_VERSION']=float(version[:-3])
+def _get_prog_names(conf,compiler):
+	if compiler=='intel':
+		compiler_name='ICL'
+		linker_name='XILINK'
+		lib_name='XILIB'
+	else:
+		compiler_name='CL'
+		linker_name='LINK'
+		lib_name='LIB'
+	return compiler_name,linker_name,lib_name
+@conf
+def find_msvc(conf):
+	if sys.platform=='cygwin':
+		conf.fatal('MSVC module does not work under cygwin Python!')
+	v=conf.env
+	path=v['PATH']
+	compiler=v['MSVC_COMPILER']
+	version=v['MSVC_VERSION']
+	compiler_name,linker_name,lib_name=_get_prog_names(conf,compiler)
+	v.MSVC_MANIFEST=(compiler=='msvc'and version>=8)or(compiler=='wsdk'and version>=6)or(compiler=='intel'and version>=11)
+	cxx=None
+	if v['CXX']:cxx=v['CXX']
+	elif'CXX'in conf.environ:cxx=conf.environ['CXX']
+	cxx=conf.find_program(compiler_name,var='CXX',path_list=path)
+	cxx=conf.cmd_to_list(cxx)
+	env=dict(conf.environ)
+	if path:env.update(PATH=';'.join(path))
+	if not conf.cmd_and_log(cxx+['/nologo','/help'],env=env):
+		conf.fatal('the msvc compiler could not be identified')
+	v['CC']=v['CXX']=cxx
+	v['CC_NAME']=v['CXX_NAME']='msvc'
+	if not v['LINK_CXX']:
+		link=conf.find_program(linker_name,path_list=path)
+		if link:v['LINK_CXX']=link
+		else:conf.fatal('%s was not found (linker)'%linker_name)
+		v['LINK']=link
+	if not v['LINK_CC']:
+		v['LINK_CC']=v['LINK_CXX']
+	if not v['AR']:
+		stliblink=conf.find_program(lib_name,path_list=path,var='AR')
+		if not stliblink:return
+		v['ARFLAGS']=['/NOLOGO']
+	if v.MSVC_MANIFEST:
+		conf.find_program('MT',path_list=path,var='MT')
+		v['MTFLAGS']=['/NOLOGO']
+	try:
+		conf.load('winres')
+	except Errors.WafError:
+		warn('Resource compiler not found. Compiling resource file is disabled')
+@conf
+def visual_studio_add_flags(self):
+	v=self.env
+	try:v.prepend_value('INCLUDES',[x for x in self.environ['INCLUDE'].split(';')if x])
+	except Exception:pass
+	try:v.prepend_value('LIBPATH',[x for x in self.environ['LIB'].split(';')if x])
+	except Exception:pass
+@conf
+def msvc_common_flags(conf):
+	v=conf.env
+	v['DEST_BINFMT']='pe'
+	v.append_value('CFLAGS',['/nologo'])
+	v.append_value('CXXFLAGS',['/nologo'])
+	v['DEFINES_ST']='/D%s'
+	v['CC_SRC_F']=''
+	v['CC_TGT_F']=['/c','/Fo']
+	if v['MSVC_VERSION']>=8:
+		v['CC_TGT_F']=['/FC']+v['CC_TGT_F']
+	v['CXX_SRC_F']=''
+	v['CXX_TGT_F']=['/c','/Fo']
+	if v['MSVC_VERSION']>=8:
+		v['CXX_TGT_F']=['/FC']+v['CXX_TGT_F']
+	v['CPPPATH_ST']='/I%s'
+	v['AR_TGT_F']=v['CCLNK_TGT_F']=v['CXXLNK_TGT_F']='/OUT:'
+	v['CFLAGS_CONSOLE']=v['CXXFLAGS_CONSOLE']=['/SUBSYSTEM:CONSOLE']
+	v['CFLAGS_NATIVE']=v['CXXFLAGS_NATIVE']=['/SUBSYSTEM:NATIVE']
+	v['CFLAGS_POSIX']=v['CXXFLAGS_POSIX']=['/SUBSYSTEM:POSIX']
+	v['CFLAGS_WINDOWS']=v['CXXFLAGS_WINDOWS']=['/SUBSYSTEM:WINDOWS']
+	v['CFLAGS_WINDOWSCE']=v['CXXFLAGS_WINDOWSCE']=['/SUBSYSTEM:WINDOWSCE']
+	v['CFLAGS_CRT_MULTITHREADED']=v['CXXFLAGS_CRT_MULTITHREADED']=['/MT']
+	v['CFLAGS_CRT_MULTITHREADED_DLL']=v['CXXFLAGS_CRT_MULTITHREADED_DLL']=['/MD']
+	v['CFLAGS_CRT_MULTITHREADED_DBG']=v['CXXFLAGS_CRT_MULTITHREADED_DBG']=['/MTd']
+	v['CFLAGS_CRT_MULTITHREADED_DLL_DBG']=v['CXXFLAGS_CRT_MULTITHREADED_DLL_DBG']=['/MDd']
+	v['LIB_ST']='%s.lib'
+	v['LIBPATH_ST']='/LIBPATH:%s'
+	v['STLIB_ST']='%s.lib'
+	v['STLIBPATH_ST']='/LIBPATH:%s'
+	v.append_value('LINKFLAGS',['/NOLOGO'])
+	if v['MSVC_MANIFEST']:
+		v.append_value('LINKFLAGS',['/MANIFEST'])
+	v['CFLAGS_cshlib']=[]
+	v['CXXFLAGS_cxxshlib']=[]
+	v['LINKFLAGS_cshlib']=v['LINKFLAGS_cxxshlib']=['/DLL']
+	v['cshlib_PATTERN']=v['cxxshlib_PATTERN']='%s.dll'
+	v['implib_PATTERN']='%s.lib'
+	v['IMPLIB_ST']='/IMPLIB:%s'
+	v['LINKFLAGS_cstlib']=[]
+	v['cstlib_PATTERN']=v['cxxstlib_PATTERN']='%s.lib'
+	v['cprogram_PATTERN']=v['cxxprogram_PATTERN']='%s.exe'
+@after_method('apply_link')
+@feature('c','cxx')
+def apply_flags_msvc(self):
+	if self.env.CC_NAME!='msvc'or not getattr(self,'link_task',None):
+		return
+	is_static=isinstance(self.link_task,ccroot.stlink_task)
+	subsystem=getattr(self,'subsystem','')
+	if subsystem:
+		subsystem='/subsystem:%s'%subsystem
+		flags=is_static and'ARFLAGS'or'LINKFLAGS'
+		self.env.append_value(flags,subsystem)
+	if not is_static:
+		for f in self.env.LINKFLAGS:
+			d=f.lower()
+			if d[1:]=='debug':
+				pdbnode=self.link_task.outputs[0].change_ext('.pdb')
+				self.link_task.outputs.append(pdbnode)
+				try:
+					self.install_task.source.append(pdbnode)
+				except AttributeError:
+					pass
+				break
+@feature('cprogram','cshlib','cxxprogram','cxxshlib')
+@after_method('apply_link')
+def apply_manifest(self):
+	if self.env.CC_NAME=='msvc'and self.env.MSVC_MANIFEST and getattr(self,'link_task',None):
+		out_node=self.link_task.outputs[0]
+		man_node=out_node.parent.find_or_declare(out_node.name+'.manifest')
+		self.link_task.outputs.append(man_node)
+		self.link_task.do_manifest=True
+def exec_mf(self):
+	env=self.env
+	mtool=env['MT']
+	if not mtool:
+		return 0
+	self.do_manifest=False
+	outfile=self.outputs[0].abspath()
+	manifest=None
+	for out_node in self.outputs:
+		if out_node.name.endswith('.manifest'):
+			manifest=out_node.abspath()
+			break
+	if manifest is None:
+		return 0
+	mode=''
+	if'cprogram'in self.generator.features or'cxxprogram'in self.generator.features:
+		mode='1'
+	elif'cshlib'in self.generator.features or'cxxshlib'in self.generator.features:
+		mode='2'
+	debug('msvc: embedding manifest in mode %r'%mode)
+	lst=[]
+	lst.append(env['MT'])
+	lst.extend(Utils.to_list(env['MTFLAGS']))
+	lst.extend(['-manifest',manifest])
+	lst.append('-outputresource:%s;%s'%(outfile,mode))
+	lst=[lst]
+	return self.exec_command(*lst)
+def quote_response_command(self,flag):
+	if flag.find(' ')>-1:
+		for x in('/LIBPATH:','/IMPLIB:','/OUT:','/I'):
+			if flag.startswith(x):
+				flag='%s"%s"'%(x,flag[len(x):])
+				break
+		else:
+			flag='"%s"'%flag
+	return flag
+def exec_response_command(self,cmd,**kw):
+	try:
+		tmp=None
+		if sys.platform.startswith('win')and isinstance(cmd,list)and len(' '.join(cmd))>=8192:
+			program=cmd[0]
+			cmd=[self.quote_response_command(x)for x in cmd]
+			(fd,tmp)=tempfile.mkstemp()
+			os.write(fd,'\r\n'.join(i.replace('\\','\\\\')for i in cmd[1:]))
+			os.close(fd)
+			cmd=[program,'@'+tmp]
+		ret=self.generator.bld.exec_command(cmd,**kw)
+	finally:
+		if tmp:
+			try:
+				os.remove(tmp)
+			except OSError:
+				pass
+	return ret
+def exec_command_msvc(self,*k,**kw):
+	if isinstance(k[0],list):
+		lst=[]
+		carry=''
+		for a in k[0]:
+			if a=='/Fo'or a=='/doc'or a[-1]==':':
+				carry=a
+			else:
+				lst.append(carry+a)
+				carry=''
+		k=[lst]
+	if self.env['PATH']:
+		env=dict(self.env.env or os.environ)
+		env.update(PATH=';'.join(self.env['PATH']))
+		kw['env']=env
+	bld=self.generator.bld
+	try:
+		if not kw.get('cwd',None):
+			kw['cwd']=bld.cwd
+	except AttributeError:
+		bld.cwd=kw['cwd']=bld.variant_dir
+	ret=self.exec_response_command(k[0],**kw)
+	if not ret and getattr(self,'do_manifest',None):
+		ret=self.exec_mf()
+	return ret
+def wrap_class(class_name):
+	cls=Task.classes.get(class_name,None)
+	if not cls:
+		return None
+	derived_class=type(class_name,(cls,),{})
+	def exec_command(self,*k,**kw):
+		if self.env['CC_NAME']=='msvc':
+			return self.exec_command_msvc(*k,**kw)
+		else:
+			return super(derived_class,self).exec_command(*k,**kw)
+	derived_class.exec_command=exec_command
+	derived_class.exec_response_command=exec_response_command
+	derived_class.quote_response_command=quote_response_command
+	derived_class.exec_command_msvc=exec_command_msvc
+	derived_class.exec_mf=exec_mf
+	return derived_class
+for k in'c cxx cprogram cxxprogram cshlib cxxshlib cstlib cxxstlib'.split():
+	wrap_class(k)
+def make_winapp(self,family):
+	append=self.env.append_unique
+	append('DEFINES','WINAPI_FAMILY=%s'%family)
+	append('CXXFLAGS','/ZW')
+	append('CXXFLAGS','/TP')
+	for lib_path in self.env.LIBPATH:
+		append('CXXFLAGS','/AI%s'%lib_path)
+@feature('winphoneapp')
+@after_method('process_use')
+@after_method('propagate_uselib_vars')
+def make_winphone_app(self):
+	make_winapp(self,'WINAPI_FAMILY_PHONE_APP')
+	conf.env.append_unique('LINKFLAGS','/NODEFAULTLIB:ole32.lib')
+	conf.env.append_unique('LINKFLAGS','PhoneAppModelHost.lib')
+@feature('winapp')
+@after_method('process_use')
+@after_method('propagate_uselib_vars')
+def make_windows_app(self):
+	make_winapp(self,'WINAPI_FAMILY_DESKTOP_APP')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/nasm.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/nasm.py
new file mode 100644
index 0000000..e3126dd
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/nasm.py
@@ -0,0 +1,14 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import waflib.Tools.asm
+from waflib.TaskGen import feature
+@feature('asm')
+def apply_nasm_vars(self):
+	self.env.append_value('ASFLAGS',self.to_list(getattr(self,'nasm_flags',[])))
+def configure(conf):
+	nasm=conf.find_program(['nasm','yasm'],var='AS')
+	conf.env.AS_TGT_F=['-o']
+	conf.env.ASLNK_TGT_F=['-o']
+	conf.load('asm')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/perl.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/perl.py
new file mode 100644
index 0000000..8b6c2f8
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/perl.py
@@ -0,0 +1,80 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Task,Options,Utils
+from waflib.Configure import conf
+from waflib.TaskGen import extension,feature,before_method
+@before_method('apply_incpaths','apply_link','propagate_uselib_vars')
+@feature('perlext')
+def init_perlext(self):
+	self.uselib=self.to_list(getattr(self,'uselib',[]))
+	if not'PERLEXT'in self.uselib:self.uselib.append('PERLEXT')
+	self.env['cshlib_PATTERN']=self.env['cxxshlib_PATTERN']=self.env['perlext_PATTERN']
+@extension('.xs')
+def xsubpp_file(self,node):
+	outnode=node.change_ext('.c')
+	self.create_task('xsubpp',node,outnode)
+	self.source.append(outnode)
+class xsubpp(Task.Task):
+	run_str='${PERL} ${XSUBPP} -noprototypes -typemap ${EXTUTILS_TYPEMAP} ${SRC} > ${TGT}'
+	color='BLUE'
+	ext_out=['.h']
+@conf
+def check_perl_version(self,minver=None):
+	res=True
+	if minver:
+		cver='.'.join(map(str,minver))
+	else:
+		cver=''
+	self.start_msg('Checking for minimum perl version %s'%cver)
+	perl=getattr(Options.options,'perlbinary',None)
+	if not perl:
+		perl=self.find_program('perl',var='PERL')
+	if not perl:
+		self.end_msg("Perl not found",color="YELLOW")
+		return False
+	self.env['PERL']=perl
+	version=self.cmd_and_log([perl,"-e",'printf \"%vd\", $^V'])
+	if not version:
+		res=False
+		version="Unknown"
+	elif not minver is None:
+		ver=tuple(map(int,version.split(".")))
+		if ver<minver:
+			res=False
+	self.end_msg(version,color=res and"GREEN"or"YELLOW")
+	return res
+@conf
+def check_perl_module(self,module):
+	cmd=[self.env['PERL'],'-e','use %s'%module]
+	self.start_msg('perl module %s'%module)
+	try:
+		r=self.cmd_and_log(cmd)
+	except Exception:
+		self.end_msg(False)
+		return None
+	self.end_msg(r or True)
+	return r
+@conf
+def check_perl_ext_devel(self):
+	env=self.env
+	perl=env.PERL
+	if not perl:
+		self.fatal('find perl first')
+	def read_out(cmd):
+		return Utils.to_list(self.cmd_and_log(perl+cmd))
+	env['LINKFLAGS_PERLEXT']=read_out(" -MConfig -e'print $Config{lddlflags}'")
+	env['INCLUDES_PERLEXT']=read_out(" -MConfig -e'print \"$Config{archlib}/CORE\"'")
+	env['CFLAGS_PERLEXT']=read_out(" -MConfig -e'print \"$Config{ccflags} $Config{cccdlflags}\"'")
+	env['XSUBPP']=read_out(" -MConfig -e'print \"$Config{privlib}/ExtUtils/xsubpp$Config{exe_ext}\"'")
+	env['EXTUTILS_TYPEMAP']=read_out(" -MConfig -e'print \"$Config{privlib}/ExtUtils/typemap\"'")
+	if not getattr(Options.options,'perlarchdir',None):
+		env['ARCHDIR_PERL']=self.cmd_and_log(perl+" -MConfig -e'print $Config{sitearch}'")
+	else:
+		env['ARCHDIR_PERL']=getattr(Options.options,'perlarchdir')
+	env['perlext_PATTERN']='%s.'+self.cmd_and_log(perl+" -MConfig -e'print $Config{dlext}'")
+def options(opt):
+	opt.add_option('--with-perl-binary',type='string',dest='perlbinary',help='Specify alternate perl binary',default=None)
+	opt.add_option('--with-perl-archdir',type='string',dest='perlarchdir',help='Specify directory where to install arch specific files',default=None)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/python.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/python.py
new file mode 100644
index 0000000..da5f982
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/python.py
@@ -0,0 +1,351 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib import Utils,Options,Errors,Logs
+from waflib.TaskGen import extension,before_method,after_method,feature
+from waflib.Configure import conf
+FRAG='''
+#include <Python.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+	void Py_Initialize(void);
+	void Py_Finalize(void);
+#ifdef __cplusplus
+}
+#endif
+int main(int argc, char **argv)
+{
+   (void)argc; (void)argv;
+   Py_Initialize();
+   Py_Finalize();
+   return 0;
+}
+'''
+INST='''
+import sys, py_compile
+py_compile.compile(sys.argv[1], sys.argv[2], sys.argv[3])
+'''
+DISTUTILS_IMP=['from distutils.sysconfig import get_config_var, get_python_lib']
+@extension('.py')
+def process_py(self,node):
+	try:
+		if not self.bld.is_install:
+			return
+	except AttributeError:
+		return
+	try:
+		if not self.install_path:
+			return
+	except AttributeError:
+		self.install_path='${PYTHONDIR}'
+	def inst_py(ctx):
+		install_from=getattr(self,'install_from',None)
+		if install_from:
+			install_from=self.path.find_dir(install_from)
+		install_pyfile(self,node,install_from)
+	self.bld.add_post_fun(inst_py)
+def install_pyfile(self,node,install_from=None):
+	from_node=install_from or node.parent
+	tsk=self.bld.install_as(self.install_path+'/'+node.path_from(from_node),node,postpone=False)
+	path=tsk.get_install_path()
+	if self.bld.is_install<0:
+		Logs.info("+ removing byte compiled python files")
+		for x in'co':
+			try:
+				os.remove(path+x)
+			except OSError:
+				pass
+	if self.bld.is_install>0:
+		try:
+			st1=os.stat(path)
+		except OSError:
+			Logs.error('The python file is missing, this should not happen')
+		for x in['c','o']:
+			do_inst=self.env['PY'+x.upper()]
+			try:
+				st2=os.stat(path+x)
+			except OSError:
+				pass
+			else:
+				if st1.st_mtime<=st2.st_mtime:
+					do_inst=False
+			if do_inst:
+				lst=(x=='o')and[self.env['PYFLAGS_OPT']]or[]
+				(a,b,c)=(path,path+x,tsk.get_install_path(destdir=False)+x)
+				argv=self.env['PYTHON']+lst+['-c',INST,a,b,c]
+				Logs.info('+ byte compiling %r'%(path+x))
+				env=self.env.env or None
+				ret=Utils.subprocess.Popen(argv,env=env).wait()
+				if ret:
+					raise Errors.WafError('py%s compilation failed %r'%(x,path))
+@feature('py')
+def feature_py(self):
+	pass
+@feature('pyext')
+@before_method('propagate_uselib_vars','apply_link')
+@after_method('apply_bundle')
+def init_pyext(self):
+	self.uselib=self.to_list(getattr(self,'uselib',[]))
+	if not'PYEXT'in self.uselib:
+		self.uselib.append('PYEXT')
+	self.env.cshlib_PATTERN=self.env.cxxshlib_PATTERN=self.env.macbundle_PATTERN=self.env.pyext_PATTERN
+	self.env.fcshlib_PATTERN=self.env.dshlib_PATTERN=self.env.pyext_PATTERN
+	try:
+		if not self.install_path:
+			return
+	except AttributeError:
+		self.install_path='${PYTHONARCHDIR}'
+@feature('pyext')
+@before_method('apply_link','apply_bundle')
+def set_bundle(self):
+	if Utils.unversioned_sys_platform()=='darwin':
+		self.mac_bundle=True
+@before_method('propagate_uselib_vars')
+@feature('pyembed')
+def init_pyembed(self):
+	self.uselib=self.to_list(getattr(self,'uselib',[]))
+	if not'PYEMBED'in self.uselib:
+		self.uselib.append('PYEMBED')
+@conf
+def get_python_variables(self,variables,imports=None):
+	if not imports:
+		try:
+			imports=self.python_imports
+		except AttributeError:
+			imports=DISTUTILS_IMP
+	program=list(imports)
+	program.append('')
+	for v in variables:
+		program.append("print(repr(%s))"%v)
+	os_env=dict(os.environ)
+	try:
+		del os_env['MACOSX_DEPLOYMENT_TARGET']
+	except KeyError:
+		pass
+	try:
+		out=self.cmd_and_log(self.env.PYTHON+['-c','\n'.join(program)],env=os_env)
+	except Errors.WafError:
+		self.fatal('The distutils module is unusable: install "python-devel"?')
+	self.to_log(out)
+	return_values=[]
+	for s in out.split('\n'):
+		s=s.strip()
+		if not s:
+			continue
+		if s=='None':
+			return_values.append(None)
+		elif(s[0]=="'"and s[-1]=="'")or(s[0]=='"'and s[-1]=='"'):
+			return_values.append(eval(s))
+		elif s[0].isdigit():
+			return_values.append(int(s))
+		else:break
+	return return_values
+@conf
+def check_python_headers(conf):
+	env=conf.env
+	if not env['CC_NAME']and not env['CXX_NAME']:
+		conf.fatal('load a compiler first (gcc, g++, ..)')
+	if not env['PYTHON_VERSION']:
+		conf.check_python_version()
+	pybin=conf.env.PYTHON
+	if not pybin:
+		conf.fatal('Could not find the python executable')
+	v='prefix SO LDFLAGS LIBDIR LIBPL INCLUDEPY Py_ENABLE_SHARED MACOSX_DEPLOYMENT_TARGET LDSHARED CFLAGS'.split()
+	try:
+		lst=conf.get_python_variables(["get_config_var('%s') or ''"%x for x in v])
+	except RuntimeError:
+		conf.fatal("Python development headers not found (-v for details).")
+	vals=['%s = %r'%(x,y)for(x,y)in zip(v,lst)]
+	conf.to_log("Configuration returned from %r:\n%r\n"%(pybin,'\n'.join(vals)))
+	dct=dict(zip(v,lst))
+	x='MACOSX_DEPLOYMENT_TARGET'
+	if dct[x]:
+		conf.env[x]=conf.environ[x]=dct[x]
+	env['pyext_PATTERN']='%s'+dct['SO']
+	all_flags=dct['LDFLAGS']+' '+dct['CFLAGS']
+	conf.parse_flags(all_flags,'PYEMBED')
+	all_flags=dct['LDFLAGS']+' '+dct['LDSHARED']+' '+dct['CFLAGS']
+	conf.parse_flags(all_flags,'PYEXT')
+	result=None
+	for name in('python'+env['PYTHON_VERSION'],'python'+env['PYTHON_VERSION']+'m','python'+env['PYTHON_VERSION'].replace('.','')):
+		if not result and env['LIBPATH_PYEMBED']:
+			path=env['LIBPATH_PYEMBED']
+			conf.to_log("\n\n# Trying default LIBPATH_PYEMBED: %r\n"%path)
+			result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBPATH_PYEMBED'%name)
+		if not result and dct['LIBDIR']:
+			path=[dct['LIBDIR']]
+			conf.to_log("\n\n# try again with -L$python_LIBDIR: %r\n"%path)
+			result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in LIBDIR'%name)
+		if not result and dct['LIBPL']:
+			path=[dct['LIBPL']]
+			conf.to_log("\n\n# try again with -L$python_LIBPL (some systems don't install the python library in $prefix/lib)\n")
+			result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in python_LIBPL'%name)
+		if not result:
+			path=[os.path.join(dct['prefix'],"libs")]
+			conf.to_log("\n\n# try again with -L$prefix/libs, and pythonXY name rather than pythonX.Y (win32)\n")
+			result=conf.check(lib=name,uselib='PYEMBED',libpath=path,mandatory=False,msg='Checking for library %s in $prefix/libs'%name)
+		if result:
+			break
+	if result:
+		env['LIBPATH_PYEMBED']=path
+		env.append_value('LIB_PYEMBED',[name])
+	else:
+		conf.to_log("\n\n### LIB NOT FOUND\n")
+	if(Utils.is_win32 or sys.platform.startswith('os2')or dct['Py_ENABLE_SHARED']):
+		env['LIBPATH_PYEXT']=env['LIBPATH_PYEMBED']
+		env['LIB_PYEXT']=env['LIB_PYEMBED']
+	num='.'.join(env['PYTHON_VERSION'].split('.')[:2])
+	conf.find_program([''.join(pybin)+'-config','python%s-config'%num,'python-config-%s'%num,'python%sm-config'%num],var='PYTHON_CONFIG',display_name="python-config",mandatory=False)
+	includes=[]
+	if conf.env.PYTHON_CONFIG:
+		for incstr in conf.cmd_and_log([conf.env.PYTHON_CONFIG,'--includes']).strip().split():
+			if(incstr.startswith('-I')or incstr.startswith('/I')):
+				incstr=incstr[2:]
+			if incstr not in includes:
+				includes.append(incstr)
+		conf.to_log("Include path for Python extensions (found via python-config --includes): %r\n"%(includes,))
+		env['INCLUDES_PYEXT']=includes
+		env['INCLUDES_PYEMBED']=includes
+	else:
+		conf.to_log("Include path for Python extensions ""(found via distutils module): %r\n"%(dct['INCLUDEPY'],))
+		env['INCLUDES_PYEXT']=[dct['INCLUDEPY']]
+		env['INCLUDES_PYEMBED']=[dct['INCLUDEPY']]
+	if env['CC_NAME']=='gcc':
+		env.append_value('CFLAGS_PYEMBED',['-fno-strict-aliasing'])
+		env.append_value('CFLAGS_PYEXT',['-fno-strict-aliasing'])
+	if env['CXX_NAME']=='gcc':
+		env.append_value('CXXFLAGS_PYEMBED',['-fno-strict-aliasing'])
+		env.append_value('CXXFLAGS_PYEXT',['-fno-strict-aliasing'])
+	if env.CC_NAME=="msvc":
+		from distutils.msvccompiler import MSVCCompiler
+		dist_compiler=MSVCCompiler()
+		dist_compiler.initialize()
+		env.append_value('CFLAGS_PYEXT',dist_compiler.compile_options)
+		env.append_value('CXXFLAGS_PYEXT',dist_compiler.compile_options)
+		env.append_value('LINKFLAGS_PYEXT',dist_compiler.ldflags_shared)
+	try:
+		conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',uselib='PYEMBED',fragment=FRAG,errmsg=':-(')
+	except conf.errors.ConfigurationError:
+		xx=conf.env.CXX_NAME and'cxx'or'c'
+		flags=['--cflags','--libs','--ldflags']
+		for f in flags:
+			conf.check_cfg(msg='Asking python-config for pyembed %s flags'%f,path=conf.env.PYTHON_CONFIG,package='',uselib_store='PYEMBED',args=[f])
+		conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',msg='Getting pyembed flags from python-config',fragment=FRAG,errmsg='Could not build a python embedded interpreter',features='%s %sprogram pyembed'%(xx,xx))
+		for f in flags:
+			conf.check_cfg(msg='Asking python-config for pyext %s flags'%f,path=conf.env.PYTHON_CONFIG,package='',uselib_store='PYEXT',args=[f])
+		conf.check(header_name='Python.h',define_name='HAVE_PYTHON_H',msg='Getting pyext flags from python-config',features='%s %sshlib pyext'%(xx,xx),fragment=FRAG,errmsg='Could not build python extensions')
+@conf
+def check_python_version(conf,minver=None):
+	assert minver is None or isinstance(minver,tuple)
+	pybin=conf.env['PYTHON']
+	if not pybin:
+		conf.fatal('could not find the python executable')
+	cmd=pybin+['-c','import sys\nfor x in sys.version_info: print(str(x))']
+	Logs.debug('python: Running python command %r'%cmd)
+	lines=conf.cmd_and_log(cmd).split()
+	assert len(lines)==5,"found %i lines, expected 5: %r"%(len(lines),lines)
+	pyver_tuple=(int(lines[0]),int(lines[1]),int(lines[2]),lines[3],int(lines[4]))
+	result=(minver is None)or(pyver_tuple>=minver)
+	if result:
+		pyver='.'.join([str(x)for x in pyver_tuple[:2]])
+		conf.env['PYTHON_VERSION']=pyver
+		if'PYTHONDIR'in conf.environ:
+			pydir=conf.environ['PYTHONDIR']
+		else:
+			if Utils.is_win32:
+				(python_LIBDEST,pydir)=conf.get_python_variables(["get_config_var('LIBDEST') or ''","get_python_lib(standard_lib=0) or ''"])
+			else:
+				python_LIBDEST=None
+				(pydir,)=conf.get_python_variables(["get_python_lib(standard_lib=0) or ''"])
+			if python_LIBDEST is None:
+				if conf.env['LIBDIR']:
+					python_LIBDEST=os.path.join(conf.env['LIBDIR'],"python"+pyver)
+				else:
+					python_LIBDEST=os.path.join(conf.env['PREFIX'],"lib","python"+pyver)
+		if'PYTHONARCHDIR'in conf.environ:
+			pyarchdir=conf.environ['PYTHONARCHDIR']
+		else:
+			(pyarchdir,)=conf.get_python_variables(["get_python_lib(plat_specific=1, standard_lib=0) or ''"])
+			if not pyarchdir:
+				pyarchdir=pydir
+		if hasattr(conf,'define'):
+			conf.define('PYTHONDIR',pydir)
+			conf.define('PYTHONARCHDIR',pyarchdir)
+		conf.env['PYTHONDIR']=pydir
+		conf.env['PYTHONARCHDIR']=pyarchdir
+	pyver_full='.'.join(map(str,pyver_tuple[:3]))
+	if minver is None:
+		conf.msg('Checking for python version',pyver_full)
+	else:
+		minver_str='.'.join(map(str,minver))
+		conf.msg('Checking for python version',pyver_tuple,">= %s"%(minver_str,)and'GREEN'or'YELLOW')
+	if not result:
+		conf.fatal('The python version is too old, expecting %r'%(minver,))
+PYTHON_MODULE_TEMPLATE='''
+import %s as current_module
+version = getattr(current_module, '__version__', None)
+if version is not None:
+    print(str(version))
+else:
+    print('unknown version')
+'''
+@conf
+def check_python_module(conf,module_name,condition=''):
+	msg="Checking for python module '%s'"%module_name
+	if condition:
+		msg='%s (%s)'%(msg,condition)
+	conf.start_msg(msg)
+	try:
+		ret=conf.cmd_and_log(conf.env['PYTHON']+['-c',PYTHON_MODULE_TEMPLATE%module_name])
+	except Exception:
+		conf.end_msg(False)
+		conf.fatal('Could not find the python module %r'%module_name)
+	ret=ret.strip()
+	if condition:
+		conf.end_msg(ret)
+		if ret=='unknown version':
+			conf.fatal('Could not check the %s version'%module_name)
+		from distutils.version import LooseVersion
+		def num(*k):
+			if isinstance(k[0],int):
+				return LooseVersion('.'.join([str(x)for x in k]))
+			else:
+				return LooseVersion(k[0])
+		d={'num':num,'ver':LooseVersion(ret)}
+		ev=eval(condition,{},d)
+		if not ev:
+			conf.fatal('The %s version does not satisfy the requirements'%module_name)
+	else:
+		if ret=='unknown version':
+			conf.end_msg(True)
+		else:
+			conf.end_msg(ret)
+def configure(conf):
+	v=conf.env
+	if not v['PYTHON']:
+		v['PYTHON']=getattr(Options.options,'python',None)or sys.executable
+	if not v['PYTHONDIR']and Options.options.pythondir:
+		v['PYTHONDIR']=Options.options.pythondir
+	if not v['PYTHONARCHDIR']and Options.options.pythonarchdir:
+		v['PYTHONARCHDIR']=Options.options.pythonarchdir
+	try:
+		conf.find_program('python',var='PYTHON')
+	except conf.errors.ConfigurationError:
+		Logs.warn("could not find a python executable, setting to sys.executable '%s'"%sys.executable)
+		conf.env.PYTHON=sys.executable
+	conf.env.PYTHON=conf.cmd_to_list(conf.env.PYTHON)
+	v['PYCMD']='"import sys, py_compile;py_compile.compile(sys.argv[1], sys.argv[2])"'
+	v['PYFLAGS']=''
+	v['PYFLAGS_OPT']='-O'
+	v['PYC']=getattr(Options.options,'pyc',1)
+	v['PYO']=getattr(Options.options,'pyo',1)
+def options(opt):
+	pyopt=opt.add_option_group("Python Options")
+	pyopt.add_option('--nopyc',action='store_false',default=1,help='Do not install bytecode compiled .pyc files (configuration) [Default:install]',dest='pyc')
+	pyopt.add_option('--nopyo',action='store_false',default=1,help='Do not install optimised compiled .pyo files (configuration) [Default:install]',dest='pyo')
+	pyopt.add_option('--python',help='python binary to be used [Default: %s]'%sys.executable,dest="python")
+	pyopt.add_option('--pythondir',help='Installation path for python modules (py, platform-independent .py and .pyc files)',dest='pythondir')
+	pyopt.add_option('--pythonarchdir',help='Installation path for python extension (pyext, platform-dependent .so or .dylib files)',dest='pythonarchdir')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/qt4.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/qt4.py
new file mode 100644
index 0000000..b4328e7
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/qt4.py
@@ -0,0 +1,455 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+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
+from waflib.Tools import c_preproc,cxx
+from waflib import Task,Utils,Options,Errors
+from waflib.TaskGen import feature,after_method,extension
+from waflib.Configure import conf
+from waflib import Logs
+MOC_H=['.h','.hpp','.hxx','.hh']
+EXT_RCC=['.qrc']
+EXT_UI=['.ui']
+EXT_QT4=['.cpp','.cc','.cxx','.C']
+QT4_LIBS="QtCore QtGui QtUiTools QtNetwork QtOpenGL QtSql QtSvg QtTest QtXml QtXmlPatterns QtWebKit Qt3Support QtHelp QtScript QtDeclarative QtDesigner"
+class qxx(Task.classes['cxx']):
+	def __init__(self,*k,**kw):
+		Task.Task.__init__(self,*k,**kw)
+		self.moc_done=0
+	def scan(self):
+		(nodes,names)=c_preproc.scan(self)
+		lst=[]
+		for x in nodes:
+			if x.name.endswith('.moc'):
+				s=x.path_from(self.inputs[0].parent.get_bld())
+				if s not in names:
+					names.append(s)
+			else:
+				lst.append(x)
+		return(lst,names)
+	def runnable_status(self):
+		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):
+		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)
+			gen=self.generator.bld.producer
+			gen.outstanding.insert(0,tsk)
+			gen.total+=1
+			return tsk
+	def add_moc_tasks(self):
+		node=self.inputs[0]
+		bld=self.generator.bld
+		try:
+			self.signature()
+		except KeyError:
+			pass
+		else:
+			delattr(self,'cache_sig')
+		moctasks=[]
+		mocfiles=[]
+		try:
+			tmp_lst=bld.raw_deps[self.uid()]
+			bld.raw_deps[self.uid()]=[]
+		except KeyError:
+			tmp_lst=[]
+		for d in tmp_lst:
+			if not d.endswith('.moc'):
+				continue
+			if d in mocfiles:
+				Logs.error("paranoia owns")
+				continue
+			mocfiles.append(d)
+			h_node=None
+			try:ext=Options.options.qt_header_ext.split()
+			except AttributeError:pass
+			if not ext:ext=MOC_H
+			base2=d[:-4]
+			for x in[node.parent]+self.generator.includes_nodes:
+				for e in ext:
+					h_node=x.find_node(base2+e)
+					if h_node:
+						break
+				if h_node:
+					m_node=h_node.change_ext('.moc')
+					break
+			else:
+				for k in EXT_QT4:
+					if base2.endswith(k):
+						for x in[node.parent]+self.generator.includes_nodes:
+							h_node=x.find_node(base2)
+							if h_node:
+								break
+					if h_node:
+						m_node=h_node.change_ext(k+'.moc')
+						break
+			if not h_node:
+				raise Errors.WafError('no header found for %r which is a moc file'%d)
+			bld.node_deps[(self.inputs[0].parent.abspath(),m_node.name)]=h_node
+			task=self.create_moc_task(h_node,m_node)
+			moctasks.append(task)
+		tmp_lst=bld.raw_deps[self.uid()]=mocfiles
+		lst=bld.node_deps.get(self.uid(),())
+		for d in lst:
+			name=d.name
+			if name.endswith('.moc'):
+				task=self.create_moc_task(bld.node_deps[(self.inputs[0].parent.abspath(),name)],d)
+				moctasks.append(task)
+		self.run_after.update(set(moctasks))
+		self.moc_done=1
+	run=Task.classes['cxx'].__dict__['run']
+class trans_update(Task.Task):
+	run_str='${QT_LUPDATE} ${SRC} -ts ${TGT}'
+	color='BLUE'
+Task.update_outputs(trans_update)
+class XMLHandler(ContentHandler):
+	def __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):
+	rcnode=node.change_ext('_rc.cpp')
+	rcctask=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):
+	uictask=self.create_task('ui4',node)
+	uictask.outputs=[self.path.find_or_declare(self.env['ui_PATTERN']%node.name[:-3])]
+@extension('.ts')
+def add_lang(self,node):
+	self.lang=self.to_list(getattr(self,'lang',[]))+[node]
+@feature('qt4')
+@after_method('apply_link')
+def apply_qt4(self):
+	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('.qm')))
+		if getattr(self,'update',None)and Options.options.trans_qt4:
+			cxxnodes=[a.inputs[0]for a in self.compiled_tasks]+[a.inputs[0]for a in self.tasks if getattr(a,'inputs',None)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+'.qrc')
+			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_QT4)
+def cxx_hook(self,node):
+	return self.create_compiled_task('qxx',node)
+class rcc(Task.Task):
+	color='BLUE'
+	run_str='${QT_RCC} -name ${SRC[0].name} ${SRC[0].abspath()} ${RCC_ST} -o ${TGT}'
+	ext_out=['.h']
+	def scan(self):
+		node=self.inputs[0]
+		if not has_xml:
+			Logs.error('no xml support was found, the rcc dependencies will be incomplete!')
+			return([],[])
+		parser=make_parser()
+		curHandler=XMLHandler()
+		parser.setContentHandler(curHandler)
+		fi=open(self.inputs[0].abspath(),'r')
+		try:
+			parser.parse(fi)
+		finally:
+			fi.close()
+		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)
+class moc(Task.Task):
+	color='BLUE'
+	run_str='${QT_MOC} ${MOC_FLAGS} ${MOCCPPPATH_ST:INCPATHS} ${MOCDEFINES_ST:DEFINES} ${SRC} ${MOC_ST} ${TGT}'
+class ui4(Task.Task):
+	color='BLUE'
+	run_str='${QT_UIC} ${SRC} -o ${TGT}'
+	ext_out=['.h']
+class ts2qm(Task.Task):
+	color='BLUE'
+	run_str='${QT_LRELEASE} ${QT_LRELEASE_FLAGS} ${SRC} -qm ${TGT}'
+class qm2rcc(Task.Task):
+	color='BLUE'
+	after='ts2qm'
+	def run(self):
+		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):
+	self.find_qt4_binaries()
+	self.set_qt4_libs_to_check()
+	self.set_qt4_defines()
+	self.find_qt4_libraries()
+	self.add_qt4_rpath()
+	self.simplify_qt4_libs()
+@conf
+def find_qt4_binaries(self):
+	env=self.env
+	opt=Options.options
+	qtdir=getattr(opt,'qtdir','')
+	qtbin=getattr(opt,'qtbin','')
+	paths=[]
+	if qtdir:
+		qtbin=os.path.join(qtdir,'bin')
+	if not qtdir:
+		qtdir=os.environ.get('QT4_ROOT','')
+		qtbin=os.environ.get('QT4_BIN',None)or os.path.join(qtdir,'bin')
+	if qtbin:
+		paths=[qtbin]
+	if not qtdir:
+		paths=os.environ.get('PATH','').split(os.pathsep)
+		paths.append('/usr/share/qt4/bin/')
+		try:
+			lst=Utils.listdir('/usr/local/Trolltech/')
+		except OSError:
+			pass
+		else:
+			if lst:
+				lst.sort()
+				lst.reverse()
+				qtdir='/usr/local/Trolltech/%s/'%lst[0]
+				qtbin=os.path.join(qtdir,'bin')
+				paths.append(qtbin)
+	cand=None
+	prev_ver=['4','0','0']
+	for qmk in['qmake-qt4','qmake4','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
+	if cand:
+		self.env.QMAKE=cand
+	else:
+		self.fatal('Could not find qmake for qt4')
+	qtbin=self.cmd_and_log([self.env.QMAKE,'-query','QT_INSTALL_BINS']).strip()+os.sep
+	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-qt3','uic3'],'QT_UIC3')
+	find_bin(['uic-qt4','uic'],'QT_UIC')
+	if not env['QT_UIC']:
+		self.fatal('cannot find the uic compiler for qt4')
+	try:
+		uicver=self.cmd_and_log(env['QT_UIC']+" -version 2>&1").strip()
+	except self.errors.ConfigurationError:
+		self.fatal('this uic compiler is for qt3, add uic for qt4 to your path')
+	uicver=uicver.replace('Qt User Interface Compiler ','').replace('User Interface Compiler for Qt','')
+	self.msg('Checking for uic version','%s'%uicver)
+	if uicver.find(' 3.')!=-1:
+		self.fatal('this uic compiler is for qt3, add uic for qt4 to your path')
+	find_bin(['moc-qt4','moc'],'QT_MOC')
+	find_bin(['rcc'],'QT_RCC')
+	find_bin(['lrelease-qt4','lrelease'],'QT_LRELEASE')
+	find_bin(['lupdate-qt4','lupdate'],'QT_LUPDATE')
+	env['UIC3_ST']='%s -o %s'
+	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 find_qt4_libraries(self):
+	qtlibs=getattr(Options.options,'qtlibs',None)or os.environ.get("QT4_LIBDIR",None)
+	if not qtlibs:
+		try:
+			qtlibs=self.cmd_and_log([self.env.QMAKE,'-query','QT_INSTALL_LIBS']).strip()
+		except Errors.WafError:
+			qtdir=self.cmd_and_log([self.env.QMAKE,'-query','QT_INSTALL_PREFIX']).strip()+os.sep
+			qtlibs=os.path.join(qtdir,'lib')
+	self.msg('Found the Qt4 libraries in',qtlibs)
+	qtincludes=os.environ.get("QT4_INCLUDES",None)or self.cmd_and_log([self.env.QMAKE,'-query','QT_INSTALL_HEADERS']).strip()
+	env=self.env
+	if not'PKG_CONFIG_PATH'in os.environ:
+		os.environ['PKG_CONFIG_PATH']='%s:%s/pkgconfig:/usr/lib/qt4/lib/pkgconfig:/opt/qt4/lib/pkgconfig:/usr/lib/qt4/lib:/opt/qt4/lib'%(qtlibs,qtlibs)
+	try:
+		if os.environ.get("QT4_XCOMPILE",None):
+			raise self.errors.ConfigurationError()
+		self.check_cfg(atleast_pkgconfig_version='0.1')
+	except self.errors.ConfigurationError:
+		for i in self.qt4_vars:
+			uselib=i.upper()
+			if Utils.unversioned_sys_platform()=="darwin":
+				frameworkName=i+".framework"
+				qtDynamicLib=os.path.join(qtlibs,frameworkName,i)
+				if os.path.exists(qtDynamicLib):
+					env.append_unique('FRAMEWORK_'+uselib,i)
+					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(qtlibs,frameworkName,'Headers'))
+			elif env.DEST_OS!="win32":
+				qtDynamicLib=os.path.join(qtlibs,"lib"+i+".so")
+				qtStaticLib=os.path.join(qtlibs,"lib"+i+".a")
+				if os.path.exists(qtDynamicLib):
+					env.append_unique('LIB_'+uselib,i)
+					self.msg('Checking for %s'%i,qtDynamicLib,'GREEN')
+				elif os.path.exists(qtStaticLib):
+					env.append_unique('LIB_'+uselib,i)
+					self.msg('Checking for %s'%i,qtStaticLib,'GREEN')
+				else:
+					self.msg('Checking for %s'%i,False,'YELLOW')
+				env.append_unique('LIBPATH_'+uselib,qtlibs)
+				env.append_unique('INCLUDES_'+uselib,qtincludes)
+				env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
+			else:
+				for k in("lib%s.a","lib%s4.a","%s.lib","%s4.lib"):
+					lib=os.path.join(qtlibs,k%i)
+					if os.path.exists(lib):
+						env.append_unique('LIB_'+uselib,i+k[k.find("%s")+2:k.find('.')])
+						self.msg('Checking for %s'%i,lib,'GREEN')
+						break
+				else:
+					self.msg('Checking for %s'%i,False,'YELLOW')
+				env.append_unique('LIBPATH_'+uselib,qtlibs)
+				env.append_unique('INCLUDES_'+uselib,qtincludes)
+				env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
+				uselib=i.upper()+"_debug"
+				for k in("lib%sd.a","lib%sd4.a","%sd.lib","%sd4.lib"):
+					lib=os.path.join(qtlibs,k%i)
+					if os.path.exists(lib):
+						env.append_unique('LIB_'+uselib,i+k[k.find("%s")+2:k.find('.')])
+						self.msg('Checking for %s'%i,lib,'GREEN')
+						break
+				else:
+					self.msg('Checking for %s'%i,False,'YELLOW')
+				env.append_unique('LIBPATH_'+uselib,qtlibs)
+				env.append_unique('INCLUDES_'+uselib,qtincludes)
+				env.append_unique('INCLUDES_'+uselib,os.path.join(qtincludes,i))
+	else:
+		for i in self.qt4_vars_debug+self.qt4_vars:
+			self.check_cfg(package=i,args='--cflags --libs',mandatory=False)
+@conf
+def simplify_qt4_libs(self):
+	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.qt4_vars,'LIBPATH_QTCORE')
+	process_lib(self.qt4_vars_debug,'LIBPATH_QTCORE_DEBUG')
+@conf
+def add_qt4_rpath(self):
+	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.qt4_vars,'LIBPATH_QTCORE')
+		process_rpath(self.qt4_vars_debug,'LIBPATH_QTCORE_DEBUG')
+@conf
+def set_qt4_libs_to_check(self):
+	if not hasattr(self,'qt4_vars'):
+		self.qt4_vars=QT4_LIBS
+	self.qt4_vars=Utils.to_list(self.qt4_vars)
+	if not hasattr(self,'qt4_vars_debug'):
+		self.qt4_vars_debug=[a+'_debug'for a in self.qt4_vars]
+	self.qt4_vars_debug=Utils.to_list(self.qt4_vars_debug)
+@conf
+def set_qt4_defines(self):
+	if sys.platform!='win32':
+		return
+	for x in self.qt4_vars:
+		y=x[2:].upper()
+		self.env.append_unique('DEFINES_%s'%x.upper(),'QT_%s_LIB'%y)
+		self.env.append_unique('DEFINES_%s_DEBUG'%x.upper(),'QT_%s_LIB'%y)
+def options(opt):
+	opt.add_option('--want-rpath',action='store_true',default=False,dest='want_rpath',help='enable the rpath for qt libraries')
+	opt.add_option('--header-ext',type='string',default='',help='header extension for moc files',dest='qt_header_ext')
+	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_qt4",default=False)
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ruby.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ruby.py
new file mode 100644
index 0000000..04cddfb
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/ruby.py
@@ -0,0 +1,103 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Task,Options,Utils
+from waflib.TaskGen import before_method,feature,after_method,Task,extension
+from waflib.Configure import conf
+@feature('rubyext')
+@before_method('apply_incpaths','apply_lib_vars','apply_bundle','apply_link')
+def init_rubyext(self):
+	self.install_path='${ARCHDIR_RUBY}'
+	self.uselib=self.to_list(getattr(self,'uselib',''))
+	if not'RUBY'in self.uselib:
+		self.uselib.append('RUBY')
+	if not'RUBYEXT'in self.uselib:
+		self.uselib.append('RUBYEXT')
+@feature('rubyext')
+@before_method('apply_link','propagate_uselib')
+def apply_ruby_so_name(self):
+	self.env['cshlib_PATTERN']=self.env['cxxshlib_PATTERN']=self.env['rubyext_PATTERN']
+@conf
+def check_ruby_version(self,minver=()):
+	if Options.options.rubybinary:
+		self.env.RUBY=Options.options.rubybinary
+	else:
+		self.find_program('ruby',var='RUBY')
+	ruby=self.env.RUBY
+	try:
+		version=self.cmd_and_log([ruby,'-e','puts defined?(VERSION) ? VERSION : RUBY_VERSION']).strip()
+	except Exception:
+		self.fatal('could not determine ruby version')
+	self.env.RUBY_VERSION=version
+	try:
+		ver=tuple(map(int,version.split(".")))
+	except Exception:
+		self.fatal('unsupported ruby version %r'%version)
+	cver=''
+	if minver:
+		if ver<minver:
+			self.fatal('ruby is too old %r'%ver)
+		cver='.'.join([str(x)for x in minver])
+	else:
+		cver=ver
+	self.msg('Checking for ruby version %s'%str(minver or''),cver)
+@conf
+def check_ruby_ext_devel(self):
+	if not self.env.RUBY:
+		self.fatal('ruby detection is required first')
+	if not self.env.CC_NAME and not self.env.CXX_NAME:
+		self.fatal('load a c/c++ compiler first')
+	version=tuple(map(int,self.env.RUBY_VERSION.split(".")))
+	def read_out(cmd):
+		return Utils.to_list(self.cmd_and_log([self.env.RUBY,'-rrbconfig','-e',cmd]))
+	def read_config(key):
+		return read_out('puts Config::CONFIG[%r]'%key)
+	ruby=self.env['RUBY']
+	archdir=read_config('archdir')
+	cpppath=archdir
+	if version>=(1,9,0):
+		ruby_hdrdir=read_config('rubyhdrdir')
+		cpppath+=ruby_hdrdir
+		cpppath+=[os.path.join(ruby_hdrdir[0],read_config('arch')[0])]
+	self.check(header_name='ruby.h',includes=cpppath,errmsg='could not find ruby header file')
+	self.env.LIBPATH_RUBYEXT=read_config('libdir')
+	self.env.LIBPATH_RUBYEXT+=archdir
+	self.env.INCLUDES_RUBYEXT=cpppath
+	self.env.CFLAGS_RUBYEXT=read_config('CCDLFLAGS')
+	self.env.rubyext_PATTERN='%s.'+read_config('DLEXT')[0]
+	flags=read_config('LDSHARED')
+	while flags and flags[0][0]!='-':
+		flags=flags[1:]
+	if len(flags)>1 and flags[1]=="ppc":
+		flags=flags[2:]
+	self.env.LINKFLAGS_RUBYEXT=flags
+	self.env.LINKFLAGS_RUBYEXT+=read_config('LIBS')
+	self.env.LINKFLAGS_RUBYEXT+=read_config('LIBRUBYARG_SHARED')
+	if Options.options.rubyarchdir:
+		self.env.ARCHDIR_RUBY=Options.options.rubyarchdir
+	else:
+		self.env.ARCHDIR_RUBY=read_config('sitearchdir')[0]
+	if Options.options.rubylibdir:
+		self.env.LIBDIR_RUBY=Options.options.rubylibdir
+	else:
+		self.env.LIBDIR_RUBY=read_config('sitelibdir')[0]
+@conf
+def check_ruby_module(self,module_name):
+	self.start_msg('Ruby module %s'%module_name)
+	try:
+		self.cmd_and_log([self.env['RUBY'],'-e','require \'%s\';puts 1'%module_name])
+	except Exception:
+		self.end_msg(False)
+		self.fatal('Could not find the ruby module %r'%module_name)
+	self.end_msg(True)
+@extension('.rb')
+def process(self,node):
+	tsk=self.create_task('run_ruby',node)
+class run_ruby(Task.Task):
+	run_str='${RUBY} ${RBFLAGS} -I ${SRC[0].parent.abspath()} ${SRC}'
+def options(opt):
+	opt.add_option('--with-ruby-archdir',type='string',dest='rubyarchdir',help='Specify directory where to install arch specific files')
+	opt.add_option('--with-ruby-libdir',type='string',dest='rubylibdir',help='Specify alternate ruby library path')
+	opt.add_option('--with-ruby-binary',type='string',dest='rubybinary',help='Specify alternate ruby binary')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/suncc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/suncc.py
new file mode 100644
index 0000000..edd24cd
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/suncc.py
@@ -0,0 +1,53 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Utils
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_scc(conf):
+	v=conf.env
+	cc=None
+	if v['CC']:cc=v['CC']
+	elif'CC'in conf.environ:cc=conf.environ['CC']
+	if not cc:cc=conf.find_program('cc',var='CC')
+	if not cc:conf.fatal('Could not find a Sun C compiler')
+	cc=conf.cmd_to_list(cc)
+	try:
+		conf.cmd_and_log(cc+['-flags'])
+	except Exception:
+		conf.fatal('%r is not a Sun compiler'%cc)
+	v['CC']=cc
+	v['CC_NAME']='sun'
+@conf
+def scc_common_flags(conf):
+	v=conf.env
+	v['CC_SRC_F']=[]
+	v['CC_TGT_F']=['-c','-o']
+	if not v['LINK_CC']:v['LINK_CC']=v['CC']
+	v['CCLNK_SRC_F']=''
+	v['CCLNK_TGT_F']=['-o']
+	v['CPPPATH_ST']='-I%s'
+	v['DEFINES_ST']='-D%s'
+	v['LIB_ST']='-l%s'
+	v['LIBPATH_ST']='-L%s'
+	v['STLIB_ST']='-l%s'
+	v['STLIBPATH_ST']='-L%s'
+	v['SONAME_ST']='-Wl,-h,%s'
+	v['SHLIB_MARKER']='-Bdynamic'
+	v['STLIB_MARKER']='-Bstatic'
+	v['cprogram_PATTERN']='%s'
+	v['CFLAGS_cshlib']=['-Kpic','-DPIC']
+	v['LINKFLAGS_cshlib']=['-G']
+	v['cshlib_PATTERN']='lib%s.so'
+	v['LINKFLAGS_cstlib']=['-Bstatic']
+	v['cstlib_PATTERN']='lib%s.a'
+def configure(conf):
+	conf.find_scc()
+	conf.find_ar()
+	conf.scc_common_flags()
+	conf.cc_load_tools()
+	conf.cc_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/suncxx.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/suncxx.py
new file mode 100644
index 0000000..4b8b931
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/suncxx.py
@@ -0,0 +1,54 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+from waflib import Utils
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_sxx(conf):
+	v=conf.env
+	cc=None
+	if v['CXX']:cc=v['CXX']
+	elif'CXX'in conf.environ:cc=conf.environ['CXX']
+	if not cc:cc=conf.find_program('CC',var='CXX')
+	if not cc:cc=conf.find_program('c++',var='CXX')
+	if not cc:conf.fatal('Could not find a Sun C++ compiler')
+	cc=conf.cmd_to_list(cc)
+	try:
+		conf.cmd_and_log(cc+['-flags'])
+	except Exception:
+		conf.fatal('%r is not a Sun compiler'%cc)
+	v['CXX']=cc
+	v['CXX_NAME']='sun'
+@conf
+def sxx_common_flags(conf):
+	v=conf.env
+	v['CXX_SRC_F']=[]
+	v['CXX_TGT_F']=['-c','-o']
+	if not v['LINK_CXX']:v['LINK_CXX']=v['CXX']
+	v['CXXLNK_SRC_F']=[]
+	v['CXXLNK_TGT_F']=['-o']
+	v['CPPPATH_ST']='-I%s'
+	v['DEFINES_ST']='-D%s'
+	v['LIB_ST']='-l%s'
+	v['LIBPATH_ST']='-L%s'
+	v['STLIB_ST']='-l%s'
+	v['STLIBPATH_ST']='-L%s'
+	v['SONAME_ST']='-Wl,-h,%s'
+	v['SHLIB_MARKER']='-Bdynamic'
+	v['STLIB_MARKER']='-Bstatic'
+	v['cxxprogram_PATTERN']='%s'
+	v['CXXFLAGS_cxxshlib']=['-Kpic','-DPIC']
+	v['LINKFLAGS_cxxshlib']=['-G']
+	v['cxxshlib_PATTERN']='lib%s.so'
+	v['LINKFLAGS_cxxstlib']=['-Bstatic']
+	v['cxxstlib_PATTERN']='lib%s.a'
+def configure(conf):
+	conf.find_sxx()
+	conf.find_ar()
+	conf.sxx_common_flags()
+	conf.cxx_load_tools()
+	conf.cxx_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/tex.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/tex.py
new file mode 100644
index 0000000..6813022
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/tex.py
@@ -0,0 +1,257 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,re
+from waflib import Utils,Task,Errors,Logs
+from waflib.TaskGen import feature,before_method
+re_bibunit=re.compile(r'\\(?P<type>putbib)\[(?P<file>[^\[\]]*)\]',re.M)
+def bibunitscan(self):
+	node=self.inputs[0]
+	nodes=[]
+	if not node:return nodes
+	code=node.read()
+	for match in re_bibunit.finditer(code):
+		path=match.group('file')
+		if path:
+			for k in['','.bib']:
+				Logs.debug('tex: trying %s%s'%(path,k))
+				fi=node.parent.find_resource(path+k)
+				if fi:
+					nodes.append(fi)
+			else:
+				Logs.debug('tex: could not find %s'%path)
+	Logs.debug("tex: found the following bibunit files: %s"%nodes)
+	return nodes
+exts_deps_tex=['','.ltx','.tex','.bib','.pdf','.png','.eps','.ps']
+exts_tex=['.ltx','.tex']
+re_tex=re.compile(r'\\(?P<type>include|bibliography|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P<file>[^{}]*)}',re.M)
+g_bibtex_re=re.compile('bibdata',re.M)
+class tex(Task.Task):
+	bibtex_fun,_=Task.compile_fun('${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}',shell=False)
+	bibtex_fun.__doc__="""
+	Execute the program **bibtex**
+	"""
+	makeindex_fun,_=Task.compile_fun('${MAKEINDEX} ${MAKEINDEXFLAGS} ${SRCFILE}',shell=False)
+	makeindex_fun.__doc__="""
+	Execute the program **makeindex**
+	"""
+	def exec_command(self,cmd,**kw):
+		bld=self.generator.bld
+		try:
+			if not kw.get('cwd',None):
+				kw['cwd']=bld.cwd
+		except AttributeError:
+			bld.cwd=kw['cwd']=bld.variant_dir
+		return Utils.subprocess.Popen(cmd,**kw).wait()
+	def scan_aux(self,node):
+		nodes=[node]
+		re_aux=re.compile(r'\\@input{(?P<file>[^{}]*)}',re.M)
+		def parse_node(node):
+			code=node.read()
+			for match in re_aux.finditer(code):
+				path=match.group('file')
+				found=node.parent.find_or_declare(path)
+				if found and found not in nodes:
+					Logs.debug('tex: found aux node '+found.abspath())
+					nodes.append(found)
+					parse_node(found)
+		parse_node(node)
+		return nodes
+	def scan(self):
+		node=self.inputs[0]
+		nodes=[]
+		names=[]
+		seen=[]
+		if not node:return(nodes,names)
+		def parse_node(node):
+			if node in seen:
+				return
+			seen.append(node)
+			code=node.read()
+			global re_tex
+			for match in re_tex.finditer(code):
+				for path in match.group('file').split(','):
+					if path:
+						add_name=True
+						found=None
+						for k in exts_deps_tex:
+							Logs.debug('tex: trying %s%s'%(path,k))
+							found=node.parent.find_resource(path+k)
+							for tsk in self.generator.tasks:
+								if not found or found in tsk.outputs:
+									break
+							else:
+								nodes.append(found)
+								add_name=False
+								for ext in exts_tex:
+									if found.name.endswith(ext):
+										parse_node(found)
+										break
+						if add_name:
+							names.append(path)
+		parse_node(node)
+		for x in nodes:
+			x.parent.get_bld().mkdir()
+		Logs.debug("tex: found the following : %s and names %s"%(nodes,names))
+		return(nodes,names)
+	def check_status(self,msg,retcode):
+		if retcode!=0:
+			raise Errors.WafError("%r command exit status %r"%(msg,retcode))
+	def bibfile(self):
+		for aux_node in self.aux_nodes:
+			try:
+				ct=aux_node.read()
+			except(OSError,IOError):
+				Logs.error('Error reading %s: %r'%aux_node.abspath())
+				continue
+			if g_bibtex_re.findall(ct):
+				Logs.warn('calling bibtex')
+				self.env.env={}
+				self.env.env.update(os.environ)
+				self.env.env.update({'BIBINPUTS':self.TEXINPUTS,'BSTINPUTS':self.TEXINPUTS})
+				self.env.SRCFILE=aux_node.name[:-4]
+				self.check_status('error when calling bibtex',self.bibtex_fun())
+	def bibunits(self):
+		try:
+			bibunits=bibunitscan(self)
+		except OSError:
+			Logs.error('error bibunitscan')
+		else:
+			if bibunits:
+				fn=['bu'+str(i)for i in xrange(1,len(bibunits)+1)]
+				if fn:
+					Logs.warn('calling bibtex on bibunits')
+				for f in fn:
+					self.env.env={'BIBINPUTS':self.TEXINPUTS,'BSTINPUTS':self.TEXINPUTS}
+					self.env.SRCFILE=f
+					self.check_status('error when calling bibtex',self.bibtex_fun())
+	def makeindex(self):
+		try:
+			idx_path=self.idx_node.abspath()
+			os.stat(idx_path)
+		except OSError:
+			Logs.warn('index file %s absent, not calling makeindex'%idx_path)
+		else:
+			Logs.warn('calling makeindex')
+			self.env.SRCFILE=self.idx_node.name
+			self.env.env={}
+			self.check_status('error when calling makeindex %s'%idx_path,self.makeindex_fun())
+	def bibtopic(self):
+		p=self.inputs[0].parent.get_bld()
+		if os.path.exists(os.path.join(p.abspath(),'btaux.aux')):
+			self.aux_nodes+=p.ant_glob('*[0-9].aux')
+	def run(self):
+		env=self.env
+		if not env['PROMPT_LATEX']:
+			env.append_value('LATEXFLAGS','-interaction=batchmode')
+			env.append_value('PDFLATEXFLAGS','-interaction=batchmode')
+			env.append_value('XELATEXFLAGS','-interaction=batchmode')
+		fun=self.texfun
+		node=self.inputs[0]
+		srcfile=node.abspath()
+		texinputs=self.env.TEXINPUTS or''
+		self.TEXINPUTS=node.parent.get_bld().abspath()+os.pathsep+node.parent.get_src().abspath()+os.pathsep+texinputs+os.pathsep
+		self.cwd=self.inputs[0].parent.get_bld().abspath()
+		Logs.warn('first pass on %s'%self.__class__.__name__)
+		self.env.env={}
+		self.env.env.update(os.environ)
+		self.env.env.update({'TEXINPUTS':self.TEXINPUTS})
+		self.env.SRCFILE=srcfile
+		self.check_status('error when calling latex',fun())
+		self.aux_nodes=self.scan_aux(node.change_ext('.aux'))
+		self.idx_node=node.change_ext('.idx')
+		self.bibtopic()
+		self.bibfile()
+		self.bibunits()
+		self.makeindex()
+		hash=''
+		for i in range(10):
+			prev_hash=hash
+			try:
+				hashes=[Utils.h_file(x.abspath())for x in self.aux_nodes]
+				hash=Utils.h_list(hashes)
+			except(OSError,IOError):
+				Logs.error('could not read aux.h')
+				pass
+			if hash and hash==prev_hash:
+				break
+			Logs.warn('calling %s'%self.__class__.__name__)
+			self.env.env={}
+			self.env.env.update(os.environ)
+			self.env.env.update({'TEXINPUTS':self.TEXINPUTS})
+			self.env.SRCFILE=srcfile
+			self.check_status('error when calling %s'%self.__class__.__name__,fun())
+class latex(tex):
+	texfun,vars=Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}',shell=False)
+class pdflatex(tex):
+	texfun,vars=Task.compile_fun('${PDFLATEX} ${PDFLATEXFLAGS} ${SRCFILE}',shell=False)
+class xelatex(tex):
+	texfun,vars=Task.compile_fun('${XELATEX} ${XELATEXFLAGS} ${SRCFILE}',shell=False)
+class dvips(Task.Task):
+	run_str='${DVIPS} ${DVIPSFLAGS} ${SRC} -o ${TGT}'
+	color='BLUE'
+	after=['latex','pdflatex','xelatex']
+class dvipdf(Task.Task):
+	run_str='${DVIPDF} ${DVIPDFFLAGS} ${SRC} ${TGT}'
+	color='BLUE'
+	after=['latex','pdflatex','xelatex']
+class pdf2ps(Task.Task):
+	run_str='${PDF2PS} ${PDF2PSFLAGS} ${SRC} ${TGT}'
+	color='BLUE'
+	after=['latex','pdflatex','xelatex']
+@feature('tex')
+@before_method('process_source')
+def apply_tex(self):
+	if not getattr(self,'type',None)in['latex','pdflatex','xelatex']:
+		self.type='pdflatex'
+	tree=self.bld
+	outs=Utils.to_list(getattr(self,'outs',[]))
+	self.env['PROMPT_LATEX']=getattr(self,'prompt',1)
+	deps_lst=[]
+	if getattr(self,'deps',None):
+		deps=self.to_list(self.deps)
+		for filename in deps:
+			n=self.path.find_resource(filename)
+			if not n:
+				self.bld.fatal('Could not find %r for %r'%(filename,self))
+			if not n in deps_lst:
+				deps_lst.append(n)
+	for node in self.to_nodes(self.source):
+		if self.type=='latex':
+			task=self.create_task('latex',node,node.change_ext('.dvi'))
+		elif self.type=='pdflatex':
+			task=self.create_task('pdflatex',node,node.change_ext('.pdf'))
+		elif self.type=='xelatex':
+			task=self.create_task('xelatex',node,node.change_ext('.pdf'))
+		task.env=self.env
+		if deps_lst:
+			try:
+				lst=tree.node_deps[task.uid()]
+				for n in deps_lst:
+					if not n in lst:
+						lst.append(n)
+			except KeyError:
+				tree.node_deps[task.uid()]=deps_lst
+		v=dict(os.environ)
+		p=node.parent.abspath()+os.pathsep+self.path.abspath()+os.pathsep+self.path.get_bld().abspath()+os.pathsep+v.get('TEXINPUTS','')+os.pathsep
+		v['TEXINPUTS']=p
+		if self.type=='latex':
+			if'ps'in outs:
+				tsk=self.create_task('dvips',task.outputs,node.change_ext('.ps'))
+				tsk.env.env=dict(v)
+			if'pdf'in outs:
+				tsk=self.create_task('dvipdf',task.outputs,node.change_ext('.pdf'))
+				tsk.env.env=dict(v)
+		elif self.type=='pdflatex':
+			if'ps'in outs:
+				self.create_task('pdf2ps',task.outputs,node.change_ext('.ps'))
+	self.source=[]
+def configure(self):
+	v=self.env
+	for p in'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps'.split():
+		try:
+			self.find_program(p,var=p.upper())
+		except self.errors.ConfigurationError:
+			pass
+	v['DVIPSFLAGS']='-Ppdf'
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/vala.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/vala.py
new file mode 100644
index 0000000..96248c1
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/vala.py
@@ -0,0 +1,201 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os.path,shutil,re
+from waflib import Context,Task,Utils,Logs,Options,Errors
+from waflib.TaskGen import extension,taskgen_method
+from waflib.Configure import conf
+class valac(Task.Task):
+	vars=["VALAC","VALAC_VERSION","VALAFLAGS"]
+	ext_out=['.h']
+	def run(self):
+		cmd=[self.env['VALAC']]+self.env['VALAFLAGS']
+		cmd.extend([a.abspath()for a in self.inputs])
+		ret=self.exec_command(cmd,cwd=self.outputs[0].parent.abspath())
+		if ret:
+			return ret
+		for x in self.outputs:
+			if id(x.parent)!=id(self.outputs[0].parent):
+				shutil.move(self.outputs[0].parent.abspath()+os.sep+x.name,x.abspath())
+		if self.generator.dump_deps_node:
+			self.generator.dump_deps_node.write('\n'.join(self.generator.packages))
+		return ret
+valac=Task.update_outputs(valac)
+@taskgen_method
+def init_vala_task(self):
+	self.profile=getattr(self,'profile','gobject')
+	if self.profile=='gobject':
+		self.uselib=Utils.to_list(getattr(self,'uselib',[]))
+		if not'GOBJECT'in self.uselib:
+			self.uselib.append('GOBJECT')
+	def addflags(flags):
+		self.env.append_value('VALAFLAGS',flags)
+	if self.profile:
+		addflags('--profile=%s'%self.profile)
+	if hasattr(self,'threading'):
+		if self.profile=='gobject':
+			if not'GTHREAD'in self.uselib:
+				self.uselib.append('GTHREAD')
+		else:
+			Logs.warn("Profile %s means no threading support"%self.profile)
+			self.threading=False
+		if self.threading:
+			addflags('--threading')
+	valatask=self.valatask
+	self.is_lib='cprogram'not in self.features
+	if self.is_lib:
+		addflags('--library=%s'%self.target)
+		h_node=self.path.find_or_declare('%s.h'%self.target)
+		valatask.outputs.append(h_node)
+		addflags('--header=%s'%h_node.name)
+		valatask.outputs.append(self.path.find_or_declare('%s.vapi'%self.target))
+		if getattr(self,'gir',None):
+			gir_node=self.path.find_or_declare('%s.gir'%self.gir)
+			addflags('--gir=%s'%gir_node.name)
+			valatask.outputs.append(gir_node)
+	self.vala_target_glib=getattr(self,'vala_target_glib',getattr(Options.options,'vala_target_glib',None))
+	if self.vala_target_glib:
+		addflags('--target-glib=%s'%self.vala_target_glib)
+	addflags(['--define=%s'%x for x in getattr(self,'vala_defines',[])])
+	packages_private=Utils.to_list(getattr(self,'packages_private',[]))
+	addflags(['--pkg=%s'%x for x in packages_private])
+	def _get_api_version():
+		api_version='1.0'
+		if hasattr(Context.g_module,'API_VERSION'):
+			version=Context.g_module.API_VERSION.split(".")
+			if version[0]=="0":
+				api_version="0."+version[1]
+			else:
+				api_version=version[0]+".0"
+		return api_version
+	self.includes=Utils.to_list(getattr(self,'includes',[]))
+	self.uselib=self.to_list(getattr(self,'uselib',[]))
+	valatask.install_path=getattr(self,'install_path','')
+	valatask.vapi_path=getattr(self,'vapi_path','${DATAROOTDIR}/vala/vapi')
+	valatask.pkg_name=getattr(self,'pkg_name',self.env['PACKAGE'])
+	valatask.header_path=getattr(self,'header_path','${INCLUDEDIR}/%s-%s'%(valatask.pkg_name,_get_api_version()))
+	valatask.install_binding=getattr(self,'install_binding',True)
+	self.packages=packages=Utils.to_list(getattr(self,'packages',[]))
+	self.vapi_dirs=vapi_dirs=Utils.to_list(getattr(self,'vapi_dirs',[]))
+	includes=[]
+	if hasattr(self,'use'):
+		local_packages=Utils.to_list(self.use)[:]
+		seen=[]
+		while len(local_packages)>0:
+			package=local_packages.pop()
+			if package in seen:
+				continue
+			seen.append(package)
+			try:
+				package_obj=self.bld.get_tgen_by_name(package)
+			except Errors.WafError:
+				continue
+			package_name=package_obj.target
+			package_node=package_obj.path
+			package_dir=package_node.path_from(self.path)
+			for task in package_obj.tasks:
+				for output in task.outputs:
+					if output.name==package_name+".vapi":
+						valatask.set_run_after(task)
+						if package_name not in packages:
+							packages.append(package_name)
+						if package_dir not in vapi_dirs:
+							vapi_dirs.append(package_dir)
+						if package_dir not in includes:
+							includes.append(package_dir)
+			if hasattr(package_obj,'use'):
+				lst=self.to_list(package_obj.use)
+				lst.reverse()
+				local_packages=[pkg for pkg in lst if pkg not in seen]+local_packages
+	addflags(['--pkg=%s'%p for p in packages])
+	for vapi_dir in vapi_dirs:
+		v_node=self.path.find_dir(vapi_dir)
+		if not v_node:
+			Logs.warn('Unable to locate Vala API directory: %r'%vapi_dir)
+		else:
+			addflags('--vapidir=%s'%v_node.abspath())
+			addflags('--vapidir=%s'%v_node.get_bld().abspath())
+	self.dump_deps_node=None
+	if self.is_lib and self.packages:
+		self.dump_deps_node=self.path.find_or_declare('%s.deps'%self.target)
+		valatask.outputs.append(self.dump_deps_node)
+	self.includes.append(self.bld.srcnode.abspath())
+	self.includes.append(self.bld.bldnode.abspath())
+	for include in includes:
+		try:
+			self.includes.append(self.path.find_dir(include).abspath())
+			self.includes.append(self.path.find_dir(include).get_bld().abspath())
+		except AttributeError:
+			Logs.warn("Unable to locate include directory: '%s'"%include)
+	if self.is_lib and valatask.install_binding:
+		headers_list=[o for o in valatask.outputs if o.suffix()==".h"]
+		try:
+			self.install_vheader.source=headers_list
+		except AttributeError:
+			self.install_vheader=self.bld.install_files(valatask.header_path,headers_list,self.env)
+		vapi_list=[o for o in valatask.outputs if(o.suffix()in(".vapi",".deps"))]
+		try:
+			self.install_vapi.source=vapi_list
+		except AttributeError:
+			self.install_vapi=self.bld.install_files(valatask.vapi_path,vapi_list,self.env)
+		gir_list=[o for o in valatask.outputs if o.suffix()=='.gir']
+		try:
+			self.install_gir.source=gir_list
+		except AttributeError:
+			self.install_gir=self.bld.install_files(getattr(self,'gir_path','${DATAROOTDIR}/gir-1.0'),gir_list,self.env)
+@extension('.vala','.gs')
+def vala_file(self,node):
+	try:
+		valatask=self.valatask
+	except AttributeError:
+		valatask=self.valatask=self.create_task('valac')
+		self.init_vala_task()
+	valatask.inputs.append(node)
+	c_node=node.change_ext('.c')
+	valatask.outputs.append(c_node)
+	self.source.append(c_node)
+@conf
+def find_valac(self,valac_name,min_version):
+	valac=self.find_program(valac_name,var='VALAC')
+	try:
+		output=self.cmd_and_log(valac+' --version')
+	except Exception:
+		valac_version=None
+	else:
+		ver=re.search(r'\d+.\d+.\d+',output).group(0).split('.')
+		valac_version=tuple([int(x)for x in ver])
+	self.msg('Checking for %s version >= %r'%(valac_name,min_version),valac_version,valac_version and valac_version>=min_version)
+	if valac and valac_version<min_version:
+		self.fatal("%s version %r is too old, need >= %r"%(valac_name,valac_version,min_version))
+	self.env['VALAC_VERSION']=valac_version
+	return valac
+@conf
+def check_vala(self,min_version=(0,8,0),branch=None):
+	if not branch:
+		branch=min_version[:2]
+	try:
+		find_valac(self,'valac-%d.%d'%(branch[0],branch[1]),min_version)
+	except self.errors.ConfigurationError:
+		find_valac(self,'valac',min_version)
+@conf
+def check_vala_deps(self):
+	if not self.env['HAVE_GOBJECT']:
+		pkg_args={'package':'gobject-2.0','uselib_store':'GOBJECT','args':'--cflags --libs'}
+		if getattr(Options.options,'vala_target_glib',None):
+			pkg_args['atleast_version']=Options.options.vala_target_glib
+		self.check_cfg(**pkg_args)
+	if not self.env['HAVE_GTHREAD']:
+		pkg_args={'package':'gthread-2.0','uselib_store':'GTHREAD','args':'--cflags --libs'}
+		if getattr(Options.options,'vala_target_glib',None):
+			pkg_args['atleast_version']=Options.options.vala_target_glib
+		self.check_cfg(**pkg_args)
+def configure(self):
+	self.load('gnu_dirs')
+	self.check_vala_deps()
+	self.check_vala()
+	self.env.VALAFLAGS=['-C','--quiet']
+def options(opt):
+	opt.load('gnu_dirs')
+	valaopts=opt.add_option_group('Vala Compiler Options')
+	valaopts.add_option('--vala-target-glib',default=None,dest='vala_target_glib',metavar='MAJOR.MINOR',help='Target version of glib for Vala GObject code generation')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/waf_unit_test.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/waf_unit_test.py
new file mode 100644
index 0000000..3363172
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/waf_unit_test.py
@@ -0,0 +1,97 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys
+from waflib.TaskGen import feature,after_method
+from waflib import Utils,Task,Logs,Options
+testlock=Utils.threading.Lock()
+@feature('test')
+@after_method('apply_link')
+def make_test(self):
+	if getattr(self,'link_task',None):
+		self.create_task('utest',self.link_task.outputs)
+class utest(Task.Task):
+	color='PINK'
+	after=['vnum','inst']
+	vars=[]
+	def runnable_status(self):
+		if getattr(Options.options,'no_tests',False):
+			return Task.SKIP_ME
+		ret=super(utest,self).runnable_status()
+		if ret==Task.SKIP_ME:
+			if getattr(Options.options,'all_tests',False):
+				return Task.RUN_ME
+		return ret
+	def run(self):
+		filename=self.inputs[0].abspath()
+		self.ut_exec=getattr(self.generator,'ut_exec',[filename])
+		if getattr(self.generator,'ut_fun',None):
+			self.generator.ut_fun(self)
+		try:
+			fu=getattr(self.generator.bld,'all_test_paths')
+		except AttributeError:
+			fu=os.environ.copy()
+			lst=[]
+			for g in self.generator.bld.groups:
+				for tg in g:
+					if getattr(tg,'link_task',None):
+						s=tg.link_task.outputs[0].parent.abspath()
+						if s not in lst:
+							lst.append(s)
+			def add_path(dct,path,var):
+				dct[var]=os.pathsep.join(Utils.to_list(path)+[os.environ.get(var,'')])
+			if Utils.is_win32:
+				add_path(fu,lst,'PATH')
+			elif Utils.unversioned_sys_platform()=='darwin':
+				add_path(fu,lst,'DYLD_LIBRARY_PATH')
+				add_path(fu,lst,'LD_LIBRARY_PATH')
+			else:
+				add_path(fu,lst,'LD_LIBRARY_PATH')
+			self.generator.bld.all_test_paths=fu
+		cwd=getattr(self.generator,'ut_cwd','')or self.inputs[0].parent.abspath()
+		testcmd=getattr(Options.options,'testcmd',False)
+		if testcmd:
+			self.ut_exec=(testcmd%self.ut_exec[0]).split(' ')
+		proc=Utils.subprocess.Popen(self.ut_exec,cwd=cwd,env=fu,stderr=Utils.subprocess.PIPE,stdout=Utils.subprocess.PIPE)
+		(stdout,stderr)=proc.communicate()
+		tup=(filename,proc.returncode,stdout,stderr)
+		self.generator.utest_result=tup
+		testlock.acquire()
+		try:
+			bld=self.generator.bld
+			Logs.debug("ut: %r",tup)
+			try:
+				bld.utest_results.append(tup)
+			except AttributeError:
+				bld.utest_results=[tup]
+		finally:
+			testlock.release()
+def summary(bld):
+	lst=getattr(bld,'utest_results',[])
+	if lst:
+		Logs.pprint('CYAN','execution summary')
+		total=len(lst)
+		tfail=len([x for x in lst if x[1]])
+		Logs.pprint('CYAN','  tests that pass %d/%d'%(total-tfail,total))
+		for(f,code,out,err)in lst:
+			if not code:
+				Logs.pprint('CYAN','    %s'%f)
+		Logs.pprint('CYAN','  tests that fail %d/%d'%(tfail,total))
+		for(f,code,out,err)in lst:
+			if code:
+				Logs.pprint('CYAN','    %s'%f)
+def set_exit_code(bld):
+	lst=getattr(bld,'utest_results',[])
+	for(f,code,out,err)in lst:
+		if code:
+			msg=[]
+			if out:
+				msg.append('stdout:%s%s'%(os.linesep,out.decode('utf-8')))
+			if err:
+				msg.append('stderr:%s%s'%(os.linesep,err.decode('utf-8')))
+			bld.fatal(os.linesep.join(msg))
+def options(opt):
+	opt.add_option('--notests',action='store_true',default=False,help='Exec no unit tests',dest='no_tests')
+	opt.add_option('--alltests',action='store_true',default=False,help='Exec all unit tests',dest='all_tests')
+	opt.add_option('--testcmd',action='store',default=False,help='Run the unit tests using the test-cmd string'' example "--test-cmd="valgrind --error-exitcode=1'' %s" to run under valgrind',dest='testcmd')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/winres.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/winres.py
new file mode 100644
index 0000000..88904af
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/winres.py
@@ -0,0 +1,85 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import re,traceback
+from waflib import Task,Logs,Utils
+from waflib.TaskGen import extension
+from waflib.Tools import c_preproc
+@extension('.rc')
+def rc_file(self,node):
+	obj_ext='.rc.o'
+	if self.env['WINRC_TGT_F']=='/fo':
+		obj_ext='.res'
+	rctask=self.create_task('winrc',node,node.change_ext(obj_ext))
+	try:
+		self.compiled_tasks.append(rctask)
+	except AttributeError:
+		self.compiled_tasks=[rctask]
+re_lines=re.compile('(?:^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*?)\s*$)|''(?:^\w+[ \t]*(ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)[ \t]*(.*?)\s*$)',re.IGNORECASE|re.MULTILINE)
+class rc_parser(c_preproc.c_parser):
+	def filter_comments(self,filepath):
+		code=Utils.readf(filepath)
+		if c_preproc.use_trigraphs:
+			for(a,b)in c_preproc.trig_def:code=code.split(a).join(b)
+		code=c_preproc.re_nl.sub('',code)
+		code=c_preproc.re_cpp.sub(c_preproc.repl,code)
+		ret=[]
+		for m in re.finditer(re_lines,code):
+			if m.group(2):
+				ret.append((m.group(2),m.group(3)))
+			else:
+				ret.append(('include',m.group(5)))
+		return ret
+	def addlines(self,node):
+		self.currentnode_stack.append(node.parent)
+		filepath=node.abspath()
+		self.count_files+=1
+		if self.count_files>c_preproc.recursion_limit:
+			raise c_preproc.PreprocError("recursion limit exceeded")
+		pc=self.parse_cache
+		Logs.debug('preproc: reading file %r',filepath)
+		try:
+			lns=pc[filepath]
+		except KeyError:
+			pass
+		else:
+			self.lines.extend(lns)
+			return
+		try:
+			lines=self.filter_comments(filepath)
+			lines.append((c_preproc.POPFILE,''))
+			lines.reverse()
+			pc[filepath]=lines
+			self.lines.extend(lines)
+		except IOError:
+			raise c_preproc.PreprocError("could not read the file %s"%filepath)
+		except Exception:
+			if Logs.verbose>0:
+				Logs.error("parsing %s failed"%filepath)
+				traceback.print_exc()
+class winrc(Task.Task):
+	run_str='${WINRC} ${WINRCFLAGS} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${WINRC_TGT_F} ${TGT} ${WINRC_SRC_F} ${SRC}'
+	color='BLUE'
+	def scan(self):
+		tmp=rc_parser(self.generator.includes_nodes)
+		tmp.start(self.inputs[0],self.env)
+		nodes=tmp.nodes
+		names=tmp.names
+		if Logs.verbose:
+			Logs.debug('deps: deps for %s: %r; unresolved %r'%(str(self),nodes,names))
+		return(nodes,names)
+def configure(conf):
+	v=conf.env
+	v['WINRC_TGT_F']='-o'
+	v['WINRC_SRC_F']='-i'
+	if not conf.env.WINRC:
+		if v.CC_NAME=='msvc':
+			conf.find_program('RC',var='WINRC',path_list=v['PATH'])
+			v['WINRC_TGT_F']='/fo'
+			v['WINRC_SRC_F']=''
+		else:
+			conf.find_program('windres',var='WINRC',path_list=v['PATH'])
+	if not conf.env.WINRC:
+		conf.fatal('winrc was not found!')
+	v['WINRCFLAGS']=[]
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/xlc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/xlc.py
new file mode 100644
index 0000000..fbf0fcf
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/xlc.py
@@ -0,0 +1,45 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_xlc(conf):
+	cc=conf.find_program(['xlc_r','xlc'],var='CC')
+	cc=conf.cmd_to_list(cc)
+	conf.get_xlc_version(cc)
+	conf.env.CC_NAME='xlc'
+	conf.env.CC=cc
+@conf
+def xlc_common_flags(conf):
+	v=conf.env
+	v['CC_SRC_F']=[]
+	v['CC_TGT_F']=['-c','-o']
+	if not v['LINK_CC']:v['LINK_CC']=v['CC']
+	v['CCLNK_SRC_F']=[]
+	v['CCLNK_TGT_F']=['-o']
+	v['CPPPATH_ST']='-I%s'
+	v['DEFINES_ST']='-D%s'
+	v['LIB_ST']='-l%s'
+	v['LIBPATH_ST']='-L%s'
+	v['STLIB_ST']='-l%s'
+	v['STLIBPATH_ST']='-L%s'
+	v['RPATH_ST']='-Wl,-rpath,%s'
+	v['SONAME_ST']=[]
+	v['SHLIB_MARKER']=[]
+	v['STLIB_MARKER']=[]
+	v['LINKFLAGS_cprogram']=['-Wl,-brtl']
+	v['cprogram_PATTERN']='%s'
+	v['CFLAGS_cshlib']=['-fPIC']
+	v['LINKFLAGS_cshlib']=['-G','-Wl,-brtl,-bexpfull']
+	v['cshlib_PATTERN']='lib%s.so'
+	v['LINKFLAGS_cstlib']=[]
+	v['cstlib_PATTERN']='lib%s.a'
+def configure(conf):
+	conf.find_xlc()
+	conf.find_ar()
+	conf.xlc_common_flags()
+	conf.cc_load_tools()
+	conf.cc_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/xlcxx.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/xlcxx.py
new file mode 100644
index 0000000..b7efb23
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Tools/xlcxx.py
@@ -0,0 +1,45 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib.Tools import ccroot,ar
+from waflib.Configure import conf
+@conf
+def find_xlcxx(conf):
+	cxx=conf.find_program(['xlc++_r','xlc++'],var='CXX')
+	cxx=conf.cmd_to_list(cxx)
+	conf.get_xlc_version(cxx)
+	conf.env.CXX_NAME='xlc++'
+	conf.env.CXX=cxx
+@conf
+def xlcxx_common_flags(conf):
+	v=conf.env
+	v['CXX_SRC_F']=[]
+	v['CXX_TGT_F']=['-c','-o']
+	if not v['LINK_CXX']:v['LINK_CXX']=v['CXX']
+	v['CXXLNK_SRC_F']=[]
+	v['CXXLNK_TGT_F']=['-o']
+	v['CPPPATH_ST']='-I%s'
+	v['DEFINES_ST']='-D%s'
+	v['LIB_ST']='-l%s'
+	v['LIBPATH_ST']='-L%s'
+	v['STLIB_ST']='-l%s'
+	v['STLIBPATH_ST']='-L%s'
+	v['RPATH_ST']='-Wl,-rpath,%s'
+	v['SONAME_ST']=[]
+	v['SHLIB_MARKER']=[]
+	v['STLIB_MARKER']=[]
+	v['LINKFLAGS_cxxprogram']=['-Wl,-brtl']
+	v['cxxprogram_PATTERN']='%s'
+	v['CXXFLAGS_cxxshlib']=['-fPIC']
+	v['LINKFLAGS_cxxshlib']=['-G','-Wl,-brtl,-bexpfull']
+	v['cxxshlib_PATTERN']='lib%s.so'
+	v['LINKFLAGS_cxxstlib']=[]
+	v['cxxstlib_PATTERN']='lib%s.a'
+def configure(conf):
+	conf.find_xlcxx()
+	conf.find_ar()
+	conf.xlcxx_common_flags()
+	conf.cxx_load_tools()
+	conf.cxx_add_flags()
+	conf.link_add_flags()
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Utils.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Utils.py
new file mode 100644
index 0000000..9532a3b
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Utils.py
@@ -0,0 +1,412 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os,sys,errno,traceback,inspect,re,shutil,datetime,gc
+import subprocess
+try:
+	from collections import deque
+except ImportError:
+	class deque(list):
+		def popleft(self):
+			return self.pop(0)
+try:
+	import _winreg as winreg
+except ImportError:
+	try:
+		import winreg
+	except ImportError:
+		winreg=None
+from waflib import Errors
+try:
+	from collections import UserDict
+except ImportError:
+	from UserDict import UserDict
+try:
+	from hashlib import md5
+except ImportError:
+	try:
+		from md5 import md5
+	except ImportError:
+		pass
+try:
+	import threading
+except ImportError:
+	class threading(object):
+		pass
+	class Lock(object):
+		def acquire(self):
+			pass
+		def release(self):
+			pass
+	threading.Lock=threading.Thread=Lock
+else:
+	run_old=threading.Thread.run
+	def run(*args,**kwargs):
+		try:
+			run_old(*args,**kwargs)
+		except(KeyboardInterrupt,SystemExit):
+			raise
+		except Exception:
+			sys.excepthook(*sys.exc_info())
+	threading.Thread.run=run
+SIG_NIL='iluvcuteoverload'
+O644=420
+O755=493
+rot_chr=['\\','|','/','-']
+rot_idx=0
+try:
+	from collections import defaultdict
+except ImportError:
+	class defaultdict(dict):
+		def __init__(self,default_factory):
+			super(defaultdict,self).__init__()
+			self.default_factory=default_factory
+		def __getitem__(self,key):
+			try:
+				return super(defaultdict,self).__getitem__(key)
+			except KeyError:
+				value=self.default_factory()
+				self[key]=value
+				return value
+is_win32=sys.platform in('win32','cli')
+indicator='\x1b[K%s%s%s\r'
+if is_win32 and'NOCOLOR'in os.environ:
+	indicator='%s%s%s\r'
+def readf(fname,m='r',encoding='ISO8859-1'):
+	if sys.hexversion>0x3000000 and not'b'in m:
+		m+='b'
+		f=open(fname,m)
+		try:
+			txt=f.read()
+		finally:
+			f.close()
+		txt=txt.decode(encoding)
+	else:
+		f=open(fname,m)
+		try:
+			txt=f.read()
+		finally:
+			f.close()
+	return txt
+def writef(fname,data,m='w',encoding='ISO8859-1'):
+	if sys.hexversion>0x3000000 and not'b'in m:
+		data=data.encode(encoding)
+		m+='b'
+	f=open(fname,m)
+	try:
+		f.write(data)
+	finally:
+		f.close()
+def h_file(fname):
+	f=open(fname,'rb')
+	m=md5()
+	try:
+		while fname:
+			fname=f.read(200000)
+			m.update(fname)
+	finally:
+		f.close()
+	return m.digest()
+if hasattr(os,'O_NOINHERIT'):
+	def readf_win32(f,m='r',encoding='ISO8859-1'):
+		flags=os.O_NOINHERIT|os.O_RDONLY
+		if'b'in m:
+			flags|=os.O_BINARY
+		if'+'in m:
+			flags|=os.O_RDWR
+		try:
+			fd=os.open(f,flags)
+		except OSError:
+			raise IOError('Cannot read from %r'%f)
+		if sys.hexversion>0x3000000 and not'b'in m:
+			m+='b'
+			f=os.fdopen(fd,m)
+			try:
+				txt=f.read()
+			finally:
+				f.close()
+			txt=txt.decode(encoding)
+		else:
+			f=os.fdopen(fd,m)
+			try:
+				txt=f.read()
+			finally:
+				f.close()
+		return txt
+	def writef_win32(f,data,m='w',encoding='ISO8859-1'):
+		if sys.hexversion>0x3000000 and not'b'in m:
+			data=data.encode(encoding)
+			m+='b'
+		flags=os.O_CREAT|os.O_TRUNC|os.O_WRONLY|os.O_NOINHERIT
+		if'b'in m:
+			flags|=os.O_BINARY
+		if'+'in m:
+			flags|=os.O_RDWR
+		try:
+			fd=os.open(f,flags)
+		except OSError:
+			raise IOError('Cannot write to %r'%f)
+		f=os.fdopen(fd,m)
+		try:
+			f.write(data)
+		finally:
+			f.close()
+	def h_file_win32(fname):
+		try:
+			fd=os.open(fname,os.O_BINARY|os.O_RDONLY|os.O_NOINHERIT)
+		except OSError:
+			raise IOError('Cannot read from %r'%fname)
+		f=os.fdopen(fd,'rb')
+		m=md5()
+		try:
+			while fname:
+				fname=f.read(200000)
+				m.update(fname)
+		finally:
+			f.close()
+		return m.digest()
+	readf_old=readf
+	writef_old=writef
+	h_file_old=h_file
+	readf=readf_win32
+	writef=writef_win32
+	h_file=h_file_win32
+try:
+	x=''.encode('hex')
+except LookupError:
+	import binascii
+	def to_hex(s):
+		ret=binascii.hexlify(s)
+		if not isinstance(ret,str):
+			ret=ret.decode('utf-8')
+		return ret
+else:
+	def to_hex(s):
+		return s.encode('hex')
+to_hex.__doc__="""
+Return the hexadecimal representation of a string
+
+:param s: string to convert
+:type s: string
+"""
+listdir=os.listdir
+if is_win32:
+	def listdir_win32(s):
+		if not s:
+			try:
+				import ctypes
+			except ImportError:
+				return[x+':\\'for x in list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')]
+			else:
+				dlen=4
+				maxdrives=26
+				buf=ctypes.create_string_buffer(maxdrives*dlen)
+				ndrives=ctypes.windll.kernel32.GetLogicalDriveStringsA(maxdrives*dlen,ctypes.byref(buf))
+				return[str(buf.raw[4*i:4*i+2].decode('ascii'))for i in range(int(ndrives/dlen))]
+		if len(s)==2 and s[1]==":":
+			s+=os.sep
+		if not os.path.isdir(s):
+			e=OSError('%s is not a directory'%s)
+			e.errno=errno.ENOENT
+			raise e
+		return os.listdir(s)
+	listdir=listdir_win32
+def num2ver(ver):
+	if isinstance(ver,str):
+		ver=tuple(ver.split('.'))
+	if isinstance(ver,tuple):
+		ret=0
+		for i in range(4):
+			if i<len(ver):
+				ret+=256**(3-i)*int(ver[i])
+		return ret
+	return ver
+def ex_stack():
+	exc_type,exc_value,tb=sys.exc_info()
+	exc_lines=traceback.format_exception(exc_type,exc_value,tb)
+	return''.join(exc_lines)
+def to_list(sth):
+	if isinstance(sth,str):
+		return sth.split()
+	else:
+		return sth
+re_nl=re.compile('\r*\n',re.M)
+def str_to_dict(txt):
+	tbl={}
+	lines=re_nl.split(txt)
+	for x in lines:
+		x=x.strip()
+		if not x or x.startswith('#')or x.find('=')<0:
+			continue
+		tmp=x.split('=')
+		tbl[tmp[0].strip()]='='.join(tmp[1:]).strip()
+	return tbl
+def split_path(path):
+	return path.split('/')
+def split_path_cygwin(path):
+	if path.startswith('//'):
+		ret=path.split('/')[2:]
+		ret[0]='/'+ret[0]
+		return ret
+	return path.split('/')
+re_sp=re.compile('[/\\\\]')
+def split_path_win32(path):
+	if path.startswith('\\\\'):
+		ret=re.split(re_sp,path)[2:]
+		ret[0]='\\'+ret[0]
+		return ret
+	return re.split(re_sp,path)
+if sys.platform=='cygwin':
+	split_path=split_path_cygwin
+elif is_win32:
+	split_path=split_path_win32
+split_path.__doc__="""
+Split a path by / or \\. This function is not like os.path.split
+
+:type  path: string
+:param path: path to split
+:return:     list of strings
+"""
+def check_dir(path):
+	if not os.path.isdir(path):
+		try:
+			os.makedirs(path)
+		except OSError ,e:
+			if not os.path.isdir(path):
+				raise Errors.WafError('Cannot create the folder %r'%path,ex=e)
+def def_attrs(cls,**kw):
+	for k,v in kw.items():
+		if not hasattr(cls,k):
+			setattr(cls,k,v)
+def quote_define_name(s):
+	fu=re.compile("[^a-zA-Z0-9]").sub("_",s)
+	fu=fu.upper()
+	return fu
+def h_list(lst):
+	m=md5()
+	m.update(str(lst))
+	return m.digest()
+def h_fun(fun):
+	try:
+		return fun.code
+	except AttributeError:
+		try:
+			h=inspect.getsource(fun)
+		except IOError:
+			h="nocode"
+		try:
+			fun.code=h
+		except AttributeError:
+			pass
+		return h
+reg_subst=re.compile(r"(\\\\)|(\$\$)|\$\{([^}]+)\}")
+def subst_vars(expr,params):
+	def repl_var(m):
+		if m.group(1):
+			return'\\'
+		if m.group(2):
+			return'$'
+		try:
+			return params.get_flat(m.group(3))
+		except AttributeError:
+			return params[m.group(3)]
+	return reg_subst.sub(repl_var,expr)
+def destos_to_binfmt(key):
+	if key=='darwin':
+		return'mac-o'
+	elif key in('win32','cygwin','uwin','msys'):
+		return'pe'
+	return'elf'
+def unversioned_sys_platform():
+	s=sys.platform
+	if s=='java':
+		from java.lang import System
+		s=System.getProperty('os.name')
+		if s=='Mac OS X':
+			return'darwin'
+		elif s.startswith('Windows '):
+			return'win32'
+		elif s=='OS/2':
+			return'os2'
+		elif s=='HP-UX':
+			return'hpux'
+		elif s in('SunOS','Solaris'):
+			return'sunos'
+		else:s=s.lower()
+	if s=='powerpc':
+		return'darwin'
+	if s=='win32'or s.endswith('os2')and s!='sunos2':return s
+	return re.split('\d+$',s)[0]
+def nada(*k,**kw):
+	pass
+class Timer(object):
+	def __init__(self):
+		self.start_time=datetime.datetime.utcnow()
+	def __str__(self):
+		delta=datetime.datetime.utcnow()-self.start_time
+		days=int(delta.days)
+		hours=delta.seconds//3600
+		minutes=(delta.seconds-hours*3600)//60
+		seconds=delta.seconds-hours*3600-minutes*60+float(delta.microseconds)/1000/1000
+		result=''
+		if days:
+			result+='%dd'%days
+		if days or hours:
+			result+='%dh'%hours
+		if days or hours or minutes:
+			result+='%dm'%minutes
+		return'%s%.3fs'%(result,seconds)
+if is_win32:
+	old=shutil.copy2
+	def copy2(src,dst):
+		old(src,dst)
+		shutil.copystat(src,dst)
+	setattr(shutil,'copy2',copy2)
+if os.name=='java':
+	try:
+		gc.disable()
+		gc.enable()
+	except NotImplementedError:
+		gc.disable=gc.enable
+def read_la_file(path):
+	sp=re.compile(r'^([^=]+)=\'(.*)\'$')
+	dc={}
+	for line in readf(path).splitlines():
+		try:
+			_,left,right,_=sp.split(line.strip())
+			dc[left]=right
+		except ValueError:
+			pass
+	return dc
+def nogc(fun):
+	def f(*k,**kw):
+		try:
+			gc.disable()
+			ret=fun(*k,**kw)
+		finally:
+			gc.enable()
+		return ret
+	f.__doc__=fun.__doc__
+	return f
+def run_once(fun):
+	cache={}
+	def wrap(k):
+		try:
+			return cache[k]
+		except KeyError:
+			ret=fun(k)
+			cache[k]=ret
+			return ret
+	wrap.__cache__=cache
+	return wrap
+def get_registry_app_path(key,filename):
+	if not winreg:
+		return None
+	try:
+		result=winreg.QueryValue(key,"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s.exe"%filename[0])
+	except WindowsError:
+		pass
+	else:
+		if os.path.isfile(result):
+			return result
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Utils.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Utils.pyc
new file mode 100644
index 0000000..fdee815
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/Utils.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/__init__.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/__init__.py
new file mode 100644
index 0000000..efeed79
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/__init__.py
@@ -0,0 +1,4 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/__init__.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/__init__.pyc
new file mode 100644
index 0000000..1c26616
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/__init__.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/ansiterm.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/ansiterm.py
new file mode 100644
index 0000000..0de6171
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/ansiterm.py
@@ -0,0 +1,177 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import sys,os
+try:
+	if not(sys.stderr.isatty()and sys.stdout.isatty()):
+		raise ValueError('not a tty')
+	from ctypes import*
+	class COORD(Structure):
+		_fields_=[("X",c_short),("Y",c_short)]
+	class SMALL_RECT(Structure):
+		_fields_=[("Left",c_short),("Top",c_short),("Right",c_short),("Bottom",c_short)]
+	class CONSOLE_SCREEN_BUFFER_INFO(Structure):
+		_fields_=[("Size",COORD),("CursorPosition",COORD),("Attributes",c_short),("Window",SMALL_RECT),("MaximumWindowSize",COORD)]
+	class CONSOLE_CURSOR_INFO(Structure):
+		_fields_=[('dwSize',c_ulong),('bVisible',c_int)]
+	sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
+	csinfo=CONSOLE_CURSOR_INFO()
+	hconsole=windll.kernel32.GetStdHandle(-11)
+	windll.kernel32.GetConsoleScreenBufferInfo(hconsole,byref(sbinfo))
+	if sbinfo.Size.X<9 or sbinfo.Size.Y<9:raise ValueError('small console')
+	windll.kernel32.GetConsoleCursorInfo(hconsole,byref(csinfo))
+except Exception:
+	pass
+else:
+	import re,threading
+	is_vista=getattr(sys,"getwindowsversion",None)and sys.getwindowsversion()[0]>=6
+	try:
+		_type=unicode
+	except NameError:
+		_type=str
+	to_int=lambda number,default:number and int(number)or default
+	wlock=threading.Lock()
+	STD_OUTPUT_HANDLE=-11
+	STD_ERROR_HANDLE=-12
+	class AnsiTerm(object):
+		def __init__(self):
+			self.encoding=sys.stdout.encoding
+			self.hconsole=windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
+			self.cursor_history=[]
+			self.orig_sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
+			self.orig_csinfo=CONSOLE_CURSOR_INFO()
+			windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(self.orig_sbinfo))
+			windll.kernel32.GetConsoleCursorInfo(hconsole,byref(self.orig_csinfo))
+		def screen_buffer_info(self):
+			sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
+			windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(sbinfo))
+			return sbinfo
+		def clear_line(self,param):
+			mode=param and int(param)or 0
+			sbinfo=self.screen_buffer_info()
+			if mode==1:
+				line_start=COORD(0,sbinfo.CursorPosition.Y)
+				line_length=sbinfo.Size.X
+			elif mode==2:
+				line_start=COORD(sbinfo.CursorPosition.X,sbinfo.CursorPosition.Y)
+				line_length=sbinfo.Size.X-sbinfo.CursorPosition.X
+			else:
+				line_start=sbinfo.CursorPosition
+				line_length=sbinfo.Size.X-sbinfo.CursorPosition.X
+			chars_written=c_int()
+			windll.kernel32.FillConsoleOutputCharacterA(self.hconsole,c_wchar(' '),line_length,line_start,byref(chars_written))
+			windll.kernel32.FillConsoleOutputAttribute(self.hconsole,sbinfo.Attributes,line_length,line_start,byref(chars_written))
+		def clear_screen(self,param):
+			mode=to_int(param,0)
+			sbinfo=self.screen_buffer_info()
+			if mode==1:
+				clear_start=COORD(0,0)
+				clear_length=sbinfo.CursorPosition.X*sbinfo.CursorPosition.Y
+			elif mode==2:
+				clear_start=COORD(0,0)
+				clear_length=sbinfo.Size.X*sbinfo.Size.Y
+				windll.kernel32.SetConsoleCursorPosition(self.hconsole,clear_start)
+			else:
+				clear_start=sbinfo.CursorPosition
+				clear_length=((sbinfo.Size.X-sbinfo.CursorPosition.X)+sbinfo.Size.X*(sbinfo.Size.Y-sbinfo.CursorPosition.Y))
+			chars_written=c_int()
+			windll.kernel32.FillConsoleOutputCharacterA(self.hconsole,c_wchar(' '),clear_length,clear_start,byref(chars_written))
+			windll.kernel32.FillConsoleOutputAttribute(self.hconsole,sbinfo.Attributes,clear_length,clear_start,byref(chars_written))
+		def push_cursor(self,param):
+			sbinfo=self.screen_buffer_info()
+			self.cursor_history.append(sbinfo.CursorPosition)
+		def pop_cursor(self,param):
+			if self.cursor_history:
+				old_pos=self.cursor_history.pop()
+				windll.kernel32.SetConsoleCursorPosition(self.hconsole,old_pos)
+		def set_cursor(self,param):
+			y,sep,x=param.partition(';')
+			x=to_int(x,1)-1
+			y=to_int(y,1)-1
+			sbinfo=self.screen_buffer_info()
+			new_pos=COORD(min(max(0,x),sbinfo.Size.X),min(max(0,y),sbinfo.Size.Y))
+			windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos)
+		def set_column(self,param):
+			x=to_int(param,1)-1
+			sbinfo=self.screen_buffer_info()
+			new_pos=COORD(min(max(0,x),sbinfo.Size.X),sbinfo.CursorPosition.Y)
+			windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos)
+		def move_cursor(self,x_offset=0,y_offset=0):
+			sbinfo=self.screen_buffer_info()
+			new_pos=COORD(min(max(0,sbinfo.CursorPosition.X+x_offset),sbinfo.Size.X),min(max(0,sbinfo.CursorPosition.Y+y_offset),sbinfo.Size.Y))
+			windll.kernel32.SetConsoleCursorPosition(self.hconsole,new_pos)
+		def move_up(self,param):
+			self.move_cursor(y_offset=-to_int(param,1))
+		def move_down(self,param):
+			self.move_cursor(y_offset=to_int(param,1))
+		def move_left(self,param):
+			self.move_cursor(x_offset=-to_int(param,1))
+		def move_right(self,param):
+			self.move_cursor(x_offset=to_int(param,1))
+		def next_line(self,param):
+			sbinfo=self.screen_buffer_info()
+			self.move_cursor(x_offset=-sbinfo.CursorPosition.X,y_offset=to_int(param,1))
+		def prev_line(self,param):
+			sbinfo=self.screen_buffer_info()
+			self.move_cursor(x_offset=-sbinfo.CursorPosition.X,y_offset=-to_int(param,1))
+		def rgb2bgr(self,c):
+			return((c&1)<<2)|(c&2)|((c&4)>>2)
+		def set_color(self,param):
+			cols=param.split(';')
+			sbinfo=CONSOLE_SCREEN_BUFFER_INFO()
+			windll.kernel32.GetConsoleScreenBufferInfo(self.hconsole,byref(sbinfo))
+			attr=sbinfo.Attributes
+			for c in cols:
+				if is_vista:
+					c=int(c)
+				else:
+					c=to_int(c,0)
+				if c in range(30,38):
+					attr=(attr&0xfff0)|self.rgb2bgr(c-30)
+				elif c in range(40,48):
+					attr=(attr&0xff0f)|(self.rgb2bgr(c-40)<<4)
+				elif c==0:
+					attr=self.orig_sbinfo.Attributes
+				elif c==1:
+					attr|=0x08
+				elif c==4:
+					attr|=0x80
+				elif c==7:
+					attr=(attr&0xff88)|((attr&0x70)>>4)|((attr&0x07)<<4)
+			windll.kernel32.SetConsoleTextAttribute(self.hconsole,attr)
+		def show_cursor(self,param):
+			csinfo.bVisible=1
+			windll.kernel32.SetConsoleCursorInfo(self.hconsole,byref(csinfo))
+		def hide_cursor(self,param):
+			csinfo.bVisible=0
+			windll.kernel32.SetConsoleCursorInfo(self.hconsole,byref(csinfo))
+		ansi_command_table={'A':move_up,'B':move_down,'C':move_right,'D':move_left,'E':next_line,'F':prev_line,'G':set_column,'H':set_cursor,'f':set_cursor,'J':clear_screen,'K':clear_line,'h':show_cursor,'l':hide_cursor,'m':set_color,'s':push_cursor,'u':pop_cursor,}
+		ansi_tokens=re.compile('(?:\x1b\[([0-9?;]*)([a-zA-Z])|([^\x1b]+))')
+		def write(self,text):
+			try:
+				wlock.acquire()
+				for param,cmd,txt in self.ansi_tokens.findall(text):
+					if cmd:
+						cmd_func=self.ansi_command_table.get(cmd)
+						if cmd_func:
+							cmd_func(self,param)
+					else:
+						self.writeconsole(txt)
+			finally:
+				wlock.release()
+		def writeconsole(self,txt):
+			chars_written=c_int()
+			writeconsole=windll.kernel32.WriteConsoleA
+			if isinstance(txt,_type):
+				writeconsole=windll.kernel32.WriteConsoleW
+			TINY_STEP=3000
+			for x in range(0,len(txt),TINY_STEP):
+				tiny=txt[x:x+TINY_STEP]
+				writeconsole(self.hconsole,tiny,len(tiny),byref(chars_written),None)
+		def flush(self):
+			pass
+		def isatty(self):
+			return True
+	sys.stderr=sys.stdout=AnsiTerm()
+	os.environ['TERM']='vt100'
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/ansiterm.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/ansiterm.pyc
new file mode 100644
index 0000000..66446c8
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/ansiterm.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/__init__.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/__init__.py
new file mode 100644
index 0000000..efeed79
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/__init__.py
@@ -0,0 +1,4 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/__init__.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/__init__.pyc
new file mode 100644
index 0000000..deadd32
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/__init__.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/boost.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/boost.py
new file mode 100644
index 0000000..72a8706
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/boost.py
@@ -0,0 +1,260 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+'''
+
+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']
+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 << std::endl; }
+'''
+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.add_option('--boost-includes',type='string',default='',dest='boost_includes',help='''path to the boost includes root (~boost root)
+				   e.g. /path/to/boost_1_47_0''')
+	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_47_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,dir):
+	try:
+		return self.root.find_dir(dir).find_node(BOOST_VERSION_FILE)
+	except:
+		return None
+@conf
+def boost_get_version(self,dir):
+	re_but=re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.*)"$',re.M)
+	try:
+		val=re_but.search(self.__boost_get_version_file(dir).read()).group(1)
+	except:
+		val=self.check_cxx(fragment=BOOST_VERSION_CODE,includes=[dir],execute=False,define_ret=True)
+	return val
+@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:
+			try:
+				path=self.root.find_dir(d)
+				files=path.ant_glob('*boost_*')
+				if files:
+					break
+				path=self.root.find_dir(d+'64')
+				files=path.ant_glob('*boost_*')
+				if files:
+					break
+			except:
+				path=None
+	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''
+		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),'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):
+	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)
+	self.env.BOOST_VERSION=self.boost_get_version(inc)
+	self.end_msg(self.env.BOOST_VERSION)
+	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="\n".join(['#include <boost/system/error_code.hpp>','int main() { boost::system::error_code c; }',]),use=var,execute=False,)
+		if'thread'in params['lib']:
+			self.check_cxx(fragment="\n".join(['#include <boost/thread.hpp>','int main() { boost::thread t; }',]),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']:
+			self.env['DEFINES_%s'%var]+=['BOOST_ALL_NO_LIB']
+			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]
+			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 ,e:
+			self.end_msg("Could not link against boost libraries using supplied options")
+			self.fatal('The configuration failed')
+		self.end_msg('ok')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/boost.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/boost.pyc
new file mode 100644
index 0000000..3ab3bca
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/boost.pyc
Binary files differ
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/doxygen.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/doxygen.py
new file mode 100644
index 0000000..10c425c
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/doxygen.py
@@ -0,0 +1,145 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from fnmatch import fnmatchcase
+import os,os.path,re,stat
+from waflib import Task,Utils,Node,Logs
+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()
+			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
+			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):
+		if self.pars.get('RECURSIVE')=='YES':
+			Logs.warn("Doxygen RECURSIVE dependencies are not supported")
+		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
+		nodes=[]
+		names=[]
+		for node in self.doxy_inputs:
+			if os.path.isdir(node.abspath()):
+				for m in node.ant_glob(file_patterns):
+					nodes.append(m)
+			else:
+				nodes.append(node)
+		return(nodes,names)
+	def run(self):
+		dct=self.pars.copy()
+		dct['INPUT']=' '.join([x.abspath()for x in self.doxy_inputs])
+		code='\n'.join(['%s = %s'%(x,dct[x])for x in self.pars])
+		code=code
+		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):
+	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):
+			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')
+	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):
+	conf.find_program('doxygen',var='DOXYGEN')
+	conf.find_program('tar',var='TAR')
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/protoc.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/protoc.py
new file mode 100644
index 0000000..d5feb5a
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/extras/protoc.py
@@ -0,0 +1,25 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+from waflib.Task import Task
+from waflib.TaskGen import extension
+class protoc(Task):
+	run_str='${PROTOC} ${PROTOC_FLAGS} ${PROTOC_ST:INCPATHS} ${SRC[0].abspath()}'
+	color='BLUE'
+	ext_out=['.h','pb.cc']
+@extension('.proto')
+def process_protoc(self,node):
+	cpp_node=node.change_ext('.pb.cc')
+	hpp_node=node.change_ext('.pb.h')
+	self.create_task('protoc',node,[cpp_node,hpp_node])
+	self.source.append(cpp_node)
+	if'cxx'in self.features and not self.env.PROTOC_FLAGS:
+		self.env.PROTOC_FLAGS='--cpp_out=%s'%node.parent.get_bld().abspath()
+	use=getattr(self,'use','')
+	if not'PROTOBUF'in use:
+		self.use=self.to_list(use)+['PROTOBUF']
+def configure(conf):
+	conf.check_cfg(package="protobuf",uselib_store="PROTOBUF",args=['--cflags','--libs'])
+	conf.find_program('protoc',var='PROTOC')
+	conf.env.PROTOC_ST='-I%s'
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/fixpy2.py b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/fixpy2.py
new file mode 100644
index 0000000..98f7036
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/fixpy2.py
@@ -0,0 +1,53 @@
+#! /usr/bin/env python
+# encoding: utf-8
+# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
+
+import os
+all_modifs={}
+def fixdir(dir):
+	global all_modifs
+	for k in all_modifs:
+		for v in all_modifs[k]:
+			modif(os.path.join(dir,'waflib'),k,v)
+def modif(dir,name,fun):
+	if name=='*':
+		lst=[]
+		for y in'. Tools extras'.split():
+			for x in os.listdir(os.path.join(dir,y)):
+				if x.endswith('.py'):
+					lst.append(y+os.sep+x)
+		for x in lst:
+			modif(dir,x,fun)
+		return
+	filename=os.path.join(dir,name)
+	f=open(filename,'r')
+	try:
+		txt=f.read()
+	finally:
+		f.close()
+	txt=fun(txt)
+	f=open(filename,'w')
+	try:
+		f.write(txt)
+	finally:
+		f.close()
+def subst(*k):
+	def do_subst(fun):
+		global all_modifs
+		for x in k:
+			try:
+				all_modifs[x].append(fun)
+			except KeyError:
+				all_modifs[x]=[fun]
+		return fun
+	return do_subst
+@subst('*')
+def r1(code):
+	code=code.replace(',e:',',e:')
+	code=code.replace("",'')
+	code=code.replace('','')
+	return code
+@subst('Runner.py')
+def r4(code):
+	code=code.replace('next(self.biter)','self.biter.next()')
+	return code
diff --git a/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/fixpy2.pyc b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/fixpy2.pyc
new file mode 100644
index 0000000..62761bc
--- /dev/null
+++ b/src/.waf-1.7.11-bbc5cd6dca9f655c3704b49a62d00211/waflib/fixpy2.pyc
Binary files differ
diff --git a/src/communication/nlsr_dm.cpp b/src/communication/nlsr_dm.cpp
index e425767..ffb85e3 100644
--- a/src/communication/nlsr_dm.cpp
+++ b/src/communication/nlsr_dm.cpp
@@ -191,21 +191,26 @@
   void
   DataManager::processContentKeys(Nlsr& pnlsr, const ndn::Data& data)
   {
-    cout<<" processContentKeys called "<<endl;
+    std::cout<<" processContentKeys called "<<endl;
     ndn::shared_ptr<ndn::IdentityCertificate> cert=
       ndn::make_shared<ndn::IdentityCertificate>();
     cert->wireDecode(data.getContent().blockFromValue());
-    cout<<*(cert)<<endl;
+    std::cout<<*(cert)<<endl;
     std::string dataName=data.getName().toUri();
     nlsrTokenizer nt(dataName,"/");
     std::string certName=nt.getTokenString(0,nt.getTokenNumber()-3);
     uint32_t seqNum=boost::lexical_cast<uint32_t>(nt.getToken(
                       nt.getTokenNumber()-2));
     cout<<"Cert Name: "<<certName<<" Seq Num: "<<seqNum<<std::endl;
-    if ( pnlsr.getKeyManager().verify(*(cert)))
+    if ( pnlsr.getKeyManager().verify(pnlsr, *(cert)))
     {
       pnlsr.getKeyManager().addCertificate(cert, seqNum, true);
-      //pnlsr.getKeyManager().printCertStore();
     }
+    else
+    {
+      pnlsr.getKeyManager().addCertificate(cert, seqNum, false);
+    }
+    
+    pnlsr.getKeyManager().printCertStore();
   }
 }//namespace nlsr
diff --git a/src/communication/nlsr_im.cpp b/src/communication/nlsr_im.cpp
index b22b445..16d0c72 100644
--- a/src/communication/nlsr_im.cpp
+++ b/src/communication/nlsr_im.cpp
@@ -43,12 +43,6 @@
     {
       processInterestKeys(pnlsr,interest);
     }
-    //Data data(ndn::Name(interest->getName()).append("testApp").appendVersion());
-    //data.setFreshnessPeriod(1000); // 10 sec
-    //data.setContent((const uint8_t*)"HELLO KITTY", sizeof("HELLO KITTY"));
-    //pnlsr.getKeyChain().sign(data);
-    //cout << ">> D: " << data << endl;
-    //pnlsr.getNlsrFace().put(data);
   }
 
   void
@@ -190,31 +184,54 @@
     string intName=interest.getName().toUri();
     cout<<"Interest Name for Key: "<<intName<<std::endl;
     nlsrTokenizer nt(intName,"/");
-    std::string certName=nt.getTokenString(0,nt.getTokenNumber()-2);
-    uint32_t seqNum=boost::lexical_cast<uint32_t>(nt.getToken(
-                      nt.getTokenNumber()-1));
-    cout<<"Cert Name: "<<certName<<" Seq Num: "<<seqNum<<std::endl;
-    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> chkCert=
-      pnlsr.getKeyManager().getCertificateFromStore(certName,seqNum);
+    std::string chkString("ID-CERT");
+    std::string certName;
+    uint32_t seqNum;
+    ndn::Name dataName;
+    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> chkCert;
+    if( nt.getTokenPosition(chkString) == nt.getTokenNumber()-1 )
+    {
+      certName=nt.getTokenString(0,nt.getTokenNumber()-1);
+      cout<<"Cert Name: "<<certName<<std::endl;
+      chkCert=pnlsr.getKeyManager().getCertificateFromStore(certName);
+    }
+    else
+    {
+      certName=nt.getTokenString(0,nt.getTokenNumber()-2);
+      seqNum=boost::lexical_cast<uint32_t>(nt.getToken(nt.getTokenNumber()-1));
+      cout<<"Cert Name: "<<certName<<" Seq Num: "<<seqNum<<std::endl;
+      chkCert=pnlsr.getKeyManager().getCertificateFromStore(certName,seqNum);
+    }
     if( chkCert.second )
     {
-      Data data(ndn::Name(interest.getName()).appendVersion());
+      if(nt.getTokenPosition(chkString) == nt.getTokenNumber()-1)
+      {
+        std::string dn;
+        dataName=ndn::Name(interest.getName()).appendVersion();
+        std::pair<uint32_t, bool> seqChk = 
+                           pnlsr.getKeyManager().getCertificateSeqNum(certName);
+        if( seqChk.second )
+        {
+          dn=dataName.toUri()+"/"+boost::lexical_cast<std::string>(seqChk.first);
+          dataName=ndn::Name(dn);
+        }
+        else
+        {
+          dn=dataName.toUri()+"/"+boost::lexical_cast<std::string>(10);
+          dataName=ndn::Name(dn);
+        }
+        
+      }
+      else
+      {
+        dataName=ndn::Name(interest.getName());
+      }
+      Data data(dataName.appendVersion());
       data.setFreshnessPeriod(1000); //10 sec
       data.setContent(chkCert.first->wireEncode());
       pnlsr.getKeyManager().signData(data);
       pnlsr.getNlsrFace()->put(data);
     }
-    //std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> chkCert=
-    /*
-    ndn::shared_ptr<ndn::IdentityCertificate> cert=pnlsr.getKeyManager().getCertificate();
-    Data data(ndn::Name(interest.getName()).appendVersion());
-    data.setFreshnessPeriod(1000); // 10 sec
-    data.setContent(cert->wireEncode());
-    pnlsr.getKeyManager().signData(data);
-    //std::ofstream outFile("data_sent");
-    //ndn::io::save(data,outFile,ndn::io::NO_ENCODING);
-    pnlsr.getNlsrFace()->put(data);
-    */
   }
 
 
diff --git a/src/communication/nlsr_slh.cpp b/src/communication/nlsr_slh.cpp
index 098610d..189612a 100644
--- a/src/communication/nlsr_slh.cpp
+++ b/src/communication/nlsr_slh.cpp
@@ -130,10 +130,10 @@
   void
   SyncLogicHandler::publishKeyUpdate(KeyManager& km)
   {
-    publishSyncUpdate(km.getRootCertName().toUri(), 10);
-    publishSyncUpdate(km.getSiteCertName().toUri(), 10);
-    publishSyncUpdate(km.getOperatorCertName().toUri(), 10);
-    publishSyncUpdate(km.getRouterCertName().toUri(), km.getCertSeqNo());
+    //publishSyncUpdate(km.getRootCertName().toUri(), 10);
+    //publishSyncUpdate(km.getSiteCertName().toUri(), 10);
+    //publishSyncUpdate(km.getOperatorCertName().toUri(), 10);
+    //publishSyncUpdate(km.getRouterCertName().toUri(), km.getCertSeqNo());
     publishSyncUpdate(km.getProcessCertName().toUri(),km.getCertSeqNo());
   }
 
diff --git a/src/nlsr.cpp b/src/nlsr.cpp
index e2c8e57..08338f2 100644
--- a/src/nlsr.cpp
+++ b/src/nlsr.cpp
@@ -48,7 +48,7 @@
     fib.setFibEntryRefreshTime(2*confParam.getLsaRefreshTime());
     if( ! km.initKeyManager(confParam) )
     {
-      std::cerr<<"Can not initiate certificate"<<endl;
+      std::cerr<<"Can not initiate/load certificate"<<endl;
     }
     sm.setSeqFileName(confParam.getSeqFileDir());
     sm.initiateSeqNoFromFile();
diff --git a/src/nlsr.hpp b/src/nlsr.hpp
index ffdcdc1..9a580f3 100644
--- a/src/nlsr.hpp
+++ b/src/nlsr.hpp
@@ -20,7 +20,6 @@
 #include "communication/nlsr_slh.hpp"
 
 
-
 namespace nlsr
 {
 
diff --git a/src/security/nlsr_cert_store.cpp b/src/security/nlsr_cert_store.cpp
index d1e821a..897d44a 100644
--- a/src/security/nlsr_cert_store.cpp
+++ b/src/security/nlsr_cert_store.cpp
@@ -1,4 +1,8 @@
+#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp> 
+#include <ndn-cpp-dev/security/key-chain.hpp>
 #include "nlsr_cert_store.hpp"
+#include "nlsr_wle.hpp"
+#include "nlsr_km.hpp"
 
 namespace nlsr
 {
@@ -6,9 +10,13 @@
   nlsrCertificateStoreEntryCompare(NlsrCertificateStoreEntry& ncse1,
                                    NlsrCertificateStoreEntry& ncse2)
 
-  {
-    return ncse1.getCert()->getName().toUri() ==
-           ncse2.getCert()->getName().toUri() ;
+  {    
+    int sizeDiff=ncse1.getCert()->getName().size()-
+                                              ncse2.getCert()->getName().size();
+    return (ncse2.getCert()->getName().isPrefixOf(ncse1.getCert()->getName()) &&
+                                               (sizeDiff <= 1 && sizeDiff>= 0));
+  
+    
   }
 
   static bool
@@ -17,8 +25,59 @@
 
   {
     ndn::Name ccn(compCertName);
-    return ( ncse1.getCert()->getName().toUri() == compCertName ||
-             ccn.isPrefixOf(ncse1.getCert()->getName()) );
+    int sizeDiff= ncse1.getCert()->getName().size() -ccn.size();
+    return ( ccn.isPrefixOf(ncse1.getCert()->getName()) &&
+                                               (sizeDiff <= 1 && sizeDiff>= 0));
+  }
+  
+  void 
+  NlsrCertificateStore::updateWaitingList(std::string respCertName)
+  {
+    ndn::Name tmpName(respCertName);
+    respCertName=tmpName.getPrefix(-1).toUri();
+    std::pair<WaitingListEntry, bool> chkWle=
+                              waitingList.getWaitingListEntry(respCertName);
+    if( chkWle.second )
+    {
+      std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> sc=
+                                          getCertificateFromStore(respCertName);
+      std::list<std::string> waitees=(chkWle.first).getWaitingCerts();
+      for(std::list<std::string>::iterator it = waitees.begin();
+                                                       it != waitees.end();++it)
+      {
+        KeyManager km;
+        std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> wc=
+                                                 getCertificateFromStore(*(it));
+        if( wc.second && sc.second )
+        {
+          if(km.verifySignature(*(wc.first),sc.first->getPublicKeyInfo()))
+          {
+            //1. Update Certificate Store
+            setCertificateIsVerified(*(it),true);
+            //2. Call updateWaitingList for waitee ( *(it) )
+            updateWaitingList(*(it));
+          }
+        }
+      }
+    }
+    
+    //remove that entry from waiting list
+    waitingList.removeFromWaitingList(respCertName);
+  }
+  
+  void
+  NlsrCertificateStore::updateWaitingList(NlsrCertificateStoreEntry& ncse)
+  {
+    if( ncse.getIsSignerVerified())
+    {
+      updateWaitingList(ncse.getCert()->getName().toUri());
+    }
+    else
+    {
+      ndn::SignatureSha256WithRsa signature(ncse.getCert()->getSignature());
+      waitingList.addtoWaitingList(signature.getKeyLocator().getName().toUri(), 
+                                             ncse.getCert()->getName().toUri());
+    }
   }
 
   bool
@@ -30,14 +89,16 @@
     if(it == certTable.end())
     {
       certTable.push_back(ncse);
+      updateWaitingList(ncse);
       return true;
     }
-    if( it !=  certTable.end() )
+    else if( it !=  certTable.end() )
     {
       if ( (*it).getCertSeqNum() < ncse.getCertSeqNum() )
       {
         certTable.erase(it);
         certTable.push_back(ncse);
+        updateWaitingList(ncse);
         return true;
       }
     }
@@ -52,6 +113,48 @@
     return addCertificate(ncse);
   }
 
+  std::pair<uint32_t, bool>
+  NlsrCertificateStore::getCertificateSeqNum(std::string certName)
+  {
+    std::list<NlsrCertificateStoreEntry>::iterator it =
+      std::find_if( certTable.begin(), certTable.end(),
+                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+    if(it == certTable.end())
+    {
+      return std::make_pair(0,false);
+    }
+    return std::make_pair((*it).getCertSeqNum(),true);
+  }
+  
+ 
+  
+  void 
+  NlsrCertificateStore::setCertificateIsVerified(std::string certName, 
+                                                                bool isVerified)
+  {
+    std::list<NlsrCertificateStoreEntry>::iterator it =
+      std::find_if( certTable.begin(), certTable.end(),
+                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+    if(it != certTable.end())
+    {
+      it->setIsSignerVerified(true);
+    }
+  }
+  
+  bool
+  NlsrCertificateStore::getCertificateIsVerified( std::string certName )
+  {
+    std::list<NlsrCertificateStoreEntry>::iterator it =
+      std::find_if( certTable.begin(), certTable.end(),
+                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+    if(it != certTable.end())
+    {
+      return it->getIsSignerVerified();
+    }
+    
+    return false;
+  }
+
   std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
   NlsrCertificateStore::getCertificateFromStore(const std::string certName)
   {
@@ -61,7 +164,7 @@
     if(it == certTable.end())
     {
       ndn::shared_ptr<ndn::IdentityCertificate> cert=
-        ndn::make_shared<ndn::IdentityCertificate>();
+                                    ndn::make_shared<ndn::IdentityCertificate>();
       return std::make_pair(cert,false);
     }
     return std::make_pair((*it).getCert(),true);
@@ -126,5 +229,6 @@
     {
       std::cout<<(*it)<<std::endl;
     }
+    std::cout<<waitingList<<std::endl;
   }
 }
diff --git a/src/security/nlsr_cert_store.hpp b/src/security/nlsr_cert_store.hpp
index 5c9cabb..d9c9b64 100644
--- a/src/security/nlsr_cert_store.hpp
+++ b/src/security/nlsr_cert_store.hpp
@@ -4,6 +4,7 @@
 #include<list>
 #include <ndn-cpp-dev/security/identity-certificate.hpp>
 #include "nlsr_cse.hpp"
+#include "nlsr_wl.hpp"
 
 namespace nlsr
 {
@@ -11,20 +12,30 @@
   {
   public:
     NlsrCertificateStore()
+        : certTable()
+        , waitingList()
     {}
 
     bool addCertificate(NlsrCertificateStoreEntry & ncse);
     bool addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
                         , uint32_t csn, bool isv);
     std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-    getCertificateFromStore(const std::string certName);
+                            getCertificateFromStore(const std::string certName);
     std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-    getCertificateFromStore(const std::string certName, int checkSeqNum);
+           getCertificateFromStore(const std::string certName, int checkSeqNum);
     bool removeCertificateFromStroe(const std::string certName);
     bool isCertificateNewInStore(const std::string certName, int checkSeqNo);
+    std::pair<uint32_t, bool> getCertificateSeqNum(std::string certName);
     void printCertStore();
+    void setCertificateIsVerified(std::string certName, bool isVerified);
+    bool getCertificateIsVerified(std::string certName);
+  private:
+    void updateWaitingList(NlsrCertificateStoreEntry& ncse);
+    void updateWaitingList(std::string respCertName);
+    
   private:
     std::list<NlsrCertificateStoreEntry> certTable;
+    WaitingList waitingList;
   };
 }
 
diff --git a/src/security/nlsr_km.cpp b/src/security/nlsr_km.cpp
index 8838878..183e934 100644
--- a/src/security/nlsr_km.cpp
+++ b/src/security/nlsr_km.cpp
@@ -4,6 +4,7 @@
 #include <stdexcept>
 #include "nlsr_sm.hpp"
 #include "nlsr_km.hpp"
+#include "nlsr.hpp"
 
 namespace nlsr
 {
@@ -34,13 +35,13 @@
     ndn::KeyChain::deleteIdentity(processIdentity);
     processCertName = ndn::KeyChain::createIdentity(processIdentity);
     cout<<"Certificate Name: "<<processCertName.toUri()<<endl;
-    processKeyName=
-      ndn::IdentityCertificate::certificateNameToPublicKeyName(processCertName);
+    processKeyName=processCertName.getPrefix(-2);
     cout<<"Key Name: "<<processKeyName.toUri()<<endl;
-    ndn::shared_ptr<ndn::IdentityCertificate> cert=getCertificate(processCertName);
+    ndn::shared_ptr<ndn::IdentityCertificate> cert = 
+                                                getCertificate(processCertName);
     signByIdentity(*(cert),routerIdentity);
     certStore.addCertificate(cert, certSeqNo, true);
-    //certStore.printCertStore();
+    certStore.printCertStore();
     return true;
   }
 
@@ -73,22 +74,27 @@
         case KEY_TYPE_ROOT:
           certStore.addCertificate(cert, 10, true);
           rootCertName=certName;
+          std::cout<<"Root Cert: "<<rootCertName<<std::endl;
           break;
         case KEY_TYPE_SITE:
           certStore.addCertificate(cert, 10, true);
           siteCertName=certName;
+          std::cout<<"Site Cert: "<<siteCertName<<std::endl;
           break;
         case KEY_TYPE_OPERATOR:
           certStore.addCertificate(cert, 10, true);
           opCertName=certName;
+          std::cout<<"Operator Cert: "<<opCertName<<std::endl;
           break;
         case KEY_TYPE_ROUTER:
           certStore.addCertificate(cert, certSeqNo, true);
           routerCertName=certName;
+          std::cout<<"Router Cert: "<<routerCertName<<std::endl;
           break;
         case KEY_TYPE_PROCESS:
           certStore.addCertificate(cert, certSeqNo, true);
           processCertName=certName;
+          std::cout<<"Process Cert: "<<processCertName<<std::endl;
           break;
         default:
           break;
@@ -188,12 +194,24 @@
     return certStore.getCertificateFromStore(certName, checkSeqNum);
   }
 
+  std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+  KeyManager::getCertificateFromStore(const std::string certName)
+  {
+    return certStore.getCertificateFromStore(certName);
+  }
+
   bool
   KeyManager::addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
                              , uint32_t csn, bool isv)
   {
     return certStore.addCertificate(pcert, csn, isv);
   }
+  
+  std::pair<uint32_t, bool> 
+  KeyManager::getCertificateSeqNum(std::string certName)
+  {
+    return certStore.getCertificateSeqNum(certName);
+  }
 
   nlsrKeyType
   KeyManager::getKeyTypeFromName(const std::string keyName)
@@ -300,6 +318,85 @@
     }
     return siteName;
   }
+  
+  std::string 
+  KeyManager::getRootName(const std::string name)
+  {
+    std::string rName;
+    nlsrTokenizer nt(name,"/");
+    std::string rkp(nlsrRootKeyPrefix);
+    nlsrTokenizer ntRkp(rkp,"/");
+    rName=nt.getTokenString(0,ntRkp.getTokenNumber()-1);
+    return rName;
+  }
+  
+  
+  bool
+  KeyManager::verifyCertPacket(Nlsr& pnlsr, ndn::IdentityCertificate& packet)
+    {
+      std::cout<<"KeyManager::verifyCertPacket Called"<<std::endl;
+      ndn::SignatureSha256WithRsa signature(packet.getSignature());
+      std::string signingCertName=signature.getKeyLocator().getName().toUri();
+      std::string packetName=packet.getName().toUri();
+      
+      std::cout<<"Packet Name: "<<packetName<<std::endl;
+      std::cout<<"Signee Name: "<<signingCertName<<std::endl;
+      
+      int paketCertType=getKeyTypeFromName(packetName);
+      int signingCertType=getKeyTypeFromName(signingCertName);
+      
+      if( signingCertType > paketCertType ) //lower level Cert can not sign
+      {                                     //upper level Cert
+        return false;
+      }
+      
+      if((signingCertType == paketCertType) && (paketCertType != KEY_TYPE_ROOT))
+      {
+        return false;
+      }
+      
+      std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> signee=
+                             certStore.getCertificateFromStore(signingCertName);
+      
+      if( signee.second )
+      {
+        switch(paketCertType)
+        {
+          case KEY_TYPE_ROOT:
+            return ((getRootName(packetName) == nlsrRootKeyPrefix) &&
+                     verifySignature(packet,signee.first->getPublicKeyInfo()));
+            break;
+          case KEY_TYPE_SITE:
+            return ((getRootName(packetName) == getRootName(signingCertName)) &&
+                      verifySignature(packet,signee.first->getPublicKeyInfo()) &&
+                      certStore.getCertificateIsVerified(signingCertName));                   
+            break;
+          case KEY_TYPE_OPERATOR:
+            return ((getSiteName(packetName) == getSiteName(signingCertName)) &&
+                     verifySignature(packet,signee.first->getPublicKeyInfo()) &&
+                     certStore.getCertificateIsVerified(signingCertName)); 
+            break;
+          case KEY_TYPE_ROUTER:
+            return ((getSiteName(packetName) == getSiteName(signingCertName)) &&
+                     verifySignature(packet,signee.first->getPublicKeyInfo()) &&
+                     certStore.getCertificateIsVerified(signingCertName));
+            break;
+          case KEY_TYPE_PROCESS:
+            return ((getRouterName(packetName) == getRouterName(signingCertName)) &&
+                     verifySignature(packet,signee.first->getPublicKeyInfo()) &&
+                     certStore.getCertificateIsVerified(signingCertName));
+            break;
+        }
+      }
+      else
+      {
+        std::cout<<"Certificate Not Found in store. Sending Interest"<<std::endl;
+        pnlsr.getIm().expressInterest(pnlsr, signingCertName, 3,
+                              pnlsr.getConfParameter().getInterestResendTime());
+        return false;
+      }
+      return false;
+    }
 }
 
 
diff --git a/src/security/nlsr_km.hpp b/src/security/nlsr_km.hpp
index c141fcf..7d75fb2 100644
--- a/src/security/nlsr_km.hpp
+++ b/src/security/nlsr_km.hpp
@@ -14,6 +14,7 @@
 
 namespace nlsr
 {
+  class Nlsr;
   enum nlsrKeyType
   {
     KEY_TYPE_ROOT,
@@ -173,18 +174,14 @@
         std::string routerNameFromPacketName=getRouterName(packetName);
         std::string routerNameFromCertName=getRouterName(signingCertName);
         return ( (routerNameFromPacketName== routerNameFromCertName) &&
-                 verifySignature(packet, signee.first->getPublicKeyInfo()));
+                 verifySignature(packet, signee.first->getPublicKeyInfo()) &&
+                 certStore.getCertificateIsVerified(signingCertName));
       }
       return false;
     }
 
     bool
-    verifyCertPacket(ndn::IdentityCertificate packet)
-    {
-      std::cout<<"KeyManager::verifyCertPacket Called"<<std::endl;
-      return true;
-    }
-
+    verifyCertPacket(Nlsr& pnlsr, ndn::IdentityCertificate& packet);
 
   public:
     template<typename T>
@@ -192,19 +189,17 @@
     verify(T& packet )
     {
       std::cout<<"KeyManager::verify Called"<<std::endl;
-      std::string packetName=packet.getName().toUri();
-      nlsrTokenizer nt(packetName,"/");
-      std::string keyHandle("keys");
-      if ( nt.doesTokenExist(keyHandle) )
-      {
-        return verifyCertPacket(packet);
-      }
-      else
-      {
-        return verifyDataPacket(packet);
-      }
+      
+      return verifyDataPacket(packet);
+      
       return false;
     }
+    
+    bool
+    verify(Nlsr& pnlsr, ndn::IdentityCertificate& packet)
+    {
+      return verifyCertPacket(pnlsr, packet);
+    }
 
     ndn::Name getProcessCertName();
     ndn::Name getRouterCertName();
@@ -213,6 +208,7 @@
     ndn::Name getRootCertName();
 
     uint32_t getCertSeqNo();
+    std::pair<uint32_t, bool> getCertificateSeqNum(std::string certName);
     void setCerSeqNo(uint32_t csn);
     void initCertSeqFromFile(string certSeqFileDir);
     void writeCertSeqToFile();
@@ -231,6 +227,7 @@
     nlsrKeyType getKeyTypeFromName(const std::string keyName);
     std::string getRouterName(const std::string name);
     std::string getSiteName(const std::string name);
+    std::string getRootName(const std::string name);
 
   private:
     ndn::Name processIdentity;
diff --git a/src/security/nlsr_wl.cpp b/src/security/nlsr_wl.cpp
new file mode 100644
index 0000000..39ddfe3
--- /dev/null
+++ b/src/security/nlsr_wl.cpp
@@ -0,0 +1,75 @@
+#include <ndn-cpp-dev/face.hpp>
+#include "nlsr_wl.hpp"
+
+namespace nlsr
+{
+  static bool
+  waitingListCompare(const WaitingListEntry& w1, const std::string& respCert)
+  {
+    return w1.getResponsibleCert() == respCert;
+  }
+  
+  std::pair<WaitingListEntry, bool> 
+  WaitingList::getWaitingListEntry(std::string respCert)
+  {
+    std::list<WaitingListEntry>::iterator it = std::find_if( waitingTable.begin(),
+                waitingTable.end(),ndn::bind(&waitingListCompare, _1, respCert));
+    if( it != waitingTable.end() )
+    {
+      return std::make_pair(*(it),true);
+    }
+    
+    WaitingListEntry wle;
+    return std::make_pair(wle,false);
+    
+  }
+  
+  bool 
+  WaitingList::addtoWaitingList(std::string respCert, std::string waitee)
+  {
+    std::list<WaitingListEntry>::iterator it = std::find_if( waitingTable.begin(),
+                waitingTable.end(),ndn::bind(&waitingListCompare, _1, respCert));
+    if( it == waitingTable.end() )
+    {
+      WaitingListEntry newWle(respCert);
+      newWle.addWaitee(waitee);
+      waitingTable.push_back(newWle);
+      return true;
+    }
+    else
+    {
+      return it->addWaitee(waitee);
+    }
+    return false;
+  }
+  
+  bool 
+  WaitingList::removeFromWaitingList(std::string respCert)
+  {
+    std::list<WaitingListEntry>::iterator it = std::find_if( waitingTable.begin(),
+                waitingTable.end(),ndn::bind(&waitingListCompare, _1, respCert));
+    if( it == waitingTable.end() )
+    {
+      return false;
+    }
+    else
+    {
+      waitingTable.erase(it);
+      return true;
+    }
+    return false;
+  }
+  
+  std::ostream& 
+  operator<<(std::ostream& os, WaitingList wl)
+  {
+    os<<"-------Waiting List--------"<<std::endl;
+    std::list<WaitingListEntry> wles=wl.getWaitingTable();
+    for( std::list<WaitingListEntry> ::iterator it=wles.begin(); 
+                                                        it != wles.end(); ++it)
+    {
+      os<<*(it)<<std::endl;
+    }
+    return os;
+  }
+}
diff --git a/src/security/nlsr_wl.hpp b/src/security/nlsr_wl.hpp
new file mode 100644
index 0000000..c287842
--- /dev/null
+++ b/src/security/nlsr_wl.hpp
@@ -0,0 +1,31 @@
+#ifndef NLSR_WL_HPP
+#define NLSR_WL_HPP
+
+#include "nlsr_wle.hpp"
+
+namespace nlsr
+{
+  class WaitingList
+  {
+    public:
+      WaitingList()
+        : waitingTable()
+      {}
+      
+      std::list<WaitingListEntry>& getWaitingTable()
+      {
+        return waitingTable;
+      }
+      
+      bool addtoWaitingList(std::string respCert, std::string waitee);
+      std::pair<WaitingListEntry, bool> getWaitingListEntry(std::string respCert);
+      bool removeFromWaitingList(std::string respCert);
+      
+    private:
+      std::list<WaitingListEntry> waitingTable;
+  };
+  
+  std::ostream& operator<<(std::ostream& os, WaitingList wl);
+}
+
+#endif
diff --git a/src/security/nlsr_wle.cpp b/src/security/nlsr_wle.cpp
new file mode 100644
index 0000000..df83544
--- /dev/null
+++ b/src/security/nlsr_wle.cpp
@@ -0,0 +1,42 @@
+#include <iostream>
+#include <list>
+#include <ndn-cpp-dev/face.hpp>
+#include "nlsr_wle.hpp"
+
+namespace nlsr
+{
+  static bool
+  waiteeCompare(std::string& w1, std::string& w2)
+  {
+    return w1 == w2 ;
+  }
+  
+  bool
+  WaitingListEntry::addWaitee(std::string waiteeName)
+  {
+    std::list<std::string>::iterator it = std::find_if( waitingCerts.begin(),
+                waitingCerts.end(),ndn::bind(&waiteeCompare, _1, waiteeName));
+    if( it == waitingCerts.end() )
+    {
+      waitingCerts.push_back(waiteeName);
+      return true;
+    }
+    
+    return false;
+  }
+
+  std::ostream& 
+  operator<<(std::ostream& os, const WaitingListEntry& we)
+  {
+    os<<"-------------Wiating List Entry-------------"<<std::endl;
+    os<<"Responsible Certificate: "<<we.getResponsibleCert()<<std::endl;
+    std::list<std::string> waitee=we.getWaitingCerts();
+    int i=1;
+    for(std::list<std::string>::iterator it=waitee.begin(); 
+                                             it!=waitee.end(); ++i, ++it)
+    {
+      os<<"Waite "<<i<<": "<<*(it)<<std::endl;
+    }
+    return os;
+  }
+}
diff --git a/src/security/nlsr_wle.hpp b/src/security/nlsr_wle.hpp
new file mode 100644
index 0000000..c8e6fd6
--- /dev/null
+++ b/src/security/nlsr_wle.hpp
@@ -0,0 +1,47 @@
+#ifndef NLSR_WLE_HPP
+#define NLSR_WLE_HPP
+
+#include <list>
+#include <iostream>
+
+namespace nlsr
+{
+  class WaitingListEntry
+  {
+    public:
+      WaitingListEntry()
+        : responsibleCert()
+        , waitingCerts()
+      {}
+      
+      WaitingListEntry(std::string resCert)
+        : responsibleCert(resCert)
+        , waitingCerts()
+      {}
+      
+      std::string getResponsibleCert() const
+      {
+        return responsibleCert;
+      }
+      
+      void setResponsibleCert(std::string resCert)
+      {
+        responsibleCert=resCert;
+      }
+      
+      std::list<std::string> getWaitingCerts() const
+      {
+        return waitingCerts;
+      }
+      
+      bool addWaitee(std::string waiteeName);
+      
+    private:
+      std::string responsibleCert;
+      std::list<std::string> waitingCerts;
+  };
+  
+  std::ostream& operator<<(std::ostream& os, const WaitingListEntry& we);
+} //end name space
+
+#endif
