Index: Jenkins/Distribute
===================================================================
--- Jenkins/Distribute	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ Jenkins/Distribute	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -15,4 +15,5 @@
 	SrcDir    = pwd tmp: false
 	Settings  = null
+	Version   = ''
 
 	// Local variables
@@ -22,51 +23,34 @@
 	currentBuild.result = "SUCCESS"
 
-	try {
-		//Wrap build to add timestamp to command line
-		wrap([$class: 'TimestamperBuildWrapper']) {
+	//Wrap build to add timestamp to command line
+	wrap([$class: 'TimestamperBuildWrapper']) {
 
-			final commit = prepare_build()
+		final commit, build
+		(commit, build) = prepare_build()
 
-			node('x64') {
-				BuildDir  = pwd tmp: true
-				SrcDir    = pwd tmp: false
-
-				Tools.Clean()
-
-				Tools.Checkout( commit )
-			}
-
-			// Update the build directories when exiting the node
+		node('x64') {
 			BuildDir  = pwd tmp: true
 			SrcDir    = pwd tmp: false
+
+			Tools.Clean()
+
+			Tools.Checkout( commit )
+
+			Version = GetVersion( build )
+
+			Configure()
+
+			Package()
+
+			Test()
+
+			Archive()
 		}
+
+		// Update the build directories when exiting the node
+		BuildDir  = pwd tmp: true
+		SrcDir    = pwd tmp: false
 	}
 
-	//If an exception is caught we need to change the status and remember to
-	//attach the build log to the email
-	// catch (Exception caughtError) {
-		// //rethrow error later
-		// err = caughtError
-
-		// echo err.toString()
-
-		// //An error has occured, the build log is relevent
-		// log_needed = true
-
-		// //Store the result of the build log
-		// currentBuild.result = "${StageName} FAILURE".trim()
-	// }
-
-	finally {
-		// //Send email with final results if this is not a full build
-		// email(log_needed)
-
-		// echo 'Distribution Completed'
-
-		// /* Must re-throw exception to propagate error */
-		// if (err) {
-		// 	throw err
-		// }
-	}
 }
 
@@ -74,17 +58,64 @@
 // Main compilation routines
 //===========================================================================================================
+def GetVersion(build) {
+	final pver = sh(
+		returnStdout: true,
+		script: "sed 's/AC_INIT(\\[cfa-cc\\],\\[\\(.*\\)\\],\\[cforall@plg.uwaterloo.ca\\])/\\1/;t;d' ${SrcDir}/configure.ac"
+	).trim()
 
+	final version = "${pver}.${build}"
 
-//Compilation script is done here but environnement set-up and error handling is done in main loop
-// def checkout() {
-// 	build_stage('Checkout', true) {
-// 		//checkout the source code and clean the repo
-// 		final scmVars = checkout scm
-// 		Settings.GitNewRef = scmVars.GIT_COMMIT
-// 		Settings.GitOldRef = scmVars.GIT_PREVIOUS_COMMIT
+	echo "Package Version: ${pver}"
+	echo "Build   Version: ${build}"
+	echo "Long    Version: ${version}"
 
-// 		echo GitLogMessage()
-// 	}
-// }
+	return version
+}
+
+def Configure() {
+	Tools.BuildStage('Configure', true) {
+		// Configure must be run inside the tree
+		dir (SrcDir) {
+			// Generate the necessary build files
+			sh './autogen.sh'
+		}
+
+		// Build outside of the src tree to ease cleaning
+		dir (BuildDir) {
+			// Configure the compilation (Output is not relevant)
+			// Use the current directory as the installation target so nothing escapes the sandbox
+			// Also specify the compiler by hand
+			sh "${SrcDir}/configure CXX=g++-9 CC=gcc-9 AR=gcc-ar RANLIB=gcc-ranlib --quiet"
+
+			// Configure libcfa
+			sh 'make -j 8 --no-print-directory configure-libcfa'
+		}
+	}
+}
+
+def Package() {
+	Tools.BuildStage('Package', true) {
+		dir (BuildDir) {
+			sh "make VERSION=${Version} dist"
+		}
+	}
+}
+
+def Test() {
+	Tools.BuildStage('Test', true) {
+		dir (BuildDir) {
+			sh "make VERSION=${Version} distcheck -j 8"
+		}
+	}
+}
+
+def Archive() {
+	Tools.BuildStage('Archive', true) {
+		dir (BuildDir) {
+			archiveArtifacts artifacts: "cfa-cc-*.tar.gz", fingerprint: true
+		}
+	}
+}
+
 
 //===========================================================================================================
@@ -107,4 +138,9 @@
 					defaultValue: '',  								\
 				],												\
+				[$class: 'StringParameterDefinition',						\
+					description: 'Build Number to put into the version',			\
+					name: 'Build',									\
+					defaultValue: '0',  								\
+				],												\
 			],
 		]])
@@ -121,5 +157,5 @@
 	echo "Distributing git commit ${ref}"
 
-	return params.GitRef
+	return [params.GitRef, params.Build]
 }
 
Index: Jenkins/FullBuild
===================================================================
--- Jenkins/FullBuild	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ Jenkins/FullBuild	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -26,6 +26,10 @@
 					gcc_5_x64_old: { trigger_build( 'gcc-5',   'x64', false ) },
 					clang_x64_old: { trigger_build( 'clang',   'x64', false ) },
-					// clang_x64_new: { trigger_build( 'clang',   'x64', true  ) },
+					clang_x64_new: { trigger_build( 'clang',   'x64', true  ) },
 				)
+			}
+
+			stage('Package') {
+				build job: 'Cforall_Distribute_Ref', parameters: [string(name: 'GitRef', value: gitRefNewValue), string(name: 'Build', value: currentBuild.number)]
 			}
 		}
