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
