Index: Jenkinsfile
===================================================================
--- Jenkinsfile	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ Jenkinsfile	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,418 @@
+#!groovy
+
+//===========================================================================================================
+// Main loop of the compilation
+//===========================================================================================================
+
+node('master') {
+	// Globals
+	BuildDir  = pwd tmp: true
+	SrcDir    = pwd tmp: false
+	Settings  = null
+	StageName = ''
+
+	// Local variables
+	def err = null
+	def log_needed = false
+
+	currentBuild.result = "SUCCESS"
+
+	try {
+		//Wrap build to add timestamp to command line
+		wrap([$class: 'TimestamperBuildWrapper']) {
+
+			notify_server(0)
+
+			Settings = prepare_build()
+
+			node(Settings.Architecture.node) {
+				BuildDir  = pwd tmp: true
+				SrcDir    = pwd tmp: false
+
+				clean()
+
+				checkout()
+
+				notify_server(0)
+
+				build()
+
+				test()
+
+				benchmark()
+
+				build_doc()
+
+				publish()
+			}
+
+			// Update the build directories when exiting the node
+			BuildDir  = pwd tmp: true
+			SrcDir    = pwd tmp: false
+
+			notify_server(45)
+		}
+	}
+
+	//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
+		if( Settings && !Settings.Silent ) {
+			email(log_needed, Settings.IsSandbox)
+		}
+
+		echo 'Build Completed'
+
+		/* Must re-throw exception to propagate error */
+		if (err) {
+			throw err
+		}
+	}
+}
+//===========================================================================================================
+// Main compilation routines
+//===========================================================================================================
+def clean() {
+	build_stage('Cleanup') {
+		// clean the build by wipping the build directory
+		dir(BuildDir) {
+			deleteDir()
+		}
+	}
+}
+
+//Compilation script is done here but environnement set-up and error handling is done in main loop
+def checkout() {
+	build_stage('Checkout') {
+		//checkout the source code and clean the repo
+		final scmVars = checkout scm
+		Settings.GitNewRef = scmVars.GIT_COMMIT
+		Settings.GitOldRef = scmVars.GIT_PREVIOUS_COMMIT
+
+		echo GitLogMessage()
+	}
+}
+
+def build() {
+	build_stage('Build') {
+		// Build outside of the src tree to ease cleaning
+		dir (BuildDir) {
+			//Configure the conpilation (Output is not relevant)
+			//Use the current directory as the installation target so nothing escapes the sandbox
+			//Also specify the compiler by hand
+			targets=""
+			if( Settings.RunAllTests ) {
+				targets="--with-target-hosts='host:debug,host:nodebug'"
+			} else {
+				targets="--with-target-hosts='host:debug'"
+			}
+
+			sh "${SrcDir}/configure CXX=${Settings.Compiler.CXX} CC=${Settings.Compiler.CC} ${Settings.Architecture.flags} ${targets} --quiet"
+
+			//Compile the project
+			sh 'make -j 8 --no-print-directory'
+		}
+	}
+}
+
+def test() {
+	build_stage('Test') {
+
+		dir (BuildDir) {
+			//Run the tests from the tests directory
+			if ( Settings.RunAllTests ) {
+				sh 'make --no-print-directory -C tests timeouts="--timeout=600" all-tests debug=yes'
+				sh 'make --no-print-directory -C tests timeouts="--timeout=600" all-tests debug=no '
+			}
+			else {
+				sh 'make --no-print-directory -C tests'
+			}
+		}
+	}
+}
+
+def benchmark() {
+	build_stage('Benchmark') {
+
+		if( !Settings.RunBenchmark ) return
+
+		dir (BuildDir) {
+			//Append bench results
+			sh "${SrcDir}/benchmark/jenkins.sh ${Settings.GitNewRef} ${Settings.Architecture} ${BuildDir}/bench.json"
+		}
+	}
+}
+
+def build_doc() {
+	build_stage('Documentation') {
+
+		if( !Settings.BuildDocumentation ) return
+
+		dir ('doc/user') {
+			make_doc()
+		}
+
+		dir ('doc/refrat') {
+			make_doc()
+		}
+	}
+}
+
+def publish() {
+	build_stage('Publish') {
+
+		if( !Settings.Publish ) return
+
+		//Then publish the results
+		sh 'curl --silent --show-error -H \'Content-Type: application/json\' --data @${BuildDir}/bench.json https://cforall.uwaterloo.ca:8082/jenkins/publish > /dev/null || true'
+	}
+}
+
+//===========================================================================================================
+//Routine responsible of sending the email notification once the build is completed
+//===========================================================================================================
+def GitLogMessage() {
+	if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
+
+	sh "${SrcDir}/tools/PrettyGitLogs.sh ${SrcDir} ${BuildDir} ${Settings.GitOldRef} ${Settings.GitNewRef}"
+
+	def gitUpdate = readFile("${BuildDir}/GIT_UPDATE")
+	def gitLog    = readFile("${BuildDir}/GIT_LOG")
+	def gitDiff   = readFile("${BuildDir}/GIT_DIFF")
+
+	return """
+The branch ${env.BRANCH_NAME} has been updated.
+${gitUpdate}
+
+Check console output at ${env.BUILD_URL} to view the results.
+
+- Status --------------------------------------------------------------
+
+BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}
+
+- Log -----------------------------------------------------------------
+${gitLog}
+-----------------------------------------------------------------------
+Summary of changes:
+${gitDiff}
+"""
+}
+
+//Standard build email notification
+def email(boolean log, boolean bIsSandbox) {
+	//Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
+	//Configurations for email format
+	echo 'Notifying users of result'
+
+	def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
+	def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
+	def email_body = """This is an automated email from the Jenkins build machine. It was
+generated because of a git hooks/post-receive script following
+a ref change which was pushed to the Cforall repository.
+""" + GitLogMessage()
+
+	def email_to = "cforall@lists.uwaterloo.ca"
+
+	if( Settings && !Settings.IsSandbox ) {
+		//send email notification
+		emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
+	} else {
+		echo "Would send email to: ${email_to}"
+		echo "With title: ${email_subject}"
+		echo "Content: \n${email_body}"
+	}
+}
+
+//===========================================================================================================
+// Helper classes/variables/routines
+//===========================================================================================================
+//Description of a compiler (Must be serializable since pipelines are persistent)
+class CC_Desc implements Serializable {
+	public String name
+	public String CXX
+	public String CC
+
+	CC_Desc(String name, String CXX, String CC) {
+		this.name = name
+		this.CXX = CXX
+		this.CC = CC
+	}
+}
+
+//Description of an architecture (Must be serializable since pipelines are persistent)
+class Arch_Desc implements Serializable {
+	public String name
+	public String flags
+	public String node
+
+	Arch_Desc(String name, String flags, String node) {
+		this.name  = name
+		this.flags = flags
+		this.node  = node
+	}
+}
+
+class BuildSettings implements Serializable {
+	public final CC_Desc Compiler
+	public final Arch_Desc Architecture
+	public final Boolean RunAllTests
+	public final Boolean RunBenchmark
+	public final Boolean BuildDocumentation
+	public final Boolean Publish
+	public final Boolean Silent
+	public final Boolean IsSandbox
+	public final String DescLong
+	public final String DescShort
+
+	public String GitNewRef
+	public String GitOldRef
+
+	BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
+		switch( param.Compiler ) {
+			case 'gcc-6':
+				this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
+			break
+			case 'gcc-5':
+				this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
+			break
+			case 'gcc-4.9':
+				this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
+			break
+			case 'clang':
+				this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
+			break
+			default :
+				error "Unhandled compiler : ${cc}"
+		}
+
+		switch( param.Architecture ) {
+			case 'x64':
+				this.Architecture = new Arch_Desc('x64', '--host=x86_64', 'x64')
+			break
+			case 'x86':
+				this.Architecture = new Arch_Desc('x86', '--host=i386', 'x86')
+			break
+			default :
+				error "Unhandled architecture : ${arch}"
+		}
+
+		this.RunAllTests        = param.RunAllTests
+		this.RunBenchmark       = param.RunBenchmark
+		this.BuildDocumentation = param.BuildDocumentation
+		this.Publish            = param.Publish
+		this.Silent             = param.Silent
+		this.IsSandbox          = (branch == "jenkins-sandbox")
+
+		def full = param.RunAllTests ? " (Full)" : ""
+		this.DescShort = "${ this.Compiler.name }:${ this.Architecture.name }${full}"
+
+		this.DescLong = """Compiler 	         : ${ this.Compiler.name } (${ this.Compiler.CXX }/${ this.Compiler.CC })
+Architecture            : ${ this.Architecture.name }
+Arc Flags               : ${ this.Architecture.flags }
+Run All Tests           : ${ this.RunAllTests.toString() }
+Run Benchmark           : ${ this.RunBenchmark.toString() }
+Build Documentation     : ${ this.BuildDocumentation.toString() }
+Publish                 : ${ this.Publish.toString() }
+Silent                  : ${ this.Silent.toString() }
+"""
+
+		this.GitNewRef = ''
+		this.GitOldRef = ''
+	}
+}
+
+def prepare_build() {
+	// prepare the properties
+	properties ([ 													\
+		[$class: 'ParametersDefinitionProperty', 								\
+			parameterDefinitions: [ 									\
+				[$class: 'ChoiceParameterDefinition',						\
+					description: 'Which compiler to use',					\
+					name: 'Compiler',									\
+					choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang',					\
+					defaultValue: 'gcc-6',								\
+				],												\
+				[$class: 'ChoiceParameterDefinition',						\
+					description: 'The target architecture',					\
+					name: 'Architecture',								\
+					choices: 'x64\nx86',								\
+					defaultValue: 'x64',								\
+				],												\
+				[$class: 'BooleanParameterDefinition',  						\
+					description: 'If false, only the quick test suite is ran', 		\
+					name: 'RunAllTests', 								\
+					defaultValue: false,  								\
+				], 												\
+				[$class: 'BooleanParameterDefinition',  						\
+					description: 'If true, jenkins also runs benchmarks', 		\
+					name: 'RunBenchmark', 								\
+					defaultValue: false,  								\
+				], 												\
+				[$class: 'BooleanParameterDefinition',  						\
+					description: 'If true, jenkins also builds documentation', 		\
+					name: 'BuildDocumentation', 							\
+					defaultValue: true,  								\
+				],												\
+				[$class: 'BooleanParameterDefinition',  						\
+					description: 'If true, jenkins also publishes results', 		\
+					name: 'Publish', 									\
+					defaultValue: false,  								\
+				],												\
+				[$class: 'BooleanParameterDefinition',  						\
+					description: 'If true, jenkins will not send emails', 		\
+					name: 'Silent', 									\
+					defaultValue: false,  								\
+				],												\
+			],
+		]])
+
+	// It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer
+	checkout scm
+
+	final settings = new BuildSettings(params, env.BRANCH_NAME)
+
+	currentBuild.description = settings.DescShort
+	echo                       settings.DescLong
+
+	return settings
+}
+
+def build_stage(String name, Closure block ) {
+	StageName = name
+	echo " -------- ${StageName} -------- "
+	stage(name, block)
+}
+
+def notify_server(int wait) {
+	sh """curl --silent --show-error --data "wait=${wait}" -X POST https://cforall.uwaterloo.ca:8082/jenkins/notify > /dev/null || true"""
+	return
+}
+
+def make_doc() {
+	def err = null
+	try {
+		sh 'make clean > /dev/null'
+		sh 'make > /dev/null 2>&1'
+	}
+	catch (Exception caughtError) {
+		err = caughtError //rethrow error later
+		sh 'cat build/*.log'
+	}
+	finally {
+		if (err) throw err // Must re-throw exception to propagate error
+	}
+}
Index: benchmark/Makefile.am
===================================================================
--- benchmark/Makefile.am	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ benchmark/Makefile.am	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -21,7 +21,7 @@
 include $(top_srcdir)/src/cfa.make
 
-AM_CFLAGS = -O2 -Wall -I$(srcdir) -lrt -pthread
-AM_CFAFLAGS = -quiet -in-tree -nodebug
-AM_UPPFLAGS = -quiet -nodebug -multi
+AM_CFLAGS = -O2 -Wall -Wextra -Werror -I$(srcdir) -lrt -pthread
+AM_CFAFLAGS = -quiet -nodebug -in-tree
+AM_UPPFLAGS = -quiet -nodebug -multi -std=c++14
 
 BENCH_V_CC = $(__bench_v_CC_$(__quiet))
@@ -139,4 +139,7 @@
 	$(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/fetch_add.c
 
+tls-fetch_add$(EXEEXT):
+	$(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/tls-fetch_add.c
+
 ## =========================================================================================================
 CTXSWITCH_DEPEND  =                 \
@@ -144,4 +147,5 @@
 	function.run			\
 	fetch_add.run			\
+	tls-fetch_add.run			\
 	ctxswitch-pthread.run		\
 	ctxswitch-cfa_coroutine.run	\
Index: benchmark/Makefile.in
===================================================================
--- benchmark/Makefile.in	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ benchmark/Makefile.in	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -371,7 +371,7 @@
 
 # applies to both programs
-AM_CFLAGS = -O2 -Wall -I$(srcdir) -lrt -pthread
-AM_CFAFLAGS = -quiet -in-tree -nodebug
-AM_UPPFLAGS = -quiet -nodebug -multi
+AM_CFLAGS = -O2 -Wall -Wextra -Werror -I$(srcdir) -lrt -pthread
+AM_CFAFLAGS = -quiet -nodebug -in-tree
+AM_UPPFLAGS = -quiet -nodebug -multi -std=c++14
 BENCH_V_CC = $(__bench_v_CC_$(__quiet))
 BENCH_V_CFA = $(__bench_v_CFA_$(__quiet))
@@ -402,9 +402,9 @@
 dummy_SOURCES = dummyC.c dummyCXX.cpp
 CTXSWITCH_DEPEND = loop.run function.run fetch_add.run \
-	ctxswitch-pthread.run ctxswitch-cfa_coroutine.run \
-	ctxswitch-cfa_thread.run ctxswitch-cfa_thread2.run \
-	ctxswitch-upp_coroutine.run ctxswitch-upp_thread.run \
-	ctxswitch-goroutine.run ctxswitch-java_thread.run \
-	$(am__append_1)
+	tls-fetch_add.run ctxswitch-pthread.run \
+	ctxswitch-cfa_coroutine.run ctxswitch-cfa_thread.run \
+	ctxswitch-cfa_thread2.run ctxswitch-upp_coroutine.run \
+	ctxswitch-upp_thread.run ctxswitch-goroutine.run \
+	ctxswitch-java_thread.run $(am__append_1)
 testdir = $(top_srcdir)/tests
 all: all-am
@@ -799,4 +799,7 @@
 	$(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/fetch_add.c
 
+tls-fetch_add$(EXEEXT):
+	$(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/tls-fetch_add.c
+
 @WITH_LIBFIBRE_TRUE@ctxswitch-kos_fibre$(EXEEXT):
 @WITH_LIBFIBRE_TRUE@	$(BENCH_V_CXX)$(CXXCOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/kos_fibre.cpp  -I$(LIBFIBRE_DIR) -lfibre
Index: benchmark/tls-fetch_add.c
===================================================================
--- benchmark/tls-fetch_add.c	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ benchmark/tls-fetch_add.c	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,27 @@
+#include <stdbool.h>
+#include <stdio.h>
+
+#include "bench.h"
+
+#define thread_local _Thread_local
+
+volatile thread_local bool value;
+
+void __attribute__((noinline)) do_call() {
+	__atomic_store_n( &value, true, __ATOMIC_RELAXED );
+	__atomic_signal_fence(__ATOMIC_ACQUIRE);
+	asm volatile ("");
+	__atomic_store_n( &value, false, __ATOMIC_RELAXED );
+	__atomic_signal_fence(__ATOMIC_RELEASE);
+}
+
+int main(int argc, char* argv[]) {
+	BENCH(
+		for (size_t i = 0; i < n; i++) {
+			do_call();
+		},
+		result
+	)
+
+	printf("%llu\n", result);
+}
Index: configure
===================================================================
--- configure	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ configure	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -16738,5 +16738,5 @@
 
 #==============================================================================
-ac_config_files="$ac_config_files Makefile driver/Makefile src/Makefile benchmark/Makefile tests/Makefile tests/preempt_longrun/Makefile tools/Makefile tools/prettyprinter/Makefile"
+ac_config_files="$ac_config_files Makefile driver/Makefile src/Makefile benchmark/Makefile tests/Makefile longrun_tests/Makefile tools/Makefile tools/prettyprinter/Makefile"
 
 
@@ -17876,5 +17876,5 @@
     "benchmark/Makefile") CONFIG_FILES="$CONFIG_FILES benchmark/Makefile" ;;
     "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
-    "tests/preempt_longrun/Makefile") CONFIG_FILES="$CONFIG_FILES tests/preempt_longrun/Makefile" ;;
+    "longrun_tests/Makefile") CONFIG_FILES="$CONFIG_FILES longrun_tests/Makefile" ;;
     "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;;
     "tools/prettyprinter/Makefile") CONFIG_FILES="$CONFIG_FILES tools/prettyprinter/Makefile" ;;
Index: configure.ac
===================================================================
--- configure.ac	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ configure.ac	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -211,5 +211,5 @@
 	benchmark/Makefile
 	tests/Makefile
-	tests/preempt_longrun/Makefile
+	longrun_tests/Makefile
 	tools/Makefile
 	tools/prettyprinter/Makefile
Index: doc/bibliography/pl.bib
===================================================================
--- doc/bibliography/pl.bib	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ doc/bibliography/pl.bib	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -1163,16 +1163,16 @@
     title	= {Checked C: Making C Safe by Extension},
     booktitle	= {2018 IEEE Cybersecurity Development (SecDev)},
-    year = {2018},
-    month = {September},
-    pages = {53-60},
-    publisher = {IEEE},
-    url = {https://www.microsoft.com/en-us/research/publication/checkedc-making-c-safe-by-extension/},
+    year	= {2018},
+    month	= {September},
+    pages	= {53-60},
+    publisher	= {IEEE},
+    url		= {https://www.microsoft.com/en-us/research/publication/checkedc-making-c-safe-by-extension/},
 }
 
 @misc{Clang,
-    keywords = {clang},
-    contributer = {a3moss@uwaterloo.ca},
-    title = {Clang: a {C} language family frontend for {LLVM}},
-    howpublished = {\href{https://clang.llvm.org/}{https://\-clang.llvm.org/}}
+    keywords	= {clang},
+    contributer	= {a3moss@uwaterloo.ca},
+    title	= {Clang: a {C} language family frontend for {LLVM}},
+    howpublished= {\href{https://clang.llvm.org/}{https://\-clang.llvm.org/}}
 }
 
@@ -2347,4 +2347,20 @@
 }
 
+@article{Ritchie93,
+    keywords	= {C, history},
+    contributer	= {pabuhr@plg},
+    author	= {Ritchie, Dennis M.},
+    title	= {The Development of the {C} Language},
+    journal	= sigplan,
+    volume	= 28,
+    number	= 3,
+    month	= mar,
+    year	= 1993,
+    pages	= {201--208},
+    url		= {http://doi.acm.org/10.1145/155360.155580},
+    publisher	= {ACM},
+    address	= {New York, NY, USA},
+} 
+
 @article{design,
     keywords	= {Smalltalk, designing classes},
@@ -2354,5 +2370,7 @@
     journal	= joop,
     year	= 1988,
-    volume	= 1, number = 2, pages = {22-35},
+    volume	= 1,
+    number	= 2,
+    pages	= {22-35},
     comment	= {
 	Abstract classes represent standard protocols.  ``It is better to
@@ -3789,4 +3807,16 @@
     optaddress	= {Waterloo, Ontario, Canada, N2L 3G1},
     note	= {\href{https://uwspace.uwaterloo.ca/handle/10012/13935}{https://\-uwspace.uwaterloo.ca/\-handle/\-10012/\-13935}},
+}
+
+@article{Swift05,
+   contributer	= {pabuhr@plg},
+   author	= {Michael M. Swift and Brian N. Bershad and Henry M. Levy},
+   title	= {Improving the Reliability of Commodity Operating Systems},
+   journal	= tocs,
+   volume	= 23,
+   number	= 1,
+   month	= feb,
+   year		= 2005,
+   pages	= {77-110},
 }
 
Index: doc/papers/concurrency/Paper.tex
===================================================================
--- doc/papers/concurrency/Paper.tex	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ doc/papers/concurrency/Paper.tex	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -215,5 +215,8 @@
 {}
 \lstnewenvironment{Go}[1][]
-{\lstset{#1}}
+{\lstset{language=go,moredelim=**[is][\protect\color{red}]{`}{`},#1}\lstset{#1}}
+{}
+\lstnewenvironment{python}[1][]
+{\lstset{language=python,moredelim=**[is][\protect\color{red}]{`}{`},#1}\lstset{#1}}
 {}
 
@@ -228,5 +231,5 @@
 }
 
-\title{\texorpdfstring{Advanced Control-flow in \protect\CFA}{Advanced Control-flow in Cforall}}
+\title{\texorpdfstring{Advanced Control-flow and Concurrency in \protect\CFA}{Advanced Control-flow in Cforall}}
 
 \author[1]{Thierry Delisle}
@@ -242,9 +245,9 @@
 \abstract[Summary]{
 \CFA is a modern, polymorphic, non-object-oriented, backwards-compatible extension of the C programming language.
-This paper discusses the advanced control-flow features in \CFA, which include concurrency and parallelism, and its supporting runtime system.
-These features are created from scratch as ISO C's concurrency is low-level and unimplemented, so C programmers continue to rely on the C pthreads library.
-\CFA provides high-level control-flow mechanisms, like coroutines and user-level threads, and monitors for mutual exclusion and synchronization.
-A unique contribution of this work is allowing multiple monitors to be safely acquired \emph{simultaneously} (deadlock free), while integrating this capability with all monitor synchronization mechanisms.
-All features respect the expectations of C programmers, while being fully integrate with the \CFA polymorphic type-system and other language features.
+This paper discusses some advanced control-flow and concurrency/parallelism features in \CFA, along with the supporting runtime.
+These features are created from scratch because they do not exist in ISO C, or are low-level and/or unimplemented, so C programmers continue to rely on library features, like C pthreads.
+\CFA introduces language-level control-flow mechanisms, like coroutines, user-level threading, and monitors for mutual exclusion and synchronization.
+A unique contribution of this work is allowing multiple monitors to be safely acquired \emph{simultaneously} (deadlock free), while integrating this capability with monitor synchronization mechanisms.
+These features also integrate with the \CFA polymorphic type-system and exception handling, while respecting the expectations and style of C programmers.
 Experimental results show comparable performance of the new features with similar mechanisms in other concurrent programming-languages.
 }%
@@ -261,15 +264,16 @@
 \section{Introduction}
 
-This paper discusses the design of advanced, high-level control-flow extensions (especially concurrency and parallelism) in \CFA and its runtime.
+This paper discusses the design of language-level control-flow and concurrency/parallelism extensions in \CFA and its runtime.
 \CFA is a modern, polymorphic, non-object-oriented\footnote{
 \CFA has features often associated with object-oriented programming languages, such as constructors, destructors, virtuals and simple inheritance.
 However, functions \emph{cannot} be nested in structures, so there is no lexical binding between a structure and set of functions (member/method) implemented by an implicit \lstinline@this@ (receiver) parameter.},
 backwards-compatible extension of the C programming language~\cite{Moss18}.
-Within the \CFA framework, new control-flow features were created from scratch.
-ISO \Celeven defines only a subset of the \CFA extensions, and with respect to concurrency~\cite[\S~7.26]{C11}, the features are largely wrappers for a subset of the pthreads library~\cite{Butenhof97,Pthreads}.
-Furthermore, \Celeven and pthreads concurrency is basic, based on thread fork/join in a function and a few locks, which is low-level and error prone;
-no high-level language concurrency features exist.
-Interestingly, almost a decade after publication of the \Celeven standard, neither gcc-8, clang-8 nor msvc-19 (most recent versions) support the \Celeven include @threads.h@, indicating little interest in the C concurrency approach.
-Finally, while the \Celeven standard does not state a concurrent threading-model, the historical association with pthreads suggests the threading model is kernel-level threading (1:1)~\cite{ThreadModel}.
+Within the \CFA framework, new control-flow features are created from scratch.
+ISO \Celeven defines only a subset of the \CFA extensions, where the overlapping features are concurrency~\cite[\S~7.26]{C11}.
+However, \Celeven concurrency is largely wrappers for a subset of the pthreads library~\cite{Butenhof97,Pthreads}.
+Furthermore, \Celeven and pthreads concurrency is simple, based on thread fork/join in a function and a few locks, which is low-level and error prone;
+no high-level language concurrency features are defined.
+Interestingly, almost a decade after publication of the \Celeven standard, neither gcc-8, clang-8 nor msvc-19 (most recent versions) support the \Celeven include @threads.h@, indicating little interest in the C11 concurrency approach.
+Finally, while the \Celeven standard does not state a concurrent threading-model, the historical association with pthreads suggests implementations would adopt kernel-level threading (1:1)~\cite{ThreadModel}.
 
 In contrast, there has been a renewed interest during the past decade in user-level (M:N, green) threading in old and new programming languages.
@@ -284,13 +288,13 @@
 
 A further effort over the past decade is the development of language memory-models to deal with the conflict between certain language features and compiler/hardware optimizations.
-This issue can be rephrased as some features are pervasive (language and runtime) and cannot be safely added via a library to prevent invalidation by sequential optimizations~\cite{Buhr95a,Boehm05}.
+This issue can be rephrased as: some language features are pervasive (language and runtime) and cannot be safely added via a library to prevent invalidation by sequential optimizations~\cite{Buhr95a,Boehm05}.
 The consequence is that a language must be cognizant of these features and provide sufficient tools to program around any safety issues.
 For example, C created the @volatile@ qualifier to provide correct execution for @setjmp@/@logjmp@ (concurrency came later).
-The simplest solution is to provide a handful of complex qualifiers and functions (e.g., @volatile@ and atomics) allowing programmers to write consistent/race-free programs, often in the sequentially-consistent memory-model~\cite{Boehm12}.
+The common solution is to provide a handful of complex qualifiers and functions (e.g., @volatile@ and atomics) allowing programmers to write consistent/race-free programs, often in the sequentially-consistent memory-model~\cite{Boehm12}.
 
 While having a sufficient memory-model allows sound libraries to be constructed, writing these libraries can quickly become awkward and error prone, and using these low-level libraries has the same issues.
 Essentially, using low-level explicit locks is the concurrent equivalent of assembler programming.
-Just as most assembler programming is replaced with programming in a high-level language, explicit locks can be replaced with high-level concurrency constructs in a programming language.
-The goal is to get the compiler to check for correct usage and follow any complex coding conventions implicitly.
+Just as most assembler programming is replaced with high-level programming, explicit locks can be replaced with high-level concurrency in a programming language.
+Then the goal is for the compiler to check for correct usage and follow any complex coding conventions implicitly.
 The drawback is that language constructs may preclude certain specialized techniques, therefore introducing inefficiency or inhibiting concurrency.
 For most concurrent programs, these drawbacks are insignificant in comparison to the speed of composition, and subsequent reliability and maintainability of the high-level concurrent program.
@@ -299,5 +303,5 @@
 As stated, this observation applies to non-concurrent forms of complex control-flow, like exception handling and coroutines.
 
-Adapting the programming language allows matching the control-flow model with the programming-language style, versus adapting to one general (sound) library/paradigm.
+Adapting the programming language to these features also allows matching the control-flow model with the programming-language style, versus adopting one general (sound) library/paradigm.
 For example, it is possible to provide exceptions, coroutines, monitors, and tasks as specialized types in an object-oriented language, integrating these constructs to allow leveraging the type-system (static type-checking) and all other object-oriented capabilities~\cite{uC++}.
 It is also possible to leverage call/return for blocking communication via new control structures, versus switching to alternative communication paradigms, like channels or message passing.
@@ -307,8 +311,17 @@
 however, the reverse is seldom true, i.e., given implicit concurrency, e.g., actors, it is virtually impossible to create explicit concurrency, e.g., blocking thread objects.}
 Finally, with extended language features and user-level threading it is possible to discretely fold locking and non-blocking I/O multiplexing into the language's I/O libraries, so threading implicitly dovetails with the I/O subsystem.
-
-\CFA embraces language extensions and user-level threading to provide advanced control-flow and concurrency.
-We attempt to show the \CFA extensions and runtime are demonstrably better than those proposed for \CC and other concurrent, imperative programming languages.
-The contributions of this work are:
+\CFA embraces language extensions and user-level threading to provide advanced control-flow (exception handling\footnote{
+\CFA exception handling will be presented in a separate paper.
+The key feature that dovetails with this paper is non-local exceptions allowing exceptions to be raised across stacks, with synchronous exceptions raised among coroutines and asynchronous exceptions raised among threads, similar to that in \uC~\cite[\S~5]{uC++}
+} and coroutines) and concurrency.
+
+Most augmented traditional (Fortran 18~\cite{Fortran18}, Cobol 14~\cite{Cobol14}, Ada 12~\cite{Ada12}, Java 11~\cite{Java11}) and new languages (Go~\cite{Go}, Rust~\cite{Rust}, and D~\cite{D}), except \CC, diverge from C with different syntax and semantics, only interoperate indirectly with C, and are not systems languages, for those with managed memory.
+As a result, there is a significant learning curve to move to these languages, and C legacy-code must be rewritten.
+While \CC, like \CFA, takes an evolutionary approach to extend C, \CC's constantly growing complex and interdependent features-set (e.g., objects, inheritance, templates, etc.) mean idiomatic \CC code is difficult to use from C, and C programmers must expend significant effort learning \CC.
+Hence, rewriting and retraining costs for these languages, even \CC, are prohibitive for companies with a large C software-base.
+\CFA with its orthogonal feature-set, its high-performance runtime, and direct access to all existing C libraries circumvents these problems.
+
+We present comparative examples so the reader can judge if the \CFA control-flow extensions are equivalent or better than those in or proposed for \Celeven, \CC and other concurrent, imperative programming languages, and perform experiments to show the \CFA runtime is competitive with other similar mechanisms.
+The detailed contributions of this work are:
 \begin{itemize}
 \item
@@ -615,7 +628,7 @@
 
 
-\section{Coroutines: A Stepping Stone}\label{coroutine}
-
-Advanced controlWhile the focus of this discussion is concurrency and parallelism, it is important to address coroutines, which are a significant building block of a concurrency system (but not concurrent among themselves).
+\section{Coroutines: Stepping Stone}
+\label{coroutine}
+
 Coroutines are generalized routines allowing execution to be temporarily suspended and later resumed.
 Hence, unlike a normal routine, a coroutine may not terminate when it returns to its caller, allowing it to be restarted with the values and execution location present at the point of suspension.
@@ -641,20 +654,43 @@
 \centering
 \newbox\myboxA
+% \begin{lrbox}{\myboxA}
+% \begin{cfa}[aboveskip=0pt,belowskip=0pt]
+% `int fn1, fn2, state = 1;`   // single global variables
+% int fib() {
+% 	int fn;
+% 	`switch ( state )` {  // explicit execution state
+% 	  case 1: fn = 0;  fn1 = fn;  state = 2;  break;
+% 	  case 2: fn = 1;  fn2 = fn1;  fn1 = fn;  state = 3;  break;
+% 	  case 3: fn = fn1 + fn2;  fn2 = fn1;  fn1 = fn;  break;
+% 	}
+% 	return fn;
+% }
+% int main() {
+% 
+% 	for ( int i = 0; i < 10; i += 1 ) {
+% 		printf( "%d\n", fib() );
+% 	}
+% }
+% \end{cfa}
+% \end{lrbox}
 \begin{lrbox}{\myboxA}
 \begin{cfa}[aboveskip=0pt,belowskip=0pt]
-`int f1, f2, state = 1;`   // single global variables
-int fib() {
-	int fn;
-	`switch ( state )` {  // explicit execution state
-	  case 1: fn = 0;  f1 = fn;  state = 2;  break;
-	  case 2: fn = 1;  f2 = f1;  f1 = fn;  state = 3;  break;
-	  case 3: fn = f1 + f2;  f2 = f1;  f1 = fn;  break;
-	}
-	return fn;
-}
+#define FIB_INIT { 0, 1 }
+typedef struct { int fn1, fn; } Fib;
+int fib( Fib * f ) {
+
+	int ret = f->fn1;
+	f->fn1 = f->fn;
+	f->fn = ret + f->fn;
+	return ret;
+}
+
+
+
 int main() {
-
+	Fib f1 = FIB_INIT, f2 = FIB_INIT;
 	for ( int i = 0; i < 10; i += 1 ) {
-		printf( "%d\n", fib() );
+		printf( "%d %d\n",
+				fib( &f1 ), fib( &f2 ) );
 	}
 }
@@ -665,84 +701,106 @@
 \begin{lrbox}{\myboxB}
 \begin{cfa}[aboveskip=0pt,belowskip=0pt]
-#define FIB_INIT `{ 0, 1 }`
-typedef struct { int f2, f1; } Fib;
-int fib( Fib * f ) {
-
-	int ret = f->f2;
-	int fn = f->f1 + f->f2;
-	f->f2 = f->f1; f->f1 = fn;
-
-	return ret;
-}
-int main() {
-	Fib f1 = FIB_INIT, f2 = FIB_INIT;
-	for ( int i = 0; i < 10; i += 1 ) {
-		printf( "%d %d\n", fib( &f1 ), fib( &f2 ) );
+`coroutine` Fib { int fn1; };
+void main( Fib & fib ) with( fib ) {
+	int fn;
+	[fn1, fn] = [0, 1];
+	for () {
+		`suspend();`
+		[fn1, fn] = [fn, fn1 + fn];
 	}
 }
-\end{cfa}
-\end{lrbox}
-
-\subfloat[3 States: global variables]{\label{f:GlobalVariables}\usebox\myboxA}
-\qquad
-\subfloat[1 State: external variables]{\label{f:ExternalState}\usebox\myboxB}
-\caption{C Fibonacci Implementations}
-\label{f:C-fibonacci}
-
-\bigskip
-
-\newbox\myboxA
-\begin{lrbox}{\myboxA}
-\begin{cfa}[aboveskip=0pt,belowskip=0pt]
-`coroutine` Fib { int fn; };
-void main( Fib & fib ) with( fib ) {
-	int f1, f2;
-	fn = 0;  f1 = fn;  `suspend()`;
-	fn = 1;  f2 = f1;  f1 = fn;  `suspend()`;
-	for ( ;; ) {
-		fn = f1 + f2;  f2 = f1;  f1 = fn;  `suspend()`;
-	}
-}
-int next( Fib & fib ) with( fib ) {
-	`resume( fib );`
-	return fn;
+int ?()( Fib & fib ) with( fib ) {
+	`resume( fib );`  return fn1;
 }
 int main() {
 	Fib f1, f2;
-	for ( int i = 1; i <= 10; i += 1 ) {
-		sout | next( f1 ) | next( f2 );
-	}
-}
+	for ( 10 ) {
+		sout | f1() | f2();
+}
+
+
 \end{cfa}
 \end{lrbox}
-\newbox\myboxB
-\begin{lrbox}{\myboxB}
-\begin{cfa}[aboveskip=0pt,belowskip=0pt]
-`coroutine` Fib { int ret; };
-void main( Fib & f ) with( fib ) {
-	int fn, f1 = 1, f2 = 0;
-	for ( ;; ) {
-		ret = f2;
-
-		fn = f1 + f2;  f2 = f1;  f1 = fn; `suspend();`
-	}
-}
-int next( Fib & fib ) with( fib ) {
-	`resume( fib );`
-	return ret;
-}
-
-
-
-
-
-
-\end{cfa}
+
+\newbox\myboxC
+\begin{lrbox}{\myboxC}
+\begin{python}[aboveskip=0pt,belowskip=0pt]
+
+def Fib():
+
+    fn1, fn = 0, 1
+    while True:
+        `yield fn1`
+        fn1, fn = fn, fn1 + fn
+
+
+// next prewritten
+
+
+f1 = Fib()
+f2 = Fib()
+for i in range( 10 ):
+	print( next( f1 ), next( f2 ) )
+
+
+
+\end{python}
 \end{lrbox}
-\subfloat[3 States, internal variables]{\label{f:Coroutine3States}\usebox\myboxA}
-\qquad\qquad
-\subfloat[1 State, internal variables]{\label{f:Coroutine1State}\usebox\myboxB}
-\caption{\CFA Coroutine Fibonacci Implementations}
-\label{f:cfa-fibonacci}
+
+\subfloat[C]{\label{f:GlobalVariables}\usebox\myboxA}
+\hspace{3pt}
+\vrule
+\hspace{3pt}
+\subfloat[\CFA]{\label{f:ExternalState}\usebox\myboxB}
+\hspace{3pt}
+\vrule
+\hspace{3pt}
+\subfloat[Python]{\label{f:ExternalState}\usebox\myboxC}
+\caption{Fibonacci Generator}
+\label{f:C-fibonacci}
+
+% \bigskip
+% 
+% \newbox\myboxA
+% \begin{lrbox}{\myboxA}
+% \begin{cfa}[aboveskip=0pt,belowskip=0pt]
+% `coroutine` Fib { int fn; };
+% void main( Fib & fib ) with( fib ) {
+% 	fn = 0;  int fn1 = fn; `suspend()`;
+% 	fn = 1;  int fn2 = fn1;  fn1 = fn; `suspend()`;
+% 	for () {
+% 		fn = fn1 + fn2; fn2 = fn1; fn1 = fn; `suspend()`; }
+% }
+% int next( Fib & fib ) with( fib ) { `resume( fib );` return fn; }
+% int main() {
+% 	Fib f1, f2;
+% 	for ( 10 )
+% 		sout | next( f1 ) | next( f2 );
+% }
+% \end{cfa}
+% \end{lrbox}
+% \newbox\myboxB
+% \begin{lrbox}{\myboxB}
+% \begin{python}[aboveskip=0pt,belowskip=0pt]
+% 
+% def Fibonacci():
+% 	fn = 0;	fn1 = fn; `yield fn`  # suspend
+% 	fn = 1; fn2 = fn1; fn1 = fn; `yield fn`
+% 	while True:
+% 		fn = fn1 + fn2; fn2 = fn1; fn1 = fn; `yield fn`
+% 
+% 
+% f1 = Fibonacci()
+% f2 = Fibonacci()
+% for i in range( 10 ):
+% 	print( `next( f1 )`, `next( f2 )` ) # resume
+% 
+% \end{python}
+% \end{lrbox}
+% \subfloat[\CFA]{\label{f:Coroutine3States}\usebox\myboxA}
+% \qquad
+% \subfloat[Python]{\label{f:Coroutine1State}\usebox\myboxB}
+% \caption{Fibonacci input coroutine, 3 states, internal variables}
+% \label{f:cfa-fibonacci}
 \end{figure}
 
@@ -784,34 +842,27 @@
 \begin{lrbox}{\myboxA}
 \begin{cfa}[aboveskip=0pt,belowskip=0pt]
-`coroutine` Format {
-	char ch;   // used for communication
-	int g, b;  // global because used in destructor
+`coroutine` Fmt {
+	char ch;   // communication variables
+	int g, b;   // needed in destructor
 };
-void main( Format & fmt ) with( fmt ) {
-	for ( ;; ) {
-		for ( g = 0; g < 5; g += 1 ) {      // group
-			for ( b = 0; b < 4; b += 1 ) { // block
+void main( Fmt & fmt ) with( fmt ) {
+	for () {
+		for ( g = 0; g < 5; g += 1 ) { // groups
+			for ( b = 0; b < 4; b += 1 ) { // blocks
 				`suspend();`
-				sout | ch;              // separator
-			}
-			sout | "  ";               // separator
-		}
-		sout | nl;
-	}
-}
-void ?{}( Format & fmt ) { `resume( fmt );` }
-void ^?{}( Format & fmt ) with( fmt ) {
-	if ( g != 0 || b != 0 ) sout | nl;
-}
-void format( Format & fmt ) {
-	`resume( fmt );`
-}
+				sout | ch; } // print character
+			sout | "  "; } // block separator
+		sout | nl; }  // group separator
+}
+void ?{}( Fmt & fmt ) { `resume( fmt );` } // prime
+void ^?{}( Fmt & fmt ) with( fmt ) { // destructor
+	if ( g != 0 || b != 0 )	// special case
+		sout | nl; }
+void send( Fmt & fmt, char c ) { fmt.ch = c; `resume( fmt )`; }
 int main() {
-	Format fmt;
-	eof: for ( ;; ) {
-		sin | fmt.ch;
-	  if ( eof( sin ) ) break eof;
-		format( fmt );
-	}
+	Fmt fmt;
+ 	sout | nlOff;	// turn off auto newline
+	for ( 41 )
+		send( fmt, 'a' );
 }
 \end{cfa}
@@ -820,42 +871,35 @@
 \newbox\myboxB
 \begin{lrbox}{\myboxB}
-\begin{cfa}[aboveskip=0pt,belowskip=0pt]
-struct Format {
-	char ch;
-	int g, b;
-};
-void format( struct Format * fmt ) {
-	if ( fmt->ch != -1 ) {      // not EOF ?
-		printf( "%c", fmt->ch );
-		fmt->b += 1;
-		if ( fmt->b == 4 ) {  // block
-			printf( "  " );      // separator
-			fmt->b = 0;
-			fmt->g += 1;
-		}
-		if ( fmt->g == 5 ) {  // group
-			printf( "\n" );     // separator
-			fmt->g = 0;
-		}
-	} else {
-		if ( fmt->g != 0 || fmt->b != 0 ) printf( "\n" );
-	}
-}
-int main() {
-	struct Format fmt = { 0, 0, 0 };
-	for ( ;; ) {
-		scanf( "%c", &fmt.ch );
-	  if ( feof( stdin ) ) break;
-		format( &fmt );
-	}
-	fmt.ch = -1;
-	format( &fmt );
-}
-\end{cfa}
+\begin{python}[aboveskip=0pt,belowskip=0pt]
+
+
+
+def Fmt():
+	try:
+		while True:
+			for g in range( 5 ):
+				for b in range( 4 ):
+
+					print( `(yield)`, end='' )
+				print( '  ', end='' )
+			print()
+
+
+	except GeneratorExit:
+		if g != 0 | b != 0:
+			print()
+
+
+fmt = Fmt()
+`next( fmt )`			 # prime
+for i in range( 41 ):
+	`fmt.send( 'a' );`	# send to yield
+
+\end{python}
 \end{lrbox}
-\subfloat[\CFA Coroutine]{\label{f:CFAFmt}\usebox\myboxA}
+\subfloat[\CFA]{\label{f:CFAFmt}\usebox\myboxA}
 \qquad
-\subfloat[C Linearized]{\label{f:CFmt}\usebox\myboxB}
-\caption{Formatting text into lines of 5 blocks of 4 characters.}
+\subfloat[Python]{\label{f:CFmt}\usebox\myboxB}
+\caption{Output formatting text}
 \label{f:fmt-line}
 \end{figure}
@@ -878,5 +922,5 @@
 void main( Prod & prod ) with( prod ) {
 	// 1st resume starts here
-	for ( int i = 0; i < N; i += 1 ) {
+	for ( i; N ) {
 		int p1 = random( 100 ), p2 = random( 100 );
 		sout | p1 | " " | p2;
@@ -894,5 +938,5 @@
 }
 void start( Prod & prod, int N, Cons &c ) {
-	&prod.c = &c;
+	&prod.c = &c; // reassignable reference
 	prod.[N, receipt] = [N, 0];
 	`resume( prod );`
@@ -909,8 +953,8 @@
 	Prod & p;
 	int p1, p2, status;
-	_Bool done;
+	bool done;
 };
 void ?{}( Cons & cons, Prod & p ) {
-	&cons.p = &p;
+	&cons.p = &p; // reassignable reference
 	cons.[status, done ] = [0, false];
 }
@@ -969,4 +1013,59 @@
 The program main restarts after the resume in @start@.
 @start@ returns and the program main terminates.
+
+One \emph{killer} application for a coroutine is device drivers, which at one time caused 70\%-85\% of failures in Windows/Linux~\cite{Swift05}.
+Many device drivers are a finite state-machine parsing a protocol, e.g.:
+\begin{tabbing}
+\ldots STX \= \ldots message \ldots \= ESC \= ETX \= \ldots message \ldots  \= ETX \= 2-byte crc \= \ldots	\kill
+\ldots STX \> \ldots message \ldots \> ESC \> ETX \> \ldots message \ldots  \> ETX \> 2-byte crc \> \ldots
+\end{tabbing}
+where a network message begins with the control character STX and ends with an ETX, followed by a 2-byte cyclic-redundancy check.
+Control characters may appear in a message if preceded by an ESC.
+Because FSMs can be complex and occur frequently in important domains, direct support of the coroutine is crucial in a systems programminglanguage.
+
+\begin{figure}
+\begin{cfa}
+enum Status { CONT, MSG, ESTX, ELNTH, ECRC };
+`coroutine` Driver {
+	Status status;
+	char * msg, byte;
+};
+void ?{}( Driver & d, char * m ) { d.msg = m; }		$\C[3.0in]{// constructor}$
+Status next( Driver & d, char b ) with( d ) {		$\C{// 'with' opens scope}$
+	byte = b; `resume( d );` return status;
+}
+void main( Driver & d ) with( d ) {
+	enum { STX = '\002', ESC = '\033', ETX = '\003', MaxMsg = 64 };
+	unsigned short int crc;							$\C{// error checking}$
+  msg: for () {										$\C{// parse message}$
+		status = CONT;
+		unsigned int lnth = 0, sum = 0;
+		while ( byte != STX ) `suspend();`
+	  emsg: for () {
+			`suspend();`							$\C{// process byte}$
+			choose ( byte ) {						$\C{// switch with default break}$
+			  case STX:
+				status = ESTX; `suspend();` continue msg;
+			  case ETX:
+				break emsg;
+			  case ESC:
+				suspend();
+			} // choose
+			if ( lnth >= MaxMsg ) {					$\C{// buffer full ?}$
+				status = ELNTH; `suspend();` continue msg; }
+			msg[lnth++] = byte;
+			sum += byte;
+		} // for
+		msg[lnth] = '\0';							$\C{// terminate string}\CRT$
+		`suspend();`
+		crc = (unsigned char)byte << 8;	// prevent sign extension for signed char
+		`suspend();`
+		status = (crc | (unsigned char)byte) == sum ? MSG : ECRC;
+		`suspend();`
+	} // for
+}
+\end{cfa}
+\caption{Device driver for simple communication protocol}
+\end{figure}
 
 
Index: doc/papers/concurrency/examples/C++Cor-ts.cpp
===================================================================
--- doc/papers/concurrency/examples/C++Cor-ts.cpp	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/C++Cor-ts.cpp	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,42 @@
+
+
+auto result = co_await expression;
+
+//   |  |
+//   |  |
+//  \    /
+//   \  /
+//    \/
+
+auto&& __a = expression;
+if (!__a.await_ready()) {
+	__a.await_suspend(coroutine-handle)
+	// ...suspend/resume point...
+}
+auto result = __a.await_resume();
+
+//==================================================
+
+co_yield i;
+
+//   |  |
+//   |  |
+//  \    /
+//   \  /
+//    \/
+
+co_await __promise.yield_value(i);
+
+//==================================================
+
+... coroutine() {
+	__coroutine_context* __context = new __coroutine_context{};
+	__return = __context->_promise.get_return_object();
+	co_await   __context->_promise.initial_suspend();
+
+	...
+
+__final_suspend_label:
+	co_await __context->promise.final_suspend();
+	delete __context;
+}
Index: doc/papers/concurrency/examples/Fib.c
===================================================================
--- doc/papers/concurrency/examples/Fib.c	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Fib.c	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,23 @@
+#include <stdio.h>
+
+#define FIB_INIT { 0, 1 }
+typedef struct { int fn1, fn; } Fib;
+int fib( Fib * f ) {
+
+	int ret = f->fn1;
+	f->fn1 = f->fn;
+	f->fn = ret + f->fn;
+
+	return ret;
+}
+int main() {
+	Fib f1 = FIB_INIT, f2 = FIB_INIT;
+	for ( int i = 0; i < 10; i += 1 ) {
+		printf( "%d %d\n", fib( &f1 ), fib( &f2 ) );
+	}
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "gcc Fib.c" //
+// End: //
Index: doc/papers/concurrency/examples/Fib.cfa
===================================================================
--- doc/papers/concurrency/examples/Fib.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Fib.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,72 @@
+#include <thread.hfa>
+#include <fstream.hfa>
+
+int fn1, fn2, state = 1;
+int fib_gvar() {
+	int fn;
+	choose ( state ) {
+	  case 1: fn = 0;  fn1 = fn;  state = 2;
+	  case 2: fn = 1;  fn2 = fn1;  fn1 = fn;  state = 3;
+	  case 3: fn = fn1 + fn2;  fn2 = fn1;  fn1 = fn;
+	}
+	return fn;
+}
+
+#define FIB_INIT { 0, 1 }
+typedef struct { int fn1, fn2; } Fib;
+int fib_state( Fib & f ) with( f ) {
+	int ret = fn2;
+	int fn = fn1 + fn2;
+	fn2 = fn1; fn1 = fn;
+	return ret;
+}
+
+coroutine Fib1 { int fn; };						// used for communication
+void main( Fib1 & fib ) with( fib ) {			// called on first resume
+	fn = 0;  int fn1 = fn; suspend();
+	fn = 1;  int fn2 = fn1;  fn1 = fn; suspend();
+	for () {
+		fn = fn1 + fn2;  fn2 = fn1;  fn1 = fn; suspend();
+	}
+}
+int next( Fib1 & fib ) with( fib ) { resume( fib ); return fn; }
+
+coroutine Fib2 { int ret; };					// used for communication
+void main( Fib2 & fib ) with( fib ) {			// called on first resume
+	int fn, fn1 = 1, fn2 = 0;					// precompute first two states
+	for () {
+		ret = fn2;
+		fn = fn1 + fn2;  fn2 = fn1;  fn1 = fn;	// general case
+		suspend();								// restart last resume
+	}
+}
+int next( Fib2 & fib ) with( fib ) {
+	resume( fib );								// restart last suspend
+	return ret;
+}
+
+int main() {
+	for ( 10 )
+		sout | fib_gvar();
+	sout | nl;
+
+	Fib f1 = FIB_INIT, f2 = FIB_INIT;
+	for ( 10 )
+		sout | fib_state( f1 ) | fib_state( f2 );
+	sout | nl;
+
+	Fib1 f1, f2;
+	for ( 10 )
+		sout | next( f1 ) | next( f2 );
+	sout | nl;
+
+	Fib2 f1, f2;
+	for ( 10 )
+		sout | next( (Fib2 &)f1 ) | next( (Fib2 &)f2 );
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// fill-column: 120 //
+// compile-command: "cfa Fib.cfa" //
+// End: //
Index: doc/papers/concurrency/examples/Fib.cpp
===================================================================
--- doc/papers/concurrency/examples/Fib.cpp	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Fib.cpp	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,120 @@
+#include <algorithm>
+#include <iostream>
+#include <iterator>
+#include <vector>
+
+#include <experimental/coroutine>
+
+template<typename T>
+struct cor_range {
+	struct promise_type {
+		T _value;
+
+		cor_range get_return_object() {
+			return cor_range(std::experimental::coroutine_handle<promise_type>::from_promise(*this));
+		}
+
+		auto initial_suspend() { return std::experimental::suspend_always(); }
+		auto final_suspend()   { return std::experimental::suspend_always(); }
+
+		void return_value(T value) {
+			_value = value;
+		}
+
+		auto yield_value(T value) {
+			_value = value;
+			return std::experimental::suspend_always();
+		}
+
+		void unhandled_exception() {}
+	};
+
+	std::experimental::coroutine_handle<promise_type> _coroutine = nullptr;
+
+	explicit cor_range(std::experimental::coroutine_handle<promise_type> coroutine)
+		: _coroutine(coroutine)
+	{}
+
+	~cor_range() {
+		if(_coroutine) { _coroutine.destroy(); }
+	}
+
+	cor_range() = default;
+	cor_range(cor_range const &) = delete;
+	cor_range& operator=(cor_range const &) = delete;
+
+	cor_range(cor_range&& other) {
+		std::swap(_coroutine, other._coroutine);
+	}
+
+	cor_range& operator=(cor_range&& other) {
+		if(&other != this) {
+			_coroutine = other._coroutine;
+			other._coroutine = nullptr;
+		}
+		return *this;
+	}
+
+	T next() {
+		_coroutine.resume();
+		return _coroutine.promise()._value;
+	}
+
+	struct iterator : std::iterator<std::input_iterator_tag, T> {
+		std::experimental::coroutine_handle<promise_type> _coroutine = nullptr;
+
+		iterator() = default;
+		explicit iterator(std::experimental::coroutine_handle<promise_type> coroutine)
+			: _coroutine(coroutine)
+		{}
+
+		iterator& operator++() {
+			_coroutine.resume();
+			return *this;
+		}
+
+		T const & operator*() const {
+			return _coroutine.promise()._value;
+		}
+	};
+
+	iterator begin() {
+		if(_coroutine) {
+			_coroutine.resume();
+			if(_coroutine.done()) { return end(); }
+		}
+
+		return iterator{ _coroutine };
+	}
+
+	iterator end() { return iterator{}; }
+};
+
+cor_range<int> fib() {
+	int fn;
+	fn = 0; int fn1 = fn; co_yield fn;
+	fn = 1; int fn2 = fn1; fn1 = fn; co_yield fn;
+	for(;;) {
+		fn = fn1 + fn2; fn2 = fn1; fn1 = fn; co_yield fn;
+	}
+}
+
+int main() {
+	{
+		auto f1 = fib();
+		auto f2 = fib();
+		for(int i = 0; i < 10; i++) {
+			std::cout << f1.next() << " " << f2.next() << std::endl;
+		}
+	}
+
+	{
+		auto f1 = fib();
+		std::vector<int> fibs;
+		std::copy_n(f1.begin(), 10, std::back_inserter(fibs));
+
+		for(auto i : fibs) {
+			std::cout << i << std::endl;
+		}
+	}
+}
Index: doc/papers/concurrency/examples/Fib.py
===================================================================
--- doc/papers/concurrency/examples/Fib.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Fib.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,17 @@
+def Fib():
+	fn = 0;	fn1 = fn; yield fn  # suspend
+	fn = 1; fn2 = fn1; fn1 = fn; yield fn
+	while True:
+		fn = fn1 + fn2; fn2 = fn1; fn1 = fn; yield fn
+
+
+
+f1 = Fib()
+f2 = Fib()
+for i in range( 10 ):
+	print( next( f1 ), next( f2 ) )  # resume
+
+# Local Variables: #
+# tab-width: 4 #
+# compile-command: "python3.5 Fib.py" #
+# End: #
Index: doc/papers/concurrency/examples/Fib.sim
===================================================================
--- doc/papers/concurrency/examples/Fib.sim	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Fib.sim	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,47 @@
+BEGIN
+	CLASS Fibonacci;
+		HIDDEN fn, main;					! private members;
+	BEGIN
+		INTEGER fn;							! communication;
+
+		PROCEDURE main;						! mimic uC++ coroutine main;
+		BEGIN
+			INTEGER fn1, fn2;
+
+			fn := 0; fn1 := fn;
+			Detach;							! suspend();
+			fn := 1; fn2 := fn1; fn1 := fn;
+			Detach;							! suspend();
+			WHILE TRUE DO BEGIN
+				fn := fn1 + fn2; fn2 := fn1; fn1 := fn;
+				Detach;						! suspend();
+			END;
+		END;
+
+		INTEGER PROCEDURE next;
+		BEGIN
+			Call( THIS Fibonacci );			! resume();
+			next := fn;
+		END;
+		! Fibonacci constructor code;
+		Detach;								! return to declaration;
+		main;								! call main as last line of constructor;
+	END Fibonacci;
+	! program main equivalent;
+	REF(Fibonacci) f1, f2;					! objects are references;
+	INTEGER i;
+
+	f1 :- NEW Fibonacci;
+	f2 :- NEW Fibonacci;
+	FOR i := 1 STEP 1 UNTIL 10 DO BEGIN
+		OutInt( f1.next, 3 );
+		OutText( " " );
+		OutInt( f2.next, 3 );
+		OutImage;
+	END
+END;
+
+! Local Variables: ;
+! tab-width: 4 ;
+! compile-command: "cim Fib.sim" ;
+! End: ;
Index: doc/papers/concurrency/examples/Fib2.cfa
===================================================================
--- doc/papers/concurrency/examples/Fib2.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Fib2.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,45 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// fibonacci_1.cfa -- 1-state finite-state machine: precomputed first two states returning f(n - 1)
+//
+// Author           : Peter A. Buhr
+// Created On       : Thu Apr 26 23:20:08 2018
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Fri Mar 22 17:26:41 2019
+// Update Count     : 28
+// 
+
+#include <fstream.hfa>
+#include <coroutine.hfa>
+
+coroutine Fibonacci { int fn1; };						// used for communication
+
+void main( Fibonacci & fib ) with( fib ) {				// called on first resume
+	int fn;
+	[fn1, fn] = [0, 1];									// precompute first two states
+	for () {
+		suspend();										// restart last resume
+		[fn1, fn] = [fn, fn1 + fn];						// general case
+	} // for
+}
+
+int ?()( Fibonacci & fib ) with( fib ) {				// function call operator
+	resume( fib );										// restart last suspend
+	return fn1;
+}
+
+int main() {
+	Fibonacci f1, f2;
+	for ( 10 ) {										// print N Fibonacci values
+		sout | f1() | f2();
+	} // for
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa fibonacci_1.cfa" //
+// End: //
Index: doc/papers/concurrency/examples/Fib2.cpp
===================================================================
--- doc/papers/concurrency/examples/Fib2.cpp	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Fib2.cpp	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,121 @@
+#include <algorithm>
+#include <iostream>
+#include <iterator>
+#include <vector>
+
+#include <experimental/coroutine>
+
+template<typename T>
+struct cor_range {
+	struct promise_type {
+		T _value;
+
+		cor_range get_return_object() {
+			return cor_range(std::experimental::coroutine_handle<promise_type>::from_promise(*this));
+		}
+
+		auto initial_suspend() { return std::experimental::suspend_always(); }
+		auto final_suspend()   { return std::experimental::suspend_always(); }
+
+		void return_value(T value) {
+			_value = value;
+		}
+
+		auto yield_value(T value) {
+			_value = value;
+			return std::experimental::suspend_always();
+		}
+
+		void unhandled_exception() {}
+	};
+
+	std::experimental::coroutine_handle<promise_type> _coroutine = nullptr;
+
+	explicit cor_range(std::experimental::coroutine_handle<promise_type> coroutine)
+		: _coroutine(coroutine)
+	{}
+
+	~cor_range() {
+		if(_coroutine) { _coroutine.destroy(); }
+	}
+
+	cor_range() = default;
+	cor_range(cor_range const &) = delete;
+	cor_range& operator=(cor_range const &) = delete;
+
+	cor_range(cor_range&& other) {
+		std::swap(_coroutine, other._coroutine);
+	}
+
+	cor_range& operator=(cor_range&& other) {
+		if(&other != this) {
+			_coroutine = other._coroutine;
+			other._coroutine = nullptr;
+		}
+		return *this;
+	}
+
+	T next() {
+		_coroutine.resume();
+		return _coroutine.promise()._value;
+	}
+
+	struct iterator : std::iterator<std::input_iterator_tag, T> {
+		std::experimental::coroutine_handle<promise_type> _coroutine = nullptr;
+
+		iterator() = default;
+		explicit iterator(std::experimental::coroutine_handle<promise_type> coroutine)
+			: _coroutine(coroutine)
+		{}
+
+		iterator& operator++() {
+			_coroutine.resume();
+			return *this;
+		}
+
+		T const & operator*() const {
+			return _coroutine.promise()._value;
+		}
+	};
+
+	iterator begin() {
+		if(_coroutine) {
+			_coroutine.resume();
+			if(_coroutine.done()) { return end(); }
+		}
+
+		return iterator{ _coroutine };
+	}
+
+	iterator end() { return iterator{}; }
+};
+
+cor_range<int> fib() {
+	int fn1 = 0, fn = 1;
+	for(;;) {
+		co_yield fn1;
+		int temp = fn1;
+		fn1 = fn;
+		fn = temp + fn;
+	}
+}
+
+int main() {
+	{
+		auto f1 = fib();
+		auto f2 = fib();
+		for(int i = 0; i < 10; i++) {
+			std::cout << f1.next() << " " << f2.next() << std::endl;
+		}
+	}
+
+	{
+		auto f1 = fib();
+		std::vector<int> fibs;
+		std::copy_n(f1.begin(), 10, std::back_inserter(fibs));
+
+		for(auto i : fibs) {
+			std::cout << i << std::endl;
+		}
+	}
+}
Index: doc/papers/concurrency/examples/Fib2.py
===================================================================
--- doc/papers/concurrency/examples/Fib2.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Fib2.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,15 @@
+def Fib():
+    fn1, fn = 0, 1
+    while True:
+        yield fn1
+        fn1, fn = fn, fn1 + fn
+
+f1 = Fib()
+f2 = Fib()
+for i in range( 10 ):
+	print( next( f1 ), next( f2 ) )  # resume
+
+# Local Variables: #
+# tab-width: 4 #
+# compile-command: "python3.5 Fib2.py" #
+# End: #
Index: doc/papers/concurrency/examples/FibRefactor.py
===================================================================
--- doc/papers/concurrency/examples/FibRefactor.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/FibRefactor.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,25 @@
+def Fib():
+	def Refactor():
+		nonlocal fn, fn1
+		fn = 0;	fn1 = fn
+		yield fn						# suspend
+
+	def Refactor2():
+		nonlocal fn, fn1, fn2
+		fn = 1; fn2 = fn1; fn1 = fn
+		yield fn						# suspend
+
+	yield from Refactor()
+	yield from Refactor2()
+	while True:
+		fn = fn1 + fn2; fn2 = fn1; fn1 = fn; yield fn
+
+f1 = Fib()
+f2 = Fib()
+for i in range( 10 ):
+	print( next( f1 ), next( f2 ) )		# resume
+
+# Local Variables: #
+# tab-width: 4 #
+# compile-command: "python3.5 FibRefactor.py" #
+# End: #
Index: doc/papers/concurrency/examples/Fmt.sim
===================================================================
--- doc/papers/concurrency/examples/Fmt.sim	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Fmt.sim	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,46 @@
+BEGIN
+	CLASS FmtLines;
+		HIDDEN ch, main;					! private members;
+	BEGIN
+		CHARACTER ch;						! communication;
+
+		PROCEDURE main;						! mimic uC++ coroutine main;
+		BEGIN
+			INTEGER g, b;
+
+			WHILE TRUE DO BEGIN				! for as many characters;
+				FOR g := 1 STEP 1 UNTIL 5 DO BEGIN		! groups of 5;
+					FOR b := 1 STEP 1 UNTIL 4 DO BEGIN	! blocks of 4;
+						OutChar( ch );
+						Detach;				! suspend();
+					END;
+					OutText( "  " );
+				END;
+				OutImage;					! start newline;
+			END;
+		END;
+
+		PROCEDURE prt( chp );
+			CHARACTER chp;
+		BEGIN
+			ch := chp;						! communication;
+			Call( THIS FmtLines );			! resume();
+		END;
+		! FmtLines constructor code;
+		Detach;								! return to declaration;
+		main;								! call main as last line of constructor;
+	END FmtLines;
+	! program main equivalent;
+	REF(FmtLines) fmt;						! objects are references;
+	INTEGER i;
+
+	fmt :- NEW FmtLines;
+	FOR i := Rank( ' ' ) STEP 1 UNTIL Rank( 'z' ) DO BEGIN
+		fmt.prt( Char( i ) );
+	END
+END;
+
+! Local Variables: ;
+! tab-width: 4 ;
+! compile-command: "cim Fmt.sim" ;
+! End: ;
Index: doc/papers/concurrency/examples/Format.cc
===================================================================
--- doc/papers/concurrency/examples/Format.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Format.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,34 @@
+_Coroutine Format {
+	char ch; // used for communication
+	int g, b; // global because used in destructor
+	void main() {
+		for ( ;; ) { // for as many characters
+			for ( g = 0; g < 5; g += 1 ) { // groups of 5 blocks
+				for ( b = 0; b < 4; b += 1 ) { // blocks of 4 characters
+//					for ( ;; ) { // for newline characters
+						suspend();
+//						if ( ch != '\n' ) break; // ignore newline
+//					}
+//					cout << ch; // print character
+				}
+//				cout << " "; // print block separator
+			}
+//			cout << endl; // print group separator
+		}
+	}
+  public:
+	Format() { resume(); } // start coroutine
+//	~Format() { if ( g != 0 | | b != 0 ) cout << endl; }
+	void prt( char ch ) { Format::ch = ch; resume(); }
+};
+
+int main() {
+	Format fmt;
+	for ( long int i = 0; i < 1000000000; i += 1 )
+		fmt.prt( 'a' );
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "u++-work -O2 -nodebubg Format.cc" //
+// End: //
Index: doc/papers/concurrency/examples/Format.cfa
===================================================================
--- doc/papers/concurrency/examples/Format.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Format.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,84 @@
+#if 1
+#include <fstream.hfa>
+#include <coroutine.hfa>
+
+coroutine Fmt {
+	char ch;								// communication variables
+	int g, b;								// needed in destructor
+};
+void main( Fmt & fmt ) with( fmt ) {
+	for () {								// for as many characters
+		for ( g = 0; g < 5; g += 1 ) {		// groups of 5 blocks
+			for ( b = 0; b < 4; b += 1 ) {	// blocks of 4 characters
+//				do {
+					suspend();
+//				} while ( ch == '\n' || ch == '\t' );
+				sout | ch;					// print character
+			}
+			sout | "  ";					// block separator
+		}
+		sout | nl;							// group separator
+	}
+}
+void ?{}( Fmt & fmt ) { resume( fmt ); } // prime (start) coroutine
+void ^?{}( Fmt & fmt ) with( fmt ) { // destructor
+	if ( g != 0 || b != 0 )	// special case
+		sout | nl; }
+void send( Fmt & fmt, char c ) { fmt.ch = c; resume( fmt ); }
+int main() {
+	Fmt fmt;
+ 	sout | nlOff;							// turn off auto newline
+	for ( 41 )
+		send( fmt, 'a' );
+  // 	sout | nlOff;							// turn off auto newline
+  // eof: for () {								// read until end of file
+  // 		sin | fmt.ch;						// read one character
+  // 	  if ( eof( sin ) ) break eof;			// eof ?
+  // 		format( fmt );						// push character for formatting
+  // 	}
+}
+#else
+
+#include <stdio.h>
+
+struct Format {
+	char ch;								// used for communication
+	int g, b;								// global because used in destructor
+};
+
+void format( struct Format * fmt ) {
+	if ( fmt->ch != -1 ) { // not EOF ?
+//		if ( fmt->ch == '\n' || fmt->ch == '\t' ) return;
+//		printf( "%c %d %d", fmt->ch, fmt->g, fmt->b );		// character
+		printf( "%c", fmt->ch );		// character
+		fmt->b += 1;
+		if ( fmt->b == 4 ) {	// block ?
+			printf( "  " ); // separator
+			fmt->b = 0;
+			fmt->g += 1;
+		}
+		if ( fmt->g == 5 ) {	// group ?
+			printf( "\n" ); // separator
+			fmt->g = 0;
+		}
+	} else {
+		if ( fmt->g != 0 || fmt->b != 0 ) printf( "\n" );
+	}
+}
+int main() {
+	struct Format fmt = { 0, 0, 0 };
+	for ( ;; ) {
+		scanf( "%c", &fmt.ch );
+	  if ( feof( stdin ) ) break;
+		format( &fmt );
+	}
+	fmt.ch = -1;
+	format( &fmt );
+}
+#endif
+
+// Local Variables: //
+// tab-width: 4 //
+// fill-column: 120 //
+// compile-command: "cfa Format.cfa" //
+// End: //
Index: doc/papers/concurrency/examples/Format.cpp
===================================================================
--- doc/papers/concurrency/examples/Format.cpp	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Format.cpp	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,96 @@
+#include <iostream>
+#include <experimental/coroutine>
+
+struct fmt_cor {
+	struct promise_type {
+		char _value;
+
+		fmt_cor get_return_object() {
+			return fmt_cor(std::experimental::coroutine_handle<promise_type>::from_promise(*this));
+		}
+
+		auto initial_suspend() { return std::experimental::suspend_never(); }
+		auto final_suspend()   { return std::experimental::suspend_always(); }
+
+		void return_void() {}
+		void unhandled_exception() {}
+	};
+
+	struct get {
+		promise_type * _promise = nullptr;
+
+		bool await_ready() noexcept {
+			return false;
+		}
+
+		void await_suspend(std::experimental::coroutine_handle<promise_type> _coroutine) noexcept {
+			_promise = &_coroutine.promise();
+		}
+		char await_resume() noexcept {
+			assert(_promise);
+			return _promise->_value;
+		}
+	};
+
+	std::experimental::coroutine_handle<promise_type> _coroutine = nullptr;
+
+	explicit fmt_cor(std::experimental::coroutine_handle<promise_type> coroutine)
+		: _coroutine(coroutine)
+	{}
+
+	~fmt_cor() {
+		if(_coroutine) {
+			_coroutine.destroy();
+
+		}
+	}
+
+	fmt_cor() = default;
+	fmt_cor(fmt_cor const &) = delete;
+	fmt_cor& operator=(fmt_cor const &) = delete;
+
+	fmt_cor(fmt_cor&& other) {
+		std::swap(_coroutine, other._coroutine);
+	}
+
+	fmt_cor& operator=(fmt_cor&& other) {
+		if(&other != this) {
+			_coroutine = other._coroutine;
+			other._coroutine = nullptr;
+		}
+		return *this;
+	}
+
+	void send(char a) {
+		_coroutine.promise()._value = a;
+		_coroutine.resume();
+	}
+};
+
+fmt_cor Fmt() {
+	struct locals {
+		int g, b;
+
+		~locals() {
+			if (g != 0 | b != 0) {
+				std::cout << "\n";
+			}
+		}
+	} l;
+	for(;;) {
+		for(l.g = 0; l.g < 5; l.g++) {
+			for(l.b = 0; l.b < 4; l.b++) {
+				std::cout << co_await fmt_cor::get();
+			}
+			std::cout << "  ";
+		}
+		std::cout << std::endl;
+	}
+}
+
+int main() {
+	auto fmt = Fmt();
+	for(int i = 0; i < 41; i++) {
+		fmt.send('a');
+	}
+}
Index: doc/papers/concurrency/examples/Format.py
===================================================================
--- doc/papers/concurrency/examples/Format.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Format.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,21 @@
+def Format():
+	try:
+		while True:
+			for g in range( 5 ): 	# groups of 5 blocks
+				for b in range( 4 ): # blocks of 4 characters
+					print( (yield), end='' ) # receive from send
+				print( '  ', end='' ) # block separator
+			print()					# group separator
+	except GeneratorExit:			# destructor
+		if g != 0 | b != 0:			# special case
+			print()
+
+fmt = Format()
+next( fmt )							# prime generator
+for i in range( 41 ):
+	fmt.send( 'a' );				# send to yield
+
+# Local Variables: #
+# tab-width: 4 #
+# compile-command: "python3.5 Format.py" #
+# End: #
Index: doc/papers/concurrency/examples/Pingpong.cc
===================================================================
--- doc/papers/concurrency/examples/Pingpong.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Pingpong.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,31 @@
+#include <iostream>
+using namespace std;
+
+_Coroutine PingPong {
+	const char * name;
+	const unsigned int N;
+	PingPong * part;
+	void main() { // ping’s starter ::main, pong’s starter ping
+		for ( unsigned int i = 0; i < N; i += 1 ) {
+			cout << name << endl;
+			part->cycle();
+		}
+	}
+  public:
+	PingPong( const char * name, unsigned int N, PingPong & part )
+		: name( name ), N( N ), part( & part ) {}
+	PingPong( const char * name, unsigned int N ) : name( name ), N( N ) {}
+	void partner( PingPong & part ) { PingPong::part = &part; }
+	void cycle() { resume(); }
+};
+int main() {
+	enum { N = 10 };
+	PingPong ping( "ping", N ), pong( "pong", N, ping );
+	ping.partner( pong );
+	ping.cycle();
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "u++-work -O2 -nodebug Pingpong.cc" //
+// End: //
Index: doc/papers/concurrency/examples/Pingpong.cfa
===================================================================
--- doc/papers/concurrency/examples/Pingpong.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Pingpong.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,38 @@
+#include <coroutine.hfa>
+#include <fstream.hfa>
+
+coroutine PingPong {
+	const char * name;
+	unsigned int N;
+	PingPong & part;
+};
+
+void ?{}( PingPong & this, const char * name, unsigned int N, PingPong & part ) {
+	this.[name, N] = [name, N];  &this.part = &part;
+}
+void ?{}( PingPong & this, const char * name, unsigned int N ) {
+	this{ name, N, *0p };								// call first constructor
+}
+void cycle( PingPong & pingpong ) {
+	resume( pingpong );
+}
+void partner( PingPong & this, PingPong & part ) {
+	&this.part = &part;
+	resume( this );
+}
+void main( PingPong & pingpong ) with(pingpong) {		// ping's starter ::main, pong's starter ping
+	for ( N ) {											// N ping-pongs
+		sout | name;
+		cycle( part );
+	} // for
+}
+int main() {
+	enum { N = 5 };
+	PingPong ping = { "ping", N }, pong = { "pong", N, ping };
+	partner( ping, pong );
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa Pingpong.cfa" //
+// End: //
Index: doc/papers/concurrency/examples/Pingpong.py
===================================================================
--- doc/papers/concurrency/examples/Pingpong.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Pingpong.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,32 @@
+def PingPong( name, N ):
+	partner = (yield)           # get partner
+	yield                       # resume scheduler
+	for i in range( N ):
+		print( name )
+		yield partner           # execute next
+	print( "end", name )
+
+def Scheduler():
+	n = (yield)                 # starting coroutine
+	while True:
+		n = next( n )           # schedule coroutine
+
+pi = PingPong( "ping", 5 )
+po = PingPong( "pong", 5 )
+next( pi )                      # prime
+pi.send( po )                   # send partner
+next( po )                      # prime
+po.send( pi )                   # send partner
+
+s = Scheduler();
+next( s )                       # prime
+try:
+	s.send( pi )				# start cycle
+except StopIteration:
+	print( "scheduler stop" )
+print( "stop" )
+
+# Local Variables: #
+# tab-width: 4 #
+# compile-command: "python3.5 Pingpong.py" #
+# End: #
Index: doc/papers/concurrency/examples/ProdCons.cfa
===================================================================
--- doc/papers/concurrency/examples/ProdCons.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/ProdCons.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,76 @@
+#include <fstream.hfa>
+#include <coroutine.hfa>
+#include <stdlib.hfa>									// random
+#include <unistd.h>										// getpid
+coroutine Cons;											// forward
+int delivery( Cons & cons, int p1, int p2 );
+void stop( Cons & cons );
+
+coroutine Prod {
+	Cons & c;
+	int N, money, receipt;
+};
+void main( Prod & prod ) with( prod ) {					// starter ::main
+	// 1st resume starts here
+	for ( i; N ) {										// N pairs of values
+		int p1 = random( 100 ), p2 = random( 100 );
+		sout | p1 | " " | p2;
+		int status = delivery( c, p1, p2 );
+		sout | " $" | money | nl | status;
+		receipt += 1;
+	}
+	stop( c );
+	sout | "prod stops";
+}
+int payment( Prod & prod, int m ) with(prod) {
+	money = m;
+	resume( prod );										// main 1st time, then
+	return receipt;										// prod in delivery
+}
+void start( Prod & prod, int N, Cons &c ) {
+	&prod.c = &c;
+	prod.[N, receipt] = [N, 0];
+	resume( prod );										// activate main
+}
+coroutine Cons {
+	Prod & p;
+	int p1, p2, status;
+	bool done;
+};
+void ?{}( Cons & cons, Prod & p ) {
+	&cons.p = &p;
+	cons.[status, done ] = [0, false];
+}
+void ^?{}( Cons & cons ) {}
+void main( Cons & cons ) with( cons ) {					// starter prod
+	// 1st resume starts here
+	int money = 1, receipt;
+	for ( ; ! done; ) {
+		sout | p1 | " " | p2 | nl | " $" | money;
+		status += 1;
+		receipt = payment( p, money );
+		sout | " #" | receipt;
+		money += 1;
+	}
+	sout | "cons stops";
+}
+int delivery( Cons & cons, int p1, int p2 ) {
+	cons.[p1, p2] = [p1, p2];
+	resume( cons );										// main 1st time, then
+	return cons.status;									// cons in payment
+}
+void stop( Cons & cons ) {
+	cons.done = true;
+	resume( cons );										// activate payment
+}
+int main() {
+	Prod prod;
+	Cons cons = { prod };
+	srandom( getpid() );
+	start( prod, 5, cons );
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa ProdCons.cfa" //
+// End: //
Index: doc/papers/concurrency/examples/ProdCons.cpp
===================================================================
--- doc/papers/concurrency/examples/ProdCons.cpp	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/ProdCons.cpp	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,244 @@
+#include <cassert>
+#include <cstdlib>
+#include <iostream>
+#include <experimental/coroutine>
+#include <unistd.h>
+
+int random(int max) {
+	return std::rand() % max;
+}
+
+struct Prod;
+struct Cons;
+
+struct resumable {
+	virtual resumable * resume() = 0;
+};
+
+struct Prod : public resumable {
+	struct local {
+		Cons * c;
+		int N, money, receipt;
+	};
+
+	struct promise_type {
+		local _l;
+		resumable * next;
+
+		Prod get_return_object() {
+			return Prod(std::experimental::coroutine_handle<promise_type>::from_promise(*this));
+		}
+
+		auto initial_suspend() { return std::experimental::suspend_never(); }
+		auto final_suspend()   { return std::experimental::suspend_always(); }
+
+		void return_void() {}
+		void unhandled_exception() {}
+	};
+
+	struct data {
+		promise_type * _promise = nullptr;
+		bool await_ready() noexcept { return false; }
+		void await_suspend(std::experimental::coroutine_handle<promise_type> _coroutine) noexcept {
+			_promise = &_coroutine.promise();
+		}
+		local & await_resume() noexcept { assert(_promise); return _promise->_l; }
+	};
+
+	std::experimental::coroutine_handle<promise_type> _coroutine = nullptr;
+
+	explicit Prod(std::experimental::coroutine_handle<promise_type> coroutine)
+		: _coroutine(coroutine)
+	{}
+
+	~Prod() {
+		if(_coroutine) { _coroutine.destroy(); }
+	}
+
+	Prod() = default;
+	Prod(Prod const &) = delete;
+	Prod& operator=(Prod const &) = delete;
+
+	Prod(Prod&& other) {
+		std::swap(_coroutine, other._coroutine);
+	}
+
+	Prod& operator=(Prod&& other) {
+		if(&other != this) {
+			_coroutine = other._coroutine;
+			other._coroutine = nullptr;
+		}
+		return *this;
+	}
+
+	static Prod main();
+
+	struct payment_return;
+
+	payment_return payment(int money);
+
+	auto start(int N, Cons & c) {
+		_coroutine.promise()._l.c = &c;
+		_coroutine.promise()._l.N = N;
+		_coroutine.promise()._l.receipt = 0;
+	}
+
+	virtual resumable * resume() override final {
+		_coroutine.resume();
+		return _coroutine.promise().next;
+	}
+};
+
+struct Cons : public resumable {
+	struct local {
+		Prod * p;
+		int p1, p2, status;
+		bool done;
+	};
+
+	struct promise_type {
+		local _l;
+		resumable * next;
+
+		Cons get_return_object() {
+			return Cons(std::experimental::coroutine_handle<promise_type>::from_promise(*this));
+		}
+
+		auto initial_suspend() { return std::experimental::suspend_never(); }
+		auto final_suspend()   { return std::experimental::suspend_always(); }
+
+		void return_void() {}
+		void unhandled_exception() {}
+	};
+
+	struct data {
+		Prod * _p;
+		data(Prod & prod) : _p(&prod) {}
+		promise_type * _promise = nullptr;
+		bool await_ready() noexcept { return false; }
+		void await_suspend(std::experimental::coroutine_handle<promise_type> _coroutine) noexcept {
+			_promise = &_coroutine.promise();
+		}
+		local & await_resume() noexcept { assert(_promise); _promise->_l.p = _p; return _promise->_l; }
+	};
+
+	std::experimental::coroutine_handle<promise_type> _coroutine = nullptr;
+
+	explicit Cons(std::experimental::coroutine_handle<promise_type> coroutine)
+		: _coroutine(coroutine)
+	{}
+
+	~Cons() {
+		if(_coroutine) { _coroutine.destroy(); }
+	}
+
+	Cons() = default;
+	Cons(Cons const &) = delete;
+	Cons& operator=(Cons const &) = delete;
+
+	Cons(Cons&& other) {
+		std::swap(_coroutine, other._coroutine);
+	}
+
+	Cons& operator=(Cons&& other) {
+		if(&other != this) {
+			_coroutine = other._coroutine;
+			other._coroutine = nullptr;
+		}
+		return *this;
+	}
+
+	static Cons main( Prod & prod );
+
+	auto deliver(int p1, int p2) {
+		_coroutine.promise()._l.p1 = p1;
+		_coroutine.promise()._l.p2 = p2;
+
+		struct ret {
+			int _status;
+			Cons * c;
+			bool await_ready() { return false; }
+			void await_suspend(std::experimental::coroutine_handle<Prod::promise_type> _coroutine) {
+				_coroutine.promise().next = c;
+			}
+			int await_resume() { return _status; }
+		};
+		return ret{ _coroutine.promise()._l.status, this };
+	}
+
+	auto stop() {
+		_coroutine.promise()._l.done = true;
+		struct ret {
+			Cons * c;
+			Prod::promise_type * _promise;
+			bool await_ready() { return false; }
+			void await_suspend(std::experimental::coroutine_handle<Prod::promise_type> _coroutine) {
+				_promise = &_coroutine.promise();
+				_promise->next = c;
+			}
+			void await_resume() {
+				_promise->next = nullptr;
+			}
+		};
+		return ret{this, nullptr};
+	}
+
+	virtual resumable * resume() override final {
+		_coroutine.resume();
+		return _coroutine.promise().next;
+	}
+};
+
+struct Prod::payment_return {
+	int _receipt;
+	Prod * p;
+	bool await_ready() { return false; }
+	void await_suspend(std::experimental::coroutine_handle<Cons::promise_type> _coroutine) {
+		_coroutine.promise().next = p;
+	}
+	int await_resume() { return _receipt; }
+};
+
+Prod::payment_return Prod::payment(int money)  {
+	_coroutine.promise()._l.money = money;
+	return payment_return{ _coroutine.promise()._l.receipt, this };
+}
+
+Prod Prod::main() {
+	auto & p = co_await Prod::data();
+	for(int i = 0; i < p.N; i++) {
+		int p1 = random(100), p2 = random(100);
+		std::cout << p1 << " " << p2 << std::endl;
+		int status = co_await p.c->deliver(p1, p2);
+		std::cout << " $" << p.money << std::endl << status << std::endl;
+		p.receipt += 1;
+	}
+	co_await p.c->stop();
+	std::cout << "prod stops" << std::endl;
+}
+
+Cons Cons::main( Prod & prod ) {
+	auto & c = co_await Cons::data( prod );
+	int money = 1, receipt;
+	for(;!c.done ;) {
+		std::cout << c.p1 << " " << c.p2 << std::endl;
+		std::cout << " $ " << money << std::endl;
+		c.status += 1;
+		receipt = co_await c.p->payment( money );
+		std::cout << " # " << receipt << std::endl;
+		money += 1;
+	}
+	std::cout << "cons stops" << std::endl;
+}
+
+void dispatch(resumable * r) {
+	while((r = r->resume()));
+}
+
+int main() {
+	auto prod = Prod::main();
+	auto cons = Cons::main( prod );
+	srandom( getpid() );
+	prod.start(5, cons);
+	dispatch(&prod);
+}
Index: doc/papers/concurrency/examples/ProdCons.py
===================================================================
--- doc/papers/concurrency/examples/ProdCons.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/ProdCons.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,40 @@
+def Prod( N ):
+	cons = (yield)              # get cons
+	yield                       # resume scheduler
+	for i in range( N ):
+		print( "prod" )
+		yield cons              # execute next
+	print( "end", "prod" )
+
+def Cons( N ):
+	prod = (yield)              # get prod
+	yield                       # resume scheduler
+	for i in range( N ):
+		print( "cons" )
+		yield prod              # execute next
+	print( "end", "cons" )
+
+def Scheduler():
+	n = (yield)                 # starting coroutine
+	while True:
+		n = next( n )           # schedule coroutine
+
+prod = Prod( 5 )
+cons = Cons( 5 )
+next( prod )                    # prime
+prod.send( cons )               # send cons
+next( cons )                    # prime
+cons.send( prod )               # send prod
+
+s = Scheduler();
+next( s )                       # prime
+try:
+	s.send( prod )				# start cycle
+except StopIteration:
+	print( "scheduler stop" )
+print( "stop" )
+
+# Local Variables: #
+# tab-width: 4 #
+# compile-command: "python3.5 ProdCons.py" #
+# End: #
Index: doc/papers/concurrency/examples/ProdCons.sim
===================================================================
--- doc/papers/concurrency/examples/ProdCons.sim	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/ProdCons.sim	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,104 @@
+BEGIN
+	CLASS Consumer( prod );
+   		REF(Producer) prod; ! constructor parameter;
+		HIDDEN p1, p2, status, done, Main;
+	BEGIN
+		INTEGER p1, p2, status;
+		BOOLEAN done;
+		PROCEDURE main;
+		BEGIN
+			INTEGER money, receipt;
+
+			money := 1;
+			WHILE NOT done DO BEGIN
+				OutText( "cons receives: " );
+				OutInt( p1, 3 );
+				OutText( ", " );
+				OutInt( p2, 3 );
+				status := status + 1;
+				OutText( " and pays $" );
+				OutInt( money, 3 ); OutImage;
+				receipt := prod.payment( money );
+				OutText( "cons receipt #" );
+				OutInt( receipt, 3 ); OutImage;
+				money := money + 1;
+			END;
+			OutText( "cons stops" ); OutImage;
+		END;
+		INTEGER PROCEDURE delivery( p1p, p2p );
+			INTEGER p1p, p2p;
+		BEGIN
+			p1 := p1p;
+			p2 := p2p;
+			Resume( THIS Consumer );
+			delivery := status;
+		END;
+		PROCEDURE stop;
+		BEGIN
+			done := TRUE;
+			Call( THIS Consumer );
+		END;
+		! Consumer constructor code;
+		status := 0;
+		done := FALSE;
+		Detach;
+		main;
+	END Consumer;
+
+	CLASS Producer;
+		HIDDEN cons, N, money, receipt, Main;
+	BEGIN
+		REF(Consumer) cons;
+		INTEGER N, money, receipt;
+		PROCEDURE main;
+		BEGIN
+			INTEGER i, p1, p2, status;
+
+			FOR i := 1 STEP 1 UNTIL N DO BEGIN  
+				p1 := RandInt( 1, 100, p1 );
+				p2 := RandInt( 1, 100, p2 );
+				OutText( "prod delivers: " );
+				OutInt( p1, 3 ); OutText( ", " );
+				OutInt( p2, 3 ); OutImage;
+				status := cons.delivery( p1, p2 );
+				OutText( "prod status: " );
+				OutInt( status, 3 ); OutImage;
+			END;
+			cons.stop;
+			OutText( "prod stops" ); OutImage;
+		END;
+		INTEGER PROCEDURE payment( moneyp );
+			INTEGER moneyp;
+		BEGIN
+			money := moneyp;
+			OutText( "prod payment of $" );
+			OutInt( money, 3 ); OutImage;
+			Resume( THIS Producer );
+			receipt := receipt + 1;
+			payment := receipt;
+		END;
+		PROCEDURE start( Np, consp );
+			INTEGER Np;
+			REF(Consumer) consp;
+		BEGIN
+			N := Np;
+			cons :- consp;
+			Resume( THIS Producer );
+		END;
+		! Producer constructor code;
+		receipt := 0;
+		Detach;
+		main;
+	END Producer;
+	! program main equivalent;
+	REF(Producer) prod;
+	REF(Consumer) cons;
+	prod :- NEW Producer;
+	cons :- NEW Consumer( prod );
+	prod.start( 5, cons );
+END;
+
+! Local Variables: ;
+! tab-width: 4 ;
+! compile-command: "cim ProdCons.sim" ;
+! End: ;
Index: doc/papers/concurrency/examples/Refactor.py
===================================================================
--- doc/papers/concurrency/examples/Refactor.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/Refactor.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,29 @@
+def Recursion():
+	def Refactor():
+		N = (yield)
+		print( N );
+		if N == 0:
+			yield 0
+		r = Refactor()
+		next( r )
+		x = r.send( N - 1 )
+		print( x );
+		yield x
+
+	N = (yield)
+	print( N );
+	r = Refactor()
+	next( r )
+	print( r.send( N - 1 ) )
+
+c = Recursion()
+next( c )
+try:
+	c.send( 5 )
+except StopIteration:
+	print( "stop" )
+
+# Local Variables: #
+# tab-width: 4 #
+# compile-command: "python3.5 Refactor.py" #
+# End: #
Index: doc/papers/concurrency/examples/counter.cpp
===================================================================
--- doc/papers/concurrency/examples/counter.cpp	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/papers/concurrency/examples/counter.cpp	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,62 @@
+#include <iostream>
+#include <experimental/coroutine>
+
+struct counter_cor {
+	struct promise_type {
+		counter_cor get_return_object() {
+			return counter_cor(std::experimental::coroutine_handle<promise_type>::from_promise(*this));
+		}
+
+		auto initial_suspend() { return std::experimental::suspend_never(); }
+		auto final_suspend()   { return std::experimental::suspend_never(); }
+
+		void return_void() {}
+
+		void unhandled_exception() {}
+	};
+
+	std::experimental::coroutine_handle<promise_type> _coroutine = nullptr;
+
+	explicit counter_cor(std::experimental::coroutine_handle<promise_type> coroutine)
+		: _coroutine(coroutine)
+	{}
+
+	~counter_cor() {
+		if(_coroutine) { _coroutine.destroy(); }
+	}
+
+	counter_cor() = default;
+	counter_cor(counter_cor const &) = delete;
+	counter_cor& operator=(counter_cor const &) = delete;
+
+	counter_cor(counter_cor&& other) {
+		std::swap(_coroutine, other._coroutine);
+	}
+
+	counter_cor& operator=(counter_cor&& other) {
+		if(&other != this) {
+			_coroutine = other._coroutine;
+			other._coroutine = nullptr;
+		}
+		return *this;
+	}
+
+	void resume() { _coroutine.resume(); }
+};
+
+counter_cor counter() {
+	std::cout << "Counter: called\n";
+	for(unsigned i = 1;; i++) {
+		co_await std::experimental::suspend_always{};
+		std::cout << "Counter: Resumed " << i << " time(s)\n";
+	}
+}
+
+int main() {
+	std::cout << "Main: calling counter\n";
+	auto c = counter();
+	std::cout << "Main: resumes\n";
+	c.resume();
+	c.resume();
+	std::cout << "Main: done\n";
+}
Index: doc/proposals/interned_string.cc
===================================================================
--- doc/proposals/interned_string.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/proposals/interned_string.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,8 @@
+// Copyright (c) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in 
+// the file "LICENCE" distributed with this repository.
+
+#include "interned_string.h"
+
+std::unordered_set< std::string > interned_string::canonical;
Index: doc/proposals/interned_string.h
===================================================================
--- doc/proposals/interned_string.h	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/proposals/interned_string.h	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,57 @@
+#pragma once
+
+// Copyright (c) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in 
+// the file "LICENCE" distributed with this repository.
+
+#include <functional>
+#include <string>
+#include <unordered_set>
+#include <utility>
+
+/// Keeps canonical copies of a std::string for quicker comparisons
+class interned_string {
+	/// Shared map of canonical string representations
+	static std::unordered_set< std::string > canonical;
+
+	/// Canonical representation of empty string
+	static const std::string* empty_string() {
+		static const std::string* mt = [](){
+			return &*canonical.emplace( "" ).first;
+		}();
+		return mt;
+	}
+
+	/// Canonicalize string
+	template<typename S>
+	static const std::string* intern( S&& s ) {
+		return &*canonical.emplace( std::forward<S>(s) ).first;
+	}
+
+	/// Pointer to stored string
+	const std::string* s;
+	
+public:
+	interned_string() : s{empty_string()} {}
+	interned_string(const char* cs) : s{intern(cs)} {}
+	interned_string(const std::string& ss) : s{intern(ss)} {}
+
+	operator const std::string& () const { return *s; }
+
+	bool operator== (const interned_string& o) const { return s == o.s; }
+	bool operator!= (const interned_string& o) const { return s != o.s; }
+	bool operator< (const interned_string& o) const { return *s < *o.s; }
+};
+
+inline std::ostream& operator<< (std::ostream& out, const interned_string& s) {
+	return out << (const std::string&)s;
+}
+
+namespace std {
+	template<> struct hash<interned_string> {
+		std::size_t operator() (const interned_string& s) const {
+			return std::hash<const std::string*>{}( &(const std::string&)s );
+		}
+	};
+}
Index: doc/proposals/specialized_casts.md
===================================================================
--- doc/proposals/specialized_casts.md	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ doc/proposals/specialized_casts.md	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,32 @@
+## Specialized Casts ##
+
+There is some use in Cforall for cast operators with semantics other than the standard C cast. To make these alternate casts look like the familiar C cast, this proposal follows the example of the virtual proposal's virtual cast `(virtual Foo)x` and uses an added (pseudo-)keyword inside the cast parens.
+
+### C (Conversion) Cast ###
+The standard C cast performs _conversions_, transformations between types which may make a new object with a different in-memory representation. Cforall maintains these semantics in a backward-compatible way while accounting for name overloading by choosing the lowest-cost interpretation of the argument expression which is convertable to the target type, breaking ties by conversion cost.
+
+The C cast must be maintained for backward-compatibility, and developing a second cast operator with identical semantics seems an undesirable multiplication of language features, but `(convert Foo)` or `(to Foo)` would be reasonable options for a keyword. An alternate semantics for a Cforall-specific conversion cast would be to choose the cast interpretation with the lowest sum of conversion cost and interpretation cost, which aligns better with Cforall function call resolution algorithm.
+
+### Ascription Cast ###
+Using casts in Cforall for type _ascription_ ("select the interpretation of this type") works by the conversion-cost tiebreaker behaviour of the cast operator. However, the ascription interpretation of casts is prioritized less than the conversion interpretation of casts, sometimes resulting in some surprising results, as in the following example:
+
+	int f(int);      // f1
+	int f(double);   // f2
+	int g(int);      // g1
+	double g(long);  // g2
+
+	f((double)42);   // selects f2 by cast on argument
+	(double)g(42);   // does NOT select g2, argument conversion cost results in g1
+
+An ascription cast which reversed the priorities of the C cast would be useful for selecting expressions based on their return type; a reversal of the priorities of the standard C cast would work for this (that is, select the lowest-cost conversion, breaking ties based on argument cost). A plausible stricter semantics would be to select the cheapest interpretation with a zero-cost conversion to the target type, reporting a compiler error otherwise (this semantics would make ascription a solely compile-time phenomenon, rather than relying on possible runtime conversions). A resonable keyword would be `(as Foo)`, which is short, evocative, and echos "ascription"; `(return Foo)` would not introduce new keywords, and speaks to its use in return-type selection, as in the following corrected version of the example above:
+
+	(as double)g(42);  // selects g2, as expected (under either presented ascription semantics)
+
+### Coercion Cast ###
+Some of the explict conversions in C are defined to be a _coercions_ (reinterpret the bits of this value as another type). Use of coercions often relies on non-standard implementation details of the provided environment, and as such is discouraged, but is sometimes necessary. Since all explicit pointer casts in C are coercions, any lvalue `x` in C/Cforall can be coerced with the pattern `*(Foo*)&x`, but this is complex and doesn't extend to rvalues. A dedicated coercion cast would solve these issues; `(reinterpret Foo)` (from C++), `(transmute Foo)` (from Rust), or `(coerce Foo)` would be reasonable keywords.
+
+### Qualifier Cast ###
+A more restricted (and thus safer) form of coercion is modifiying the qualifiers of a type; C++ has `const_cast` for this purpose, and a similar feature would be useful for Cforall. With regard to syntax, `(requalify const Foo)`/`(requalify Foo)` to add/strip `const` would echo C++, but given that the vast majority of uses are stripping const-qualfiers, `(non const)` would be shorter, clearer, easily searchable, and not require the programmer to exactly match the argument type. In this syntax, coercion casts could be used to add qualifiers, or another cast type (say `(with const)`) could be introduced to add qualfiers.
+
+### Virtual Cast ###
+_see virtual.txt; semantics equivalent to C++ dynamic cast_
Index: doc/proposals/vtable.md
===================================================================
--- doc/proposals/vtable.md	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ doc/proposals/vtable.md	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -11,4 +11,9 @@
 should be able to store anything that goes into a trait.
 
+I also include notes on a sample implementation, which primarly exists to show
+there is a resonable implementation. The code samples for that are in a slight
+psudo-code to help avoid name mangling and keeps some CFA features while they
+would actually be writen in C.
+
 Trait Instances
 ---------------
@@ -42,12 +47,120 @@
 before.
 
-Internally a trait object is a pair of pointers. One to an underlying object
-and the other to the vtable. All calls on an trait are implemented by looking
-up the matching function pointer and passing the underlying object and the
-remaining arguments to it.
-
-Trait objects can be moved by moving the pointers. Almost all other operations
-require some functions to be implemented on the underlying type. Depending on
-what is in the virtual table a trait type could be a dtype or otype.
+For traits to be used this way they should meet two requirements. First they
+should only have a single polymorphic type and each assertion should use that
+type once as a parameter. Extentions may later loosen these requirements.
+
+If a trait object is used it should generate a series of implicate functions
+each of which implements one of the functions required by the trait. So for
+combiner there is an implicate:
+
+    void combine(trait combiner & this, int);
+
+This function is the one actually called at the end
+
+The main use case for trait objects is that they can be stored. They can be
+passed into functions, but using the trait directly is prefred in this case.
+
+    trait drawable(otype T) {
+        void draw(Surface & to, T & draw);
+        Rect(int) drawArea(T & draw);
+    };
+
+    struct UpdatingSurface {
+        Surface * surface;
+        vector(trait drawable) drawables;
+    };
+
+    void updateSurface(UpdatingSurface & us) {
+        for (size_t i = 0 ; i < us.drawables.size ; ++i) {
+            draw(us.surface, us.drawables[i]);
+        }
+    }
+
+Currently these traits are limited to 1 trait parameter and functions should
+have exactly 1 parameter. We cannot abstract away pairs of types and still
+pass them into normal functions, which take them seperately.
+
+The second is required the because we need to get the vtable from somewhere.
+If there are 0 trait objects than no vtable is avalible, if we have more than
+1 than the vtables give conflicting answers on what underlying function to
+call. And even then the underlying type assumes a concrete type.
+
+This loop can sort of be broken by using the trait object directly in the
+signature. This has well defined meaning, but might not be useful.
+
+    trait example(otype T) {
+        bool test(T & this, trait example & that);
+    }
+
+#### Sample Implementation
+A simple way to implement trait objects is by a pair of pointers. One to the
+underlying object and one to the vtable.
+
+    struct vtable_drawable {
+        void (*draw)(Surface &, void *);
+        Rect(int) (*drawArea)(void *);
+    };
+
+    struct drawable {
+        void * object;
+        vtable_drawable * vtable;
+    };
+
+The functions that run on the trait object would generally be generated using
+the following pattern:
+
+    void draw(Surface & surface, drawable & traitObj) {
+        return traitObj.vtable->draw(surface, traitObj.object);
+    }
+
+There may have to be special cases for things like copy construction, that
+might require a more sigificant wrapper. On the other hand moving could be
+implemented by moving the pointers without any need to refer to the base
+object.
+
+### Extention: Multiple Trait Parameters
+Currently, this gives traits two independent uses. They use the same syntax,
+except for limits boxable traits have, and yet don't really mix. The most
+natural way to do this is to allow trait instances to pick one parameter
+that they are generic over, the others they choose types to implement.
+
+The two ways to do the selection, the first is do it at the trait definition.
+Each trait picks out a single parameter which it can box (here the `virtual`
+qualifier). When you create an instance of a trait object you provide
+arguments like for a generic structure, but skip over the marked parameter.
+
+    trait combiner(virtual otype T, otype Combined) {
+        void combine(T &, Combined &);
+    }
+
+    trait combiner(int) int_combiner;
+
+The second is to do it at the instaniation point. A placeholder (here the
+keyword `virtual`) is used to explicately skip over the parameter that will be
+abstracted away, with the same rules as above if it was the marked parameter.
+
+    trait combiner(otype T, otype Combined) {
+        void combine(T &, Combined &);
+    };
+
+    trait combiner(virtual, int) int_combiner;
+
+Using both (first to set the default, second as a local override) would also
+work, although might be exessively complicated.
+
+This is useful in cases where you want to use a generic type, but leave part
+of it open and store partially generic result. As a simple example
+
+    trait folder(otype T, otype In, otype Out) {
+        void fold(T & this, In);
+        Out fold_result(T & this);
+    }
+
+Which allows you to fold values without putting them in a container. If they
+are already in a container this is exessive, but if they are generated over
+time this gives you a simple interface. This could for instance be used in
+a profile, where T changes for each profiling statistic and you can plug in
+multiple profilers for any run by adding them to an array.
 
 Hierarchy
@@ -90,19 +203,130 @@
 the pointer to it.
 
+Exception Example:
+(Also I'm not sure where I got these casing rules.)
+
+    trait exception(otype T) virtual() {
+        char const * what(T & this);
+    }
+
+    trait io_error(otype T) virtual(exception) {
+        FILE * which_file(T & this);
+    }
+
+    struct eof_error(otype T) virtual(io_error) {
+        FILE * file;
+    }
+
+    char const * what(eof_error &) {
+        return "Tried to read from an empty file.";
+    }
+
+    FILE * which_file(eof_error & this) {
+        return eof_error.file;
+    }
+
+Ast Example:
+
+    trait ast_node(otype T) virtual() {
+        void print(T & this, ostream & out);
+        void visit(T & this, Visitor & visitor);
+        CodeLocation const & get_code_location(T & this);
+    }
+
+    trait expression_node(otype T) virtual(ast_node) {
+        Type eval_type(T const & this);
+    }
+
+    struct operator_expression virtual(expression_node) {
+        enum operator_kind kind;
+        trait expression_node rands[2];
+    }
+
+    trait statement_node(otype T) virtual(ast_node) {
+        vector(Label) & get_labels(T & this);
+    }
+
+    struct goto_statement virtual(statement_node) {
+        vector(Label) labels;
+        Label target;
+    }
+
+    trait declaration_node(otype T) virtual(ast_node) {
+        string name_of(T const & this);
+        Type type_of(T const & this);
+    }
+
+    struct using_declaration virtual(declaration_node) {
+        string new_type;
+        Type old_type;
+    }
+
+    struct variable_declaration virtual(declaration_node) {
+        string name;
+        Type type;
+    }
+
+#### Sample Implementation
+The type id may be as little as:
+
+    struct typeid {
+        struct typeid const * const parent;
+    };
+
+Some linker magic would have to be used to ensure exactly one copy of each
+structure for each type exists in memory. There seem to be spectial once
+sections that support this and it should be easier than generating unique
+ids across compilation units.
+
+The structure could be extended to contain any additional type information.
+
+There are two general designs for vtables with type ids. The first is to put
+the type id at the top of the vtable, this is the most compact and efficient
+solution but only works if we have exactly 1 vtable for each type. The second
+is to put a pointer to the type id in each vtable. This has more overhead but
+allows multiple vtables.
+
+    struct <trait>_vtable {
+        struct typeid const id;
+
+        // Trait dependent list of vtable members.
+    };
+
+    struct <trait>_vtable {
+        struct typeid const * const id;
+
+        // Trait dependent list of vtable members.
+    };
+
+### Virtual Casts
+To convert from a pointer to a type higher on the hierarchy to one lower on
+the hierarchy a check is used to make sure that the underlying type is also
+of that lower type.
+
+The proposed syntax for this is:
+
+    trait SubType * new_value = (virtual trait SubType *)super_type;
+
+It will return the same pointer if it does point to the subtype and null if
+it does not, doing the check and conversion in one operation.
+
 ### Inline vtables
 Since the structures here are usually made to be turned into trait objects
 it might be worth it to have fields on them to store the virtual table
-pointer. This would have to be declared on the trait as an assertion, but if
-it is the trait object could be a single pointer.
-
-It is trivial to do if the field with the virtual table pointer is fixed.
-Otherwise some trickery with pointing to the field and storing the offset in
-the virtual table to recover the main object would have to be used.
+pointer. This would have to be declared on the trait as an assertion (example:
+`vtable;` or `T.vtable;`), but if it is the trait object could be a single
+pointer.
+
+There are also three options for where the pointer to the vtable. It could be
+anywhere, a fixed location for each trait or always at the front. For the per-
+trait solution an extention to specify what it is (example `vtable[0];`) which
+could also be used to combine it with others. So these options can be combined
+to allow access to all three options.
 
 ### Virtual Tables as Types
-Here we consider encoding plus the implementation of functions on it. Which
-is to say in the type hierarchy structures aren't concrete types anymore,
-instead they are parent types to vtables, which combine the encoding and
-implementation.
+Here we consider encoding plus the implementation of functions on it to be a
+type. Which is to say in the type hierarchy structures aren't concrete types
+anymore, instead they are parent types to vtables, which combine the encoding
+and implementation.
 
 Resolution Scope
@@ -123,6 +347,18 @@
 other.
 
-Some syntax would have to be added. All resolutions can be found at compile
-time and a single vtable created for each type at compilation time.
+Some syntax would have to be added to specify the resolution point. To ensure
+a single instance there may have to be two variants, one forward declaration
+and one to create the instance. With some compiler magic the forward
+declaration maybe enough.
+
+    extern trait combiner(struct summation) vtable;
+    trait combiner(struct summation) vtable;
+
+Or (with the same variants):
+
+    vtable combiner(struct summation);
+
+The extern variant promises that the vtable will exist while the normal one
+is where the resolution actually happens.
 
 ### Explicit Resolution Points:
@@ -141,4 +377,26 @@
 vtable.
 
+    extern trait combiner(struct summation) vtable sum;
+    trait combiner(struct summation) vtable sum;
+
+    extern trait combiner(struct summation) vtable sum default;
+    trait combiner(struct summation) vtable sum default;
+
+The extern difference is the same before. The name (sum in the samples) is
+used at the binding site to say which one is picked. The default keyword can
+be used in only some of the declarations.
+
+    trait combiner fee = (summation_instance, sum);
+    trait combiner foe = summation_instance;
+
+(I am not really happy about this syntax, but it kind of works.)
+The object being bound is required. The name of the vtable is optional if
+there is exactly one vtable name marked with default.
+
+These could also be placed inside functions. In which case both the name and
+the default keyword might be optional. If the name is ommited in an assignment
+the closest vtable is choosen (returning to the global default rule if no
+approprate local vtable is in scope).
+
 ### Site Based Resolution:
 Every place in code where the binding of a vtable to an object occurs has
Index: doc/user/user.tex
===================================================================
--- doc/user/user.tex	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ doc/user/user.tex	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -11,6 +11,6 @@
 %% Created On       : Wed Apr  6 14:53:29 2016
 %% Last Modified By : Peter A. Buhr
-%% Last Modified On : Tue Dec 11 23:19:26 2018
-%% Update Count     : 3400
+%% Last Modified On : Sun Apr 14 11:02:34 2019
+%% Update Count     : 3443
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
@@ -508,16 +508,22 @@
 
 As for \Index{division}, there are exponentiation operators for integral and floating types, including the builtin \Index{complex} types.
-Unsigned integral exponentiation\index{exponentiation!unsigned integral} is performed with repeated multiplication\footnote{The multiplication computation is $O(\log y)$.} (or shifting if the base is 2).
-Signed integral exponentiation\index{exponentiation!signed integral} is performed with repeated multiplication (or shifting if the base is 2), but yields a floating result because $x^{-y}=1/x^y$.
-Hence, it is important to designate exponent integral-constants as unsigned or signed: ©3 \ 3u© return an integral result, while ©3 \ 3© returns a floating result.
-Floating exponentiation\index{exponentiation!floating} is performed using \Index{logarithm}s\index{exponentiation!logarithm}, so the base cannot be negative.
-\begin{cfa}
-sout | 2 ®\® 8u | 4 ®\® 3u | -4 ®\® 3u | 4 ®\® -3 | -4 ®\® -3 | 4.0 ®\® 2.1 | (1.0f+2.0fi) ®\® (3.0f+2.0fi);
-256 64 -64 0.015625 -0.015625 18.3791736799526 0.264715-1.1922i
-\end{cfa}
+Integral exponentiation\index{exponentiation!unsigned integral} is performed with repeated multiplication\footnote{The multiplication computation is $O(\log y)$.} (or shifting if the exponent is 2).
+Overflow from large exponents or negative exponents return zero.
+Floating exponentiation\index{exponentiation!floating} is performed using \Index{logarithm}s\index{exponentiation!logarithm}, so the exponent cannot be negative.
+\begin{cfa}
+sout | 1 ®\® 0 | 1 ®\® 1 | 2 ®\® 8 | -4 ®\® 3 | 5 ®\® 3 | 5 ®\® 32 | 5L ®\® 32 | 5L ®\® 64 | -4 ®\® -3 | -4.0 ®\® -3 | 4.0 ®\® 2.1
+	   | (1.0f+2.0fi) ®\® (3.0f+2.0fi);
+1 1 256 -64 125 ®0® 3273344365508751233 ®0® ®0® -0.015625 18.3791736799526 0.264715-1.1922i
+\end{cfa}
+Note, ©5 ®\® 32© and ©5L ®\® 64© overflow, and ©-4 ®\® -3© is a fraction but stored in an integer so all three computations generate an integral zero.
 Parenthesis are necessary for complex constants or the expression is parsed as ©1.0f+®(®2.0fi \ 3.0f®)®+2.0fi©.
-The exponentiation operator is available for all the basic types, but for user-defined types, only the integral-computation versions are available.
-For returning an integral value, the user type ©T© must define multiplication, ©*©, and one, ©1©;
-for returning a floating value, an additional divide of type ©T© into a ©double© returning a ©double© (©double ?/?( double, T )©) is necessary for negative exponents.
+The exponentiation operator is available for all the basic types, but for user-defined types, only the integral-computation version is available.
+\begin{cfa}
+forall( otype OT | { void ?{}( OT & this, one_t ); OT ?*?( OT, OT ); } )
+OT ?®\®?( OT ep, unsigned int y );
+forall( otype OT | { void ?{}( OT & this, one_t ); OT ?*?( OT, OT ); } )
+OT ?®\®?( OT ep, unsigned long int y );
+\end{cfa}
+The user type ©T© must define multiplication, one, ©1©, and, ©*©.
 
 
@@ -549,72 +555,90 @@
 \subsection{Loop Control}
 
-The ©for©/©while©/©do-while© loop-control allows empty or simplified ranges.
+The ©for©/©while©/©do-while© loop-control allows empty or simplified ranges (see Figure~\ref{f:LoopControlExamples}).
+\begin{itemize}
+\item
 An empty conditional implies ©1©.
-The up-to range ©~©\index{~@©~©} means exclusive range [M,N);
-the up-to range ©~=©\index{~=@©~=©} means inclusive range [M,N].
-The down-to range ©-~©\index{-~@©-~©} means exclusive range [N,M);
-the down-to range ©-~=©\index{-~=@©-~=©} means inclusive range [N,M].
+\item
+The up-to range ©~©\index{~@©~©} means exclusive range [M,N).
+\item
+The up-to range ©~=©\index{~=@©~=©} means inclusive range [M,N].
+\item
+The down-to range ©-~©\index{-~@©-~©} means exclusive range [N,M).
+\item
+The down-to range ©-~=©\index{-~=@©-~=©} means inclusive range [N,M].
+\item
+©@© means put nothing in this field.
+\item
 ©0© is the implicit start value;
+\item
 ©1© is the implicit increment value.
+\item
 The up-to range uses ©+=© for increment;
-the down-to range uses ©-=© for decrement.
+\item
+The down-to range uses ©-=© for decrement.
+\item
 The loop index is polymorphic in the type of the start value or comparison value when start is implicitly ©0©.
+\end{itemize}
+
+\begin{figure}
 \begin{cquote}
-\begin{tabular}{@{}ll|l@{}}
-\multicolumn{2}{c|}{loop control} & \multicolumn{1}{c}{output} \\
+\begin{tabular}{@{}l|l@{}}
+\multicolumn{1}{c|}{loop control} & \multicolumn{1}{c}{output} \\
 \hline
 \begin{cfa}
-while ®()® { sout | "empty"; break; }
-do { sout | "empty"; break; } while ®()®;
-for ®()® { sout | "empty"; break; }
-for ( ®0® ) { sout | "A"; }
-for ( ®1® ) { sout | "A"; }
-for ( ®10® ) { sout | "A"; }
-for ( ®1 ~= 10 ~ 2® ) { sout | "B"; }
-for ( ®10 -~= 1 ~ 2® ) { sout | "C"; }
-for ( ®0.5 ~ 5.5® ) { sout | "D"; }
-for ( ®5.5 -~ 0.5® ) { sout | "E"; }
-for ( ®i; 10® ) { sout | i; }
-for ( ®i; 1 ~= 10 ~ 2® ) { sout | i; }
-for ( ®i; 10 -~= 1 ~ 2® ) { sout | i; }
-for ( ®i; 0.5 ~ 5.5® ) { sout | i; }
-for ( ®i; 5.5 -~ 0.5® ) { sout | i; }
-for ( ®ui; 2u ~= 10u ~ 2u® ) { sout | ui; }
-for ( ®ui; 10u -~= 2u ~ 2u® ) { sout | ui; }
+sout | nlOff;
+while ®()® { sout | "empty"; break; } sout | nl;
+do { sout | "empty"; break; } while ®()®; sout | nl;
+for ®()® { sout | "empty"; break; } sout | nl;
+for ( ®0® ) { sout | "A"; } sout | "zero" | nl;
+for ( ®1® ) { sout | "A"; } sout | nl;
+for ( ®10® ) { sout | "A"; } sout | nl;
+for ( ®1 ~= 10 ~ 2® ) { sout | "B"; } sout | nl;
+for ( ®10 -~= 1 ~ 2® ) { sout | "C"; } sout | nl;
+for ( ®0.5 ~ 5.5® ) { sout | "D"; } sout | nl;
+for ( ®5.5 -~ 0.5® ) { sout | "E"; } sout | nl;
+for ( ®i; 10® ) { sout | i; } sout | nl;
+for ( ®i; 1 ~= 10 ~ 2® ) { sout | i; } sout | nl;
+for ( ®i; 10 -~= 1 ~ 2® ) { sout | i; } sout | nl;
+for ( ®i; 0.5 ~ 5.5® ) { sout | i; } sout | nl;
+for ( ®i; 5.5 -~ 0.5® ) { sout | i; } sout | nl;
+for ( ®ui; 2u ~= 10u ~ 2u® ) { sout | ui; } sout | nl;
+for ( ®ui; 10u -~= 2u ~ 2u® ) { sout | ui; } sout | nl;
 enum { N = 10 };
-for ( ®N® ) { sout | "N"; }
-for ( ®i; N® ) { sout | i; }
-for ( ®i; N -~ 0® ) { sout | i; }
+for ( ®N® ) { sout | "N"; } sout | nl;
+for ( ®i; N® ) { sout | i; } sout | nl;
+for ( ®i; N -~ 0® ) { sout | i; } sout | nl;
 const int start = 3, comp = 10, inc = 2;
-for ( ®i; start ~ comp ~ inc + 1® ) { sout | i; }
+for ( ®i; start ~ comp ~ inc + 1® ) { sout | i; } sout | nl;
+for ( ®i; 1 ~ @® ) { if ( i > 10 ) break;
+	sout | i; } sout | nl;
+for ( ®i; 10 -~ @® ) { if ( i < 0 ) break;
+	sout | i; } sout | nl;
+for ( ®i; 2 ~ @ ~ 2® ) { if ( i > 10 ) break;
+	sout | i; } sout | nl;
+for ( ®i; 2.1 ~ @ ~ @® ) { if ( i > 10.5 ) break;
+	sout | i; i += 1.7; } sout | nl;
+for ( ®i; 10 -~ @ ~ 2® ) { if ( i < 0 ) break;
+	sout | i; } sout | nl;
+for ( ®i; 12.1 ~ @ ~ @® ) { if ( i < 2.5 ) break;
+	sout | i; i -= 1.7; } sout | nl;
+for ( ®i; 5 : j; -5 ~ @® ) { sout | i | j; } sout | nl;
+for ( ®i; 5 : j; -5 -~ @® ) { sout | i | j; } sout | nl;
+for ( ®i; 5 : j; -5 ~ @ ~ 2® ) { sout | i | j; } sout | nl;
+for ( ®i; 5 : j; -5 -~ @ ~ 2® ) { sout | i | j; } sout | nl;
+for ( ®j; -5 ~ @ : i; 5® ) { sout | i | j; } sout | nl;
+for ( ®j; -5 -~ @ : i; 5® ) { sout | i | j; } sout | nl;
+for ( ®j; -5 ~ @ ~ 2 : i; 5® ) { sout | i | j; } sout | nl;
+for ( ®j; -5 -~ @ ~ 2 : i; 5® ) { sout | i | j; } sout | nl;
+for ( ®j; -5 -~ @ ~ 2 : i; 5 : k; 1.5 ~ @® ) {
+	sout | i | j | k; } sout | nl;
+for ( ®j; -5 -~ @ ~ 2 : k; 1.5 ~ @ : i; 5® ) {
+	sout | i | j | k; } sout | nl;
+for ( ®k; 1.5 ~ @ : j; -5 -~ @ ~ 2 : i; 5® ) {
+	sout | i | j | k; } sout | nl;
 \end{cfa}
 &
 \begin{cfa}
-sout | nl;
-sout | nl;
-sout | nl;
-sout | "zero" | nl;
-sout | nl;
-sout | nl;
-sout | nl;
-sout | nl;
-sout | nl;
-sout | nl;
-sout | nl;
-sout | nl;
-sout | nl;
-sout | nl;
-sout | nl;
-sout | nl;
-sout | nl | nl;
-
-sout | nl;
-sout | nl;
-sout | nl | nl;
-
-sout | nl;
-\end{cfa}
-&
-\begin{cfa}
+
 empty
 empty
@@ -640,7 +664,36 @@
 
 3 6 9
+
+1 2 3 4 5 6 7 8 9 10
+
+10 9 8 7 6 5 4 3 2 1 0
+
+2 4 6 8 10
+
+2.1 3.8 5.5 7.2 8.9
+
+10 8 6 4 2 0
+
+12.1 10.4 8.7 7 5.3 3.6
+0 -5 1 -4 2 -3 3 -2 4 -1
+0 -5 1 -6 2 -7 3 -8 4 -9
+0 -5 1 -3 2 -1 3 1 4 3
+0 -5 1 -7 2 -9 3 -11 4 -13
+0 -5 1 -4 2 -3 3 -2 4 -1
+0 -5 1 -6 2 -7 3 -8 4 -9
+0 -5 1 -3 2 -1 3 1 4 3
+0 -5 1 -7 2 -9 3 -11 4 -13
+
+0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5
+
+0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5
+
+0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5
 \end{cfa}
 \end{tabular}
 \end{cquote}
+\caption{Loop Control Examples}
+\label{f:LoopControlExamples}
+\end{figure}
 
 
@@ -1320,5 +1373,8 @@
 \end{cfa}
 Essentially, the return type is wrapped around the routine name in successive layers (like an \Index{onion}).
-While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice.
+While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice, even though Dennis Richie believed otherwise:
+\begin{quote}
+In spite of its difficulties, I believe that the C's approach to declarations remains plausible, and am comfortable with it; it is a useful unifying principle.~\cite[p.~12]{Ritchie93}
+\end{quote}
 
 \CFA provides its own type, variable and routine declarations, using a different syntax.
Index: libcfa/configure
===================================================================
--- libcfa/configure	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/configure	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -2977,4 +2977,6 @@
 	;;
 esac
+
+CONFIG_CFAFLAGS="${CONFIG_CFAFLAGS} ${CFAFLAGS}"
 
 
Index: libcfa/configure.ac
===================================================================
--- libcfa/configure.ac	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/configure.ac	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -64,4 +64,6 @@
 esac
 
+CONFIG_CFAFLAGS="${CONFIG_CFAFLAGS} ${CFAFLAGS}"
+
 AC_SUBST(CONFIG_CFLAGS)
 AC_SUBST(CONFIG_CFAFLAGS)
Index: libcfa/prelude/builtins.c
===================================================================
--- libcfa/prelude/builtins.c	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/prelude/builtins.c	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Fri Jul 21 16:21:03 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun Mar 10 10:52:50 2019
-// Update Count     : 31
+// Last Modified On : Tue Mar 26 23:10:36 2019
+// Update Count     : 95
 //
 
@@ -18,4 +18,5 @@
 typedef unsigned long long __cfaabi_abi_exception_type_t;
 
+#include <limits.h>										// CHAR_BIT
 #include "../src/virtual.h"
 #include "../src/exception.h"
@@ -26,19 +27,21 @@
 // increment/decrement unification
 
-static inline forall( dtype T | { T & ?+=?( T &, one_t ); } )
-T & ++? ( T & x ) { return x += 1; }
+static inline {
+	forall( dtype DT | { DT & ?+=?( DT &, one_t ); } )
+	DT & ++?( DT & x ) { return x += 1; }
 
-static inline forall( dtype T | sized(T) | { void ?{}( T &, T ); void ^?{}( T & ); T & ?+=?( T &, one_t ); } )
-T & ?++ ( T & x ) { T tmp = x; x += 1; return tmp; }
+	forall( dtype DT | sized(DT) | { void ?{}( DT &, DT ); void ^?{}( DT & ); DT & ?+=?( DT &, one_t ); } )
+	DT & ?++( DT & x ) { DT tmp = x; x += 1; return tmp; }
 
-static inline forall( dtype T | { T & ?-=?( T &, one_t ); } )
-T & --? ( T & x ) { return x -= 1; }
+	forall( dtype DT | { DT & ?-=?( DT &, one_t ); } )
+	DT & --?( DT & x ) { return x -= 1; }
 
-static inline forall( dtype T | sized(T) | { void ?{}( T &, T ); void ^?{}( T & ); T & ?-=?( T &, one_t ); } )
-T & ?-- ( T & x ) { T tmp = x; x -= 1; return tmp; }
+	forall( dtype DT | sized(DT) | { void ?{}( DT &, DT ); void ^?{}( DT & ); DT & ?-=?( DT &, one_t ); } )
+	DT & ?--( DT & x ) { DT tmp = x; x -= 1; return tmp; }
+} // distribution
 
 // universal typed pointer constant
-
-static inline forall( dtype T ) T * intptr( uintptr_t addr ) { return (T *)addr; }
+// Compiler issue: there is a problem with anonymous types that do not have a size.
+static inline forall( dtype DT | sized(DT) ) DT * intptr( uintptr_t addr ) { return (DT *)addr; }
 
 // exponentiation operator implementation
@@ -53,65 +56,59 @@
 } // extern "C"
 
-static inline float ?\?( float x, float y ) { return powf( x, y ); }
-static inline double ?\?( double x, double y ) { return pow( x, y ); }
-static inline long double ?\?( long double x, long double y ) { return powl( x, y ); }
-static inline float _Complex ?\?( float _Complex x, _Complex float y ) { return cpowf(x, y ); }
-static inline double _Complex ?\?( double _Complex x, _Complex double y ) { return cpow( x, y ); }
-static inline long double _Complex ?\?( long double _Complex x, _Complex long double y ) { return cpowl( x, y ); }
+static inline {
+	float ?\?( float x, float y ) { return powf( x, y ); }
+	double ?\?( double x, double y ) { return pow( x, y ); }
+	long double ?\?( long double x, long double y ) { return powl( x, y ); }
+	float _Complex ?\?( float _Complex x, _Complex float y ) { return cpowf(x, y ); }
+	double _Complex ?\?( double _Complex x, _Complex double y ) { return cpow( x, y ); }
+	long double _Complex ?\?( long double _Complex x, _Complex long double y ) { return cpowl( x, y ); }
+} // distribution
 
-static inline long int ?\?( long int ep, unsigned long int y ) { // disallow negative exponent
-	if ( y == 0 ) return 1;								// base case
-	if ( ep == 2 ) return ep << (y - 1);				// special case, positive shifting only
-	typeof( ep ) op = 1;								// accumulate odd product
-	for ( ; y > 1; y >>= 1 ) {							// squaring exponentiation, O(log2 y)
-		if ( (y & 1) == 1 ) op *= ep;					// odd ?
-		ep *= ep;
-	} // for
-	return ep * op;
-} // ?\?
+#define __CFA_BASE_COMP_1__() if ( ep == 1 ) return 1
+#define __CFA_BASE_COMP_2__() if ( ep == 2 ) return ep << (y - 1)
+#define __CFA_EXP_OVERFLOW__() if ( y >= sizeof(y) * CHAR_BIT ) return 0
 
-static inline forall( otype T | { void ?{}( T & this, one_t ); T ?*?( T, T ); } )
-T ?\?( T ep, unsigned long int y ) {
-	if ( y == 0 ) return 1;
-	T op = 1;
-	for ( ; y > 1; y >>= 1 ) {							// squaring exponentiation, O(log2 y)
-		if ( (y & 1) == 1 ) op = op * ep;				// odd ?
-		ep = ep * ep;
-	} // for
-	return ep * op;
-} // ?\?
+#define __CFA_EXP__() \
+	if ( y == 0 ) return 1;								/* convention */ \
+	__CFA_BASE_COMP_1__();								/* base case */ \
+	__CFA_BASE_COMP_2__();								/* special case, positive shifting for integral types */ \
+	__CFA_EXP_OVERFLOW__();								/* immediate overflow, negative exponent > 2^size-1 */ \
+	typeof(ep) op = 1;									/* accumulate odd product */ \
+	for ( ; y > 1; y >>= 1 ) {							/* squaring exponentiation, O(log2 y) */ \
+		if ( (y & 1) == 1 ) op = op * ep;				/* odd ? */ \
+		ep = ep * ep; \
+	} \
+	return ep * op
 
-// unsigned computation may be faster and larger
-static inline unsigned long int ?\?( unsigned long int ep, unsigned long int y ) { // disallow negative exponent
-	if ( y == 0 ) return 1;								// base case
-	if ( ep == 2 ) return ep << (y - 1);				// special case, positive shifting only
-	typeof( ep ) op = 1;								// accumulate odd product
-	for ( ; y > 1; y >>= 1 ) {							// squaring exponentiation, O(log2 y)
-		if ( (y & 1) == 1 ) op *= ep;					// odd ?
-		ep *= ep;
-	} // for
-	return ep * op;
-} // ?\?
+static inline {
+	long int ?\?( int ep, unsigned int y ) { __CFA_EXP__(); }
+	long int ?\?( long int ep, unsigned long int y ) { __CFA_EXP__(); }
+	// unsigned computation may be faster and larger
+	unsigned long int ?\?( unsigned int ep, unsigned int y ) { __CFA_EXP__(); }
+	unsigned long int ?\?( unsigned long int ep, unsigned long int y ) { __CFA_EXP__(); }
+} // distribution
 
-static inline double ?\?( long int x, signed long int y ) {	// allow negative exponent
-	if ( y >=  0 ) return (double)(x \ (unsigned long int)y);
-	else return 1.0 / x \ (unsigned int)(-y);
-} // ?\?
+#undef __CFA_BASE_COMP_1__
+#undef __CFA_BASE_COMP_2__
+#undef __CFA_EXP_OVERFLOW__
+#define __CFA_BASE_COMP_1__()
+#define __CFA_BASE_COMP_2__()
+#define __CFA_EXP_OVERFLOW__()
 
-// FIXME (x \ (unsigned long int)y) relies on X ?\?(T, unsigned long) a function that is neither
-// defined, nor passed as an assertion parameter. Without user-defined conversions, cannot specify
-// X as a type that casts to double, yet it doesn't make sense to write functions with that type
-// signature where X is double.
+static inline forall( otype OT | { void ?{}( OT & this, one_t ); OT ?*?( OT, OT ); } ) {
+	OT ?\?( OT ep, unsigned int y ) { __CFA_EXP__(); }
+	OT ?\?( OT ep, unsigned long int y ) { __CFA_EXP__(); }
+} // distribution
 
-// static inline forall( otype T | { void ?{}( T & this, one_t ); T ?*?( T, T ); double ?/?( double, T ); } )
-// double ?\?( T x, signed long int y ) {
-//     if ( y >=  0 ) return (double)(x \ (unsigned long int)y);
-//     else return 1.0 / x \ (unsigned long int)(-y);
-// } // ?\?
+#undef __CFA_BASE_COMP_1__
+#undef __CFA_BASE_COMP_2__
+#undef __CFA_EXP_OVERFLOW__
 
-static inline long int ?\=?( long int & x, unsigned long int y ) { x = x \ y; return x; }
-static inline unsigned long int ?\=?( unsigned long int & x, unsigned long int y ) { x = x \ y; return x; }
-static inline int ?\=?( int & x, unsigned long int y ) { x = x \ y; return x; }
-static inline unsigned int ?\=?( unsigned int & x, unsigned long int y ) { x = x \ y; return x; }
+static inline {
+	long int ?\=?( long int & x, unsigned long int y ) { x = x \ y; return x; }
+	unsigned long int ?\=?( unsigned long int & x, unsigned long int y ) { x = x \ y; return x; }
+	int ?\=?( int & x, unsigned long int y ) { x = x \ y; return x; }
+	unsigned int ?\=?( unsigned int & x, unsigned long int y ) { x = x \ y; return x; }
+} // distribution
 
 // Local Variables: //
Index: libcfa/prelude/prelude-gen.cc
===================================================================
--- libcfa/prelude/prelude-gen.cc	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/prelude/prelude-gen.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Sat Feb 16 08:44:58 2019
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Mar  8 16:00:22 2019
-// Update Count     : 26
+// Last Modified On : Tue Apr  2 17:18:24 2019
+// Update Count     : 37
 // 
 
@@ -118,5 +118,6 @@
 	{ "?!=?", false, "signed int", Normal, "" },
 	{ "?=?", true, "", Normal, "" }, // void * LHS, zero_t RHS ???
-	{ "*?", false, "&", Normal, " | sized(DT)" }, // & ???
+//	{ "*?", false, "&", Normal, " | sized(DT)" }, // & ???
+	{ "*?", false, "&", Normal, "" }, // & ???
 
 	{ "?-?", false, "ptrdiff_t", Normal, " | sized(DT)" },
@@ -208,7 +209,7 @@
 		cout << "void ?{} (" << type << " &);" << endl;
 		cout << "void ?{} (" << type << " &, " << type << ");" << endl;
-		cout << type << "  ?=? (" << type << " &, " << type << ")";
+		cout << type << " ?=? (" << type << " &, " << type << ")";
 		if ( do_volatile ) {
-			cout << ",  ?=?(volatile " << type << " &, " << type << ")";
+			cout << ", ?=?(volatile " << type << " &, " << type << ")";
 		}
 		cout << ";" << endl;
@@ -217,5 +218,7 @@
 
 	otype("zero_t");
+	cout << endl;
 	otype("one_t");
+	cout << endl;
 	otype("_Bool", true);
 	cout << endl;
@@ -225,4 +228,5 @@
 		cout << "void ?{}(" << type.name << " &, " << type.name << ");" << endl;
 		cout << "void ?{}(" << type.name << " &, zero_t);" << endl;
+		cout << "void ?{}(" << type.name << " &, one_t);" << endl;
 		cout << "void ^?{}(" << type.name << " &);" << endl;
 		cout << endl;
Index: libcfa/src/Makefile.am
===================================================================
--- libcfa/src/Makefile.am	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/Makefile.am	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -74,9 +74,9 @@
 
 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
-	${AM_V_GEN}@CFACC@ ${AM_CFLAGS} ${CFLAGS} -quiet -in-tree @CONFIG_CFAFLAGS@ -XCFA -l ${<} -c -o ${@}
+	${AM_V_GEN}$(CFACOMPILE) -quiet -in-tree -XCFA -l ${<} -c -o ${@}
 
 prelude.lo: prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
 	${AM_V_GEN}$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile \
-	@CFACC@ ${AM_CFLAGS} ${CFLAGS} -quiet -in-tree @CONFIG_CFAFLAGS@ -XCFA -l ${<} -c -o ${@}
+	$(CFACOMPILE) -quiet -in-tree -XCFA -l ${<} -c -o ${@}
 
 
Index: libcfa/src/Makefile.in
===================================================================
--- libcfa/src/Makefile.in	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/Makefile.in	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -926,9 +926,9 @@
 
 prelude.o : prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
-	${AM_V_GEN}@CFACC@ ${AM_CFLAGS} ${CFLAGS} -quiet -in-tree @CONFIG_CFAFLAGS@ -XCFA -l ${<} -c -o ${@}
+	${AM_V_GEN}$(CFACOMPILE) -quiet -in-tree -XCFA -l ${<} -c -o ${@}
 
 prelude.lo: prelude.cfa extras.cf gcc-builtins.cf builtins.cf @CFACC@ @CFACPP@
 	${AM_V_GEN}$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile \
-	@CFACC@ ${AM_CFLAGS} ${CFLAGS} -quiet -in-tree @CONFIG_CFAFLAGS@ -XCFA -l ${<} -c -o ${@}
+	$(CFACOMPILE) -quiet -in-tree -XCFA -l ${<} -c -o ${@}
 
 #----------------------------------------------------------------------------------------------------------------
Index: libcfa/src/concurrency/CtxSwitch-x86_64.S
===================================================================
--- libcfa/src/concurrency/CtxSwitch-x86_64.S	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/concurrency/CtxSwitch-x86_64.S	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -88,4 +88,59 @@
 	ret
 
+//.text
+//	.align 2
+//.globl	CtxStore
+//CtxStore:
+//	// Save floating & SSE control words on the stack.
+//
+//	subq   $8,%rsp
+//	stmxcsr 0(%rsp)         // 4 bytes
+//	fnstcw  4(%rsp)         // 2 bytes
+//
+//	// Save volatile registers on the stack.
+//
+//	pushq %r15
+//	pushq %r14
+//	pushq %r13
+//	pushq %r12
+//	pushq %rbx
+//
+//	// Save old context in the "from" area.
+//
+//	movq %rsp,SP_OFFSET(%rdi)
+//	movq %rbp,FP_OFFSET(%rdi)
+//
+//	// Return to thread
+//
+//	ret
+//
+//.text
+//	.align 2
+//.globl 	CtxRet
+//CtxRet:
+//	// Load new context from the "to" area.
+//
+//	movq SP_OFFSET(%rdi),%rsp
+//	movq FP_OFFSET(%rdi),%rbp
+//
+//	// Load volatile registers from the stack.
+//
+//	popq %rbx
+//	popq %r12
+//	popq %r13
+//	popq %r14
+//	popq %r15
+//
+//	// Load floating & SSE control words from the stack.
+//
+//	fldcw   4(%rsp)
+//	ldmxcsr 0(%rsp)
+//	addq   $8,%rsp
+//
+//	// Return to thread.
+//
+//	ret
+
+
 .text
 	.align 2
Index: libcfa/src/concurrency/coroutine.cfa
===================================================================
--- libcfa/src/concurrency/coroutine.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/concurrency/coroutine.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -35,5 +35,5 @@
 
 extern "C" {
-      void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage) __attribute__ ((__noreturn__));
+      void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc *) __attribute__ ((__noreturn__));
       static void _CtxCoroutine_UnwindCleanup(_Unwind_Reason_Code, struct _Unwind_Exception *) __attribute__ ((__noreturn__));
       static void _CtxCoroutine_UnwindCleanup(_Unwind_Reason_Code, struct _Unwind_Exception *) {
@@ -84,5 +84,5 @@
 void ^?{}(coroutine_desc& this) {
       if(this.state != Halted && this.state != Start) {
-            coroutine_desc * src = TL_GET( this_coroutine );
+            coroutine_desc * src = TL_GET( this_thread )->curr_cor;
             coroutine_desc * dst = &this;
 
@@ -115,5 +115,6 @@
 // Wrapper for co
 void CoroutineCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
-      // Safety note : This could cause some false positives due to preemption
+      // Safety note : Preemption must be disabled since there is a race condition
+      // kernelTLS.this_thread->curr_cor and $rsp/$rbp must agree at all times
       verify( TL_GET( preemption_state.enabled ) || TL_GET( this_processor )->do_terminate );
       disable_interrupts();
@@ -123,5 +124,5 @@
 
       // set new coroutine that task is executing
-      kernelTLS.this_coroutine = dst;
+      TL_GET( this_thread )->curr_cor = dst;
 
       // context switch to specified coroutine
@@ -134,9 +135,9 @@
 
       enable_interrupts( __cfaabi_dbg_ctx );
-      // Safety note : This could cause some false positives due to preemption
       verify( TL_GET( preemption_state.enabled ) || TL_GET( this_processor )->do_terminate );
 
+
       if( unlikely(src->cancellation != NULL) ) {
-            _CtxCoroutine_Unwind(src->cancellation);
+            _CtxCoroutine_Unwind(src->cancellation, src);
       }
 } //ctxSwitchDirect
@@ -197,6 +198,5 @@
       }
 
-      void __leave_coroutine() {
-            coroutine_desc * src = TL_GET( this_coroutine ); // optimization
+      void __leave_coroutine( coroutine_desc * src ) {
             coroutine_desc * starter = src->cancellation != 0 ? src->last : src->starter;
 
Index: libcfa/src/concurrency/coroutine.hfa
===================================================================
--- libcfa/src/concurrency/coroutine.hfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/concurrency/coroutine.hfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -46,5 +46,5 @@
 //-----------------------------------------------------------------------------
 // Public coroutine API
-static inline void suspend();
+static inline void suspend(void);
 
 forall(dtype T | is_coroutine(T))
@@ -71,5 +71,5 @@
 
 // Suspend implementation inlined for performance
-static inline void suspend() {
+static inline void suspend(void) {
 	// optimization : read TLS once and reuse it
 	// Safety note: this is preemption safe since if
@@ -77,5 +77,5 @@
 	// will also migrate which means this value will
 	// stay in syn with the TLS
-	coroutine_desc * src = TL_GET( this_coroutine );
+	coroutine_desc * src = TL_GET( this_thread )->curr_cor;
 
 	assertf( src->last != 0,
@@ -99,5 +99,5 @@
 	// will also migrate which means this value will
 	// stay in syn with the TLS
-	coroutine_desc * src = TL_GET( this_coroutine );
+	coroutine_desc * src = TL_GET( this_thread )->curr_cor;
 	coroutine_desc * dst = get_coroutine(cor);
 
@@ -129,5 +129,5 @@
 	// will also migrate which means this value will
 	// stay in syn with the TLS
-	coroutine_desc * src = TL_GET( this_coroutine );
+	coroutine_desc * src = TL_GET( this_thread )->curr_cor;
 
 	// not resuming self ?
@@ -146,4 +146,70 @@
 }
 
+
+
+// static inline bool suspend_checkpoint(void) {
+// 	// optimization : read TLS once and reuse it
+// 	// Safety note: this is preemption safe since if
+// 	// preemption occurs after this line, the pointer
+// 	// will also migrate which means this value will
+// 	// stay in syn with the TLS
+// 	// set state of current coroutine to inactive
+//       this->state = Checkpoint;
+
+//       // context switch to specified coroutine
+//       assert( src->stack.context );
+
+//       CtxStore(src->stack.context);
+
+// 	bool ret = this->state == Checkpoint;
+
+//       // set state of new coroutine to active
+//       src->state = Active;
+
+//       enable_interrupts( __cfaabi_dbg_ctx );
+//       // Safety note : This could cause some false positives due to preemption
+//       verify( TL_GET( preemption_state.enabled ) || TL_GET( this_processor )->do_terminate );
+
+//       if( unlikely(src->cancellation != NULL) ) {
+//             _CtxCoroutine_Unwind(src->cancellation);
+//       }
+
+// 	return ret;
+// }
+
+// static inline void suspend_return(void) {
+// 	// optimization : read TLS once and reuse it
+// 	// Safety note: this is preemption safe since if
+// 	// preemption occurs after this line, the pointer
+// 	// will also migrate which means this value will
+// 	// stay in syn with the TLS
+// 	coroutine_desc * src = TL_GET( this_thread )->curr_cor;
+
+// 	assertf( src->last != 0,
+// 		"Attempt to suspend coroutine \"%.256s\" (%p) that has never been resumed.\n"
+// 		"Possible cause is a suspend executed in a member called by a coroutine user rather than by the coroutine main.",
+// 		src->name, src );
+// 	assertf( src->last->state != Halted,
+// 		"Attempt by coroutine \"%.256s\" (%p) to suspend back to terminated coroutine \"%.256s\" (%p).\n"
+// 		"Possible cause is terminated coroutine's main routine has already returned.",
+// 		src->name, src, src->last->name, src->last );
+
+// 	// Safety note : Preemption must be disabled here since kernelTLS.this_coroutine must always be up to date
+//       verify( TL_GET( preemption_state.enabled ) || TL_GET( this_processor )->do_terminate );
+//       disable_interrupts();
+
+//       // set state of current coroutine to inactive
+//       src->state = src->state == Halted ? Halted : Inactive;
+
+//       // set new coroutine that task is executing
+//       kernelTLS.this_coroutine = dst;
+
+//       // context switch to specified coroutine
+//       assert( src->stack.context );
+// 	CtxRet( src->stack.context );
+
+// 	abort();
+// }
+
 // Local Variables: //
 // mode: c //
Index: libcfa/src/concurrency/invoke.c
===================================================================
--- libcfa/src/concurrency/invoke.c	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/concurrency/invoke.c	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -28,6 +28,6 @@
 
 extern void __suspend_internal(void);
-extern void __leave_coroutine(void);
-extern void __finish_creation(void);
+extern void __leave_coroutine( struct coroutine_desc * );
+extern void __finish_creation( struct coroutine_desc * );
 extern void __leave_thread_monitor( struct thread_desc * this );
 extern void disable_interrupts();
@@ -52,5 +52,5 @@
 
 	//Final suspend, should never return
-	__leave_coroutine();
+	__leave_coroutine( cor );
 	__cabi_abort( "Resumed dead coroutine" );
 }
@@ -62,10 +62,10 @@
 	__attribute((__unused__)) struct _Unwind_Exception * unwind_exception,
 	__attribute((__unused__)) struct _Unwind_Context * context,
-	__attribute((__unused__)) void * param
+	void * param
 ) {
 	if( actions & _UA_END_OF_STACK  ) {
 		// We finished unwinding the coroutine,
 		// leave it
-		__leave_coroutine();
+		__leave_coroutine( param );
 		__cabi_abort( "Resumed dead coroutine" );
 	}
@@ -75,7 +75,7 @@
 }
 
-void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage) __attribute__ ((__noreturn__));
-void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage) {
-	_Unwind_Reason_Code ret = _Unwind_ForcedUnwind( storage, _CtxCoroutine_UnwindStop, NULL );
+void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc * cor) __attribute__ ((__noreturn__));
+void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc * cor) {
+	_Unwind_Reason_Code ret = _Unwind_ForcedUnwind( storage, _CtxCoroutine_UnwindStop, cor );
 	printf("UNWIND ERROR %d after force unwind\n", ret);
 	abort();
@@ -88,10 +88,12 @@
 	void *this
 ) {
+	// Fetch the thread handle from the user defined thread structure
+	struct thread_desc* thrd = get_thread( this );
+
 	// First suspend, once the thread arrives here,
 	// the function pointer to main can be invalidated without risk
-	__finish_creation();
+	__finish_creation(&thrd->self_cor);
 
-	// Fetch the thread handle from the user defined thread structure
-	struct thread_desc* thrd = get_thread( this );
+	// Restore the last to NULL, we clobbered because of the thunk problem
 	thrd->self_cor.last = NULL;
 
Index: libcfa/src/concurrency/invoke.h
===================================================================
--- libcfa/src/concurrency/invoke.h	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/concurrency/invoke.h	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -50,5 +50,4 @@
 
 		extern thread_local struct KernelThreadData {
-			struct coroutine_desc * volatile this_coroutine;
 			struct thread_desc    * volatile this_thread;
 			struct processor      * volatile this_processor;
@@ -61,8 +60,4 @@
 		} kernelTLS __attribute__ ((tls_model ( "initial-exec" )));
 	}
-
-	static inline struct coroutine_desc * volatile active_coroutine() { return TL_GET( this_coroutine ); }
-	static inline struct thread_desc    * volatile active_thread   () { return TL_GET( this_thread    ); }
-	static inline struct processor      * volatile active_processor() { return TL_GET( this_processor ); } // UNSAFE
 	#endif
 
@@ -170,8 +165,12 @@
 			struct thread_desc * prev;
 		} node;
-     };
-
-     #ifdef __cforall
-     extern "Cforall" {
+	};
+
+	#ifdef __cforall
+	extern "Cforall" {
+		static inline struct coroutine_desc * volatile active_coroutine() { return TL_GET( this_thread )->curr_cor; }
+		static inline struct thread_desc    * volatile active_thread   () { return TL_GET( this_thread    ); }
+		static inline struct processor      * volatile active_processor() { return TL_GET( this_processor ); } // UNSAFE
+
 		static inline thread_desc * & get_next( thread_desc & this ) {
 			return this.next;
@@ -232,4 +231,6 @@
 	extern void CtxInvokeStub( void );
 	void CtxSwitch( void * from, void * to ) asm ("CtxSwitch");
+	// void CtxStore ( void * this ) asm ("CtxStore");
+	// void CtxRet   ( void * dst  ) asm ("CtxRet");
 
 	#if   defined( __i386 )
Index: libcfa/src/concurrency/kernel.cfa
===================================================================
--- libcfa/src/concurrency/kernel.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/concurrency/kernel.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -60,5 +60,4 @@
 	NULL,
 	NULL,
-	NULL,
 	{ 1, false, false }
 };
@@ -263,5 +262,5 @@
 static void returnToKernel() {
 	coroutine_desc * proc_cor = get_coroutine(kernelTLS.this_processor->runner);
-	coroutine_desc * thrd_cor = kernelTLS.this_thread->curr_cor = kernelTLS.this_coroutine;
+	coroutine_desc * thrd_cor = kernelTLS.this_thread->curr_cor;
 	ThreadCtxSwitch(thrd_cor, proc_cor);
 }
@@ -307,5 +306,4 @@
 	processor * proc = (processor *) arg;
 	kernelTLS.this_processor = proc;
-	kernelTLS.this_coroutine = NULL;
 	kernelTLS.this_thread    = NULL;
 	kernelTLS.preemption_state.[enabled, disable_count] = [false, 1];
@@ -321,5 +319,4 @@
 
 	//Set global state
-	kernelTLS.this_coroutine = get_coroutine(proc->runner);
 	kernelTLS.this_thread    = NULL;
 
@@ -351,5 +348,5 @@
 // KERNEL_ONLY
 void kernel_first_resume(processor * this) {
-	coroutine_desc * src = kernelTLS.this_coroutine;
+	coroutine_desc * src = mainThread->curr_cor;
 	coroutine_desc * dst = get_coroutine(this->runner);
 
@@ -366,7 +363,4 @@
 	// set state of current coroutine to inactive
 	src->state = src->state == Halted ? Halted : Inactive;
-
-	// set new coroutine that task is executing
-	kernelTLS.this_coroutine = dst;
 
 	// SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch.
@@ -599,5 +593,4 @@
 	kernelTLS.this_processor = mainProcessor;
 	kernelTLS.this_thread    = mainThread;
-	kernelTLS.this_coroutine = &mainThread->self_cor;
 
 	// Enable preemption
@@ -720,6 +713,6 @@
 		__cfaabi_dbg_bits_write( abort_text, len );
 
-		if ( get_coroutine(thrd) != kernelTLS.this_coroutine ) {
-			len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", kernelTLS.this_coroutine->name, kernelTLS.this_coroutine );
+		if ( &thrd->self_cor != thrd->curr_cor ) {
+			len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", thrd->curr_cor->name, thrd->curr_cor );
 			__cfaabi_dbg_bits_write( abort_text, len );
 		}
Index: libcfa/src/concurrency/thread.cfa
===================================================================
--- libcfa/src/concurrency/thread.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/concurrency/thread.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -75,5 +75,5 @@
 	coroutine_desc* thrd_c = get_coroutine(this);
 	thread_desc   * thrd_h = get_thread   (this);
-	thrd_c->last = TL_GET( this_coroutine );
+	thrd_c->last = TL_GET( this_thread )->curr_cor;
 
 	// __cfaabi_dbg_print_safe("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h);
@@ -81,5 +81,4 @@
 	disable_interrupts();
 	create_stack(&thrd_c->stack, thrd_c->stack.size);
-	kernelTLS.this_coroutine = thrd_c;
 	CtxStart(&this, CtxInvokeThread);
 	assert( thrd_c->last->stack.context );
@@ -92,6 +91,5 @@
 extern "C" {
 	// KERNEL ONLY
-	void __finish_creation(void) {
-		coroutine_desc* thrd_c = kernelTLS.this_coroutine;
+	void __finish_creation(coroutine_desc * thrd_c) {
 		ThreadCtxSwitch( thrd_c, thrd_c->last );
 	}
@@ -120,8 +118,6 @@
 	// set new coroutine that the processor is executing
 	// and context switch to it
-	kernelTLS.this_coroutine = dst;
 	assert( src->stack.context );
 	CtxSwitch( src->stack.context, dst->stack.context );
-	kernelTLS.this_coroutine = src;
 
 	// set state of new coroutine to active
Index: libcfa/src/fstream.cfa
===================================================================
--- libcfa/src/fstream.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/fstream.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Dec 24 18:33:38 2018
-// Update Count     : 304
+// Last Modified On : Sat Apr 20 12:03:43 2019
+// Update Count     : 311
 //
 
@@ -23,4 +23,5 @@
 #include <complex.h>									// creal, cimag
 #include <assert.h>
+#include <errno.h>										// errno
 
 #define IO_MSG "I/O error: "
@@ -32,4 +33,5 @@
 	os.nlOnOff = nlOnOff;
 	os.prt = prt;
+	os.sawNL = false;
 	sepSet( os, separator );
 	sepSetCur( os, sepGet( os ) );
@@ -105,7 +107,5 @@
 	#ifdef __CFA_DEBUG__
 	if ( file == 0 ) {
-		fprintf( stderr, IO_MSG "open output file \"%s\", ", name );
-		perror( 0 );
-		exit( EXIT_FAILURE );
+		abort( IO_MSG "open output file \"%s\", %s", name, strerror( errno ) );
 	} // if
 	#endif // __CFA_DEBUG__
@@ -121,5 +121,5 @@
 
 	if ( fclose( (FILE *)(os.file) ) == EOF ) {
-		perror( IO_MSG "close output" );
+		abort( IO_MSG "close output %s", strerror( errno ) );
 	} // if
 } // close
@@ -127,11 +127,9 @@
 ofstream & write( ofstream & os, const char * data, size_t size ) {
 	if ( fail( os ) ) {
-		fprintf( stderr, "attempt write I/O on failed stream\n" );
-		exit( EXIT_FAILURE );
+		abort( "attempt write I/O on failed stream\n" );
 	} // if
 
 	if ( fwrite( data, 1, size, (FILE *)(os.file) ) != size ) {
-		perror( IO_MSG "write" );
-		exit( EXIT_FAILURE );
+		abort( IO_MSG "write %s", strerror( errno ) );
 	} // if
 	return os;
@@ -144,6 +142,5 @@
 	if ( len == EOF ) {
 		if ( ferror( (FILE *)(os.file) ) ) {
-			fprintf( stderr, "invalid write\n" );
-			exit( EXIT_FAILURE );
+			abort( "invalid write\n" );
 		} // if
 	} // if
@@ -166,4 +163,5 @@
 void ?{}( ifstream & is, void * file ) {
 	is.file = file;
+	is.nlOnOff = false;
 }
 
@@ -177,4 +175,8 @@
 	open( is, name, "r" );
 }
+
+void nlOn( ifstream & os ) { os.nlOnOff = true; }
+void nlOff( ifstream & os ) { os.nlOnOff = false; }
+bool getANL( ifstream & os ) { return os.nlOnOff; }
 
 int fail( ifstream & is ) {
@@ -187,10 +189,8 @@
 
 void open( ifstream & is, const char * name, const char * mode ) {
-	FILE *file = fopen( name, mode );
+	FILE * file = fopen( name, mode );
 	#ifdef __CFA_DEBUG__
 	if ( file == 0 ) {
-		fprintf( stderr, IO_MSG "open input file \"%s\", ", name );
-		perror( 0 );
-		exit( EXIT_FAILURE );
+		abort( IO_MSG "open input file \"%s\", %s\n", name, strerror( errno ) );
 	} // if
 	#endif // __CFA_DEBUG__
@@ -206,5 +206,5 @@
 
 	if ( fclose( (FILE *)(is.file) ) == EOF ) {
-		perror( IO_MSG "close input" );
+		abort( IO_MSG "close input %s", strerror( errno ) );
 	} // if
 } // close
@@ -212,11 +212,9 @@
 ifstream & read( ifstream & is, char * data, size_t size ) {
 	if ( fail( is ) ) {
-		fprintf( stderr, "attempt read I/O on failed stream\n" );
-		exit( EXIT_FAILURE );
+		abort( "attempt read I/O on failed stream\n" );
 	} // if
 
 	if ( fread( data, size, 1, (FILE *)(is.file) ) == 0 ) {
-		perror( IO_MSG "read" );
-		exit( EXIT_FAILURE );
+		abort( IO_MSG "read %s", strerror( errno ) );
 	} // if
 	return is;
@@ -225,11 +223,9 @@
 ifstream &ungetc( ifstream & is, char c ) {
 	if ( fail( is ) ) {
-		fprintf( stderr, "attempt ungetc I/O on failed stream\n" );
-		exit( EXIT_FAILURE );
+		abort( "attempt ungetc I/O on failed stream\n" );
 	} // if
 
 	if ( ungetc( c, (FILE *)(is.file) ) == EOF ) {
-		perror( IO_MSG "ungetc" );
-		exit( EXIT_FAILURE );
+		abort( IO_MSG "ungetc %s", strerror( errno ) );
 	} // if
 	return is;
@@ -243,6 +239,5 @@
 	if ( len == EOF ) {
 		if ( ferror( (FILE *)(is.file) ) ) {
-			fprintf( stderr, "invalid read\n" );
-			exit( EXIT_FAILURE );
+			abort( "invalid read\n" );
 		} // if
 	} // if
Index: libcfa/src/fstream.hfa
===================================================================
--- libcfa/src/fstream.hfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/fstream.hfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Dec 24 18:33:41 2018
-// Update Count     : 149
+// Last Modified On : Sat Apr 20 12:03:58 2019
+// Update Count     : 151
 //
 
@@ -73,7 +73,11 @@
 struct ifstream {
 	void * file;
+	bool nlOnOff;
 }; // ifstream
 
 // public
+void nlOn( ifstream & );
+void nlOff( ifstream & );
+bool getANL( ifstream & );
 int fail( ifstream & is );
 int eof( ifstream & is );
Index: libcfa/src/gmp.hfa
===================================================================
--- libcfa/src/gmp.hfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/gmp.hfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Tue Apr 19 08:43:43 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec  4 23:25:51 2018
-// Update Count     : 22
+// Last Modified On : Sat Apr 20 09:01:52 2019
+// Update Count     : 24
 //
 
@@ -271,5 +271,5 @@
 
 	void ?|?( ostype & os, Int mp ) {
-		(ostype)(os | mp); if ( getANL( os ) ) nl( os );
+		(ostype)(os | mp); nl( os );
 	} // ?|?
 } // distribution
Index: libcfa/src/heap.cfa
===================================================================
--- libcfa/src/heap.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/heap.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Tue Dec 19 21:58:35 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Sep  6 09:01:30 2018
-// Update Count     : 513
+// Last Modified On : Fri Mar 22 13:43:10 2019
+// Update Count     : 514
 //
 
@@ -1034,4 +1034,4 @@
 // Local Variables: //
 // tab-width: 4 //
-// compile-command: "cfa -nodebug -O2 heap.c" //
+// compile-command: "cfa -nodebug -O2 heap.cfa" //
 // End: //
Index: libcfa/src/iostream.cfa
===================================================================
--- libcfa/src/iostream.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/iostream.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Mar  4 20:57:24 2019
-// Update Count     : 593
+// Last Modified On : Sat Apr 20 14:02:43 2019
+// Update Count     : 617
 //
 
@@ -396,5 +396,11 @@
 
 	istype & ?|?( istype & is, char & c ) {
-		fmt( is, "%c", &c );							// must pass pointer through varg to fmt
+		char temp;
+		for () {
+			fmt( is, "%c", &temp );							// must pass pointer through varg to fmt
+			// do not overwrite parameter with newline unless appropriate
+			if ( temp != '\n' || getANL( is ) ) { c = temp; break; }
+			if ( eof( is ) ) break;
+		} // for
 		return is;
 	} // ?|?
@@ -498,4 +504,14 @@
 		return is;
 	} // nl
+
+	istype & nlOn( istype & is ) {
+		nlOn( is );										// call void returning
+		return is;
+	} // nlOn
+
+	istype & nlOff( istype & is ) {
+		nlOff( is );									// call void returning
+		return is;
+	} // nlOff
 } // distribution
 
Index: libcfa/src/iostream.hfa
===================================================================
--- libcfa/src/iostream.hfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/iostream.hfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Feb 26 16:57:22 2019
-// Update Count     : 221
+// Last Modified On : Sat Apr 20 12:04:07 2019
+// Update Count     : 226
 //
 
@@ -149,4 +149,7 @@
 
 trait istream( dtype istype ) {
+	void nlOn( istype & );								// read newline
+	void nlOff( istype & );								// scan newline
+	bool getANL( istype & );							// get scan newline (on/off)
 	int fail( istype & );
 	int eof( istype & );
@@ -187,4 +190,6 @@
 
 	// manipulators
+	istype & nlOn( istype & );
+	istype & nlOff( istype & );
 	istype & ?|?( istype &, istype & (*)( istype & ) );
 	istype & nl( istype & is );
Index: libcfa/src/rational.cfa
===================================================================
--- libcfa/src/rational.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/rational.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Wed Apr  6 17:54:28 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sun Dec 23 22:56:49 2018
-// Update Count     : 170
+// Last Modified On : Thu Mar 28 17:33:03 2019
+// Update Count     : 181
 //
 
@@ -35,6 +35,5 @@
 	static RationalImpl simplify( RationalImpl & n, RationalImpl & d ) {
 		if ( d == (RationalImpl){0} ) {
-			serr | "Invalid rational number construction: denominator cannot be equal to 0.";
-			exit( EXIT_FAILURE );
+			abort( "Invalid rational number construction: denominator cannot be equal to 0.\n" );
 		} // exit
 		if ( d < (RationalImpl){0} ) { d = -d; n = -n; } // move sign to numerator
@@ -54,6 +53,5 @@
 	void ?{}( Rational(RationalImpl) & r, RationalImpl n, RationalImpl d ) {
 		RationalImpl t = simplify( n, d );				// simplify
-		r.numerator = n / t;
-		r.denominator = d / t;
+		r.[numerator, denominator] = [n / t, d / t];
 	} // rational
 
@@ -78,6 +76,5 @@
 		RationalImpl prev = r.numerator;
 		RationalImpl t = gcd( abs( n ), r.denominator ); // simplify
-		r.numerator = n / t;
-		r.denominator = r.denominator / t;
+		r.[numerator, denominator] = [n / t, r.denominator / t];
 		return prev;
 	} // numerator
@@ -86,6 +83,5 @@
 		RationalImpl prev = r.denominator;
 		RationalImpl t = simplify( r.numerator, d );	// simplify
-		r.numerator = r.numerator / t;
-		r.denominator = d / t;
+		r.[numerator, denominator] = [r.numerator / t, d / t];
 		return prev;
 	} // denominator
@@ -120,20 +116,16 @@
 
 	Rational(RationalImpl) +?( Rational(RationalImpl) r ) {
-		Rational(RationalImpl) t = { r.numerator, r.denominator };
-		return t;
+		return (Rational(RationalImpl)){ r.numerator, r.denominator };
 	} // +?
 
 	Rational(RationalImpl) -?( Rational(RationalImpl) r ) {
-		Rational(RationalImpl) t = { -r.numerator, r.denominator };
-		return t;
+		return (Rational(RationalImpl)){ -r.numerator, r.denominator };
 	} // -?
 
 	Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
 		if ( l.denominator == r.denominator ) {			// special case
-			Rational(RationalImpl) t = { l.numerator + r.numerator, l.denominator };
-			return t;
+			return (Rational(RationalImpl)){ l.numerator + r.numerator, l.denominator };
 		} else {
-			Rational(RationalImpl) t = { l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator };
-			return t;
+			return (Rational(RationalImpl)){ l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator };
 		} // if
 	} // ?+?
@@ -141,24 +133,19 @@
 	Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
 		if ( l.denominator == r.denominator ) {			// special case
-			Rational(RationalImpl) t = { l.numerator - r.numerator, l.denominator };
-			return t;
+			return (Rational(RationalImpl)){ l.numerator - r.numerator, l.denominator };
 		} else {
-			Rational(RationalImpl) t = { l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator };
-			return t;
+			return (Rational(RationalImpl)){ l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator };
 		} // if
 	} // ?-?
 
 	Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
-		Rational(RationalImpl) t = { l.numerator * r.numerator, l.denominator * r.denominator };
-		return t;
+		return (Rational(RationalImpl)){ l.numerator * r.numerator, l.denominator * r.denominator };
 	} // ?*?
 
 	Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
 		if ( r.numerator < (RationalImpl){0} ) {
-			r.numerator = -r.numerator;
-			r.denominator = -r.denominator;
+			r.[numerator, denominator] = [-r.numerator, -r.denominator];
 		} // if
-		Rational(RationalImpl) t = { l.numerator * r.denominator, l.denominator * r.numerator };
-		return t;
+		return (Rational(RationalImpl)){ l.numerator * r.denominator, l.denominator * r.numerator };
 	} // ?/?
 
@@ -167,7 +154,6 @@
 	forall( dtype istype | istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } )
 	istype & ?|?( istype & is, Rational(RationalImpl) & r ) {
-		RationalImpl t;
 		is | r.numerator | r.denominator;
-		t = simplify( r.numerator, r.denominator );
+		RationalImpl t = simplify( r.numerator, r.denominator );
 		r.numerator /= t;
 		r.denominator /= t;
@@ -185,4 +171,13 @@
 	} // distribution
 } // distribution
+
+forall( otype RationalImpl | arithmetic( RationalImpl ) | { RationalImpl ?\?( RationalImpl, unsigned long ); } )
+Rational(RationalImpl) ?\?( Rational(RationalImpl) x, long int y ) {
+	if ( y < 0 ) {
+		return (Rational(RationalImpl)){ x.denominator \ -y, x.numerator \ -y };
+	} else {
+		return (Rational(RationalImpl)){ x.numerator \ y, x.denominator \ y };
+	} // if
+}
 
 // conversion
Index: libcfa/src/rational.hfa
===================================================================
--- libcfa/src/rational.hfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/rational.hfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -12,6 +12,6 @@
 // Created On       : Wed Apr  6 17:56:25 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec  4 23:07:46 2018
-// Update Count     : 106
+// Last Modified On : Tue Mar 26 23:16:10 2019
+// Update Count     : 109
 //
 
@@ -98,4 +98,7 @@
 } // distribution
 
+forall( otype RationalImpl | arithmetic( RationalImpl ) |{RationalImpl ?\?( RationalImpl, unsigned long );} )
+Rational(RationalImpl) ?\?( Rational(RationalImpl) x, long int y );
+
 // conversion
 forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
Index: libcfa/src/stdhdr/stdbool.h
===================================================================
--- libcfa/src/stdhdr/stdbool.h	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/stdhdr/stdbool.h	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,10 +10,21 @@
 // Created On       : Mon Jul  4 23:25:26 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul  5 20:39:51 2016
-// Update Count     : 12
+// Last Modified On : Mon Mar 25 08:00:08 2019
+// Update Count     : 15
 // 
 
 extern "C" {
 #include_next <stdbool.h>								// has internal check for multiple expansion
+
+// allows printing as true/false
+#if defined( true )
+#undef true
+#define true ((_Bool)1)
+#endif // true
+
+#if defined( false )
+#undef false
+#define false ((_Bool)0)
+#endif // false
 } // extern "C"
 
Index: libcfa/src/stdlib.hfa
===================================================================
--- libcfa/src/stdlib.hfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ libcfa/src/stdlib.hfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Thu Jan 28 17:12:35 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Dec 17 15:37:45 2018
-// Update Count     : 346
+// Last Modified On : Wed Apr 24 17:35:43 2019
+// Update Count     : 352
 //
 
@@ -40,11 +40,4 @@
 	} // malloc
 
-	// T & malloc( void ) {
-	// 	int & p = *(T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc
-	// 	printf( "& malloc %p\n", &p );
-	// 	return p;
-	// 	//	return (T &)*(T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc
-	// } // malloc
-
 	T * calloc( size_t dim ) {
 		return (T *)(void *)calloc( dim, sizeof(T) );	// C calloc
@@ -76,5 +69,5 @@
 	T * alloc( char fill ) {
 		T * ptr = (T *)(void *)malloc( (size_t)sizeof(T) );	// C malloc
-		return (T *)memset( ptr, (int)fill, sizeof(T) );	// initial with fill value
+		return (T *)memset( ptr, (int)fill, sizeof(T) ); // initialize with fill value
 	} // alloc
 
@@ -84,6 +77,6 @@
 
 	T * alloc( size_t dim, char fill ) {
-		T * ptr = (T *)(void *)malloc( dim * (size_t)sizeof(T) ); // C malloc
-		return (T *)memset( ptr, (int)fill, dim * sizeof(T) );	  // initial with fill value
+		T * ptr = (T *)(void *)malloc( dim * (size_t)sizeof(T) ); // C calloc
+		return (T *)memset( ptr, (int)fill, dim * sizeof(T) ); // initialize with fill value
 	} // alloc
 
Index: longrun_tests/Makefile.am
===================================================================
--- longrun_tests/Makefile.am	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ longrun_tests/Makefile.am	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,87 @@
+######################## -*- Mode: Makefile-Automake -*- ######################
+##
+## 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.
+##
+## Makefile.am --
+##
+## Author           : Thierry Delisle
+## Created On       : Fri Jun 16 10:57:34 2017
+## Last Modified By :
+## Last Modified On :
+## Update Count     : 0
+###############################################################################
+
+AUTOMAKE_OPTIONS = foreign    # do not require all the GNU file names
+ACLOCAL_AMFLAGS  = -I automake
+
+include $(top_srcdir)/src/cfa.make
+
+repeats=10
+max_time=600
+preempt=10ul\`ms
+debug=-debug
+type=LONG
+
+REPEAT = $(abs_top_builddir)/tools/repeat
+WATCHDOG = $(abs_top_builddir)/tools/watchdog
+TIME = /usr/bin/time -f "%E"
+
+UPDATED_TYPE = $(shell $(srcdir)/update-type $(type))
+
+BUILD_FLAGS =
+AM_CFAFLAGS = \
+	-g \
+	-Wall \
+	-Wno-unused-function \
+	-quiet \
+	-O2 \
+	-DPREEMPTION_RATE=$(preempt) \
+	-I$(abs_top_srcdir)/tests \
+	-I$(srcdir) \
+	-DTEST_$(shell cat .type | tr a-z A-Z) \
+	-in-tree
+
+TESTS = block coroutine create disjoint enter enter3 processor stack wait yield
+
+# .INTERMEDIATE: $(TESTS)
+
+all-local: $(TESTS:=.run)
+
+runall : $(TESTS:=.run)
+	@ echo "All programs terminated normally"
+
+watchall : $(TESTS:=.watch)
+	@ echo "All programs terminated normally"
+
+compileall : $(TESTS)
+	@ echo "Compiled"
+
+clean-local:
+	rm -f $(TESTS) core* out.log .type
+
+% : %.cfa $(CFACC) $(UPDATED_TYPE)
+	$(AM_V_CFA)$(CFACOMPILE) $(<) $(debug) -o $(@)
+
+%.run : % $(REPEAT)
+	@ time $(REPEAT) -r out.log -i -s $(repeats) timeout $(max_time) ./$(<)
+	@ rm $(<)
+	@ echo -e "$(<): SUCCESS\n"
+
+%.watch : % $(WATCHDOG)
+	@ time $(WATCHDOG} ./$(<)
+	@ rm $(<)
+	@ echo -e "$(<): SUCCESS\n"
+
+%.time : % $(REPEAT)
+	@ $(REPEAT) -i -s -- $(repeats) $(TIME) -a -o times.log ./$(<)
+	@ rm $(<)
+	@ echo -e "$(<): SUCCESS\n"
+
+$(REPEAT): $(abs_top_builddir)/tools/Makefile
+	@+make -C $(abs_top_builddir)/tools/
+
+$(WATCHDOG): $(abs_top_builddir)/tools/Makefile
+	@+make -C $(abs_top_builddir)/tools/
Index: longrun_tests/Makefile.in
===================================================================
--- longrun_tests/Makefile.in	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ longrun_tests/Makefile.in	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,1005 @@
+# Makefile.in generated by automake 1.15 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2014 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+######################## -*- Mode: Makefile-Automake -*- ######################
+###############################################################################
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = longrun_tests
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/automake/libtool.m4 \
+	$(top_srcdir)/automake/ltoptions.m4 \
+	$(top_srcdir)/automake/ltsugar.m4 \
+	$(top_srcdir)/automake/ltversion.m4 \
+	$(top_srcdir)/automake/lt~obsolete.m4 \
+	$(top_srcdir)/automake/cfa.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red='[0;31m'; \
+    grn='[0;32m'; \
+    lgn='[1;32m'; \
+    blu='[1;34m'; \
+    mgn='[0;35m'; \
+    brg='[1m'; \
+    std='[m'; \
+  fi; \
+}
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/automake/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/automake/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+	$(top_srcdir)/automake/test-driver $(top_srcdir)/src/cfa.make
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_IN_TREE_FLAGS = @BUILD_IN_TREE_FLAGS@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFACC = @CFACC@
+CFACPP = @CFACPP@
+CFA_BACKEND_CC = @CFA_BACKEND_CC@
+CFA_BINDIR = @CFA_BINDIR@
+CFA_FLAGS = @CFA_FLAGS@
+CFA_INCDIR = @CFA_INCDIR@
+CFA_LIBDIR = @CFA_LIBDIR@
+CFA_NAME = @CFA_NAME@
+CFA_PREFIX = @CFA_PREFIX@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DRIVER_DIR = @DRIVER_DIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+HOST_FLAGS = @HOST_FLAGS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@
+LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TARGET_HOSTS = @TARGET_HOSTS@
+VERSION = @VERSION@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign    # do not require all the GNU file names
+ACLOCAL_AMFLAGS = -I automake
+CFACOMPILE = $(CFACC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(CFAFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCFACOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CFACC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(CFAFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+
+AM_V_CFA = $(am__v_CFA_@AM_V@)
+am__v_CFA_ = $(am__v_CFA_@AM_DEFAULT_V@)
+am__v_CFA_0 = @echo "  CFA     " $@;
+am__v_CFA_1 = 
+AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
+am__v_JAVAC_ = $(am__v_JAVAC_@AM_DEFAULT_V@)
+am__v_JAVAC_0 = @echo "  JAVAC   " $@;
+am__v_JAVAC_1 = 
+AM_V_GOC = $(am__v_GOC_@AM_V@)
+am__v_GOC_ = $(am__v_GOC_@AM_DEFAULT_V@)
+am__v_GOC_0 = @echo "  GOC     " $@;
+am__v_GOC_1 = 
+UPPCC = u++
+UPPCOMPILE = $(UPPCC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_UPPFLAGS) $(UPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_CFLAGS) $(CFLAGS)
+AM_V_UPP = $(am__v_UPP_@AM_V@)
+am__v_UPP_ = $(am__v_UPP_@AM_DEFAULT_V@)
+am__v_UPP_0 = @echo "  UPP     " $@;
+am__v_UPP_1 = 
+repeats = 10
+max_time = 600
+preempt = 10ul\`ms
+debug = -debug
+type = LONG
+REPEAT = $(abs_top_builddir)/tools/repeat
+WATCHDOG = $(abs_top_builddir)/tools/watchdog
+TIME = /usr/bin/time -f "%E"
+UPDATED_TYPE = $(shell $(srcdir)/update-type $(type))
+BUILD_FLAGS = 
+AM_CFAFLAGS = \
+	-g \
+	-Wall \
+	-Wno-unused-function \
+	-quiet \
+	-O2 \
+	-DPREEMPTION_RATE=$(preempt) \
+	-I$(abs_top_srcdir)/tests \
+	-I$(srcdir) \
+	-DTEST_$(shell cat .type | tr a-z A-Z) \
+	-in-tree
+
+TESTS = block coroutine create disjoint enter enter3 processor stack wait yield
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cfa .lo .log .o .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am $(top_srcdir)/src/cfa.make $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign longrun_tests/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign longrun_tests/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+$(top_srcdir)/src/cfa.make $(am__empty):
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	elif test -n "$$redo_logs"; then \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all 
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+block.log: block
+	@p='block'; \
+	b='block'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+coroutine.log: coroutine
+	@p='coroutine'; \
+	b='coroutine'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+create.log: create
+	@p='create'; \
+	b='create'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+disjoint.log: disjoint
+	@p='disjoint'; \
+	b='disjoint'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+enter.log: enter
+	@p='enter'; \
+	b='enter'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+enter3.log: enter3
+	@p='enter3'; \
+	b='enter3'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+processor.log: processor
+	@p='processor'; \
+	b='processor'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+stack.log: stack
+	@p='stack'; \
+	b='stack'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+wait.log: wait
+	@p='wait'; \
+	b='wait'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+yield.log: yield
+	@p='yield'; \
+	b='yield'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@	@p='$<'; \
+@am__EXEEXT_TRUE@	$(am__set_b); \
+@am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile all-local
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: all all-am all-local check check-TESTS check-am clean \
+	clean-generic clean-libtool clean-local cscopelist-am ctags-am \
+	distclean distclean-generic distclean-libtool distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am recheck tags-am \
+	uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+.cfa.o:
+	$(AM_V_CFA)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+	$(CFACOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+	$(am__mv) $$depbase.Tpo $$depbase.Po
+
+.cfa.lo:
+	$(AM_V_CFA)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+	$(LTCFACOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+	$(am__mv) $$depbase.Tpo $$depbase.Plo
+
+# .INTERMEDIATE: $(TESTS)
+
+all-local: $(TESTS:=.run)
+
+runall : $(TESTS:=.run)
+	@ echo "All programs terminated normally"
+
+watchall : $(TESTS:=.watch)
+	@ echo "All programs terminated normally"
+
+compileall : $(TESTS)
+	@ echo "Compiled"
+
+clean-local:
+	rm -f $(TESTS) core* out.log .type
+
+% : %.cfa $(CFACC) $(UPDATED_TYPE)
+	$(AM_V_CFA)$(CFACOMPILE) $(<) $(debug) -o $(@)
+
+%.run : % $(REPEAT)
+	@ time $(REPEAT) -r out.log -i -s $(repeats) timeout $(max_time) ./$(<)
+	@ rm $(<)
+	@ echo -e "$(<): SUCCESS\n"
+
+%.watch : % $(WATCHDOG)
+	@ time $(WATCHDOG} ./$(<)
+	@ rm $(<)
+	@ echo -e "$(<): SUCCESS\n"
+
+%.time : % $(REPEAT)
+	@ $(REPEAT) -i -s -- $(repeats) $(TIME) -a -o times.log ./$(<)
+	@ rm $(<)
+	@ echo -e "$(<): SUCCESS\n"
+
+$(REPEAT): $(abs_top_builddir)/tools/Makefile
+	@+make -C $(abs_top_builddir)/tools/
+
+$(WATCHDOG): $(abs_top_builddir)/tools/Makefile
+	@+make -C $(abs_top_builddir)/tools/
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
Index: longrun_tests/block.cfa
===================================================================
--- longrun_tests/block.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ longrun_tests/block.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,1 @@
+../tests/concurrent/signal/block.cfa
Index: longrun_tests/coroutine.cfa
===================================================================
--- longrun_tests/coroutine.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ longrun_tests/coroutine.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,1 @@
+../tests/concurrent/coroutineYield.cfa
Index: longrun_tests/create.cfa
===================================================================
--- longrun_tests/create.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ longrun_tests/create.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,27 @@
+#include <kernel.hfa>
+#include <thread.hfa>
+#include <time.hfa>
+
+#include "long_tests.hfa"
+
+#ifndef PREEMPTION_RATE
+#error PREEMPTION_RATE not defined in makefile
+#endif
+
+Duration default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+static const unsigned long N = 60_000ul;
+
+thread worker_t {};
+
+void main(worker_t & this) {}
+
+int main(int argc, char* argv[]) {
+	processor p;
+	for(int i = 0; TEST(i < N); i++) {
+		worker_t w[7];
+		KICK_WATCHDOG;
+	}
+}
Index: longrun_tests/disjoint.cfa
===================================================================
--- longrun_tests/disjoint.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ longrun_tests/disjoint.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,1 @@
+../tests/concurrent/signal/disjoint.cfa
Index: longrun_tests/enter.cfa
===================================================================
--- longrun_tests/enter.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ longrun_tests/enter.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,37 @@
+#include <kernel.hfa>
+#include <monitor.hfa>
+#include <thread.hfa>
+#include <time.hfa>
+
+#define __kick_rate 75000ul
+#include "long_tests.hfa"
+
+#ifndef PREEMPTION_RATE
+#error PREEMPTION_RATE not defined in makefile
+#endif
+
+Duration default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+static const unsigned long N  = 2_100_000ul;
+
+monitor mon_t {};
+void foo( mon_t & mutex this ) {
+	KICK_WATCHDOG;
+}
+
+mon_t mon;
+thread worker_t {};
+void main( worker_t & this ) {
+	for( unsigned long i = 0; TEST(i < N); i++ ) {
+		foo( mon );
+	}
+}
+
+int main(int argc, char * argv[] ) {
+	processor p;
+	{
+		worker_t w[7];
+	}
+}
Index: longrun_tests/enter3.cfa
===================================================================
--- longrun_tests/enter3.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ longrun_tests/enter3.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,45 @@
+#include <kernel.hfa>
+#include <monitor.hfa>
+#include <thread.hfa>
+#include <time.hfa>
+
+#define __kick_rate 75000ul
+#include "long_tests.hfa"
+
+#ifndef PREEMPTION_RATE
+#error PREEMPTION_RATE not defined in makefile
+#endif
+
+Duration default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+static const unsigned long N  = 500_000ul;
+
+monitor mon_t {};
+
+mon_t mon1, mon2, mon3;
+
+void foo( mon_t & mutex a, mon_t & mutex b, mon_t & mutex c ) {
+	KICK_WATCHDOG;
+}
+
+thread worker_t {};
+
+void main( worker_t & this ) {
+	for( unsigned long i = 0; TEST(i < N); i++ ) {
+		foo( mon1, mon2, mon3 );
+	}
+}
+
+extern "C" {
+static worker_t * workers;
+}
+
+int main(int argc, char * argv[] ) {
+	processor p;
+	{
+		worker_t w[7];
+		workers = w;
+	}
+}
Index: longrun_tests/preempt.cfa
===================================================================
--- longrun_tests/preempt.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ longrun_tests/preempt.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,1 @@
+../tests/concurrent/preempt.cfa
Index: longrun_tests/processor.cfa
===================================================================
--- longrun_tests/processor.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ longrun_tests/processor.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,33 @@
+#include <kernel.hfa>
+#include <thread.hfa>
+#include <time.hfa>
+
+#include <unistd.h>
+
+#include "long_tests.hfa"
+
+#ifndef PREEMPTION_RATE
+#error PREEMPTION_RATE not defined in makefile
+#endif
+
+Duration default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+static const unsigned long N = 50_000ul;
+
+int main(int argc, char* argv[]) {
+	processor * p[15];
+	for ( int pi = 0; pi < 15; pi++ ) {
+		p[pi] = new();
+	}
+	for ( int i = 0; TEST(i < N); i++) {
+		int pi = i % 15;
+		delete( p[pi] );
+		p[pi] = new();
+		KICK_WATCHDOG;
+	}
+	for ( int pi = 0; pi < 15; pi++ ) {
+		delete( p[pi] );
+	}
+}
Index: longrun_tests/stack.cfa
===================================================================
--- longrun_tests/stack.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ longrun_tests/stack.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,46 @@
+#include <kernel.hfa>
+#include <math.hfa>
+#include <thread.hfa>
+#include <time.hfa>
+
+#define __kick_rate 5000000ul
+#include "long_tests.hfa"
+
+#ifndef PREEMPTION_RATE
+#error PREEMPTION_RATE not defined in makefile
+#endif
+
+Duration default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+thread worker_t {};
+
+void main(worker_t & this) {
+	while(TEST(0)) {
+		volatile long long p = 5_021_609ul;
+		volatile long long a = 326_417ul;
+		volatile long long n = 1l;
+		for (volatile long long i = 0; i < p; i++) {
+			n *= a;
+			n %= p;
+			KICK_WATCHDOG;
+		}
+
+		if( !TEST(n == a) ) {
+			abort();
+		}
+	}
+}
+
+extern "C" {
+static worker_t * workers;
+}
+
+int main(int argc, char* argv[]) {
+	processor p;
+	{
+		worker_t w[7];
+		workers = w;
+	}
+}
Index: longrun_tests/update-type
===================================================================
--- longrun_tests/update-type	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ longrun_tests/update-type	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+if [ "$#" -ne 1 ]
+then
+	echo "illegal number of parameters, must be 1 was $#"
+	exit
+fi
+
+NEW="$(echo $1 | tr a-z A-Z)"
+TYPE_FILE=".type"
+if [ -f "$TYPE_FILE" ]
+then
+	OLD="$(cat $TYPE_FILE | tr a-z A-Z)"
+	if [ $OLD == $NEW ]
+	then
+		echo > /dev/null
+		# echo "$TYPE_FILE stayed unchanged"
+	else
+		echo "$NEW" > "$TYPE_FILE"
+		# echo "$TYPE_FILE changed from '$OLD' to '$NEW'"
+	fi
+else
+	echo "$NEW" > "$TYPE_FILE"
+fi
+echo "$TYPE_FILE"
Index: longrun_tests/wait.cfa
===================================================================
--- longrun_tests/wait.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ longrun_tests/wait.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,1 @@
+../tests/concurrent/signal/wait.cfa
Index: longrun_tests/yield.cfa
===================================================================
--- longrun_tests/yield.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ longrun_tests/yield.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,41 @@
+#include <kernel.hfa>
+#include <thread.hfa>
+#include <time.hfa>
+
+#define __kick_rate 550000ul
+#include "long_tests.hfa"
+
+#ifndef PREEMPTION_RATE
+#error PREEMPTION_RATE not defined in makefile
+#endif
+
+Duration default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+#ifdef TEST_LONG
+static const unsigned long N = 9_750_000ul;
+#else
+static const unsigned long N = 325_000ul;
+#endif
+
+thread worker_t {};
+
+void main(worker_t & this) {
+	for(int i = 0; TEST(i < N); i++) {
+		yield();
+		KICK_WATCHDOG;
+	}
+}
+
+extern "C" {
+static worker_t * workers;
+}
+
+int main(int argc, char* argv[]) {
+	processor p;
+	{
+		worker_t w[7];
+		workers = w;
+	}
+}
Index: src/Common/PassVisitor.cc
===================================================================
--- src/Common/PassVisitor.cc	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/Common/PassVisitor.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -17,2 +17,3 @@
 
 PassVisitorStats pass_visitor_stats;
+Stats::Counters::SimpleCounter* BaseSyntaxNode::new_nodes = nullptr;
Index: src/Common/PersistentMap.h
===================================================================
--- src/Common/PersistentMap.h	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ src/Common/PersistentMap.h	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,292 @@
+//
+// 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.
+//
+// PersistentMap.h --
+//
+// Author           : Aaron B. Moss
+// Created On       : Thu Mar  7 15:50:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Thu Mar  7 15:50:00 2019
+// Update Count     : 1
+//
+
+#pragma once
+
+#include <cassert>        // for assertf
+#include <cstddef>        // for size_t
+#include <functional>     // for hash, equal_to
+#include <memory>         // for shared_ptr, enable_shared_from_this, make_shared
+#include <unordered_map>  // for unordered_map
+#include <utility>        // for forward, move
+
+/// Wraps a hash table in a persistent data structure, using a technique based 
+/// on the persistent array in Conchon & Filliatre "A Persistent Union-Find 
+/// Data Structure"
+
+template<typename Key, typename Val,
+         typename Hash = std::hash<Key>, typename Eq = std::equal_to<Key>>
+class PersistentMap 
+	: public std::enable_shared_from_this<PersistentMap<Key, Val, Hash, Eq>> {
+public:
+	/// Type of this class
+	using Self = PersistentMap<Key, Val, Hash, Eq>;
+	/// Type of pointer to this class
+	using Ptr = std::shared_ptr<Self>;
+
+	/// Types of version nodes
+	enum Mode { 
+		BASE,  ///< Root node of version tree
+		REM,   ///< Key removal node
+		INS,   ///< Key update node
+		UPD    ///< Key update node
+	};
+
+private:
+	using Base = std::unordered_map<Key, Val, Hash, Eq>;
+
+	/// Insertion/update node
+	struct Ins {
+		Ptr base;  ///< Modified map
+		Key key;   ///< Key inserted
+		Val val;   ///< Value stored
+
+		template<typename P, typename K, typename V>
+		Ins(P&& p, K&& k, V&& v)
+		: base(std::forward<P>(p)), key(std::forward<K>(k)), val(std::forward<V>(v)) {}
+	};
+
+	/// Removal node
+	struct Rem {
+		Ptr base;  ///< Modified map
+		Key key;   ///< Key removed
+		
+		template<typename P, typename K>
+		Rem(P&& p, K&& k) : base(std::forward<P>(p)), key(std::forward<K>(k)) {}
+	};
+
+	/// Underlying storage
+	union Data {
+		char def;
+		Base base;
+		Ins ins;
+		Rem rem;
+
+		Data() : def('\0') {}
+		~Data() {}
+	} data;
+
+	/// Type of node
+	mutable Mode mode;
+
+	/// get mutable reference as T
+	template<typename T>
+	T& as() { return reinterpret_cast<T&>(data); }
+
+	/// get const reference as T
+	template<typename T>
+	const T& as() const { return reinterpret_cast<const T&>(data); }
+
+	/// get rvalue reference as T
+	template<typename T>
+	T&& take_as() { return std::move(as<T>()); }
+
+	/// initialize as T
+	template<typename T, typename... Args>
+	void init( Args&&... args ) {
+		new( &as<T>() ) T { std::forward<Args>(args)... };
+	}
+
+	/// reset as current mode
+	void reset() {
+		switch( mode ) {
+			case BASE:          as<Base>().~Base(); break;
+			case REM:           as<Rem>().~Rem();   break;
+			case INS: case UPD: as<Ins>().~Ins();   break;
+		}
+	}
+
+	/// reset as base
+	void reset_as_base() {
+		as<Base>().~Base();
+	}
+
+public:
+	using key_type = typename Base::key_type;
+	using mapped_type = typename Base::mapped_type;
+	using value_type = typename Base::value_type;
+	using size_type = typename Base::size_type;
+	using difference_type = typename Base::difference_type;
+	using iterator = typename Base::const_iterator;
+
+	PersistentMap() : data(), mode(BASE) { init<Base>(); }
+
+	PersistentMap( Base&& b ) : data(), mode(BASE) { init<Base>(std::move(b)); }
+
+	PersistentMap( const Self& o ) = delete;
+
+	Self& operator= ( const Self& o ) = delete;
+
+	~PersistentMap() { reset(); }
+
+	/// Create a pointer to a new, empty persistent map
+	static Ptr new_ptr() { return std::make_shared<Self>(); }
+
+	/// reroot persistent map at current node
+	void reroot() const {
+		// recursive base case
+		if ( mode == BASE ) return;
+
+		// reroot base
+		Self* mut_this = const_cast<Self*>(this);
+		Ptr base = ( mode == REM ) ? mut_this->as<Rem>().base : mut_this->as<Ins>().base;
+		base->reroot();
+
+		// remove map from base
+		Base base_map = base->template take_as<Base>();
+		base->reset_as_base();
+
+		// switch base to inverse of self and mutate base map
+		switch ( mode ) {
+			case REM: {
+				Rem& self = mut_this->as<Rem>();
+				auto it = base_map.find( self.key );
+
+				base->template init<Ins>( 
+						mut_this->shared_from_this(), std::move(self.key), std::move(it->second) );
+				base->mode = INS;
+
+				base_map.erase( it );
+				break;
+			}
+			case INS: {
+				Ins& self = mut_this->as<Ins>();
+
+				base->template init<Rem>( mut_this->shared_from_this(), self.key );
+				base->mode = REM;
+
+				base_map.emplace( std::move(self.key), std::move(self.val) );
+				break;
+			}
+			case UPD: {
+				Ins& self = mut_this->as<Ins>();
+				auto it = base_map.find( self.key );
+
+				base->template init<Ins>( 
+						mut_this->shared_from_this(), std::move(self.key), std::move(it->second) );
+				base->mode = UPD;
+
+				it->second = std::move(self.val);
+				break;
+			}
+			case BASE: assertf(false, "unreachable"); break;
+		}
+
+		// set base map into self
+		mut_this->reset();
+		mut_this->init<Base>( std::move(base_map) );
+		mode = BASE;
+	}
+
+private:
+	/// the base after rerooting at the current node
+	const Base& rerooted() const {
+		reroot();
+		return as<Base>();
+	}
+
+public:
+	/// true iff the map is empty
+	bool empty() const { return rerooted().empty(); }
+
+	/// number of entries in map
+	size_type size() const { return rerooted().size(); }
+
+	/// begin iterator for map; may be invalidated by calls to non-iteration functions
+	/// or functions on other maps in the same tree
+	iterator begin() const { return rerooted().begin(); }
+
+	/// end iterator for map; may be invalidated by calls to non-iteration functions
+	/// or functions on other maps in the same tree
+	iterator end() const { return rerooted().end(); }
+
+	/// underlying map iterator for value
+	iterator find(const Key& k) const { return rerooted().find( k ); }
+
+	/// check if value is present
+	size_type count(const Key& k) const { return rerooted().count( k ); }
+
+	/// get value; undefined behaviour if not present
+	const Val& get(const Key& k) const {
+		const Base& self = rerooted();
+		auto it = self.find( k );
+		return it->second;
+	}
+
+	/// get value; returns default if not present
+	template<typename V>
+	Val get_or_default(const Key& k, V&& d) const {
+		const Base& self = rerooted();
+		auto it = self.find( k );
+		if ( it == self.end() ) return d;
+		else return it->second;
+	}
+
+	/// set value, storing new map in output variable
+	template<typename K, typename V>
+	Ptr set(K&& k, V&& v) {
+		reroot();
+
+		// transfer map to new node
+		Ptr ret = std::make_shared<Self>( take_as<Base>() );
+		reset_as_base();
+		Base& base_map = ret->template as<Base>();
+
+		// check if this is update or insert
+		auto it = base_map.find( k );
+		if ( it == base_map.end() ) {
+			// set self to REM node and insert into base
+			init<Rem>( ret, k );
+			mode = REM;
+
+			base_map.emplace_hint( it, std::forward<K>(k), std::forward<V>(v) );
+		} else {
+			// set self to UPD node and modify base
+			init<Ins>( ret, std::forward<K>(k), std::move(it->second) );
+			mode = UPD;
+
+			it->second = std::forward<V>(v);
+		}
+
+		return ret;
+	}
+
+	/// remove value, storing new map in output variable; does nothing if key not in map
+	Ptr erase(const Key& k) {
+		reroot();
+		
+		// exit early if key does not exist in map
+		if ( ! as<Base>().count( k ) ) return this->shared_from_this();
+
+		// transfer map to new node
+		Ptr ret = std::make_shared<Self>( take_as<Base>() );
+		reset_as_base();
+		Base& base_map = ret->template as<Base>();
+
+		// set self to INS node and remove from base
+		init<Ins>( ret, k, base_map[k] );
+		mode = INS;
+
+		base_map.erase( k );
+
+		return ret;
+	}
+};
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/Common/Stats/Counter.h
===================================================================
--- src/Common/Stats/Counter.h	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/Common/Stats/Counter.h	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -37,4 +37,5 @@
 			class SimpleCounter {
 			public:
+				inline void operator++() {}
 				inline void operator++(int) {}
 				inline void operator+=(size_t) {}
@@ -84,4 +85,5 @@
 				virtual void print(std::ostream & os) override { os << count; }
 
+				inline void operator++()             { if(!enabled) return; count++;        }
 				inline void operator++(int)          { if(!enabled) return; count++;        }
 				inline void operator+=(size_t value) { if(!enabled) return; count += value; }
Index: src/ControlStruct/ForExprMutator.cc
===================================================================
--- src/ControlStruct/ForExprMutator.cc	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/ControlStruct/ForExprMutator.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Fri Aug 18 10:22:00 2017
-// Update Count     : 12
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Mar 11 22:26:52 2019
+// Update Count     : 14
 //
 
@@ -21,5 +21,5 @@
 
 namespace ControlStruct {
-	Statement *hoist( Statement *originalStmt, std::list<Statement *> &init ) {
+	Statement * hoist( Statement * originalStmt, std::list<Statement *> & init ) {
 		// If no hoisting is needed, skip:
 		if ( 0 == init.size() ) {
@@ -29,6 +29,6 @@
 		// Create compound statement, move initializers outside,
 		// the resut of the original stays as is.
-		CompoundStmt *block = new CompoundStmt();
-		std::list<Statement *> &stmts = block->get_kids();
+		CompoundStmt * block = new CompoundStmt();
+		std::list<Statement *> & stmts = block->get_kids();
 		stmts.splice( stmts.end(), init );
 
@@ -38,12 +38,12 @@
 	}
 
-	Statement *ForExprMutator::postmutate( IfStmt *ifStmt ) {
+	Statement * ForExprMutator::postmutate( IfStmt * ifStmt ) {
 		return hoist( ifStmt, ifStmt->initialization );
 	}
-	Statement *ForExprMutator::postmutate( ForStmt *forStmt ) {
+	Statement * ForExprMutator::postmutate( ForStmt * forStmt ) {
 		// hoist any initializer declarations to make them C89 (rather than C99)
 		return hoist( forStmt, forStmt->initialization );
 	}
-	Statement *ForExprMutator::postmutate( WhileStmt *whileStmt ) {
+	Statement * ForExprMutator::postmutate( WhileStmt * whileStmt ) {
 		return hoist( whileStmt, whileStmt->initialization );
 	}
Index: src/ControlStruct/LabelFixer.cc
===================================================================
--- src/ControlStruct/LabelFixer.cc	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/ControlStruct/LabelFixer.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Rob Schluntz
-// Last Modified On : Tue Jul 28 13:32:43 2015
-// Update Count     : 156
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Mar 11 22:26:02 2019
+// Update Count     : 159
 //
 
@@ -32,5 +32,5 @@
 	}
 
-	LabelFixer::LabelFixer( LabelGenerator *gen ) : generator ( gen ) {
+	LabelFixer::LabelFixer( LabelGenerator * gen ) : generator ( gen ) {
 		if ( generator == 0 )
 			generator = LabelGenerator::getGenerator();
@@ -49,5 +49,5 @@
 
 	// prune to at most one label definition for each statement
-	void LabelFixer::previsit( Statement *stmt ) {
+	void LabelFixer::previsit( Statement * stmt ) {
 		std::list< Label > &labels = stmt->get_labels();
 
@@ -58,5 +58,5 @@
 	}
 
-	void LabelFixer::previsit( BranchStmt *branchStmt ) {
+	void LabelFixer::previsit( BranchStmt * branchStmt ) {
 		previsit( ( Statement *)branchStmt );
 
@@ -75,7 +75,7 @@
 
 
-	// sets the definition of the labelTable entry to be the provided
-	// statement for every label in the list parameter. Happens for every kind of statement
-	Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) {
+	// sets the definition of the labelTable entry to be the provided statement for every label in the list
+	// parameter. Happens for every kind of statement
+	Label LabelFixer::setLabelsDef( std::list< Label > & llabel, Statement * definition ) {
 		assert( definition != 0 );
 		assert( llabel.size() > 0 );
@@ -100,6 +100,5 @@
 		} // for
 
-		// produce one of the labels attached to this statement to be
-		// temporarily used as the canonical label
+		// produce one of the labels attached to this statement to be temporarily used as the canonical label
 		return labelTable[ llabel.front() ]->get_label();
 	}
@@ -117,5 +116,5 @@
 
 	// Builds a table that maps a label to its defining statement.
-	std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticErrorException ) {
+	std::map<Label, Statement * > * LabelFixer::resolveJumps() throw ( SemanticErrorException ) {
 		std::map< Label, Statement * > *ret = new std::map< Label, Statement * >();
 		for ( std::map< Label, Entry * >::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) {
Index: src/ControlStruct/LabelGenerator.cc
===================================================================
--- src/ControlStruct/LabelGenerator.cc	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/ControlStruct/LabelGenerator.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -9,7 +9,7 @@
 // Author           : Rodolfo G. Esteves
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Thr Aug 14 14:14:00 2015
-// Update Count     : 14
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Mar 11 22:23:20 2019
+// Update Count     : 15
 //
 
@@ -24,10 +24,9 @@
 
 namespace ControlStruct {
-	LabelGenerator *LabelGenerator::labelGenerator = 0;
+	LabelGenerator * LabelGenerator::labelGenerator = 0;
 
-	LabelGenerator *LabelGenerator::getGenerator() {
+	LabelGenerator * LabelGenerator::getGenerator() {
 		if ( LabelGenerator::labelGenerator == 0 )
 			LabelGenerator::labelGenerator = new LabelGenerator();
-
 		return labelGenerator;
 	}
@@ -38,5 +37,5 @@
 		if ( stmt && ! stmt->get_labels().empty() ) {
 			os << "_" << stmt->get_labels().front() << "__";
-		}
+		} // if
 		std::string ret = os.str();
 		Label l( ret );
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/Parser/ParseNode.h	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Sat May 16 13:28:16 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Feb 13 17:36:49 2019
-// Update Count     : 867
+// Last Modified On : Mon Apr 15 14:22:39 2019
+// Update Count     : 874
 //
 
@@ -132,12 +132,12 @@
 	void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
 
-	Expression *get_expr() const { return expr.get(); }
 	template<typename T>
 	bool isExpressionType() const {	return nullptr != dynamic_cast<T>(expr.get()); }
 
 	Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
+
+	std::unique_ptr<Expression> expr;					// public because of lifetime implications
   private:
 	bool extension = false;
-	std::unique_ptr<Expression> expr;
 }; // ExpressionNode
 
Index: src/Parser/lex.ll
===================================================================
--- src/Parser/lex.ll	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/Parser/lex.ll	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
  * Created On       : Sat Sep 22 08:58:10 2001
  * Last Modified By : Peter A. Buhr
- * Last Modified On : Sun Mar 10 09:13:09 2019
- * Update Count     : 706
+ * Last Modified On : Wed Mar 13 14:54:30 2019
+ * Update Count     : 707
  */
 
@@ -226,4 +226,5 @@
 char			{ KEYWORD_RETURN(CHAR); }
 choose			{ KEYWORD_RETURN(CHOOSE); }				// CFA
+coerce			{ KEYWORD_RETURN(COERCE); }				// CFA
 _Complex		{ KEYWORD_RETURN(COMPLEX); }			// C99
 __complex		{ KEYWORD_RETURN(COMPLEX); }			// GCC
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/Parser/parser.yy	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Feb 21 08:45:07 2019
-// Update Count     : 4232
+// Last Modified On : Mon Apr 15 15:02:56 2019
+// Update Count     : 4290
 //
 
@@ -185,5 +185,5 @@
 
 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
-	ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->get_expr());
+	ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get());
 	if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) {
     	type = new ExpressionNode( new CastExpr( maybeMoveBuild< Expression >(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) );
@@ -198,7 +198,7 @@
 
 ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
-	if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->get_expr()) ) {
+	if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->expr.get()) ) {
 		return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
-	} else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index->get_expr()) ) {
+	} else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index->expr.get()) ) {
 		if ( NameExpr * identifier = dynamic_cast<NameExpr *>(commaExpr->arg1 ) ) {
 			return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
@@ -265,5 +265,5 @@
 %token RESTRICT											// C99
 %token ATOMIC											// C11
-%token FORALL MUTEX VIRTUAL								// CFA
+%token FORALL MUTEX VIRTUAL COERCE						// CFA
 %token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED
 %token BOOL COMPLEX IMAGINARY							// C99
@@ -334,10 +334,10 @@
 %type<en> subrange
 %type<decl> asm_name_opt
-%type<en> asm_operands_opt asm_operands_list asm_operand
+%type<en> asm_operands_opt				asm_operands_list			asm_operand
 %type<label> label_list
 %type<en> asm_clobbers_list_opt
 %type<flag> asm_volatile_opt
 %type<en> handler_predicate_opt
-%type<genexpr> generic_association generic_assoc_list
+%type<genexpr> generic_association		generic_assoc_list
 
 // statements
@@ -795,4 +795,5 @@
 	| '(' type_no_function ')' cast_expression
 		{ $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
+		// keyword cast cannot be grouped because of reduction in aggregate_key
 	| '(' COROUTINE '&' ')' cast_expression				// CFA
 		{ $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Coroutine, $5 ) ); }
@@ -806,6 +807,24 @@
 	| '(' VIRTUAL type_no_function ')' cast_expression	// CFA
 		{ $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $5 ), maybeMoveBuildType( $3 ) ) ); }
+	| '(' RETURN type_no_function ')' cast_expression	// CFA
+		{ SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; }
+	| '(' COERCE type_no_function ')' cast_expression	// CFA
+		{ SemanticError( yylloc, "Coerce cast is currently unimplemented." ); $$ = nullptr; }
+	| '(' qualifier_cast_list ')' cast_expression		// CFA
+		{ SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; }
 //	| '(' type_no_function ')' tuple
 //		{ $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
+	;
+
+qualifier_cast_list:
+	cast_modifier type_qualifier_name
+	| cast_modifier MUTEX
+	| qualifier_cast_list cast_modifier type_qualifier_name
+	| qualifier_cast_list cast_modifier MUTEX
+	;
+
+cast_modifier:
+	'-'
+	| '+'
 	;
 
@@ -1145,5 +1164,22 @@
 	for_control_expression
 	| for_control_expression_list ':' for_control_expression
-		{ $$ = $3; }
+		// ForCtrl + ForCtrl:
+		//    init + init => multiple declaration statements that are hoisted
+		//    condition + condition => (expression) && (expression)
+		//    change + change => (expression), (expression)
+		{
+			$1->init->set_last( $3->init );
+			if ( $1->condition ) {
+				if ( $3->condition ) {
+					$1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true ) );
+				} // if
+			} else $1->condition = $3->condition;
+			if ( $1->change ) {
+				if ( $3->change ) {
+					$1->change->expr.reset( new CommaExpr( $1->change->expr.release(), $3->change->expr.release() ) );
+				} // if
+			} else $1->change = $3->change;
+			$$ = $1;
+		}
 	;
 
@@ -1155,4 +1191,5 @@
 	| declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';'
 		{ $$ = new ForCtrl( $1, $2, $4 ); }
+
 	| comma_expression									// CFA
 		{ $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
@@ -1169,4 +1206,10 @@
 	| comma_expression ';' comma_expression inclexcl comma_expression '~' comma_expression // CFA
 		{ $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); }
+
+		// There is a S/R conflicit if ~ and -~ are factored out.
+	| comma_expression ';' comma_expression '~' '@'		// CFA
+		{ $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
+	| comma_expression ';' comma_expression ErangeDown '@' // CFA
+		{ $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
 	| comma_expression ';' comma_expression '~' '@' '~' comma_expression // CFA
 		{ $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, $7 ); }
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -258,13 +258,17 @@
 			// - necessary pre-requisite to pruning
 			AltList candidates;
+			std::list<std::string> errors;
 			for ( unsigned i = 0; i < alternatives.size(); ++i ) {
-				resolveAssertions( alternatives[i], indexer, candidates );
+				resolveAssertions( alternatives[i], indexer, candidates, errors );
 			}
 			// fail early if none such
 			if ( mode.failFast && candidates.empty() ) {
 				std::ostringstream stream;
-				stream << "No resolvable alternatives for expression " << expr << "\n"
-				       << "Alternatives with failing assertions are:\n";
-				printAlts( alternatives, stream, 1 );
+				stream << "No alternatives with satisfiable assertions for " << expr << "\n";
+				//        << "Alternatives with failing assertions are:\n";
+				// printAlts( alternatives, stream, 1 );
+				for ( const auto& err : errors ) {
+					stream << err;
+				}
 				SemanticError( expr->location, stream.str() );
 			}
Index: src/ResolvExpr/ResolveAssertions.cc
===================================================================
--- src/ResolvExpr/ResolveAssertions.cc	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/ResolvExpr/ResolveAssertions.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -20,5 +20,6 @@
 #include <list>                     // for list
 #include <memory>                   // for unique_ptr
-#include <string>
+#include <sstream>                  // for ostringstream
+#include <string>                   // for string
 #include <unordered_map>            // for unordered_map, unordered_multimap
 #include <utility>                  // for move
@@ -27,4 +28,5 @@
 #include "Alternative.h"            // for Alternative, AssertionItem, AssertionList
 #include "Common/FilterCombos.h"    // for filterCombos
+#include "Common/Indenter.h"        // for Indenter
 #include "Common/utility.h"         // for sort_mins
 #include "ResolvExpr/RenameVars.h"  // for renameTyVars
@@ -97,4 +99,6 @@
 			return { item, item.matches[i] };
 		}
+
+		const DeclarationWithType* get_decl() const { return cache->at(key).deferIds[0].decl; }
 
 		// sortable by key
@@ -364,5 +368,5 @@
 	static const int recursionLimit = /* 10 */ 4;
 
-	void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out ) {
+	void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out, std::list<std::string>& errors ) {
 		// finish early if no assertions to resolve
 		if ( alt.need.empty() ) {
@@ -385,5 +389,15 @@
 				for ( auto& assn : resn.need ) {
 					// fail early if any assertion is not resolvable
-					if ( ! resolveAssertion( assn, resn, assnCache ) ) goto nextResn;
+					if ( ! resolveAssertion( assn, resn, assnCache ) ) {
+						Indenter tabs{ Indenter::tabsize, 3 };
+						std::ostringstream ss;
+						ss << tabs << "Unsatisfiable alternative:\n";
+						resn.alt.print( ss, ++tabs );
+						ss << --tabs << "Could not satisfy assertion:\n";
+						assn.decl->print( ss, ++tabs );
+						
+						errors.emplace_back( ss.str() );
+						goto nextResn;
+					}
 				}
 
@@ -404,4 +418,19 @@
 						resn.deferred, 
 						CandidateEnvMerger{ resn.alt.env, resn.alt.openVars, resn.indexer } );
+					// fail early if no mutually-compatible assertion satisfaction
+					if ( compatible.empty() ) {
+						Indenter tabs{ Indenter::tabsize, 3 };
+						std::ostringstream ss;
+						ss << tabs << "Unsatisfiable alternative:\n";
+						resn.alt.print( ss, ++tabs );
+						ss << --tabs << "No mutually-compatible satisfaction for assertions:\n";
+						++tabs;
+						for ( const auto& d : resn.deferred ) {
+							d.get_decl()->print( ss, tabs );
+						}
+
+						errors.emplace_back( ss.str() );
+						goto nextResn;
+					}
 					// sort by cost
 					CandidateCost coster{ resn.indexer };
Index: src/ResolvExpr/ResolveAssertions.h
===================================================================
--- src/ResolvExpr/ResolveAssertions.h	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/ResolvExpr/ResolveAssertions.h	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -24,5 +24,5 @@
 namespace ResolvExpr {
 	/// Recursively resolves all assertions provided in an alternative; returns true iff succeeds
-	void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out );
+	void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out, std::list<std::string>& errors );
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/TypeEnvironment.cc
===================================================================
--- src/ResolvExpr/TypeEnvironment.cc	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/ResolvExpr/TypeEnvironment.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -386,5 +386,7 @@
 	}
 
-	bool TypeEnvironment::bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
+	bool TypeEnvironment::bindVarToVar( TypeInstType *var1, TypeInstType *var2, 
+			TypeDecl::Data && data, AssertionSet &need, AssertionSet &have, 
+			const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
 
 		auto class1 = internal_lookup( var1->get_name() );
@@ -428,4 +430,5 @@
 					class1->set_type( common );
 				}
+				class1->data.isComplete |= data.isComplete;
 				env.erase( class2 );
 			} else return false;
@@ -435,8 +438,10 @@
 				class1->vars.insert( class2->vars.begin(), class2->vars.end() );
 				class1->allowWidening = widen1;
+				class1->data.isComplete |= data.isComplete;
 				env.erase( class2 );
 			} else {
 				class2->vars.insert( class1->vars.begin(), class1->vars.end() );
 				class2->allowWidening = widen2;
+				class2->data.isComplete |= data.isComplete;
 				env.erase( class1 );
 			} // if
@@ -445,8 +450,10 @@
 			class1->vars.insert( var2->get_name() );
 			class1->allowWidening = widen1;
+			class1->data.isComplete |= data.isComplete;
 		} else if ( class2 != env.end() ) {
 			// var1 unbound, add to class2
 			class2->vars.insert( var1->get_name() );
 			class2->allowWidening = widen2;
+			class2->data.isComplete |= data.isComplete;
 		} else {
 			// neither var bound, create new class
Index: src/ResolvExpr/TypeEnvironment.h
===================================================================
--- src/ResolvExpr/TypeEnvironment.h	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/ResolvExpr/TypeEnvironment.h	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -139,5 +139,5 @@
 		/// Binds the type classes represented by `var1` and `var2` together; will add 
 		/// one or both classes if needed. Returns false on failure.
-		bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
+		bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, TypeDecl::Data && data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
 
 		/// Disallows widening for all bindings in the environment
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/ResolvExpr/Unify.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -172,6 +172,12 @@
 		bool isopen2 = var2 && ( entry2 != openVars.end() );
 
-		if ( isopen1 && isopen2 && entry1->second == entry2->second ) {
-			result = env.bindVarToVar( var1, var2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer );
+		if ( isopen1 && isopen2 ) {
+			if ( entry1->second.kind != entry2->second.kind ) {
+				result = false;
+			} else {
+				result = env.bindVarToVar( 
+					var1, var2, TypeDecl::Data{ entry1->second, entry2->second }, needAssertions, 
+					haveAssertions, openVars, widenMode, indexer );
+			}
 		} else if ( isopen1 ) {
 			result = env.bindVar( var1, type2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer );
Index: src/SymTab/Indexer.cc
===================================================================
--- src/SymTab/Indexer.cc	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/SymTab/Indexer.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 21:37:33 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug 17 16:08:40 2017
-// Update Count     : 20
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Fri Mar  8 13:55:00 2019
+// Update Count     : 21
 //
 
@@ -17,15 +17,16 @@
 
 #include <cassert>                 // for assert, strict_dynamic_cast
-#include <iostream>                // for operator<<, basic_ostream, ostream
 #include <string>                  // for string, operator<<, operator!=
+#include <memory>                  // for shared_ptr, make_shared
 #include <unordered_map>           // for operator!=, unordered_map<>::const...
 #include <unordered_set>           // for unordered_set
 #include <utility>                 // for pair, make_pair, move
+#include <vector>                  // for vector
 
 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign
 #include "Common/SemanticError.h"  // for SemanticError
 #include "Common/utility.h"        // for cloneAll
-#include "Common/Stats/Counter.h" // for counters
-#include "GenPoly/GenPoly.h"
+#include "Common/Stats/Counter.h"  // for counters
+#include "GenPoly/GenPoly.h"       // for getFunctionType
 #include "InitTweak/InitTweak.h"   // for isConstructor, isCopyFunction, isC...
 #include "Mangler.h"               // for Mangler
@@ -39,27 +40,9 @@
 #include "SynTree/Type.h"          // for Type, StructInstType, UnionInstType
 
-#define debugPrint(x) if ( doDebug ) { std::cerr << x; }
-
 namespace SymTab {
 
 	// Statistics block
 	namespace {
-
-		static inline auto stats_idtable() {
-			using namespace Stats::Counters;
-			static auto group = build<CounterGroup>("IdTable");
-			static struct {
-				SimpleCounter * find;
-				AverageCounter<double> * size;
-				AverageCounter<double> * key;
-			} ret = {
-				.find = build<SimpleCounter>("Find calls", group),
-				.size = build<AverageCounter<double>>("Average Size", group),
-				.key  = build<AverageCounter<double>>("Average Key Size", group),
-			};
-			return ret;
-		}
-
-		static inline auto stats_indexers() {
+		static inline auto stats() {
 			using namespace Stats::Counters;
 			static auto group   = build<CounterGroup>("Indexers");
@@ -67,11 +50,23 @@
 				SimpleCounter * count;
 				AverageCounter<double> * size;
-				AverageCounter<double> * depth_a;
-				MaxCounter<size_t> * depth_m;
+				SimpleCounter * new_scopes;
+				SimpleCounter * lazy_scopes;
+				AverageCounter<double> * avg_scope_depth;
+				MaxCounter<size_t> * max_scope_depth;
+				SimpleCounter * add_calls;
+				SimpleCounter * lookup_calls;
+				SimpleCounter * map_lookups;
+				SimpleCounter * map_mutations;
 			} ret = {
 				.count   = build<SimpleCounter>("Count", group),
 				.size    = build<AverageCounter<double>>("Average Size", group),
-				.depth_a = build<AverageCounter<double>>("Average Depth", group),
-				.depth_m = build<MaxCounter<size_t>>("Max Depth", group),
+				.new_scopes = build<SimpleCounter>("Scopes", group),
+				.lazy_scopes = build<SimpleCounter>("Lazy Scopes", group),
+				.avg_scope_depth = build<AverageCounter<double>>("Average Scope", group),
+				.max_scope_depth = build<MaxCounter<size_t>>("Max Scope", group),
+				.add_calls = build<SimpleCounter>("Add Calls", group),
+				.lookup_calls = build<SimpleCounter>("Lookup Calls", group),
+				.map_lookups = build<SimpleCounter>("Map Lookups", group),
+				.map_mutations = build<SimpleCounter>("Map Mutations", group)
 			};
 			return ret;
@@ -79,391 +74,116 @@
 	}
 
-	std::ostream & operator<<( std::ostream & out, const Indexer::IdData & data ) {
-		return out << "(" << data.id << "," << data.baseExpr << ")";
-	}
-
-	typedef std::unordered_map< std::string, Indexer::IdData > MangleTable;
-	typedef std::unordered_map< std::string, MangleTable > IdTable;
-	typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable;
-	typedef std::unordered_map< std::string, StructDecl* > StructTable;
-	typedef std::unordered_map< std::string, EnumDecl* > EnumTable;
-	typedef std::unordered_map< std::string, UnionDecl* > UnionTable;
-	typedef std::unordered_map< std::string, TraitDecl* > TraitTable;
-
-	void dump( const IdTable &table, std::ostream &os ) {
-		for ( IdTable::const_iterator id = table.begin(); id != table.end(); ++id ) {
-			for ( MangleTable::const_iterator mangle = id->second.begin(); mangle != id->second.end(); ++mangle ) {
-				os << mangle->second << std::endl;
-			}
-		}
-	}
-
-	template< typename Decl >
-	void dump( const std::unordered_map< std::string, Decl* > &table, std::ostream &os ) {
-		for ( typename std::unordered_map< std::string, Decl* >::const_iterator it = table.begin(); it != table.end(); ++it ) {
-			os << it->second << std::endl;
-		} // for
-	}
-
-	struct Indexer::Impl {
-		Impl( unsigned long _scope ) : refCount(1), scope( _scope ), size( 0 ), base(),
-				idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {}
-		Impl( unsigned long _scope, Indexer &&_base ) : refCount(1), scope( _scope ), size( 0 ), base( _base ),
-				idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {}
-		unsigned long refCount;   ///< Number of references to these tables
-		unsigned long scope;      ///< Scope these tables are associated with
-		unsigned long size;       ///< Number of elements stored in this table
-		const Indexer base;       ///< Base indexer this extends
-
-		IdTable idTable;          ///< Identifier namespace
-		TypeTable typeTable;      ///< Type namespace
-		StructTable structTable;  ///< Struct namespace
-		EnumTable enumTable;      ///< Enum namespace
-		UnionTable unionTable;    ///< Union namespace
-		TraitTable traitTable;    ///< Trait namespace
-	};
-
-	Indexer::Impl *Indexer::newRef( Indexer::Impl *toClone ) {
-		if ( ! toClone ) return 0;
-
-		// shorten the search chain by skipping empty links
-		Indexer::Impl *ret = toClone->size == 0 ? toClone->base.tables : toClone;
-		if ( ret ) { ++ret->refCount; }
-
-		return ret;
-	}
-
-	void Indexer::deleteRef( Indexer::Impl *toFree ) {
-		if ( ! toFree ) return;
-
-		if ( --toFree->refCount == 0 ) delete toFree;
-	}
-
-	void Indexer::removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const {
-		// only need to perform this step for constructors, destructors, and assignment functions
-		if ( ! CodeGen::isCtorDtorAssign( id ) ) return;
-
-		// helpful data structure to organize properties for a type
-		struct ValueType {
-			struct DeclBall { // properties for this particular decl
-				IdData decl;
-				bool isUserDefinedFunc;
-				bool isCopyFunc;
-			};
-			// properties for this type
-			bool existsUserDefinedCopyFunc = false;    // user-defined copy ctor found
-			BaseSyntaxNode * deleteStmt = nullptr;     // non-null if a user-defined function is found
-			std::list< DeclBall > decls;
-
-			// another FunctionDecl for the current type was found - determine
-			// if it has special properties and update data structure accordingly
-			ValueType & operator+=( IdData data ) {
-				DeclarationWithType * function = data.id;
-				bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->linkage );
-				bool isCopyFunc = InitTweak::isCopyFunction( function, function->name );
-				decls.push_back( DeclBall{ data, isUserDefinedFunc, isCopyFunc } );
-				existsUserDefinedCopyFunc = existsUserDefinedCopyFunc || (isUserDefinedFunc && isCopyFunc);
-				if ( isUserDefinedFunc && ! deleteStmt ) {
-					// any user-defined function can act as an implicit delete statement for generated constructors.
-					// a delete stmt should not act as an implicit delete statement.
-					deleteStmt = data.id;
-				}
-				return *this;
-			}
-		}; // ValueType
-
-		std::list< IdData > copy;
-		copy.splice( copy.end(), out );
-
-		// organize discovered declarations by type
-		std::unordered_map< std::string, ValueType > funcMap;
-		for ( auto decl : copy ) {
-			if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl.id ) ) {
-				std::list< DeclarationWithType * > & params = function->type->parameters;
-				assert( ! params.empty() );
-				// use base type of pointer, so that qualifiers on the pointer type aren't considered.
-				Type * base = InitTweak::getPointerBase( params.front()->get_type() );
-				assert( base );
-				funcMap[ Mangler::mangle( base ) ] += decl;
-			} else {
-				out.push_back( decl );
-			}
-		}
-
-		// if a type contains user defined ctor/dtor/assign, then special rules trigger, which determine
-		// the set of ctor/dtor/assign that can be used  by the requester. In particular, if the user defines
-		// a default ctor, then the generated default ctor is unavailable, likewise for copy ctor
-		// and dtor. If the user defines any ctor/dtor, then no generated field ctors are available.
-		// If the user defines any ctor then the generated default ctor is unavailable (intrinsic default
-		// ctor must be overridden exactly). If the user defines anything that looks like a copy constructor,
-		// then the generated copy constructor is unavailable, and likewise for the assignment operator.
-		for ( std::pair< const std::string, ValueType > & pair : funcMap ) {
-			ValueType & val = pair.second;
-			for ( ValueType::DeclBall ball : val.decls ) {
-				bool isNotUserDefinedFunc = ! ball.isUserDefinedFunc && ball.decl.id->linkage != LinkageSpec::Intrinsic;
-				bool isCopyFunc = ball.isCopyFunc;
-				bool existsUserDefinedCopyFunc = val.existsUserDefinedCopyFunc;
-
-				// only implicitly delete non-user defined functions that are not intrinsic, and are
-				// not copy functions (assignment or copy constructor). If a  user-defined copy function exists,
-				// do not pass along the non-user-defined copy functions since signatures do not have to match,
-				// and the generated functions will often be cheaper.
-				if ( isNotUserDefinedFunc ) {
-					if ( isCopyFunc ) {
-						// Skip over non-user-defined copy functions when there is a user-defined copy function.
-						// Since their signatures do not have to be exact, deleting them is the wrong choice.
-						if ( existsUserDefinedCopyFunc ) continue;
-					} else {
-						// delete non-user-defined non-copy functions if applicable.
-						// deleteStmt will be non-null only if a user-defined function is found.
-						ball.decl.deleteStmt = val.deleteStmt;
-					}
-				}
-				out.push_back( ball.decl );
-			}
-		}
-	}
-
-	void Indexer::makeWritable() {
-		if ( ! tables ) {
-			// create indexer if not yet set
-			tables = new Indexer::Impl( scope );
-		} else if ( tables->refCount > 1 || tables->scope != scope ) {
-			// make this indexer the base of a fresh indexer at the current scope
-			tables = new Indexer::Impl( scope, std::move( *this ) );
-		}
-	}
-
-	Indexer::Indexer() : tables( 0 ), scope( 0 ) {
-		(*stats_indexers().count)++;
-	}
-
-	Indexer::Indexer( const Indexer &that ) : doDebug( that.doDebug ), tables( newRef( that.tables ) ), scope( that.scope ) {
-		(*stats_indexers().count)++;
-	}
-
-	Indexer::Indexer( Indexer &&that ) : doDebug( that.doDebug ), tables( that.tables ), scope( that.scope ) {
-		that.tables = 0;
-	}
+	Indexer::Indexer() 
+	: idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 
+	  prevScope(), scope( 0 ), repScope( 0 ) { ++*stats().count; }
 
 	Indexer::~Indexer() {
-		if(tables) {
-			stats_indexers().size->push( tables->idTable.size() );
-			size_t depth = 1;
-			for( auto crnt = tables->base.tables; crnt; crnt = crnt->base.tables ) {
-				++depth;
-			}
-			stats_indexers().depth_a->push( depth );
-			stats_indexers().depth_m->push( depth );
-		}
-		deleteRef( tables );
-	}
-
-	Indexer& Indexer::operator= ( const Indexer &that ) {
-		deleteRef( tables );
-
-		tables = newRef( that.tables );
-		scope = that.scope;
-		doDebug = that.doDebug;
-
-		return *this;
-	}
-
-	Indexer& Indexer::operator= ( Indexer &&that ) {
-		deleteRef( tables );
-
-		tables = that.tables;
-		scope = that.scope;
-		doDebug = that.doDebug;
-
-		that.tables = 0;
-
-		return *this;
+		stats().size->push( idTable ? idTable->size() : 0 );
+	}
+
+	void Indexer::lazyInitScope() {
+		if ( repScope < scope ) {
+			++*stats().lazy_scopes;
+			// create rollback
+			prevScope = std::make_shared<Indexer>( *this );
+			// update repScope
+			repScope = scope;
+		}
+	}
+
+	void Indexer::enterScope() {
+		++scope;
+
+		++*stats().new_scopes;
+		stats().avg_scope_depth->push( scope );
+		stats().max_scope_depth->push( scope );
+	}
+
+	void Indexer::leaveScope() {
+		if ( repScope == scope ) {
+			Ptr prev = prevScope;           // make sure prevScope stays live
+			*this = std::move(*prevScope);  // replace with previous scope
+		}
+
+		--scope;
 	}
 
 	void Indexer::lookupId( const std::string &id, std::list< IdData > &out ) const {
-		std::unordered_set< std::string > foundMangleNames;
-
-		Indexer::Impl *searchTables = tables;
-		while ( searchTables ) {
-
-			(*stats_idtable().find)++;
-			stats_idtable().key->push( id.size() );
-			stats_idtable().size->push( searchTables->idTable.size() );
-			IdTable::const_iterator decls = searchTables->idTable.find( id );
-			if ( decls != searchTables->idTable.end() ) {
-				const MangleTable &mangleTable = decls->second;
-				for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
-					// mark the mangled name as found, skipping this insertion if a declaration for that name has already been found
-					if ( foundMangleNames.insert( decl->first ).second == false ) continue;
-
-					out.push_back( decl->second );
-				}
-			}
-
-			// get declarations from base indexers
-			searchTables = searchTables->base.tables;
-		}
-
-		// some special functions, e.g. constructors and destructors
-		// remove autogenerated functions when they are defined so that
-		// they can never be matched
-		removeSpecialOverrides( id, out );
+		++*stats().lookup_calls;
+		if ( ! idTable ) return;
+
+		++*stats().map_lookups;
+		auto decls = idTable->find( id );
+		if ( decls == idTable->end() ) return;
+
+		for ( auto decl : *(decls->second) ) {
+			out.push_back( decl.second );
+		}
 	}
 
 	NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
-		if ( ! tables ) return 0;
-
-		TypeTable::const_iterator ret = tables->typeTable.find( id );
-		return ret != tables->typeTable.end() ? ret->second : tables->base.lookupType( id );
+		++*stats().lookup_calls;
+		if ( ! typeTable ) return nullptr;
+		++*stats().map_lookups;
+		auto it = typeTable->find( id );
+		return it == typeTable->end() ? nullptr : it->second.decl;
 	}
 
 	StructDecl *Indexer::lookupStruct( const std::string &id ) const {
-		if ( ! tables ) return 0;
-
-		StructTable::const_iterator ret = tables->structTable.find( id );
-		return ret != tables->structTable.end() ? ret->second : tables->base.lookupStruct( id );
+		++*stats().lookup_calls;
+		if ( ! structTable ) return nullptr;
+		++*stats().map_lookups;
+		auto it = structTable->find( id );
+		return it == structTable->end() ? nullptr : it->second.decl;
+	}
+
+	EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
+		++*stats().lookup_calls;
+		if ( ! enumTable ) return nullptr;
+		++*stats().map_lookups;
+		auto it = enumTable->find( id );
+		return it == enumTable->end() ? nullptr : it->second.decl;
+	}
+
+	UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
+		++*stats().lookup_calls;
+		if ( ! unionTable ) return nullptr;
+		++*stats().map_lookups;
+		auto it = unionTable->find( id );
+		return it == unionTable->end() ? nullptr : it->second.decl;
+	}
+
+	TraitDecl *Indexer::lookupTrait( const std::string &id ) const {
+		++*stats().lookup_calls;
+		if ( ! traitTable ) return nullptr;
+		++*stats().map_lookups;
+		auto it = traitTable->find( id );
+		return it == traitTable->end() ? nullptr : it->second.decl;
+	}
+
+	const Indexer* Indexer::atScope( unsigned long target ) const {
+		// by lazy construction, final indexer in list has repScope 0, cannot be > target
+		// otherwise, will find first scope representing the target
+		const Indexer* indexer = this;
+		while ( indexer->repScope > target ) {
+			indexer = indexer->prevScope.get();
+		}
+		return indexer;
 	}
 
 	NamedTypeDecl *Indexer::globalLookupType( const std::string &id ) const {
-		return lookupTypeAtScope( id, 0 );
+		return atScope( 0 )->lookupType( id );
 	}
 
 	StructDecl *Indexer::globalLookupStruct( const std::string &id ) const {
-		return lookupStructAtScope( id, 0 );
+		return atScope( 0 )->lookupStruct( id );
 	}
 
 	UnionDecl *Indexer::globalLookupUnion( const std::string &id ) const {
-		return lookupUnionAtScope( id, 0 );
+		return atScope( 0 )->lookupUnion( id );
 	}
 
 	EnumDecl *Indexer::globalLookupEnum( const std::string &id ) const {
-		return lookupEnumAtScope( id, 0 );
-	}
-
-	EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
-		if ( ! tables ) return 0;
-
-		EnumTable::const_iterator ret = tables->enumTable.find( id );
-		return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnum( id );
-	}
-
-	UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
-		if ( ! tables ) return 0;
-
-		UnionTable::const_iterator ret = tables->unionTable.find( id );
-		return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnion( id );
-	}
-
-	TraitDecl *Indexer::lookupTrait( const std::string &id ) const {
-		if ( ! tables ) return 0;
-
-		TraitTable::const_iterator ret = tables->traitTable.find( id );
-		return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTrait( id );
-	}
-
-	const Indexer::IdData * Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const {
-		if ( ! tables ) return nullptr;
-		if ( tables->scope < scope ) return nullptr;
-
-		(*stats_idtable().find)++;
-		stats_idtable().key->push( id.size() );
-		stats_idtable().size->push( tables->idTable.size() );
-		IdTable::const_iterator decls = tables->idTable.find( id );
-		if ( decls != tables->idTable.end() ) {
-			const MangleTable &mangleTable = decls->second;
-			MangleTable::const_iterator decl = mangleTable.find( mangleName );
-			if ( decl != mangleTable.end() ) return &decl->second;
-		}
-
-		return tables->base.lookupIdAtScope( id, mangleName, scope );
-	}
-
-	Indexer::IdData * Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) {
-		return const_cast<IdData *>(const_cast<const Indexer *>(this)->lookupIdAtScope( id, mangleName, scope ));
-	}
-
-	bool Indexer::hasIncompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const {
-		if ( ! tables ) return false;
-		if ( tables->scope < scope ) return false;
-
-		(*stats_idtable().find)++;
-		stats_idtable().key->push( id.size() );
-		stats_idtable().size->push( tables->idTable.size() );
-		IdTable::const_iterator decls = tables->idTable.find( id );
-		if ( decls != tables->idTable.end() ) {
-			const MangleTable &mangleTable = decls->second;
-			for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
-				// check for C decls with the same name, skipping those with a compatible type (by mangleName)
-				if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first != mangleName ) return true;
-			}
-		}
-
-		return tables->base.hasIncompatibleCDecl( id, mangleName, scope );
-	}
-
-	bool Indexer::hasCompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const {
-		if ( ! tables ) return false;
-		if ( tables->scope < scope ) return false;
-
-		(*stats_idtable().find)++;
-		stats_idtable().key->push( id.size() );
-		stats_idtable().size->push( tables->idTable.size() );
-		IdTable::const_iterator decls = tables->idTable.find( id );
-		if ( decls != tables->idTable.end() ) {
-			const MangleTable &mangleTable = decls->second;
-			for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
-				// check for C decls with the same name, skipping
-				// those with an incompatible type (by mangleName)
-				if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first == mangleName ) return true;
-			}
-		}
-
-		return tables->base.hasCompatibleCDecl( id, mangleName, scope );
-	}
-
-	NamedTypeDecl *Indexer::lookupTypeAtScope( const std::string &id, unsigned long scope ) const {
-		if ( ! tables ) return 0;
-		if ( tables->scope < scope ) return 0;
-		if ( tables->scope > scope ) return tables->base.lookupTypeAtScope( id, scope );
-
-		TypeTable::const_iterator ret = tables->typeTable.find( id );
-		return ret != tables->typeTable.end() ? ret->second : tables->base.lookupTypeAtScope( id, scope );
-	}
-
-	StructDecl *Indexer::lookupStructAtScope( const std::string &id, unsigned long scope ) const {
-		if ( ! tables ) return 0;
-		if ( tables->scope < scope ) return 0;
-		if ( tables->scope > scope ) return tables->base.lookupStructAtScope( id, scope );
-
-		StructTable::const_iterator ret = tables->structTable.find( id );
-		return ret != tables->structTable.end() ? ret->second : tables->base.lookupStructAtScope( id, scope );
-	}
-
-	EnumDecl *Indexer::lookupEnumAtScope( const std::string &id, unsigned long scope ) const {
-		if ( ! tables ) return 0;
-		if ( tables->scope < scope ) return 0;
-		if ( tables->scope > scope ) return tables->base.lookupEnumAtScope( id, scope );
-
-		EnumTable::const_iterator ret = tables->enumTable.find( id );
-		return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnumAtScope( id, scope );
-	}
-
-	UnionDecl *Indexer::lookupUnionAtScope( const std::string &id, unsigned long scope ) const {
-		if ( ! tables ) return 0;
-		if ( tables->scope < scope ) return 0;
-		if ( tables->scope > scope ) return tables->base.lookupUnionAtScope( id, scope );
-
-		UnionTable::const_iterator ret = tables->unionTable.find( id );
-		return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnionAtScope( id, scope );
-	}
-
-	TraitDecl *Indexer::lookupTraitAtScope( const std::string &id, unsigned long scope ) const {
-		if ( ! tables ) return 0;
-		if ( tables->scope < scope ) return 0;
-		if ( tables->scope > scope ) return tables->base.lookupTraitAtScope( id, scope );
-
-		TraitTable::const_iterator ret = tables->traitTable.find( id );
-		return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTraitAtScope( id, scope );
+		return atScope( 0 )->lookupEnum( id );
 	}
 
@@ -487,45 +207,241 @@
 	}
 
-	bool addedIdConflicts( Indexer::IdData & existing, DeclarationWithType *added, BaseSyntaxNode * deleteStmt, Indexer::ConflictFunction handleConflicts ) {
-		// if we're giving the same name mangling to things of different types then there is something wrong
+	
+	bool Indexer::addedIdConflicts( 
+			const Indexer::IdData & existing, DeclarationWithType *added, 
+			Indexer::OnConflict handleConflicts, BaseSyntaxNode * deleteStmt ) {
+		// if we're giving the same name mangling to things of different types then there is 
+		// something wrong
 		assert( (isObject( added ) && isObject( existing.id ) )
 			|| ( isFunction( added ) && isFunction( existing.id ) ) );
 
-		if ( LinkageSpec::isOverridable( existing.id->get_linkage() ) ) {
+		if ( LinkageSpec::isOverridable( existing.id->linkage ) ) {
 			// new definition shadows the autogenerated one, even at the same scope
 			return false;
-		} else if ( LinkageSpec::isMangled( added->get_linkage() ) || ResolvExpr::typesCompatible( added->get_type(), existing.id->get_type(), Indexer() ) ) {
+		} else if ( LinkageSpec::isMangled( added->linkage ) 
+				|| ResolvExpr::typesCompatible( 
+					added->get_type(), existing.id->get_type(), Indexer() ) ) {
 
 			// it is a conflict if one declaration is deleted and the other is not
 			if ( deleteStmt && ! existing.deleteStmt ) {
-				return handleConflicts( existing, "deletion of defined identifier " );
+				if ( handleConflicts.mode == OnConflict::Error ) {
+					SemanticError( added, "deletion of defined identifier " );
+				}
+				return true;
 			} else if ( ! deleteStmt && existing.deleteStmt ) {
-				return handleConflicts( existing, "definition of deleted identifier " );
+				if ( handleConflicts.mode == OnConflict::Error ) {
+					SemanticError( added, "definition of deleted identifier " );
+				}
+				return true;
 			}
 
 			if ( isDefinition( added ) && isDefinition( existing.id ) ) {
-				if ( isFunction( added ) ) {
-					return handleConflicts( existing, "duplicate function definition for " );
+				if ( handleConflicts.mode == OnConflict::Error ) {
+					SemanticError( added, 
+						isFunction( added ) ? 
+							"duplicate function definition for " : 
+							"duplicate object definition for " );
+				}
+				return true;
+			} // if
+		} else {
+			if ( handleConflicts.mode == OnConflict::Error ) {
+				SemanticError( added, "duplicate definition for " );
+			}
+			return true;
+		} // if
+
+		return true;
+	}
+
+	bool Indexer::hasCompatibleCDecl( const std::string &id, const std::string &mangleName ) const {
+		if ( ! idTable ) return false;
+
+		++*stats().map_lookups;
+		auto decls = idTable->find( id );
+		if ( decls == idTable->end() ) return false;
+
+		for ( auto decl : *(decls->second) ) {
+			// skip other scopes (hidden by this decl)
+			if ( decl.second.scope != scope ) continue;
+			// check for C decl with compatible type (by mangleName)
+			if ( ! LinkageSpec::isMangled( decl.second.id->linkage ) && decl.first == mangleName ) {
+				return true;
+			}
+		}
+		
+		return false;
+	}
+
+	bool Indexer::hasIncompatibleCDecl( 
+			const std::string &id, const std::string &mangleName ) const {
+		if ( ! idTable ) return false;
+
+		++*stats().map_lookups;
+		auto decls = idTable->find( id );
+		if ( decls == idTable->end() ) return false;
+
+		for ( auto decl : *(decls->second) ) {
+			// skip other scopes (hidden by this decl)
+			if ( decl.second.scope != scope ) continue;
+			// check for C decl with incompatible type (by manglename)
+			if ( ! LinkageSpec::isMangled( decl.second.id->linkage ) && decl.first != mangleName ) {
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	/// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function
+	std::string getOtypeKey( FunctionDecl* function ) {
+		auto& params = function->type->parameters;
+		assert( ! params.empty() );
+		// use base type of pointer, so that qualifiers on the pointer type aren't considered.
+		Type* base = InitTweak::getPointerBase( params.front()->get_type() );
+		assert( base );
+		return Mangler::mangle( base );
+	}
+
+	/// gets the declaration for the function acting on a type specified by otype key, 
+	/// nullptr if none such
+	FunctionDecl * getFunctionForOtype( DeclarationWithType * decl, const std::string& otypeKey ) {
+		FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl );
+		if ( ! func || otypeKey != getOtypeKey( func ) ) return nullptr;
+		return func;
+	}
+
+	bool Indexer::removeSpecialOverrides( 
+			Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) {
+		// if a type contains user defined ctor/dtor/assign, then special rules trigger, which 
+		// determinethe set of ctor/dtor/assign that can be used  by the requester. In particular, 
+		// if the user defines a default ctor, then the generated default ctor is unavailable, 
+		// likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 
+		// field ctors are available. If the user defines any ctor then the generated default ctor 
+		// is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 
+		// anything that looks like a copy constructor, then the generated copy constructor is 
+		// unavailable, and likewise for the assignment operator.
+
+		// only relevant on function declarations
+		FunctionDecl * function = dynamic_cast< FunctionDecl * >( data.id );
+		if ( ! function ) return true;
+		// only need to perform this check for constructors, destructors, and assignment functions
+		if ( ! CodeGen::isCtorDtorAssign( data.id->name ) ) return true;
+
+		// set up information for this type
+		bool dataIsUserDefinedFunc = ! LinkageSpec::isOverridable( function->linkage );
+		bool dataIsCopyFunc = InitTweak::isCopyFunction( function, function->name );
+		std::string dataOtypeKey = getOtypeKey( function );
+
+		if ( dataIsUserDefinedFunc && dataIsCopyFunc ) {
+			// this is a user-defined copy function
+			// if this is the first such, delete/remove non-user-defined overloads as needed
+			std::vector< std::string > removed;
+			std::vector< MangleTable::value_type > deleted;
+			bool alreadyUserDefinedFunc = false;
+			
+			for ( const auto& entry : *mangleTable ) {
+				// skip decls that aren't functions or are for the wrong type
+				FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
+				if ( ! decl ) continue;
+
+				bool isCopyFunc = InitTweak::isCopyFunction( decl, decl->name );
+				if ( ! LinkageSpec::isOverridable( decl->linkage ) ) {
+					// matching user-defined function
+					if ( isCopyFunc ) {
+						// mutation already performed, return early
+						return true;
+					} else {
+						// note that non-copy deletions already performed
+						alreadyUserDefinedFunc = true;
+					}
 				} else {
-					return handleConflicts( existing, "duplicate object definition for " );
-				} // if
-			} // if
-		} else {
-			return handleConflicts( existing, "duplicate definition for " );
-		} // if
-
+					// non-user-defined function; mark for deletion/removal as appropriate
+					if ( isCopyFunc ) {
+						removed.push_back( entry.first );
+					} else if ( ! alreadyUserDefinedFunc ) {
+						deleted.push_back( entry );
+					}
+				}
+			}
+
+			// perform removals from mangle table, and deletions if necessary
+			for ( const auto& key : removed ) {
+				++*stats().map_mutations;
+				mangleTable = mangleTable->erase( key );
+			}
+			if ( ! alreadyUserDefinedFunc ) for ( const auto& entry : deleted ) {
+				++*stats().map_mutations;
+				mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } );
+			}
+		} else if ( dataIsUserDefinedFunc ) {
+			// this is a user-defined non-copy function
+			// if this is the first user-defined function, delete non-user-defined overloads
+			std::vector< MangleTable::value_type > deleted;
+			
+			for ( const auto& entry : *mangleTable ) {
+				// skip decls that aren't functions or are for the wrong type
+				FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
+				if ( ! decl ) continue;
+
+				// exit early if already a matching user-defined function;
+				// earlier function will have mutated table
+				if ( ! LinkageSpec::isOverridable( decl->linkage ) ) return true;
+
+				// skip mutating intrinsic functions
+				if ( decl->linkage == LinkageSpec::Intrinsic ) continue;
+
+				// user-defined non-copy functions do not override copy functions
+				if ( InitTweak::isCopyFunction( decl, decl->name ) ) continue;
+
+				// this function to be deleted after mangleTable iteration is complete
+				deleted.push_back( entry );
+			}
+
+			// mark deletions to update mangle table
+			// this needs to be a separate loop because of iterator invalidation
+			for ( const auto& entry : deleted ) {
+				++*stats().map_mutations;
+				mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } );
+			}
+		} else if ( function->linkage != LinkageSpec::Intrinsic ) {
+			// this is an overridable generated function
+			// if there already exists a matching user-defined function, delete this appropriately
+			for ( const auto& entry : *mangleTable ) {
+				// skip decls that aren't functions or are for the wrong type
+				FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
+				if ( ! decl ) continue;
+
+				// skip non-user-defined functions
+				if ( LinkageSpec::isOverridable( decl->linkage ) ) continue;
+
+				if ( dataIsCopyFunc ) {
+					// remove current function if exists a user-defined copy function
+					// since the signatures for copy functions don't need to match exactly, using 
+					// a delete statement is the wrong approach
+					if ( InitTweak::isCopyFunction( decl, decl->name ) ) return false;
+				} else {
+					// mark current function deleted by first user-defined function found
+					data.deleteStmt = decl;
+					return true;
+				}
+			}
+		}
+		
+		// nothing (more) to fix, return true
 		return true;
 	}
 
-	void Indexer::addId( DeclarationWithType *decl, ConflictFunction handleConflicts, Expression * baseExpr, BaseSyntaxNode * deleteStmt ) {
-		if ( decl->name == "" ) return;
-		debugPrint( "Adding Id " << decl->name << std::endl );
-		makeWritable();
-
+	void Indexer::addId( 
+			DeclarationWithType *decl, OnConflict handleConflicts, Expression * baseExpr, 
+			BaseSyntaxNode * deleteStmt ) {
+		++*stats().add_calls;
 		const std::string &name = decl->name;
+		if ( name == "" ) return;
+		
 		std::string mangleName;
 		if ( LinkageSpec::isOverridable( decl->linkage ) ) {
-			// mangle the name without including the appropriate suffix, so overridable routines are placed into the
-			// same "bucket" as their user defined versions.
+			// mangle the name without including the appropriate suffix, so overridable routines 
+			// are placed into the same "bucket" as their user defined versions.
 			mangleName = Mangler::mangle( decl, false );
 		} else {
@@ -533,38 +449,71 @@
 		} // if
 
-		// this ensures that no two declarations with the same unmangled name at the same scope both have C linkage
-		if ( ! LinkageSpec::isMangled( decl->linkage ) ) {
-			// NOTE this is broken in Richard's original code in such a way that it never triggers (it
-			// doesn't check decls that have the same manglename, and all C-linkage decls are defined to
-			// have their name as their manglename, hence the error can never trigger).
-			// The code here is closer to correct, but name mangling would have to be completely
-			// isomorphic to C type-compatibility, which it may not be.
-			if ( hasIncompatibleCDecl( name, mangleName, scope ) ) {
+		// this ensures that no two declarations with the same unmangled name at the same scope 
+		// both have C linkage
+		if ( LinkageSpec::isMangled( decl->linkage ) ) {
+			// Check that a Cforall declaration doesn't override any C declaration
+			if ( hasCompatibleCDecl( name, mangleName ) ) {
+				SemanticError( decl, "Cforall declaration hides C function " );
+			}
+		} else {
+			// NOTE: only correct if name mangling is completely isomorphic to C 
+			// type-compatibility, which it may not be.
+			if ( hasIncompatibleCDecl( name, mangleName ) ) {
 				SemanticError( decl, "conflicting overload of C function " );
 			}
-		} else {
-			// Check that a Cforall declaration doesn't override any C declaration
-			if ( hasCompatibleCDecl( name, mangleName, scope ) ) {
-				SemanticError( decl, "Cforall declaration hides C function " );
-			}
-		}
-
-		// Skip repeat declarations of the same identifier
-		IdData * existing = lookupIdAtScope( name, mangleName, scope );
-		if ( existing && existing->id && addedIdConflicts( *existing, decl, deleteStmt, handleConflicts ) ) return;
-
-		// add to indexer
-		tables->idTable[ name ][ mangleName ] = IdData{ decl, baseExpr, deleteStmt };
-		++tables->size;
+		}
+
+		// ensure tables exist and add identifier
+		MangleTable::Ptr mangleTable;
+		if ( ! idTable ) {
+			idTable = IdTable::new_ptr();
+			mangleTable = MangleTable::new_ptr();
+		} else {
+			++*stats().map_lookups;
+			auto decls = idTable->find( name );
+			if ( decls == idTable->end() ) {
+				mangleTable = MangleTable::new_ptr();
+			} else {
+				mangleTable = decls->second;
+				// skip in-scope repeat declarations of same identifier
+				++*stats().map_lookups;
+				auto existing = mangleTable->find( mangleName );
+				if ( existing != mangleTable->end()
+						&& existing->second.scope == scope
+						&& existing->second.id ) {
+					if ( addedIdConflicts( existing->second, decl, handleConflicts, deleteStmt ) ) {
+						if ( handleConflicts.mode == OnConflict::Delete ) {
+							// set delete expression for conflicting identifier
+							lazyInitScope();
+							*stats().map_mutations += 2;
+							idTable = idTable->set(
+								name,
+								mangleTable->set( 
+									mangleName, 
+									IdData{ existing->second, handleConflicts.deleteStmt } ) );
+						}
+						return;
+					}
+				}
+			}
+		}
+
+		// add/overwrite with new identifier
+		lazyInitScope();
+		IdData data{ decl, baseExpr, deleteStmt, scope };
+		// Ensure that auto-generated ctor/dtor/assignment are deleted if necessary
+		if ( ! removeSpecialOverrides( data, mangleTable ) ) return;
+		*stats().map_mutations += 2;
+		idTable = idTable->set( name, mangleTable->set( mangleName, std::move(data) ) );
 	}
 
 	void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) {
 		// default handling of conflicts is to raise an error
-		addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, baseExpr, decl->isDeleted ? decl : nullptr );
+		addId( decl, OnConflict::error(), baseExpr, decl->isDeleted ? decl : nullptr );
 	}
 
 	void Indexer::addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt ) {
 		// default handling of conflicts is to raise an error
-		addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, nullptr, deleteStmt );
+		addId( decl, OnConflict::error(), nullptr, deleteStmt );
 	}
 
@@ -581,25 +530,26 @@
 			}
 		}
-		// does not need to be added to the table if both existing and added have a base that are the same
+		// does not need to be added to the table if both existing and added have a base that are 
+		// the same
 		return true;
 	}
 
 	void Indexer::addType( NamedTypeDecl *decl ) {
-		debugPrint( "Adding type " << decl->name << std::endl );
-		makeWritable();
-
+		++*stats().add_calls;
 		const std::string &id = decl->name;
-		TypeTable::iterator existing = tables->typeTable.find( id );
-		if ( existing == tables->typeTable.end() ) {
-			NamedTypeDecl *parent = tables->base.lookupTypeAtScope( id, scope );
-			if ( ! parent || ! addedTypeConflicts( parent, decl ) ) {
-				tables->typeTable.insert( existing, std::make_pair( id, decl ) );
-				++tables->size;
-			}
-		} else {
-			if ( ! addedTypeConflicts( existing->second, decl ) ) {
-				existing->second = decl;
-			}
-		}
+
+		if ( ! typeTable ) { 
+			typeTable = TypeTable::new_ptr();
+		} else {
+			++*stats().map_lookups;
+			auto existing = typeTable->find( id );
+			if ( existing != typeTable->end() 
+				&& existing->second.scope == scope 
+				&& addedTypeConflicts( existing->second.decl, decl ) ) return;
+		}
+		
+		lazyInitScope();
+		++*stats().map_mutations;
+		typeTable = typeTable->set( id, Scoped<NamedTypeDecl>{ decl, scope } );
 	}
 
@@ -614,90 +564,89 @@
 
 	void Indexer::addStruct( const std::string &id ) {
-		debugPrint( "Adding fwd decl for struct " << id << std::endl );
 		addStruct( new StructDecl( id ) );
 	}
 
 	void Indexer::addStruct( StructDecl *decl ) {
-		debugPrint( "Adding struct " << decl->name << std::endl );
-		makeWritable();
-
+		++*stats().add_calls;
 		const std::string &id = decl->name;
-		StructTable::iterator existing = tables->structTable.find( id );
-		if ( existing == tables->structTable.end() ) {
-			StructDecl *parent = tables->base.lookupStructAtScope( id, scope );
-			if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
-				tables->structTable.insert( existing, std::make_pair( id, decl ) );
-				++tables->size;
-			}
-		} else {
-			if ( ! addedDeclConflicts( existing->second, decl ) ) {
-				existing->second = decl;
-			}
-		}
+
+		if ( ! structTable ) {
+			structTable = StructTable::new_ptr();
+		} else {
+			++*stats().map_lookups;
+			auto existing = structTable->find( id );
+			if ( existing != structTable->end()  
+				&& existing->second.scope == scope 
+				&& addedDeclConflicts( existing->second.decl, decl ) ) return;
+		}
+
+		lazyInitScope();
+		++*stats().map_mutations;
+		structTable = structTable->set( id, Scoped<StructDecl>{ decl, scope } );
 	}
 
 	void Indexer::addEnum( EnumDecl *decl ) {
-		debugPrint( "Adding enum " << decl->name << std::endl );
-		makeWritable();
-
+		++*stats().add_calls;
 		const std::string &id = decl->name;
-		EnumTable::iterator existing = tables->enumTable.find( id );
-		if ( existing == tables->enumTable.end() ) {
-			EnumDecl *parent = tables->base.lookupEnumAtScope( id, scope );
-			if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
-				tables->enumTable.insert( existing, std::make_pair( id, decl ) );
-				++tables->size;
-			}
-		} else {
-			if ( ! addedDeclConflicts( existing->second, decl ) ) {
-				existing->second = decl;
-			}
-		}
+
+		if ( ! enumTable ) {
+			enumTable = EnumTable::new_ptr();
+		} else {
+			++*stats().map_lookups;
+			auto existing = enumTable->find( id );
+			if ( existing != enumTable->end()  
+				&& existing->second.scope == scope 
+				&& addedDeclConflicts( existing->second.decl, decl ) ) return;
+		}
+		
+		lazyInitScope();
+		++*stats().map_mutations;
+		enumTable = enumTable->set( id, Scoped<EnumDecl>{ decl, scope } );
 	}
 
 	void Indexer::addUnion( const std::string &id ) {
-		debugPrint( "Adding fwd decl for union " << id << std::endl );
 		addUnion( new UnionDecl( id ) );
 	}
 
 	void Indexer::addUnion( UnionDecl *decl ) {
-		debugPrint( "Adding union " << decl->name << std::endl );
-		makeWritable();
-
+		++*stats().add_calls;
 		const std::string &id = decl->name;
-		UnionTable::iterator existing = tables->unionTable.find( id );
-		if ( existing == tables->unionTable.end() ) {
-			UnionDecl *parent = tables->base.lookupUnionAtScope( id, scope );
-			if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
-				tables->unionTable.insert( existing, std::make_pair( id, decl ) );
-				++tables->size;
-			}
-		} else {
-			if ( ! addedDeclConflicts( existing->second, decl ) ) {
-				existing->second = decl;
-			}
-		}
+
+		if ( ! unionTable ) {
+			unionTable = UnionTable::new_ptr();
+		} else {
+			++*stats().map_lookups;
+			auto existing = unionTable->find( id );
+			if ( existing != unionTable->end() 
+				&& existing->second.scope == scope 
+				&& addedDeclConflicts( existing->second.decl, decl ) ) return;
+		}
+
+		lazyInitScope();
+		++*stats().map_mutations;
+		unionTable = unionTable->set( id, Scoped<UnionDecl>{ decl, scope } );
 	}
 
 	void Indexer::addTrait( TraitDecl *decl ) {
-		debugPrint( "Adding trait " << decl->name << std::endl );
-		makeWritable();
-
+		++*stats().add_calls;
 		const std::string &id = decl->name;
-		TraitTable::iterator existing = tables->traitTable.find( id );
-		if ( existing == tables->traitTable.end() ) {
-			TraitDecl *parent = tables->base.lookupTraitAtScope( id, scope );
-			if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
-				tables->traitTable.insert( existing, std::make_pair( id, decl ) );
-				++tables->size;
-			}
-		} else {
-			if ( ! addedDeclConflicts( existing->second, decl ) ) {
-				existing->second = decl;
-			}
-		}
-	}
-
-	void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, ConflictFunction handleConflicts ) {
+
+		if ( ! traitTable ) {
+			traitTable = TraitTable::new_ptr();
+		} else {
+			++*stats().map_lookups;
+			auto existing = traitTable->find( id );
+			if ( existing != traitTable->end() 
+				&& existing->second.scope == scope 
+				&& addedDeclConflicts( existing->second.decl, decl ) ) return;
+		}
+
+		lazyInitScope();
+		++*stats().map_mutations;
+		traitTable = traitTable->set( id, Scoped<TraitDecl>{ decl, scope } );
+	}
+
+	void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, 
+			OnConflict handleConflicts ) {
 		for ( Declaration * decl : aggr->members ) {
 			if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
@@ -705,5 +654,5 @@
 				if ( dwt->name == "" ) {
 					Type * t = dwt->get_type()->stripReferences();
-					if ( dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t ) ) {
+					if ( dynamic_cast<StructInstType*>( t ) || dynamic_cast<UnionInstType*>( t ) ) {
 						Expression * base = expr->clone();
 						ResolvExpr::Cost cost = ResolvExpr::Cost::zero; // xxx - carry this cost into the indexer as a base cost?
@@ -722,9 +671,5 @@
 				assertf( aggr, "WithStmt expr has non-aggregate type: %s", toString( expr->result ).c_str() );
 
-				addMembers( aggr, expr, [withStmt](IdData & existing, const std::string &) {
-					// on conflict, delete the identifier
-					existing.deleteStmt = withStmt;
-					return true;
-				});
+				addMembers( aggr, expr, OnConflict::deleteWith( withStmt ) );
 			}
 		}
@@ -748,64 +693,4 @@
 		addIds( ftype->returnVals );
 		addIds( ftype->parameters );
-	}
-
-	void Indexer::enterScope() {
-		++scope;
-
-		if ( doDebug ) {
-			std::cerr << "--- Entering scope " << scope << std::endl;
-		}
-	}
-
-	void Indexer::leaveScope() {
-		using std::cerr;
-
-		assert( scope > 0 && "cannot leave initial scope" );
-		if ( doDebug ) {
-			cerr << "--- Leaving scope " << scope << " containing" << std::endl;
-		}
-		--scope;
-
-		while ( tables && tables->scope > scope ) {
-			if ( doDebug ) {
-				dump( tables->idTable, cerr );
-				dump( tables->typeTable, cerr );
-				dump( tables->structTable, cerr );
-				dump( tables->enumTable, cerr );
-				dump( tables->unionTable, cerr );
-				dump( tables->traitTable, cerr );
-			}
-
-			// swap tables for base table until we find one at an appropriate scope
-			Indexer::Impl *base = newRef( tables->base.tables );
-			deleteRef( tables );
-			tables = base;
-		}
-	}
-
-	void Indexer::print( std::ostream &os, int indent ) const {
-		using std::cerr;
-
-		if ( tables ) {
-			os << "--- scope " << tables->scope << " ---" << std::endl;
-
-			os << "===idTable===" << std::endl;
-			dump( tables->idTable, os );
-			os << "===typeTable===" << std::endl;
-			dump( tables->typeTable, os );
-			os << "===structTable===" << std::endl;
-			dump( tables->structTable, os );
-			os << "===enumTable===" << std::endl;
-			dump( tables->enumTable, os );
-			os << "===unionTable===" << std::endl;
-			dump( tables->unionTable, os );
-			os << "===contextTable===" << std::endl;
-			dump( tables->traitTable, os );
-
-			tables->base.print( os, indent );
-		} else {
-			os << "--- end ---" << std::endl;
-		}
-
 	}
 
Index: src/SymTab/Indexer.h
===================================================================
--- src/SymTab/Indexer.h	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/SymTab/Indexer.h	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -9,36 +9,31 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 21:38:55 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug 17 16:09:12 2017
-// Update Count     : 8
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Fri Mar  8 13:55:00 2019
+// Update Count     : 9
 //
 
 #pragma once
 
-#include <iosfwd>             // for ostream
-#include <list>               // for list
-#include <string>             // for string
-#include <functional>         // for function
+#include <functional>              // for function
+#include <list>                    // for list
+#include <memory>                  // for shared_ptr, enable_shared_from_this
+#include <string>                  // for string
 
-#include "SynTree/Visitor.h"  // for Visitor
-#include "SynTree/SynTree.h"  // for AST nodes
+#include "Common/PersistentMap.h"  // for PersistentMap
+#include "SynTree/SynTree.h"       // for AST nodes
 
 namespace ResolvExpr {
-class Cost;
+	class Cost;
 }
 
 namespace SymTab {
-	class Indexer {
-	  public:
+	class Indexer : public std::enable_shared_from_this<SymTab::Indexer> {
+	public:
 		explicit Indexer();
+		virtual ~Indexer();
 
-		Indexer( const Indexer &that );
-		Indexer( Indexer &&that );
-		virtual ~Indexer();
-		Indexer& operator= ( const Indexer &that );
-		Indexer& operator= ( Indexer &&that );
-
-		// when using an indexer manually (e.g., within a mutator traversal), it is necessary to tell the indexer
-		// explicitly when scopes begin and end
+		// when using an indexer manually (e.g., within a mutator traversal), it is necessary to 
+		// tell the indexer explicitly when scopes begin and end
 		void enterScope();
 		void leaveScope();
@@ -50,8 +45,15 @@
 			/// non-null if this declaration is deleted
 			BaseSyntaxNode * deleteStmt = nullptr;
+			/// scope of identifier
+			unsigned long scope = 0;
 
 			// NOTE: shouldn't need either of these constructors, but gcc-4 does not properly support initializer lists with default members.
 			IdData() = default;
-			IdData( DeclarationWithType * id, Expression * baseExpr, BaseSyntaxNode * deleteStmt ) : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ) {}
+			IdData( 
+				DeclarationWithType * id, Expression * baseExpr, BaseSyntaxNode * deleteStmt,
+				unsigned long scope ) 
+				: id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ), scope( scope ) {}
+			IdData( const IdData& o, BaseSyntaxNode * deleteStmt )
+				: id( o.id ), baseExpr( o.baseExpr ), deleteStmt( deleteStmt ), scope( o.scope ) {}
 
 			Expression * combine( ResolvExpr::Cost & cost ) const;
@@ -80,22 +82,4 @@
 		EnumDecl *globalLookupEnum( const std::string &id ) const;
 
-		void print( std::ostream &os, int indent = 0 ) const;
-
-		/// looks up a specific mangled ID at the given scope
-		IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope );
-		const IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
-		/// returns true if there exists a declaration with C linkage and the given name with a different mangled name
-		bool hasIncompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
-		/// returns true if there exists a declaration with C linkage and the given name with the same mangled name
-		bool hasCompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
-		// equivalents to lookup functions that only look at tables at scope `scope` (which should be >= tables->scope)
-		NamedTypeDecl *lookupTypeAtScope( const std::string &id, unsigned long scope ) const;
-		StructDecl *lookupStructAtScope( const std::string &id, unsigned long scope ) const;
-		EnumDecl *lookupEnumAtScope( const std::string &id, unsigned long scope ) const;
-		UnionDecl *lookupUnionAtScope( const std::string &id, unsigned long scope ) const;
-		TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const;
-
-		typedef std::function<bool(IdData &, const std::string &)> ConflictFunction;
-
 		void addId( DeclarationWithType * decl, Expression * baseExpr = nullptr );
 		void addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt );
@@ -112,7 +96,4 @@
 		void addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt );
 
-		/// adds all of the members of the Aggregate (addWith helper)
-		void addMembers( AggregateDecl * aggr, Expression * expr, ConflictFunction );
-
 		/// convenience function for adding a list of Ids to the indexer
 		void addIds( const std::list< DeclarationWithType * > & decls );
@@ -124,26 +105,80 @@
 		void addFunctionType( FunctionType * ftype );
 
-		bool doDebug = false; ///< Display debugging trace?
 	  private:
-		struct Impl;
+	  	/// Wraps a Decl* with a scope
+	  	template<typename Decl>
+		struct Scoped {
+			Decl* decl;           ///< declaration
+			unsigned long scope;  ///< scope of this declaration
 
-		Impl *tables;         ///< Copy-on-write instance of table data structure
-		unsigned long scope;  ///< Scope index of this pointer
+			Scoped(Decl* d, unsigned long s) : decl(d), scope(s) {}
+		};
 
-		/// Takes a new ref to a table (returns null if null)
-		static Impl *newRef( Impl *toClone );
-		/// Clears a ref to a table (does nothing if null)
-		static void deleteRef( Impl *toFree );
+		using Ptr = std::shared_ptr<const Indexer>;
 
-		// Removes matching autogenerated constructors and destructors
-		// so that they will not be selected
-		// void removeSpecialOverrides( FunctionDecl *decl );
-		void removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const;
+		using MangleTable = PersistentMap< std::string, IdData >;
+		using IdTable = PersistentMap< std::string, MangleTable::Ptr >;
+		using TypeTable = PersistentMap< std::string, Scoped<NamedTypeDecl> >;
+		using StructTable = PersistentMap< std::string, Scoped<StructDecl> >;
+		using EnumTable = PersistentMap< std::string, Scoped<EnumDecl> >;
+		using UnionTable = PersistentMap< std::string, Scoped<UnionDecl> >;
+		using TraitTable = PersistentMap< std::string, Scoped<TraitDecl> >;
 
-		/// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope)
-		void makeWritable();
+		IdTable::Ptr idTable;          ///< identifier namespace
+		TypeTable::Ptr typeTable;      ///< type namespace
+		StructTable::Ptr structTable;  ///< struct namespace
+		EnumTable::Ptr enumTable;      ///< enum namespace
+		UnionTable::Ptr unionTable;    ///< union namespace
+		TraitTable::Ptr traitTable;    ///< trait namespace
+
+		Ptr prevScope;                 ///< reference to indexer for parent scope
+		unsigned long scope;           ///< Scope index of this indexer
+		unsigned long repScope;        ///< Scope index of currently represented scope
+
+		/// Ensures that a proper backtracking scope exists before a mutation
+		void lazyInitScope();
+
+		/// Gets the indexer at the given scope
+		const Indexer* atScope( unsigned long scope ) const;
+
+		/// Removes matching autogenerated constructors and destructors so that they will not be 
+		/// selected. If returns false, passed decl should not be added.
+		bool removeSpecialOverrides( IdData& decl, MangleTable::Ptr& mangleTable );
+
+		/// Options for handling identifier conflicts
+		struct OnConflict {
+			enum {
+				Error,  ///< Throw a semantic error
+				Delete  ///< Delete the earlier version with the delete statement
+			} mode;
+			BaseSyntaxNode * deleteStmt;  ///< Statement that deletes this expression
+
+		private:
+			OnConflict() : mode(Error), deleteStmt(nullptr) {}
+			OnConflict( BaseSyntaxNode * d ) : mode(Delete), deleteStmt(d) {}
+		public:
+			OnConflict( const OnConflict& ) = default;
+
+			static OnConflict error() { return {}; }
+			static OnConflict deleteWith( BaseSyntaxNode * d ) { return { d }; }
+		};
+
+		/// true if the existing identifier conflicts with the added identifier
+		bool addedIdConflicts(
+			const IdData& existing, DeclarationWithType * added, OnConflict handleConflicts, 
+			BaseSyntaxNode * deleteStmt );
 
 		/// common code for addId, addDeletedId, etc.
-		void addId( DeclarationWithType * decl, ConflictFunction, Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr );
+		void addId( 
+			DeclarationWithType * decl, OnConflict handleConflicts, 
+			Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr );
+
+		/// adds all of the members of the Aggregate (addWith helper)
+		void addMembers( AggregateDecl * aggr, Expression * expr, OnConflict handleConflicts );
+
+		/// returns true if there exists a declaration with C linkage and the given name with the same mangled name
+		bool hasCompatibleCDecl( const std::string &id, const std::string &mangleName ) const;
+		/// returns true if there exists a declaration with C linkage and the given name with a different mangled name
+		bool hasIncompatibleCDecl( const std::string &id, const std::string &mangleName ) const;
 	};
 } // namespace SymTab
Index: src/SynTree/Attribute.cc
===================================================================
--- src/SynTree/Attribute.cc	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/SynTree/Attribute.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -21,5 +21,5 @@
 #include "Expression.h"      // for Expression
 
-Attribute::Attribute( const Attribute &other ) : name( other.name ) {
+Attribute::Attribute( const Attribute &other ) : BaseSyntaxNode( other ), name( other.name ) {
 	cloneAll( other.parameters, parameters );
 }
Index: src/SynTree/BaseSyntaxNode.h
===================================================================
--- src/SynTree/BaseSyntaxNode.h	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/SynTree/BaseSyntaxNode.h	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -18,4 +18,6 @@
 #include "Common/CodeLocation.h"
 #include "Common/Indenter.h"
+#include "Common/Stats.h"
+
 class Visitor;
 class Mutator;
@@ -23,5 +25,10 @@
 class BaseSyntaxNode {
   public:
+  static Stats::Counters::SimpleCounter* new_nodes;
+
 	CodeLocation location;
+
+  BaseSyntaxNode() { ++*new_nodes; }
+  BaseSyntaxNode( const BaseSyntaxNode& o ) : location(o.location) { ++*new_nodes; }
 
 	virtual ~BaseSyntaxNode() {}
Index: src/SynTree/Constant.cc
===================================================================
--- src/SynTree/Constant.cc	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/SynTree/Constant.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -25,5 +25,5 @@
 Constant::Constant( Type * type, std::string rep, double val ) : type( type ), rep( rep ), val( val ) {}
 
-Constant::Constant( const Constant &other ) : rep( other.rep ), val( other.val ) {
+Constant::Constant( const Constant &other ) : BaseSyntaxNode( other ), rep( other.rep ), val( other.val ) {
 	type = other.type->clone();
 }
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/SynTree/Declaration.h	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -211,7 +211,11 @@
 		TypeDecl::Kind kind;
 		bool isComplete;
+		
 		Data() : kind( (TypeDecl::Kind)-1 ), isComplete( false ) {}
 		Data( TypeDecl * typeDecl ) : Data( typeDecl->get_kind(), typeDecl->isComplete() ) {}
 		Data( Kind kind, bool isComplete ) : kind( kind ), isComplete( isComplete ) {}
+		Data( const Data& d1, const Data& d2 ) 
+		: kind( d1.kind ), isComplete ( d1.isComplete || d2.isComplete ) {}
+
 		bool operator==(const Data & other) const { return kind == other.kind && isComplete == other.isComplete; }
 		bool operator!=(const Data & other) const { return !(*this == other);}
Index: src/SynTree/Statement.h
===================================================================
--- src/SynTree/Statement.h	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/SynTree/Statement.h	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Mar  8 14:53:02 2018
-// Update Count     : 78
+// Last Modified On : Tue Mar 12 09:01:53 2019
+// Update Count     : 83
 //
 
@@ -19,5 +19,5 @@
 #include <list>                    // for list
 #include <memory>                  // for allocator
-#include <vector>	                 // for vector
+#include <vector>				   // for vector
 
 #include "BaseSyntaxNode.h"        // for BaseSyntaxNode
@@ -43,8 +43,8 @@
 	const std::list<Label> & get_labels() const { return labels; }
 
-	virtual Statement *clone() const override = 0;
-	virtual void accept( Visitor &v ) override = 0;
-	virtual Statement *acceptMutator( Mutator &m ) override = 0;
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	virtual Statement * clone() const override = 0;
+	virtual void accept( Visitor & v ) override = 0;
+	virtual Statement * acceptMutator( Mutator & m ) override = 0;
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -55,5 +55,5 @@
 	CompoundStmt();
 	CompoundStmt( std::list<Statement *> stmts );
-	CompoundStmt( const CompoundStmt &other );
+	CompoundStmt( const CompoundStmt & other );
 	virtual ~CompoundStmt();
 
@@ -62,8 +62,8 @@
 	void push_front( Statement * stmt ) { kids.push_front( stmt ); }
 
-	virtual CompoundStmt *clone() const override { return new CompoundStmt( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual CompoundStmt *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	virtual CompoundStmt * clone() const override { return new CompoundStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual CompoundStmt * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -72,25 +72,25 @@
 	NullStmt( const std::list<Label> & labels = {} );
 
-	virtual NullStmt *clone() const override { return new NullStmt( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual NullStmt *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	virtual NullStmt * clone() const override { return new NullStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual NullStmt * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
 class ExprStmt : public Statement {
   public:
-	Expression *expr;
-
-	ExprStmt( Expression *expr );
-	ExprStmt( const ExprStmt &other );
+	Expression * expr;
+
+	ExprStmt( Expression * expr );
+	ExprStmt( const ExprStmt & other );
 	virtual ~ExprStmt();
 
-	Expression *get_expr() { return expr; }
-	void set_expr( Expression *newValue ) { expr = newValue; }
-
-	virtual ExprStmt *clone() const override { return new ExprStmt( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	Expression * get_expr() { return expr; }
+	void set_expr( Expression * newValue ) { expr = newValue; }
+
+	virtual ExprStmt * clone() const override { return new ExprStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -98,11 +98,11 @@
   public:
 	bool voltile;
-	Expression *instruction;
+	Expression * instruction;
 	std::list<Expression *> output, input;
 	std::list<ConstantExpr *> clobber;
 	std::list<Label> gotolabels;
 
-	AsmStmt( bool voltile, Expression *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels );
-	AsmStmt( const AsmStmt &other );
+	AsmStmt( bool voltile, Expression * instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels );
+	AsmStmt( const AsmStmt & other );
 	virtual ~AsmStmt();
 
@@ -114,9 +114,9 @@
 	void set_output( const std::list<Expression *> & newValue ) { output = newValue; }
 	std::list<Expression *> & get_input() { return input; }
-	void set_input( const std::list<Expression *> &newValue ) { input = newValue; }
+	void set_input( const std::list<Expression *> & newValue ) { input = newValue; }
 	std::list<ConstantExpr *> & get_clobber() { return clobber; }
-	void set_clobber( const std::list<ConstantExpr *> &newValue ) { clobber = newValue; }
+	void set_clobber( const std::list<ConstantExpr *> & newValue ) { clobber = newValue; }
 	std::list<Label> & get_gotolabels() { return gotolabels; }
-	void set_gotolabels( const std::list<Label> &newValue ) { gotolabels = newValue; }
+	void set_gotolabels( const std::list<Label> & newValue ) { gotolabels = newValue; }
 
 	virtual AsmStmt * clone() const { return new AsmStmt( *this ); }
@@ -141,26 +141,26 @@
 class IfStmt : public Statement {
   public:
-	Expression *condition;
-	Statement *thenPart;
-	Statement *elsePart;
+	Expression * condition;
+	Statement * thenPart;
+	Statement * elsePart;
 	std::list<Statement *> initialization;
 
-	IfStmt( Expression *condition, Statement *thenPart, Statement *elsePart,
+	IfStmt( Expression * condition, Statement * thenPart, Statement * elsePart,
 			std::list<Statement *> initialization = std::list<Statement *>() );
-	IfStmt( const IfStmt &other );
+	IfStmt( const IfStmt & other );
 	virtual ~IfStmt();
 
-	std::list<Statement *> &get_initialization() { return initialization; }
-	Expression *get_condition() { return condition; }
-	void set_condition( Expression *newValue ) { condition = newValue; }
-	Statement *get_thenPart() { return thenPart; }
-	void set_thenPart( Statement *newValue ) { thenPart = newValue; }
-	Statement *get_elsePart() { return elsePart; }
-	void set_elsePart( Statement *newValue ) { elsePart = newValue; }
-
-	virtual IfStmt *clone() const override { return new IfStmt( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	std::list<Statement *> & get_initialization() { return initialization; }
+	Expression * get_condition() { return condition; }
+	void set_condition( Expression * newValue ) { condition = newValue; }
+	Statement * get_thenPart() { return thenPart; }
+	void set_thenPart( Statement * newValue ) { thenPart = newValue; }
+	Statement * get_elsePart() { return elsePart; }
+	void set_elsePart( Statement * newValue ) { elsePart = newValue; }
+
+	virtual IfStmt * clone() const override { return new IfStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -170,18 +170,18 @@
 	std::list<Statement *> statements;
 
-	SwitchStmt( Expression *condition, const std::list<Statement *> &statements );
-	SwitchStmt( const SwitchStmt &other );
+	SwitchStmt( Expression * condition, const std::list<Statement *> & statements );
+	SwitchStmt( const SwitchStmt & other );
 	virtual ~SwitchStmt();
 
-	Expression *get_condition() { return condition; }
-	void set_condition( Expression *newValue ) { condition = newValue; }
+	Expression * get_condition() { return condition; }
+	void set_condition( Expression * newValue ) { condition = newValue; }
 
 	std::list<Statement *> & get_statements() { return statements; }
 
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-
-	virtual SwitchStmt *clone() const override { return new SwitchStmt( *this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+
+	virtual SwitchStmt * clone() const override { return new SwitchStmt( *this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 
 };
@@ -192,6 +192,6 @@
 	std::list<Statement *> stmts;
 
-	CaseStmt( Expression *conditions, const std::list<Statement *> &stmts, bool isdef = false ) throw (SemanticErrorException);
-	CaseStmt( const CaseStmt &other );
+	CaseStmt( Expression * conditions, const std::list<Statement *> & stmts, bool isdef = false ) throw (SemanticErrorException);
+	CaseStmt( const CaseStmt & other );
 	virtual ~CaseStmt();
 
@@ -201,15 +201,15 @@
 	void set_default(bool b) { _isDefault = b; }
 
-	Expression * &get_condition() { return condition; }
-	void set_condition( Expression *newValue ) { condition = newValue; }
-
-	std::list<Statement *> &get_statements() { return stmts; }
-	void set_statements( std::list<Statement *> &newValue ) { stmts = newValue; }
-
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-
-	virtual CaseStmt *clone() const override { return new CaseStmt( *this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	Expression * & get_condition() { return condition; }
+	void set_condition( Expression * newValue ) { condition = newValue; }
+
+	std::list<Statement *> & get_statements() { return stmts; }
+	void set_statements( std::list<Statement *> & newValue ) { stmts = newValue; }
+
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+
+	virtual CaseStmt * clone() const override { return new CaseStmt( *this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
   private:
 	bool _isDefault;
@@ -218,25 +218,24 @@
 class WhileStmt : public Statement {
   public:
-	Expression *condition;
-	Statement *body;
+	Expression * condition;
+	Statement * body;
 	std::list<Statement *> initialization;
 	bool isDoWhile;
 
-	WhileStmt( Expression *condition,
-	       Statement *body, std::list<Statement *> & initialization, bool isDoWhile = false );
-	WhileStmt( const WhileStmt &other );
+	WhileStmt( Expression * condition, Statement * body, std::list<Statement *> & initialization, bool isDoWhile = false );
+	WhileStmt( const WhileStmt & other );
 	virtual ~WhileStmt();
 
-	Expression *get_condition() { return condition; }
-	void set_condition( Expression *newValue ) { condition = newValue; }
-	Statement *get_body() { return body; }
-	void set_body( Statement *newValue ) { body = newValue; }
+	Expression * get_condition() { return condition; }
+	void set_condition( Expression * newValue ) { condition = newValue; }
+	Statement * get_body() { return body; }
+	void set_body( Statement * newValue ) { body = newValue; }
 	bool get_isDoWhile() { return isDoWhile; }
 	void set_isDoWhile( bool newValue ) { isDoWhile = newValue; }
 
-	virtual WhileStmt *clone() const override { return new WhileStmt( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	virtual WhileStmt * clone() const override { return new WhileStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -244,25 +243,24 @@
   public:
 	std::list<Statement *> initialization;
-	Expression *condition;
-	Expression *increment;
-	Statement *body;
-
-	ForStmt( std::list<Statement *> initialization,
-	     Expression *condition = 0, Expression *increment = 0, Statement *body = 0 );
-	ForStmt( const ForStmt &other );
+	Expression * condition;
+	Expression * increment;
+	Statement * body;
+
+	ForStmt( std::list<Statement *> initialization, Expression * condition = 0, Expression * increment = 0, Statement * body = 0 );
+	ForStmt( const ForStmt & other );
 	virtual ~ForStmt();
 
-	std::list<Statement *> &get_initialization() { return initialization; }
-	Expression *get_condition() { return condition; }
-	void set_condition( Expression *newValue ) { condition = newValue; }
-	Expression *get_increment() { return increment; }
-	void set_increment( Expression *newValue ) { increment = newValue; }
-	Statement *get_body() { return body; }
-	void set_body( Statement *newValue ) { body = newValue; }
-
-	virtual ForStmt *clone() const override { return new ForStmt( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	std::list<Statement *> & get_initialization() { return initialization; }
+	Expression * get_condition() { return condition; }
+	void set_condition( Expression * newValue ) { condition = newValue; }
+	Expression * get_increment() { return increment; }
+	void set_increment( Expression * newValue ) { increment = newValue; }
+	Statement * get_body() { return body; }
+	void set_body( Statement * newValue ) { body = newValue; }
+
+	virtual ForStmt * clone() const override { return new ForStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -274,9 +272,9 @@
 	const Label originalTarget;
 	Label target;
-	Expression *computedTarget;
+	Expression * computedTarget;
 	Type type;
 
 	BranchStmt( Label target, Type ) throw (SemanticErrorException);
-	BranchStmt( Expression *computedTarget, Type ) throw (SemanticErrorException);
+	BranchStmt( Expression * computedTarget, Type ) throw (SemanticErrorException);
 
 	Label get_originalTarget() { return originalTarget; }
@@ -284,33 +282,33 @@
 	void set_target( Label newValue ) { target = newValue; }
 
-	Expression *get_computedTarget() { return computedTarget; }
+	Expression * get_computedTarget() { return computedTarget; }
 	void set_target( Expression * newValue ) { computedTarget = newValue; }
 
 	Type get_type() { return type; }
-	const char *get_typename() { return brType[ type ]; }
-
-	virtual BranchStmt *clone() const override { return new BranchStmt( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	const char * get_typename() { return brType[ type ]; }
+
+	virtual BranchStmt * clone() const override { return new BranchStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
   private:
-	static const char *brType[];
+	static const char * brType[];
 };
 
 class ReturnStmt : public Statement {
   public:
-	Expression *expr;
-
-	ReturnStmt( Expression *expr );
-	ReturnStmt( const ReturnStmt &other );
+	Expression * expr;
+
+	ReturnStmt( Expression * expr );
+	ReturnStmt( const ReturnStmt & other );
 	virtual ~ReturnStmt();
 
-	Expression *get_expr() { return expr; }
-	void set_expr( Expression *newValue ) { expr = newValue; }
-
-	virtual ReturnStmt *clone() const override { return new ReturnStmt( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	Expression * get_expr() { return expr; }
+	void set_expr( Expression * newValue ) { expr = newValue; }
+
+	virtual ReturnStmt * clone() const override { return new ReturnStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -324,5 +322,5 @@
 
 	ThrowStmt( Kind kind, Expression * expr, Expression * target = nullptr );
-	ThrowStmt( const ThrowStmt &other );
+	ThrowStmt( const ThrowStmt & other );
 	virtual ~ThrowStmt();
 
@@ -333,8 +331,8 @@
 	void set_target( Expression * newTarget ) { target = newTarget; }
 
-	virtual ThrowStmt *clone() const override { return new ThrowStmt( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	virtual ThrowStmt * clone() const override { return new ThrowStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -345,19 +343,19 @@
 	FinallyStmt * finallyBlock;
 
-	TryStmt( CompoundStmt *tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock = 0 );
-	TryStmt( const TryStmt &other );
+	TryStmt( CompoundStmt * tryBlock, std::list<CatchStmt *> & handlers, FinallyStmt * finallyBlock = 0 );
+	TryStmt( const TryStmt & other );
 	virtual ~TryStmt();
 
-	CompoundStmt *get_block() const { return block; }
-	void set_block( CompoundStmt *newValue ) { block = newValue; }
+	CompoundStmt * get_block() const { return block; }
+	void set_block( CompoundStmt * newValue ) { block = newValue; }
 	std::list<CatchStmt *>& get_catchers() { return handlers; }
 
-	FinallyStmt *get_finally() const { return finallyBlock; }
-	void set_finally( FinallyStmt *newValue ) { finallyBlock = newValue; }
-
-	virtual TryStmt *clone() const override { return new TryStmt( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	FinallyStmt * get_finally() const { return finallyBlock; }
+	void set_finally( FinallyStmt * newValue ) { finallyBlock = newValue; }
+
+	virtual TryStmt * clone() const override { return new TryStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -367,42 +365,42 @@
 
 	const Kind kind;
-	Declaration *decl;
-	Expression *cond;
-	Statement *body;
-
-	CatchStmt( Kind kind, Declaration *decl,
-	           Expression *cond, Statement *body );
-	CatchStmt( const CatchStmt &other );
+	Declaration * decl;
+	Expression * cond;
+	Statement * body;
+
+	CatchStmt( Kind kind, Declaration * decl,
+	           Expression * cond, Statement * body );
+	CatchStmt( const CatchStmt & other );
 	virtual ~CatchStmt();
 
 	Kind get_kind() { return kind; }
-	Declaration *get_decl() { return decl; }
-	void set_decl( Declaration *newValue ) { decl = newValue; }
-	Expression *get_cond() { return cond; }
-	void set_cond( Expression *newCond ) { cond = newCond; }
-	Statement *get_body() { return body; }
-	void set_body( Statement *newValue ) { body = newValue; }
-
-	virtual CatchStmt *clone() const override { return new CatchStmt( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	Declaration * get_decl() { return decl; }
+	void set_decl( Declaration * newValue ) { decl = newValue; }
+	Expression * get_cond() { return cond; }
+	void set_cond( Expression * newCond ) { cond = newCond; }
+	Statement * get_body() { return body; }
+	void set_body( Statement * newValue ) { body = newValue; }
+
+	virtual CatchStmt * clone() const override { return new CatchStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
 class FinallyStmt : public Statement {
   public:
-	CompoundStmt *block;
-
-	FinallyStmt( CompoundStmt *block );
-	FinallyStmt( const FinallyStmt &other );
+	CompoundStmt * block;
+
+	FinallyStmt( CompoundStmt * block );
+	FinallyStmt( const FinallyStmt & other );
 	virtual ~FinallyStmt();
 
-	CompoundStmt *get_block() const { return block; }
-	void set_block( CompoundStmt *newValue ) { block = newValue; }
-
-	virtual FinallyStmt *clone() const override { return new FinallyStmt( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	CompoundStmt * get_block() const { return block; }
+	void set_block( CompoundStmt * newValue ) { block = newValue; }
+
+	virtual FinallyStmt * clone() const override { return new FinallyStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
@@ -438,8 +436,8 @@
 	} orelse;
 
-	virtual WaitForStmt *clone() const override { return new WaitForStmt( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	virtual WaitForStmt * clone() const override { return new WaitForStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 
 };
@@ -464,23 +462,22 @@
 class DeclStmt : public Statement {
   public:
-	Declaration *decl;
-
-	DeclStmt( Declaration *decl );
-	DeclStmt( const DeclStmt &other );
+	Declaration * decl;
+
+	DeclStmt( Declaration * decl );
+	DeclStmt( const DeclStmt & other );
 	virtual ~DeclStmt();
 
-	Declaration *get_decl() const { return decl; }
-	void set_decl( Declaration *newValue ) { decl = newValue; }
-
-	virtual DeclStmt *clone() const override { return new DeclStmt( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
-};
-
-
-/// represents an implicit application of a constructor or destructor. Qualifiers are replaced
-/// immediately before and after the call so that qualified objects can be constructed
-/// with the same functions as unqualified objects.
+	Declaration * get_decl() const { return decl; }
+	void set_decl( Declaration * newValue ) { decl = newValue; }
+
+	virtual DeclStmt * clone() const override { return new DeclStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
+};
+
+
+/// represents an implicit application of a constructor or destructor. Qualifiers are replaced immediately before and
+/// after the call so that qualified objects can be constructed with the same functions as unqualified objects.
 class ImplicitCtorDtorStmt : public Statement {
   public:
@@ -492,11 +489,11 @@
 	virtual ~ImplicitCtorDtorStmt();
 
-	Statement *get_callStmt() const { return callStmt; }
+	Statement * get_callStmt() const { return callStmt; }
 	void set_callStmt( Statement * newValue ) { callStmt = newValue; }
 
-	virtual ImplicitCtorDtorStmt *clone() const override { return new ImplicitCtorDtorStmt( *this ); }
-	virtual void accept( Visitor &v ) override { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
-	virtual void print( std::ostream &os, Indenter indent = {} ) const override;
+	virtual ImplicitCtorDtorStmt * clone() const override { return new ImplicitCtorDtorStmt( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, Indenter indent = {} ) const override;
 };
 
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ src/main.cc	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -65,13 +65,21 @@
 using namespace std;
 
-
 void NewPass(const char * const name) {
 	Stats::Heap::newPass(name);
 	using namespace Stats::Counters;
-	static auto pass_visitor_group = build<CounterGroup>("Pass Visitor");
-	auto pass = build<CounterGroup>(name, pass_visitor_group);
-	pass_visitor_stats.depth = 0;
-	pass_visitor_stats.avg = build<AverageCounter<double>>("Average Depth", pass);
-	pass_visitor_stats.max = build<MaxCounter<double>>("Max Depth", pass);
+	
+	{
+		static auto group = build<CounterGroup>("Pass Visitor");
+		auto pass = build<CounterGroup>(name, group);
+		pass_visitor_stats.depth = 0;
+		pass_visitor_stats.avg = build<AverageCounter<double>>("Average Depth", pass);
+		pass_visitor_stats.max = build<MaxCounter<double>>("Max Depth", pass);
+	}
+
+	{
+		static auto group = build<CounterGroup>("Syntax Node");
+		auto pass = build<CounterGroup>(name, group);
+		BaseSyntaxNode::new_nodes = build<SimpleCounter>("Allocs", pass);
+	}
 }
 
Index: tests/.expect/KRfunctions.x64.txt
===================================================================
--- tests/.expect/KRfunctions.x64.txt	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/.expect/KRfunctions.x64.txt	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -82,7 +82,7 @@
     signed int _X1ai_2;
     signed int _X1bi_2;
-    signed int *(*_tmp_cp_ret2)(signed int _X1xi_1, signed int _X1yi_1);
-    ((void)(_X1xFPi_ii__2=(((void)(_tmp_cp_ret2=_X3f10FFPi_ii__iPiPid__1(3, (&_X1ai_2), (&_X1bi_2), 3.5))) , _tmp_cp_ret2)));
-    ((void)(_tmp_cp_ret2) /* ^?{} */);
+    signed int *(*_tmp_cp_ret4)(signed int _X1xi_1, signed int _X1yi_1);
+    ((void)(_X1xFPi_ii__2=(((void)(_tmp_cp_ret4=_X3f10FFPi_ii__iPiPid__1(3, (&_X1ai_2), (&_X1bi_2), 3.5))) , _tmp_cp_ret4)));
+    ((void)(_tmp_cp_ret4) /* ^?{} */);
     const signed int _X2f1Fi_iPiPi__2(signed int _X1ai_2, signed int *_X1bPi_2, signed int *_X1cPi_2){
         __attribute__ ((unused)) const signed int _X10_retval_f1Ki_2;
Index: tests/.expect/KRfunctions.x86.txt
===================================================================
--- tests/.expect/KRfunctions.x86.txt	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/.expect/KRfunctions.x86.txt	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -82,7 +82,7 @@
     signed int _X1ai_2;
     signed int _X1bi_2;
-    signed int *(*_tmp_cp_ret2)(signed int _X1xi_1, signed int _X1yi_1);
-    ((void)(_X1xFPi_ii__2=(((void)(_tmp_cp_ret2=_X3f10FFPi_ii__iPiPid__1(3, (&_X1ai_2), (&_X1bi_2), 3.5))) , _tmp_cp_ret2)));
-    ((void)(_tmp_cp_ret2) /* ^?{} */);
+    signed int *(*_tmp_cp_ret4)(signed int _X1xi_1, signed int _X1yi_1);
+    ((void)(_X1xFPi_ii__2=(((void)(_tmp_cp_ret4=_X3f10FFPi_ii__iPiPid__1(3, (&_X1ai_2), (&_X1bi_2), 3.5))) , _tmp_cp_ret4)));
+    ((void)(_tmp_cp_ret4) /* ^?{} */);
     const signed int _X2f1Fi_iPiPi__2(signed int _X1ai_2, signed int *_X1bPi_2, signed int *_X1cPi_2){
         __attribute__ ((unused)) const signed int _X10_retval_f1Ki_2;
Index: tests/.expect/completeTypeError.txt
===================================================================
--- tests/.expect/completeTypeError.txt	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/.expect/completeTypeError.txt	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -1,11 +1,56 @@
-completeTypeError.cfa:33:1 error: No reasonable alternatives for expression Applying untyped:
-  Name: *?
-...to:
-  Name: v
+completeTypeError.cfa:34:1 error: Cannot choose between 2 alternatives for expression
+Generated Cast of:
+  Applying untyped:
+    Name: *?
+  ...to:
+    Name: x
 
-completeTypeError.cfa:34:1 error: No reasonable alternatives for expression Applying untyped:
-  Name: *?
-...to:
-  Name: y
+... to: nothing Alternatives are:
+Cost ( 0, 1, 2, 0, 1, -1, 0 ): Generated Cast of:
+     Application of
+       Variable Expression: *?: forall
+         DT: object type
+         function
+       ... with parameters
+         intrinsic pointer to instance of type DT (not function type)
+       ... returning
+         _retval__operator_deref: reference to instance of type DT (not function type)
+         ... with attributes:
+           Attribute with name: unused
+
+
+     ... to arguments
+       Variable Expression: x: pointer to instance of struct A with body 0
+
+   ... to: nothing
+ (types:
+   void 
+ )
+ Environment:( _80_4_DT ) -> instance of struct A with body 0 (no widening)
+
+
+Cost ( 0, 1, 2, 0, 1, -1, 0 ): Generated Cast of:
+     Application of
+       Variable Expression: *?: forall
+         DT: object type
+         function
+       ... with parameters
+         intrinsic pointer to instance of type DT (not function type)
+       ... returning
+         _retval__operator_deref: reference to instance of type DT (not function type)
+         ... with attributes:
+           Attribute with name: unused
+
+
+     ... to arguments
+       Variable Expression: x: pointer to instance of struct B with body 1
+
+   ... to: nothing
+ (types:
+   void 
+ )
+ Environment:( _80_4_DT ) -> instance of struct B with body 1 (no widening)
+
+
 
 completeTypeError.cfa:35:1 error: No reasonable alternatives for expression Applying untyped:
@@ -24,69 +69,73 @@
   Name: v
 
-completeTypeError.cfa:58:1 error: No reasonable alternatives for expression Applying untyped:
+completeTypeError.cfa:59:1 error: No reasonable alternatives for expression Applying untyped:
   Name: baz
 ...to:
   Name: y
 
-completeTypeError.cfa:59:1 error: No reasonable alternatives for expression Applying untyped:
+completeTypeError.cfa:60:1 error: No reasonable alternatives for expression Applying untyped:
   Name: quux
 ...to:
   Name: y
 
-completeTypeError.cfa:60:1 error: No reasonable alternatives for expression Applying untyped:
-  Name: *?
-...to:
-  Name: y
-
-completeTypeError.cfa:72:1 error: No resolvable alternatives for expression Applying untyped:
+completeTypeError.cfa:72:1 error: No alternatives with satisfiable assertions for Applying untyped:
   Name: baz
 ...to:
   Name: z
 
-Alternatives with failing assertions are:
+   Unsatisfiable alternative:
 Cost ( 0, 1, 0, 0, 1, -5, 0 ): Application of
-     Variable Expression: baz: forall
-       T: sized object type
-       ... with assertions
-         ?=?: pointer to function
-         ... with parameters
-           reference to instance of type T (not function type)
-           instance of type T (not function type)
-         ... returning
-           _retval__operator_assign: instance of type T (not function type)
-           ... with attributes:
-             Attribute with name: unused
+         Variable Expression: baz: forall
+           T: sized object type
+           ... with assertions
+             ?=?: pointer to function
+             ... with parameters
+               reference to instance of type T (not function type)
+               instance of type T (not function type)
+             ... returning
+               _retval__operator_assign: instance of type T (not function type)
+               ... with attributes:
+                 Attribute with name: unused
 
 
-         ?{}: pointer to function
+             ?{}: pointer to function
+             ... with parameters
+               reference to instance of type T (not function type)
+             ... returning nothing
+
+             ?{}: pointer to function
+             ... with parameters
+               reference to instance of type T (not function type)
+               instance of type T (not function type)
+             ... returning nothing
+
+             ^?{}: pointer to function
+             ... with parameters
+               reference to instance of type T (not function type)
+             ... returning nothing
+
+
+           function
          ... with parameters
-           reference to instance of type T (not function type)
+           pointer to instance of type T (not function type)
          ... returning nothing
 
-         ?{}: pointer to function
-         ... with parameters
-           reference to instance of type T (not function type)
-           instance of type T (not function type)
-         ... returning nothing
+       ... to arguments
+         Variable Expression: z: pointer to instance of type T (not function type)
 
-         ^?{}: pointer to function
-         ... with parameters
-           reference to instance of type T (not function type)
-         ... returning nothing
+     (types:
+       void 
+     )
+     Environment:( _99_0_T ) -> instance of type T (not function type) (no widening)
+
+   Could not satisfy assertion:
+?=?: pointer to function
+     ... with parameters
+       reference to instance of type _99_0_T (not function type)
+       instance of type _99_0_T (not function type)
+     ... returning
+       _retval__operator_assign: instance of type _99_0_T (not function type)
+       ... with attributes:
+         Attribute with name: unused
 
 
-       function
-     ... with parameters
-       pointer to instance of type T (not function type)
-     ... returning nothing
-
-   ... to arguments
-     Variable Expression: z: pointer to instance of type T (not function type)
-
- (types:
-   void 
- )
- Environment:( _74_0_T ) -> instance of type T (not function type) (no widening)
-
-
-
Index: tests/.expect/declarationSpecifier.x64.txt
===================================================================
--- tests/.expect/declarationSpecifier.x64.txt	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/.expect/declarationSpecifier.x64.txt	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -698,7 +698,7 @@
 signed int main(signed int _X4argci_1, char **_X4argvPPc_1, char **_X4envpPPc_1){
     __attribute__ ((unused)) signed int _X12_retval_maini_1;
-    signed int _tmp_cp_ret2;
-    ((void)(_X12_retval_maini_1=(((void)(_tmp_cp_ret2=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret2)) /* ?{} */);
-    ((void)(_tmp_cp_ret2) /* ^?{} */);
+    signed int _tmp_cp_ret4;
+    ((void)(_X12_retval_maini_1=(((void)(_tmp_cp_ret4=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret4)) /* ?{} */);
+    ((void)(_tmp_cp_ret4) /* ^?{} */);
     return _X12_retval_maini_1;
 }
Index: tests/.expect/declarationSpecifier.x86.txt
===================================================================
--- tests/.expect/declarationSpecifier.x86.txt	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/.expect/declarationSpecifier.x86.txt	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -698,7 +698,7 @@
 signed int main(signed int _X4argci_1, char **_X4argvPPc_1, char **_X4envpPPc_1){
     __attribute__ ((unused)) signed int _X12_retval_maini_1;
-    signed int _tmp_cp_ret2;
-    ((void)(_X12_retval_maini_1=(((void)(_tmp_cp_ret2=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret2)) /* ?{} */);
-    ((void)(_tmp_cp_ret2) /* ^?{} */);
+    signed int _tmp_cp_ret4;
+    ((void)(_X12_retval_maini_1=(((void)(_tmp_cp_ret4=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret4)) /* ?{} */);
+    ((void)(_tmp_cp_ret4) /* ^?{} */);
     return _X12_retval_maini_1;
 }
Index: tests/.expect/extension.x64.txt
===================================================================
--- tests/.expect/extension.x64.txt	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/.expect/extension.x64.txt	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -186,7 +186,7 @@
     __extension__ signed int _X1ci_2;
     ((void)(__extension__ _X1ai_2=(__extension__ _X1bi_2+__extension__ _X1ci_2)));
-    signed int _tmp_cp_ret2;
-    ((void)(((void)(_tmp_cp_ret2=__extension__ _X4fredFi_i__1(3))) , _tmp_cp_ret2));
-    ((void)(_tmp_cp_ret2) /* ^?{} */);
+    signed int _tmp_cp_ret4;
+    ((void)(((void)(_tmp_cp_ret4=__extension__ _X4fredFi_i__1(3))) , _tmp_cp_ret4));
+    ((void)(_tmp_cp_ret4) /* ^?{} */);
     __extension__ signed int _X4maryFi_i__2(signed int _X1pi_2){
         __attribute__ ((unused)) signed int _X12_retval_maryi_2;
Index: tests/.expect/extension.x86.txt
===================================================================
--- tests/.expect/extension.x86.txt	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/.expect/extension.x86.txt	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -186,7 +186,7 @@
     __extension__ signed int _X1ci_2;
     ((void)(__extension__ _X1ai_2=(__extension__ _X1bi_2+__extension__ _X1ci_2)));
-    signed int _tmp_cp_ret2;
-    ((void)(((void)(_tmp_cp_ret2=__extension__ _X4fredFi_i__1(3))) , _tmp_cp_ret2));
-    ((void)(_tmp_cp_ret2) /* ^?{} */);
+    signed int _tmp_cp_ret4;
+    ((void)(((void)(_tmp_cp_ret4=__extension__ _X4fredFi_i__1(3))) , _tmp_cp_ret4));
+    ((void)(_tmp_cp_ret4) /* ^?{} */);
     __extension__ signed int _X4maryFi_i__2(signed int _X1pi_2){
         __attribute__ ((unused)) signed int _X12_retval_maryi_2;
Index: tests/.expect/gccExtensions.x64.txt
===================================================================
--- tests/.expect/gccExtensions.x64.txt	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/.expect/gccExtensions.x64.txt	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -171,7 +171,7 @@
 signed int main(signed int _X4argci_1, char **_X4argvPPc_1, char **_X4envpPPc_1){
     __attribute__ ((unused)) signed int _X12_retval_maini_1;
-    signed int _tmp_cp_ret2;
-    ((void)(_X12_retval_maini_1=(((void)(_tmp_cp_ret2=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret2)) /* ?{} */);
-    ((void)(_tmp_cp_ret2) /* ^?{} */);
+    signed int _tmp_cp_ret4;
+    ((void)(_X12_retval_maini_1=(((void)(_tmp_cp_ret4=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret4)) /* ?{} */);
+    ((void)(_tmp_cp_ret4) /* ^?{} */);
     return _X12_retval_maini_1;
 }
Index: tests/.expect/gccExtensions.x86.txt
===================================================================
--- tests/.expect/gccExtensions.x86.txt	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/.expect/gccExtensions.x86.txt	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -171,7 +171,7 @@
 signed int main(signed int _X4argci_1, char **_X4argvPPc_1, char **_X4envpPPc_1){
     __attribute__ ((unused)) signed int _X12_retval_maini_1;
-    signed int _tmp_cp_ret2;
-    ((void)(_X12_retval_maini_1=(((void)(_tmp_cp_ret2=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret2)) /* ?{} */);
-    ((void)(_tmp_cp_ret2) /* ^?{} */);
+    signed int _tmp_cp_ret4;
+    ((void)(_X12_retval_maini_1=(((void)(_tmp_cp_ret4=invoke_main(_X4argci_1, _X4argvPPc_1, _X4envpPPc_1))) , _tmp_cp_ret4)) /* ?{} */);
+    ((void)(_tmp_cp_ret4) /* ^?{} */);
     return _X12_retval_maini_1;
 }
Index: tests/.expect/loopctrl.txt
===================================================================
--- tests/.expect/loopctrl.txt	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/.expect/loopctrl.txt	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -19,4 +19,6 @@
 10 8 6 4 2
 
+1 2 3 4 5 6 7 8 9 10
+10 9 8 7 6 5 4 3 2 1 0
 2 4 6 8 10
 2.1 3.8 5.5 7.2 8.9
@@ -42,2 +44,16 @@
 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)
 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)
+
+0 -5 1 -4 2 -3 3 -2 4 -1 5 0 6 1 7 2 8 3 9 4
+0 -5 1 -6 2 -7 3 -8 4 -9 5 -10 6 -11 7 -12 8 -13 9 -14
+0 -5 1 -3 2 -1 3 1 4 3 5 5 6 7 7 9 8 11 9 13
+0 -5 1 -7 2 -9 3 -11 4 -13 5 -15 6 -17 7 -19 8 -21 9 -23
+
+0 -5 1 -4 2 -3 3 -2 4 -1 5 0 6 1 7 2 8 3 9 4
+0 -5 1 -6 2 -7 3 -8 4 -9 5 -10 6 -11 7 -12 8 -13 9 -14
+0 -5 1 -3 2 -1 3 1 4 3 5 5 6 7 7 9 8 11 9 13
+0 -5 1 -7 2 -9 3 -11 4 -13 5 -15 6 -17 7 -19 8 -21 9 -23
+
+0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 5 -15 6.5 6 -17 7.5 7 -19 8.5 8 -21 9.5 9 -23 10.5
+0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 5 -15 6.5 6 -17 7.5 7 -19 8.5 8 -21 9.5 9 -23 10.5
+0 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 5 -15 6.5 6 -17 7.5 7 -19 8.5 8 -21 9.5 9 -23 10.5
Index: tests/.expect/math1.txt
===================================================================
--- tests/.expect/math1.txt	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/.expect/math1.txt	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,4 +10,8 @@
 expm1:1.71828 1.71828182845905 1.71828182845904524
 pow:1 1 1 0.273957+0.583701i 0.273957253830121+0.583700758758615i -0.638110484918098871+0.705394566961838155i
-\ 16 256
-\ 912673 256 64 -64 0.015625 -0.015625 18.3791736799526 0.264715-1.1922i
+16 \ 2 = 256
+912673 256 64 -64 0 0
+0.015625 -0.015625 18.3791736799526 0.264715-1.1922i
+0 0 18.3791736799526 0.264715-1.1922i
+16
+4 16
Index: tests/Makefile.am
===================================================================
--- tests/Makefile.am	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/Makefile.am	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -28,5 +28,5 @@
 timeouts=
 
-TEST_PY = python ${builddir}/test.py
+TEST_PY = python3 ${builddir}/test.py
 
 # applies to both programs
@@ -36,10 +36,10 @@
 	-Wno-unused-function \
 	-quiet @CFA_FLAGS@ \
-	-DIN_DIR="${srcdir}/.in/"
+	-DIN_DIR="${abs_srcdir}/.in/"
 
 AM_CFLAGS += ${DEBUG_FLAGS} ${INSTALL_FLAGS} ${ARCH_FLAGS}
 CC = @CFACC@
 
-PRETTY_PATH=cd ${srcdir} &&
+PRETTY_PATH=mkdir -p $(dir $(abspath ${@})) && cd ${srcdir} &&
 
 .PHONY: list .validate
@@ -48,6 +48,6 @@
 
 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
-# automake doesn't know we still need C rules so pretend like we have a C program
-_dummy_hack_SOURCES = .dummy_hack.c
+# automake doesn't know we still need C/CPP rules so pretend like we have a C program
+_dummy_hack_SOURCES = .dummy_hack.c .dummy_hackxx.cpp
 
 #----------------------------------------------------------------------------------------------------------------
@@ -74,4 +74,7 @@
 	@echo "int main() { return 0; }" > ${@}
 
+.dummy_hackxx.cpp:
+	@echo "int bar() { return 0; }" > ${@}
+
 concurrency :
 	@+${TEST_PY} --debug=${debug}  --install=${installed} -Iconcurrent
@@ -79,71 +82,70 @@
 #----------------------------------------------------------------------------------------------------------------
 
+# Use for all tests, make sure the path are correct and all flags are added
+CFACOMPILETEST=$(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) $($(shell echo "${@}_FLAGS" | sed 's/-\|\//_/g'))
+
+# Use for tests that either generate an executable, print directyl to stdout or the make command is expected to fail
+CFATEST_STDOUT=$(CFACOMPILETEST) -o $(abspath ${@})
+
+# Use for tests where the make command is expecte to succeed but the expected.txt should be compared to stderr
+CFATEST_STDERR=$(CFACOMPILETEST) 2> $(abspath ${@})
+
+#----------------------------------------------------------------------------------------------------------------
+
 # implicit rule so not all test require a rule
 % : %.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
+	$(CFATEST_STDOUT)
 
-declarationSpecifier: declarationSpecifier.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
+% : %.cpp
+	$(PRETTY_PATH) $(CXXCOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
 
-gccExtensions : gccExtensions.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
+#------------------------------------------------------------------------------
+# TARGET WITH STANDARD RULE BUT CUSTOM FLAGS
+#------------------------------------------------------------------------------
+# Expected failures
+declarationSpecifier_FLAGS= -CFA -XCFA -p
+gccExtensions_FLAGS= -CFA -XCFA -p
+extension_FLAGS= -CFA -XCFA -p
+attributes_FLAGS= -CFA -XCFA -p
+functions_FLAGS= -CFA -XCFA -p
+KRfunctions_FLAGS= -CFA -XCFA -p
+gmp_FLAGS= -lgmp
 
-extension : extension.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
+#------------------------------------------------------------------------------
+# Expected failures
+completeTypeError_FLAGS= -DERR1
 
-attributes : attributes.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
+#------------------------------------------------------------------------------
+# CUSTOM TARGET
+#------------------------------------------------------------------------------
+typedefRedef-ERR1: typedefRedef.cfa $(CFACC)
+	$(CFATEST_STDOUT) -DERR1
 
-functions: functions.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
+alloc-ERROR: alloc.cfa $(CFACC)
+	$(CFATEST_STDOUT) -DERR1
 
-KRfunctions : KRfunctions.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
+nested-types-ERR1: nested-types.cfa $(CFACC)
+	$(CFATEST_STDOUT) -DERR1
 
-sched-ext-parse : sched-ext-parse.c $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
+nested-types-ERR2: nested-types.cfa $(CFACC)
+	$(CFATEST_STDOUT) -DERR2
 
-gmp : gmp.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -lgmp $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
+raii/dtor-early-exit-ERR1: raii/dtor-early-exit.cfa $(CFACC)
+	$(CFATEST_STDOUT) -DERR1
+
+raii/dtor-early-exit-ERR2: raii/dtor-early-exit.cfa $(CFACC)
+	$(CFATEST_STDOUT) -DERR2
+
+raii/memberCtors-ERR1: raii/memberCtors.cfa $(CFACC)
+	$(CFATEST_STDOUT) -DERR1
+
+raii/ctor-autogen-ERR1: raii/ctor-autogen.cfa $(CFACC)
+	$(CFATEST_STDOUT) -DERR1
 
 #builtins
 builtins/sync: builtins/sync.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) 2> $(abspath ${@}) -fsyntax-only
-
-#------------------------------------------------------------------------------
-
-#To make errors path independent we need to cd into the correct directories
-completeTypeError : completeTypeError.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-typedefRedef-ERR1: typedefRedef.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-alloc-ERROR: alloc.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-fallthrough-ERROR: fallthrough.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-nested-types-ERR1: nested-types.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-nested-types-ERR2: nested-types.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR2 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-# Constructor/destructor tests
-raii/dtor-early-exit-ERR1: raii/dtor-early-exit.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-raii/dtor-early-exit-ERR2: raii/dtor-early-exit.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR2 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-raii/memberCtors-ERR1: raii/memberCtors.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-raii/ctor-autogen-ERR1: raii/ctor-autogen.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
+	$(CFATEST_STDERR) -fsyntax-only
 
 # Warnings
 warnings/self-assignment: warnings/self-assignment.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) 2> $(abspath ${@}) -fsyntax-only
+	$(CFATEST_STDERR) -fsyntax-only
Index: tests/Makefile.in
===================================================================
--- tests/Makefile.in	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/Makefile.in	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -107,5 +107,5 @@
 CONFIG_CLEAN_FILES = config.py
 CONFIG_CLEAN_VPATH_FILES = test.py
-am__dummy_hack_OBJECTS = .dummy_hack.$(OBJEXT)
+am__dummy_hack_OBJECTS = .dummy_hack.$(OBJEXT) .dummy_hackxx.$(OBJEXT)
 _dummy_hack_OBJECTS = $(am__dummy_hack_OBJECTS)
 _dummy_hack_LDADD = $(LDADD)
@@ -155,4 +155,22 @@
 am__v_CCLD_0 = @echo "  CCLD    " $@;
 am__v_CCLD_1 = 
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
 SOURCES = $(_dummy_hack_SOURCES) $(avl_test_SOURCES)
 DIST_SOURCES = $(_dummy_hack_SOURCES) $(avl_test_SOURCES)
@@ -360,18 +378,45 @@
 concurrent = 
 timeouts = 
-TEST_PY = python ${builddir}/test.py
+TEST_PY = python3 ${builddir}/test.py
 
 # applies to both programs
 AM_CFLAGS = $(if $(test), 2> $(test), ) -g -Wall -Wno-unused-function \
-	-quiet @CFA_FLAGS@ -DIN_DIR="${srcdir}/.in/" ${DEBUG_FLAGS} \
-	${INSTALL_FLAGS} ${ARCH_FLAGS}
-PRETTY_PATH = cd ${srcdir} &&
+	-quiet @CFA_FLAGS@ -DIN_DIR="${abs_srcdir}/.in/" \
+	${DEBUG_FLAGS} ${INSTALL_FLAGS} ${ARCH_FLAGS}
+PRETTY_PATH = mkdir -p $(dir $(abspath ${@})) && cd ${srcdir} &&
 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
-# automake doesn't know we still need C rules so pretend like we have a C program
-_dummy_hack_SOURCES = .dummy_hack.c
+# automake doesn't know we still need C/CPP rules so pretend like we have a C program
+_dummy_hack_SOURCES = .dummy_hack.c .dummy_hackxx.cpp
+
+#----------------------------------------------------------------------------------------------------------------
+
+# Use for all tests, make sure the path are correct and all flags are added
+CFACOMPILETEST = $(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) $($(shell echo "${@}_FLAGS" | sed 's/-\|\//_/g'))
+
+# Use for tests that either generate an executable, print directyl to stdout or the make command is expected to fail
+CFATEST_STDOUT = $(CFACOMPILETEST) -o $(abspath ${@})
+
+# Use for tests where the make command is expecte to succeed but the expected.txt should be compared to stderr
+CFATEST_STDERR = $(CFACOMPILETEST) 2> $(abspath ${@})
+
+#------------------------------------------------------------------------------
+# TARGET WITH STANDARD RULE BUT CUSTOM FLAGS
+#------------------------------------------------------------------------------
+# Expected failures
+declarationSpecifier_FLAGS = -CFA -XCFA -p
+gccExtensions_FLAGS = -CFA -XCFA -p
+extension_FLAGS = -CFA -XCFA -p
+attributes_FLAGS = -CFA -XCFA -p
+functions_FLAGS = -CFA -XCFA -p
+KRfunctions_FLAGS = -CFA -XCFA -p
+gmp_FLAGS = -lgmp
+
+#------------------------------------------------------------------------------
+# Expected failures
+completeTypeError_FLAGS = -DERR1
 all: all-am
 
 .SUFFIXES:
-.SUFFIXES: .c .cfa .dummy_hack .lo .o .obj .validate
+.SUFFIXES: .c .cfa .cpp .dummy_hack .dummy_hackxx .lo .o .obj .validate
 $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am $(top_srcdir)/src/cfa.make $(am__configure_deps)
 	@for dep in $?; do \
@@ -409,5 +454,5 @@
 .dummy_hack$(EXEEXT): $(_dummy_hack_OBJECTS) $(_dummy_hack_DEPENDENCIES) $(EXTRA__dummy_hack_DEPENDENCIES) 
 	@rm -f .dummy_hack$(EXEEXT)
-	$(AM_V_CCLD)$(LINK) $(_dummy_hack_OBJECTS) $(_dummy_hack_LDADD) $(LIBS)
+	$(AM_V_CXXLD)$(CXXLINK) $(_dummy_hack_OBJECTS) $(_dummy_hack_LDADD) $(LIBS)
 avltree/$(am__dirstamp):
 	@$(MKDIR_P) avltree
@@ -443,4 +488,5 @@
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/.dummy_hack.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/.dummy_hackxx.Po@am__quote@
 
 .c.o:
@@ -467,4 +513,28 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+.cpp.o:
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cpp.obj:
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cpp.lo:
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCXX_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
 
 mostlyclean-libtool:
@@ -717,4 +787,7 @@
 	@echo "int main() { return 0; }" > ${@}
 
+.dummy_hackxx.cpp:
+	@echo "int bar() { return 0; }" > ${@}
+
 concurrency :
 	@+${TEST_PY} --debug=${debug}  --install=${installed} -Iconcurrent
@@ -724,71 +797,43 @@
 # implicit rule so not all test require a rule
 % : %.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-declarationSpecifier: declarationSpecifier.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-gccExtensions : gccExtensions.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-extension : extension.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-attributes : attributes.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-functions: functions.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-KRfunctions : KRfunctions.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-sched-ext-parse : sched-ext-parse.c $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -CFA -XCFA -p $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-gmp : gmp.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -lgmp $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
+	$(CFATEST_STDOUT)
+
+% : %.cpp
+	$(PRETTY_PATH) $(CXXCOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
+
+#------------------------------------------------------------------------------
+# CUSTOM TARGET
+#------------------------------------------------------------------------------
+typedefRedef-ERR1: typedefRedef.cfa $(CFACC)
+	$(CFATEST_STDOUT) -DERR1
+
+alloc-ERROR: alloc.cfa $(CFACC)
+	$(CFATEST_STDOUT) -DERR1
+
+nested-types-ERR1: nested-types.cfa $(CFACC)
+	$(CFATEST_STDOUT) -DERR1
+
+nested-types-ERR2: nested-types.cfa $(CFACC)
+	$(CFATEST_STDOUT) -DERR2
+
+raii/dtor-early-exit-ERR1: raii/dtor-early-exit.cfa $(CFACC)
+	$(CFATEST_STDOUT) -DERR1
+
+raii/dtor-early-exit-ERR2: raii/dtor-early-exit.cfa $(CFACC)
+	$(CFATEST_STDOUT) -DERR2
+
+raii/memberCtors-ERR1: raii/memberCtors.cfa $(CFACC)
+	$(CFATEST_STDOUT) -DERR1
+
+raii/ctor-autogen-ERR1: raii/ctor-autogen.cfa $(CFACC)
+	$(CFATEST_STDOUT) -DERR1
 
 #builtins
 builtins/sync: builtins/sync.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) 2> $(abspath ${@}) -fsyntax-only
-
-#------------------------------------------------------------------------------
-
-#To make errors path independent we need to cd into the correct directories
-completeTypeError : completeTypeError.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-typedefRedef-ERR1: typedefRedef.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-alloc-ERROR: alloc.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-fallthrough-ERROR: fallthrough.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-nested-types-ERR1: nested-types.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-nested-types-ERR2: nested-types.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR2 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-# Constructor/destructor tests
-raii/dtor-early-exit-ERR1: raii/dtor-early-exit.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-raii/dtor-early-exit-ERR2: raii/dtor-early-exit.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR2 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-raii/memberCtors-ERR1: raii/memberCtors.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
-
-raii/ctor-autogen-ERR1: raii/ctor-autogen.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) -DERR1 $(shell realpath --relative-to=${srcdir} ${<}) -o $(abspath ${@})
+	$(CFATEST_STDERR) -fsyntax-only
 
 # Warnings
 warnings/self-assignment: warnings/self-assignment.cfa $(CFACC)
-	$(PRETTY_PATH) $(CFACOMPILE) $(shell realpath --relative-to=${srcdir} ${<}) 2> $(abspath ${@}) -fsyntax-only
+	$(CFATEST_STDERR) -fsyntax-only
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
Index: tests/completeTypeError.cfa
===================================================================
--- tests/completeTypeError.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/completeTypeError.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -5,10 +5,10 @@
 forall(dtype T | sized(T)) void quux(T *);
 
-struct A; // incomplete
-struct B {}; // complete
+struct A;	// incomplete
+struct B {};	// complete
 
 int main() {
-	int *i;
-	void *v;
+	int * i;
+	void * v;
 
 	A * x;
@@ -19,5 +19,5 @@
 	// okay
 	*i;
-	*x; // picks B
+	*y;
 	*z;
 	foo(i);
@@ -32,5 +32,5 @@
 	// bad
 	*v;
-	*y;
+	*x;	// ambiguous
 	foo(v);
 	baz(v);
@@ -52,4 +52,5 @@
 void qux(T * y) {
 	// okay
+	*y;
 	bar(y);
 	qux(y);
@@ -58,5 +59,4 @@
 	baz(y);
 	quux(y);
-	*y;
 }
 
Index: tests/concurrent/examples/boundedBufferEXT.cfa
===================================================================
--- tests/concurrent/examples/boundedBufferEXT.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/concurrent/examples/boundedBufferEXT.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Wed Apr 18 22:52:12 2018
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Feb 20 08:36:45 2019
-// Update Count     : 11
+// Last Modified On : Fri Mar 22 13:41:33 2019
+// Update Count     : 12
 //
 
@@ -122,4 +122,4 @@
 // Local Variables: //
 // tab-width: 4 //
-// compile-command: "cfa boundedBufferEXT.c" //
+// compile-command: "cfa boundedBufferEXT.cfa" //
 // End: //
Index: tests/concurrent/examples/boundedBufferINT.cfa
===================================================================
--- tests/concurrent/examples/boundedBufferINT.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/concurrent/examples/boundedBufferINT.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Mon Oct 30 12:45:13 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Feb 20 08:37:24 2019
-// Update Count     : 87
+// Last Modified On : Fri Mar 22 13:41:52 2019
+// Update Count     : 88
 //
 
@@ -123,4 +123,4 @@
 // Local Variables: //
 // tab-width: 4 //
-// compile-command: "cfa boundedBufferINT.c" //
+// compile-command: "cfa boundedBufferINT.cfa" //
 // End: //
Index: tests/concurrent/examples/datingService.cfa
===================================================================
--- tests/concurrent/examples/datingService.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/concurrent/examples/datingService.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Mon Oct 30 12:56:20 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Feb 20 08:37:12 2019
-// Update Count     : 30
+// Last Modified On : Fri Mar 22 13:41:39 2019
+// Update Count     : 31
 //
 
@@ -112,4 +112,4 @@
 // Local Variables: //
 // tab-width: 4 //
-// compile-command: "cfa datingService.c" //
+// compile-command: "cfa datingService.cfa" //
 // End: //
Index: tests/concurrent/examples/quickSort.cfa
===================================================================
--- tests/concurrent/examples/quickSort.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/concurrent/examples/quickSort.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -11,6 +11,6 @@
 // Created On       : Wed Dec  6 12:15:52 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Feb 20 08:38:24 2019
-// Update Count     : 169
+// Last Modified On : Fri Mar 22 13:42:01 2019
+// Update Count     : 170
 //
 
@@ -180,4 +180,4 @@
 // Local Variables: //
 // tab-width: 4 //
-// compile-command: "cfa quickSort.c" //
+// compile-command: "cfa quickSort.cfa" //
 // End: //
Index: tests/concurrent/examples/quickSort.generic.cfa
===================================================================
--- tests/concurrent/examples/quickSort.generic.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ tests/concurrent/examples/quickSort.generic.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,186 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// quickSort.c -- In-place concurrent quick-sort: threads are created to partition to a specific depth, then sequential
+//		recursive-calls are use to sort each partition.
+//
+// Author           : Peter A. Buhr
+// Created On       : Wed Dec  6 12:15:52 2017
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Fri Mar 15 14:52:41 2019
+// Update Count     : 147
+//
+
+#include <fstream.hfa>
+#include <stdlib.hfa>
+#include <kernel.hfa>
+#include <thread.hfa>
+#include <string.h>										// strcmp
+
+forall( otype T | { int ?<?( T, T ); } ) {
+	thread Quicksort {
+		T * values;										// communication variables
+		int low, high, depth;
+	};
+
+	void ?{}( Quicksort(T) & qs, T values[], int size, int depth ) {
+		qs.values = values;  qs.low = 0;  qs.high = size;  qs.depth = depth;
+	} // Quicksort
+
+	void main( Quicksort(T) & qs ) {					// thread starts here
+		// nested routines: information hiding
+
+		void ?{}( Quicksort(T) & qs, T values[], int low, int high, int depth ) {
+			qs.values = values;  qs.low = low;  qs.high = high;  qs.depth = depth;
+		} // Quicksort
+
+		void sort( T values[], int low, int high, int depth ) {
+			int left, right;							// index to left/right-hand side of the values
+			T pivot;									// pivot value of values
+			T swap;										// temporary
+
+			//verify();									// check for stack overflow due to recursion
+
+			// partition while 2 or more elements in the array
+			if ( low < high ) {
+				pivot = values[low + ( high - low ) / 2];
+				left  = low;
+				right = high;
+
+				// partition: move values less < pivot before the pivot and values > pivot after the pivot
+				do {
+					while ( values[left] < pivot ) left += 1; // changed values[left] < pivot
+					while ( pivot < values[right] ) right -= 1;
+					if ( left <= right ) {
+						swap = values[left];			// interchange values
+						values[left]  = values[right];
+						values[right] = swap;
+						left += 1;
+						right -= 1;
+					} // if
+				} while ( left <= right );
+
+				// restrict number of tasks to slightly greater than number of processors
+				if ( depth > 0 ) {
+					depth -= 1;
+					Quicksort(T) rqs = { values, low, right, depth }; // concurrently sort upper half
+					//Quicksort lqs( values, left, high, depth ); // concurrently sort lower half
+					sort( values, left, high, depth );	// concurrently sort lower half
+				} else {
+					sort( values, low, right, 0 );		// sequentially sort lower half
+					sort( values, left, high, 0 );		// sequentially sort upper half
+				} // if
+			} // if
+		} // sort
+
+		with( qs ) {
+			sort( values, low, high, depth );
+		} // with
+	} // main
+}
+
+bool convert( int & val, const char * nptr ) {			// convert C string to integer
+	char * eptr;
+	int temp = strto( nptr, &eptr, 10 );				// do not change val on false
+	// true => entire string valid with no extra characters
+	return *nptr != '\0' && *eptr == '\0' ? val = temp, true : false;
+} // convert
+
+void usage( char * argv[] ) {
+	sout | "Usage:" | argv[0] | "( -s unsorted-file [ sorted-file ] | -t size (>= 0) [ depth (>= 0) ] )";
+	exit( EXIT_FAILURE );								// TERMINATE!
+} // usage
+
+
+#define ELEMTYPE int
+
+int main( int argc, char * argv[] ) {
+	ifstream & unsortedfile = sin;
+	ofstream & sortedfile = sout;						// default value
+	int depth = 0, size;
+
+	if ( argc != 1 ) {									// do not use defaults
+		if ( argc < 2 || argc > 4 ) usage( argv );		// wrong number of options
+		if ( strcmp( argv[1], "-t" ) == 0 ) {			// timing ?
+			&unsortedfile = (ifstream *)0;				// no input
+			choose ( argc ) {
+			  case 4:
+				if ( ! convert( depth, argv[3] ) || depth < 0 ) usage( argv );
+				fallthrough;
+			  case 3:
+				if ( ! convert( size, argv[2] ) || size < 0 ) usage( argv );
+			} // choose
+		} else {										// sort file
+			choose ( argc ) {
+			  case 3:
+				&sortedfile = new( (const char *)argv[2] ); // open the output file
+				if ( fail( sortedfile ) ) {
+					serr | "Error! Could not open sorted output file \"" | argv[2] | "\"";
+					usage( argv );
+				} // if
+				fallthrough;
+			  case 2:
+				&unsortedfile = new( (const char *)argv[1] ); // open the input file
+				if ( fail( unsortedfile ) ) {
+					serr | "Error! Could not open unsorted input file \"" | argv[1] | "\"";
+					usage( argv );
+				} // if
+			} // choose
+		} // if
+	} // if
+	sortedfile | nlOff;									// turn off auto newline
+
+	enum { ValuesPerLine = 22 };						// number of values printed per line
+
+	if ( &unsortedfile ) {								// generate output ?
+		for () {
+			unsortedfile | size;						// read number of elements in the list
+		  if ( eof( unsortedfile ) ) break;
+			ELEMTYPE * values = alloc( size );			// values to be sorted, too large to put on stack
+			for ( int counter = 0; counter < size; counter += 1 ) { // read unsorted numbers
+				unsortedfile | values[counter];
+				if ( counter != 0 && counter % ValuesPerLine == 0 ) sortedfile | nl | "  ";
+				sortedfile | values[counter];
+				if ( counter < size - 1 && (counter + 1) % ValuesPerLine != 0 ) sortedfile | ' ';
+			} // for
+			sortedfile | nl;
+			if ( size > 0 ) {							// values to sort ?
+				Quicksort(ELEMTYPE) QS = { values, size - 1, 0 }; // sort values
+			} // wait until sort tasks terminate
+			for ( int counter = 0; counter < size; counter += 1 ) { // print sorted list
+				if ( counter != 0 && counter % ValuesPerLine == 0 ) sortedfile | nl | "  ";
+				sortedfile | values[counter];
+				if ( counter < size - 1 && (counter + 1) % ValuesPerLine != 0 ) sortedfile | ' ';
+			} // for
+			sortedfile | nl | nl;
+
+			delete( values );
+		} // for
+		if ( &unsortedfile != &sin ) delete( &unsortedfile ); // close input/output files
+		if ( &sortedfile != &sout ) delete( &sortedfile );
+	} else {
+		processor processors[ (1 << depth) - 1 ] __attribute__(( unused )); // create 2^depth-1 kernel threads
+
+		ELEMTYPE * values = alloc( size );				// values to be sorted, too large to put on stack
+		for ( int counter = 0; counter < size; counter += 1 ) { // generate unsorted numbers
+			values[counter] = size - counter;			// descending values
+		} // for
+		{
+			Quicksort(ELEMTYPE) QS = { values, size - 1, depth }; // sort values
+		} // wait until sort tasks terminate
+
+		// for ( int counter = 0; counter < size - 1; counter += 1 ) { // check sorting
+		// 	if ( values[counter] > values[counter + 1] ) abort();
+		// } // for
+
+		delete( values );
+	} // if
+} // main
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa quickSort.generic.cfa" //
+// End: //
Index: tests/concurrent/waitfor/parse2.cfa
===================================================================
--- tests/concurrent/waitfor/parse2.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/concurrent/waitfor/parse2.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Wed Aug 30 17:53:29 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Aug 30 17:55:17 2017
-// Update Count     : 2
+// Last Modified On : Fri Mar 22 13:42:11 2019
+// Update Count     : 3
 // 
 
@@ -246,4 +246,4 @@
 // Local Variables: //
 // tab-width: 4 //
-// compile-command: "cfa waitfor.c" //
+// compile-command: "cfa waitfor.cfa" //
 // End: //
Index: tests/config.py.in
===================================================================
--- tests/config.py.in	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/config.py.in	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -1,3 +1,3 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # encoding: utf-8
 """
Index: tests/coroutine/.expect/devicedriver.txt
===================================================================
--- tests/coroutine/.expect/devicedriver.txt	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ tests/coroutine/.expect/devicedriver.txt	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,8 @@
+msg:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+msg:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+msg:
+msg:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+msg:escapeSTXescapeESCescapeETX
+CRC failure
+STX in message
+message too long
Index: tests/coroutine/.expect/fmtLines.txt
===================================================================
--- tests/coroutine/.expect/fmtLines.txt	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/coroutine/.expect/fmtLines.txt	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -16,7 +16,7 @@
 difi  ed B  y :   Pete  r A.  
  Buh  r//   Last   Mod  ifie  
-d On   : T  ue D  ec 1  1 23  
-:31:  12 2  018/  / Up  date  
- Cou  nt       :   32/  /#in  
+d On   : F  ri M  ar 2  2 13  
+:41:  03 2  019/  / Up  date  
+ Cou  nt       :   33/  /#in  
 clud  e <f  stre  am.h  fa>#  
 incl  ude   <cor  outi  ne.h  
@@ -76,3 +76,3 @@
 th:   4 //  // c  ompi  le-c  
 omma  nd:   "cfa   fmt  Line  
-s.c"   ///  / En  d: /  /
+s.cf  a" /  ///   End:   //
Index: tests/coroutine/.in/fmtLines.txt
===================================================================
--- tests/coroutine/.in/fmtLines.txt	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/coroutine/.in/fmtLines.txt	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Sun Sep 17 21:56:15 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec 11 23:31:12 2018
-// Update Count     : 32
+// Last Modified On : Fri Mar 22 13:41:03 2019
+// Update Count     : 33
 //
 
@@ -64,4 +64,4 @@
 // Local Variables: //
 // tab-width: 4 //
-// compile-command: "cfa fmtLines.c" //
+// compile-command: "cfa fmtLines.cfa" //
 // End: //
Index: tests/coroutine/cntparens.cfa
===================================================================
--- tests/coroutine/cntparens.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ tests/coroutine/cntparens.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,60 @@
+// 
+// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+// 
+// cntparens.cfa -- match left/right parenthesis
+// 
+// Author           : Peter A. Buhr
+// Created On       : Sat Apr 20 11:04:45 2019
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sat Apr 20 11:06:21 2019
+// Update Count     : 1
+// 
+
+#include <fstream.hfa>
+#include <coroutine.hfa>
+
+enum Status { Cont, Match, Error };
+coroutine CntParens {
+	char ch;											// used for communication
+	Status status;
+	unsigned int cnt;
+}; // CntParens
+
+void main( CntParens & cpns ) with( cpns ) {
+	for ( ; ch == '('; cnt += 1 ) {						// left parenthesis
+		suspend();
+	}
+	for ( ; ch == ')' && cnt > 1; cnt -= 1 ) {			// right parenthesis
+		suspend();
+	}
+	status = ch == ')' ? Match : Error;
+} // main
+	
+void ?{}( CntParens & cpns ) with( cpns ) { status = Cont; cnt = 0; }
+
+Status next( CntParens & cpns, char c ) with( cpns ) {
+	ch = c;
+	resume( cpns );
+	return status;
+}
+
+int main() {
+	CntParens cpns;
+	char ch;
+
+	for () {											// read until end of file
+		sin | ch;										// read one character
+	  if ( eof( sin ) ) { sout | "Error"; break; }		// eof ?
+		Status ret = next( cpns, ch );					// push character for formatting
+	  if ( ret == Match ) { sout | "Match"; break; }
+	  if ( ret == Error ) { sout | "Error"; break; }
+	} // for
+} // main
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa -g -Wall -Wextra cntparens.cfa" //
+// End: //
Index: tests/coroutine/devicedriver.cfa
===================================================================
--- tests/coroutine/devicedriver.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
+++ tests/coroutine/devicedriver.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -0,0 +1,91 @@
+// 
+// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+// 
+// devicedriver.cfa -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Sat Mar 16 15:30:34 2019
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sat Apr 20 09:07:19 2019
+// Update Count     : 90
+// 
+
+#include <fstream.hfa>
+#include <coroutine.hfa>
+
+enum Status { CONT, MSG, ESTX, ELNTH, ECRC };
+coroutine Driver {
+	Status status;
+	char * msg, byte;
+}; // Driver
+
+void ?{}( Driver & d, char * m ) { d.msg = m; }
+Status next( Driver & d, char b ) with( d ) {
+	byte = b; resume( d ); return status;
+} // next
+
+void checkCRC( Driver & d, unsigned int sum ) with( d ) {
+	suspend();
+	unsigned short int crc = byte << 8;					// sign extension over written
+	suspend();
+	// prevent sign extension for signed char
+	status = (crc | (unsigned char)byte) == sum ? MSG : ECRC;
+} // checkCRC
+
+void main( Driver & d ) with( d ) {
+	enum { STX = '\002', ESC = '\033', ETX = '\003', MaxMsg = 64 };
+  msg: for () {											// parse message
+		status = CONT;
+		unsigned int lnth = 0, sum = 0;
+		while ( byte != STX ) suspend();
+	  emsg: for () {
+			suspend();
+			choose ( byte ) {							// process byte
+			  case STX:
+				status = ESTX; suspend(); continue msg;
+			  case ETX:
+				break emsg;
+			  case ESC:
+				suspend();
+			} // choose
+			if ( lnth >= MaxMsg ) {						// buffer full ?
+				status = ELNTH; suspend(); continue msg;
+			} // if
+			msg[lnth++] = byte;
+			sum += byte;
+		} // for
+		msg[lnth] = '\0';								// terminate string
+		checkCRC( d, sum );								// refactor CRC check
+		suspend();
+	} // for
+} // main
+
+int main() {
+	char msg[65], byte;
+	Driver driver = { msg };
+
+	sin | nlOn;											// read newline (all) characters
+  eof: for () {											// read until end of file
+		sin | byte;										// read one character
+	  if ( eof( sin ) ) break eof;						// eof ?
+		choose( next( driver, byte ) ) {				// analyse character
+		  case MSG:
+			sout | "msg:" | msg;
+		  case ESTX:
+			sout | "STX in message";
+		  case ELNTH:
+			sout | "message too long";
+		  case ECRC:
+			sout | "CRC failure";
+		  default: ;
+		} // choose
+	} // for
+} // main
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa -g -Wall -Wextra devicedriver.cfa" //
+// End: //
Index: tests/coroutine/fibonacci.cfa
===================================================================
--- tests/coroutine/fibonacci.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/coroutine/fibonacci.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Thu Jun  8 07:29:37 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec 11 21:57:33 2018
-// Update Count     : 25
+// Last Modified On : Fri Mar 22 13:40:35 2019
+// Update Count     : 26
 //
 
@@ -45,4 +45,4 @@
 // Local Variables: //
 // tab-width: 4 //
-// compile-command: "cfa fibonacci.c" //
+// compile-command: "cfa fibonacci.cfa" //
 // End: //
Index: tests/coroutine/fibonacci_1.cfa
===================================================================
--- tests/coroutine/fibonacci_1.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/coroutine/fibonacci_1.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -5,11 +5,11 @@
 // file "LICENCE" distributed with Cforall.
 //
-// fibonacci_1.c -- 1-state finite-state machine: precomputed first two states returning f(n - 2)
+// fibonacci_1.cfa -- 1-state finite-state machine: precomputed first two states returning f(n - 1)
 //
 // Author           : Peter A. Buhr
 // Created On       : Thu Apr 26 23:20:08 2018
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec 11 21:57:54 2018
-// Update Count     : 14
+// Last Modified On : Thu Mar 21 08:10:45 2019
+// Update Count     : 25
 // 
 
@@ -17,12 +17,12 @@
 #include <coroutine.hfa>
 
-coroutine Fibonacci { int ret; };						// used for communication
+coroutine Fibonacci { int fn1; };						// used for communication
 
 void main( Fibonacci & fib ) with( fib ) {				// called on first resume
-	int fn, fn1 = 1, fn2 = 0;							// precompute first two states
+	int fn;
+	[fn1, fn] = [0, 1];									// precompute first two states
 	for () {
-		ret = fn2;
-		fn = fn1 + fn2;  fn2 = fn1;  fn1 = fn;			// general case
 		suspend();										// restart last resume
+		[fn1, fn] = [fn, fn1 + fn];						// general case
 	} // for
 }
@@ -30,5 +30,5 @@
 int next( Fibonacci & fib ) with( fib ) {
 	resume( fib );										// restart last suspend
-	return ret;
+	return fn1;
 }
 
@@ -42,4 +42,4 @@
 // Local Variables: //
 // tab-width: 4 //
-// compile-command: "cfa fibonacci_1.c" //
+// compile-command: "cfa fibonacci_1.cfa" //
 // End: //
Index: tests/coroutine/fmtLines.cfa
===================================================================
--- tests/coroutine/fmtLines.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/coroutine/fmtLines.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Sun Sep 17 21:56:15 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Dec 22 18:27:00 2018
-// Update Count     : 57
+// Last Modified On : Fri Mar 22 13:41:16 2019
+// Update Count     : 58
 //
 
@@ -63,4 +63,4 @@
 // Local Variables: //
 // tab-width: 4 //
-// compile-command: "cfa fmtLines.c" //
+// compile-command: "cfa fmtLines.cfa" //
 // End: //
Index: tests/coroutine/pingpong.cfa
===================================================================
--- tests/coroutine/pingpong.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/coroutine/pingpong.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Wed Sep 20 11:55:23 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec 11 21:58:06 2018
-// Update Count     : 29
+// Last Modified On : Tue Mar 26 17:54:14 2019
+// Update Count     : 35
 //
 
@@ -20,15 +20,12 @@
 	const char * name;
 	/* const */ unsigned int N;
-	PingPong * part;
+	PingPong & part;
 };
 
 void ?{}( PingPong & this, const char * name, unsigned int N, PingPong & part ) {
-	(this.__cor){name};
-	this.name = name;
-	this.N = N;
-	this.part = &part;
+	this.[name, N] = [name, N];  &this.part = &part;
 }
 void ?{}( PingPong & this, const char * name, unsigned int N ) {
-	this{ name, N, *(PingPong *)0 };
+	this{ name, N, *0p };								// call first constructor
 }
 void cycle( PingPong & pingpong ) {
@@ -36,11 +33,11 @@
 }
 void partner( PingPong & this, PingPong & part ) {
-	this.part = &part;
+	&this.part = &part;
 	resume( this );
 }
-void main( PingPong & pingpong ) {						// ping's starter ::main, pong's starter ping
-	for ( pingpong.N ) {								// N ping-pongs
-		sout | pingpong.name;
-		cycle( *pingpong.part );
+void main( PingPong & pingpong ) with(pingpong) {		// ping's starter ::main, pong's starter ping
+	for ( N ) {											// N ping-pongs
+		sout | name;
+		cycle( part );
 	} // for
 }
@@ -53,4 +50,4 @@
 // Local Variables: //
 // tab-width: 4 //
-// compile-command: "cfa pingpong.c" //
+// compile-command: "cfa pingpong.cfa" //
 // End: //
Index: tests/coroutine/prodcons.cfa
===================================================================
--- tests/coroutine/prodcons.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/coroutine/prodcons.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Mon Sep 18 12:23:39 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Dec 12 23:04:49 2018
-// Update Count     : 53
+// Last Modified On : Fri Mar 22 13:41:10 2019
+// Update Count     : 54
 //
 
@@ -91,4 +91,4 @@
 // Local Variables: //
 // tab-width: 4 //
-// compile-command: "cfa prodcons.c" //
+// compile-command: "cfa prodcons.cfa" //
 // End: //
Index: tests/coroutine/runningTotal.cfa
===================================================================
--- tests/coroutine/runningTotal.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/coroutine/runningTotal.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Wed Dec  6 08:05:27 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec 11 21:59:00 2018
-// Update Count     : 4
+// Last Modified On : Fri Mar 22 13:40:49 2019
+// Update Count     : 5
 //
 
@@ -48,4 +48,4 @@
 // Local Variables: //
 // tab-width: 4 //
-// compile-command: "cfa runningTotal.c" //
+// compile-command: "cfa runningTotal.cfa" //
 // End: //
Index: tests/forall.cfa
===================================================================
--- tests/forall.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/forall.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Wed May  9 08:48:15 2018
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Nov  6 17:53:43 2018
-// Update Count     : 31
+// Last Modified On : Tue Mar 19 08:29:38 2019
+// Update Count     : 32
 // 
 
@@ -53,6 +53,4 @@
 	right = temp;
 }
-
-void ?{}( int & c, zero_t ) { c = 0; }					// not in prelude
 
 trait sumable( otype T ) {
Index: tests/function-operator.cfa
===================================================================
--- tests/function-operator.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/function-operator.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Fri Aug 25 15:21:11 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec  4 21:37:09 2018
-// Update Count     : 9
+// Last Modified On : Thu Apr 11 18:27:45 2019
+// Update Count     : 10
 //
 
@@ -62,5 +62,5 @@
 
 // test ?()(T, ...) -- ?() with function call-by-reference
-forall(otype Generator, otype GenRet | { GenRet ?()(Generator &); }, dtype Iter, otype T| Iterator(Iter, T) | Assignable(T, GenRet))
+forall(otype Generator, otype GenRet | { GenRet ?()(Generator &); }, dtype Iter, otype T | Iterator(Iter, T) | Assignable(T, GenRet))
 void generate(Iter first, Iter last, Generator & gen) {
 	int i = 0;
Index: tests/io2.cfa
===================================================================
--- tests/io2.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/io2.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Wed Mar  2 16:56:02 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Dec 21 08:20:14 2018
-// Update Count     : 112
+// Last Modified On : Thu Apr 18 08:03:30 2019
+// Update Count     : 113
 //
 
@@ -97,5 +97,5 @@
 	sout | 1 | sepOff | 2 | 3;							// locally turn off implicit separator
 	sout | sepOn | sepOn | 1 | 2 | 3 | sepOn | sepOff | sepOn | '\n' | nonl; // no separator at start/end of line
-	sout | 1 | 2 | 3 | "\n\n" | sepOn | nonl;					// no separator at start of next line
+	sout | 1 | 2 | 3 | "\n\n" | sepOn | nonl;			// no separator at start of next line
 	sout | 1 | 2 | 3;
 	sout | nl;
Index: tests/loopctrl.cfa
===================================================================
--- tests/loopctrl.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/loopctrl.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Wed Aug  8 18:32:59 2018
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Feb 21 08:54:47 2019
-// Update Count     : 86
+// Last Modified On : Sat Apr 13 11:03:09 2019
+// Update Count     : 104
 // 
 
@@ -56,4 +56,13 @@
 	for ( ui; 10u -~= 2u ~ 2u ) { sout | ui; }			sout | nl | nl;
 
+	// @ means do nothing
+	for ( i; 1 ~ @ ) {
+	  if ( i > 10 ) break;
+		sout | i;
+	}													sout | nl;
+	for ( i; 10 -~ @ ) {
+	  if ( i < 0 ) break;
+		sout | i;
+	}													sout | nl;
 	for ( i; 2 ~ @ ~ 2 ) {
 	  if ( i > 10 ) break;
@@ -94,5 +103,19 @@
 	for ( s; (S){10,10} -~ (S){0} ~ (S){1} ) { sout | s; } sout | nl;
 	for ( s; (S){10,10} -~= (S){0} ) { sout | s; }		 sout | nl;
-	for ( s; (S){10,10} -~= (S){0} ~ (S){1} ) { sout | s; } sout | nl;
+	for ( s; (S){10,10} -~= (S){0} ~ (S){1} ) { sout | s; } sout | nl | nl;
+
+	for ( i; 10 : j; -5 ~ @ ) { sout | i | j; } sout | nl;
+	for ( i; 10 : j; -5 -~ @ ) { sout | i | j; } sout | nl;
+	for ( i; 10 : j; -5 ~ @ ~ 2 ) { sout | i | j; } sout | nl;
+	for ( i; 10 : j; -5 -~ @ ~ 2 ) { sout | i | j; } sout | nl | nl;
+
+	for ( j; -5 ~ @ : i; 10 ) { sout | i | j; } sout | nl;
+	for ( j; -5 -~ @ : i; 10 ) { sout | i | j; } sout | nl;
+	for ( j; -5 ~ @ ~ 2 : i; 10 ) { sout | i | j; } sout | nl;
+	for ( j; -5 -~ @ ~ 2 : i; 10 ) { sout | i | j; } sout | nl | nl;
+
+	for ( j; -5 -~ @ ~ 2 : i; 10 : k; 1.5 ~ @ ) { sout | i | j | k; } sout | nl;
+	for ( j; -5 -~ @ ~ 2 : k; 1.5 ~ @ : i; 10 ) { sout | i | j | k; } sout | nl;
+	for ( k; 1.5 ~ @ : j; -5 -~ @ ~ 2 : i; 10 ) { sout | i | j | k; } sout | nl;
 }
 
Index: tests/math1.cfa
===================================================================
--- tests/math1.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/math1.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Fri Apr 22 14:59:21 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Dec 12 16:28:49 2018
-// Update Count     : 89
+// Last Modified On : Mon Mar 25 22:56:47 2019
+// Update Count     : 109
 //
 
@@ -49,7 +49,19 @@
 	unsigned int e = 2;
     b \= e;
-    sout | "\\" | b | b \ e;
-    sout | "\\" | 'a' \ 3u | 2 \ 8u | 4 \ 3u | -4 \ 3u | nonl;
+    sout | b | "\\" | e | "= " | b \ e;
+    sout | 'a' \ 3 | 2 \ 8 | 4 \ 3 | -4 \ 3 | 4 \ -3 | -4 \ -3;
+	sout | 4.0 \ -3 | -4.0 \ -3 | 4.0 \ 2.1 | (1.0f+2.0fi) \ (3.0f+2.0fi);
 	sout | 4 \ -3 | -4 \ -3 | 4.0 \ 2.1 | (1.0f+2.0fi) \ (3.0f+2.0fi);
+
+	struct S { int i; };
+	double ?*?( double d, S s ) { return d * s.i; }
+	double ?/?( double d, S s ) { return d / s.i; }
+	S ?\?( S s, unsigned long y ) { return (S){ s.i \ y }; }
+	ofstream & ?|?( ofstream & os, S s ) { return os | s.i; }
+	void ?|?( ofstream & os, S s ) { (ofstream &)(os | s); nl( os ); }
+	S s = { 4 };
+	S x = s \ 2;
+	sout | x;
+	sout | s.i | s \ 2u;
 } // main
 
Index: sts/preempt_longrun/Makefile.am
===================================================================
--- tests/preempt_longrun/Makefile.am	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ 	(revision )
@@ -1,79 +1,0 @@
-######################## -*- Mode: Makefile-Automake -*- ######################
-##
-## 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.
-##
-## Makefile.am --
-##
-## Author           : Thierry Delisle
-## Created On       : Fri Jun 16 10:57:34 2017
-## Last Modified By :
-## Last Modified On :
-## Update Count     : 0
-###############################################################################
-
-AUTOMAKE_OPTIONS = foreign    # do not require all the GNU file names
-ACLOCAL_AMFLAGS  = -I automake
-
-repeats=10
-max_time=600
-preempt=10ul\`ms
-debug=-debug
-type=LONG
-
-REPEAT = ${abs_top_srcdir}/tools/repeat
-WATCHDOG = ${abs_top_srcdir}/tools/watchdog
-TIME = /usr/bin/time -f "%E"
-
-# $(shell ./update-type $(type))
-# ./update-type $(type)
-
-UPDATED_TYPE = $(shell ./update-type $(type))
-
-BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -O2 -DPREEMPTION_RATE=${preempt} -I.. -I. -DTEST_$(shell cat .type | tr a-z A-Z)
-CFLAGS = ${BUILD_FLAGS}
-CC = @CFACC@
-
-TESTS = block coroutine create disjoint enter enter3 processor stack wait yield
-
-# .INTERMEDIATE: ${TESTS}
-
-all-local: ${TESTS:=.run}
-
-runall : ${TESTS:=.run}
-	@ echo "All programs terminated normally"
-
-watchall : ${TESTS:=.watch}
-	@ echo "All programs terminated normally"
-
-compileall : ${TESTS}
-	@ echo "Compiled"
-
-clean-local:
-	rm -f ${TESTS} core* out.log .type
-
-% : %.c ${CC} ${UPDATED_TYPE}
-	${AM_V_GEN}${CC} ${CFLAGS} ${<} $(debug) -o ${@}
-
-%.run : % ${REPEAT}
-	@ time ${REPEAT} -r out.log -i -s $(repeats) timeout ${max_time} ./${<}
-	@ rm ${<}
-	@ echo -e "${<}: SUCCESS\n"
-
-%.watch : % ${WATCHDOG}
-	@ time ${WATCHDOG} ./${<}
-	@ rm ${<}
-	@ echo -e "${<}: SUCCESS\n"
-
-%.time : % ${REPEAT}
-	@ ${REPEAT} -i -s -- $(repeats) $(TIME) -a -o times.log ./${<}
-	@ rm ${<}
-	@ echo -e "${<}: SUCCESS\n"
-
-${REPEAT}: ${abs_top_srcdir}/tools/Makefile
-	@+make -C ${abs_top_srcdir}/tools/
-
-${WATCHDOG}: ${abs_top_srcdir}/tools/Makefile
-	@+make -C ${abs_top_srcdir}/tools/
Index: sts/preempt_longrun/Makefile.in
===================================================================
--- tests/preempt_longrun/Makefile.in	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ 	(revision )
@@ -1,961 +1,0 @@
-# Makefile.in generated by automake 1.15 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994-2014 Free Software Foundation, Inc.
-
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-######################## -*- Mode: Makefile-Automake -*- ######################
-###############################################################################
-VPATH = @srcdir@
-am__is_gnu_make = { \
-  if test -z '$(MAKELEVEL)'; then \
-    false; \
-  elif test -n '$(MAKE_HOST)'; then \
-    true; \
-  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
-    true; \
-  else \
-    false; \
-  fi; \
-}
-am__make_running_with_option = \
-  case $${target_option-} in \
-      ?) ;; \
-      *) echo "am__make_running_with_option: internal error: invalid" \
-              "target option '$${target_option-}' specified" >&2; \
-         exit 1;; \
-  esac; \
-  has_opt=no; \
-  sane_makeflags=$$MAKEFLAGS; \
-  if $(am__is_gnu_make); then \
-    sane_makeflags=$$MFLAGS; \
-  else \
-    case $$MAKEFLAGS in \
-      *\\[\ \	]*) \
-        bs=\\; \
-        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
-          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
-    esac; \
-  fi; \
-  skip_next=no; \
-  strip_trailopt () \
-  { \
-    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
-  }; \
-  for flg in $$sane_makeflags; do \
-    test $$skip_next = yes && { skip_next=no; continue; }; \
-    case $$flg in \
-      *=*|--*) continue;; \
-        -*I) strip_trailopt 'I'; skip_next=yes;; \
-      -*I?*) strip_trailopt 'I';; \
-        -*O) strip_trailopt 'O'; skip_next=yes;; \
-      -*O?*) strip_trailopt 'O';; \
-        -*l) strip_trailopt 'l'; skip_next=yes;; \
-      -*l?*) strip_trailopt 'l';; \
-      -[dEDm]) skip_next=yes;; \
-      -[JT]) skip_next=yes;; \
-    esac; \
-    case $$flg in \
-      *$$target_option*) has_opt=yes; break;; \
-    esac; \
-  done; \
-  test $$has_opt = yes
-am__make_dryrun = (target_option=n; $(am__make_running_with_option))
-am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = tests/preempt_longrun
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/automake/libtool.m4 \
-	$(top_srcdir)/automake/ltoptions.m4 \
-	$(top_srcdir)/automake/ltsugar.m4 \
-	$(top_srcdir)/automake/ltversion.m4 \
-	$(top_srcdir)/automake/lt~obsolete.m4 \
-	$(top_srcdir)/automake/cfa.m4 $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-AM_V_P = $(am__v_P_@AM_V@)
-am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
-am__v_P_0 = false
-am__v_P_1 = :
-AM_V_GEN = $(am__v_GEN_@AM_V@)
-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo "  GEN     " $@;
-am__v_GEN_1 = 
-AM_V_at = $(am__v_at_@AM_V@)
-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
-am__v_at_0 = @
-am__v_at_1 = 
-SOURCES =
-DIST_SOURCES =
-am__can_run_installinfo = \
-  case $$AM_UPDATE_INFO_DIR in \
-    n|no|NO) false;; \
-    *) (install-info --version) >/dev/null 2>&1;; \
-  esac
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-am__tty_colors_dummy = \
-  mgn= red= grn= lgn= blu= brg= std=; \
-  am__color_tests=no
-am__tty_colors = { \
-  $(am__tty_colors_dummy); \
-  if test "X$(AM_COLOR_TESTS)" = Xno; then \
-    am__color_tests=no; \
-  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
-    am__color_tests=yes; \
-  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
-    am__color_tests=yes; \
-  fi; \
-  if test $$am__color_tests = yes; then \
-    red='[0;31m'; \
-    grn='[0;32m'; \
-    lgn='[1;32m'; \
-    blu='[1;34m'; \
-    mgn='[0;35m'; \
-    brg='[1m'; \
-    std='[m'; \
-  fi; \
-}
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
-    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
-    *) f=$$p;; \
-  esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
-  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
-  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
-  for p in $$list; do echo "$$p $$p"; done | \
-  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
-  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
-    if (++n[$$2] == $(am__install_max)) \
-      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
-    END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
-  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
-  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__uninstall_files_from_dir = { \
-  test -z "$$files" \
-    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
-    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
-         $(am__cd) "$$dir" && rm -f $$files; }; \
-  }
-am__recheck_rx = ^[ 	]*:recheck:[ 	]*
-am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
-am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
-# A command that, given a newline-separated list of test names on the
-# standard input, print the name of the tests that are to be re-run
-# upon "make recheck".
-am__list_recheck_tests = $(AWK) '{ \
-  recheck = 1; \
-  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
-    { \
-      if (rc < 0) \
-        { \
-          if ((getline line2 < ($$0 ".log")) < 0) \
-	    recheck = 0; \
-          break; \
-        } \
-      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
-        { \
-          recheck = 0; \
-          break; \
-        } \
-      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
-        { \
-          break; \
-        } \
-    }; \
-  if (recheck) \
-    print $$0; \
-  close ($$0 ".trs"); \
-  close ($$0 ".log"); \
-}'
-# A command that, given a newline-separated list of test names on the
-# standard input, create the global log from their .trs and .log files.
-am__create_global_log = $(AWK) ' \
-function fatal(msg) \
-{ \
-  print "fatal: making $@: " msg | "cat >&2"; \
-  exit 1; \
-} \
-function rst_section(header) \
-{ \
-  print header; \
-  len = length(header); \
-  for (i = 1; i <= len; i = i + 1) \
-    printf "="; \
-  printf "\n\n"; \
-} \
-{ \
-  copy_in_global_log = 1; \
-  global_test_result = "RUN"; \
-  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
-    { \
-      if (rc < 0) \
-         fatal("failed to read from " $$0 ".trs"); \
-      if (line ~ /$(am__global_test_result_rx)/) \
-        { \
-          sub("$(am__global_test_result_rx)", "", line); \
-          sub("[ 	]*$$", "", line); \
-          global_test_result = line; \
-        } \
-      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
-        copy_in_global_log = 0; \
-    }; \
-  if (copy_in_global_log) \
-    { \
-      rst_section(global_test_result ": " $$0); \
-      while ((rc = (getline line < ($$0 ".log"))) != 0) \
-      { \
-        if (rc < 0) \
-          fatal("failed to read from " $$0 ".log"); \
-        print line; \
-      }; \
-      printf "\n"; \
-    }; \
-  close ($$0 ".trs"); \
-  close ($$0 ".log"); \
-}'
-# Restructured Text title.
-am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
-# Solaris 10 'make', and several other traditional 'make' implementations,
-# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
-# by disabling -e (using the XSI extension "set +e") if it's set.
-am__sh_e_setup = case $$- in *e*) set +e;; esac
-# Default flags passed to test drivers.
-am__common_driver_flags = \
-  --color-tests "$$am__color_tests" \
-  --enable-hard-errors "$$am__enable_hard_errors" \
-  --expect-failure "$$am__expect_failure"
-# To be inserted before the command running the test.  Creates the
-# directory for the log if needed.  Stores in $dir the directory
-# containing $f, in $tst the test, in $log the log.  Executes the
-# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
-# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
-# will run the test scripts (or their associated LOG_COMPILER, if
-# thy have one).
-am__check_pre = \
-$(am__sh_e_setup);					\
-$(am__vpath_adj_setup) $(am__vpath_adj)			\
-$(am__tty_colors);					\
-srcdir=$(srcdir); export srcdir;			\
-case "$@" in						\
-  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
-    *) am__odir=.;; 					\
-esac;							\
-test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
-  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
-if test -f "./$$f"; then dir=./;			\
-elif test -f "$$f"; then dir=;				\
-else dir="$(srcdir)/"; fi;				\
-tst=$$dir$$f; log='$@'; 				\
-if test -n '$(DISABLE_HARD_ERRORS)'; then		\
-  am__enable_hard_errors=no; 				\
-else							\
-  am__enable_hard_errors=yes; 				\
-fi; 							\
-case " $(XFAIL_TESTS) " in				\
-  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
-    am__expect_failure=yes;;				\
-  *)							\
-    am__expect_failure=no;;				\
-esac; 							\
-$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
-# A shell command to get the names of the tests scripts with any registered
-# extension removed (i.e., equivalently, the names of the test logs, with
-# the '.log' extension removed).  The result is saved in the shell variable
-# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
-# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
-# since that might cause problem with VPATH rewrites for suffix-less tests.
-# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
-am__set_TESTS_bases = \
-  bases='$(TEST_LOGS)'; \
-  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
-  bases=`echo $$bases`
-RECHECK_LOGS = $(TEST_LOGS)
-AM_RECURSIVE_TARGETS = check recheck
-TEST_SUITE_LOG = test-suite.log
-TEST_EXTENSIONS = @EXEEXT@ .test
-LOG_DRIVER = $(SHELL) $(top_srcdir)/automake/test-driver
-LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
-am__set_b = \
-  case '$@' in \
-    */*) \
-      case '$*' in \
-        */*) b='$*';; \
-          *) b=`echo '$@' | sed 's/\.log$$//'`; \
-       esac;; \
-    *) \
-      b='$*';; \
-  esac
-am__test_logs1 = $(TESTS:=.log)
-am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
-TEST_LOGS = $(am__test_logs2:.test.log=.log)
-TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/automake/test-driver
-TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
-	$(TEST_LOG_FLAGS)
-am__DIST_COMMON = $(srcdir)/Makefile.in \
-	$(top_srcdir)/automake/test-driver
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-BUILD_IN_TREE_FLAGS = @BUILD_IN_TREE_FLAGS@
-CC = @CFACC@
-CCAS = @CCAS@
-CCASDEPMODE = @CCASDEPMODE@
-CCASFLAGS = @CCASFLAGS@
-CCDEPMODE = @CCDEPMODE@
-CFACC = @CFACC@
-CFACPP = @CFACPP@
-CFA_BACKEND_CC = @CFA_BACKEND_CC@
-CFA_BINDIR = @CFA_BINDIR@
-CFA_FLAGS = @CFA_FLAGS@
-CFA_INCDIR = @CFA_INCDIR@
-CFA_LIBDIR = @CFA_LIBDIR@
-CFA_NAME = @CFA_NAME@
-CFA_PREFIX = @CFA_PREFIX@
-CFLAGS = ${BUILD_FLAGS}
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DLLTOOL = @DLLTOOL@
-DRIVER_DIR = @DRIVER_DIR@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GREP = @GREP@
-HOST_FLAGS = @HOST_FLAGS@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LEX = @LEX@
-LEXLIB = @LEXLIB@
-LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
-LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@
-LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
-MAKEINFO = @MAKEINFO@
-MANIFEST_TOOL = @MANIFEST_TOOL@
-MKDIR_P = @MKDIR_P@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-TARGET_HOSTS = @TARGET_HOSTS@
-VERSION = @VERSION@
-YACC = @YACC@
-YFLAGS = @YFLAGS@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-runstatedir = @runstatedir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-AUTOMAKE_OPTIONS = foreign    # do not require all the GNU file names
-ACLOCAL_AMFLAGS = -I automake
-repeats = 10
-max_time = 600
-preempt = 10ul\`ms
-debug = -debug
-type = LONG
-REPEAT = ${abs_top_srcdir}/tools/repeat
-WATCHDOG = ${abs_top_srcdir}/tools/watchdog
-TIME = /usr/bin/time -f "%E"
-
-# $(shell ./update-type $(type))
-# ./update-type $(type)
-UPDATED_TYPE = $(shell ./update-type $(type))
-BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -O2 -DPREEMPTION_RATE=${preempt} -I.. -I. -DTEST_$(shell cat .type | tr a-z A-Z)
-TESTS = block coroutine create disjoint enter enter3 processor stack wait yield
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .log .test .test$(EXEEXT) .trs
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-	        && { if test -f $@; then exit 0; else break; fi; }; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/preempt_longrun/Makefile'; \
-	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --foreign tests/preempt_longrun/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure:  $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-
-mostlyclean-libtool:
-	-rm -f *.lo
-
-clean-libtool:
-	-rm -rf .libs _libs
-tags TAGS:
-
-ctags CTAGS:
-
-cscope cscopelist:
-
-
-# Recover from deleted '.trs' file; this should ensure that
-# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
-# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
-# to avoid problems with "make -n".
-.log.trs:
-	rm -f $< $@
-	$(MAKE) $(AM_MAKEFLAGS) $<
-
-# Leading 'am--fnord' is there to ensure the list of targets does not
-# expand to empty, as could happen e.g. with make check TESTS=''.
-am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
-am--force-recheck:
-	@:
-
-$(TEST_SUITE_LOG): $(TEST_LOGS)
-	@$(am__set_TESTS_bases); \
-	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
-	redo_bases=`for i in $$bases; do \
-	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
-	            done`; \
-	if test -n "$$redo_bases"; then \
-	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
-	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
-	  if $(am__make_dryrun); then :; else \
-	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
-	  fi; \
-	fi; \
-	if test -n "$$am__remaking_logs"; then \
-	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
-	       "recursion detected" >&2; \
-	elif test -n "$$redo_logs"; then \
-	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
-	fi; \
-	if $(am__make_dryrun); then :; else \
-	  st=0;  \
-	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
-	  for i in $$redo_bases; do \
-	    test -f $$i.trs && test -r $$i.trs \
-	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
-	    test -f $$i.log && test -r $$i.log \
-	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
-	  done; \
-	  test $$st -eq 0 || exit 1; \
-	fi
-	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
-	ws='[ 	]'; \
-	results=`for b in $$bases; do echo $$b.trs; done`; \
-	test -n "$$results" || results=/dev/null; \
-	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
-	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
-	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
-	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
-	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
-	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
-	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
-	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
-	  success=true; \
-	else \
-	  success=false; \
-	fi; \
-	br='==================='; br=$$br$$br$$br$$br; \
-	result_count () \
-	{ \
-	    if test x"$$1" = x"--maybe-color"; then \
-	      maybe_colorize=yes; \
-	    elif test x"$$1" = x"--no-color"; then \
-	      maybe_colorize=no; \
-	    else \
-	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
-	    fi; \
-	    shift; \
-	    desc=$$1 count=$$2; \
-	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
-	      color_start=$$3 color_end=$$std; \
-	    else \
-	      color_start= color_end=; \
-	    fi; \
-	    echo "$${color_start}# $$desc $$count$${color_end}"; \
-	}; \
-	create_testsuite_report () \
-	{ \
-	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
-	  result_count $$1 "PASS: " $$pass  "$$grn"; \
-	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
-	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
-	  result_count $$1 "FAIL: " $$fail  "$$red"; \
-	  result_count $$1 "XPASS:" $$xpass "$$red"; \
-	  result_count $$1 "ERROR:" $$error "$$mgn"; \
-	}; \
-	{								\
-	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
-	    $(am__rst_title);						\
-	  create_testsuite_report --no-color;				\
-	  echo;								\
-	  echo ".. contents:: :depth: 2";				\
-	  echo;								\
-	  for b in $$bases; do echo $$b; done				\
-	    | $(am__create_global_log);					\
-	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
-	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
-	if $$success; then						\
-	  col="$$grn";							\
-	 else								\
-	  col="$$red";							\
-	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
-	fi;								\
-	echo "$${col}$$br$${std}"; 					\
-	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
-	echo "$${col}$$br$${std}"; 					\
-	create_testsuite_report --maybe-color;				\
-	echo "$$col$$br$$std";						\
-	if $$success; then :; else					\
-	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
-	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
-	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
-	  fi;								\
-	  echo "$$col$$br$$std";					\
-	fi;								\
-	$$success || exit 1
-
-check-TESTS:
-	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
-	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
-	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
-	@set +e; $(am__set_TESTS_bases); \
-	log_list=`for i in $$bases; do echo $$i.log; done`; \
-	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
-	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
-	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
-	exit $$?;
-recheck: all 
-	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
-	@set +e; $(am__set_TESTS_bases); \
-	bases=`for i in $$bases; do echo $$i; done \
-	         | $(am__list_recheck_tests)` || exit 1; \
-	log_list=`for i in $$bases; do echo $$i.log; done`; \
-	log_list=`echo $$log_list`; \
-	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
-	        am__force_recheck=am--force-recheck \
-	        TEST_LOGS="$$log_list"; \
-	exit $$?
-block.log: block
-	@p='block'; \
-	b='block'; \
-	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
-	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
-	"$$tst" $(AM_TESTS_FD_REDIRECT)
-coroutine.log: coroutine
-	@p='coroutine'; \
-	b='coroutine'; \
-	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
-	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
-	"$$tst" $(AM_TESTS_FD_REDIRECT)
-create.log: create
-	@p='create'; \
-	b='create'; \
-	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
-	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
-	"$$tst" $(AM_TESTS_FD_REDIRECT)
-disjoint.log: disjoint
-	@p='disjoint'; \
-	b='disjoint'; \
-	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
-	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
-	"$$tst" $(AM_TESTS_FD_REDIRECT)
-enter.log: enter
-	@p='enter'; \
-	b='enter'; \
-	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
-	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
-	"$$tst" $(AM_TESTS_FD_REDIRECT)
-enter3.log: enter3
-	@p='enter3'; \
-	b='enter3'; \
-	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
-	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
-	"$$tst" $(AM_TESTS_FD_REDIRECT)
-processor.log: processor
-	@p='processor'; \
-	b='processor'; \
-	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
-	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
-	"$$tst" $(AM_TESTS_FD_REDIRECT)
-stack.log: stack
-	@p='stack'; \
-	b='stack'; \
-	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
-	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
-	"$$tst" $(AM_TESTS_FD_REDIRECT)
-wait.log: wait
-	@p='wait'; \
-	b='wait'; \
-	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
-	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
-	"$$tst" $(AM_TESTS_FD_REDIRECT)
-yield.log: yield
-	@p='yield'; \
-	b='yield'; \
-	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
-	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
-	"$$tst" $(AM_TESTS_FD_REDIRECT)
-.test.log:
-	@p='$<'; \
-	$(am__set_b); \
-	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
-	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
-	"$$tst" $(AM_TESTS_FD_REDIRECT)
-@am__EXEEXT_TRUE@.test$(EXEEXT).log:
-@am__EXEEXT_TRUE@	@p='$<'; \
-@am__EXEEXT_TRUE@	$(am__set_b); \
-@am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
-@am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
-@am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
-@am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	list='$(DISTFILES)'; \
-	  dist_files=`for file in $$list; do echo $$file; done | \
-	  sed -e "s|^$$srcdirstrip/||;t" \
-	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-	case $$dist_files in \
-	  */*) $(MKDIR_P) `echo "$$dist_files" | \
-			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-			   sort -u` ;; \
-	esac; \
-	for file in $$dist_files; do \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  if test -d $$d/$$file; then \
-	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-	    if test -d "$(distdir)/$$file"; then \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
-	  else \
-	    test -f "$(distdir)/$$file" \
-	    || cp -p $$d/$$file "$(distdir)/$$file" \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
-check: check-am
-all-am: Makefile all-local
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	if test -z '$(STRIP)'; then \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	      install; \
-	else \
-	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
-	fi
-mostlyclean-generic:
-	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
-	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
-	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
-
-clean-generic:
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool clean-local mostlyclean-am
-
-distclean: distclean-am
-	-rm -f Makefile
-distclean-am: clean-am distclean-generic
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-generic mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am:
-
-.MAKE: check-am install-am install-strip
-
-.PHONY: all all-am all-local check check-TESTS check-am clean \
-	clean-generic clean-libtool clean-local cscopelist-am ctags-am \
-	distclean distclean-generic distclean-libtool distdir dvi \
-	dvi-am html html-am info info-am install install-am \
-	install-data install-data-am install-dvi install-dvi-am \
-	install-exec install-exec-am install-html install-html-am \
-	install-info install-info-am install-man install-pdf \
-	install-pdf-am install-ps install-ps-am install-strip \
-	installcheck installcheck-am installdirs maintainer-clean \
-	maintainer-clean-generic mostlyclean mostlyclean-generic \
-	mostlyclean-libtool pdf pdf-am ps ps-am recheck tags-am \
-	uninstall uninstall-am
-
-.PRECIOUS: Makefile
-
-
-# .INTERMEDIATE: ${TESTS}
-
-all-local: ${TESTS:=.run}
-
-runall : ${TESTS:=.run}
-	@ echo "All programs terminated normally"
-
-watchall : ${TESTS:=.watch}
-	@ echo "All programs terminated normally"
-
-compileall : ${TESTS}
-	@ echo "Compiled"
-
-clean-local:
-	rm -f ${TESTS} core* out.log .type
-
-% : %.c ${CC} ${UPDATED_TYPE}
-	${AM_V_GEN}${CC} ${CFLAGS} ${<} $(debug) -o ${@}
-
-%.run : % ${REPEAT}
-	@ time ${REPEAT} -r out.log -i -s $(repeats) timeout ${max_time} ./${<}
-	@ rm ${<}
-	@ echo -e "${<}: SUCCESS\n"
-
-%.watch : % ${WATCHDOG}
-	@ time ${WATCHDOG} ./${<}
-	@ rm ${<}
-	@ echo -e "${<}: SUCCESS\n"
-
-%.time : % ${REPEAT}
-	@ ${REPEAT} -i -s -- $(repeats) $(TIME) -a -o times.log ./${<}
-	@ rm ${<}
-	@ echo -e "${<}: SUCCESS\n"
-
-${REPEAT}: ${abs_top_srcdir}/tools/Makefile
-	@+make -C ${abs_top_srcdir}/tools/
-
-${WATCHDOG}: ${abs_top_srcdir}/tools/Makefile
-	@+make -C ${abs_top_srcdir}/tools/
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
Index: sts/preempt_longrun/block.c
===================================================================
--- tests/preempt_longrun/block.c	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ 	(revision )
@@ -1,1 +1,0 @@
-../concurrent/signal/block.c
Index: sts/preempt_longrun/coroutine.c
===================================================================
--- tests/preempt_longrun/coroutine.c	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ 	(revision )
@@ -1,1 +1,0 @@
-../concurrent/coroutineYield.c
Index: sts/preempt_longrun/create.c
===================================================================
--- tests/preempt_longrun/create.c	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ 	(revision )
@@ -1,27 +1,0 @@
-#include <kernel.hfa>
-#include <thread.hfa>
-#include <time.hfa>
-
-#include "long_tests.hfa"
-
-#ifndef PREEMPTION_RATE
-#error PREEMPTION_RATE not defined in makefile
-#endif
-
-Duration default_preemption() {
-	return PREEMPTION_RATE;
-}
-
-static const unsigned long N = 60_000ul;
-
-thread worker_t {};
-
-void main(worker_t & this) {}
-
-int main(int argc, char* argv[]) {
-	processor p;
-	for(int i = 0; TEST(i < N); i++) {
-		worker_t w[7];
-		KICK_WATCHDOG;
-	}
-}
Index: sts/preempt_longrun/disjoint.c
===================================================================
--- tests/preempt_longrun/disjoint.c	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ 	(revision )
@@ -1,1 +1,0 @@
-../concurrent/signal/disjoint.c
Index: sts/preempt_longrun/enter.c
===================================================================
--- tests/preempt_longrun/enter.c	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ 	(revision )
@@ -1,37 +1,0 @@
-#include <kernel.hfa>
-#include <monitor.hfa>
-#include <thread.hfa>
-#include <time.hfa>
-
-#define __kick_rate 75000ul
-#include "long_tests.h"
-
-#ifndef PREEMPTION_RATE
-#error PREEMPTION_RATE not defined in makefile
-#endif
-
-Duration default_preemption() {
-	return PREEMPTION_RATE;
-}
-
-static const unsigned long N  = 2_100_000ul;
-
-monitor mon_t {};
-void foo( mon_t & mutex this ) {
-	KICK_WATCHDOG;
-}
-
-mon_t mon;
-thread worker_t {};
-void main( worker_t & this ) {
-	for( unsigned long i = 0; TEST(i < N); i++ ) {
-		foo( mon );
-	}
-}
-
-int main(int argc, char * argv[] ) {
-	processor p;
-	{
-		worker_t w[7];
-	}
-}
Index: sts/preempt_longrun/enter3.c
===================================================================
--- tests/preempt_longrun/enter3.c	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ 	(revision )
@@ -1,45 +1,0 @@
-#include <kernel.hfa>
-#include <monitor.hfa>
-#include <thread.hfa>
-#include <time.hfa>
-
-#define __kick_rate 75000ul
-#include "long_tests.hfa"
-
-#ifndef PREEMPTION_RATE
-#error PREEMPTION_RATE not defined in makefile
-#endif
-
-Duration default_preemption() {
-	return PREEMPTION_RATE;
-}
-
-static const unsigned long N  = 500_000ul;
-
-monitor mon_t {};
-
-mon_t mon1, mon2, mon3;
-
-void foo( mon_t & mutex a, mon_t & mutex b, mon_t & mutex c ) {
-	KICK_WATCHDOG;
-}
-
-thread worker_t {};
-
-void main( worker_t & this ) {
-	for( unsigned long i = 0; TEST(i < N); i++ ) {
-		foo( mon1, mon2, mon3 );
-	}
-}
-
-extern "C" {
-static worker_t * workers;
-}
-
-int main(int argc, char * argv[] ) {
-	processor p;
-	{
-		worker_t w[7];
-		workers = w;
-	}
-}
Index: sts/preempt_longrun/preempt.c
===================================================================
--- tests/preempt_longrun/preempt.c	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ 	(revision )
@@ -1,1 +1,0 @@
-../concurrent/preempt.c
Index: sts/preempt_longrun/processor.c
===================================================================
--- tests/preempt_longrun/processor.c	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ 	(revision )
@@ -1,33 +1,0 @@
-#include <kernel.hfa>
-#include <thread.hfa>
-#include <time.hfa>
-
-#include <unistd.h>
-
-#include "long_tests.hfa"
-
-#ifndef PREEMPTION_RATE
-#error PREEMPTION_RATE not defined in makefile
-#endif
-
-Duration default_preemption() {
-	return PREEMPTION_RATE;
-}
-
-static const unsigned long N = 50_000ul;
-
-int main(int argc, char* argv[]) {
-	processor * p[15];
-	for ( int pi = 0; pi < 15; pi++ ) {
-		p[pi] = new();
-	}
-	for ( int i = 0; TEST(i < N); i++) {
-		int pi = i % 15;
-		delete( p[pi] );
-		p[pi] = new();
-		KICK_WATCHDOG;
-	}
-	for ( int pi = 0; pi < 15; pi++ ) {
-		delete( p[pi] );
-	}
-}
Index: sts/preempt_longrun/stack.c
===================================================================
--- tests/preempt_longrun/stack.c	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ 	(revision )
@@ -1,46 +1,0 @@
-#include <kernel.hfa>
-#include <math.hfa>
-#include <thread.hfa>
-#include <time.hfa>
-
-#define __kick_rate 5000000ul
-#include "long_tests.h"
-
-#ifndef PREEMPTION_RATE
-#error PREEMPTION_RATE not defined in makefile
-#endif
-
-Duration default_preemption() {
-	return PREEMPTION_RATE;
-}
-
-thread worker_t {};
-
-void main(worker_t & this) {
-	while(TEST(0)) {
-		volatile long long p = 5_021_609ul;
-		volatile long long a = 326_417ul;
-		volatile long long n = 1l;
-		for (volatile long long i = 0; i < p; i++) {
-			n *= a;
-			n %= p;
-			KICK_WATCHDOG;
-		}
-
-		if( !TEST(n == a) ) {
-			abort();
-		}
-	}
-}
-
-extern "C" {
-static worker_t * workers;
-}
-
-int main(int argc, char* argv[]) {
-	processor p;
-	{
-		worker_t w[7];
-		workers = w;
-	}
-}
Index: sts/preempt_longrun/update-type
===================================================================
--- tests/preempt_longrun/update-type	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ 	(revision )
@@ -1,25 +1,0 @@
-#!/bin/bash
-
-if [ "$#" -ne 1 ]
-then
-	echo "illegal number of parameters, must be 1 was $#"
-	exit
-fi
-
-NEW="$(echo $1 | tr a-z A-Z)"
-TYPE_FILE=".type"
-if [ -f "$TYPE_FILE" ]
-then
-	OLD="$(cat $TYPE_FILE | tr a-z A-Z)"
-	if [ $OLD == $NEW ]
-	then
-		echo > /dev/null
-		# echo "$TYPE_FILE stayed unchanged"
-	else
-		echo "$NEW" > "$TYPE_FILE"
-		# echo "$TYPE_FILE changed from '$OLD' to '$NEW'"
-	fi
-else
-	echo "$NEW" > "$TYPE_FILE"
-fi
-echo "$TYPE_FILE"
Index: sts/preempt_longrun/wait.c
===================================================================
--- tests/preempt_longrun/wait.c	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ 	(revision )
@@ -1,1 +1,0 @@
-../concurrent/signal/wait.c
Index: sts/preempt_longrun/yield.c
===================================================================
--- tests/preempt_longrun/yield.c	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ 	(revision )
@@ -1,41 +1,0 @@
-#include <kernel.hfa>
-#include <thread.hfa>
-#include <time.hfa>
-
-#define __kick_rate 550000ul
-#include "long_tests.hfa"
-
-#ifndef PREEMPTION_RATE
-#error PREEMPTION_RATE not defined in makefile
-#endif
-
-Duration default_preemption() {
-	return PREEMPTION_RATE;
-}
-
-#ifdef TEST_LONG
-static const unsigned long N = 9_750_000ul;
-#else
-static const unsigned long N = 325_000ul;
-#endif
-
-thread worker_t {};
-
-void main(worker_t & this) {
-	for(int i = 0; TEST(i < N); i++) {
-		yield();
-		KICK_WATCHDOG;
-	}
-}
-
-extern "C" {
-static worker_t * workers;
-}
-
-int main(int argc, char* argv[]) {
-	processor p;
-	{
-		worker_t w[7];
-		workers = w;
-	}
-}
Index: tests/pybin/settings.py
===================================================================
--- tests/pybin/settings.py	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/pybin/settings.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -1,7 +1,6 @@
-from __future__ import print_function
-
 import os
+import subprocess
 import sys
-import tools
+from . import tools
 
 try :
@@ -39,5 +38,5 @@
 	def __init__(self, arch):
 		try:
-			canonical_host = Architecture.makeCanonical( config.HOSTARCH )
+			canonical_host = Architecture.make_canonical( config.HOSTARCH )
 		except KeyError:
 			print("Unkown host architecture %s" % config.HOSTARCH, file=sys.stderr)
@@ -46,5 +45,5 @@
 		if arch:
 			try:
-				arch = Architecture.makeCanonical( arch )
+				arch = Architecture.make_canonical( arch )
 			except KeyError:
 				print("Unkown architecture %s" % arch, file=sys.stderr)
@@ -77,5 +76,5 @@
 
 	@classmethod
-	def makeCanonical(_, arch):
+	def make_canonical(_, arch):
 		return Architecture.KnownArchitectures[arch]
 
@@ -84,10 +83,10 @@
 	def __init__(self, value):
 		self.string = "debug" if value else "no debug"
-		self.flags  = """DEBUG_FLAGS="%s" """ % ("-debug -O0" if value else "-nodebug -O2")
+		self.flags  = """DEBUG_FLAGS=%s""" % ("-debug -O0" if value else "-nodebug -O2")
 
 class Install:
 	def __init__(self, value):
 		self.string = "installed" if value else "in-tree"
-		self.flags  = """INSTALL_FLAGS="%s" """ % ("" if value else "-in-tree")
+		self.flags  = """INSTALL_FLAGS=%s""" % ("" if value else "-in-tree")
 
 class Timeouts:
@@ -112,22 +111,24 @@
 	global install
 	global timeout
+	global output_width
 
-	dry_run    = options.dry_run
-	generating = options.regenerate_expected
-	make       = 'make'
-	debug	     = Debug(options.debug)
-	install    = Install(options.install)
-	arch       = Architecture(options.arch)
-	timeout    = Timeouts(options.timeout, options.global_timeout)
+	dry_run      = options.dry_run
+	generating   = options.regenerate_expected
+	make         = ['make']
+	debug        = Debug(options.debug)
+	install      = Install(options.install)
+	arch         = Architecture(options.arch)
+	timeout      = Timeouts(options.timeout, options.global_timeout)
+	output_width = 24
 
 
-def updateMakeCmd(force, jobs):
+def update_make_cmd(force, jobs):
 	global make
 
-	make = "make" if not force else ("make -j%i" % jobs)
+	make = ['make'] if not force else ['make', "-j%i" % jobs]
 
 def validate():
 	errf = os.path.join(BUILDDIR, ".validate.err")
-	make_ret, _ = tools.make( ".validate", error_file = errf, redirects  = "2> /dev/null 1> /dev/null", )
+	make_ret, out = tools.make( ".validate", error_file = errf, output=subprocess.DEVNULL, error=subprocess.DEVNULL )
 	if make_ret != 0:
 		with open (errf, "r") as myfile:
@@ -139,2 +140,6 @@
 
 	tools.rm(errf)
+
+def prep_output(tests):
+	global output_width
+	output_width = max(map(lambda t: len(t.target()), tests))
Index: tests/pybin/test_run.py
===================================================================
--- tests/pybin/test_run.py	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/pybin/test_run.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -4,16 +4,4 @@
 
 import pybin.settings
-import datetime
-
-from string import Template
-
-class DeltaTemplate(Template):
-    delimiter = "%"
-
-def strfdelta(tdelta, fmt):
-    d["H"], rem = divmod(tdelta.seconds, 3600)
-    d["M"], d["S"] = divmod(rem, 60)
-    t = DeltaTemplate(fmt)
-    return t.substitute(**d)
 
 # Test class that defines what a test is
Index: tests/pybin/tools.py
===================================================================
--- tests/pybin/tools.py	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/pybin/tools.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -1,6 +1,5 @@
-from __future__ import print_function
-
 import __main__
 import argparse
+import contextlib
 import fileinput
 import multiprocessing
@@ -10,9 +9,11 @@
 import signal
 import stat
+import subprocess
 import sys
+import tempfile
 import time
+import types
 
 from pybin import settings
-from subprocess import Popen, PIPE, STDOUT
 
 ################################################################################
@@ -21,19 +22,47 @@
 
 # helper functions to run terminal commands
-def sh(cmd, print2stdout = True, input = None):
-	# add input redirection if needed
-	if input and os.path.isfile(input):
-		cmd += " < %s" % input
+def sh(*cmd, timeout = False, output = None, input = None, error = subprocess.STDOUT):
+	cmd = list(cmd)
 
 	# if this is a dry_run, only print the commands that would be ran
 	if settings.dry_run :
-		print("cmd: %s" % cmd)
+		cmd = "{} cmd: {}".format(os.getcwd(), ' '.join(cmd))
+		if output and not isinstance(output, int):
+			cmd += " > "
+			cmd += output
+
+		if error and not isinstance(error, int):
+			cmd += " 2> "
+			cmd += error
+
+		if input and not isinstance(input, int) and os.path.isfile(input):
+			cmd += " < "
+			cmd += input
+
+		print(cmd)
 		return 0, None
 
-	# otherwise create a pipe and run the desired command
-	else :
-		proc = Popen(cmd, stdout=None if print2stdout else PIPE, stderr=STDOUT, shell=True)
-		out, err = proc.communicate()
-		return proc.returncode, out
+	with contextlib.ExitStack() as onexit:
+		# add input redirection if needed
+		input = openfd(input, 'r', onexit, True)
+
+		# add output redirection if needed
+		output = openfd(output, 'w', onexit, False)
+
+		# add error redirection if needed
+		error = openfd(error, 'w', onexit, False)
+
+		# run the desired command
+		try:
+			proc = subprocess.run(
+				cmd,
+				stdin =input,
+				stdout=output,
+				stderr=error,
+				timeout=settings.timeout.single if timeout else None
+			)
+			return proc.returncode, proc.stdout.decode("utf-8") if proc.stdout else None
+		except subprocess.TimeoutExpired:
+			return 124, str(None)
 
 def is_ascii(fname):
@@ -45,5 +74,5 @@
 		return False
 
-	code, out = sh("file %s" % fname, print2stdout = False)
+	code, out = sh("file %s" % fname, output=subprocess.PIPE)
 	if code != 0:
 		return False
@@ -56,19 +85,34 @@
 	return match.group(1).startswith("ASCII text")
 
+def is_exe(fname):
+	return os.path.isfile(fname) and os.access(fname, os.X_OK)
+
+def openfd(file, mode, exitstack, checkfile):
+	if not file:
+		return file
+
+	if isinstance(file, int):
+		return file
+
+	if checkfile and not os.path.isfile(file):
+		return None
+
+	file = open(file, mode)
+	exitstack.push(file)
+	return file
+
 # Remove 1 or more files silently
 def rm( files ):
-	if isinstance( files, basestring ):
-		sh("rm -f %s > /dev/null 2>&1" % files )
-	else:
-		for file in files:
-			sh("rm -f %s > /dev/null 2>&1" % file )
+	if isinstance(files, str ): files = [ files ]
+	for file in files:
+		sh( 'rm', '-f', file, output=subprocess.DEVNULL, error=subprocess.DEVNULL )
 
 # Create 1 or more directory
 def mkdir( files ):
-	if isinstance( files, basestring ):
-		sh("mkdir -p %s" % os.path.dirname(files) )
-	else:
-		for file in files:
-			sh("mkdir -p %s" % os.path.dirname(file) )
+	if isinstance(files, str ): files = [ files ]
+	for file in files:
+		p = os.path.normpath( file )
+		d = os.path.dirname ( p )
+		sh( 'mkdir', '-p', d, output=subprocess.DEVNULL, error=subprocess.DEVNULL )
 
 
@@ -80,31 +124,26 @@
 # diff two files
 def diff( lhs, rhs ):
-	# diff the output of the files
-	diff_cmd = ("diff --text "
-#				"--ignore-all-space "
-#				"--ignore-blank-lines "
-				"--old-group-format='\t\tmissing lines :\n"
-				"%%<' \\\n"
-				"--new-group-format='\t\tnew lines :\n"
-				"%%>' \\\n"
-				"--unchanged-group-format='%%=' \\"
-				"--changed-group-format='\t\texpected :\n"
-				"%%<"
-				"\t\tgot :\n"
-				"%%>\n' \\\n"
-				"--new-line-format='\t\t%%dn\t%%L' \\\n"
-				"--old-line-format='\t\t%%dn\t%%L' \\\n"
-				"--unchanged-line-format='' \\\n"
-				"%s %s")
-
 	# fetch return code and error from the diff command
-	return sh(diff_cmd % (lhs, rhs), False)
+	return sh(
+		'''diff''',
+		'''--text''',
+		'''--old-group-format=\t\tmissing lines :\n%<''',
+		'''--new-line-format=\t\t%dn\t%L''',
+		'''--new-group-format=\t\tnew lines : \n%>''',
+		'''--old-line-format=\t\t%dn\t%L''',
+		'''--unchanged-group-format=%=''',
+		'''--changed-group-format=\t\texpected :\n%<\t\tgot :\n%>''',
+		'''--unchanged-line-format=''',
+		lhs,
+		rhs,
+		output=subprocess.PIPE
+	)
 
 # call make
-def make(target, flags = '', redirects = '', error_file = None, silent = False):
-	test_param = """test="%s" """ % (error_file) if error_file else ''
-	cmd = ' '.join([
-		settings.make,
-		'-s' if silent else '',
+def make(target, *, flags = '', output = None, error = None, error_file = None, silent = False):
+	test_param = """test="%s" """ % (error_file) if error_file else None
+	cmd = [
+		*settings.make,
+		'-s' if silent else None,
 		test_param,
 		settings.arch.flags,
@@ -112,14 +151,10 @@
 		settings.install.flags,
 		flags,
-		target,
-		redirects
-	])
-	return sh(cmd)
+		target
+	]
+	cmd = [s for s in cmd if s]
+	return sh(*cmd, output=output, error=error)
 
 def which(program):
-    import os
-    def is_exe(fpath):
-        return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
-
     fpath, fname = os.path.split(program)
     if fpath:
@@ -134,7 +169,13 @@
     return None
 
-def run(exe, output, input):
-	ret, _ = sh("timeout %d %s > %s 2>&1" % (settings.timeout.single, exe, output), input = input)
-	return ret
+@contextlib.contextmanager
+def tempdir():
+	cwd = os.getcwd()
+	with tempfile.TemporaryDirectory() as temp:
+		os.chdir(temp)
+		try:
+			yield temp
+		finally:
+			os.chdir(cwd)
 
 ################################################################################
@@ -143,10 +184,10 @@
 # move a file
 def mv(source, dest):
-	ret, _ = sh("mv %s %s" % (source, dest))
+	ret, _ = sh("mv", source, dest)
 	return ret
 
 # cat one file into the other
 def cat(source, dest):
-	ret, _ = sh("cat %s > %s" % (source, dest))
+	ret, _ = sh("cat", source, output=dest)
 	return ret
 
@@ -163,24 +204,13 @@
 
 # helper function to check if a files contains only a specific string
-def fileContainsOnly(file, text) :
+def file_contains_only(file, text) :
 	with open(file) as f:
 		ff = f.read().strip()
 		result = ff == text.strip()
 
-		return result;
-
-# check whether or not a file is executable
-def fileIsExecutable(file) :
-	try :
-		fileinfo = os.stat(file)
-		return bool(fileinfo.st_mode & stat.S_IXUSR)
-	except Exception as inst:
-		print(type(inst))    # the exception instance
-		print(inst.args)     # arguments stored in .args
-		print(inst)
-		return False
+		return result
 
 # transform path to canonical form
-def canonicalPath(path):
+def canonical_path(path):
 	abspath = os.path.abspath(__main__.__file__)
 	dname = os.path.dirname(abspath)
@@ -188,23 +218,20 @@
 
 # compare path even if form is different
-def pathCmp(lhs, rhs):
-	return canonicalPath( lhs ) == canonicalPath( rhs )
+def path_cmp(lhs, rhs):
+	return canonical_path( lhs ) == canonical_path( rhs )
 
 # walk all files in a path
-def pathWalk( op ):
-	def step(_, dirname, names):
+def path_walk( op ):
+	dname = settings.SRCDIR
+	for dirname, _, names in os.walk(dname):
 		for name in names:
 			path = os.path.join(dirname, name)
 			op( path )
 
-	# Start the walk
-	dname = settings.SRCDIR
-	os.path.walk(dname, step, '')
-
 ################################################################################
 #               system
 ################################################################################
 # count number of jobs to create
-def jobCount( options, tests ):
+def job_count( options, tests ):
 	# check if the user already passed in a number of jobs for multi-threading
 	if not options.jobs:
@@ -228,23 +255,4 @@
 	return min( options.jobs, len(tests) ), force
 
-# setup a proper processor pool with correct signal handling
-def setupPool(jobs):
-	original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
-	pool = multiprocessing.Pool(jobs)
-	signal.signal(signal.SIGINT, original_sigint_handler)
-
-	return pool
-
-# handle signals in scope
-class SignalHandling():
-	def __enter__(self):
-		# enable signal handling
-	    	signal.signal(signal.SIGINT, signal.SIG_DFL)
-
-	def __exit__(self, type, value, traceback):
-		# disable signal handling
-		signal.signal(signal.SIGINT, signal.SIG_IGN)
-
-
 # enable core dumps for all the test children
 resource.setrlimit(resource.RLIMIT_CORE, (resource.RLIM_INFINITY, resource.RLIM_INFINITY))
@@ -261,30 +269,27 @@
 		return False
 	raise argparse.ArgumentTypeError(msg)
-	return False
 
 def fancy_print(text):
 	column = which('column')
 	if column:
-		cmd = "%s 2> /dev/null" % column
-		proc = Popen(cmd, stdin=PIPE, stderr=None, shell=True)
-		proc.communicate(input=text + "\n")
+		subprocess.run(column, input=bytes(text + "\n", "UTF-8"))
 	else:
 		print(text)
 
 
-def coreInfo(path):
+def core_info(path):
+	if not os.path.isfile(path):
+		return 1, "ERR Executable path is wrong"
+
 	cmd   = os.path.join(settings.SRCDIR, "pybin/print-core.gdb")
 	if not os.path.isfile(cmd):
 		return 1, "ERR Printing format for core dumps not found"
 
-	dname = os.path.dirname(path)
-	core  = os.path.join(dname, "core" )
-	if not os.path.isfile(path):
-		return 1, "ERR Executable path is wrong"
+	core  = os.path.join(os.getcwd(), "core" )
 
 	if not os.path.isfile(core):
 		return 1, "ERR No core dump"
 
-	return sh("gdb -n %s %s -batch -x %s" % (path, core, cmd), print2stdout=False)
+	return sh('gdb', '-n', path, core, '-batch', '-x', cmd, output=subprocess.PIPE)
 
 class Timed:
Index: tests/raii/init_once.cfa
===================================================================
--- tests/raii/init_once.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/raii/init_once.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Tue Jun 14 15:43:35 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul  9 11:30:29 2016
-// Update Count     : 3
+// Last Modified On : Fri Mar 22 13:41:26 2019
+// Update Count     : 4
 //
 
@@ -192,4 +192,4 @@
 // Local Variables: //
 // tab-width: 4 //
-// compile-command: "cfa init_once.c" //
+// compile-command: "cfa init_once.cfa" //
 // End: //
Index: tests/rational.cfa
===================================================================
--- tests/rational.cfa	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/rational.cfa	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -10,6 +10,6 @@
 // Created On       : Mon Mar 28 08:43:12 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec  4 21:46:42 2018
-// Update Count     : 69
+// Last Modified On : Wed Mar 27 07:37:17 2019
+// Update Count     : 80
 //
 
@@ -19,8 +19,4 @@
 #include <fstream.hfa>
 
-// UNNECESSARY, FIX ME
-void ?{}( int & this ) { this = 0; }
-void ?{}( int & this, zero_t ) { this = 0; }
-void ?{}( int & this, one_t ) { this = 1; }
 double convert( int i ) { return (double)i; }
 int convert( double d ) { return (int)d; }
@@ -58,4 +54,6 @@
 	sout | a * b;
 	sout | a / b;
+//	sout | a \ 2 | b \ 2; // FIX ME
+//	sout | a \ -2 | b \ -2;
 
 	sout | "conversion";
Index: tests/test.py
===================================================================
--- tests/test.py	(revision 69c37ccfbd57ffcac000650a919c9708faf8c701)
+++ tests/test.py	(revision f343c6b9c8b5f408f8025426215c2bc3b3ba5ede)
@@ -1,4 +1,3 @@
-#!/usr/bin/python
-from __future__ import print_function
+#!/usr/bin/python3
 
 from pybin.tools import *
@@ -9,4 +8,5 @@
 import re
 import sys
+import tempfile
 import time
 
@@ -15,8 +15,8 @@
 ################################################################################
 
-def findTests():
+def find_tests():
 	expected = []
 
-	def matchTest(path):
+	def match_test(path):
 		match = re.search("^%s\/([\w\/\-_]*).expect\/([\w\-_]+)(\.[\w\-_]+)?\.txt$" % settings.SRCDIR, path)
 		if match :
@@ -28,12 +28,12 @@
 				expected.append(test)
 
-	pathWalk( matchTest )
+	path_walk( match_test )
 
 	return expected
 
 # reads the directory ./.expect and indentifies the tests
-def listTests( includes, excludes ):
+def list_tests( includes, excludes ):
 	# tests directly in the .expect folder will always be processed
-	test_list = findTests()
+	test_list = find_tests()
 
 	# if we have a limited number of includes, filter by them
@@ -52,5 +52,5 @@
 
 # from the found tests, filter all the valid tests/desired tests
-def validTests( options ):
+def valid_tests( options ):
 	tests = []
 
@@ -59,7 +59,7 @@
 	if options.regenerate_expected :
 		for testname in options.tests :
-			testname = canonicalPath( testname )
+			testname = canonical_path( testname )
 			if Test.valid_name(testname):
-				found = [test for test in allTests if canonicalPath( test.target() ) == testname]
+				found = [test for test in all_tests if canonical_path( test.target() ) == testname]
 				tests.append( found[0] if len(found) == 1 else Test.from_target(testname) )
 			else :
@@ -69,5 +69,5 @@
 		# otherwise we only need to validate that all tests are present in the complete list
 		for testname in options.tests:
-			test = [t for t in allTests if pathCmp( t.target(), testname )]
+			test = [t for t in all_tests if path_cmp( t.target(), testname )]
 
 			if test :
@@ -79,5 +79,5 @@
 
 # parses the option
-def getOptions():
+def parse_args():
 	# create a parser with the arguments for the tests script
 	parser = argparse.ArgumentParser(description='Script which runs cforall tests')
@@ -102,5 +102,5 @@
 		print('ERROR: invalid arguments', file=sys.stderr)
 		parser.print_help(sys.stderr)
-    		sys.exit(1)
+		sys.exit(1)
 
 	# script must have at least some tests to run or be listing
@@ -112,5 +112,5 @@
 	# check that exactly one of the booleans is set to true
 	if not sum( (listing, all_tests, some_tests, some_dirs) ) > 0 :
-		print('ERROR: must have option \'--all\', \'--list\', \'--include\', \'-I\' or non-empty test list', file=sys.stderr)
+		print('''ERROR: must have option '--all', '--list', '--include', '-I' or non-empty test list''', file=sys.stderr)
 		parser.print_help()
 		sys.exit(1)
@@ -124,9 +124,6 @@
 	return val == 0 or settings.dry_run
 
-def isExe(file):
-	return settings.dry_run or fileIsExecutable(file)
-
-def noRule(file, target):
-	return not settings.dry_run and fileContainsOnly(file, "make: *** No rule to make target `%s'.  Stop." % target)
+def no_rule(file, target):
+	return not settings.dry_run and file_contains_only(file, "make: *** No rule to make target `%s'.  Stop." % target)
 
 # logic to run a single test and return the result (No handling of printing or other test framework logic)
@@ -145,38 +142,40 @@
 	# build, skipping to next test on error
 	with Timed() as comp_dur:
-		make_ret, _ = make( test.target(), 	redirects  = ("2> %s 1> /dev/null" % out_file), error_file = err_file )
-
-	# if the make command succeds continue otherwise skip to diff
+		make_ret, _ = make( test.target(), output=subprocess.DEVNULL, error=out_file, error_file = err_file )
+
 	run_dur = None
-	if success(make_ret):
-		with Timed() as run_dur:
-			if isExe(exe_file):
-				# run test
-				retcode = run(exe_file, out_file, in_file)
+	# run everything in a temp directory to make sure core file are handled properly
+	with tempdir():
+		# if the make command succeds continue otherwise skip to diff
+		if success(make_ret):
+			with Timed() as run_dur:
+				if settings.dry_run or is_exe(exe_file):
+					# run test
+					retcode, _ = sh(exe_file, output=out_file, input=in_file, timeout=True)
+				else :
+					# simply cat the result into the output
+					retcode = cat(exe_file, out_file)
+		else:
+			retcode = mv(err_file, out_file)
+
+		if success(retcode):
+			if settings.generating :
+				# if we are ounly generating the output we still need to check that the test actually exists
+				if no_rule(out_file, test.target()) :
+					retcode = 1
+					error = "\t\tNo make target for test %s!" % test.target()
+					rm(out_file)
+				else:
+					error = None
 			else :
-				# simply cat the result into the output
-				retcode = cat(exe_file, out_file)
-	else:
-		retcode = mv(err_file, out_file)
-
-	if success(retcode):
-		if settings.generating :
-			# if we are ounly generating the output we still need to check that the test actually exists
-			if noRule(out_file, test.target()) :
-				retcode = 1
-				error = "\t\tNo make target for test %s!" % test.target()
-				rm(out_file)
-			else:
-				error = None
-		else :
-			# fetch return code and error from the diff command
-			retcode, error = diff(cmp_file, out_file)
-
-	else:
-		with open (out_file, "r") as myfile:
-			error = myfile.read()
-
-		ret, info = coreInfo(exe_file)
-		error = error + info
+				# fetch return code and error from the diff command
+				retcode, error = diff(cmp_file, out_file)
+
+		else:
+			with open (out_file, "r") as myfile:
+				error = myfile.read()
+
+			ret, info = core_info(exe_file)
+			error = error + info if error else info
 
 
@@ -189,8 +188,7 @@
 # run a single test and handle the errors, outputs, printing, exception handling, etc.
 def run_test_worker(t) :
-
-	with SignalHandling():
+	try :
 		# print formated name
-		name_txt = "%24s  " % t.name
+		name_txt = '{0:{width}}  '.format(t.target(), width=settings.output_width)
 
 		retcode, error, duration = run_single_test(t)
@@ -200,8 +198,8 @@
 
 		#print result with error if needed
-		text = name_txt + result_txt
+		text = '\t' + name_txt + result_txt
 		out = sys.stdout
 		if error :
-			text = text + "\n" + error
+			text = text + '\n' + error
 			out = sys.stderr
 
@@ -210,13 +208,15 @@
 		sys.stderr.flush()
 
-	return retcode != TestResult.SUCCESS
+		return retcode != TestResult.SUCCESS
+	except KeyboardInterrupt:
+		False
 
 # run the given list of tests with the given parameters
 def run_tests(tests, jobs) :
 	# clean the sandbox from previous commands
-	make('clean', redirects = '> /dev/null 2>&1')
+	make('clean', output=subprocess.DEVNULL, error=subprocess.DEVNULL)
 
 	# create the executor for our jobs and handle the signal properly
-	pool = setupPool(jobs)
+	pool = multiprocessing.Pool(jobs)
 
 	# for each test to run
@@ -233,5 +233,5 @@
 
 	# clean the workspace
-	make('clean', redirects = '> /dev/null 2>&1')
+	make('clean', output=subprocess.DEVNULL, error=subprocess.DEVNULL)
 
 	for failed in results:
@@ -248,5 +248,5 @@
 
 	# parse the command line arguments
-	options = getOptions()
+	options = parse_args()
 
 	# init global settings
@@ -254,14 +254,14 @@
 
 	# fetch the liest of all valid tests
-	allTests = listTests( options.include, options.exclude )
+	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.list or options.list_comp or options.include :
-		tests = allTests
+		tests = all_tests
 
 	#otherwise we need to validate that the test list that was entered is valid
 	else :
-		tests = validTests( options )
+		tests = valid_tests( options )
 
 	# make sure we have at least some test to run
@@ -281,18 +281,20 @@
 	elif options.list :
 		print("Listing for %s:%s"% (settings.arch.string, settings.debug.string))
-		fancy_print("\n".join(map(lambda t: "%s" % (t.toString()), tests)))
+		fancy_print("\n".join(map(lambda t: t.toString(), tests)))
 
 	else :
 		# check the build configuration works
+		settings.prep_output(tests)
 		settings.validate()
 
-		options.jobs, forceJobs = jobCount( options, tests )
-		settings.updateMakeCmd(forceJobs, options.jobs)
-
-		print('%s (%s:%s) on %i cores' % (
-			'Regenerate tests' if settings.generating else 'Running',
+		options.jobs, forceJobs = job_count( options, tests )
+		settings.update_make_cmd(forceJobs, options.jobs)
+
+		print('%s %i tests on %i cores (%s:%s)' % (
+			'Regenerating' if settings.generating else 'Running',
+			len(tests),
+			options.jobs,
 			settings.arch.string,
-			settings.debug.string,
-			options.jobs
+			settings.debug.string
 		))
 