Index: Jenkins/tools.groovy
===================================================================
--- Jenkins/tools.groovy	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ Jenkins/tools.groovy	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -68,9 +68,6 @@
 PrevGitNewRef = ''
 def GitLogMessage(String oldRef = '', String newRef = '') {
-	if (!oldRef) { if(!PrevGitOldRef) { return "\nERROR retrieveing current git information!\n"  } else { PreGitOldRef = oldRef } }
-	if (!newRef) { if(!PrevGitNewRef) { return "\nERROR retrieveing previous git information!\n" } else { PreGitNewRef = newRef } }
-
-	PrevGitOldRef = oldRef
-	PrevGitNewRef = newRef
+	if (!oldRef) { if(!PrevGitOldRef) { return "\nERROR retrieveing current git information!\n"  } else { oldRef = PrevGitOldRef } }
+	if (!newRef) { if(!PrevGitNewRef) { return "\nERROR retrieveing previous git information!\n" } else { newRef = PrevGitNewRef } }
 
 	def revText = sh(returnStdout: true, script: "git rev-list ${oldRef}..${newRef}").trim()
Index: Jenkinsfile
===================================================================
--- Jenkinsfile	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ Jenkinsfile	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -93,5 +93,5 @@
 		// Build outside of the src tree to ease cleaning
 		dir (BuildDir) {
-			//Configure the conpilation (Output is not relevant)
+			//Configure the compilation (Output is not relevant)
 			//Use the current directory as the installation target so nothing escapes the sandbox
 			//Also specify the compiler by hand
Index: Makefile.am
===================================================================
--- Makefile.am	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ Makefile.am	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -19,7 +19,8 @@
 
 MAINTAINERCLEANFILES = lib/* bin/* tests/.deps/* tests/.out/* # order important
+DISTCLEANFILES = version
 
 SUBDIRS = driver src . @LIBCFA_TARGET_DIRS@
-DIST_SUBDIRS = driver src . libcfa benchmark longrun_tests tests tools tools/prettyprinter
+DIST_SUBDIRS = driver src . libcfa tests
 
 @LIBCFA_TARGET_MAKEFILES@ : Makefile $(srcdir)/libcfa/configure
@@ -34,5 +35,5 @@
 man1_MANS = doc/man/cfa.1
 
-EXTRA_DIST = LICENSE doc/man/cfa.1 libcfa/configure libcfa/Makefile.dist.am libcfa/Makefile.dist.in
+EXTRA_DIST = LICENSE doc/man/cfa.1 libcfa/configure libcfa/Makefile.dist.am libcfa/Makefile.dist.in tools/build/distcc_hash tools/build/push2dist.sh
 
 debug=yes
@@ -50,2 +51,18 @@
 	@./config.status --config | sed "s/ /\n\t/g; s/\t'/\t/g; s/'\n/\n/g; s/^'//g; s/'$$//g"
 	@find libcfa -name config.status -printf "\n%h\n\t" -exec {} --config \; | sed "s/ /\n\t/g; s/\t'/\t/g; s/'\n/\n/g; s/^'//g; s/'$$//g"
+
+mostlyclean-local: @LIBCFA_TARGET_MAKEFILES@
+	for dir in @LIBCFA_TARGET_DIRS@; do \
+		$(MAKE) -C $${dir} mostlyclean; \
+	done
+
+clean-local: @LIBCFA_TARGET_MAKEFILES@
+	for dir in @LIBCFA_TARGET_DIRS@; do \
+		$(MAKE) -C $${dir} clean; \
+	done
+
+distclean-local: @LIBCFA_TARGET_MAKEFILES@
+	for dir in @LIBCFA_TARGET_DIRS@; do \
+		$(MAKE) -C $${dir} distclean; \
+		rm $${dir}/config.data; \
+	done
Index: configure.ac
===================================================================
--- configure.ac	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ configure.ac	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -3,5 +3,5 @@
 
 AC_PREREQ([2.68])
-AC_INIT([cfa-cc],[1.0.0.0],[cforall@plg.uwaterloo.ca])
+AC_INIT([cfa-cc],[1.0.0],[cforall@plg.uwaterloo.ca])
 AC_CONFIG_AUX_DIR([automake])
 AC_CONFIG_MACRO_DIRS([automake])
@@ -28,5 +28,5 @@
 # New AST toggling support
 AH_TEMPLATE([CFA_USE_NEW_AST],[Sets whether or not to use the new-ast, this is adefault value and can be overrided by --old-ast and --new-ast])
-DEFAULT_NEW_AST="False"
+DEFAULT_NEW_AST="True"
 AC_ARG_ENABLE(new-ast,
 	[  --enable-new-ast     whether or not to use new ast as the default AST algorithm],
@@ -35,5 +35,5 @@
 		no)  newast=false; DEFAULT_NEW_AST="False" ;;
 		*) AC_MSG_ERROR([bad value ${enableval} for --enable-new-ast]) ;;
-	esac],[newast=false])
+	esac],[newast=true])
 AC_DEFINE_UNQUOTED([CFA_USE_NEW_AST], $newast)
 AC_SUBST(DEFAULT_NEW_AST)
@@ -103,6 +103,6 @@
 # Create variables for commonly used targets
 
-TOP_SRCDIR="$(readlink -m $ac_confdir/)/"
-TOP_BUILDDIR="$(readlink -m $ac_pwd/)/"
+TOP_SRCDIR="$(readlink -e $ac_abs_confdir/)/"
+TOP_BUILDDIR="$(readlink -e $ac_pwd/)/"
 
 AC_DEFINE_UNQUOTED(TOP_SRCDIR, "$TOP_SRCDIR", [Top src directory])
@@ -139,4 +139,8 @@
 		\'--enable-gprofiler=*) ;;
 		\'--disable-gprofiler) ;;
+
+		# skip the target hosts
+		\'--enable-new-ast=*) ;;
+		\'--disable-new-ast) ;;
 
 		# skip this, it only causes problems
@@ -287,10 +291,16 @@
 	libcfa/Makefile:libcfa/Makefile.dist.in
 	tests/Makefile
-	longrun_tests/Makefile
-	benchmark/Makefile
-	benchmark/io/http/Makefile
-	tools/Makefile
-	tools/prettyprinter/Makefile
 	])
+
+# Some of our makefile don't need to be distributed
+AM_CONDITIONAL([CFORALL_DISTRIBUTE], [test -e $TOP_SRCDIR/autogen.sh])
+AM_COND_IF([CFORALL_DISTRIBUTE],
+	[AC_CONFIG_FILES([
+		longrun_tests/Makefile
+		benchmark/Makefile
+		benchmark/io/http/Makefile
+		tools/Makefile
+		tools/prettyprinter/Makefile
+		])])
 
 AC_CONFIG_LINKS([tests/test.py:tests/test.py])
Index: driver/Makefile.am
===================================================================
--- driver/Makefile.am	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ driver/Makefile.am	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -28,4 +28,5 @@
 	@test -z "$(CFA_BINDIR)" || $(MKDIR_P) "$(CFA_BINDIR)"
 	@echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) cfa '$(CFA_BINDIR)/$(CFA_NAME)'"; \
+	chmod u+w $(CFA_BINDIR);\
 	$(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) cfa $(CFA_BINDIR)/$(CFA_NAME) || exit $$?
 
Index: libcfa/configure.ac
===================================================================
--- libcfa/configure.ac	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ libcfa/configure.ac	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -3,5 +3,5 @@
 
 AC_PREREQ([2.68])
-AC_INIT([cfa-cc],[1.0.0.0],[cforall@plg.uwaterloo.ca])
+AC_INIT([cfa-cc],[1.0.0],[cforall@plg.uwaterloo.ca])
 AC_CONFIG_AUX_DIR([automake])
 AC_CONFIG_MACRO_DIRS([automake])
Index: libcfa/prelude/Makefile.am
===================================================================
--- libcfa/prelude/Makefile.am	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ libcfa/prelude/Makefile.am	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -70,4 +70,5 @@
 
 MOSTLYCLEANFILES = bootloader.c builtins.cf extras.cf gcc-builtins.c gcc-builtins.cf prelude.cfa
+DISTCLEANFILES = $(DEPDIR)/builtins.Po
 MAINTAINERCLEANFILES = ${addprefix ${libdir}/,${cfalib_DATA}} ${addprefix ${libdir}/,${lib_LIBRARIES}}
 
Index: libcfa/src/Makefile.am
===================================================================
--- libcfa/src/Makefile.am	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ libcfa/src/Makefile.am	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -11,6 +11,6 @@
 ## Created On       : Sun May 31 08:54:01 2015
 ## Last Modified By : Peter A. Buhr
-## Last Modified On : Mon Jun  1 13:35:33 2020
-## Update Count     : 248
+## Last Modified On : Wed Dec  9 22:46:14 2020
+## Update Count     : 250
 ###############################################################################
 
@@ -43,4 +43,5 @@
 	clock.hfa \
 	exception.hfa \
+	exception.h \
 	gmp.hfa \
 	math.hfa \
@@ -51,4 +52,8 @@
 	bits/defs.hfa \
 	bits/locks.hfa \
+	bits/collection.hfa \
+	bits/stack.hfa \
+	bits/queue.hfa \
+	bits/sequence.hfa \
 	concurrency/iofwd.hfa \
 	containers/list.hfa \
@@ -77,5 +82,4 @@
 	bits/debug.cfa \
 	exception.c \
-	exception.h \
 	interpose.cfa \
 	lsda.h \
@@ -195,4 +199,7 @@
 	-rm -rf ${CFA_INCDIR} ${CFA_LIBDIR}
 
+distclean-local:
+	find ${builddir} -path '*.Plo' -delete
+
 
 # $(AM_V_CFA)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
Index: libcfa/src/bits/collection.hfa
===================================================================
--- libcfa/src/bits/collection.hfa	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ libcfa/src/bits/collection.hfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -7,4 +7,6 @@
 
 inline {
+	// PUBLIC
+
 	void ?{}( Colable & co ) with( co ) {
 		next = 0p;
@@ -16,7 +18,9 @@
 	}
 
-	Colable * getNext( Colable & co ) with( co ) {
-		return next;
+	Colable & getNext( Colable & co ) with( co ) {
+		return *next;
 	}
+
+	// PRIVATE
 
 	Colable *& Next( Colable * cp ) {
@@ -24,4 +28,5 @@
 	}
 
+	// wrappers to make Collection have T
 	forall( dtype T ) {
 		T *& Next( T * n ) {
Index: bcfa/src/bits/multi_list.cfa
===================================================================
--- libcfa/src/bits/multi_list.cfa	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ 	(revision )
@@ -1,101 +1,0 @@
-#include <fstream.hfa>
-#include <stdlib.hfa>
-#include "sequence.hfa"
-#include "queue.hfa"
-#include "stack.hfa"
-
-struct Task;											// node type
-
-struct TaskDL {
-	inline Seqable;
-	Task & node;
-};
-void ?{}( TaskDL & this, Task & task ) with( this ) {
-	((Seqable &)this){};
-	&node = &task;										// pointer to containing node
-}
-Task & task( TaskDL & this ) with( this ) {				// getter routine for containing node
-	return node;
-}
-
-struct TaskSL {
-	inline Colable;
-	Task & node;
-};
-void ?{}( TaskSL & this, Task & task ) with( this ) {
-	((Colable &)this){};
-	&node = &task;										// pointer to containing node
-}
-Task & task( TaskSL & this ) with( this ) {				// getter routine for containing node
-	return node;
-}
-
-struct Task {
-	TaskDL clusterRef;									// list of tasks on cluster
-	TaskDL readyRef;									// list of tasks on ready queue
-	TaskSL mutexRef;									// list of tasks on mutex queue
-	int id;
-};
-void ?{}( Task & this, int id ) with( this ) {
-	((TaskDL &)clusterRef){ this };
-	((TaskDL &)readyRef){ this };
-	((TaskSL &)mutexRef){ this };
-	this.id = id;
-}
-
-int main() {
-	Sequence(TaskDL) clustList, readyList;				// task lists
-	Queue(TaskSL) mutexList;
-	enum { Lnth = 10 };
-
-	for ( id; Lnth ) {
-		Task & task = *new( id );						// create task node
-		addHead( clustList, task.clusterRef );			// insert on lists in opposite directions
-		addTail( readyList, task.readyRef );
-		addHead( mutexList, task.mutexRef );
-	}
-
-	SeqIter(TaskDL) sqiter;
-	TaskDL & dl;
-	TaskSL & sl;
-
-	sout | nlOff;
-	for ( over( sqiter, clustList ); sqiter >> dl; ) {	// print lists
-		Task & tmp = task( dl ); sout | tmp.id;
-		// sout | task( dl ).id;
-	}
-	sout | nl;
-	for ( over( sqiter, readyList ); sqiter >> dl; ) {
-		Task & tmp = task( dl ); sout | tmp.id;
-		// sout | task( dl ).id;
-	}
-	sout | nl;
-	for ( QueueIter(TaskSL) qiter = { mutexList }; qiter >> sl; ) {	// print lists
-		Task & tmp = task( sl ); sout | tmp.id;
-		// sout | task( sl ).id;
-	}
-	sout | nl;
-	for ( Lnth ) {										// remove nodes from clustList. mutexList
-		dropHead( clustList );
-		drop( mutexList );
-	}
-	// Simultaneous deletion only safe if all nodes are traversed in same direction.
-	for ( Lnth ) {										// remove nodes from readyList and safe to delete nodes
-		delete( &task( dropHead( readyList ) ) );
-	}
-
-	// Re-purpose Seqable as Colable
-	Stack(TaskDL) mutexStack;
-	for ( id; Lnth ) {
-		Task & task = *new( id );						// create task node
-		push( mutexStack, task.clusterRef );			// insert on lists in opposite directions
-	}
-	for ( StackIter(TaskDL) stiter = { mutexStack }; stiter >> dl; ) {
-		Task & tmp = task( dl ); sout | tmp.id;
-		// sout | task( dl ).id;
-	}
-	sout | nl;
-	for ( Lnth ) {										// remove nodes from readyList and safe to delete nodes
-		delete( &task( pop( mutexStack ) ) );
-	}
-}
Index: libcfa/src/bits/queue.hfa
===================================================================
--- libcfa/src/bits/queue.hfa	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ libcfa/src/bits/queue.hfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -1,5 +1,5 @@
 #pragma once
 
-#include "collection.hfa"
+#include "bits/collection.hfa"
 
 forall( dtype T ) {
@@ -28,14 +28,14 @@
 
 		T * succ( Queue(T) & q, T * n ) with( q ) {		// pre: *n in *q
-#ifdef __CFA_DEBUG__
+			#ifdef __CFA_DEBUG__
 			if ( ! listed( n ) ) abort( "(Queue &)%p.succ( %p ) : Node is not on a list.", &q, n );
-#endif // __CFA_DEBUG__
+			#endif // __CFA_DEBUG__
 			return (Next( n ) == n) ? 0p : Next( n );
 		} // post: n == tail() & succ(n) == 0 | n != tail() & *succ(n) in *q
 
 		void addHead( Queue(T) & q, T & n ) with( q ) {
-#ifdef __CFA_DEBUG__
+			#ifdef __CFA_DEBUG__
 			if ( listed( &n ) ) abort( "(Queue &)%p.addHead( %p ) : Node is already on another list.", &q, &n );
-#endif // __CFA_DEBUG__
+			#endif // __CFA_DEBUG__
 			if ( last ) {
 				Next( &n ) = &head( q );
@@ -43,16 +43,16 @@
 			} else {
 				root = last = &n;
-				Next( &n ) = &n;							// last node points to itself
+				Next( &n ) = &n;						// last node points to itself
 			}
 		}
 
 		void addTail( Queue(T) & q, T & n ) with( q ) {
-#ifdef __CFA_DEBUG__
+			#ifdef __CFA_DEBUG__
 			if ( listed( &n ) ) abort( "(Queue &)%p.addTail( %p ) : Node is already on another list.", &q, &n );
-#endif // __CFA_DEBUG__
+			#endif // __CFA_DEBUG__
 			if ( last ) Next( last ) = &n;
 			else root = &n;
 			last = &n;
-			Next( &n ) = &n;								// last node points to itself
+			Next( &n ) = &n;							// last node points to itself
 		}
 
@@ -78,7 +78,7 @@
 
 		void remove( Queue(T) & q, T & n ) with( q ) {	// O(n)
-#ifdef __CFA_DEBUG__
+			#ifdef __CFA_DEBUG__
 			if ( ! listed( (Colable &)n ) ) abort( "(Queue &)%p.remove( %p ) : Node is not on a list.", &q, &n );
-#endif // __CFA_DEBUG__
+			#endif // __CFA_DEBUG__
 			T * prev = 0p;
 			T * curr = (T *)root;
@@ -96,8 +96,8 @@
 					break;
 				}
-#ifdef __CFA_DEBUG__
 				// not found => error
-				if (curr == last) abort( "(Queue &)%p.remove( %p ) : Node is not in list.", &q, &n );
-#endif // __CFA_DEBUG__
+				#ifdef __CFA_DEBUG__
+				if ( curr == last ) abort( "(Queue &)%p.remove( %p ) : Node is not in list.", &q, &n );
+				#endif // __CFA_DEBUG__
 				prev = curr;
 				curr = Next( curr );
@@ -125,7 +125,7 @@
 		// Node "n" must be in the "from" list.
 		void split( Queue(T) & q, Queue(T) & from, T & n ) with( q ) {
-#ifdef __CFA_DEBUG__
+			#ifdef __CFA_DEBUG__
 			if ( ! listed( (Colable &)n ) ) abort( "(Queue &)%p.split( %p ) : Node is not on a list.", &q, &n );
-#endif // __CFA_DEBUG__
+			#endif // __CFA_DEBUG__
 			Queue(T) to;
 			to.root = from.root;						// start of "to" list
@@ -177,6 +177,2 @@
 	} // distribution
 } // distribution
-
-// Local Variables: //
-// compile-command: "cfa queue.cfa" //
-// End: //
Index: bcfa/src/bits/queue_example.cfa
===================================================================
--- libcfa/src/bits/queue_example.cfa	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ 	(revision )
@@ -1,112 +1,0 @@
-#include <fstream.hfa>
-#include <stdlib.hfa>									// new, delete
-#include "queue.hfa"
-
-int main() {
-	// Fred test
-
-	struct Fred {
-		inline Colable;									// Plan 9 inheritance
-		int i;
-	};
-	void ?{}( Fred & fred ) { abort(); }
-	void ?{}( Fred & fred, int p ) with( fred ) {
-		i = p;
-	}
-
-	Queue(Fred) fred;
-	QueueIter(Fred) fredIter = { fred };
-	Fred & f;
-
-	sout | nlOff;										// turn off auto newline
-
-	for ( ; fredIter >> f; ) {							// empty list
-		sout | f.i | ' ';
-	}
-	sout | "empty" | nl;
-	
-	for ( i; 10 ) {
-		add( fred, *new( 2 * i ) );
-	}
-
-	for ( QueueIter(Fred) iter = { fred }; iter >> f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( i; 9 ) {
-		delete( &drop( fred ) );
-	}
-
-	for ( over( fredIter, fred ); fredIter >> f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 10 ) {
-		add( fred, *new( 2 * i + 1 ) );
-	}
-	for ( over( fredIter, fred ); fredIter >> f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( over( fredIter, fred ); fredIter >> f; ) {
-		delete( &f );
-	}
-
-	// Mary test
-
-	struct Mary {
-		inline Fred;									// Plan 9 inheritance
-		int j;
-	};
-	void ?{}( Mary & mary ) { abort(); }
-	void ?{}( Mary & mary, int p ) with( mary ) {
-		((Fred &)mary){ p };
-		j = i = p;
-	}
-
-	Queue(Mary) mary;
-	QueueIter(Mary) maryIter = { mary };
-	Mary & m;
-
-	for ( ; maryIter >> m; ) {							// empty list
-		sout | m.i | m.j | ' ';
-	}
-	sout | "empty" | nl;
-	
-	for ( i; 10 ) {
-		add( mary, *new( 2 * i ) );
-	}
-
-	for ( QueueIter(Mary) iter = { mary }; iter >> m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 9 ) {
-		delete( &drop( mary ) );
-	}
-
-	for ( over( maryIter, mary ); maryIter >> m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 10 ) {
-		add( mary, *new( 2 * i + 1 ) );
-	}
-	for ( over( maryIter, mary ); maryIter >> m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	for ( over( maryIter, mary ); maryIter >> m; ) {
-		delete( &m );
-	}
-}
-
-// Local Variables: //
-// compile-command: "cfa queue_example.cfa" //
-// End: //
Index: libcfa/src/bits/sequence.hfa
===================================================================
--- libcfa/src/bits/sequence.hfa	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ libcfa/src/bits/sequence.hfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -1,5 +1,5 @@
 #pragma once
 
-#include "collection.hfa"
+#include "bits/collection.hfa"
 
 struct Seqable {
@@ -9,6 +9,8 @@
 
 inline {
+	// PUBLIC
+
 	void ?{}( Seqable & sq ) with( sq ) {
-		((Colable &) sq){};
+		((Colable &)sq){};
 		back = 0p;
 	} // post: ! listed()
@@ -18,7 +20,16 @@
 	}
 
+	// PRIVATE
+
 	Seqable *& Back( Seqable * sq ) {
 		return sq->back;
 	}
+
+	// wrappers to make Collection have T
+	forall( dtype T ) {
+		T *& Back( T * n ) {
+			return (T *)Back( (Seqable *)n );
+		}
+	} // distribution
 } // distribution
 
@@ -34,13 +45,9 @@
 		} // post: empty() & head() == 0 | !empty() & head() in *s
 
-		T *& Back( T * n ) {
-			return (T *)Back( (Seqable *)n );
-		}
-
 		void ?{}( Sequence(T) &, const Sequence(T) & ) = void; // no copy
 		Sequence(T) & ?=?( const Sequence(T) & ) = void; // no assignment
 
 		void ?{}( Sequence(T) & s ) with( s ) {	
-			((Collection &) s){};
+			((Collection &)s){};
 		}	// post: isEmpty().
 
@@ -50,9 +57,9 @@
 		}	// post: empty() & tail() == 0 | !empty() & tail() in *s
 
-		// Return a pointer to the element after *n, or 0p if there isn't one.
+		// Return a pointer to the element after *n, or 0p if list empty.
 		T * succ( Sequence(T) & s, T * n ) with( s ) {	// pre: *n in *s
-#ifdef __CFA_DEBUG__
+			#ifdef __CFA_DEBUG__
 			if ( ! listed( n ) ) abort( "(Sequence &)%p.succ( %p ) : Node is not on a list.", &s, n );
-#endif // __CFA_DEBUG__
+			#endif // __CFA_DEBUG__
 			return Next( n ) == &head( s ) ? 0p : Next( n );
 		} // post: n == tail() & succ(n) == 0 | n != tail() & *succ(n) in *s
@@ -60,7 +67,7 @@
 		// Return a pointer to the element before *n, or 0p if there isn't one.
 		T * pred( Sequence(T) & s, T * n ) with( s ) {	// pre: *n in *s
-#ifdef __CFA_DEBUG__
+			#ifdef __CFA_DEBUG__
 			if ( ! listed( n ) ) abort( "(Sequence &)%p.pred( %p ) : Node is not on a list.", &s, n );
-#endif // __CFA_DEBUG__
+			#endif // __CFA_DEBUG__
 			return n == &head( s ) ? 0p : Back( n );
 		}	// post: n == head() & head(n) == 0 | n != head() & *pred(n) in *s
@@ -69,7 +76,7 @@
 		// Insert *n into the sequence before *bef, or at the end if bef == 0.
 		void insertBef( Sequence(T) & s, T & n, T & bef ) with( s ) { // pre: !n->listed() & *bef in *s
-#ifdef __CFA_DEBUG__
+			#ifdef __CFA_DEBUG__
 			if ( listed( &n ) ) abort( "(Sequence &)%p.insertBef( %p, %p ) : Node is already on another list.", &s, n, &bef );
-#endif // __CFA_DEBUG__
+			#endif // __CFA_DEBUG__
 			if ( &bef == &head( s ) ) {					// must change root
 				if ( root ) {
@@ -101,7 +108,7 @@
 		// Insert *n into the sequence after *aft, or at the beginning if aft == 0.
 		void insertAft( Sequence(T) & s, T & aft, T & n ) with( s ) {	// pre: !n->listed() & *aft in *s
-#ifdef __CFA_DEBUG__
+			#ifdef __CFA_DEBUG__
 			if ( listed( &n ) ) abort( "(Sequence &)%p.insertAft( %p, %p ) : Node is already on another list.", &s, &aft, &n );
-#endif // __CFA_DEBUG__
+			#endif // __CFA_DEBUG__
 			if ( ! &aft ) {								// must change root
 				if ( root ) {
@@ -130,7 +137,7 @@
 		// pre: n->listed() & *n in *s
 		void remove( Sequence(T) & s, T & n ) with( s ) { // O(1)
-#ifdef __CFA_DEBUG__
+			#ifdef __CFA_DEBUG__
 			if ( ! listed( &n ) ) abort( "(Sequence &)%p.remove( %p ) : Node is not on a list.", &s, &n );
-#endif // __CFA_DEBUG__
+			#endif // __CFA_DEBUG__
 			if ( &n == &head( s ) ) {
 				if ( Next( &head( s ) ) == &head( s ) ) root = 0p;
@@ -188,7 +195,7 @@
 		// Node "n" must be in the "from" list.
 		void split( Sequence(T) & s, Sequence(T) & from, T & n ) with( s ) {
-#ifdef __CFA_DEBUG__
+			#ifdef __CFA_DEBUG__
 			if ( ! listed( &n ) ) abort( "(Sequence &)%p.split( %p ) : Node is not on a list.", &s, &n );
-#endif // __CFA_DEBUG__
+			#endif // __CFA_DEBUG__
 			Sequence(T) to;
 			to.root = from.root;						// start of "to" list
@@ -199,5 +206,5 @@
 				Back( &head( from ) ) = Back( &head( to ) ); // fix "from" list
 		 		Next( Back( &head( to ) ) ) = &head( from );
-				Next( &n ) = &head( to );					// fix "to" list
+				Next( &n ) = &head( to );				// fix "to" list
 				Back( &head( to ) ) = &n;
 			} // if
@@ -214,5 +221,5 @@
 		// passing the sequence, traversing would require its length. Thus the iterator needs a pointer to the sequence
 		// to pass to succ/pred. Both stack and queue just encounter 0p since the lists are not circular.
-		Sequence(T) * seq;
+		Sequence(T) * seq;								// FIX ME: cannot be reference
 	};
 
@@ -224,5 +231,5 @@
 
 		void ?{}( SeqIter(T) & si, Sequence(T) & s ) with( si ) {
-			((ColIter &) si){};
+			((ColIter &)si){};
 			seq = &s;
 			curr = &head( s );
@@ -230,5 +237,5 @@
 
 		void ?{}( SeqIter(T) & si, Sequence(T) & s, T & start ) with( si ) {
-			((ColIter &) si){};
+			((ColIter &)si){};
 			seq = &s;
 			curr = &start;
@@ -255,15 +262,15 @@
 		inline ColIter;
 		// See above for explanation.
-		Sequence(T) * seq;
+		Sequence(T) * seq;								// FIX ME: cannot be reference
 	};
 
 	inline {
 		void ?{}( SeqIterRev(T) & si ) with( si ) {	
-			((ColIter &) si){};
+			((ColIter &)si){};
 			seq = 0p;
 		} // post: elts = null.
 
 		void ?{}( SeqIterRev(T) & si, Sequence(T) & s ) with( si ) {	
-			((ColIter &) si){};
+			((ColIter &)si){};
 			seq = &s;
 			curr = &tail( s );
@@ -271,5 +278,5 @@
 
 		void ?{}( SeqIterRev(T) & si, Sequence(T) & s, T & start ) with( si ) {	
-			((ColIter &) si){};
+			((ColIter &)si){};
 			seq = &s;
 			curr = &start;
@@ -291,6 +298,2 @@
 	} // distribution
 } // distribution
-
-// Local Variables: //
-// compile-command: "cfa sequence.hfa" //
-// End: //
Index: bcfa/src/bits/sequence_example.cfa
===================================================================
--- libcfa/src/bits/sequence_example.cfa	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ 	(revision )
@@ -1,142 +1,0 @@
-#include <fstream.hfa>
-#include <stdlib.hfa>									// new, delete
-#include "sequence.hfa"
-
-int main() {
-	// Fred test
-
-	struct Fred {
-		inline Seqable;									// Plan 9 inheritance
-		int i;
-	};
-	void ?{}( Fred & fred ) { abort(); }
-	void ?{}( Fred & fred, int p ) with( fred ) {
-		i = p;
-	}
-
-	Sequence(Fred) fred;
-	SeqIter(Fred) fredIter = { fred };
-	Fred & f;
-
-	sout | nlOff;										// turn off auto newline
-
-	for ( ; fredIter >> f; ) {							// empty list
-		sout | f.i | ' ';
-	}
-	sout | "empty" | nl;
-	
-	for ( i; 10 ) {
-		add( fred, *new( 2 * i ) );
-	}
-
-	for ( SeqIter(Fred) iter = { fred }; iter >> f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( i; 9 ) {
-		delete( &dropHead( fred ) );
-	}
-
-	for ( over( fredIter, fred ); fredIter >> f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 10 ) {
-		addTail( fred, *new( 2 * i + 1 ) );
-	}
-	for ( over( fredIter, fred ); fredIter >> f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( i; 9 ) {
-		delete( &dropTail( fred ) );
-	}
-	for ( over( fredIter, fred ); fredIter >> f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( over( fredIter, fred ); fredIter >> f; ) {
-		delete( &f );
-	}
-
-	// Mary test
-
-	struct Mary {
-		inline Fred;									// Plan 9 inheritance
-		int j;
-	};
-	void ?{}( Mary & mary ) { abort(); }
-	void ?{}( Mary & mary, int p ) with( mary ) {
-		((Fred &)mary){ p };
-		j = p;
-	}
-
-	Sequence(Mary) mary;
-	Sequence(Mary) baz;
-	SeqIter(Mary) maryIter = { mary };
-	Mary & m;
-
-	for ( ; maryIter >> m; ) {							// empty list
-		sout | m.i | m.j | ' ';
-	}
-	sout | "empty" | nl;
-	
-	for ( i; 10 ) {
-		add( mary, *new( 2 * i ) );
-		add( baz, *new( 2 * i ) );
-	}
-
-	for ( SeqIter(Mary) iter = { mary }; iter >> m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 9 ) {
-		delete( &dropHead( mary ) );
-	}
-
-	for ( over( maryIter, mary ); maryIter >> m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 10 ) {
-		addTail( mary, *new( 2 * i + 1 ) );
-	}
-	for ( over( maryIter, mary ); maryIter >> m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	for ( i; 9 ) {
-		delete( &dropTail( mary ) );
-	}
-	for ( over( maryIter, mary ); maryIter >> m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	transfer( mary, baz );
-
-	for ( over( maryIter, baz ); maryIter >> m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | "empty" | nl;
-
-	for ( over( maryIter, mary ); maryIter >> m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	for ( over( maryIter, mary ); maryIter >> m; ) {
-		delete( &m );
-	}
-}
-
-// Local Variables: //
-// compile-command: "cfa sequence_example.cfa" //
-// End: //
Index: libcfa/src/bits/stack.hfa
===================================================================
--- libcfa/src/bits/stack.hfa	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ libcfa/src/bits/stack.hfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -1,5 +1,5 @@
 #pragma once
 
-#include "collection.hfa"
+#include "bits/collection.hfa"
 
 forall( dtype T ) {
@@ -26,7 +26,7 @@
 
 		void addHead( Stack(T) & s, T & n ) with( s ) {
-#ifdef __CFA_DEBUG__
+			#ifdef __CFA_DEBUG__
 			if ( listed( (Colable &)(n) ) ) abort( "(Stack &)%p.addHead( %p ) : Node is already on another list.", &s, n );
-#endif // __CFA_DEBUG__
+			#endif // __CFA_DEBUG__
 			Next( &n ) = &head( s ) ? &head( s ) : &n;
 			root = &n;
@@ -44,5 +44,5 @@
 			T & t = head( s );
 			if ( root ) {
-				root = ( T *)Next(root);
+				root = ( T *)Next( root );
 				if ( &head( s ) == &t ) root = 0p;		// only one element ?
 				Next( &t ) = 0p;
@@ -92,6 +92,2 @@
 	} // distribution
 } // distribution
-
-// Local Variables: //
-// compile-command: "make install" //
-// End: //
Index: bcfa/src/bits/stack_example.cfa
===================================================================
--- libcfa/src/bits/stack_example.cfa	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ 	(revision )
@@ -1,112 +1,0 @@
-#include <fstream.hfa>
-#include <stdlib.hfa>									// new, delete
-#include "stack.hfa"
-
-int main() {
-	// Fred test
-
-	struct Fred {
-		inline Colable;									// Plan 9 inheritance
-		int i;
-	};
-	void ?{}( Fred & fred ) { abort(); }
-	void ?{}( Fred & fred, int p ) with( fred ) {
-		i = p;
-	}
-
-	Stack(Fred) fred;
-	StackIter(Fred) fredIter = { fred };
-	Fred & f;
-
-	sout | nlOff;										// turn off auto newline
-
-	for ( ; fredIter >> f; ) {							// empty list
-		sout | f.i | ' ';
-	}
-	sout | "empty" | nl;
-	
-	for ( i; 10 ) {
-		push( fred, *new( 2 * i ) );
-	}
-
-	for ( StackIter(Fred) iter = { fred }; iter >> f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 9 ) {
-		delete( &pop( fred ) );
-	}
-
-	for ( over( fredIter, fred ); fredIter >> f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 10 ) {
-		push( fred, *new( 2 * i + 1 ) );
-	}
-	for ( over( fredIter, fred ); fredIter >> f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( over( fredIter, fred ); fredIter >> f; ) {
-		delete( &f );
-	}
-
-	// Mary test
-
-	struct Mary {
-		inline Fred;									// Plan 9 inheritance
-		int j;
-	};
-	void ?{}( Mary & mary ) { abort(); }
-	void ?{}( Mary & mary, int p ) with( mary ) {
-		((Fred &)mary){ p };
-		j = i = p;
-	}
-
-	Stack(Mary) mary;
-	StackIter(Mary) maryIter = { mary };
-	Mary & m;
-
-	for ( ; maryIter >> m; ) {							// empty list
-		sout | m.i | m.j | ' ';
-	}
-	sout | "empty" | nl;
-	
-	for ( i; 10 ) {
-		push( mary, *new( 2 * i ) );
-	}
-
-	for ( StackIter(Mary) iter = { mary }; iter >> m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 9 ) {
-		delete( &pop( mary ) );
-	}
-
-	for ( over( maryIter, mary ); maryIter >> m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 10 ) {
-		push( mary, *new( 2 * i + 1 ) );
-	}
-	for ( over( maryIter, mary ); maryIter >> m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	for ( over( maryIter, mary ); maryIter >> m; ) {
-		delete( &m );
-	}
-}
-
-// Local Variables: //
-// compile-command: "cfa stack_example.cfa" //
-// End: //
Index: libcfa/src/concurrency/coroutine.cfa
===================================================================
--- libcfa/src/concurrency/coroutine.cfa	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ libcfa/src/concurrency/coroutine.cfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -28,4 +28,5 @@
 #include "kernel_private.hfa"
 #include "exception.hfa"
+#include "math.hfa"
 
 #define __CFA_INVOKE_PRIVATE__
@@ -87,4 +88,5 @@
 
 void __stack_prepare( __stack_info_t * this, size_t create_size );
+void __stack_clean  ( __stack_info_t * this );
 
 //-----------------------------------------------------------------------------
@@ -107,16 +109,17 @@
 	bool userStack = ((intptr_t)this.storage & 0x1) != 0;
 	if ( ! userStack && this.storage ) {
-		__attribute__((may_alias)) intptr_t * istorage = (intptr_t *)&this.storage;
-		*istorage &= (intptr_t)-1;
-
-		void * storage = this.storage->limit;
-		__cfaabi_dbg_debug_do(
-			storage = (char*)(storage) - __page_size;
-			if ( mprotect( storage, __page_size, PROT_READ | PROT_WRITE ) == -1 ) {
-				abort( "(coStack_t *)%p.^?{}() : internal error, mprotect failure, error(%d) %s.", &this, errno, strerror( errno ) );
-			}
-		);
-		__cfaabi_dbg_print_safe("Kernel : Deleting stack %p\n", storage);
-		free( storage );
+		__stack_clean( &this );
+		// __attribute__((may_alias)) intptr_t * istorage = (intptr_t *)&this.storage;
+		// *istorage &= (intptr_t)-1;
+
+		// void * storage = this.storage->limit;
+		// __cfaabi_dbg_debug_do(
+		// 	storage = (char*)(storage) - __page_size;
+		// 	if ( mprotect( storage, __page_size, PROT_READ | PROT_WRITE ) == -1 ) {
+		// 		abort( "(coStack_t *)%p.^?{}() : internal error, mprotect failure, error(%d) %s.", &this, errno, strerror( errno ) );
+		// 	}
+		// );
+		// __cfaabi_dbg_print_safe("Kernel : Deleting stack %p\n", storage);
+		// free( storage );
 	}
 }
@@ -167,24 +170,43 @@
 	assert(__page_size != 0l);
 	size_t size = libCeiling( storageSize, 16 ) + stack_data_size;
+	size = ceiling(size, __page_size);
 
 	// If we are running debug, we also need to allocate a guardpage to catch stack overflows.
 	void * storage;
-	__cfaabi_dbg_debug_do(
-		storage = memalign( __page_size, size + __page_size );
-	);
-	__cfaabi_dbg_no_debug_do(
-		storage = (void*)malloc(size);
-	);
-
-	__cfaabi_dbg_print_safe("Kernel : Created stack %p of size %zu\n", storage, size);
-	__cfaabi_dbg_debug_do(
-		if ( mprotect( storage, __page_size, PROT_NONE ) == -1 ) {
-			abort( "__stack_alloc : internal error, mprotect failure, error(%d) %s.", (int)errno, strerror( (int)errno ) );
-		}
-		storage = (void *)(((intptr_t)storage) + __page_size);
-	);
+	// __cfaabi_dbg_debug_do(
+	// 	storage = memalign( __page_size, size + __page_size );
+	// );
+	// __cfaabi_dbg_no_debug_do(
+	// 	storage = (void*)malloc(size);
+	// );
+
+	// __cfaabi_dbg_print_safe("Kernel : Created stack %p of size %zu\n", storage, size);
+	// __cfaabi_dbg_debug_do(
+	// 	if ( mprotect( storage, __page_size, PROT_NONE ) == -1 ) {
+	// 		abort( "__stack_alloc : internal error, mprotect failure, error(%d) %s.", (int)errno, strerror( (int)errno ) );
+	// 	}
+	// 	storage = (void *)(((intptr_t)storage) + __page_size);
+	// );
+	storage = mmap(0p, size + __page_size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+	if(storage == ((void*)-1)) {
+		abort( "coroutine stack creation : internal error, mmap failure, error(%d) %s.", errno, strerror( errno ) );
+	}
+	if ( mprotect( storage, __page_size, PROT_NONE ) == -1 ) {
+		abort( "coroutine stack creation : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
+	} // if
+	storage = (void *)(((intptr_t)storage) + __page_size);
 
 	verify( ((intptr_t)storage & (libAlign() - 1)) == 0ul );
 	return [storage, size];
+}
+
+void __stack_clean  ( __stack_info_t * this ) {
+	size_t size = ((intptr_t)this->storage->base) - ((intptr_t)this->storage->limit) + sizeof(__stack_t);
+	void * storage = this->storage->limit;
+
+	storage = (void *)(((intptr_t)storage) - __page_size);
+	if(munmap(storage, size + __page_size) == -1) {
+		abort( "coroutine stack destruction : internal error, munmap failure, error(%d) %s.", errno, strerror( errno ) );
+	}
 }
 
@@ -210,7 +232,7 @@
 	assertf( size >= MinStackSize, "Stack size %zd provides less than minimum of %zd bytes for a stack.", size, MinStackSize );
 
-	this->storage = (__stack_t *)((intptr_t)storage + size);
+	this->storage = (__stack_t *)((intptr_t)storage + size - sizeof(__stack_t));
 	this->storage->limit = storage;
-	this->storage->base  = (void*)((intptr_t)storage + size);
+	this->storage->base  = (void*)((intptr_t)storage + size - sizeof(__stack_t));
 	this->storage->exception_context.top_resume = 0p;
 	this->storage->exception_context.current_exception = 0p;
Index: libcfa/src/concurrency/coroutine.hfa
===================================================================
--- libcfa/src/concurrency/coroutine.hfa	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ libcfa/src/concurrency/coroutine.hfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -102,5 +102,7 @@
 }
 
-extern void __stack_prepare   ( __stack_info_t * this, size_t size /* ignored if storage already allocated */);
+extern void __stack_prepare( __stack_info_t * this, size_t size /* ignored if storage already allocated */);
+extern void __stack_clean  ( __stack_info_t * this );
+
 
 // Suspend implementation inlined for performance
Index: libcfa/src/concurrency/io/setup.cfa
===================================================================
--- libcfa/src/concurrency/io/setup.cfa	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ libcfa/src/concurrency/io/setup.cfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -132,6 +132,5 @@
 		// Wait for the io poller thread to finish
 
-		pthread_join( iopoll.thrd, 0p );
-		free( iopoll.stack );
+		__destroy_pthread( iopoll.thrd, iopoll.stack, 0p );
 
 		int ret = close(iopoll.epollfd);
Index: libcfa/src/concurrency/kernel/startup.cfa
===================================================================
--- libcfa/src/concurrency/kernel/startup.cfa	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ libcfa/src/concurrency/kernel/startup.cfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -29,4 +29,5 @@
 #include "kernel_private.hfa"
 #include "startup.hfa"          // STARTUP_PRIORITY_XXX
+#include "math.hfa"
 
 //-----------------------------------------------------------------------------
@@ -539,4 +540,5 @@
 }
 
+extern size_t __page_size;
 void ^?{}(processor & this) with( this ){
 	if( ! __atomic_load_n(&do_terminate, __ATOMIC_ACQUIRE) ) {
@@ -550,8 +552,5 @@
 	}
 
-	int err = pthread_join( kernel_thread, 0p );
-	if( err != 0 ) abort("KERNEL ERROR: joining processor %p caused error %s\n", &this, strerror(err));
-
-	free( this.stack );
+	__destroy_pthread( kernel_thread, this.stack, 0p );
 
 	disable_interrupts();
@@ -678,14 +677,23 @@
 
 	void * stack;
-	__cfaabi_dbg_debug_do(
-		stack = memalign( __page_size, stacksize + __page_size );
-		// pthread has no mechanism to create the guard page in user supplied stack.
-		if ( mprotect( stack, __page_size, PROT_NONE ) == -1 ) {
-			abort( "mprotect : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
-		} // if
-	);
-	__cfaabi_dbg_no_debug_do(
-		stack = malloc( stacksize );
-	);
+	#warning due to the thunk problem, stack creation uses mmap, revert to malloc once this goes away
+	// __cfaabi_dbg_debug_do(
+	// 	stack = memalign( __page_size, stacksize + __page_size );
+	// 	// pthread has no mechanism to create the guard page in user supplied stack.
+	// 	if ( mprotect( stack, __page_size, PROT_NONE ) == -1 ) {
+	// 		abort( "mprotect : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
+	// 	} // if
+	// );
+	// __cfaabi_dbg_no_debug_do(
+	// 	stack = malloc( stacksize );
+	// );
+	stacksize = ceiling( stacksize, __page_size ) + __page_size;
+	stack = mmap(0p, stacksize, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+	if(stack == ((void*)-1)) {
+		abort( "pthread stack creation : internal error, mmap failure, error(%d) %s.", errno, strerror( errno ) );
+	}
+	if ( mprotect( stack, __page_size, PROT_NONE ) == -1 ) {
+		abort( "pthread stack creation : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
+	} // if
 
 	check( pthread_attr_setstack( &attr, stack, stacksize ), "pthread_attr_setstack" );
@@ -694,4 +702,24 @@
 	return stack;
 }
+
+void __destroy_pthread( pthread_t pthread, void * stack, void ** retval ) {
+	int err = pthread_join( pthread, retval );
+	if( err != 0 ) abort("KERNEL ERROR: joining pthread %p caused error %s\n", (void*)pthread, strerror(err));
+
+	pthread_attr_t attr;
+
+	check( pthread_attr_init( &attr ), "pthread_attr_init" ); // initialize attribute
+
+	size_t stacksize;
+	// default stack size, normally defined by shell limit
+	check( pthread_attr_getstacksize( &attr, &stacksize ), "pthread_attr_getstacksize" );
+	assert( stacksize >= PTHREAD_STACK_MIN );
+	stacksize += __page_size;
+
+	if(munmap(stack, stacksize) == -1) {
+		abort( "pthread stack destruction : internal error, munmap failure, error(%d) %s.", errno, strerror( errno ) );
+	}
+}
+
 
 #if defined(__CFA_WITH_VERIFY__)
Index: libcfa/src/concurrency/kernel_private.hfa
===================================================================
--- libcfa/src/concurrency/kernel_private.hfa	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ libcfa/src/concurrency/kernel_private.hfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -49,4 +49,5 @@
 
 void * __create_pthread( pthread_t *, void * (*)(void *), void * );
+void __destroy_pthread( pthread_t pthread, void * stack, void ** retval );
 
 
Index: libcfa/src/concurrency/preemption.cfa
===================================================================
--- libcfa/src/concurrency/preemption.cfa	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ libcfa/src/concurrency/preemption.cfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -354,5 +354,42 @@
 }
 
+//-----------------------------------------------------------------------------
+// Kernel Signal Debug
+void __cfaabi_check_preemption() {
+	bool ready = __preemption_enabled();
+	if(!ready) { abort("Preemption should be ready"); }
+
+	__cfaasm_label(debug, before);
+
+		sigset_t oldset;
+		int ret;
+		ret = pthread_sigmask(0, ( const sigset_t * ) 0p, &oldset);  // workaround trac#208: cast should be unnecessary
+		if(ret != 0) { abort("ERROR sigprocmask returned %d", ret); }
+
+		ret = sigismember(&oldset, SIGUSR1);
+		if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
+		if(ret == 1) { abort("ERROR SIGUSR1 is disabled"); }
+
+		ret = sigismember(&oldset, SIGALRM);
+		if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
+		if(ret == 0) { abort("ERROR SIGALRM is enabled"); }
+
+		ret = sigismember(&oldset, SIGTERM);
+		if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
+		if(ret == 1) { abort("ERROR SIGTERM is disabled"); }
+
+	__cfaasm_label(debug, after);
+}
+
+#ifdef __CFA_WITH_VERIFY__
+bool __cfaabi_dbg_in_kernel() {
+	return !__preemption_enabled();
+}
+#endif
+
 #undef __cfaasm_label
+
+//-----------------------------------------------------------------------------
+// Signal handling
 
 // sigprocmask wrapper : unblock a single signal
@@ -405,5 +442,5 @@
 		#define RELOC_SUFFIX ""
 	#endif
-	#define __cfaasm_label( label ) static struct asm_region label = \
+	#define __cfaasm_label( label ) struct asm_region label = \
 		({ \
 			struct asm_region region; \
@@ -424,5 +461,5 @@
 		#define RELOC_SUFFIX ""
 	#endif
-	#define __cfaasm_label( label ) static struct asm_region label = \
+	#define __cfaasm_label( label ) struct asm_region label = \
 		({ \
 			struct asm_region region; \
@@ -437,5 +474,5 @@
 	#ifdef __PIC__
 		// Note that this works only for gcc
-		#define __cfaasm_label( label ) static struct asm_region label = \
+		#define __cfaasm_label( label ) struct asm_region label = \
 		({ \
 			struct asm_region region; \
@@ -452,5 +489,5 @@
 		#error this is not the right thing to do
 		/*
-		#define __cfaasm_label( label ) static struct asm_region label = \
+		#define __cfaasm_label( label ) struct asm_region label = \
 		({ \
 			struct asm_region region; \
@@ -479,4 +516,5 @@
 	__cfaasm_label( check  );
 	__cfaasm_label( dsable );
+	__cfaasm_label( debug  );
 
 	// Check if preemption is safe
@@ -485,4 +523,5 @@
 	if( __cfaasm_in( ip, check  ) ) { ready = false; goto EXIT; };
 	if( __cfaasm_in( ip, dsable ) ) { ready = false; goto EXIT; };
+	if( __cfaasm_in( ip, debug  ) ) { ready = false; goto EXIT; };
 	if( !__cfaabi_tls.preemption_state.enabled) { ready = false; goto EXIT; };
 	if( __cfaabi_tls.preemption_state.in_progress ) { ready = false; goto EXIT; };
@@ -536,6 +575,5 @@
 	// Wait for the preemption thread to finish
 
-	pthread_join( alarm_thread, 0p );
-	free( alarm_stack );
+	__destroy_pthread( alarm_thread, alarm_stack, 0p );
 
 	// Preemption is now fully stopped
@@ -697,36 +735,4 @@
 }
 
-//=============================================================================================
-// Kernel Signal Debug
-//=============================================================================================
-
-void __cfaabi_check_preemption() {
-	bool ready = __preemption_enabled();
-	if(!ready) { abort("Preemption should be ready"); }
-
-	sigset_t oldset;
-	int ret;
-	ret = pthread_sigmask(0, ( const sigset_t * ) 0p, &oldset);  // workaround trac#208: cast should be unnecessary
-	if(ret != 0) { abort("ERROR sigprocmask returned %d", ret); }
-
-	ret = sigismember(&oldset, SIGUSR1);
-	if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
-	if(ret == 1) { abort("ERROR SIGUSR1 is disabled"); }
-
-	ret = sigismember(&oldset, SIGALRM);
-	if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
-	if(ret == 0) { abort("ERROR SIGALRM is enabled"); }
-
-	ret = sigismember(&oldset, SIGTERM);
-	if(ret <  0) { abort("ERROR sigismember returned %d", ret); }
-	if(ret == 1) { abort("ERROR SIGTERM is disabled"); }
-}
-
-#ifdef __CFA_WITH_VERIFY__
-bool __cfaabi_dbg_in_kernel() {
-	return !__preemption_enabled();
-}
-#endif
-
 // Local Variables: //
 // mode: c //
Index: libcfa/src/stdlib.hfa
===================================================================
--- libcfa/src/stdlib.hfa	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ libcfa/src/stdlib.hfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -10,6 +10,6 @@
 // Created On       : Thu Jan 28 17:12:35 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Nov 12 20:58:48 2020
-// Update Count     : 520
+// Last Modified On : Tue Dec  8 18:27:22 2020
+// Update Count     : 524
 //
 
@@ -268,8 +268,9 @@
 static inline forall( dtype T | { void ^?{}( T & ); } )
 void delete( T * ptr ) {
-	if ( ptr ) {										// ignore null
+	// special case for 0-sized object => always call destructor
+	if ( ptr || sizeof(ptr) == 0 ) {					// ignore null but not 0-sized objects
 		^(*ptr){};										// run destructor
-		free( ptr );
 	} // if
+	free( ptr );
 } // delete
 
Index: src/AST/module.mk
===================================================================
--- src/AST/module.mk	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ src/AST/module.mk	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -59,4 +59,5 @@
 	AST/SymbolTable.cpp \
 	AST/SymbolTable.hpp \
+	AST/TranslationUnit.hpp \
 	AST/Type.cpp \
 	AST/Type.hpp \
Index: src/Common/CodeLocationTools.cpp
===================================================================
--- src/Common/CodeLocationTools.cpp	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
+++ src/Common/CodeLocationTools.cpp	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -0,0 +1,276 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// CodeLocationTools.cpp -- Additional tools for code locations.
+//
+// Author           : Andrew Beach
+// Created On       : Fri Dec  4 15:42:00 2020
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed Dec  9  9:42:00 2020
+// Update Count     : 1
+//
+
+#include "CodeLocationTools.hpp"
+
+#include <type_traits>
+
+#include "AST/Pass.hpp"
+#include "AST/TranslationUnit.hpp"
+#include "Common/CodeLocation.h"
+
+namespace {
+
+// There are a lot of helpers in this file that could be used much more
+// generally if anyone has another use for them.
+
+// Check if a node type has a code location.
+template<typename node_t>
+struct has_code_location : public std::is_base_of<ast::ParseNode, node_t> {};
+
+template<typename node_t, bool has_location>
+struct __GetCL;
+
+template<typename node_t>
+struct __GetCL<node_t, true> {
+	static inline CodeLocation const * get( node_t const * node ) {
+		return &node->location;
+	}
+
+	static inline CodeLocation * get( node_t * node ) {
+		return &node->location;
+	}
+};
+
+template<typename node_t>
+struct __GetCL<node_t, false> {
+	static inline CodeLocation * get( node_t const * ) {
+		return nullptr;
+	}
+};
+
+template<typename node_t>
+CodeLocation const * get_code_location( node_t const * node ) {
+	return __GetCL< node_t, has_code_location< node_t >::value >::get( node );
+}
+
+template<typename node_t>
+CodeLocation * get_code_location( node_t * node ) {
+	return __GetCL< node_t, has_code_location< node_t >::value >::get( node );
+}
+
+// Fill every location with a nearby (parent) location.
+class FillCore : public ast::WithGuards {
+	CodeLocation const * parent;
+public:
+	FillCore() : parent( nullptr ) {}
+
+	template<typename node_t>
+	node_t const * previsit( node_t const * node ) {
+		GuardValue( parent );
+		CodeLocation const * location = get_code_location( node );
+		if ( location && location->isUnset() ) {
+			assert( parent );
+			node_t * newNode = ast::mutate( node );
+			CodeLocation * newLocation = get_code_location( newNode );
+			assert( newLocation );
+			*newLocation = *parent;
+			parent = newLocation;
+			return newNode;
+		} else if ( location ) {
+			parent = location;
+		}
+		return node;
+	}
+};
+
+// ALL_VISITS(macro)
+// Expands `macro(node_type, return_type)` for every visit method of the
+// ast::Visitor class where node_type is the name of the parameter and
+// return_type is the name of the return type; not including the namespace,
+// pointer or const qualifiers.
+#define ALL_VISITS(macro) \
+    macro(ObjectDecl, DeclWithType) \
+    macro(FunctionDecl, DeclWithType) \
+    macro(StructDecl, Decl) \
+    macro(UnionDecl, Decl) \
+    macro(EnumDecl, Decl) \
+    macro(TraitDecl, Decl) \
+    macro(TypeDecl, Decl) \
+    macro(TypedefDecl, Decl) \
+    macro(AsmDecl, AsmDecl) \
+    macro(StaticAssertDecl, StaticAssertDecl) \
+    macro(CompoundStmt, CompoundStmt) \
+    macro(ExprStmt, Stmt) \
+    macro(AsmStmt, Stmt) \
+    macro(DirectiveStmt, Stmt) \
+    macro(IfStmt, Stmt) \
+    macro(WhileStmt, Stmt) \
+    macro(ForStmt, Stmt) \
+    macro(SwitchStmt, Stmt) \
+    macro(CaseStmt, Stmt) \
+    macro(BranchStmt, Stmt) \
+    macro(ReturnStmt, Stmt) \
+    macro(ThrowStmt, Stmt) \
+    macro(TryStmt, Stmt) \
+    macro(CatchStmt, Stmt) \
+    macro(FinallyStmt, Stmt) \
+    macro(SuspendStmt, Stmt) \
+    macro(WaitForStmt, Stmt) \
+    macro(WithStmt, Decl) \
+    macro(NullStmt, NullStmt) \
+    macro(DeclStmt, Stmt) \
+    macro(ImplicitCtorDtorStmt, Stmt) \
+    macro(ApplicationExpr, Expr) \
+    macro(UntypedExpr, Expr) \
+    macro(NameExpr, Expr) \
+    macro(AddressExpr, Expr) \
+    macro(LabelAddressExpr, Expr) \
+    macro(CastExpr, Expr) \
+    macro(KeywordCastExpr, Expr) \
+    macro(VirtualCastExpr, Expr) \
+    macro(UntypedMemberExpr, Expr) \
+    macro(MemberExpr, Expr) \
+    macro(VariableExpr, Expr) \
+    macro(ConstantExpr, Expr) \
+    macro(SizeofExpr, Expr) \
+    macro(AlignofExpr, Expr) \
+    macro(UntypedOffsetofExpr, Expr) \
+    macro(OffsetofExpr, Expr) \
+    macro(OffsetPackExpr, Expr) \
+    macro(LogicalExpr, Expr) \
+    macro(ConditionalExpr, Expr) \
+    macro(CommaExpr, Expr) \
+    macro(TypeExpr, Expr) \
+    macro(AsmExpr, Expr) \
+    macro(ImplicitCopyCtorExpr, Expr) \
+    macro(ConstructorExpr, Expr) \
+    macro(CompoundLiteralExpr, Expr) \
+    macro(RangeExpr, Expr) \
+    macro(UntypedTupleExpr, Expr) \
+    macro(TupleExpr, Expr) \
+    macro(TupleIndexExpr, Expr) \
+    macro(TupleAssignExpr, Expr) \
+    macro(StmtExpr, Expr) \
+    macro(UniqueExpr, Expr) \
+    macro(UntypedInitExpr, Expr) \
+    macro(InitExpr, Expr) \
+    macro(DeletedExpr, Expr) \
+    macro(DefaultArgExpr, Expr) \
+    macro(GenericExpr, Expr) \
+    macro(VoidType, Type) \
+    macro(BasicType, Type) \
+    macro(PointerType, Type) \
+    macro(ArrayType, Type) \
+    macro(ReferenceType, Type) \
+    macro(QualifiedType, Type) \
+    macro(FunctionType, Type) \
+    macro(StructInstType, Type) \
+    macro(UnionInstType, Type) \
+    macro(EnumInstType, Type) \
+    macro(TraitInstType, Type) \
+    macro(TypeInstType, Type) \
+    macro(TupleType, Type) \
+    macro(TypeofType, Type) \
+    macro(VarArgsType, Type) \
+    macro(ZeroType, Type) \
+    macro(OneType, Type) \
+    macro(GlobalScopeType, Type) \
+    macro(Designation, Designation) \
+    macro(SingleInit, Init) \
+    macro(ListInit, Init) \
+    macro(ConstructorInit, Init) \
+    macro(Attribute, Attribute) \
+    macro(TypeSubstitution, TypeSubstitution)
+
+// These could even go into the ast namespace.
+enum class LeafKind {
+#define VISIT(node_type, return_type) node_type,
+	ALL_VISITS(VISIT)
+#undef VISIT
+};
+
+struct LeafKindVisitor : public ast::Visitor {
+	LeafKind kind;
+
+#define VISIT(node_type, return_type) \
+	const ast::return_type * visit( const ast::node_type * ) final { \
+		kind = LeafKind::node_type; \
+		return nullptr; \
+	}
+	ALL_VISITS(VISIT)
+#undef VISIT
+};
+
+constexpr size_t leaf_kind_count = (1 + (size_t)LeafKind::TypeSubstitution);
+
+LeafKind get_leaf_kind( ast::Node const * node ) {
+	LeafKindVisitor visitor;
+	node->accept( visitor );
+	return visitor.kind;
+}
+
+const char * leaf_kind_names[leaf_kind_count] = {
+#define VISIT(node_type, return_type) #node_type,
+	ALL_VISITS(VISIT)
+#undef VISIT
+};
+
+// Collect pointers to all the nodes with unset code locations.
+class CollectCore {
+	std::list< ast::ptr< ast::Node > > & unset;
+public:
+	CollectCore( std::list< ast::ptr< ast::Node > > & unset ) :
+		unset( unset )
+	{}
+
+	template<typename node_t>
+	void previsit( node_t const * node ) {
+		CodeLocation const * location = get_code_location( node );
+		if ( location && location->isUnset() ) {
+			unset.push_back( node );
+		}
+	}
+};
+
+} // namespace
+
+void checkAllCodeLocations( ast::TranslationUnit const & unit ) {
+	checkAllCodeLocations( "unknown location", unit );
+}
+
+void checkAllCodeLocations( char const * label, ast::TranslationUnit const & unit ) {
+	std::list< ast::ptr< ast::Node > > unsetNodes;
+	{
+		ast::Pass<CollectCore> collector( unsetNodes );
+		for ( auto node : unit.decls ) {
+			node->accept( collector );
+		}
+	}
+	if ( unsetNodes.empty() ) {
+		return;
+	}
+
+	std::cerr << "Code Location check at " << label << " failed." << std::endl;
+	std::cerr << "Total nodes without a set code location: "
+		<< unsetNodes.size() << std::endl;
+
+	size_t node_counts[leaf_kind_count] = {0};
+	for ( auto unset : unsetNodes ) {
+		node_counts[(size_t)get_leaf_kind(unset)] += 1;
+	}
+	for ( size_t i = 0 ; i < leaf_kind_count ; ++i ) {
+		if ( node_counts[i] ) {
+			std::cerr << '\t' << node_counts[i]
+				<< " of type " << leaf_kind_names[i] << std::endl;
+		}
+	}
+
+	assert( unsetNodes.empty() );
+}
+
+void forceFillCodeLocations( ast::TranslationUnit & unit ) {
+	ast::Pass<FillCore>::run( unit );
+}
Index: src/Common/CodeLocationTools.hpp
===================================================================
--- src/Common/CodeLocationTools.hpp	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
+++ src/Common/CodeLocationTools.hpp	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -0,0 +1,29 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// CodeLocationTools.hpp -- Additional tools for code locations.
+//
+// Author           : Andrew Beach
+// Created On       : Fri Dec  4 15:35:00 2020
+// Last Modified By : Andrew Beach
+// Last Modified On : Wed Dec  9  9:53:00 2020
+// Update Count     : 1
+//
+
+#pragma once
+
+namespace ast {
+	struct TranslationUnit;
+}
+
+// Search the translation unit for unset code locations and print information
+// on them, and where the check was run if provided. Abort if any unset code
+// locations are found.
+void checkAllCodeLocations( ast::TranslationUnit const & unit );
+void checkAllCodeLocations( char const *, ast::TranslationUnit const & );
+
+// Assign a nearby code-location to any unset code locations in the forest.
+void forceFillCodeLocations( ast::TranslationUnit & unit );
Index: src/Common/module.mk
===================================================================
--- src/Common/module.mk	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ src/Common/module.mk	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -18,4 +18,6 @@
       Common/Assert.cc \
       Common/CodeLocation.h \
+      Common/CodeLocationTools.hpp \
+      Common/CodeLocationTools.cpp \
       Common/CompilerError.h \
       Common/Debug.h \
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ src/main.cc	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -10,6 +10,6 @@
 // Created On       : Fri May 15 23:12:02 2015
 // Last Modified By : Andrew Beach
-// Last Modified On : Tue Dec  1 14:52:00 2020
-// Update Count     : 638
+// Last Modified On : Mon Dec  7 15:29:00 2020
+// Update Count     : 639
 //
 
@@ -40,4 +40,5 @@
 #include "CodeTools/ResolvProtoDump.h"      // for dumpAsResolvProto
 #include "CodeTools/TrackLoc.h"             // for fillLocations
+#include "Common/CodeLocationTools.hpp"     // for forceFillCodeLocations
 #include "Common/CompilerError.h"           // for CompilerError
 #include "Common/Stats.h"
@@ -353,9 +354,5 @@
 			} // if
 
-			// TODO: This is a quick fix to get the build working.
-			// Get rid of fillLocations or at least make a new-ast version.
-			translationUnit = convert( move( transUnit ) );
-			CodeTools::fillLocations( translationUnit );
-			transUnit = convert( move( translationUnit ) );
+			forceFillCodeLocations( transUnit );
 
 			PASS( "Fix Init", InitTweak::fix(transUnit, buildingLibrary()));
Index: tests/.expect/multi_list.txt
===================================================================
--- tests/.expect/multi_list.txt	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
+++ tests/.expect/multi_list.txt	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -0,0 +1,4 @@
+9 8 7 6 5 4 3 2 1 0
+0 1 2 3 4 5 6 7 8 9
+9 8 7 6 5 4 3 2 1 0
+9 8 7 6 5 4 3 2 1 0
Index: tests/.expect/queue.txt
===================================================================
--- tests/.expect/queue.txt	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
+++ tests/.expect/queue.txt	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -0,0 +1,8 @@
+empty
+0 2 4 6 8 10 12 14 16 18 
+18 
+18 1 3 5 7 9 11 13 15 17 19 
+empty
+0 0 2 2 4 4 6 6 8 8 10 10 12 12 14 14 16 16 18 18 
+18 18 
+18 18 1 1 3 3 5 5 7 7 9 9 11 11 13 13 15 15 17 17 19 19 
Index: tests/.expect/sequence.txt
===================================================================
--- tests/.expect/sequence.txt	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
+++ tests/.expect/sequence.txt	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -0,0 +1,12 @@
+empty
+0 2 4 6 8 10 12 14 16 18 
+18 
+18 1 3 5 7 9 11 13 15 17 19 
+18 1 
+empty
+0 0 2 2 4 4 6 6 8 8 10 10 12 12 14 14 16 16 18 18 
+18 18 
+18 18 1 1 3 3 5 5 7 7 9 9 11 11 13 13 15 15 17 17 19 19 
+18 18 1 1 
+empty
+18 18 1 1 0 0 2 2 4 4 6 6 8 8 10 10 12 12 14 14 16 16 18 18 
Index: tests/.expect/stack.txt
===================================================================
--- tests/.expect/stack.txt	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
+++ tests/.expect/stack.txt	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -0,0 +1,8 @@
+empty
+18 16 14 12 10 8 6 4 2 0 
+0 
+19 17 15 13 11 9 7 5 3 1 0 
+empty
+18 18 16 16 14 14 12 12 10 10 8 8 6 6 4 4 2 2 0 0 
+0 0 
+19 19 17 17 15 15 13 13 11 11 9 9 7 7 5 5 3 3 1 1 0 0 
Index: tests/Makefile.am
===================================================================
--- tests/Makefile.am	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ tests/Makefile.am	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -68,4 +68,26 @@
 .INTERMEDIATE: .validate .validate.cfa
 EXTRA_PROGRAMS = avl_test .dummy_hack # build but do not install
+EXTRA_DIST = test.py \
+	pybin/__init__.py \
+	pybin/print-core.gdb \
+	pybin/settings.py \
+	pybin/test_run.py \
+	pybin/tools.py \
+	long_tests.hfa \
+	.in/io.data \
+	avltree/avl.h \
+	avltree/avl-private.h \
+	concurrent/clib.c \
+	exceptions/with-threads.hfa \
+	exceptions/except-io.hfa
+
+dist-hook:
+	echo "Gathering test files"
+	for file in `${TEST_PY} --list-dist`; do \
+		if test -f ${srcdir}/$${file}; then \
+			$(MKDIR_P) $$(dirname ${distdir}/$${file}); \
+			cp -df ${srcdir}/$${file} ${distdir}/$${file}; \
+		fi; \
+	done
 
 avl_test_SOURCES = avltree/avl_test.cfa avltree/avl0.cfa avltree/avl1.cfa avltree/avl2.cfa avltree/avl3.cfa avltree/avl4.cfa avltree/avl-private.cfa
@@ -80,6 +102,13 @@
 	@+${TEST_PY} --debug=${debug} --install=${installed} --archive-errors=${archiveerrors} ${concurrent} ${timeouts} --all # '@' => do not echo command (SILENT), '+' => allows recursive make from within python program
 
-clean-local :
+mostlyclean-local :
 	rm -f ${EXTRA_PROGRAMS}
+	rm -rf __pycache__
+	find ${builddir} -path '*.o' -delete
+	find ${builddir} -path '*/.err/*.log' -delete
+	find ${builddir} -path '*/.out/*.log' -delete
+
+distclean-local :
+	find ${builddir} -path '*.Po' -delete
 
 list :
Index: tests/multi_list.cfa
===================================================================
--- tests/multi_list.cfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
+++ tests/multi_list.cfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -0,0 +1,101 @@
+#include <fstream.hfa>
+#include <stdlib.hfa>
+#include <bits/stack.hfa>
+#include <bits/queue.hfa>
+#include <bits/sequence.hfa>
+
+struct Task;											// node type
+
+struct TaskDL {
+	inline Seqable;
+	Task & node;
+};
+void ?{}( TaskDL & this, Task & task ) with( this ) {
+	((Seqable &)this){};
+	&node = &task;										// pointer to containing node
+}
+Task & task( TaskDL & this ) with( this ) {				// getter routine for containing node
+	return node;
+}
+
+struct TaskSL {
+	inline Colable;
+	Task & node;
+};
+void ?{}( TaskSL & this, Task & task ) with( this ) {
+	((Colable &)this){};
+	&node = &task;										// pointer to containing node
+}
+Task & task( TaskSL & this ) with( this ) {				// getter routine for containing node
+	return node;
+}
+
+struct Task {
+	TaskDL clusterRef;									// list of tasks on cluster
+	TaskDL readyRef;									// list of tasks on ready queue
+	TaskSL mutexRef;									// list of tasks on mutex queue
+	int id;
+};
+void ?{}( Task & this, int id ) with( this ) {
+	((TaskDL &)clusterRef){ this };
+	((TaskDL &)readyRef){ this };
+	((TaskSL &)mutexRef){ this };
+	this.id = id;
+}
+
+int main() {
+	Sequence(TaskDL) clustList, readyList;				// task lists
+	Queue(TaskSL) mutexList;
+	enum { Lnth = 10 };
+
+	for ( id; Lnth ) {
+		Task & task = *new( id );						// create task node
+		addHead( clustList, task.clusterRef );			// insert on lists in opposite directions
+		addTail( readyList, task.readyRef );
+		addHead( mutexList, task.mutexRef );
+	}
+
+	SeqIter(TaskDL) sqiter;
+	TaskDL & dl;										// iterator index
+	TaskSL & sl;
+
+	sout | nlOff;
+	for ( over( sqiter, clustList ); sqiter >> dl; ) {	// print lists
+		Task & tmp = task( dl ); sout | tmp.id;
+		// sout | task( dl ).id;
+	}
+	sout | nl;
+	for ( over( sqiter, readyList ); sqiter >> dl; ) {
+		Task & tmp = task( dl ); sout | tmp.id;
+		// sout | task( dl ).id;
+	}
+	sout | nl;
+	for ( QueueIter(TaskSL) qiter = { mutexList }; qiter >> sl; ) {	// print lists
+		Task & tmp = task( sl ); sout | tmp.id;
+		// sout | task( sl ).id;
+	}
+	sout | nl;
+	for ( Lnth ) {										// remove nodes from clustList. mutexList
+		dropHead( clustList );
+		drop( mutexList );
+	}
+	// Simultaneous deletion only safe if all nodes are traversed in same direction.
+	for ( Lnth ) {										// remove nodes from readyList and safe to delete nodes
+		delete( &task( dropHead( readyList ) ) );
+	}
+
+	// Re-purpose Seqable as Colable
+	Stack(TaskDL) mutexStack;
+	for ( id; Lnth ) {
+		Task & task = *new( id );						// create task node
+		push( mutexStack, task.clusterRef );			// insert on lists in opposite directions
+	}
+	for ( StackIter(TaskDL) stiter = { mutexStack }; stiter >> dl; ) {
+		Task & tmp = task( dl ); sout | tmp.id;
+		// sout | task( dl ).id;
+	}
+	sout | nl;
+	for ( Lnth ) {										// remove nodes from readyList and safe to delete nodes
+		delete( &task( pop( mutexStack ) ) );
+	}
+}
Index: tests/pybin/tools.py
===================================================================
--- tests/pybin/tools.py	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ tests/pybin/tools.py	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -191,4 +191,15 @@
 	cmd = [s for s in cmd if s]
 	return sh(*cmd, output_file=output_file, error=error)
+
+def make_recon(target):
+	cmd = [
+		*settings.make,
+		'-W',
+		os.path.abspath(os.path.join(settings.BUILDDIR, '../driver/cfa')),
+		'--recon',
+		target
+	]
+	cmd = [s for s in cmd if s]
+	return sh(*cmd, output_file=subprocess.PIPE)
 
 def which(program):
Index: tests/queue.cfa
===================================================================
--- tests/queue.cfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
+++ tests/queue.cfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -0,0 +1,108 @@
+#include <fstream.hfa>
+#include <stdlib.hfa>									// new, delete
+#include <bits/queue.hfa>
+
+int main() {
+	// Fred test
+
+	struct Fred {
+		inline Colable;									// Plan 9 inheritance
+		int i;
+	};
+	void ?{}( Fred & fred ) { abort(); }
+	void ?{}( Fred & fred, int p ) with( fred ) {
+		i = p;
+	}
+
+	Queue(Fred) fred;
+	QueueIter(Fred) fredIter = { fred };
+	Fred & f;
+
+	sout | nlOff;										// turn off auto newline
+
+	for ( ; fredIter >> f; ) {							// empty list
+		sout | f.i | ' ';
+	}
+	sout | "empty" | nl;
+	
+	for ( i; 10 ) {
+		add( fred, *new( 2 * i ) );
+	}
+
+	for ( QueueIter(Fred) iter = { fred }; iter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+
+	for ( i; 9 ) {
+		delete( &drop( fred ) );
+	}
+
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 10 ) {
+		add( fred, *new( 2 * i + 1 ) );
+	}
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		delete( &f );
+	}
+
+	// Mary test
+
+	struct Mary {
+		inline Fred;									// Plan 9 inheritance
+		int j;
+	};
+	void ?{}( Mary & mary ) { abort(); }
+	void ?{}( Mary & mary, int p ) with( mary ) {
+		((Fred &)mary){ p };
+		j = i = p;
+	}
+
+	Queue(Mary) mary;
+	QueueIter(Mary) maryIter = { mary };
+	Mary & m;
+
+	for ( ; maryIter >> m; ) {							// empty list
+		sout | m.i | m.j | ' ';
+	}
+	sout | "empty" | nl;
+	
+	for ( i; 10 ) {
+		add( mary, *new( 2 * i ) );
+	}
+
+	for ( QueueIter(Mary) iter = { mary }; iter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 9 ) {
+		delete( &drop( mary ) );
+	}
+
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 10 ) {
+		add( mary, *new( 2 * i + 1 ) );
+	}
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		delete( &m );
+	}
+}
Index: tests/sequence.cfa
===================================================================
--- tests/sequence.cfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
+++ tests/sequence.cfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -0,0 +1,138 @@
+#include <fstream.hfa>
+#include <stdlib.hfa>									// new, delete
+#include <bits/sequence.hfa>
+
+int main() {
+	// Fred test
+
+	struct Fred {
+		inline Seqable;									// Plan 9 inheritance
+		int i;
+	};
+	void ?{}( Fred & fred ) { abort(); }
+	void ?{}( Fred & fred, int p ) with( fred ) {
+		i = p;
+	}
+
+	Sequence(Fred) fred;
+	SeqIter(Fred) fredIter = { fred };
+	Fred & f;
+
+	sout | nlOff;										// turn off auto newline
+
+	for ( ; fredIter >> f; ) {							// empty list
+		sout | f.i | ' ';
+	}
+	sout | "empty" | nl;
+	
+	for ( i; 10 ) {
+		add( fred, *new( 2 * i ) );
+	}
+
+	for ( SeqIter(Fred) iter = { fred }; iter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+
+	for ( i; 9 ) {
+		delete( &dropHead( fred ) );
+	}
+
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 10 ) {
+		addTail( fred, *new( 2 * i + 1 ) );
+	}
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+
+	for ( i; 9 ) {
+		delete( &dropTail( fred ) );
+	}
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		delete( &f );
+	}
+
+	// Mary test
+
+	struct Mary {
+		inline Fred;									// Plan 9 inheritance
+		int j;
+	};
+	void ?{}( Mary & mary ) { abort(); }
+	void ?{}( Mary & mary, int p ) with( mary ) {
+		((Fred &)mary){ p };
+		j = p;
+	}
+
+	Sequence(Mary) mary;
+	Sequence(Mary) baz;
+	SeqIter(Mary) maryIter = { mary };
+	Mary & m;
+
+	for ( ; maryIter >> m; ) {							// empty list
+		sout | m.i | m.j | ' ';
+	}
+	sout | "empty" | nl;
+	
+	for ( i; 10 ) {
+		add( mary, *new( 2 * i ) );
+		add( baz, *new( 2 * i ) );
+	}
+
+	for ( SeqIter(Mary) iter = { mary }; iter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 9 ) {
+		delete( &dropHead( mary ) );
+	}
+
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 10 ) {
+		addTail( mary, *new( 2 * i + 1 ) );
+	}
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+
+	for ( i; 9 ) {
+		delete( &dropTail( mary ) );
+	}
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+
+	transfer( mary, baz );
+
+	for ( over( maryIter, baz ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | "empty" | nl;
+
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		delete( &m );
+	}
+}
Index: tests/stack.cfa
===================================================================
--- tests/stack.cfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
+++ tests/stack.cfa	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -0,0 +1,108 @@
+#include <fstream.hfa>
+#include <stdlib.hfa>									// new, delete
+#include <bits/stack.hfa>
+
+int main() {
+	// Fred test
+
+	struct Fred {
+		inline Colable;									// Plan 9 inheritance
+		int i;
+	};
+	void ?{}( Fred & fred ) { abort(); }
+	void ?{}( Fred & fred, int p ) with( fred ) {
+		i = p;
+	}
+
+	Stack(Fred) fred;
+	StackIter(Fred) fredIter = { fred };
+	Fred & f;
+
+	sout | nlOff;										// turn off auto newline
+
+	for ( ; fredIter >> f; ) {							// empty list
+		sout | f.i | ' ';
+	}
+	sout | "empty" | nl;
+	
+	for ( i; 10 ) {
+		push( fred, *new( 2 * i ) );
+	}
+
+	for ( StackIter(Fred) iter = { fred }; iter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 9 ) {
+		delete( &pop( fred ) );
+	}
+
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 10 ) {
+		push( fred, *new( 2 * i + 1 ) );
+	}
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		delete( &f );
+	}
+
+	// Mary test
+
+	struct Mary {
+		inline Fred;									// Plan 9 inheritance
+		int j;
+	};
+	void ?{}( Mary & mary ) { abort(); }
+	void ?{}( Mary & mary, int p ) with( mary ) {
+		((Fred &)mary){ p };
+		j = i = p;
+	}
+
+	Stack(Mary) mary;
+	StackIter(Mary) maryIter = { mary };
+	Mary & m;
+
+	for ( ; maryIter >> m; ) {							// empty list
+		sout | m.i | m.j | ' ';
+	}
+	sout | "empty" | nl;
+	
+	for ( i; 10 ) {
+		push( mary, *new( 2 * i ) );
+	}
+
+	for ( StackIter(Mary) iter = { mary }; iter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 9 ) {
+		delete( &pop( mary ) );
+	}
+
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 10 ) {
+		push( mary, *new( 2 * i + 1 ) );
+	}
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		delete( &m );
+	}
+}
Index: tests/test.py
===================================================================
--- tests/test.py	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ tests/test.py	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -143,4 +143,5 @@
 	parser.add_argument('-j', '--jobs', help='Number of tests to run simultaneously', type=int)
 	parser.add_argument('--list-comp', help='List all valide arguments', action='store_true')
+	parser.add_argument('--list-dist', help='List all tests for distribution', action='store_true')
 	parser.add_argument('-I','--include', help='Directory of test to include, can be used multiple time, All  if omitted', action='append')
 	parser.add_argument('-E','--exclude', help='Directory of test to exclude, can be used multiple time, None if omitted', action='append')
@@ -155,5 +156,5 @@
 
 	# script must have at least some tests to run or be listing
-	listing    = options.list or options.list_comp
+	listing    = options.list or options.list_comp or options.list_dist
 	all_tests  = options.all
 	some_tests = len(options.tests) > 0
@@ -334,5 +335,7 @@
 	settings.init( options )
 
-	# users may want to simply list the tests
+	# --------------------------------------------------
+	# list all the test for auto completion programs
+	# not pretty, single line, with the command line options
 	if options.list_comp :
 		# fetch the liest of all valid tests
@@ -340,8 +343,36 @@
 
 		# print the possible options
-		print("-h --help --debug --dry-run --list --arch --all --regenerate-expected --archive-errors --install --timeout --global-timeout --timeout-with-gdb -j --jobs -I --include -E --exclude --continue ", end='')
+		print("-h --help --debug --dry-run --list --ast=new --ast=old --arch --all --regenerate-expected --archive-errors --install --timeout --global-timeout --timeout-with-gdb -j --jobs -I --include -E --exclude --continue ", end='')
 		print(" ".join(map(lambda t: "%s" % (t.target()), tests)))
 
-	elif options.list :
+		# done
+		sys.exit(0)
+
+	# --------------------------------------------------
+	# list all the test for auto completion programs
+	if options.list_dist :
+		# fetch the liest of all valid tests
+		tests = list_tests( None, None )
+
+		for t in tests:
+			print(os.path.relpath(t.expect(), settings.SRCDIR), end=' ')
+			print(os.path.relpath(t.input() , settings.SRCDIR), end=' ')
+			code, out = make_recon(t.target())
+
+			if code != 0:
+				print('ERROR: recond failed for test {}'.format(t.target()), file=sys.stderr)
+				sys.exit(1)
+
+			print(' '.join(re.findall('([^\s]+\.cfa)', out)), end=' ')
+
+		print('')
+
+		# done
+		sys.exit(0)
+
+
+	# --------------------------------------------------
+	# list all the tests for users, in a pretty format
+	if options.list :
 		# fetch the liest of all valid tests
 		tests = list_tests( options.include, options.exclude )
@@ -350,69 +381,71 @@
 		fancy_print("\n".join(map(lambda t: t.toString(), tests)))
 
+		# done
+		sys.exit(0)
+
+	# fetch the liest of all valid tests
+	all_tests = list_tests( options.include, options.exclude )
+
+	# if user wants all tests than no other treatement of the test list is required
+	if options.all or options.include :
+		tests = all_tests
+
+	#otherwise we need to validate that the test list that was entered is valid
 	else :
-		# fetch the liest of all valid tests
-		all_tests = list_tests( options.include, options.exclude )
-
-		# if user wants all tests than no other treatement of the test list is required
-		if options.all or options.include :
-			tests = all_tests
-
-		#otherwise we need to validate that the test list that was entered is valid
-		else :
-			tests = valid_tests( options )
-
-		# make sure we have at least some test to run
-		if not tests :
-			print('ERROR: No valid test to run', file=sys.stderr)
-			sys.exit(1)
-
-		# prep invariants
-		settings.prep_output(tests)
-		failed = 0
-
-		# check if the expected files aren't empty
-		if not options.regenerate_expected:
-			for t in tests:
-				if is_empty(t.expect()):
-					print('WARNING: test "{}" has empty .expect file'.format(t.target()), file=sys.stderr)
-
-		# for each build configurations, run the test
-		with Timed() as total_dur:
-			for ast, arch, debug, install in itertools.product(settings.all_ast, settings.all_arch, settings.all_debug, settings.all_install):
-				settings.ast     = ast
-				settings.arch    = arch
-				settings.debug   = debug
-				settings.install = install
-
-				# filter out the tests for a different architecture
-				# tests are the same across debug/install
-				local_tests = settings.ast.filter( tests )
-				local_tests = settings.arch.filter( local_tests )
-				options.jobs, forceJobs = job_count( options, local_tests )
-				settings.update_make_cmd(forceJobs, options.jobs)
-
-				# check the build configuration works
-				settings.validate()
-
-				# print configuration
-				print('%s %i tests on %i cores (%s:%s - %s)' % (
-					'Regenerating' if settings.generating else 'Running',
-					len(local_tests),
-					options.jobs,
-					settings.ast.string,
-					settings.arch.string,
-					settings.debug.string
-				))
-				if not local_tests :
-					print('WARNING: No tests for this configuration')
-					continue
-
-				# otherwise run all tests and make sure to return the correct error code
-				failed = run_tests(local_tests, options.jobs)
-				if failed:
-					result = 1
-					if not settings.continue_:
-						break
-
-		print('Tests took %s' % fmtDur( total_dur.duration ))
-		sys.exit( failed )
+		tests = valid_tests( options )
+
+	# make sure we have at least some test to run
+	if not tests :
+		print('ERROR: No valid test to run', file=sys.stderr)
+		sys.exit(1)
+
+	# prep invariants
+	settings.prep_output(tests)
+	failed = 0
+
+	# check if the expected files aren't empty
+	if not options.regenerate_expected:
+		for t in tests:
+			if is_empty(t.expect()):
+				print('WARNING: test "{}" has empty .expect file'.format(t.target()), file=sys.stderr)
+
+	# for each build configurations, run the test
+	with Timed() as total_dur:
+		for ast, arch, debug, install in itertools.product(settings.all_ast, settings.all_arch, settings.all_debug, settings.all_install):
+			settings.ast     = ast
+			settings.arch    = arch
+			settings.debug   = debug
+			settings.install = install
+
+			# filter out the tests for a different architecture
+			# tests are the same across debug/install
+			local_tests = settings.ast.filter( tests )
+			local_tests = settings.arch.filter( local_tests )
+			options.jobs, forceJobs = job_count( options, local_tests )
+			settings.update_make_cmd(forceJobs, options.jobs)
+
+			# check the build configuration works
+			settings.validate()
+
+			# print configuration
+			print('%s %i tests on %i cores (%s:%s - %s)' % (
+				'Regenerating' if settings.generating else 'Running',
+				len(local_tests),
+				options.jobs,
+				settings.ast.string,
+				settings.arch.string,
+				settings.debug.string
+			))
+			if not local_tests :
+				print('WARNING: No tests for this configuration')
+				continue
+
+			# otherwise run all tests and make sure to return the correct error code
+			failed = run_tests(local_tests, options.jobs)
+			if failed:
+				result = 1
+				if not settings.continue_:
+					break
+
+	print('Tests took %s' % fmtDur( total_dur.duration ))
+	sys.exit( failed )
Index: tools/Makefile.am
===================================================================
--- tools/Makefile.am	(revision 6a45bd78e92f655b09a86343cc1f6bc004cd951d)
+++ tools/Makefile.am	(revision 3e3f236be88fc36d0ee588b73fcfe7a922800c77)
@@ -18,6 +18,4 @@
 ACLOCAL_AMFLAGS  = -I automake
 
-EXTRA_DIST = build/distcc_hash build/push2dist.sh
-
 noinst_PROGRAMS = busy catchsig repeat watchdog
 AM_CFLAGS = -Wall -Wextra -O2 -g
