Index: Jenkins/FullBuild
===================================================================
--- Jenkins/FullBuild	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ Jenkins/FullBuild	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -32,5 +32,5 @@
 
 			stage('Package') {
-				trigger_dist( commitId, currentBuild.number.toString() )
+				build job: 'Cforall_Distribute_Ref', parameters: [string(name: 'GitRef', value: commitId), string(name: 'Build', value: currentBuild.number.toString())]
 			}
 		}
@@ -103,20 +103,4 @@
 }
 
-def trigger_dist(String commitId, String buildNum) {
-	def result = build job: 'Cforall_Distribute_Ref',	\
-		parameters: [						\
-			string(name: 'GitRef', value: commitId),	\
-			string(name: 'Build' , value: buildNum)	\
-		],								\
-		propagate: false
-
-	echo(result.result)
-
-	if(result.result != 'SUCCESS') {
-		sh("wget -q -O - https://cforall.uwaterloo.ca/jenkins/job/Cforall_Distribute_Ref/${result.number}/consoleText")
-		error(result.result)
-	}
-}
-
 //===========================================================================================================
 //Routine responsible of sending the email notification once the build is completed
Index: Jenkins/tools.groovy
===================================================================
--- Jenkins/tools.groovy	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ Jenkins/tools.groovy	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -6,8 +6,12 @@
 import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
 
+// Global for the stage name
+StageName = ''
+
 // wrapper around stage declaretion to be more verbose
 // and allow showing as skipped in the UI
 def BuildStage(String name, boolean run, Closure block ) {
-	echo " -------- ${name} -------- "
+	StageName = name
+	echo " -------- ${StageName} -------- "
 	if(run) {
 		stage(name, block)
Index: Jenkinsfile
===================================================================
--- Jenkinsfile	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ Jenkinsfile	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -54,15 +54,14 @@
 	//attach the build log to the email
 	catch (Exception caughtError) {
-		// Store the result of the build log
-		currentBuild.result = "FAILURE"
-
-		// An error has occured, the build log is relevent
+		//rethrow error later
+		err = caughtError
+
+		echo err.toString()
+
+		//An error has occured, the build log is relevent
 		log_needed = true
 
-		// rethrow error later
-		err = caughtError
-
-		// print the error so it shows in the log
-		echo err.toString()
+		//Store the result of the build log
+		currentBuild.result = "${tools.StageName} FAILURE".trim()
 	}
 
Index: nchmark/Cargo.toml.in
===================================================================
--- benchmark/Cargo.toml.in	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,25 +1,0 @@
-[package]
-name = "cforall-rust-bench"
-version = "@VERSION@"
-authors = ["Cforall"]
-edition = "2018"
-
-[[bin]]
-name = "cycle-tokio"
-path = "@abs_srcdir@/readyQ/cycle.rs"
-
-[[bin]]
-name = "locality-tokio"
-path = "@abs_srcdir@/readyQ/locality.rs"
-
-[features]
-sync = ["tokio/sync"]
-time = ["tokio/time"]
-
-[dependencies]
-clap = "2.33"
-isatty = "0.1"
-num-format = "0.4.0"
-rand = "*"
-tokio = { version = "0.3.0", features = ["full"] }
-
Index: benchmark/Makefile.am
===================================================================
--- benchmark/Makefile.am	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ benchmark/Makefile.am	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -522,8 +522,2 @@
 size-cfa$(EXEEXT):
 	$(BENCH_V_CFA)$(CFACOMPILE) $(srcdir)/size/size.cfa
-
-## =========================================================================================================
-
-%-tokio$(EXEEXT): $(srcdir)/readyQ/%.rs $(srcdir)/bench.rs
-	cd $(builddir) && cargo build --release
-	cp $(builddir)/target/release/$(basename $@) $@
Index: nchmark/bench.rs
===================================================================
--- benchmark/bench.rs	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,70 +1,0 @@
-use std::io::{self, Write};
-use std::sync::atomic::{AtomicU64, AtomicBool, Ordering};
-use std::time::{Instant,Duration};
-
-use clap::{Arg, ArgMatches};
-use isatty::stdout_isatty;
-
-use tokio::time;
-
-
-// ==================================================
-pub fn args<'a, 'b>() -> [Arg<'a, 'b>; 4] {[
-	Arg::with_name("duration")  .short("d").long("duration")  .takes_value(true).default_value("5").help("Duration of the experiments in seconds"),
-	Arg::with_name("iterations").short("i").long("iterations").takes_value(true).conflicts_with("duration").help("Number of iterations of the experiments"),
-	Arg::with_name("nthreads")  .short("t").long("nthreads")  .takes_value(true).default_value("1").help("Number of threads to use"),
-	Arg::with_name("nprocs")    .short("p").long("nprocs")    .takes_value(true).default_value("1").help("Number of processors to use")
-]}
-
-pub struct BenchData {
-	pub clock_mode: bool,
-	pub stop: AtomicBool,
-	pub stop_count: u64,
-	pub duration: f64,
-	pub threads_left: AtomicU64,
-	is_tty: bool,
-}
-
-impl BenchData {
-	pub fn new(options: ArgMatches, nthreads: usize) -> BenchData {
-		let (clock_mode, stop_count, duration) = if options.is_present("iterations") {
-			(false,
-			options.value_of("iterations").unwrap().parse::<u64>().unwrap(),
-			-1.0)
-		} else {
-			(true,
-			std::u64::MAX,
-			options.value_of("duration").unwrap().parse::<f64>().unwrap())
-		};
-
-		BenchData{
-			clock_mode: clock_mode,
-			stop: AtomicBool::new(false),
-			stop_count: stop_count,
-			duration: duration,
-			threads_left: AtomicU64::new(nthreads as u64),
-			is_tty: stdout_isatty(),
-		}
-	}
-
-	pub async fn wait(&self, start: &Instant) -> Duration{
-		loop {
-			time::sleep(Duration::from_micros(100000)).await;
-			let delta = start.elapsed();
-			if self.is_tty {
-				print!(" {:.1}\r", delta.as_secs_f32());
-				io::stdout().flush().unwrap();
-			}
-			if self.clock_mode && delta >= Duration::from_secs_f64(self.duration)  {
-				break;
-			}
-			else if !self.clock_mode && self.threads_left.load(Ordering::Relaxed) == 0 {
-				break;
-			}
-		}
-
-		self.stop.store(true, Ordering::SeqCst);
-		return start.elapsed();
-	}
-}
-
Index: benchmark/creation/node_cor.js
===================================================================
--- benchmark/creation/node_cor.js	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ benchmark/creation/node_cor.js	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -6,5 +6,5 @@
 function * coroutine() { yield }
 
-for ( var i = 0; i < times; i += 1 ) { // warm JIT
+for ( var i = 0; i < times; i += 1 ) { // warm jit
 	cor = coroutine()
 }
Index: benchmark/ctxswitch/node_cor.js
===================================================================
--- benchmark/ctxswitch/node_cor.js	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ benchmark/ctxswitch/node_cor.js	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -11,5 +11,5 @@
 cor = coroutine()
 
-for ( var i = 0; i < times; i += 1 ) { // warm JIT
+for ( var i = 0; i < times; i += 1 ) { // warm git
 	cor.next();
 }
Index: benchmark/readyQ/bench.go
===================================================================
--- benchmark/readyQ/bench.go	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ benchmark/readyQ/bench.go	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -5,8 +5,6 @@
 	"flag"
 	"fmt"
-	"log"
 	"os"
 	"runtime"
-	"runtime/pprof"
 	"sync/atomic"
 	"time"
@@ -45,10 +43,9 @@
 }
 
-func bench_init() func() {
+func bench_init() {
 	nprocsOpt := flag.Int("p", 1, "The number of processors")
 	nthreadsOpt := flag.Int("t", 1, "The number of threads")
 	durationOpt := flag.Float64("d", 0, "Duration of the experiment in seconds")
 	stopOpt := flag.Uint64("i", 0, "Duration of the experiment in iterations")
-	cpuprofile := flag.String("cpuprofile", "", "write cpu profile to file")
 
 	flag.Parse()
@@ -75,17 +72,3 @@
 
 	runtime.GOMAXPROCS(nprocs)
-
-	if (*cpuprofile) != "" {
-		f, err := os.Create(*cpuprofile)
-		if err != nil {
-		    log.Fatal(err)
-		}
-		pprof.StartCPUProfile(f)
-	}
-
-	return func() {
-		if (*cpuprofile) != "" {
-			pprof.StopCPUProfile()
-		}
-	}
 }
Index: benchmark/readyQ/cycle.cpp
===================================================================
--- benchmark/readyQ/cycle.cpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ benchmark/readyQ/cycle.cpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -71,5 +71,5 @@
 		{ 'r', "ringsize", "Number of threads in a cycle", ring_size }
 	};
-	BENCH_OPT_PARSE("libfibre cycle benchmark");
+	BENCH_OPT_PARSE("cforall cycle benchmark");
 
 	{
Index: benchmark/readyQ/cycle.rs
===================================================================
--- benchmark/readyQ/cycle.rs	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ benchmark/readyQ/cycle.rs	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -1,16 +1,67 @@
+#[cfg(any(
+	feature = "sync time rt-threaded",
+  ))]
+
+extern crate tokio;
+
+use std::io::{self, Write};
 use std::sync::Arc;
-use std::sync::atomic::Ordering;
-use std::time::Instant;
+use std::sync::atomic::{AtomicU64, AtomicBool,Ordering};
+use std::time::{Instant,Duration};
 
 use tokio::runtime::Builder;
 use tokio::sync;
-
+use tokio::time;
+
+extern crate isatty;
+use isatty::stdout_isatty;
+
+extern crate num_format;
+use num_format::{Locale, ToFormattedString};
+
+extern crate clap;
 use clap::{Arg, App};
-use num_format::{Locale, ToFormattedString};
-
-#[path = "../bench.rs"]
-mod bench;
-
-// ==================================================
+
+use std::cell::UnsafeCell;
+use std::mem::MaybeUninit;
+use std::ops;
+
+pub struct InitializeCell<T> {
+    inner: UnsafeCell<MaybeUninit<T>>,
+}
+
+unsafe impl<T> Sync for InitializeCell<T> {}
+
+impl<T> InitializeCell<T> {
+    pub const unsafe fn new_uninitialized() -> InitializeCell<T> {
+	  InitializeCell {
+		inner: UnsafeCell::new(MaybeUninit::uninit()),
+	  }
+    }
+    pub const fn new(init: T) -> InitializeCell<T> {
+	  InitializeCell {
+		inner: UnsafeCell::new(MaybeUninit::new(init)),
+	  }
+    }
+    pub unsafe fn init(&self, init: T) {
+	  (*self.inner.get()) = MaybeUninit::new(init);
+    }
+}
+
+impl<T> ops::Deref for InitializeCell<T> {
+    type Target = T;
+    fn deref(&self) -> &T {
+	  unsafe {
+		&*(*self.inner.get()).as_ptr()
+	  }
+    }
+}
+
+static CLOCK_MODE: InitializeCell<bool> = unsafe { InitializeCell::new_uninitialized() };
+static STOP_COUNT: InitializeCell<u64>  = unsafe { InitializeCell::new_uninitialized() };
+static DURATION: InitializeCell<f64>    = unsafe { InitializeCell::new_uninitialized() };
+static STOP         : AtomicBool = AtomicBool::new(false);
+static THREADS_LEFT : AtomicU64  = AtomicU64 ::new(10);
+
 struct Partner {
 	sem: sync::Semaphore,
@@ -18,5 +69,5 @@
 }
 
-async fn partner_main(idx: usize, others: Arc<Vec<Arc<Partner>>>, exp: Arc<bench::BenchData> ) -> u64 {
+async fn partner_main(result: sync::oneshot::Sender<u64>, idx: usize, others: Arc<Vec<Arc<Partner>>> ) {
 	let this = &others[idx];
 	let mut count:u64 = 0;
@@ -26,16 +77,47 @@
 		count += 1;
 
-		if  exp.clock_mode && exp.stop.load(Ordering::Relaxed) { break; }
-		if !exp.clock_mode && count >= exp.stop_count { break; }
-	}
-
-	exp.threads_left.fetch_sub(1, Ordering::SeqCst);
-	count
-}
-
-// ==================================================
+		if  *CLOCK_MODE && STOP.load(Ordering::Relaxed) { break; }
+		if !*CLOCK_MODE && count >= *STOP_COUNT { break; }
+	}
+
+	THREADS_LEFT.fetch_sub(1, Ordering::SeqCst);
+	result.send( count ).unwrap();
+}
+
+fn prep(nthreads: usize, tthreads: usize) -> Vec<Arc<Partner>> {
+	let mut thddata = Vec::with_capacity(tthreads);
+	for i in 0..tthreads {
+		let pi = (i + nthreads) % tthreads;
+		thddata.push(Arc::new(Partner{
+			sem: sync::Semaphore::new(0),
+			next: pi,
+		}));
+	}
+	return thddata;
+}
+
+async fn wait(start: &Instant, is_tty: bool) {
+	loop {
+		time::sleep(Duration::from_micros(100000)).await;
+		let delta = start.elapsed();
+		if is_tty {
+			print!(" {:.1}\r", delta.as_secs_f32());
+			io::stdout().flush().unwrap();
+		}
+		if *CLOCK_MODE && delta >= Duration::from_secs_f64(*DURATION)  {
+			break;
+		}
+		else if !*CLOCK_MODE && THREADS_LEFT.load(Ordering::Relaxed) == 0 {
+			break;
+		}
+	}
+}
+
 fn main() {
 	let options = App::new("Cycle Tokio")
-		.args(&bench::args())
+		.arg(Arg::with_name("duration")  .short("d").long("duration")  .takes_value(true).default_value("5").help("Duration of the experiments in seconds"))
+		.arg(Arg::with_name("iterations").short("i").long("iterations").takes_value(true).conflicts_with("duration").help("Number of iterations of the experiments"))
+		.arg(Arg::with_name("nthreads")  .short("t").long("nthreads")  .takes_value(true).default_value("1").help("Number of threads to use"))
+		.arg(Arg::with_name("nprocs")    .short("p").long("nprocs")    .takes_value(true).default_value("1").help("Number of processors to use"))
 		.arg(Arg::with_name("ringsize")  .short("r").long("ringsize")  .takes_value(true).default_value("1").help("Number of threads in a cycle"))
 		.get_matches();
@@ -45,19 +127,24 @@
 	let nprocs    = options.value_of("nprocs").unwrap().parse::<usize>().unwrap();
 
-	let tthreads = nthreads * ring_size;
-	let exp = Arc::new(bench::BenchData::new(options, tthreads));
+	if options.is_present("iterations") {
+		unsafe{
+			CLOCK_MODE.init( false );
+			STOP_COUNT.init( options.value_of("iterations").unwrap().parse::<u64>().unwrap() );
+		}
+	}
+	else {
+		unsafe{
+			CLOCK_MODE.init(true);
+			DURATION  .init(options.value_of("duration").unwrap().parse::<f64>().unwrap());
+		}
+	}
 
 	let s = (1000000 as u64).to_formatted_string(&Locale::en);
 	assert_eq!(&s, "1,000,000");
 
-	let thddata : Arc<Vec<Arc<Partner>>> = Arc::new(
-		(0..tthreads).map(|i| {
-			let pi = (i + nthreads) % tthreads;
-			Arc::new(Partner{
-				sem: sync::Semaphore::new(0),
-				next: pi,
-			})
-		}).collect()
-	);
+
+	let tthreads = nthreads * ring_size;
+	THREADS_LEFT.store(tthreads as u64, Ordering::SeqCst);
+	let thddata = Arc::new(prep(nthreads, tthreads));
 
 	let mut global_counter :u64 = 0;
@@ -70,25 +157,35 @@
 
 	runtime.block_on(async {
-		let threads: Vec<_> = (0..tthreads).map(|i| {
-			tokio::spawn(partner_main(i, thddata.clone(), exp.clone()))
-		}).collect();
-		println!("Starting");
-
-		let start = Instant::now();
-
-		for i in 0..nthreads {
-			thddata[i].sem.add_permits(1);
-		}
-
-		duration = exp.wait(&start).await;
-
-		println!("\nDone");
-
-		for i in 0..tthreads {
-			thddata[i].sem.add_permits(1);
-		}
-
-		for t in threads {
-			global_counter += t.await.unwrap();
+		let mut result  : Vec<sync::oneshot::Receiver::<u64>> = Vec::with_capacity(tthreads);
+		{
+			let mut threads = Vec::with_capacity(tthreads);
+			for i in 0..tthreads {
+				let (s, r) = sync::oneshot::channel::<u64>();
+				result.push(r);
+				threads.push(tokio::spawn(partner_main(s, i, thddata.clone())));
+			}
+			println!("Starting");
+
+			let is_tty = stdout_isatty();
+			let start = Instant::now();
+
+			for i in 0..nthreads {
+				thddata[i].sem.add_permits(1);
+			}
+
+			wait(&start, is_tty).await;
+
+			STOP.store(true, Ordering::SeqCst);
+			duration = start.elapsed();
+
+			println!("\nDone");
+
+			for i in 0..tthreads {
+				thddata[i].sem.add_permits(1);
+			}
+
+			for _ in 0..tthreads {
+				global_counter += result.pop().unwrap().await.unwrap();
+			}
 		}
 	});
Index: nchmark/readyQ/locality.cfa
===================================================================
--- benchmark/readyQ/locality.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,285 +1,0 @@
-#include "rq_bench.hfa"
-
-struct Result {
-	uint64_t count;
-	uint64_t dmigs;
-	uint64_t gmigs;
-};
-
-// ==================================================
-thread __attribute__((aligned(128))) MyThread {
-	struct MyData * volatile data;
-
-	struct {
-		struct MySpot ** ptr;
-		size_t len;
-	} spots;
-
-	bench_sem sem;
-
-	Result result;
-
-	bool share;
-	size_t cnt;
-	processor * ttid;
-	size_t id;
-};
-
-uint64_t moved(MyThread & this, processor * ttid) {
-	if(this.ttid == ttid) {
-		return 0;
-	}
-	this.ttid = ttid;
-	return 1;
-}
-
-// ==================================================
-struct __attribute__((aligned(128))) MyData {
-	uint64_t _p1[16];  // padding
-	uint64_t * data;
-	size_t len;
-	processor * ttid;
-	size_t id;
-	uint64_t _p2[16];  // padding
-};
-
-void ?{}(MyData & this, size_t id, size_t size) {
-	this.len = size;
-	this.data = alloc(this.len, 128`align);
-	this.ttid = active_processor();
-	this.id = id;
-
-	for(i; this.len) {
-		this.data[i] = 0;
-	}
-}
-
-uint64_t moved(MyData & this, processor * ttid) {
-	if(this.ttid == ttid) {
-		return 0;
-	}
-	this.ttid = ttid;
-	return 1;
-}
-
-__attribute__((noinline)) void access(MyData & this, size_t idx) {
-	size_t l = this.len;
-	this.data[idx % l] += 1;
-}
-
-// ==================================================
-// Atomic object where a single thread can wait
-// May exchanges data
-struct __attribute__((aligned(128))) MySpot {
-	MyThread * volatile ptr;
-	size_t id;
-	uint64_t _p1[16];  // padding
-};
-
-void ?{}(MySpot & this, size_t id) {
-	this.ptr = 0p;
-	this.id  = id;
-}
-
-// Main handshake of the code
-// Single seat, first thread arriving waits
-// Next threads unblocks current one and blocks in its place
-// if share == true, exchange data in the process
-bool put( MySpot & this, MyThread & ctx, MyData * data, bool share) {
-	// Attempt to CAS our context into the seat
-	for() {
-		MyThread * expected = this.ptr;
-		if (expected == 1p) { // Seat is closed, return
-			return true;
-		}
-
-		if (__atomic_compare_exchange_n(&this.ptr, &expected, &ctx, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
-			if(expected) {
-				if(share) {
-					expected->data = data;
-				}
-				post( expected->sem );
-			}
-			break; // We got the seat
-		}
-	}
-
-	// Block once on the seat
-	wait(ctx.sem);
-
-	// Someone woke us up, get the new data
-	return false;
-}
-
-// Shutdown the spot
-// Wake current thread and mark seat as closed
-void release( MySpot & this ) {
-	MyThread * val = __atomic_exchange_n(&this.ptr, 1p, __ATOMIC_SEQ_CST);
-	if (!val) {
-		return;
-	}
-
-	// Someone was there, release them
-	post( val->sem );
-}
-
-// ==================================================
-// Do some work by accessing 'cnt' cells in the array
-__attribute__((noinline)) void work(MyData & data, size_t cnt, uint64_t & state) {
-	for (cnt) {
-		access(data, __xorshift64(state));
-	}
-}
-
-void main(MyThread & this) {
-	uint64_t state = thread_rand();
-
-	// Wait for start
-	wait(this.sem);
-
-	// Main loop
-	for() {
-		// Touch our current data, write to invalidate remote cache lines
-		work(*this.data, this.cnt, state);
-
-		// Wait on a random spot
-		uint64_t idx = __xorshift64(state) % this.spots.len;
-		bool closed = put(*this.spots.ptr[idx], this, this.data, this.share);
-
-		// Check if the experiment is over
-		if (closed) break;
-		if ( clock_mode && stop) break;
-		if (!clock_mode && this.result.count >= stop_count) break;
-
-		// Check everything is consistent
-		verify(this.data);
-
-		// write down progress and check migrations
-		processor * ttid = active_processor();
-		this.result.count += 1;
-		this.result.gmigs += moved(this, ttid);
-		this.result.dmigs += moved(*this.data, ttid);
-	}
-
-	__atomic_fetch_add(&threads_left, -1, __ATOMIC_SEQ_CST);
-}
-
-void ?{}( MyThread & this, MyData * data, MySpot ** spots, size_t spot_len, size_t cnt, bool share, size_t id) {
-	((thread&)this){ bench_cluster };
-	this.data = data;
-	this.spots.ptr = spots;
-	this.spots.len = spot_len;
-	(this.sem){};
-	this.result.count = 0;
-	this.result.gmigs = 0;
-	this.result.dmigs = 0;
-	this.share = share;
-	this.cnt = cnt;
-	this.ttid = active_processor();
-	this.id = id;
-}
-
-// ==================================================
-int main(int argc, char * argv[]) {
-	unsigned wsize = 2;
-	unsigned wcnt  = 2;
-	unsigned nspots = 0;
-	bool share = false;
-	cfa_option opt[] = {
-		BENCH_OPT,
-		{ 'n', "nspots", "Number of spots where threads sleep (nthreads - nspots are active at the same time)", nspots},
-		{ 'w', "worksize", "Size of the array for each threads, in words (64bit)", wsize},
-		{ 'c', "workcnt" , "Number of words to touch when working (random pick, cells can be picked more than once)", wcnt },
-		{ 's', "share"   , "Pass the work data to the next thread when blocking", share, parse_truefalse }
-	};
-	BENCH_OPT_PARSE("cforall cycle benchmark");
-
-	unsigned long long global_count = 0;
-	unsigned long long global_gmigs = 0;
-	unsigned long long global_dmigs = 0;
-
-	if( nspots == 0 ) { nspots = nthreads - nprocs; }
-
-	Time start, end;
-	{
-		MyData * data_arrays[nthreads];
-		for(i; nthreads) {
-			data_arrays[i] = malloc();
-			(*data_arrays[i]){ i, wsize };
-		}
-
-		MySpot * spots[nspots];
-		for(i; nspots) {
-			spots[i] = malloc();
-			(*spots[i]){ i };
-		}
-
-		BenchCluster bc = { nprocs };
-		threads_left = nprocs;
-		{
-			MyThread * threads[nthreads];
-			for(i; nthreads) {
-				threads[i] = malloc();
-				(*threads[i]){
-					data_arrays[i],
-					spots,
-					nspots,
-					wcnt,
-					share,
-					i
-				};
-			}
-
-			bool is_tty = isatty(STDOUT_FILENO);
-			start = getTimeNsec();
-
-			for(i; nthreads) {
-				post( threads[i]->sem );
-			}
-			wait(start, is_tty);
-
-			stop = true;
-			end = getTimeNsec();
-			printf("\nDone\n");
-
-			for(i; nthreads) {
-				post( threads[i]->sem );
-				MyThread & thrd = join( *threads[i] );
-				global_count += thrd.result.count;
-				global_gmigs += thrd.result.gmigs;
-				global_dmigs += thrd.result.dmigs;
-			}
-
-			for(i; nthreads) {
-				^( *threads[i] ){};
-				free( threads[i] );
-			}
-		}
-
-		for(i; nthreads) {
-			^( *data_arrays[i] ){};
-			free( data_arrays[i] );
-		}
-
-		for(i; nspots) {
-			^( *spots[i] ){};
-			free( spots[i] );
-		}
-	}
-
-	printf("Duration (ms)          : %'lf\n", (end - start)`dms);
-	printf("Number of processors   : %'d\n", nprocs);
-	printf("Number of threads      : %'d\n", nthreads);
-	printf("Total Operations(ops)  : %'15llu\n", global_count);
-	printf("Work size (64bit words): %'15u\n", wsize);
-	printf("Total Operations(ops)  : %'15llu\n", global_count);
-	printf("Total G Migrations     : %'15llu\n", global_gmigs);
-	printf("Total D Migrations     : %'15llu\n", global_dmigs);
-	printf("Ops per second         : %'18.2lf\n", ((double)global_count) / (end - start)`ds);
-	printf("ns per ops             : %'18.2lf\n", (end - start)`dns / global_count);
-	printf("Ops per threads        : %'15llu\n", global_count / nthreads);
-	printf("Ops per procs          : %'15llu\n", global_count / nprocs);
-	printf("Ops/sec/procs          : %'18.2lf\n", (((double)global_count) / nprocs) / (end - start)`ds);
-	printf("ns per ops/procs       : %'18.2lf\n", (end - start)`dns / (global_count / nprocs));
-	fflush(stdout);
-}
Index: nchmark/readyQ/locality.cpp
===================================================================
--- benchmark/readyQ/locality.cpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,333 +1,0 @@
-#include "rq_bench.hpp"
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-	#include <libfibre/fibre.h>
-#pragma GCC diagnostic pop
-
-struct Result {
-	uint64_t count = 0;
-	uint64_t dmigs = 0;
-	uint64_t gmigs = 0;
-};
-
-class __attribute__((aligned(128))) bench_sem {
-	Fibre * volatile ptr = nullptr;
-public:
-	inline bool wait() {
-		static Fibre * const ready  = reinterpret_cast<Fibre * const>(1ull);
-		for(;;) {
-			Fibre * expected = this->ptr;
-			if(expected == ready) {
-				if(__atomic_compare_exchange_n(&this->ptr, &expected, nullptr, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
-					return false;
-				}
-			}
-			else {
-				/* paranoid */ assert( expected == nullptr );
-				if(__atomic_compare_exchange_n(&this->ptr, &expected, fibre_self(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
-					fibre_park();
-					return true;
-				}
-			}
-
-		}
-	}
-
-	inline bool post() {
-		static Fibre * const ready  = reinterpret_cast<Fibre * const>(1ull);
-		for(;;) {
-			Fibre * expected = this->ptr;
-			if(expected == ready) return false;
-			if(expected == nullptr) {
-				if(__atomic_compare_exchange_n(&this->ptr, &expected, ready, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
-					return false;
-				}
-			}
-			else {
-				if(__atomic_compare_exchange_n(&this->ptr, &expected, nullptr, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
-					fibre_unpark( expected );
-					return true;
-				}
-			}
-		}
-	}
-};
-
-// ==================================================
-struct __attribute__((aligned(128))) MyData {
-	uint64_t _p1[16];  // padding
-	uint64_t * data;
-	size_t len;
-	BaseProcessor * ttid;
-	size_t id;
-	uint64_t _p2[16];  // padding
-
-	MyData(size_t id, size_t size)
-		: data( (uintptr_t *)aligned_alloc(128, size * sizeof(uint64_t)) )
-		, len( size )
-		, ttid( &Context::CurrProcessor() )
-		, id( id )
-	{
-		for(size_t i = 0; i < this->len; i++) {
-			this->data[i] = 0;
-		}
-	}
-
-	uint64_t moved(BaseProcessor * ttid) {
-		if(this->ttid == ttid) {
-			return 0;
-		}
-		this->ttid = ttid;
-		return 1;
-	}
-
-	__attribute__((noinline)) void access(size_t idx) {
-		size_t l = this->len;
-		this->data[idx % l] += 1;
-	}
-};
-
-// ==================================================
-struct __attribute__((aligned(128))) MyCtx {
-	struct MyData * volatile data;
-
-	struct {
-		struct MySpot ** ptr;
-		size_t len;
-	} spots;
-
-	bench_sem sem;
-
-	Result result;
-
-	bool share;
-	size_t cnt;
-	BaseProcessor * ttid;
-	size_t id;
-
-	MyCtx(MyData * d, MySpot ** spots, size_t len, size_t cnt, bool share, size_t id)
-		: data( d )
-		, spots{ .ptr = spots, .len = len }
-		, share( share )
-		, cnt( cnt )
-		, ttid( &Context::CurrProcessor() )
-		, id( id )
-	{}
-
-	uint64_t moved(BaseProcessor * ttid) {
-		if(this->ttid == ttid) {
-			return 0;
-		}
-		this->ttid = ttid;
-		return 1;
-	}
-};
-
-// ==================================================
-// Atomic object where a single thread can wait
-// May exchanges data
-struct __attribute__((aligned(128))) MySpot {
-	MyCtx * volatile ptr;
-	size_t id;
-	uint64_t _p1[16];  // padding
-
-	MySpot(size_t id) : ptr( nullptr ), id( id ) {}
-
-
-	static inline MyCtx * one() {
-		return reinterpret_cast<MyCtx *>(1);
-	}
-
-	// Main handshake of the code
-	// Single seat, first thread arriving waits
-	// Next threads unblocks current one and blocks in its place
-	// if share == true, exchange data in the process
-	bool put( MyCtx & ctx, MyData * data, bool share) {
-		// Attempt to CAS our context into the seat
-		for(;;) {
-			MyCtx * expected = this->ptr;
-			if (expected == one()) { // Seat is closed, return
-				return true;
-			}
-
-			if (__atomic_compare_exchange_n(&this->ptr, &expected, &ctx, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
-				if(expected) {
-					if(share) {
-						expected->data = data;
-					}
-					expected->sem.post();
-				}
-				break; // We got the seat
-			}
-		}
-
-		// Block once on the seat
-		ctx.sem.wait();
-
-		// Someone woke us up, get the new data
-		return false;
-	}
-
-	// Shutdown the spot
-	// Wake current thread and mark seat as closed
-	void release() {
-		struct MyCtx * val = __atomic_exchange_n(&this->ptr, one(), __ATOMIC_SEQ_CST);
-		if (!val) {
-			return;
-		}
-
-		// Someone was there, release them
-		val->sem.post();
-	}
-};
-
-// ==================================================
-// Random number generator, Go's native one is to slow and global
-uint64_t __xorshift64( uint64_t & state ) {
-	uint64_t x = state;
-	x ^= x << 13;
-	x ^= x >> 7;
-	x ^= x << 17;
-	return state = x;
-}
-
-// ==================================================
-// Do some work by accessing 'cnt' cells in the array
-__attribute__((noinline)) void work(MyData & data, size_t cnt, uint64_t & state) {
-	for (size_t i = 0; i < cnt; i++) {
-		data.access(__xorshift64(state));
-	}
-}
-
-void thread_main( MyCtx & ctx ) {
-	uint64_t state = ctx.id;
-
-	// Wait for start
-	ctx.sem.wait();
-
-	// Main loop
-	for(;;) {
-		// Touch our current data, write to invalidate remote cache lines
-		work( *ctx.data, ctx.cnt, state );
-
-		// Wait on a random spot
-		uint64_t idx = __xorshift64(state) % ctx.spots.len;
-		bool closed = ctx.spots.ptr[idx]->put(ctx, ctx.data, ctx.share);
-
-		// Check if the experiment is over
-		if (closed) break;
-		if ( clock_mode && stop) break;
-		if (!clock_mode && ctx.result.count >= stop_count) break;
-
-		// Check everything is consistent
-		assert( ctx.data );
-
-		// write down progress and check migrations
-		BaseProcessor * ttid = &Context::CurrProcessor();
-		ctx.result.count += 1;
-		ctx.result.gmigs += ctx.moved(ttid);
-		ctx.result.dmigs += ctx.data->moved(ttid);
-	}
-
-	__atomic_fetch_add(&threads_left, -1, __ATOMIC_SEQ_CST);
-}
-
-// ==================================================
-int main(int argc, char * argv[]) {
-	unsigned wsize = 2;
-	unsigned wcnt  = 2;
-	unsigned nspots = 0;
-	bool share = false;
-	option_t opt[] = {
-		BENCH_OPT,
-		{ 'n', "nspots", "Number of spots where threads sleep (nthreads - nspots are active at the same time)", nspots},
-		{ 'w', "worksize", "Size of the array for each threads, in words (64bit)", wsize},
-		{ 'c', "workcnt" , "Number of words to touch when working (random pick, cells can be picked more than once)", wcnt },
-		{ 's', "share"   , "Pass the work data to the next thread when blocking", share, parse_truefalse }
-	};
-	BENCH_OPT_PARSE("libfibre cycle benchmark");
-
-	std::cout.imbue(std::locale(""));
-	setlocale(LC_ALL, "");
-
-	unsigned long long global_count = 0;
-	unsigned long long global_gmigs = 0;
-	unsigned long long global_dmigs = 0;
-
-	if( nspots == 0 ) { nspots = nthreads - nprocs; }
-
-	uint64_t start, end;
-	{
-		FibreInit(1, nprocs);
-		MyData * data_arrays[nthreads];
-		for(size_t i = 0; i < nthreads; i++) {
-			data_arrays[i] = new MyData( i, wsize );
-		}
-
-		MySpot * spots[nspots];
-		for(unsigned i = 0; i < nspots; i++) {
-			spots[i] = new MySpot{ i };
-		}
-
-		threads_left = nthreads - nspots;
-		Fibre * threads[nthreads];
-		MyCtx * thddata[nthreads];
-		{
-			for(size_t i = 0; i < nthreads; i++) {
-				thddata[i] = new MyCtx(
-					data_arrays[i],
-					spots,
-					nspots,
-					wcnt,
-					share,
-					i
-				);
-				threads[i] = new Fibre( reinterpret_cast<void (*)(void *)>(thread_main), thddata[i] );
-			}
-
-			bool is_tty = isatty(STDOUT_FILENO);
-			start = getTimeNsec();
-
-			for(size_t i = 0; i < nthreads; i++) {
-				thddata[i]->sem.post();
-			}
-			wait<Fibre>(start, is_tty);
-
-			stop = true;
-			end = getTimeNsec();
-			printf("\nDone\n");
-
-			for(size_t i = 0; i < nthreads; i++) {
-				thddata[i]->sem.post();
-				fibre_join( threads[i], nullptr );
-				global_count += thddata[i]->result.count;
-				global_gmigs += thddata[i]->result.gmigs;
-				global_dmigs += thddata[i]->result.dmigs;
-			}
-		}
-
-		for(size_t i = 0; i < nthreads; i++) {
-			delete( data_arrays[i] );
-		}
-
-		for(size_t i = 0; i < nspots; i++) {
-			delete( spots[i] );
-		}
-	}
-
-	printf("Duration (ms)          : %'ld\n", to_miliseconds(end - start));
-	printf("Number of processors   : %'d\n", nprocs);
-	printf("Number of threads      : %'d\n", nthreads);
-	printf("Number of spots        : %'d\n", nspots);
-	printf("Work size (64bit words): %'15u\n", wsize);
-	printf("Total Operations(ops)  : %'15llu\n", global_count);
-	printf("Total G Migrations     : %'15llu\n", global_gmigs);
-	printf("Total D Migrations     : %'15llu\n", global_dmigs);
-	printf("Ops per second         : %'18.2lf\n", ((double)global_count) / to_fseconds(end - start));
-	printf("ns per ops             : %'18.2lf\n", ((double)(end - start)) / global_count);
-	printf("Ops per threads        : %'15llu\n", global_count / nthreads);
-	printf("Ops per procs          : %'15llu\n", global_count / nprocs);
-	printf("Ops/sec/procs          : %'18.2lf\n", (((double)global_count) / nprocs) / to_fseconds(end - start));
-	printf("ns per ops/procs       : %'18.2lf\n", ((double)(end - start)) / (global_count / nprocs));
-	fflush(stdout);
-}
Index: benchmark/readyQ/locality.go
===================================================================
--- benchmark/readyQ/locality.go	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ benchmark/readyQ/locality.go	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -2,28 +2,40 @@
 
 import (
-	"context"
 	"flag"
 	"fmt"
 	"math/rand"
 	"os"
-	"syscall"
 	"sync/atomic"
 	"time"
-	"unsafe"
-	"golang.org/x/sync/semaphore"
 	"golang.org/x/text/language"
 	"golang.org/x/text/message"
 )
 
-// ==================================================
-type MyData struct {
-	_p1 [16]uint64 // padding
-	ttid int
-	id int
-	data [] uint64
-	_p2 [16]uint64 // padding
+func handshake(stop chan struct {}, c chan [] uint64, data [] uint64, share bool) (bool, [] uint64) {
+	var s [] uint64 = data
+	if !share {
+		s = nil
+	}
+
+	// send the data
+	select {
+	case <- stop:
+		return true, nil
+	case c <- s:
+	}
+
+	// get the new data chunk
+	select {
+	case <- stop:
+		return true, nil
+	case n := <- c:
+		if share {
+			return false, n
+		}
+		return false, data
+	}
 }
 
-func NewData(id int, size uint64) (*MyData) {
+func local(result chan uint64, start chan struct{}, stop chan struct{}, size uint64, cnt uint64, channels []chan [] uint64, chan_cnt uint64, share bool) {
 	var data [] uint64
 	data = make([]uint64, size)
@@ -31,211 +43,36 @@
 		data[i] = 0
 	}
-	return &MyData{[16]uint64{0}, syscall.Gettid(), id, data,[16]uint64{0}}
+	count := uint64(0)
+	<- start
+	for true {
+		for i := uint64(0); i < cnt; i++ {
+			data[rand.Uint64() % size] += 1
+		}
+
+		i := rand.Uint64() % chan_cnt
+		var closed bool
+		closed, data = handshake(stop, channels[i], data, share)
+		count += 1
+
+		if  closed { break }
+		if !clock_mode && count >= stop_count { break }
+	}
+
+	atomic.AddInt64(&threads_left, -1);
+	result <- count
 }
 
-func (this * MyData) moved( ttid int ) (uint64) {
-	if this.ttid == ttid {
-		return 0
-	}
-	this.ttid = ttid
-	return 1
-}
+func main() {
 
-func (this * MyData) access( idx uint64 ) {
-	this.data[idx % uint64(len(this.data))] += 1
-}
-
-// ==================================================
-type MyCtx struct {
-	_p1 [16]uint64 // padding
-	s * semaphore.Weighted
-	d unsafe.Pointer
-	c context.Context
-	ttid int
-	id int
-	_p2 [16]uint64 // padding
-}
-
-func NewCtx( data * MyData, id int ) (MyCtx) {
-	r := MyCtx{[16]uint64{0},semaphore.NewWeighted(1), unsafe.Pointer(data), context.Background(), syscall.Gettid(), id,[16]uint64{0}}
-	r.s.Acquire(context.Background(), 1)
-	return r
-}
-
-func (this * MyCtx) moved( ttid int ) (uint64) {
-	if this.ttid == ttid {
-		return 0
-	}
-	this.ttid = ttid
-	return 1
-}
-
-// ==================================================
-// Atomic object where a single thread can wait
-// May exchanges data
-type Spot struct {
-	_p1 [16]uint64 // padding
-	ptr uintptr // atomic variable use fo MES
-	id int      // id for debugging
-	_p2 [16]uint64 // padding
-}
-
-// Main handshake of the code
-// Single seat, first thread arriving waits
-// Next threads unblocks current one and blocks in its place
-// if share == true, exchange data in the process
-func (this * Spot) put( ctx * MyCtx, data * MyData, share bool) (* MyData, bool) {
-	new := uintptr(unsafe.Pointer(ctx))
-	// old_d := ctx.d
-
-	// Attempt to CAS our context into the seat
-	var raw uintptr
-	for true {
-		raw = this.ptr
-		if raw == uintptr(1) { // Seat is closed, return
-			return nil, true
-		}
-		if atomic.CompareAndSwapUintptr(&this.ptr, raw, new) {
-			break // We got the seat
-		}
-	}
-
-	// If we aren't the fist in, wake someone
-	if raw != uintptr(0) {
-		var val *MyCtx
-		val = (*MyCtx)(unsafe.Pointer(raw))
-
-		// If we are sharing, give them our data
-		if share {
-			// fmt.Printf("[%d] - %d update %d: %p -> %p\n", this.id, ctx.id, val.id, val.d, data)
-			atomic.StorePointer(&val.d, unsafe.Pointer(data))
-		}
-
-		// Wake them up
-		// fmt.Printf("[%d] - %d release %d\n", this.id, ctx.id, val.id)
-		val.s.Release(1)
-	}
-
-	// fmt.Printf("[%d] - %d enter\n", this.id, ctx.id)
-
-	// Block once on the seat
-	ctx.s.Acquire(ctx.c, 1)
-
-	// Someone woke us up, get the new data
-	ret := (* MyData)(atomic.LoadPointer(&ctx.d))
-	// fmt.Printf("[%d] - %d leave: %p -> %p\n", this.id, ctx.id, ret, old_d)
-
-	return ret, false
-}
-
-// Shutdown the spot
-// Wake current thread and mark seat as closed
-func (this * Spot) release() {
-	val := (*MyCtx)(unsafe.Pointer(atomic.SwapUintptr(&this.ptr, uintptr(1))))
-	if val == nil {
-		return
-	}
-
-	// Someone was there, release them
-	val.s.Release(1)
-}
-
-// ==================================================
-// Struct for result, Go doesn't support passing tuple in channels
-type Result struct {
-	count uint64
-	gmigs uint64
-	dmigs uint64
-}
-
-func NewResult() (Result) {
-	return Result{0, 0, 0}
-}
-
-// ==================================================
-// Random number generator, Go's native one is to slow and global
-func __xorshift64( state * uint64 ) (uint64) {
-	x := *state
-	x ^= x << 13
-	x ^= x >> 7
-	x ^= x << 17
-	*state = x
-	return x
-}
-
-// ==================================================
-// Do some work by accessing 'cnt' cells in the array
-func work(data * MyData, cnt uint64, state * uint64) {
-	for i := uint64(0); i < cnt; i++ {
-		data.access(__xorshift64(state))
-	}
-}
-
-// Main body of the threads
-func local(result chan Result, start chan struct{}, size uint64, cnt uint64, channels [] Spot, share bool, id int) {
-	// Initialize some data
-    	state := rand.Uint64()    // RNG state
-	data := NewData(id, size) // Starting piece of data
-	ctx := NewCtx(data, id)   // Goroutine local context
-
-	// Prepare results
-	r := NewResult()
-
-	// Wait for start
-	<- start
-
-	// Main loop
-	for true {
-		// Touch our current data, write to invalidate remote cache lines
-		work(data, cnt, &state)
-
-		// Wait on a random spot
-		i := __xorshift64(&state) % uint64(len(channels))
-		var closed bool
-		data, closed = channels[i].put(&ctx, data, share)
-
-		// Check if the experiment is over
-		if closed { break }                                       // yes, spot was closed
-		if  clock_mode && atomic.LoadInt32(&stop) == 1 { break }  // yes, time's up
-		if !clock_mode && r.count >= stop_count { break }         // yes, iterations reached
-
-		// Check everything is consistent
-		if uint64(len(data.data)) != size { panic("Data has weird size") }
-
-		// write down progress and check migrations
-		ttid := syscall.Gettid()
-		r.count += 1
-		r.gmigs += ctx .moved(ttid)
-		r.dmigs += data.moved(ttid)
-	}
-
-	// Mark goroutine as done
-	atomic.AddInt64(&threads_left, -1);
-
-	// return result
-	result <- r
-}
-
-// ==================================================
-// Program main
-func main() {
-	// Benchmark specific command line arguments
-	nspotsOpt    := flag.Int   ("n", 0    , "Number of spots where threads sleep (nthreads - nspots are active at the same time)")
-	work_sizeOpt := flag.Uint64("w", 2    , "Size of the array for each threads, in words (64bit)")
-	countOpt     := flag.Uint64("c", 2    , "Number of words to touch when working (random pick, cells can be picked more than once)")
+	work_sizeOpt := flag.Uint64("w", 2    , "Number of words (uint64) per threads")
+	countOpt     := flag.Uint64("c", 2    , "Number of words (uint64) to touch")
 	shareOpt     := flag.Bool  ("s", false, "Pass the work data to the next thread when blocking")
 
-	// General benchmark initialization and deinitialization
-	defer bench_init()()
+	bench_init()
 
-	// Eval command line arguments
-	nspots:= *nspotsOpt
 	size  := *work_sizeOpt
 	cnt   := *countOpt
 	share := *shareOpt
 
-	if nspots == 0 { nspots = nthreads - nprocs; }
-
-	// Check params
 	if ! (nthreads > nprocs) {
 		fmt.Fprintf(os.Stderr, "Must have more threads than procs\n")
@@ -243,26 +80,24 @@
 	}
 
-	// Make global data
-	barrierStart := make(chan struct{})         // Barrier used at the start
-	threads_left = int64(nthreads - nspots)                // Counter for active threads (not 'nthreads' because at all times 'nthreads - nprocs' are blocked)
-	result  := make(chan Result)                // Channel for results
-	channels := make([]Spot, nspots) // Number of spots
+	barrierStart := make(chan struct{})
+	barrierStop  := make(chan struct{})
+	threads_left = int64(nthreads)
+	result  := make(chan uint64)
+	channels := make([]chan [] uint64, nthreads - nprocs)
 	for i := range channels {
-		channels[i] = Spot{[16]uint64{0},uintptr(0), i,[16]uint64{0}}     // init spots
+		channels[i] = make(chan [] uint64, 1)
 	}
 
-	// start the goroutines
 	for i := 0; i < nthreads; i++ {
-		go local(result, barrierStart, size, cnt, channels, share, i)
+		go local(result, barrierStart, barrierStop, size, cnt, channels, uint64(nthreads - nprocs), share)
 	}
 	fmt.Printf("Starting\n");
 
-	atomic.StoreInt32(&stop, 0)
 	start := time.Now()
-	close(barrierStart) // release barrier
+	close(barrierStart)
 
-	wait(start, true);  // general benchmark wait
+	wait(start, true);
 
-	atomic.StoreInt32(&stop, 1)
+	close(barrierStop)
 	end := time.Now()
 	delta := end.Sub(start)
@@ -270,32 +105,20 @@
 	fmt.Printf("\nDone\n")
 
-	// release all the blocked threads
-	for i := range channels {
-		channels[i].release()
+	global_counter := uint64(0)
+	for i := 0; i < nthreads; i++ {
+		global_counter += <- result
 	}
 
-	// Join and accumulate results
-	results := NewResult()
-	for i := 0; i < nthreads; i++ {
-		r := <- result
-		results.count += r.count
-		results.gmigs += r.gmigs
-		results.dmigs += r.dmigs
-	}
-
-	// Print with nice 's, i.e. 1'000'000 instead of 1000000
 	p := message.NewPrinter(language.English)
-	p.Printf("Duration (s)           : %f\n", delta.Seconds());
+	p.Printf("Duration (ms)          : %f\n", delta.Seconds());
 	p.Printf("Number of processors   : %d\n", nprocs);
 	p.Printf("Number of threads      : %d\n", nthreads);
 	p.Printf("Work size (64bit words): %d\n", size);
-	p.Printf("Total Operations(ops)  : %15d\n", results.count)
-	p.Printf("Total G Migrations     : %15d\n", results.gmigs)
-	p.Printf("Total D Migrations     : %15d\n", results.dmigs)
-	p.Printf("Ops per second         : %18.2f\n", float64(results.count) / delta.Seconds())
-	p.Printf("ns per ops             : %18.2f\n", float64(delta.Nanoseconds()) / float64(results.count))
-	p.Printf("Ops per threads        : %15d\n", results.count / uint64(nthreads))
-	p.Printf("Ops per procs          : %15d\n", results.count / uint64(nprocs))
-	p.Printf("Ops/sec/procs          : %18.2f\n", (float64(results.count) / float64(nprocs)) / delta.Seconds())
-	p.Printf("ns per ops/procs       : %18.2f\n", float64(delta.Nanoseconds()) / (float64(results.count) / float64(nprocs)))
+	p.Printf("Total Operations(ops)  : %15d\n", global_counter)
+	p.Printf("Ops per second         : %18.2f\n", float64(global_counter) / delta.Seconds())
+	p.Printf("ns per ops             : %18.2f\n", float64(delta.Nanoseconds()) / float64(global_counter))
+	p.Printf("Ops per threads        : %15d\n", global_counter / uint64(nthreads))
+	p.Printf("Ops per procs          : %15d\n", global_counter / uint64(nprocs))
+	p.Printf("Ops/sec/procs          : %18.2f\n", (float64(global_counter) / float64(nprocs)) / delta.Seconds())
+	p.Printf("ns per ops/procs       : %18.2f\n", float64(delta.Nanoseconds()) / (float64(global_counter) / float64(nprocs)))
 }
Index: nchmark/readyQ/locality.rs
===================================================================
--- benchmark/readyQ/locality.rs	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,357 +1,0 @@
-use std::ptr;
-use std::sync::Arc;
-use std::sync::atomic::{AtomicU64, Ordering};
-use std::time::Instant;
-use std::thread::{self, ThreadId};
-
-use tokio::runtime::Builder;
-use tokio::sync;
-
-use clap::{App, Arg};
-use num_format::{Locale, ToFormattedString};
-use rand::Rng;
-
-#[path = "../bench.rs"]
-mod bench;
-
-// ==================================================
-struct MyData {
-	_p1: [u64; 16],
-	data: Vec<u64>,
-	ttid: ThreadId,
-	_id: usize,
-	_p2: [u64; 16],
-}
-
-impl MyData {
-	fn new(id: usize, size: usize) -> MyData {
-		MyData {
-			_p1: [0; 16],
-			data: vec![0; size],
-			ttid: thread::current().id(),
-			_id: id,
-			_p2: [0; 16],
-		}
-	}
-
-	fn moved(&mut self, ttid: ThreadId) -> u64 {
-		if self.ttid == ttid {
-			return 0;
-		}
-		self.ttid = ttid;
-		return 1;
-	}
-
-	fn access(&mut self, idx: usize) {
-		let l = self.data.len();
-		self.data[idx % l] += 1;
-	}
-}
-
-struct MyDataPtr {
-	ptr: *mut MyData,
-}
-
-unsafe impl std::marker::Send for MyDataPtr{}
-
-// ==================================================
-struct MyCtx {
-	_p1: [u64; 16],
-	s: sync::Semaphore,
-	d: MyDataPtr,
-	ttid: ThreadId,
-	_id: usize,
-	_p2: [u64; 16],
-}
-
-impl MyCtx {
-	fn new(d: *mut MyData, id: usize) -> MyCtx {
-		MyCtx {
-			_p1: [0; 16],
-			s: sync::Semaphore::new(0),
-			d: MyDataPtr{ ptr: d },
-			ttid: thread::current().id(),
-			_id: id,
-			_p2: [0; 16],
-		}
-	}
-
-	fn moved(&mut self, ttid: ThreadId) -> u64 {
-		if self.ttid == ttid {
-			return 0;
-		}
-		self.ttid = ttid;
-		return 1;
-	}
-}
-// ==================================================
-// Atomic object where a single thread can wait
-// May exchanges data
-struct MySpot {
-	_p1: [u64; 16],
-	ptr: AtomicU64,
-	_id: usize,
-	_p2: [u64; 16],
-}
-
-impl MySpot {
-	fn new(id: usize) -> MySpot {
-		let r = MySpot{
-			_p1: [0; 16],
-			ptr: AtomicU64::new(0),
-			_id: id,
-			_p2: [0; 16],
-		};
-		r
-	}
-
-	fn one() -> u64 {
-		1
-	}
-
-	// Main handshake of the code
-	// Single seat, first thread arriving waits
-	// Next threads unblocks current one and blocks in its place
-	// if share == true, exchange data in the process
-	async fn put( &self, ctx: &mut MyCtx, data: MyDataPtr, share: bool) -> (*mut MyData, bool) {
-		{
-			// Attempt to CAS our context into the seat
-			let raw = {
-				loop {
-					let expected = self.ptr.load(Ordering::Relaxed) as u64;
-					if expected == MySpot::one() { // Seat is closed, return
-						let r: *const MyData = ptr::null();
-						return (r as *mut MyData, true);
-					}
-					let got = self.ptr.compare_and_swap(expected, ctx as *mut MyCtx as u64, Ordering::SeqCst);
-					if got == expected {
-						break expected;// We got the seat
-					}
-				}
-			};
-
-			// If we aren't the fist in, wake someone
-			if raw != 0 {
-				let val: &mut MyCtx = unsafe{ &mut *(raw as *mut MyCtx) };
-				// If we are sharing, give them our data
-				if share {
-					val.d.ptr = data.ptr;
-				}
-
-				// Wake them up
-				val.s.add_permits(1);
-			}
-		}
-
-		// Block once on the seat
-		ctx.s.acquire().await.forget();
-
-		// Someone woke us up, get the new data
-		let ret = ctx.d.ptr;
-		return (ret, false);
-	}
-
-	// Shutdown the spot
-	// Wake current thread and mark seat as closed
-	fn release(&self) {
-		let val = self.ptr.swap(MySpot::one(), Ordering::SeqCst);
-		if val == 0 {
-			return
-		}
-
-		// Someone was there, release them
-		unsafe{ &mut *(val as *mut MyCtx) }.s.add_permits(1)
-	}
-}
-
-// ==================================================
-// Struct for result, Go doesn't support passing tuple in channels
-struct Result {
-	count: u64,
-	gmigs: u64,
-	dmigs: u64,
-}
-
-impl Result {
-	fn new() -> Result {
-		Result{ count: 0, gmigs: 0, dmigs: 0}
-	}
-
-	fn add(&mut self, o: Result) {
-		self.count += o.count;
-		self.gmigs += o.gmigs;
-		self.dmigs += o.dmigs;
-	}
-}
-
-// ==================================================
-// Random number generator, Go's native one is to slow and global
-fn __xorshift64( state: &mut u64 ) -> usize {
-	let mut x = *state;
-	x ^= x << 13;
-	x ^= x >> 7;
-	x ^= x << 17;
-	*state = x;
-	x as usize
-}
-
-// ==================================================
-// Do some work by accessing 'cnt' cells in the array
-fn work(data: &mut MyData, cnt: u64, state : &mut u64) {
-	for _ in 0..cnt {
-		data.access(__xorshift64(state))
-	}
-}
-
-async fn local(start: Arc<sync::Barrier>, idata: MyDataPtr, spots : Arc<Vec<MySpot>>, cnt: u64, share: bool, id: usize, exp: Arc<bench::BenchData>) -> Result{
-	let mut state = rand::thread_rng().gen::<u64>();
-	let mut data = idata;
-	let mut ctx = MyCtx::new(data.ptr, id);
-	let _size = unsafe{ &mut *data.ptr }.data.len();
-
-	// Prepare results
-	let mut r = Result::new();
-
-	// Wait for start
-	start.wait().await;
-
-	// Main loop
-	loop {
-		// Touch our current data, write to invalidate remote cache lines
-		work(unsafe{ &mut *data.ptr }, cnt, &mut state);
-
-		// Wait on a random spot
-		let i = (__xorshift64(&mut state) as usize) % spots.len();
-		let closed = {
-			let (d, c) = spots[i].put(&mut ctx, data, share).await;
-			data = MyDataPtr{ ptr: d };
-			c
-		};
-
-		// Check if the experiment is over
-		if closed { break }                                                   // yes, spot was closed
-		if  exp.clock_mode && exp.stop.load(Ordering::Relaxed) { break }  // yes, time's up
-		if !exp.clock_mode && r.count >= exp.stop_count { break }         // yes, iterations reached
-
-		assert_ne!(data.ptr as *const MyData, ptr::null());
-
-		let d = unsafe{ &mut *data.ptr };
-
-		// Check everything is consistent
-		debug_assert_eq!(d.data.len(), _size);
-
-		// write down progress and check migrations
-		let ttid = thread::current().id();
-		r.count += 1;
-		r.gmigs += ctx .moved(ttid);
-		r.dmigs += d.moved(ttid);
-	}
-
-	exp.threads_left.fetch_sub(1, Ordering::SeqCst);
-	r
-}
-
-
-// ==================================================
-fn main() {
-	let options = App::new("Locality Tokio")
-		.args(&bench::args())
-		.arg(Arg::with_name("nspots").short("n").long("nspots")  .takes_value(true).default_value("0").help("Number of spots where threads sleep (nthreads - nspots are active at the same time)"))
-		.arg(Arg::with_name("size")  .short("w").long("worksize").takes_value(true).default_value("2").help("Size of the array for each threads, in words (64bit)"))
-		.arg(Arg::with_name("work")  .short("c").long("workcnt") .takes_value(true).default_value("2").help("Number of words to touch when working (random pick, cells can be picked more than once)"))
-		.arg(Arg::with_name("share") .short("s").long("share")   .takes_value(true).default_value("true").help("Pass the work data to the next thread when blocking"))
-		.get_matches();
-
-	let nthreads   = options.value_of("nthreads").unwrap().parse::<usize>().unwrap();
-	let nprocs     = options.value_of("nprocs").unwrap().parse::<usize>().unwrap();
-	let wsize      = options.value_of("size").unwrap().parse::<usize>().unwrap();
-	let wcnt       = options.value_of("work").unwrap().parse::<u64>().unwrap();
-	let share      = options.value_of("share").unwrap().parse::<bool>().unwrap();
-	let nspots = {
-		let val = options.value_of("nspots").unwrap().parse::<usize>().unwrap();
-		if val != 0 {
-			val
-		} else {
-			nthreads - nprocs
-		}
-	};
-
-	// Check params
-	if ! (nthreads > nprocs) {
-		panic!("Must have more threads than procs");
-	}
-
-	let s = (1000000 as u64).to_formatted_string(&Locale::en);
-	assert_eq!(&s, "1,000,000");
-
-	let exp = Arc::new(bench::BenchData::new(options, nprocs));
-	let mut results = Result::new();
-
-	let mut elapsed : std::time::Duration = std::time::Duration::from_secs(0);
-
-	let mut data_arrays : Vec<MyData> = (0..nthreads).map(|i| MyData::new(i, wsize)).rev().collect();
-	let spots : Arc<Vec<MySpot>> = Arc::new((0..nspots).map(|i| MySpot::new(i)).rev().collect());
-	let barr = Arc::new(sync::Barrier::new(nthreads + 1));
-
-	let runtime = Builder::new_multi_thread()
-		.worker_threads(nprocs)
-		.enable_all()
-		.build()
-		.unwrap();
-
-	runtime.block_on(async
-		{
-			let thrds: Vec<_> = (0..nthreads).map(|i| {
-				debug_assert!(i < data_arrays.len());
-
-				runtime.spawn(local(
-					barr.clone(),
-					MyDataPtr{ ptr: &mut data_arrays[i] },
-					spots.clone(),
-					wcnt,
-					share,
-					i,
-					exp.clone(),
-				))
-			}).collect();
-
-
-			println!("Starting");
-
-			let start = Instant::now();
-			barr.wait().await;
-
-			elapsed = exp.wait(&start).await;
-
-			println!("\nDone");
-
-			// release all the blocked threads
-			for s in &* spots {
-				s.release();
-			}
-
-			println!("Threads released");
-
-			// Join and accumulate results
-			for t in thrds {
-				results.add( t.await.unwrap() );
-			}
-
-			println!("Threads joined");
-		}
-	);
-
-	println!("Duration (ms)          : {}", (elapsed.as_millis()).to_formatted_string(&Locale::en));
-	println!("Number of processors   : {}", (nprocs).to_formatted_string(&Locale::en));
-	println!("Number of threads      : {}", (nthreads).to_formatted_string(&Locale::en));
-	println!("Work size (64bit words): {}", (wsize).to_formatted_string(&Locale::en));
-	println!("Total Operations(ops)  : {:>15}", (results.count).to_formatted_string(&Locale::en));
-	println!("Total G Migrations     : {:>15}", (results.gmigs).to_formatted_string(&Locale::en));
-	println!("Total D Migrations     : {:>15}", (results.dmigs).to_formatted_string(&Locale::en));
-	println!("Ops per second         : {:>15}", (((results.count as f64) / elapsed.as_secs() as f64) as u64).to_formatted_string(&Locale::en));
-	println!("ns per ops             : {:>15}", ((elapsed.as_nanos() as f64 / results.count as f64) as u64).to_formatted_string(&Locale::en));
-	println!("Ops per threads        : {:>15}", (results.count / nthreads as u64).to_formatted_string(&Locale::en));
-	println!("Ops per procs          : {:>15}", (results.count / nprocs as u64).to_formatted_string(&Locale::en));
-	println!("Ops/sec/procs          : {:>15}", ((((results.count as f64) / nprocs as f64) / elapsed.as_secs() as f64) as u64).to_formatted_string(&Locale::en));
-	println!("ns per ops/procs       : {:>15}", ((elapsed.as_nanos() as f64 / (results.count as f64 / nprocs as f64)) as u64).to_formatted_string(&Locale::en));
-}
Index: benchmark/readyQ/rq_bench.hfa
===================================================================
--- benchmark/readyQ/rq_bench.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ benchmark/readyQ/rq_bench.hfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -39,5 +39,5 @@
 		} else if(stop_count > 0) { \
 			clock_mode = false; \
-			printf("Running for %llu iterations\n", stop_count); \
+			printf("Running for %lu iterations\n", stop_count); \
 		} else { \
 			duration = 5; clock_mode = true;\
Index: benchmark/readyQ/rq_bench.hpp
===================================================================
--- benchmark/readyQ/rq_bench.hpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ benchmark/readyQ/rq_bench.hpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -97,18 +97,4 @@
 }
 
-bool parse_truefalse(const char * arg, bool & value) {
-	if(strcmp(arg, "true") == 0) {
-		value = true;
-		return true;
-	}
-
-	if(strcmp(arg, "false") == 0) {
-		value = false;
-		return true;
-	}
-
-	return false;
-}
-
 bool parse_settrue (const char *, bool & value ) {
 	value = true;
@@ -240,5 +226,5 @@
 	{
 		int idx = 0;
-		for(size_t i = 0; i < opt_count; i++) {
+		for(int i = 0; i < opt_count; i++) {
 			if(options[i].long_name) {
 				optarr[idx].name = options[i].long_name;
@@ -270,5 +256,5 @@
 	{
 		int idx = 0;
-		for(size_t i = 0; i < opt_count; i++) {
+		for(int i = 0; i < opt_count; i++) {
 			optstring[idx] = options[i].short_name;
 			idx++;
@@ -293,12 +279,10 @@
 			case 'h':
 				out = stdout;
-				[[fallthrough]];
 			case '?':
 				usage(argv[0], options, opt_count, usage_msg, out);
 			default:
-				for(size_t i = 0; i < opt_count; i++) {
+				for(int i = 0; i < opt_count; i++) {
 					if(opt == options[i].short_name) {
 						const char * arg = optarg ? optarg : "";
-						if( arg[0] == '=' ) { arg++; }
 						bool success = options[i].parse_fun( arg, options[i].variable );
 						if(success) goto NEXT_ARG;
@@ -335,5 +319,5 @@
 	int width = 0;
 	{
-		for(size_t i = 0; i < opt_count; i++) {
+		for(int i = 0; i < opt_count; i++) {
 			if(options[i].long_name) {
 				int w = strlen(options[i].long_name);
@@ -354,5 +338,5 @@
 	fprintf(out, "Usage:\n  %s %s\n", cmd, help);
 
-	for(size_t i = 0; i < opt_count; i++) {
+	for(int i = 0; i < opt_count; i++) {
 		printopt(out, width, max_width, options[i].short_name, options[i].long_name, options[i].help);
 	}
Index: nchmark/vector/glm_vec2.cc
===================================================================
--- benchmark/vector/glm_vec2.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,56 +1,0 @@
-#include <glm/glm.hpp>
-#include <iostream>
-#define BENCH_N 1000000000
-#include "../bench.h"
-
-using namespace glm;
-
-
-int main(int argc, char* argv[]) {
-    tvec2<volatile float> v1(1,2);
-    tvec2<volatile float> v2(20.5f, 30.2f);
-
-    {
-        BENCH(
-            for (int i = 0; i < n; i ++) {
-                volatile float res = dot(v1, v2);
-                asm volatile ("":::"memory");
-            },
-            dot_b
-        );
-        std::cout << "dot: " << dot_b << std::endl;
-    }
-
-    {
-        BENCH(
-            for (int i = 0; i < n; i ++) {
-                volatile vec2 res = v1 + v2;
-                asm volatile ("":::"memory");
-            },
-            add_b
-        );
-        std::cout << "vector addition: " << add_b << std::endl;
-    }
-
-    {
-        BENCH(
-            for (int i = 0; i < n; i ++) {
-                volatile vec2 res = normalize((tvec2<float>)v1);
-                asm volatile ("":::"memory");
-            },
-            normalize_b
-        );
-        std::cout << "normalize: " << normalize_b << std::endl;
-    }
-
-    {
-        BENCH(
-            for (int i = 0; i < n; i ++) {
-                volatile vec2 res = reflect((vec2)v1, (vec2)v2);
-                asm volatile ("":::"memory");
-            },
-            reflect_b
-        );
-        std::cout << "reflect: " << reflect_b << std::endl;
-    }
-}
Index: nchmark/vector/vec2_notemplates.cfa
===================================================================
--- benchmark/vector/vec2_notemplates.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,53 +1,0 @@
-#include "../../libcfa/src/vec/vec2_f.hfa"
-/* #include <fstream.hfa> */
-#define BENCH_N 1000000000
-#include "../bench.h"
-
-int main(int argc, char* argv[]) {
-    volatile vec2 v1 = {1,2};
-    volatile vec2 v2 = {20.5, 30.2};
-
-    {
-        BENCH(
-            for (n) {
-                volatile float res = dot(v1, v2);
-                asm volatile ("":::"memory");
-            },
-            dot_b
-        );
-        printf("dot: %g\n", dot_b);
-    }
-
-    {
-        BENCH(
-            for (n) {
-                volatile vec2 res = v1 + v2;
-                asm volatile ("":::"memory");
-            },
-            add_b
-        );
-        printf("vector addition: %g\n", add_b);
-    }
-
-    {
-        BENCH(
-            for (n) {
-                volatile vec2 res = normalize(v1);
-                asm volatile ("":::"memory");
-            },
-            normalize_b
-        );
-        printf("normalize: %g\n", normalize_b);
-    }
-
-    {
-        BENCH(
-            for (n) {
-                volatile vec2 res = reflect(v1, v2);
-                asm volatile ("":::"memory");
-            },
-            reflect_b
-        );
-        printf("reflect : %g\n", reflect_b);
-    }
-}
Index: nchmark/vector/vec2_templates.cfa
===================================================================
--- benchmark/vector/vec2_templates.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,53 +1,0 @@
-#include "../../libcfa/src/vec/vec2.hfa"
-/* #include <fstream.hfa> */
-/* #define BENCH_N 1000000 */
-#include "../bench.h"
-
-int main(int argc, char* argv[]) {
-    volatile vec2(float) v1 = {1,2};
-    volatile vec2(float) v2 = {20.5f, 30.2f};
-
-    {
-        BENCH(
-            for (n) {
-                volatile float res = dot(v1, v2);
-                asm volatile ("":::"memory");
-            },
-            dot_b
-        );
-        printf("dot: %g\n", dot_b);
-    }
-
-    {
-        BENCH(
-            for (n) {
-                volatile vec2(float) res = v1 + v2;
-                asm volatile ("":::"memory");
-            },
-            add_b
-        );
-        printf("vector addition: %g\n", add_b);
-    }
-
-    {
-        BENCH(
-            for (n) {
-                volatile vec2(float) res = normalize(v1);
-                asm volatile ("":::"memory");
-            },
-            normalize_b
-        );
-        printf("normalize: %g\n", normalize_b);
-    }
-
-    {
-        BENCH(
-            for (n) {
-                volatile vec2(float) res = reflect(v1, v2);
-                asm volatile ("":::"memory");
-            },
-            reflect_b
-        );
-        printf("reflect : %g\n", reflect_b);
-    }
-}
Index: configure.ac
===================================================================
--- configure.ac	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ configure.ac	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -295,6 +295,6 @@
 # Some of our makefile don't need to be distributed
 AM_CONDITIONAL([CFORALL_DISTRIBUTE], [test -e $TOP_SRCDIR/autogen.sh])
-AM_COND_IF([CFORALL_DISTRIBUTE], [
-	AC_CONFIG_FILES([
+AM_COND_IF([CFORALL_DISTRIBUTE],
+	[AC_CONFIG_FILES([
 		longrun_tests/Makefile
 		benchmark/Makefile
@@ -302,8 +302,5 @@
 		tools/Makefile
 		tools/prettyprinter/Makefile
-	])
-
-	AC_OUTPUT(benchmark/Cargo.toml)
-])
+		])])
 
 AC_CONFIG_LINKS([tests/test.py:tests/test.py])
Index: doc/theses/thierry_delisle_PhD/thesis/Makefile
===================================================================
--- doc/theses/thierry_delisle_PhD/thesis/Makefile	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ doc/theses/thierry_delisle_PhD/thesis/Makefile	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -28,8 +28,4 @@
 	base \
 	empty \
-	emptybit \
-	emptytls \
-	emptytree \
-	fairness \
 	system \
 }
@@ -77,7 +73,4 @@
 	${LaTeX} $<
 
-build/fairness.svg : fig/fairness.py | ${Build}
-	python3 $< $@
-
 ## Define the default recipes.
 
@@ -95,10 +88,4 @@
 	fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
 
-%.pstex : build/%.svg | ${Build}
-	inkscape -z -D --file=$< --export-eps=${Build}/$@ --export-latex
-	mv ${Build}/$@_tex ${Build}/$@_t
-	echo "sed -i 's/$@/${Build}/$@/g' ${Build}/$@_t"
-	sed -i 's/$@/${Build}\/$@/g' ${Build}/$@_t
-
 ## pstex with inverted colors
 %.dark.pstex : fig/%.fig Makefile | ${Build}
Index: c/theses/thierry_delisle_PhD/thesis/fig/fairness.py
===================================================================
--- doc/theses/thierry_delisle_PhD/thesis/fig/fairness.py	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,38 +1,0 @@
-import matplotlib.pyplot as plt
-import numpy as np
-
-import sys
-
-if __name__ == "__main__":
-	if len(sys.argv) > 2:
-		print('USAGE: %s [FILE]' % sys.argv[0], file=sys.stderr)
-		sys.exit(1)
-
-	with plt.xkcd():
-		fig = plt.figure()
-		ax = fig.add_axes((0.1, 0.2, 0.8, 0.7))
-		ax.spines['right'].set_color('none')
-		ax.spines['top'].set_color('none')
-		ax.set_xticks([])
-		ax.set_yticks([])
-		ax.set_ylim([-30, 10])
-
-		x = np.linspace(1, 100, 100)
-
-		fair = ((x / 15) ** 2)  - 28
-		ax.annotate('Fairness', xy=(70, 1), xytext=(80, 1))
-		ax.plot(fair)
-
-		local = (((x - 100) / 17.5) ** 2)  - 28
-		ax.annotate('Locality', xy=(70, 1), xytext=(1, 1))
-		ax.plot(local, color='r')
-
-		ax.set_xlabel('Ready Time')
-		ax.set_ylabel('Importance')
-		if len(sys.argv) == 1:
-			plt.show()
-		else :
-			plt.rcParams["savefig.format"] = "svg"
-			plt.rcParams["savefig.bbox"] = "tight"
-			plt.rcParams["svg.fonttype"] = 'none'
-			plt.savefig(sys.argv[1], format="svg")
Index: doc/theses/thierry_delisle_PhD/thesis/glossary.tex
===================================================================
--- doc/theses/thierry_delisle_PhD/thesis/glossary.tex	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ doc/theses/thierry_delisle_PhD/thesis/glossary.tex	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -7,5 +7,4 @@
 \newacronym{io}{I/O}{Input and Output}
 \newacronym{numa}{NUMA}{Non-Uniform Memory Access}
-\newacronym{prng}{PRNG}{Pseudo Random Number Generator}
 \newacronym{raii}{RAII}{Resource Acquisition Is Initialization}
 \newacronym{tls}{TLS}{Thread Local Storage}
Index: doc/theses/thierry_delisle_PhD/thesis/local.bib
===================================================================
--- doc/theses/thierry_delisle_PhD/thesis/local.bib	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ doc/theses/thierry_delisle_PhD/thesis/local.bib	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -609,10 +609,2 @@
   note = "[Online; accessed 23-October-2020]"
 }
-
-@misc{wiki:lcg,
-  author = "{Wikipedia contributors}",
-  title = "Linear congruential generator --- {W}ikipedia{,} The Free Encyclopedia",
-  year = "2020",
-  url = "https://en.wikipedia.org/wiki/Linear_congruential_generator",
-  note = "[Online; accessed 2-January-2021]"
-}
Index: doc/theses/thierry_delisle_PhD/thesis/text/core.tex
===================================================================
--- doc/theses/thierry_delisle_PhD/thesis/text/core.tex	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ doc/theses/thierry_delisle_PhD/thesis/text/core.tex	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -1,10 +1,10 @@
 \chapter{Scheduling Core}\label{core}
 
-Before discussing scheduling in general, where it is important to address systems that are changing states, this document discusses scheduling in a somewhat ideal scenerio, where the system has reached a steady state. For this purpose, a steady state is loosely defined as a state where there are always \glspl{thrd} ready to run and the system has the ressources necessary to accomplish the work, \eg, enough workers. In short, the system is neither overloaded nor underloaded.
+Before discussing scheduling in general, where it is important to address systems that are changing states, this document discusses scheduling in a somewhat ideal scenerio, where the system has reached a steady state. For this purpose, a steady state is loosely defined as a state where there are always \glspl{thrd} ready to run and but the system has the ressources necessary to accomplish the work. In short, the system is neither overloaded or underloaded.
 
-I believe it is important to discuss the steady state first because it is the easiest case to handle and, relatedly, the case in which the best performance is to be expected. As such, when the system is either overloaded or underloaded, a common approach is to try to adapt the system to the new load and return to the steady state, \eg, adding or removing workers. Flaws in the scheduling when the system is in the steady state can therefore to be pervasive in all states.
+I believe it is important to discuss the steady state first because it is the easiest case to handle and, relatedly, the case in which the best performance is to be expected. As such, when the system is either overloaded or underloaded, a common approach is to try to adapt the system to the new load and return to the steady state. Flaws in the scheduling in the steady state tend therefore to be pervasive in all states.
 
 \section{Design Goals}
-As with most of the design decisions behind \CFA, an important goal is to match the expectation of the programmer, according to their probable mental model. To match these expectations, the design must offer the programmers sufficient guarantees so that, as long as they respect the mental model, the system will also respect this model.
+As with most of the design decisions behind \CFA, the main goal is to match the expectation of the programmer, according to their probable mental model. To match these expectations, the design must offer the programmers sufficient guarantees so that, as long as the programmer respects the mental model, the system will also respect this model.
 
 For threading, a simple and common mental model is the ``Ideal multi-tasking CPU'' :
@@ -16,5 +16,5 @@
 Applied to threads, this model states that every ready \gls{thrd} immediately runs in parallel with all other ready \glspl{thrd}. While a strict implementation of this model is not feasible, programmers still have expectations about scheduling that come from this model.
 
-In general, the expectation at the center of this model is that ready \glspl{thrd} do not interfere with eachother but simply share the hardware. This makes it easier to reason about threading because ready \glspl{thrd} can be taken in isolation and the effect of the scheduler can be virtually ignored. This expectation of \gls{thrd} independence means the scheduler is expected to offer two guarantees:
+In general, the expectation at the center of this model is that ready \glspl{thrd} do not interfere with eachother but simply share the hardware. This makes it easier to reason about threading because ready \glspl{thrd} can be taken in isolation and the effect of the scheduler can be virtually ignored. This expectation of \gls{thrd} independence means the scheduler is expected to offer 2 guarantees:
 \begin{enumerate}
 	\item A fairness guarantee: a \gls{thrd} that is ready to run will not be prevented to do so by another thread.
@@ -24,34 +24,13 @@
 It is important to note that these guarantees are expected only up to a point. \Glspl{thrd} that are ready to run should not be prevented to do so, but they still need to share a limited amount of hardware. Therefore, the guarantee is considered respected if a \gls{thrd} gets access to a \emph{fair share} of the hardware, even if that share is very small.
 
-Similarly the performance guarantee, the lack of interferance between threads, is only relevant up to a point. Ideally the cost of running and blocking would be constant regardless of contention, but the guarantee is considered satisfied if the cost is not \emph{too high} with or without contention. How much is an acceptable cost is obviously highly variable. For this document the performance experimentation will attempt to show that the cost of scheduling is at worst equivalent to existing algorithms used in popular languages. This demonstration can be made by comparing application built in \CFA to applications built with other languages or other models. Recall from a few paragraphs ago that the expectation of programmers is that the impact of the scheduler can be ignored. Therefore, if the cost of scheduling is equivalent or lower to other popular languages, I will consider the guarantee achieved.
+Similarly the performance guarantee, the lack of interferance between threads is only relevant op to a point. Ideally the cost of running and blocking would be constant regardless of contention, but the guarantee is considered satisfied if the cost is not \emph{too high} with or without contention. How much is an acceptable cost is obviously highly variable. For this document the performance experimentation will attempt to show that the cost of scheduling is not a major factor in application performance. This demonstration can be made by comparing application built in \CFA to applications built with other languages or other models. If the performance of an application built in \CFA is not meaningfully different than one built with a different runtime, then the scheduler has a negigeable impact on performance, \ie its impact can be ignored. Recall from a few paragraphs ago that the expectation of programmers is that the impact of the scheduler can be ignored. Therefore, if the cost of scheduling is not a significant portion of the runtime of several different application, I will consider the guarantee achieved.
 
-More precisely the scheduler should be:
-\begin{itemize}
-	\item As fast as other schedulers that are less fair.
-	\item Faster than other scheduler that have equal or better fairness.
-\end{itemize}
-
-\subsection{Fairness vs Scheduler Locality}
-An important performance factor in modern architectures is cache locality. Waiting for data not present in the cache can have a major impact on performance, and having multiple \glspl{hthrd} writing to the same cache lines can lead to cache lines that need to be waited on again. It is therefore preferable to divide the data among each \gls{hthrd}\footnote{This can be an explicit division up front or using data structures where different \glspl{hthrd} are naturally routed to different cache lines.}.
-
-For a scheduler, having good locality\footnote{This section discusses \emph{internal} locality, \ie, the locality of the data used by the scheduler. \emph{External locality}, \ie, how the data used by the application is affected by scheduling, is a much more complicated subject and will be discussed in the chapters on evaluation.}, \ie, having the data be local to each \gls{hthrd}, generally conflicts with fairness. Indeed, good locality often requires avoiding the movement of cache lines, while fairness requires dynamically moving \gls{thrd}, and as a consequence cache lines, to \glspl{hthrd} that are currently more appropriate.
-
-However, I claim that in practice it is possible to strike a balance between fairness and performance because the need for these do not necessarily overlap temporaly. Figure~\ref{fig:fair} shows an visual representation of this behaviour. As mentionned, a little bit of unfairness can be acceptable, therefore it can be desirable to have an algorithm that prioritizes cache locality as long as no threads is left behind for too long.
-
-\begin{figure}
-	\begin{center}
-		\input{fairness.pstex_t}
-	\end{center}
-	\caption{Fairness vs Locality}
-	\label{fig:fair}
-	Rule of thumb graph: Importance of Fairness and Locality while a ready \gls{thrd} waits run.
-	As the time a ready \gls{thrd} waits increases, ``Ready Time'', the chances that its data is still in cache decreases. At the same time, the need for fairness increases since other \glspl{thrd} may have the chance to run many times, breaking the fairness model mentionned above. Since the actual values and curves of this graph can be highly variable, the graph is left intentionally fuzzy and innacurate.
-\end{figure}
+\todo{This paragraph should be moved later}
+% The next step is then to decide what is considered a \emph{fair share}, \ie what metric is used to measure fairness. Since \CFA is intended to allow numerous short lived threads, I decided to avoid total CPU time as the measure of fairness. Total CPU time inherently favors new \glspl{thrd} over older ones which isn't necessarily a good thing. Instead, fairness is measured in terms of opportunities to run. This metric is more appropriate for a mix of short and long lived \glspl{thrd}.
 
 \section{Design}
-A naive strictly \glsxtrshort{fifo} ready-queue does not offer sufficient performance. As shown in the evaluation sections, most production schedulers scale when adding multiple \glspl{hthrd} and that is not possible with a single point of contention. Therefore it is vital to shard the ready-queue so that multiple \glspl{hthrd} can access the ready-queue without performance degradation.
+While avoiding the pitfalls of Feedback Scheduling is fairly easy, scheduling does not innately require feedback, avoiding prioritization of \glspl{thrd} is more difficult because of implicitly priorities, see Subsection~\ref{priority}. A strictly \glsxtrshort{fifo} rea
 
-\subsection{Sharding} \label{sec:sharding}
-An interesting approach to sharding a queue is presented in \cit{Trevors paper}. This algorithm represents a queue with relaxed \glsxtrshort{fifo} guarantee using an array of strictly \glsxtrshort{fifo} sublists as shown in Figure~\ref{fig:base}. Each cell of the array contains a linked-list with a lock and each node in these list is marked with a timestamp indicating when they were added to the list. Push operations are done by picking a random cell and attempting to push to its list. If the cell is already locked, the operation is simply retried on a new cell until a lock is acquired. Pop operations are done in a similar fashion except two random cells are picked. If both cells are not already locked and both cells contain non-empty lists, the operation pops the node with the oldest timestamp. If only one of the cell is unlocked and non-empty, the operation pops from that cell. If both cells are either locked or empty, the operation picks two new cells and tries again.
+\subsection{Sharding}
 
 \begin{figure}
@@ -66,5 +45,7 @@
 
 \subsection{Finding threads}
-Once threads have been distributed onto multiple queues, indentifying which queues are empty and which are not can become a problem. Indeed, if the number of \glspl{thrd} does not far exceed the number of queues, it is probable that several of these queues are empty. Figure~\ref{fig:empty} shows an example with 2 \glspl{thrd} running on 8 queues, where the chances of getting an empty queue is 75\% per pick, meaning two random picks yield a \gls{thrd} only half the time.
+Once threads have been distributed onto multiple queues, indentifying which queues are empty and which aren't can become a problem.
+Indeed, if the number of \glspl{thrd} does not far exceed the number of queues, it is probable that several of these queues are empty.
+Figure~\ref{fig:empty} shows an example with 2 \glspl{thrd} running on 8 queues, where the chances of getting an empty queue is 75\% per pick, meaning two random picks yield a \gls{thrd} only half the time.
 
 
@@ -80,51 +61,5 @@
 This can lead to performance problems since picks that do not yield a \gls{thrd} are not useful and do not necessarily help make more informed guesses.
 
-Solutions to this problem can take many forms, but they ultimately all have to encode where the threads are in some form. My results show that the density and locality of this encoding is generally the dominating factor in these scheme. Classic solutions to this problem use one of three techniques to encode the information:
+Solutions to this problem can take many forms, but they ultimately all have to encode where the threads are in some form. My results show that the density and locality of this encoding is generally the dominating factor in these scheme.
 
-\begin{figure}
-	\begin{center}
-		{\resizebox{0.73\textwidth}{!}{\input{emptybit.pstex_t}}}
-	\end{center}
-	\vspace*{-5pt}
-	\caption{Underloaded queue with added bitmask to indicate which array cells have items.}
-	\label{fig:emptybit}
-	\begin{center}
-		{\resizebox{0.73\textwidth}{!}{\input{emptytree.pstex_t}}}
-	\end{center}
-	\vspace*{-5pt}
-	\caption{Underloaded queue with added binary search tree indicate which array cells have items.}
-	\label{fig:emptytree}
-	\begin{center}
-		{\resizebox{0.9\textwidth}{!}{\input{emptytls.pstex_t}}}
-	\end{center}
-	\vspace*{-5pt}
-	\caption{Underloaded queue with added per processor bitmask to indicate which array cells have items.}
-	\label{fig:emptytls}
-\end{figure}
-
-\paragraph{Dense Information} Figure~\ref{fig:emptybit} shows a dense bitmask to identify which inner queues are currently in use. This approach means processors can often find \glspl{thrd} in constant time, regardless of how many underlying queues are empty. Furthermore, modern x86 CPUs have extended bit manipulation instructions (BMI2) that allow using the bitmask with very little overhead compared to the randomized selection approach for a filled ready queue, offering good performance even in cases with many empty inner queues. However, this technique has its limits: with a single word\footnote{Word refers here to however many bits can be written atomically.} bitmask, the total number of underlying queues in the ready queue is limited to the number of bits in the word. With a multi-word bitmask, this maximum limit can be increased arbitrarily, but the look-up will nolonger be constant time. Finally, a dense bitmap, either single or multi-word, causes additional contention problems which reduces performance because of cache misses after updates. This central update bottleneck also means the information in the bitmask is more often stale before a processor can use it to find an item, \ie mask read says there are available \glspl{thrd} but none on queue.
-
-\paragraph{Sparse Information} Figure~\ref{fig:emptytree} shows an approach using a hierarchical tree data-structure to reduce contention and has been shown to work in similar cases~\cite{ellen2007snzi}. However, this approach may lead to poorer performance due to the inherent pointer chasing cost while still allowing more contention on the nodes of the tree if the tree is not deep enough.
-
-\paragraph{Local Information} Figure~\ref{fig:emptytls} shows an approach using dense information, similar to the bitmap, but have each thread keep its own independent copy of it. While this approach can offer good scalability \emph{and} low latency, the liveliness and discovery of the information can become a problem. This case is made worst in systems with few processors where even blind random picks can find \glspl{thrd} in few tries.
-
-I built a prototype of these approach and none of these techniques offer satisfying performance when few threads are present. All of these approach hit the same 2 problems. First, blindly picking two sub-queues is very fast which means that any improvement to the hit rate can easily be countered by a slow-down in look-up speed. Second, the array is already as sharded as is needed to avoid contention bottlenecks, so any denser data structure will tend to become a bottleneck. In all cases, these factors meant that the best cases scenerio, many threads, would get worst throughput and the worst case scenario, few threads, would get a better hit rate, but an equivalent throughput. As a result I tried an entirely different approach.
-
-\subsection{Dynamic Entropy}\cit{https://xkcd.com/2318/}
-In the worst case scenario there are few \glspl{thrd} ready to run, or more accuratly given $P$ \glspl{proc}, $T$ \glspl{thrd} and $\epsilon$, as usual, a very small number, in this case $\epsilon \ll P$, we have $T = P + \epsilon$. An important thing to note is that in this case, fairness is effectively irrelevant. Indeed, this case is close to \emph{actually matching} the model of the ``Ideal multi-tasking CPU'' presented in this chapter\footnote{For simplicity, this assumes there is a one-to-one match between \glspl{proc} and \glspl{hthrd}.}. Therefore, in this context it is possible to use a purely internal locality based approach and still meet the fairness requirements. This approach would simply have each \gls{proc} running a single \gls{thrd} repeatedly. Or from the shared ready-queue viewpoint, each \gls{proc} would push to a given sub-queue and then pop from the \emph{same} subqueue. Ideally, the scheduler would achieve this without affecting the fairness guarantees in cases where $T \gg P$.
-
-To achieve this, I use a communication channel I have not mentionned yet and which I believe I use in a novel way : the \glsxtrshort{prng}. If the scheduler has a \glsxtrshort{prng} instance per \gls{proc} exclusively used for scheduling, its seed effectively encodes a list of all the accessed subqueues, from the latest to the oldest. The only requirement to achieve this is to be able to ``replay'' the \glsxtrshort{prng} backwards. As it turns out, this is an entirely reasonnable requirement and there already exist \glsxtrshort{prng}s that are fast, compact \emph{and} can be run forward and backwards. Linear congruential generators\cite{wiki:lcg} are an example of \glsxtrshort{prng}s that match these requirements.
-
-The algorithm works as follows :
-\begin{itemize}
-	\item Each \gls{proc} has two \glsxtrshort{prng} instances, $F$ and $B$.
-	\item Push and Pop operations happen as mentionned in Section~\ref{sec:sharding} with the following exceptions:
-	\begin{itemize}
-		\item Push operations use $F$ going forward on each try and on success $F$ is copied into $B$.
-		\item Pop operations use $B$ going backwards on each try.
-	\end{itemize}
-\end{itemize}
-
-The main benefit of this technique is that it basically repects the desired properties of Figure~\ref{fig:fair}. When looking for work, \glspl{proc} will look first at the last cells they pushed to, if any, and then move backwards through the cells. As the \glspl{proc} continue looking for work, $F$ moves back and $B$ stays in place. As a result the relation between the two becomes weaker, which means that the probablisitic fairness of the algorithm reverts to normal. Chapter~\ref{proofs} discusses more formally the fairness guarantees of this algorithm.
-
-\section{Details}
+\paragraph{Dense Information}
Index: doc/theses/thierry_delisle_PhD/thesis/text/existing.tex
===================================================================
--- doc/theses/thierry_delisle_PhD/thesis/text/existing.tex	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ doc/theses/thierry_delisle_PhD/thesis/text/existing.tex	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -42,5 +42,5 @@
 \paragraph{Task Placement} Since modern computers rely heavily on cache hierarchies\cit{Do I need a citation for this}, migrating tasks from one core to another can be .  \cite{DBLP:journals/tpds/SquillanteL93}
 
-\todo{The survey is not great on this subject}
+\TODO{The survey is not great on this subject}
 
 \paragraph{Complex Machine Architecture} Another aspect that has been looked at is how well Work Stealing is applicable to different machine architectures.
Index: c/working/unified_semaphores/semaphore.cfa
===================================================================
--- doc/working/unified_semaphores/semaphore.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,403 +1,0 @@
-#include "semaphore.hfa"
-#include "kernel_private.hfa"
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <kernel.hfa>
-#include <stdlib.hfa>
-#include <thread.hfa>
-
-forall(dtype L | is_blocking_lock(L)) {
-
-	void ?{}(base_semaphore(L) & this, int count, bool is_binary) {
-		this.count = count;
-		this.lock{};
-		this.blocked_threads{};
-		this.is_binary = is_binary;
-	}
-
-	void ^?{}(base_semaphore(L) & this) {
-		// default
-	}
-
-	void ?{}(binary_semaphore(L) & this) {
-		((base_semaphore(L) &)this){ 1, true };
-	}
-
-	void ?{}(binary_semaphore(L) & this, int count) {
-		((base_semaphore(L) &)this){ count, true };
-	}
-
-	void ^?{}(binary_semaphore(L) & this) {
-		// default
-	}
-
-	void ?{}(counting_semaphore(L) & this) {
-		((base_semaphore(L) &)this){ 1, false };
-	}
-
-	void ?{}(counting_semaphore(L) & this, int count) {
-		((base_semaphore(L) &)this){ count, false };
-	}
-
-	void ^?{}(counting_semaphore(L) & this) {
-		// default
-	}
-
-	void ?{}( alarm_node_semaphore(L) & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback ) {
-		this.alarm_node{ thrd, alarm, period, callback };
-	}
-
-	void ^?{}( alarm_node_semaphore(L) & this ) {
-
-	}
-
-	void add_( base_semaphore(L) & this, struct $thread * t ) with( this ) {
-		lock( lock __cfaabi_dbg_ctx2 );
-		#if !defined( __CFA_NO_STATISTICS__ )
-			kernelTLS.this_stats = t->curr_cluster->stats;
-		#endif
-		unpark( t );
-		unlock( lock );
-	}
-
-	void remove_( base_semaphore(L) & this ) with( this ) {
-		V(this);
-	}
-
-	////////////////////////////////////////////////////////////////////////////////
-	// These extras are needed since the inheritance is broken with traits
-	////////////////////////////////////////////////////////////////////////////////
-
-	void add_( binary_semaphore(L) & this, struct $thread * t ) with( this ) {
-		add_( (base_semaphore(L) &)this, t );
-	}
-
-	void remove_( binary_semaphore(L) & this ) with( this ) {
-		remove_( (base_semaphore(L) &)this );
-	}
-
-	void add_( counting_semaphore(L) & this, struct $thread * t ) with( this ) {
-		add_( (base_semaphore(L) &)this, t );
-	}
-
-	void remove_( counting_semaphore(L) & this ) with( this ) {
-		remove_( (base_semaphore(L) &)this );
-	}
-
-	////////////////////////////////////////////////////////////////////////////////
-	////////////////////////////////////////////////////////////////////////////////
-
-	void timeout_handler ( alarm_node_semaphore(L) & this ) with( this ) {
-    	// This condition_variable member is called from the kernel, and therefore, cannot block, but it can spin.
-	    lock( sem->lock __cfaabi_dbg_ctx2 );
-	    if ( (*i)->listed ) {			// is thread on queue
-	    	info_thread(L) * copy = *i;
-			remove( sem->blocked_threads, i );		 //remove this thread O(1)
-			sem->count++;
-			if( !copy->lock ) {
-				unlock( sem->lock );
-				#if !defined( __CFA_NO_STATISTICS__ )
-					kernelTLS.this_stats = copy->t->curr_cluster->stats;
-				#endif
-				unpark( copy->t );
-	    	} else {
-	    		add_(*copy->lock, copy->t);			// call lock's add_
-	    	}
-	    }
-	    unlock( sem->lock );
-	}
-
-	void alarm_node_sem_cast( alarm_node_t & a ) {
-		timeout_handler( (alarm_node_semaphore(L) &)a );
-	}
-
-	void handle_P(base_semaphore(L) & this, info_thread( L ) & i ) with( this ) {
-		lock( lock __cfaabi_dbg_ctx2 );
-		if ( count <= 0) {
-			append( blocked_threads, &i );
-
-			if (!is_binary) count--;
-
-			i.listed = true;
-
-			size_t recursion_count;
-			if (i.lock) {
-				recursion_count = get_recursion_count( *i.lock );
-				remove_( *i.lock );
-			}
-
-			unlock( lock );
-			park( );
-
-			if (i.lock) set_recursion_count( *i.lock, recursion_count );
-		} else {
-			if (i.lock) {
-				size_t recursion_count = get_recursion_count( *i.lock );
-				remove_( *i.lock );
-				add_( *i.lock, i.t );
-				set_recursion_count( *i.lock, recursion_count );
-			}
-			count--;
-			unlock( lock );
-		}
-	}
-
-	void handle_P_timeout(base_semaphore(L) & this, info_thread( L ) & i, Time time) with( this ) {
-		lock( lock __cfaabi_dbg_ctx2 );
-		if ( count <= 0) {
-			append( blocked_threads, &i );
-
-			if (!is_binary) count--;
-
-			info_thread(L) * queue_ptr = &i;
-			i.listed = true;
-
-			alarm_node_semaphore(L) node_wrap = { i.t, time, 0`s, alarm_node_sem_cast };
-			node_wrap.sem = &this;
-			node_wrap.i = &queue_ptr;
-
-			register_self( &node_wrap.alarm_node );
-
-			size_t recursion_count;
-			if (i.lock) {
-				recursion_count = get_recursion_count( *i.lock );
-				remove_( *i.lock );
-			}
-
-			unlock( lock );
-			park( );
-
-			if (i.lock) set_recursion_count( *i.lock, recursion_count );
-		} else {
-			count--;
-			unlock( lock );
-		}
-	}
-
-	void P(base_semaphore(L) & this) with( this ) {
-		info_thread( L ) i = { kernelTLS.this_thread };
-		handle_P(this, i);
-	}
-
-	void P(base_semaphore(L) & this, uintptr_t info) with( this ) {
-		info_thread( L ) i = { kernelTLS.this_thread, info };
-		handle_P(this, i);
-	}
-
-	void P(base_semaphore(L) & this, Duration duration) with( this ) {
-		info_thread( L ) i = { kernelTLS.this_thread };
-		handle_P_timeout(this, i, __kernel_get_time() + duration);
-	}
-
-	void P(base_semaphore(L) & this, uintptr_t info, Duration duration) with( this ) {
-		info_thread( L ) i = { kernelTLS.this_thread, info };
-		handle_P_timeout(this, i, __kernel_get_time() + duration);
-	}
-
-	void P(base_semaphore(L) & this, Time time) with( this ) {
-		info_thread( L ) i = { kernelTLS.this_thread };
-		handle_P_timeout(this, i, time);
-	}
-
-	void P(base_semaphore(L) & this, uintptr_t info, Time time) with( this ) {
-		info_thread( L ) i = { kernelTLS.this_thread, info };
-		handle_P_timeout(this, i, time);
-	}
-
-	void P(base_semaphore(L) & this, L & l ) with( this ) {
-		info_thread( L ) i = { kernelTLS.this_thread };
-		i.lock = &l;
-		handle_P(this, i);
-	}
-
-	void P(base_semaphore(L) & this, L & l, uintptr_t info) with( this ) {
-		info_thread( L ) i = { kernelTLS.this_thread, info };
-		i.lock = &l;
-		handle_P(this, i);
-	}
-
-	void P(base_semaphore(L) & this, L & l, Duration duration ) with( this ) {
-		info_thread( L ) i = { kernelTLS.this_thread };
-		i.lock = &l;
-		handle_P_timeout(this, i, __kernel_get_time() + duration);
-	}
-
-	void P(base_semaphore(L) & this, L & l, uintptr_t info, Duration duration) with( this ) {
-		info_thread( L ) i = { kernelTLS.this_thread, info };
-		i.lock = &l;
-		handle_P_timeout(this, i, __kernel_get_time() + duration);
-	}
-
-	void P(base_semaphore(L) & this, L & l, Time time) with( this ) {
-		info_thread( L ) i = { kernelTLS.this_thread };
-		i.lock = &l;
-		handle_P_timeout(this, i, time);
-	}
-
-	void P(base_semaphore(L) & this, L & l, uintptr_t info, Time time) with( this ) {
-		info_thread( L ) i = { kernelTLS.this_thread, info };
-		i.lock = &l;
-		handle_P_timeout(this, i, time);
-	}
-
-	bool tryP(base_semaphore(L) & this) with( this ) {
-		lock( lock __cfaabi_dbg_ctx2 );
-		if ( count <= 0) {
-			unlock( lock );
-			return false;
-		} else {
-			count--;
-		}
-		unlock( lock );
-	}
-
-	void V(base_semaphore(L) & this) with( this ) {
-		lock( lock __cfaabi_dbg_ctx2 );
-		if( count < 0) {
-			info_thread(L) * i = pop_head( blocked_threads );
-			i->listed = false;
-			count++;
-			if ( i != 0p ) {
-				if (i->lock) {
-					add_(*i->lock, i->t);
-				} else {
-					unpark(i->t);
-				}
-			}
-		} else if (!is_binary || count == 0) {
-			count++;
-		} else {
-			fprintf( stderr, "A binary semaphore was V'd when it was already at 1" );
-		}
-		unlock( lock );
-	}
-
-
-	// TODO: Should we be able to V a binary semaphore multiple times to wake up multiple thds?
-	// right now we can't
-	void V(base_semaphore(L) & this, int times) with( this ) {
-		assert( times > 0 );
-		lock( lock __cfaabi_dbg_ctx2 );
-		while ( count < 0 && times > 0 ) {
-			info_thread(L) * i = pop_head( blocked_threads );
-			i->listed = false;
-			count++;
-			if ( i != 0p ) {
-				if (i->lock) {
-					add_(*i->lock, i->t);
-				} else {
-					unpark(i->t);
-				}
-			}
-			times--;
-		}
-		if(	!is_binary ) {
-			count += times;
-		} else if (count == 0 && times > 1) {
-			fprintf( stderr, "A binary semaphore was V'd when it was already at 1" );
-		} else {
-			count++;
-		}
-		unlock( lock );
-	}
-
-	// void ?++(base_semaphore(L) & this) with( this ) {
-	// 	V(this);
-	// }
-
-	// void ?--(base_semaphore(L) & this) with( this ) {
-	// 	P(this);
-	// }
-
-	// void ?`V(base_semaphore(L) & this) with( this ) {
-	// 	V(this);
-	// }
-
-	// void ?`P(base_semaphore(L) & this) with( this ) {
-	// 	P(this);
-	// }
-
-	uintptr_t front(base_semaphore(L) & this) with( this ) {
-		info_thread(L) *front = peek(blocked_threads);
-		if(!blocked_threads) return 0;
-		return front->info;
-	}
-
-	bool empty(base_semaphore(L) & this) with( this ) {
-		return blocked_threads ? false : true;
-	}
-
-	int counter(base_semaphore(L) & this) with( this ) {
-		return count;
-	}
-
-	// these are just to allow the semaphore to be a part of the is_blocking_lock trait
-	// they do nothing
-	void set_recursion_count( base_semaphore(L) & this, size_t recursion ) with( this ) {
-		// default
-	}
-
-	size_t get_recursion_count( base_semaphore(L) & this ) with( this ) {
-		return 0;
-	}
-
-	////////////////////////////////////////////////////////////////////////////////
-	// These extras are needed since the inheritance is broken with traits
-	// normally I'd cast to a semaphore & to call the parent but theres no need
-	// since these routines are so simple
-	////////////////////////////////////////////////////////////////////////////////
-
-	void set_recursion_count( binary_semaphore(L) & this, size_t recursion ) with( this ) {
-		// default
-	}
-
-	size_t get_recursion_count( binary_semaphore(L) & this ) with( this ) {
-		return 0;
-	}
-
-	void set_recursion_count( counting_semaphore(L) & this, size_t recursion ) with( this ) {
-		// default
-	}
-
-	size_t get_recursion_count( counting_semaphore(L) & this ) with( this ) {
-		return 0;
-	}
-
-	////////////////////////////////////////////////////////////////////////////////
-	////////////////////////////////////////////////////////////////////////////////
-}
-
-thread T1 {};
-thread T2 {};
-
-// counting_semaphore( ) s0, s1;
-
-// void main( T1 & this ) {
-// 	printf("T1 start\n");
-// 	V(s1);
-// 	P(s0);
-// 	P(s0);
-// 	V(s1, 2);
-	
-// 	printf("T1 done\n");
-// }
-
-// void main( T2 & this ) {
-// 	printf("T2 start\n");
-// 	V(s0);
-// 	P(s1);
-// 	P(s1, s0);
-// 	P(s1);
-// 	printf("T2 done\n");
-// }
-
-int main() {
-	printf("start\n");
-	// processor p[2];
-	// {
-	// 	T1 t1;
-	// 	T2 t2;
-	// }
-	printf("done\n");
-}
Index: c/working/unified_semaphores/semaphore.hfa
===================================================================
--- doc/working/unified_semaphores/semaphore.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,107 +1,0 @@
-#pragma once
-
-#include "locks.hfa"
-#include <stdbool.h>
-
-#include "bits/algorithm.hfa"
-#include "bits/locks.hfa"
-#include "bits/containers.hfa"
-
-#include "invoke.h"
-
-#include "time_t.hfa"
-#include "time.hfa"
-#include <sys/time.h>
-#include "alarm.hfa"
-
-///////////////////////////////////////////////////////////////////
-//// Semaphores
-///////////////////////////////////////////////////////////////////
-forall(dtype L | is_blocking_lock(L)) {
-
-	struct base_semaphore {
-		// internal counter for the semaphore
-		int count;
-
-		// Spin lock used for mutual exclusion
-		__spinlock_t lock;
-
-		// List of blocked threads
-		__queue_t(info_thread(L)) blocked_threads;
-
-		// Flag if the semaphor is binary
-		bool is_binary;
-	};
-
-	// A semaphore that is binary
-	// If the current owner P's this semaphore it will not block
-	struct binary_semaphore {
-		inline base_semaphore(L);
-	};
-
-	// A semaphore that maintains a counter.
-	// If a thread P's this semaphore it always decreases the counter
-	struct counting_semaphore {
-		inline base_semaphore(L);
-	};
-
-	void ?{}(base_semaphore(L) & this, int count, bool is_binary);
-	void ^?{}(base_semaphore(L) & this);
-
-	void ?{}(binary_semaphore(L) & this);
-	void ?{}(binary_semaphore(L) & this, int count);
-	void ^?{}(binary_semaphore(L) & this);
-
-	void ?{}(counting_semaphore(L) & this);
-	void ?{}(counting_semaphore(L) & this, int count);
-	void ^?{}(counting_semaphore(L) & this);
-
-	struct alarm_node_semaphore {
-		alarm_node_t alarm_node;
-
-		base_semaphore(L) * sem;
-
-		info_thread(L) ** i;
-	};
-
-	void ?{}( alarm_node_semaphore(L) & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback );
-	void ^?{}( alarm_node_semaphore(L) & this );
-
-	void add_( base_semaphore(L) & this, struct $thread * t );
-	void remove_( base_semaphore(L) & this );
-
-	// TODO: look into changing timout routines to return bool showing if signalled or woken by kernel
-	void P(base_semaphore(L) & this);
-	void P(base_semaphore(L) & this, uintptr_t info);
-	void P(base_semaphore(L) & this, Duration duration);
-	void P(base_semaphore(L) & this, uintptr_t info, Duration duration);
-	void P(base_semaphore(L) & this, Time time);
-	void P(base_semaphore(L) & this, uintptr_t info, Time time);
-	void P(base_semaphore(L) & this, base_semaphore(L) & s);
-	void P(base_semaphore(L) & this, base_semaphore(L) & s, uintptr_t info);
-	void P(base_semaphore(L) & this, base_semaphore(L) & s, Duration duration );
-	void P(base_semaphore(L) & this, base_semaphore(L) & s, uintptr_t info, Duration duration);
-	void P(base_semaphore(L) & this, base_semaphore(L) & s, Time time);
-	void P(base_semaphore(L) & this, base_semaphore(L) & s, uintptr_t info, Time time);
-
-	bool tryP(base_semaphore(L) & this);
-
-	void V(base_semaphore(L) & this);
-	void V(base_semaphore(L) & this, int times);
-
-	// void ?`++(base_semaphore(L) & this);
-	// void ?`--(base_semaphore(L) & this);
-
-	// void ?`V(base_semaphore(L) & this);
-	// void ?`P(base_semaphore(L) & this);
-
-	uintptr_t front(base_semaphore(L) & this);
-	bool empty(base_semaphore(L) & this);
-	int counter(base_semaphore(L) & this);
-
-
-	// these are to satisfy the is_blocking_lock trait so that 
-	// semaphores can be released by condition variables and vice versa
-	void set_recursion_count( base_semaphore(L) & this, size_t recursion );
-	size_t get_recursion_count( base_semaphore(L) & this );
-}
Index: libcfa/src/Makefile.am
===================================================================
--- libcfa/src/Makefile.am	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/Makefile.am	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -58,9 +58,5 @@
 	concurrency/iofwd.hfa \
 	containers/list.hfa \
-	containers/stackLockFree.hfa \
-	vec/vec.hfa \
-	vec/vec2.hfa \
-	vec/vec3.hfa \
-	vec/vec4.hfa
+	containers/stackLockFree.hfa
 
 inst_headers_src = \
@@ -98,5 +94,4 @@
 	concurrency/clib/cfathread.h \
 	concurrency/invoke.h \
-	concurrency/future.hfa \
 	concurrency/kernel/fwd.hfa
 
Index: libcfa/src/bits/collection.hfa
===================================================================
--- libcfa/src/bits/collection.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/bits/collection.hfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -1,12 +1,10 @@
 #pragma once
-#include <stdio.h> // REMOVE THIS AFTER DEBUGGING
-
 
 struct Colable {
-	struct Colable * next;										// next node in the list
+	Colable * next;										// next node in the list
 	// invariant: (next != 0) <=> listed()
 };
-#ifdef __cforall
-static inline {
+
+inline {
 	// PUBLIC
 
@@ -30,17 +28,16 @@
 	}
 
-	// // wrappers to make Collection have T
-	// forall( dtype T ) {
-	// 	T *& Next( T * n ) {
-	// 		return (T *)Next( (Colable *)n );
-	// 	}
-	// } // distribution
+	// wrappers to make Collection have T
+	forall( dtype T ) {
+		T *& Next( T * n ) {
+			return (T *)Next( (Colable *)n );
+		}
+
+		bool listed( T * n ) {
+			return Next( (Colable *)n ) != 0p;
+		}
+	} // distribution
 } // distribution
 
-forall( dtype T | { T *& Next ( T * ); } ) {
-	bool listed( T * n ) {
-		return Next( n ) != 0p;
-	}
-}
 
 struct Collection {
@@ -48,5 +45,5 @@
 };
 
-static inline {
+inline {
 	// class invariant: root == 0 & empty() | *root in *this
 	void ?{}( Collection &, const Collection & ) = void; // no copy
@@ -68,8 +65,8 @@
 
 struct ColIter {
-	void * curr;										// element returned by |
+	void * curr;										// element to be returned by >>
 };
 
-static inline {
+inline {
 	void ?{}( ColIter & colIter ) with( colIter ) {
 		curr = 0p;
@@ -82,3 +79,2 @@
 	} // distribution
 } // distribution
-#endif
Index: libcfa/src/bits/containers.hfa
===================================================================
--- libcfa/src/bits/containers.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/bits/containers.hfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -36,5 +36,5 @@
 	#define __small_array_t(T) __small_array(T)
 #else
-	#define __small_array_t(T) __small_array
+	#define __small_array_t(T) struct __small_array
 #endif
 
Index: libcfa/src/bits/defs.hfa
===================================================================
--- libcfa/src/bits/defs.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/bits/defs.hfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -29,5 +29,5 @@
 #define __cfa_anonymous_object(x) inline struct x
 #else
-#define __cfa_anonymous_object(x) struct x __cfa_anonymous_object
+#define __cfa_anonymous_object(x) x __cfa_anonymous_object
 #endif
 
Index: libcfa/src/bits/locks.hfa
===================================================================
--- libcfa/src/bits/locks.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/bits/locks.hfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -283,9 +283,4 @@
 		void ^?{}(future_t &) {}
 
-		void reset(future_t & this) {
-			// needs to be in 0p or 1p
-			__atomic_exchange_n( &this.ptr, 0p, __ATOMIC_SEQ_CST);
-		}
-
 		// check if the future is available
 		bool available( future_t & this ) {
@@ -345,12 +340,6 @@
 
 		// Mark the future as abandoned, meaning it will be deleted by the server
-		bool abandon( future_t & this ) {
-			/* paranoid */ verify( this.ptr != 3p );
-
-			// Mark the future as abandonned
+		void abandon( future_t & this ) {
 			struct oneshot * got = __atomic_exchange_n( &this.ptr, 3p, __ATOMIC_SEQ_CST);
-
-			// If the future isn't already fulfilled, let the server delete it
-			if( got == 0p ) return false;
 
 			// got == 2p: the future is ready but the context hasn't fully been consumed
@@ -358,11 +347,6 @@
 			if( got == 2p ) {
 				while( this.ptr != 1p ) Pause();
-				got = 1p;
-			}
-
-			// The future is completed delete it now
-			/* paranoid */ verify( this.ptr != 1p );
-			free( &this );
-			return true;
+			}
+			return;
 		}
 
Index: libcfa/src/bits/queue.hfa
===================================================================
--- libcfa/src/bits/queue.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/bits/queue.hfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -3,11 +3,5 @@
 #include "bits/collection.hfa"
 
-// A Queue(T) is a Collection(T) defining the ordering that nodes are returned by drop() in the same order from those
-// added by add(). T must be a public descendant of uColable.
-
-// The implementation is a typical singly-linked list, except the next field of the last element points to itself
-// instead of being null.
-
-forall( dtype T | { T *& Next ( T * ); } ) {
+forall( dtype T ) {
 	struct Queue {
 		inline Collection;								// Plan 9 inheritance
@@ -40,5 +34,5 @@
 		} // post: n == tail() & succ(n) == 0 | n != tail() & *succ(n) in *q
 
-		T & addHead( Queue(T) & q, T & n ) with( q ) {
+		void addHead( Queue(T) & q, T & n ) with( q ) {
 			#ifdef __CFA_DEBUG__
 			if ( listed( &n ) ) abort( "(Queue &)%p.addHead( %p ) : Node is already on another list.", &q, &n );
@@ -51,8 +45,7 @@
 				Next( &n ) = &n;						// last node points to itself
 			}
-			return n;
 		}
 
-		T & addTail( Queue(T) & q, T & n ) with( q ) {
+		void addTail( Queue(T) & q, T & n ) with( q ) {
 			#ifdef __CFA_DEBUG__
 			if ( listed( &n ) ) abort( "(Queue &)%p.addTail( %p ) : Node is already on another list.", &q, &n );
@@ -62,9 +55,8 @@
 			last = &n;
 			Next( &n ) = &n;							// last node points to itself
-			return n;
 		}
 
-		T & add( Queue(T) & q, T & n ) with( q ) {
-			return addTail( q, n );
+		void add( Queue(T) & q, T & n ) with( q ) {
+			addTail( q, n );
 		}
 
@@ -72,5 +64,5 @@
 			T & t = head( q );
 			if ( root ) {
-				root = Next( (T *)root );
+				root = Next( root );
 				if ( &head( q ) == &t ) {
 					root = last = 0p;					// only one element
@@ -85,5 +77,5 @@
 		}
 
-		T & remove( Queue(T) & q, T & n ) with( q ) {	// O(n)
+		void remove( Queue(T) & q, T & n ) with( q ) {	// O(n)
 			#ifdef __CFA_DEBUG__
 			if ( ! listed( (Colable &)n ) ) abort( "(Queue &)%p.remove( %p ) : Node is not on a list.", &q, &n );
@@ -111,8 +103,7 @@
 				curr = Next( curr );
 			}
-			return n;
 		} // post: ! listed( n )
 
-		T & dropTail( Queue(T) & q ) with( q ) {		// O(n)
+		T & dropTail( Queue(T) & q ) with( q ) { // O(n)
 			T & n = tail( q );
 			return &n ? remove( q, n ), n : *0p;
@@ -151,5 +142,5 @@
 } // distribution
 
-forall( dtype T | { T *& Next ( T * ); } ) {
+forall( dtype T ) {
 	struct QueueIter {
 		inline ColIter;									// Plan 9 inheritance
@@ -161,5 +152,5 @@
 		} // post: curr == 0p
 
-		// create an iterator active in queue q
+		// create an iterator active in Queue q
 		void ?{}( QueueIter(T) & qi, Queue(T) & q ) with( qi ) {
 			curr = &head( q );
@@ -170,10 +161,10 @@
 		} // post: curr = {e in q}
 
-		// make existing iterator active in queue q
+		// make existing iterator active in Queue q
 		void over( QueueIter(T) & qi, Queue(T) & q ) with( qi ) {
 			curr = &head( q );
 		} // post: curr = {e in q}
 
-		bool ?|?( QueueIter(T) & qi, T && tp ) with( qi ) {
+		bool ?>>?( QueueIter(T) & qi, T && tp ) with( qi ) {
 			if ( curr ) {
 				&tp = Curr( qi );
@@ -183,5 +174,5 @@
 			return &tp != 0p;
 		}
-		// post: elts == null & !operator|(tp) | elts != null & *tp' in elts & elts' == elts - *tp & operator|(tp)
+		// post: elts == null & !operator>>(tp) | elts != null & *tp' in elts & elts' == elts - *tp & operator>>(tp)
 	} // distribution
 } // distribution
Index: libcfa/src/bits/sequence.hfa
===================================================================
--- libcfa/src/bits/sequence.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/bits/sequence.hfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -2,13 +2,11 @@
 
 #include "bits/collection.hfa"
-#include "bits/defs.hfa"
 
 struct Seqable {
-	__cfa_anonymous_object(Colable);
-	struct Seqable * back;										// pointer to previous node in the list
+	inline Colable;
+	Seqable * back;										// pointer to previous node in the list
 };
 
-#ifdef __cforall
-static inline {
+inline {
 	// PUBLIC
 
@@ -28,25 +26,18 @@
 	}
 
-	// // wrappers to make Collection have T
-	// forall( dtype T ) {
-	// 	T *& Back( T * n ) {
-	// 		return (T *)Back( (Seqable *)n );
-	// 	}
-	// } // distribution
+	// wrappers to make Collection have T
+	forall( dtype T ) {
+		T *& Back( T * n ) {
+			return (T *)Back( (Seqable *)n );
+		}
+	} // distribution
 } // distribution
 
-
-// A Sequence(T) is a Collection(T) defining the ordering of a uStack and uQueue, and to insert and remove elements
-// anywhere in the sequence. T must be a public descendant of uSeqable.
-
-// The implementation is a typical doubly-linked list, except the next field of the last node points at the first node
-// and the back field of the last node points at the first node (circular).
-
-forall( dtype T | { T *& Back ( T * ); T *& Next ( T * ); } ) {
+forall( dtype T ) {
 	struct Sequence {
 		inline Collection;								// Plan 9 inheritance
 	};
 
-	static inline {
+	inline {
 		// wrappers to make Collection have T
 		T & head( Sequence(T) & s ) with( s ) {
@@ -59,7 +50,7 @@
 		void ?{}( Sequence(T) & s ) with( s ) {	
 			((Collection &)s){};
-		}	// post: isEmpty()
-
-		// Return a pointer to the last sequence element, without removing it.
+		}	// post: isEmpty().
+
+		// Return a pointer to the last sequence element, without removing it.	
 		T & tail( Sequence(T) & s ) with( s ) {
 			return root ? (T &)*Back( &head( s ) ) : *0p;
@@ -74,5 +65,5 @@
 		} // post: n == tail() & succ(n) == 0 | n != tail() & *succ(n) in *s
 
-		// Return a pointer to the element before *n, or 0p if list empty.
+		// Return a pointer to the element before *n, or 0p if there isn't one.
 		T * pred( Sequence(T) & s, T * n ) with( s ) {	// pre: *n in *s
 			#ifdef __CFA_DEBUG__
@@ -80,9 +71,9 @@
 			#endif // __CFA_DEBUG__
 			return n == &head( s ) ? 0p : Back( n );
-		} // post: n == head() & head(n) == 0 | n != head() & *pred(n) in *s
-
-
-		// Insert *n into the sequence before *bef, or at the end if bef == 0p.
-		T & insertBef( Sequence(T) & s, T & n, T & bef ) with( s ) { // pre: !n->listed() & *bef in *s
+		}	// post: n == head() & head(n) == 0 | n != head() & *pred(n) in *s
+
+
+		// Insert *n into the sequence before *bef, or at the end if bef == 0.
+		void insertBef( Sequence(T) & s, T & n, T & bef ) with( s ) { // pre: !n->listed() & *bef in *s
 			#ifdef __CFA_DEBUG__
 			if ( listed( &n ) ) abort( "(Sequence &)%p.insertBef( %p, %p ) : Node is already on another list.", &s, n, &bef );
@@ -112,10 +103,9 @@
 				Next( Back( &n ) ) = &n;
 			} // if
-			return n;
 		}	// post: n->listed() & *n in *s & succ(n) == bef
 
 
 		// Insert *n into the sequence after *aft, or at the beginning if aft == 0.
-		T & insertAft( Sequence(T) & s, T & aft, T & n ) with( s ) {	// pre: !n->listed() & *aft in *s
+		void insertAft( Sequence(T) & s, T & aft, T & n ) with( s ) {	// pre: !n->listed() & *aft in *s
 			#ifdef __CFA_DEBUG__
 			if ( listed( &n ) ) abort( "(Sequence &)%p.insertAft( %p, %p ) : Node is already on another list.", &s, &aft, &n );
@@ -143,9 +133,8 @@
 				Next( &aft ) = &n;
 			} // if
-			return n;
-		} // post: n->listed() & *n in *s & succ(n) == bef
+		}	  // post: n->listed() & *n in *s & succ(n) == bef
 		
 		// pre: n->listed() & *n in *s
-		T & remove( Sequence(T) & s, T & n ) with( s ) { // O(1)
+		void remove( Sequence(T) & s, T & n ) with( s ) { // O(1)
 			#ifdef __CFA_DEBUG__
 			if ( ! listed( &n ) ) abort( "(Sequence &)%p.remove( %p ) : Node is not on a list.", &s, &n );
@@ -158,22 +147,18 @@
 			Next( Back( &n ) ) = Next( &n );
 			Next( &n ) = Back( &n ) = 0p;
-			return n;
-		} // post: !n->listed()
+		}							// post: !n->listed().
 
 		// Add an element to the head of the sequence.
-		T & addHead( Sequence(T) & s, T & n ) {			// pre: !n->listed(); post: n->listed() & head() == n
-			return insertAft( s, *0p, n );
-		}
-
+		void addHead( Sequence(T) & s, T & n ) {		// pre: !n->listed(); post: n->listed() & head() == n
+			insertAft( s, *0p, n );
+		}
 		// Add an element to the tail of the sequence.
-		T & addTail( Sequence(T) & s, T & n ) {			// pre: !n->listed(); post: n->listed() & head() == n
-			return insertBef( s, n, *0p );
-		}
-
+		void addTail( Sequence(T) & s, T & n ) {		// pre: !n->listed(); post: n->listed() & head() == n
+			insertBef( s, n, *0p );
+		}
 		// Add an element to the tail of the sequence.
-		T & add( Sequence(T) & s, T & n ) {				// pre: !n->listed(); post: n->listed() & head() == n
-			return addTail( s, n );
-		}
-
+		void add( Sequence(T) & s, T & n ) {			// pre: !n->listed(); post: n->listed() & head() == n
+			addTail( s, n );
+		}
 		// Remove and return the head element in the sequence.
 		T & dropHead( Sequence(T) & s ) {
@@ -181,10 +166,8 @@
 			return &n ? remove( s, n ), n : *0p;
 		}
-
 		// Remove and return the head element in the sequence.
 		T & drop( Sequence(T) & s ) {
 			return dropHead( s );
 		}
-
 		// Remove and return the tail element in the sequence.
 		T & dropTail( Sequence(T) & s ) {
@@ -201,7 +184,7 @@
 				T * toEnd = Back( &head( s ) );
 				T * fromEnd = Back( &head( from ) );
-				Back( (T *)root ) = fromEnd;
+				Back( root ) = fromEnd;
 				Next( fromEnd ) = &head( s );
-				Back( (T *)from.root ) = toEnd;
+				Back( from.root ) = toEnd;
 				Next( toEnd ) = &head( from );
 			} // if
@@ -231,5 +214,5 @@
 } // distribution
 
-forall( dtype T | { T *& Back ( T * ); T *& Next ( T * ); } ) {
+forall( dtype T ) {
 	// SeqIter(T) is used to iterate over a Sequence(T) in head-to-tail order.
 	struct SeqIter {
@@ -241,16 +224,15 @@
 	};
 
-	static inline {
+	inline {
 		void ?{}( SeqIter(T) & si ) with( si ) {
 			((ColIter &)si){};
 			seq = 0p;
-		} // post: elts = null
-
-		// Create a iterator active in sequence s.
+		} // post: elts = null.
+
 		void ?{}( SeqIter(T) & si, Sequence(T) & s ) with( si ) {
 			((ColIter &)si){};
 			seq = &s;
 			curr = &head( s );
-		} // post: elts = null
+		} // post: elts = null.
 
 		void ?{}( SeqIter(T) & si, Sequence(T) & s, T & start ) with( si ) {
@@ -258,13 +240,12 @@
 			seq = &s;
 			curr = &start;
-		} // post: elts = null
-
-		// Make the iterator active in sequence s.
+		} // post: elts = null.
+
 		void over( SeqIter(T) & si, Sequence(T) & s ) with( si ) {
 			seq = &s;
 			curr = &head( s );
-		} // post: elts = {e in s}
-
-		bool ?|?( SeqIter(T) & si, T && tp ) with( si ) {
+		} // post: elts = {e in s}.
+
+		bool ?>>?( SeqIter(T) & si, T && tp ) with( si ) {
 			if ( curr ) {
 				&tp = Curr( si );
@@ -284,16 +265,15 @@
 	};
 
-	static inline {
+	inline {
 		void ?{}( SeqIterRev(T) & si ) with( si ) {	
 			((ColIter &)si){};
 			seq = 0p;
-		} // post: elts = null
-
-		// Create a iterator active in sequence s.
+		} // post: elts = null.
+
 		void ?{}( SeqIterRev(T) & si, Sequence(T) & s ) with( si ) {	
 			((ColIter &)si){};
 			seq = &s;
 			curr = &tail( s );
-		} // post: elts = null
+		} // post: elts = null.
 
 		void ?{}( SeqIterRev(T) & si, Sequence(T) & s, T & start ) with( si ) {	
@@ -301,13 +281,12 @@
 			seq = &s;
 			curr = &start;
-		} // post: elts = null
-
-		// Make the iterator active in sequence s.
+		} // post: elts = null.
+
 		void over( SeqIterRev(T) & si, Sequence(T) & s ) with( si ) {
 			seq = &s;
 			curr = &tail( s );
-		} // post: elts = {e in s}
-
-		bool ?|?( SeqIterRev(T) & si, T && tp ) with( si ) {
+		} // post: elts = {e in s}.
+
+		bool ?>>?( SeqIterRev(T) & si, T && tp ) with( si ) {
 			if ( curr ) {
 				&tp = Curr( si );
@@ -319,4 +298,2 @@
 	} // distribution
 } // distribution
-
-#endif
Index: libcfa/src/bits/stack.hfa
===================================================================
--- libcfa/src/bits/stack.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/bits/stack.hfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -3,11 +3,5 @@
 #include "bits/collection.hfa"
 
-// A Stack(T) is a Collection(T) defining the ordering that nodes are returned by drop() in the reverse order from those
-// added by add(). T must be a public descendant of uColable.
-
-// The implementation is a typical singly-linked list, except the next field of the last element points to itself
-// instead of being null.
-
-forall( dtype T | { T *& Next ( T * ); } ) {
+forall( dtype T ) {
 	struct Stack {
 		inline Collection;								// Plan 9 inheritance
@@ -31,5 +25,5 @@
 		}
 
-		T & addHead( Stack(T) & s, T & n ) with( s ) {
+		void addHead( Stack(T) & s, T & n ) with( s ) {
 			#ifdef __CFA_DEBUG__
 			if ( listed( (Colable &)(n) ) ) abort( "(Stack &)%p.addHead( %p ) : Node is already on another list.", &s, n );
@@ -37,13 +31,12 @@
 			Next( &n ) = &head( s ) ? &head( s ) : &n;
 			root = &n;
-			return n;
 		}
 
-		T & add( Stack(T) & s, T & n ) with( s ) {
-			return addHead( s, n );
+		void add( Stack(T) & s, T & n ) with( s ) {
+			addHead( s, n );
 		}
 
-		T & push( Stack(T) & s, T & n ) with( s ) {
-			return addHead( s, n );
+		void push( Stack(T) & s, T & n ) with( s ) {
+			addHead( s, n );
 		}
 
@@ -51,5 +44,5 @@
 			T & t = head( s );
 			if ( root ) {
-				root = ( T *)Next( (T *)root );
+				root = ( T *)Next( root );
 				if ( &head( s ) == &t ) root = 0p;		// only one element ?
 				Next( &t ) = 0p;
@@ -64,8 +57,6 @@
 } // distribution
 
-// A StackIter(T) is a subclass of ColIter(T) that generates the elements of a Stack(T).  It returns the elements in the
-// order returned by drop().
 
-forall( dtype T | { T *& Next ( T * ); } ) {
+forall( dtype T ) {
 	struct StackIter {
 		inline ColIter;									// Plan 9 inheritance
@@ -77,5 +68,5 @@
 		} // post: curr == 0p
 
-		// create an iterator active in stack s
+		// create an iterator active in Stack s
 		void ?{}( StackIter(T) & si, Stack(T) & s ) with( si ) {
 			curr = &head( s );
@@ -86,10 +77,10 @@
 		} // post: curr = {e in s}
 
-		// make existing iterator active in stack s
+		// make existing iterator active in Stack q
 		void over( StackIter(T) & si, Stack(T) & s ) with( si ) {
 			curr = &head( s );
 		} // post: curr = {e in s}
 
-		bool ?|?( StackIter(T) & si, T && tp ) with( si ) {
+		bool ?>>?( StackIter(T) & si, T && tp ) with( si ) {
 			if ( curr ) {
 				&tp = Curr( si );
Index: bcfa/src/concurrency/future.hfa
===================================================================
--- libcfa/src/concurrency/future.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,119 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2020 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// io/types.hfa --
-//
-// Author           : Thierry Delisle & Peiran Hong
-// Created On       : Wed Jan 06 17:33:18 2021
-// Last Modified By :
-// Last Modified On :
-// Update Count     :
-//
-
-#pragma once
-
-#include "bits/locks.hfa"
-#include "monitor.hfa"
-
-forall( otype T ) {
-	struct future {
-		inline future_t;
-		T result;
-	};
-
-	static inline {
-		// Reset future back to original state
-		void reset(future(T) & this) { reset( (future_t&)this ); }
-
-		// check if the future is available
-		bool available( future(T) & this ) { return available( (future_t&)this ); }
-
-		// Mark the future as abandoned, meaning it will be deleted by the server
-		// This doesn't work beause of the potential need for a destructor
-		void abandon( future(T) & this );
-
-		// Fulfil the future, returns whether or not someone was unblocked
-		bool fulfil( future(T) & this, T result ) {
-			this.result = result;
-			return fulfil( (future_t&)this );
-		}
-
-		// Wait for the future to be fulfilled
-		// Also return whether the thread had to block or not
-		[T, bool] wait( future(T) & this ) {
-			bool r = wait( (future_t&)this );
-			return [this.result, r];
-		}
-
-		// Wait for the future to be fulfilled
-		T wait( future(T) & this ) {
-			[T, bool] tt;
-			tt = wait(this);
-			return tt.0;
-		}
-	}
-}
-
-forall( otype T ) {
-	monitor multi_future {
-		inline future_t;
-		condition blocked;
-		bool has_first;
-		T result;
-	};
-
-	static inline {
-		void ?{}(multi_future(T) & this) {
-			this.has_first = false;
-		}
-
-		bool $first( multi_future(T) & mutex this ) {
-			if (this.has_first) {
-				wait( this.blocked );
-				return false;
-			}
-
-			this.has_first = true;
-			return true;
-		}
-
-		void $first_done( multi_future(T) & mutex this ) {
-			this.has_first = false;
-			signal_all( this.blocked );
-		}
-
-		// Reset future back to original state
-		void reset(multi_future(T) & mutex this) {
-			if( this.has_first != false) abort("Attempting to reset a multi_future with at least one blocked threads");
-			if( !is_empty(this.blocked) ) abort("Attempting to reset a multi_future with multiple blocked threads");
-			reset( (future_t&)this );
-		}
-
-		// Fulfil the future, returns whether or not someone was unblocked
-		bool fulfil( multi_future(T) & this, T result ) {
-			this.result = result;
-			return fulfil( (future_t&)this );
-		}
-
-		// Wait for the future to be fulfilled
-		// Also return whether the thread had to block or not
-		[T, bool] wait( multi_future(T) & this ) {
-			bool sw = $first( this );
-			bool w = !sw;
-			if ( sw ) {
-				w = wait( (future_t&)this );
-				$first_done( this );
-			}
-
-			return [this.result, w];
-		}
-
-		// Wait for the future to be fulfilled
-		T wait( multi_future(T) & this ) {
-			return wait(this).0;
-		}
-	}
-}
Index: libcfa/src/concurrency/invoke.h
===================================================================
--- libcfa/src/concurrency/invoke.h	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/concurrency/invoke.h	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -189,10 +189,4 @@
 		struct __monitor_group_t monitors;
 
-		// used to put threads on user data structures
-		struct {
-			struct $thread * next;
-			struct $thread * back;
-		} seqable;
-
 		struct {
 			struct $thread * next;
@@ -224,16 +218,4 @@
 		}
 
-		static inline $thread *& Back( $thread * this ) __attribute__((const)) {
-			return this->seqable.back;
-		}
-
-		static inline $thread *& Next( $thread * this ) __attribute__((const)) {
-			return this->seqable.next;
-		}
-
-		static inline bool listed( $thread * this ) {
-			return this->seqable.next != 0p;
-		}
-
 		static inline void ?{}(__monitor_group_t & this) {
 			(this.data){0p};
Index: libcfa/src/concurrency/kernel/startup.cfa
===================================================================
--- libcfa/src/concurrency/kernel/startup.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/concurrency/kernel/startup.cfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -118,5 +118,4 @@
 
 extern size_t __page_size;
-extern int __map_prot;
 
 //-----------------------------------------------------------------------------
@@ -726,10 +725,4 @@
 		}
 	#else
-		__cfaabi_dbg_debug_do(
-			// pthread has no mechanism to create the guard page in user supplied stack.
-			if ( mprotect( stack, __page_size, __map_prot ) == -1 ) {
-				abort( "mprotect : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
-			} // if
-		);
 		free( stack );
 	#endif
Index: libcfa/src/concurrency/locks.cfa
===================================================================
--- libcfa/src/concurrency/locks.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/concurrency/locks.cfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -1,48 +1,38 @@
 #include "locks.hfa"
 #include "kernel_private.hfa"
+#include <stdlib.h>
+#include <stdio.h>
 
 #include <kernel.hfa>
 #include <stdlib.hfa>
-
-//-----------------------------------------------------------------------------
-// info_thread
+#include <thread.hfa>
+
+///////////////////////////////////////////////////////////////////
+//// info_thread
+///////////////////////////////////////////////////////////////////
+
 forall(dtype L | is_blocking_lock(L)) {
-	struct info_thread {
-		// used to put info_thread on a dl queue (aka sequence)
-		inline Seqable;
-
-		// waiting thread
-		struct $thread * t;
-
-		// shadow field
-		uintptr_t info;
-
-		// lock that is passed to wait() (if one is passed)
-		L * lock;
-
-		// true when signalled and false when timeout wakes thread
-		bool signalled;
-	};
-
-	void ?{}( info_thread(L) & this, $thread * t, uintptr_t info, L * l ) {
+	void ?{}( info_thread(L) & this, $thread * t ) {
+		((Seqable &) this){};
+		this.t = t;
+		this.lock = 0p;
+		this.listed = false;
+	}
+
+	void ?{}( info_thread(L) & this, $thread * t, uintptr_t info ) {
 		((Seqable &) this){};
 		this.t = t;
 		this.info = info;
-		this.lock = l;
-	}
-
-	void ^?{}( info_thread(L) & this ) {}
-
-	info_thread(L) *& Back( info_thread(L) * this ) {
-		return (info_thread(L) *)Back( (Seqable *)this );
-	}
-
-	info_thread(L) *& Next( info_thread(L) * this ) {
-		return (info_thread(L) *)Next( (Colable *)this );
-	}
-}
-
-//-----------------------------------------------------------------------------
-// Blocking Locks
+		this.lock = 0p;
+		this.listed = false;
+	}
+
+	void ^?{}( info_thread(L) & this ){ }
+}
+
+///////////////////////////////////////////////////////////////////
+//// Blocking Locks
+///////////////////////////////////////////////////////////////////
+
 void ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner ) {
 	this.lock{};
@@ -56,33 +46,25 @@
 
 void ^?{}( blocking_lock & this ) {}
-void  ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };}
+void ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };}
 void ^?{}( single_acquisition_lock & this ) {}
-void  ?{}( owner_lock & this ) {((blocking_lock &)this){ true, true };}
+void ?{}( owner_lock & this ) {((blocking_lock &)this){ true, true };}
 void ^?{}( owner_lock & this ) {}
-void  ?{}( multiple_acquisition_lock & this ) {((blocking_lock &)this){ true, false };}
+void ?{}( multiple_acquisition_lock & this ) {((blocking_lock &)this){ true, false };}
 void ^?{}( multiple_acquisition_lock & this ) {}
 
 void lock( blocking_lock & this ) with( this ) {
 	lock( lock __cfaabi_dbg_ctx2 );
-	$thread * thrd = active_thread();
-
-	// single acquisition lock is held by current thread
-	/* paranoid */ verifyf( owner != thrd || multi_acquisition, "Single acquisition lock holder (%p) attempted to reacquire the lock %p resulting in a deadlock.", owner, &this );
-
-	// lock is held by some other thread
-	if ( owner != 0p && owner != thrd ) {
-		addTail( blocked_threads, *thrd );
+	if ( owner == active_thread() && !multi_acquisition) {
+		abort("A single acquisition lock holder attempted to reacquire the lock resulting in a deadlock.");
+	} else if ( owner != 0p && owner != active_thread() ) {
+		append( blocked_threads, active_thread() );
 		wait_count++;
 		unlock( lock );
 		park( );
-	}
-	// multi acquisition lock is held by current thread
-	else if ( owner == thrd && multi_acquisition ) {
+	} else if ( owner == active_thread() && multi_acquisition ) {
 		recursion_count++;
 		unlock( lock );
-	}
-	// lock isn't held
-	else {
-		owner = thrd;
+	} else {
+		owner = active_thread();
 		recursion_count = 1;
 		unlock( lock );
@@ -93,23 +75,26 @@
 	bool ret = false;
 	lock( lock __cfaabi_dbg_ctx2 );
-
-	// lock isn't held
 	if ( owner == 0p ) {
 		owner = active_thread();
 		recursion_count = 1;
 		ret = true;
-	}
-	// multi acquisition lock is held by current thread
-	else if ( owner == active_thread() && multi_acquisition ) {
+	} else if ( owner == active_thread() && multi_acquisition ) {
 		recursion_count++;
 		ret = true;
 	}
-
 	unlock( lock );
 	return ret;
 }
 
+void unlock_error_check( blocking_lock & this ) with( this ) {
+	if ( owner == 0p ){ // no owner implies lock isn't held
+		abort( "There was an attempt to release a lock that isn't held" ); 
+	} else if ( strict_owner && owner != active_thread() ) {
+		abort( "A thread other than the owner attempted to release an owner lock" ); 
+	}
+}
+
 void pop_and_set_new_owner( blocking_lock & this ) with( this ) {
-	$thread * t = &dropHead( blocked_threads );
+	$thread * t = pop_head( blocked_threads );
 	owner = t;
 	recursion_count = ( t ? 1 : 0 );
@@ -120,8 +105,5 @@
 void unlock( blocking_lock & this ) with( this ) {
 	lock( lock __cfaabi_dbg_ctx2 );
-	/* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this );
-	/* paranoid */ verifyf( owner == active_thread() || !strict_owner, "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this );
-
-	// if recursion count is zero release lock and set new owner if one is waiting
+	unlock_error_check( this );
 	recursion_count--;
 	if ( recursion_count == 0 ) {
@@ -143,14 +125,11 @@
 }
 
-void on_notify( blocking_lock & this, $thread * t ) with( this ) {
-	lock( lock __cfaabi_dbg_ctx2 );
-	// lock held
+void add_( blocking_lock & this, $thread * t ) with( this ) {
+    lock( lock __cfaabi_dbg_ctx2 );
 	if ( owner != 0p ) {
-		addTail( blocked_threads, *t );
+		append( blocked_threads, t );
 		wait_count++;
 		unlock( lock );
-	}
-	// lock not held
-	else {
+	} else {
 		owner = t;
 		recursion_count = 1;
@@ -160,84 +139,62 @@
 }
 
-void on_wait( blocking_lock & this ) with( this ) {
-	lock( lock __cfaabi_dbg_ctx2 );
-	/* paranoid */ verifyf( owner != 0p, "Attempt to release lock %p that isn't held", &this );
-	/* paranoid */ verifyf( owner == active_thread() || !strict_owner, "Thread %p other than the owner %p attempted to release owner lock %p", owner, active_thread(), &this );
-
+void remove_( blocking_lock & this ) with( this ) {
+    lock( lock __cfaabi_dbg_ctx2 );
+	unlock_error_check( this );
 	pop_and_set_new_owner( this );
 	unlock( lock );
 }
 
-//-----------------------------------------------------------------------------
-// Overloaded routines for traits
-// These routines are temporary until an inheritance bug is fixed
-void   lock      ( single_acquisition_lock & this ) { lock   ( (blocking_lock &)this ); }
-void   unlock    ( single_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); }
-void   on_wait   ( single_acquisition_lock & this ) { on_wait( (blocking_lock &)this ); }
-void   on_notify ( single_acquisition_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }
-void   set_recursion_count( single_acquisition_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); }
-size_t get_recursion_count( single_acquisition_lock & this ) { return get_recursion_count( (blocking_lock &)this ); }
-
-void   lock     ( owner_lock & this ) { lock   ( (blocking_lock &)this ); }
-void   unlock   ( owner_lock & this ) { unlock ( (blocking_lock &)this ); }
-void   on_wait  ( owner_lock & this ) { on_wait( (blocking_lock &)this ); }
-void   on_notify( owner_lock & this, struct $thread * t ) { on_notify( (blocking_lock &)this, t ); }
-void   set_recursion_count( owner_lock & this, size_t recursion ) { set_recursion_count( (blocking_lock &)this, recursion ); }
-size_t get_recursion_count( owner_lock & this ) { return get_recursion_count( (blocking_lock &)this ); }
-
-void   lock     ( multiple_acquisition_lock & this ) { lock   ( (blocking_lock &)this ); }
-void   unlock   ( multiple_acquisition_lock & this ) { unlock ( (blocking_lock &)this ); }
-void   on_wait  ( multiple_acquisition_lock & this ) { on_wait( (blocking_lock &)this ); }
-void   on_notify( multiple_acquisition_lock & this, struct $thread * t ){ on_notify( (blocking_lock &)this, t ); }
-void   set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
+///////////////////////////////////////////////////////////////////
+//// Overloaded routines for traits
+///////////////////////////////////////////////////////////////////
+
+// This is temporary until an inheritance bug is fixed
+
+void lock( single_acquisition_lock & this ){ lock( (blocking_lock &)this ); }
+void unlock( single_acquisition_lock & this ){ unlock( (blocking_lock &)this ); }
+void add_( single_acquisition_lock & this, struct $thread * t ){ add_( (blocking_lock &)this, t ); }
+void remove_( single_acquisition_lock & this ){ remove_( (blocking_lock &)this ); }
+void set_recursion_count( single_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
+size_t get_recursion_count( single_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
+
+void lock( owner_lock & this ){ lock( (blocking_lock &)this ); }
+void unlock( owner_lock & this ){ unlock( (blocking_lock &)this ); }
+void add_( owner_lock & this, struct $thread * t ){ add_( (blocking_lock &)this, t ); }
+void remove_( owner_lock & this ){ remove_( (blocking_lock &)this ); }
+void set_recursion_count( owner_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
+size_t get_recursion_count( owner_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
+
+void lock( multiple_acquisition_lock & this ){ lock( (blocking_lock &)this ); }
+void unlock( multiple_acquisition_lock & this ){ unlock( (blocking_lock &)this ); }
+void add_( multiple_acquisition_lock & this, struct $thread * t ){ add_( (blocking_lock &)this, t ); }
+void remove_( multiple_acquisition_lock & this ){ remove_( (blocking_lock &)this ); }
+void set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
 size_t get_recursion_count( multiple_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
 
-//-----------------------------------------------------------------------------
-// alarm node wrapper
+///////////////////////////////////////////////////////////////////
+//// condition variable
+///////////////////////////////////////////////////////////////////
+
 forall(dtype L | is_blocking_lock(L)) {
-	struct alarm_node_wrap {
-		alarm_node_t alarm_node;
-		condition_variable(L) * cond;
-		info_thread(L) * i;
-	};
-
-	void ?{}( alarm_node_wrap(L) & this, Time alarm, Duration period, Alarm_Callback callback, condition_variable(L) * c, info_thread(L) * i ) {
-		this.alarm_node{ callback, alarm, period };
-		this.cond = c;
-		this.i = i;
-	}
-
-	void ^?{}( alarm_node_wrap(L) & this ) { }
 
 	void timeout_handler ( alarm_node_wrap(L) & this ) with( this ) {
-		// This condition_variable member is called from the kernel, and therefore, cannot block, but it can spin.
-		lock( cond->lock __cfaabi_dbg_ctx2 );
-
-		// this check is necessary to avoid a race condition since this timeout handler
-		// 	may still be called after a thread has been removed from the queue but
-		// 	before the alarm is unregistered
-		if ( listed(i) ) {	// is thread on queue
-			i->signalled = false;
-			// remove this thread O(1)
-			remove( cond->blocked_threads, *i );
+    	// This condition_variable member is called from the kernel, and therefore, cannot block, but it can spin.
+	    lock( cond->lock __cfaabi_dbg_ctx2 );
+	    
+	    if ( i->listed ) {			// is thread on queue
+	    	cond->last_thread = i;		// REMOVE THIS AFTER DEBUG
+			remove( cond->blocked_threads, *i );		 //remove this thread O(1)
 			cond->count--;
-			if( i->lock ) {
-				// call lock's on_notify if a lock was passed
-				on_notify(*i->lock, i->t);
-			} else {
-				// otherwise wake thread
+			if( !i->lock ) {
 				unpark( i->t );
-			}
-		}
-		unlock( cond->lock );
-	}
-
-	// this casts the alarm node to our wrapped type since we used type erasure
+	    	} else {
+	    		add_(*i->lock, i->t);			// call lock's add_
+	    	}
+	    }
+	    unlock( cond->lock );
+	}
+
 	void alarm_node_wrap_cast( alarm_node_t & a ) { timeout_handler( (alarm_node_wrap(L) &)a ); }
-}
-
-//-----------------------------------------------------------------------------
-// condition variable
-forall(dtype L | is_blocking_lock(L)) {
 
 	void ?{}( condition_variable(L) & this ){
@@ -245,17 +202,22 @@
 		this.blocked_threads{};
 		this.count = 0;
+		this.last_thread = 0p; // REMOVE AFTER DEBUG
 	}
 
 	void ^?{}( condition_variable(L) & this ){ }
+
+	void ?{}( alarm_node_wrap(L) & this, Time alarm, Duration period, Alarm_Callback callback ) {
+		this.alarm_node{ callback, alarm, period };
+	}
+
+	void ^?{}( alarm_node_wrap(L) & this ) { }
 
 	void process_popped( condition_variable(L) & this, info_thread(L) & popped ) with( this ) {
 		if(&popped != 0p) {
-			popped.signalled = true;
+			popped.listed = false;
 			count--;
 			if (popped.lock) {
-				// if lock passed call on_notify
-				on_notify(*popped.lock, popped.t);
+				add_(*popped.lock, popped.t);
 			} else {
-				// otherwise wake thread
 				unpark(popped.t);
 			}
@@ -290,12 +252,12 @@
 
 	size_t queue_and_get_recursion( condition_variable(L) & this, info_thread(L) * i ) with(this) {
-		// add info_thread to waiting queue
 		addTail( blocked_threads, *i );
 		count++;
+		i->listed = true;
 		size_t recursion_count = 0;
 		if (i->lock) {
-			// if lock was passed get recursion count to reset to after waking thread
+			i->t->link.next = 1p;
 			recursion_count = get_recursion_count(*i->lock);
-			on_wait( *i->lock );
+			remove_( *i->lock );
 		}
 		return recursion_count;
@@ -307,15 +269,7 @@
 		size_t recursion_count = queue_and_get_recursion(this, &i);
 		unlock( lock );
-
-		// blocks here
-		park( );
-
-		// resets recursion count here after waking
-		if (i.lock) set_recursion_count(*i.lock, recursion_count);
-	}
-
-	#define WAIT( u, l ) \
-		info_thread( L ) i = { active_thread(), u, l }; \
-		queue_info_thread( this, i );
+		park( ); // blocks here
+		if (i.lock) set_recursion_count(*i.lock, recursion_count); // resets recursion count here after waking
+	}
 
 	// helper for wait()'s' with a timeout
@@ -323,35 +277,78 @@
 		lock( lock __cfaabi_dbg_ctx2 );
 		size_t recursion_count = queue_and_get_recursion(this, &info);
-		alarm_node_wrap(L) node_wrap = { t, 0`s, alarm_node_wrap_cast, &this, &info };
+		alarm_node_wrap(L) node_wrap = { t, 0`s, alarm_node_wrap_cast };
+		node_wrap.cond = &this;
+		node_wrap.i = &info;
 		register_self( &node_wrap.alarm_node );
 		unlock( lock );
-
-		// blocks here
 		park();
-
-		// unregisters alarm so it doesn't go off if this happens first
 		unregister_self( &node_wrap.alarm_node );
-
-		// resets recursion count here after waking
 		if (info.lock) set_recursion_count(*info.lock, recursion_count);
 	}
 
-	#define WAIT_TIME( u, l, t ) \
-		info_thread( L ) i = { active_thread(), u, l }; \
-		queue_info_thread_timeout(this, i, t ); \
-		return i.signalled;
-
-	void wait( condition_variable(L) & this                        ) with(this) { WAIT( 0, 0p    ) }
-	void wait( condition_variable(L) & this, uintptr_t info        ) with(this) { WAIT( info, 0p ) }
-	void wait( condition_variable(L) & this, L & l                 ) with(this) { WAIT( 0, &l    ) }
-	void wait( condition_variable(L) & this, L & l, uintptr_t info ) with(this) { WAIT( info, &l ) }
-
-	bool wait( condition_variable(L) & this, Duration duration                        ) with(this) { WAIT_TIME( 0   , 0p , __kernel_get_time() + duration ) }
-	bool wait( condition_variable(L) & this, uintptr_t info, Duration duration        ) with(this) { WAIT_TIME( info, 0p , __kernel_get_time() + duration ) }
-	bool wait( condition_variable(L) & this, Time time                                ) with(this) { WAIT_TIME( 0   , 0p , time ) }
-	bool wait( condition_variable(L) & this, uintptr_t info, Time time                ) with(this) { WAIT_TIME( info, 0p , time ) }
-	bool wait( condition_variable(L) & this, L & l, Duration duration                 ) with(this) { WAIT_TIME( 0   , &l , __kernel_get_time() + duration ) }
-	bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ) with(this) { WAIT_TIME( info, &l , __kernel_get_time() + duration ) }
-	bool wait( condition_variable(L) & this, L & l, Time time                         ) with(this) { WAIT_TIME( 0   , &l , time ) }
-	bool wait( condition_variable(L) & this, L & l, uintptr_t info, Time time         ) with(this) { WAIT_TIME( info, &l , time ) }
-}
+	void wait( condition_variable(L) & this ) with(this) {
+		info_thread( L ) i = { active_thread() };
+		queue_info_thread( this, i );
+	}
+
+	void wait( condition_variable(L) & this, uintptr_t info ) with(this) {
+		info_thread( L ) i = { active_thread(), info };
+		queue_info_thread( this, i );
+	}
+	
+	void wait( condition_variable(L) & this, Duration duration ) with(this) {
+		info_thread( L ) i = { active_thread() };
+		queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
+	}
+
+	void wait( condition_variable(L) & this, uintptr_t info, Duration duration ) with(this) { 
+		info_thread( L ) i = { active_thread(), info };
+		queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
+	}
+
+	void wait( condition_variable(L) & this, Time time ) with(this) {
+		info_thread( L ) i = { active_thread() };
+		queue_info_thread_timeout(this, i, time);
+	}
+
+	void wait( condition_variable(L) & this, uintptr_t info, Time time ) with(this) {
+		info_thread( L ) i = { active_thread(), info };
+		queue_info_thread_timeout(this, i, time);
+	}
+
+	void wait( condition_variable(L) & this, L & l ) with(this) {
+		info_thread(L) i = { active_thread() };
+		i.lock = &l;
+		queue_info_thread( this, i );
+	}
+
+	void wait( condition_variable(L) & this, L & l, uintptr_t info ) with(this) {
+		info_thread(L) i = { active_thread(), info };
+		i.lock = &l;
+		queue_info_thread( this, i );
+	}
+	
+	void wait( condition_variable(L) & this, L & l, Duration duration ) with(this) {
+		info_thread(L) i = { active_thread() };
+		i.lock = &l;
+		queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
+	}
+	
+	void wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration ) with(this) {
+		info_thread(L) i = { active_thread(), info };
+		i.lock = &l;
+		queue_info_thread_timeout(this, i, __kernel_get_time() + duration );
+	}
+	
+	void wait( condition_variable(L) & this, L & l, Time time ) with(this) {
+		info_thread(L) i = { active_thread() };
+		i.lock = &l;
+		queue_info_thread_timeout(this, i, time );
+	}
+	
+	void wait( condition_variable(L) & this, L & l, uintptr_t info, Time time ) with(this) {
+		info_thread(L) i = { active_thread(), info };
+		i.lock = &l;
+		queue_info_thread_timeout(this, i, time );
+	}
+}
Index: libcfa/src/concurrency/locks.hfa
===================================================================
--- libcfa/src/concurrency/locks.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/concurrency/locks.hfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -3,6 +3,8 @@
 #include <stdbool.h>
 
+#include "bits/algorithm.hfa"
 #include "bits/locks.hfa"
 #include "bits/sequence.hfa"
+#include "bits/containers.hfa"
 
 #include "invoke.h"
@@ -10,35 +12,51 @@
 #include "time_t.hfa"
 #include "time.hfa"
+#include <sys/time.h>
+#include "alarm.hfa"
 
-//-----------------------------------------------------------------------------
-// is_blocking_lock
+///////////////////////////////////////////////////////////////////
+//// is_blocking_lock
+///////////////////////////////////////////////////////////////////
+
 trait is_blocking_lock(dtype L | sized(L)) {
-	// For synchronization locks to use when acquiring
-	void on_notify( L &, struct $thread * );
-
-	// For synchronization locks to use when releasing
-	void on_wait( L & );
-
-	// to get recursion count for cond lock to reset after waking
-	size_t get_recursion_count( L & );
-
-	// to set recursion count after getting signalled;
-	void set_recursion_count( L &, size_t recursion );
+	void add_( L &, struct $thread * );		// For synchronization locks to use when acquiring
+	void remove_( L & );    // For synchronization locks to use when releasing
+	size_t get_recursion_count( L & ); // to get recursion count for cond lock to reset after waking
+	void set_recursion_count( L &, size_t recursion ); // to set recursion count after getting signalled;
 };
 
-//-----------------------------------------------------------------------------
-// info_thread
-// the info thread is a wrapper around a thread used
-// to store extra data for use in the condition variable
+///////////////////////////////////////////////////////////////////
+//// info_thread
+///////////////////////////////////////////////////////////////////
+
 forall(dtype L | is_blocking_lock(L)) {
-	struct info_thread;
+	struct info_thread {
+		inline Seqable;
+		struct $thread * t;
+		uintptr_t info;
+		L * lock;
+		bool listed;					// true if info_thread is on queue, false otherwise;
+	};
 
-	// for use by sequence
-	info_thread(L) *& Back( info_thread(L) * this );
-	info_thread(L) *& Next( info_thread(L) * this );
+
+	void ?{}( info_thread(L) & this, $thread * t );
+	void ?{}( info_thread(L) & this, $thread * t, uintptr_t info );
+	void ^?{}( info_thread(L) & this );
 }
 
-//-----------------------------------------------------------------------------
-// Blocking Locks
+///////////////////////////////////////////////////////////////////
+//// Blocking Locks
+///////////////////////////////////////////////////////////////////
+
+// struct lock_thread {
+// 	struct $thread * t;
+// 	lock_thread * next;
+// };
+
+// void ?{}( lock_thread & this, struct $thread * thd );
+// void ^?{}( lock_thread & this );
+
+// lock_thread *& get_next( lock_thread & );
+
 struct blocking_lock {
 	// Spin lock used for mutual exclusion
@@ -46,5 +64,5 @@
 
 	// List of blocked threads
-	Sequence( $thread ) blocked_threads;
+	__queue_t( $thread ) blocked_threads;
 
 	// Count of current blocked threads
@@ -76,14 +94,14 @@
 };
 
-void  ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner );
+void ?{}( blocking_lock & this, bool multi_acquisition, bool strict_owner );
 void ^?{}( blocking_lock & this );
 
-void  ?{}( single_acquisition_lock & this );
+void ?{}( single_acquisition_lock & this );
 void ^?{}( single_acquisition_lock & this );
 
-void  ?{}( owner_lock & this );
+void ?{}( owner_lock & this );
 void ^?{}( owner_lock & this );
 
-void  ?{}( multiple_acquisition_lock & this );
+void ?{}( multiple_acquisition_lock & this );
 void ^?{}( multiple_acquisition_lock & this );
 
@@ -91,6 +109,6 @@
 bool try_lock( blocking_lock & this );
 void unlock( blocking_lock & this );
-void on_notify( blocking_lock & this, struct $thread * t );
-void on_wait( blocking_lock & this );
+void add_( blocking_lock & this, struct $thread * t );
+void remove_( blocking_lock & this );
 size_t wait_count( blocking_lock & this );
 void set_recursion_count( blocking_lock & this, size_t recursion );
@@ -99,6 +117,6 @@
 void lock( single_acquisition_lock & this );
 void unlock( single_acquisition_lock & this );
-void on_notify( single_acquisition_lock & this, struct $thread * t );
-void on_wait( single_acquisition_lock & this );
+void add_( single_acquisition_lock & this, struct $thread * t );
+void remove_( single_acquisition_lock & this );
 void set_recursion_count( single_acquisition_lock & this, size_t recursion );
 size_t get_recursion_count( single_acquisition_lock & this );
@@ -106,6 +124,6 @@
 void lock( owner_lock & this );
 void unlock( owner_lock & this );
-void on_notify( owner_lock & this, struct $thread * t );
-void on_wait( owner_lock & this );
+void add_( owner_lock & this, struct $thread * t );
+void remove_( owner_lock & this );
 void set_recursion_count( owner_lock & this, size_t recursion );
 size_t get_recursion_count( owner_lock & this );
@@ -113,15 +131,18 @@
 void lock( multiple_acquisition_lock & this );
 void unlock( multiple_acquisition_lock & this );
-void on_notify( multiple_acquisition_lock & this, struct $thread * t );
-void on_wait( multiple_acquisition_lock & this );
+void add_( multiple_acquisition_lock & this, struct $thread * t );
+void remove_( multiple_acquisition_lock & this );
 void set_recursion_count( multiple_acquisition_lock & this, size_t recursion );
 size_t get_recursion_count( multiple_acquisition_lock & this );
 
-//-----------------------------------------------------------------------------
-// Synchronization Locks
+///////////////////////////////////////////////////////////////////
+//// Synchronization Locks
+///////////////////////////////////////////////////////////////////
 forall(dtype L | is_blocking_lock(L)) {
 	struct condition_variable {
 		// Spin lock used for mutual exclusion
 		__spinlock_t lock;
+
+		info_thread(L) * last_thread;
 
 		// List of blocked threads
@@ -132,6 +153,21 @@
 	};
 
-	void  ?{}( condition_variable(L) & this );
+	void ?{}( condition_variable(L) & this );
 	void ^?{}( condition_variable(L) & this );
+
+	struct alarm_node_wrap {
+		alarm_node_t alarm_node;
+
+		condition_variable(L) * cond;
+
+		info_thread(L) * i;
+	};
+
+	void ?{}( alarm_node_wrap(L) & this, Time alarm, Duration period, Alarm_Callback callback );
+	void ^?{}( alarm_node_wrap(L) & this );
+
+	void alarm_node_callback( alarm_node_wrap(L) & this );
+
+	void alarm_node_wrap_cast( alarm_node_t & a );
 
 	bool notify_one( condition_variable(L) & this );
@@ -140,19 +176,20 @@
 	uintptr_t front( condition_variable(L) & this );
 
-	bool empty  ( condition_variable(L) & this );
-	int  counter( condition_variable(L) & this );
+	bool empty( condition_variable(L) & this );
+	int counter( condition_variable(L) & this );
 
+	// TODO: look into changing timout routines to return bool showing if signalled or woken by kernel
 	void wait( condition_variable(L) & this );
 	void wait( condition_variable(L) & this, uintptr_t info );
-	bool wait( condition_variable(L) & this, Duration duration );
-	bool wait( condition_variable(L) & this, uintptr_t info, Duration duration );
-	bool wait( condition_variable(L) & this, Time time );
-	bool wait( condition_variable(L) & this, uintptr_t info, Time time );
+	void wait( condition_variable(L) & this, Duration duration );
+	void wait( condition_variable(L) & this, uintptr_t info, Duration duration );
+	void wait( condition_variable(L) & this, Time time );
+	void wait( condition_variable(L) & this, uintptr_t info, Time time );
 
 	void wait( condition_variable(L) & this, L & l );
 	void wait( condition_variable(L) & this, L & l, uintptr_t info );
-	bool wait( condition_variable(L) & this, L & l, Duration duration );
-	bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration );
-	bool wait( condition_variable(L) & this, L & l, Time time );
-	bool wait( condition_variable(L) & this, L & l, uintptr_t info, Time time );
+	void wait( condition_variable(L) & this, L & l, Duration duration );
+	void wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration );
+	void wait( condition_variable(L) & this, L & l, Time time );
+	void wait( condition_variable(L) & this, L & l, uintptr_t info, Time time );
 }
Index: libcfa/src/concurrency/monitor.hfa
===================================================================
--- libcfa/src/concurrency/monitor.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/concurrency/monitor.hfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -132,8 +132,7 @@
 
               void wait        ( condition & this, uintptr_t user_info = 0 );
-static inline bool is_empty    ( condition & this ) { return this.blocked.head == 1p; }
               bool signal      ( condition & this );
               bool signal_block( condition & this );
-static inline bool signal_all  ( condition & this ) { bool ret = false; while(!is_empty(this)) { ret = signal(this) || ret; } return ret; }
+static inline bool is_empty    ( condition & this ) { return this.blocked.head == 1p; }
          uintptr_t front       ( condition & this );
 
Index: libcfa/src/concurrency/thread.cfa
===================================================================
--- libcfa/src/concurrency/thread.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/concurrency/thread.cfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -43,7 +43,4 @@
 		canary = 0x0D15EA5E0D15EA5Ep;
 	#endif
-
-	seqable.next = 0p;
-	seqable.back = 0p;
 
 	node.next = 0p;
@@ -133,5 +130,5 @@
 
 	this_thrd->context.[SP, FP] = this_thrd->self_cor.context.[SP, FP];
-	/* paranoid */ verify( this_thrd->context.SP );
+	verify( this_thrd->context.SP );
 
 	__schedule_thread( this_thrd );
Index: libcfa/src/heap.cfa
===================================================================
--- libcfa/src/heap.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/heap.cfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -10,6 +10,6 @@
 // Created On       : Tue Dec 19 21:58:35 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Dec 16 12:28:25 2020
-// Update Count     : 1023
+// Last Modified On : Tue Dec 15 21:37:54 2020
+// Update Count     : 1013
 //
 
@@ -438,5 +438,5 @@
 	header = headerAddr( addr );
 
-  if ( unlikely( addr < heapBegin || heapEnd < addr ) ) { // mmapped ?
+  if ( unlikely( heapEnd < addr ) ) {					// mmapped ?
 		fakeHeader( header, alignment );
 		size = header->kind.real.blockSize & -3;		// mmap size
@@ -445,5 +445,5 @@
 
 	#ifdef __CFA_DEBUG__
-	checkHeader( header < (HeapManager.Storage.Header *)heapBegin, name, addr ); // bad low address ?
+	checkHeader( addr < heapBegin, name, addr );		// bad low address ?
 	#endif // __CFA_DEBUG__
 
@@ -484,7 +484,7 @@
 #endif // __CFA_DEBUG__
 
-
 #define NO_MEMORY_MSG "insufficient heap memory available for allocating %zd new bytes."
 
+#include <unistd.h>
 static inline void * extend( size_t size ) with( heapManager ) {
 	lock( extlock __cfaabi_dbg_ctx2 );
@@ -511,5 +511,5 @@
 		#ifdef __CFA_DEBUG__
 		// Set new memory to garbage so subsequent uninitialized usages might fail.
-		memset( (char *)heapEnd + heapRemaining, '\xde', increase );
+		memset( (char *)heapEnd + heapRemaining, '\hde', increase );
 		//Memset( (char *)heapEnd + heapRemaining, increase );
 		#endif // __CFA_DEBUG__
@@ -586,5 +586,5 @@
 		#ifdef __CFA_DEBUG__
 		// Set new memory to garbage so subsequent uninitialized usages might fail.
-		memset( block, '\xde', tsize );
+		memset( block, '\hde', tsize );
 		//Memset( block, tsize );
 		#endif // __CFA_DEBUG__
@@ -634,5 +634,5 @@
 		#ifdef __CFA_DEBUG__
 		// Set free memory to garbage so subsequent usages might fail.
-		memset( ((HeapManager.Storage *)header)->data, '\xde', freeElem->blockSize - sizeof( HeapManager.Storage ) );
+		memset( ((HeapManager.Storage *)header)->data, '\hde', freeElem->blockSize - sizeof( HeapManager.Storage ) );
 		//Memset( ((HeapManager.Storage *)header)->data, freeElem->blockSize - sizeof( HeapManager.Storage ) );
 		#endif // __CFA_DEBUG__
@@ -1029,5 +1029,4 @@
 	} // cmemalign
 
-
 	// Same as memalign(), but ISO/IEC 2011 C11 Section 7.22.2 states: the value of size shall be an integral multiple
     // of alignment. This requirement is universally ignored.
@@ -1046,5 +1045,4 @@
 		return 0;
 	} // posix_memalign
-
 
 	// Allocates size bytes and returns a pointer to the allocated memory. The memory address shall be a multiple of the
Index: libcfa/src/memory.cfa
===================================================================
--- libcfa/src/memory.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/memory.cfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -66,5 +66,5 @@
 forall(dtype T | sized(T), ttype Args | { void ?{}(T&, Args); })
 void ?{}(counter_ptr(T) & this, Args args) {
-	this.data = (counter_data(T)*)new(args);
+	this.data = new(args);
 }
 
@@ -126,5 +126,5 @@
 forall(dtype T | sized(T), ttype Args | { void ?{}(T &, Args); })
 void ?{}(unique_ptr(T) & this, Args args) {
-	this.data = (T *)new(args);
+	this.data = new(args);
 }
 
Index: libcfa/src/parseargs.cfa
===================================================================
--- libcfa/src/parseargs.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/parseargs.cfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -105,5 +105,4 @@
 					if(opt == options[i].short_name) {
 						const char * arg = optarg ? optarg : "";
-						if( arg[0] == '=' ) { arg++; }
 						bool success = options[i].parse( arg, options[i].variable );
 						if(success) continue NEXT_ARG;
@@ -186,18 +185,4 @@
 }
 
-bool parse_truefalse(const char * arg, bool & value) {
-	if(strcmp(arg, "true") == 0) {
-		value = true;
-		return true;
-	}
-
-	if(strcmp(arg, "false") == 0) {
-		value = false;
-		return true;
-	}
-
-	return false;
-}
-
 bool parse_settrue (const char *, bool & value ) {
 	value = true;
Index: libcfa/src/parseargs.hfa
===================================================================
--- libcfa/src/parseargs.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/parseargs.hfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -37,8 +37,7 @@
 void print_args_usage(int argc, char * argv[], cfa_option options[], size_t opt_count, const char * usage, bool error)  __attribute__ ((noreturn));
 
-bool parse_yesno    (const char *, bool & );
-bool parse_truefalse(const char *, bool & );
-bool parse_settrue  (const char *, bool & );
-bool parse_setfalse (const char *, bool & );
+bool parse_yesno   (const char *, bool & );
+bool parse_settrue (const char *, bool & );
+bool parse_setfalse(const char *, bool & );
 
 bool parse(const char *, const char * & );
Index: libcfa/src/stdlib.hfa
===================================================================
--- libcfa/src/stdlib.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ libcfa/src/stdlib.hfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -267,5 +267,5 @@
 static inline forall( dtype T | sized(T), ttype TT | { void ?{}( T &, TT ); } )
 T * new( TT p ) {
-	return &(*(T *)malloc()){ p };							// run constructor
+	return &(*malloc()){ p };							// run constructor
 } // new
 
Index: bcfa/src/vec/vec.hfa
===================================================================
--- libcfa/src/vec/vec.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,135 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2021 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// io/types.hfa --
-//
-// Author           : Dimitry Kobets
-// Created On       :
-// Last Modified By :
-// Last Modified On :
-// Update Count     :
-//
-
-#pragma once
-
-#include <math.hfa>
-
-trait fromint(otype T) {
-    void ?{}(T&, int);
-};
-trait zeroinit(otype T) {
-    void ?{}(T&, zero_t);
-};
-trait zero_assign(otype T) {
-    T ?=?(T&, zero_t);
-};
-trait subtract(otype T) {
-    T ?-?(T, T);
-};
-trait negate(otype T) {
-    T -?(T);
-};
-trait add(otype T) {
-    T ?+?(T, T);
-};
-trait multiply(otype T) {
-    T ?*?(T, T);
-};
-trait divide(otype T) {
-    T ?/?(T, T);
-};
-trait lessthan(otype T) {
-    int ?<?(T, T);
-};
-trait equality(otype T) {
-    int ?==?(T, T);
-};
-trait sqrt(otype T) {
-    T sqrt(T);
-};
-
-static inline {
-// int
-int ?=?(int& n, zero_t) { return n = 0.f; }
-// unsigned int
-int ?=?(unsigned int& n, zero_t) { return n = 0.f; }
-/* float */
-void ?{}(float& a, int b) { a = b; }
-float ?=?(float& n, zero_t) { return n = 0.f; }
-/* double */
-void ?{}(double& a, int b) { a = b; }
-double ?=?(double& n, zero_t) { return n = 0L; }
-// long double
-void ?{}(long double& a, int b) { a = b; }
-long double ?=?(long double& n, zero_t) { return n = 0L; }
-}
-
-trait dottable(otype V, otype T) {
-    T dot(V, V);
-};
-
-static inline {
-
-forall(otype T | sqrt(T), otype V | dottable(V, T))
-T length(V v) {
-   return sqrt(dot(v, v));
-}
-
-forall(otype T, otype V | dottable(V, T))
-T length_squared(V v) {
-   return dot(v, v);
-}
-
-forall(otype T, otype V | { T length(V); } | subtract(V))
-T distance(V v1, V v2) {
-    return length(v1 - v2);
-}
-
-forall(otype T, otype V | { T length(V); V ?/?(V, T); })
-V normalize(V v) {
-    return v / length(v);
-}
-
-// Project vector u onto vector v
-forall(otype T, otype V | dottable(V, T) | { V normalize(V); V ?*?(V, T); })
-V project(V u, V v) {
-    V v_norm = normalize(v);
-    return v_norm * dot(u, v_norm);
-}
-
-// Reflect incident vector v with respect to surface with normal n
-forall(otype T | fromint(T), otype V | { V project(V, V); V ?*?(T, V); V ?-?(V,V); })
-V reflect(V v, V n) {
-    return v - (T){2} * project(v, n);
-}
-
-// Refract incident vector v with respect to surface with normal n
-// eta is the ratio of indices of refraction between starting material and
-// entering material (i.e., from air to water, eta = 1/1.33)
-// v and n must already be normalized
-forall(otype T | fromint(T) | subtract(T) | multiply(T) | add(T) | lessthan(T) | sqrt(T),
-       otype V | dottable(V, T) | { V ?*?(T, V); V ?-?(V,V); void ?{}(V&, zero_t); })
-V refract(V v, V n, T eta) {
-    T dotValue = dot(n, v);
-    T k = (T){1} - eta * eta * ((T){1} - dotValue * dotValue);
-    if (k < (T){0}) {
-        return 0;
-    }
-    return eta * v - (eta * dotValue + sqrt(k)) * n;
-}
-
-// Given a perturbed normal and a geometric normal,
-// flip the perturbed normal if the geometric normal is pointing away
-// from the observer.
-// n is the perturbed vector that we want to align
-// i is the incident vector
-// ng is the geometric normal of the surface
-forall(otype T | lessthan(T) | zeroinit(T), otype V | dottable(V, T) | negate(V))
-V faceforward(V n, V i, V ng) {
-    return dot(ng, i) < (T){0} ? n : -n;
-}
-
-} // inline
Index: bcfa/src/vec/vec2.hfa
===================================================================
--- libcfa/src/vec/vec2.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,288 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2021 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// io/types.hfa --
-//
-// Author           : Dimitry Kobets
-// Created On       :
-// Last Modified By :
-// Last Modified On :
-// Update Count     :
-//
-
-#pragma once
-
-#include <iostream.hfa>
-#include "vec.hfa"
-
-forall (otype T) {
-    struct vec2 {
-        T x, y;
-    };
-}
-
-forall (otype T) {
-    static inline {
-
-    void ?{}(vec2(T)& v, T x, T y) {
-        v.[x, y] = [x, y];
-    }
-
-    forall(| zero_assign(T))
-    void ?{}(vec2(T)& vec, zero_t) with (vec) {
-        x = y = 0;
-    }
-
-    void ?{}(vec2(T)& vec, T val) with (vec) {
-        x = y = val;
-    }
-
-    void ?{}(vec2(T)& vec, vec2(T) other) with (vec) {
-        [x,y] = other.[x,y];
-    }
-
-    void ?=?(vec2(T)& vec, vec2(T) other) with (vec) {
-        [x,y] = other.[x,y];
-    }
-    forall(| zero_assign(T))
-    void ?=?(vec2(T)& vec, zero_t) with (vec) {
-        x = y = 0;
-    }
-
-    // Primitive mathematical operations
-
-    // -
-    forall(| subtract(T)) {
-    vec2(T) ?-?(vec2(T) u, vec2(T) v) {
-        return [u.x - v.x, u.y - v.y];
-    }
-    vec2(T)& ?-=?(vec2(T)& u, vec2(T) v) {
-        u = u - v;
-        return u;
-    }
-    }
-    forall(| negate(T))
-    vec2(T) -?(vec2(T) v) with (v) {
-        return [-x, -y];
-    }
-
-    forall(| { T --?(T&); }) {
-    vec2(T)& --?(vec2(T)& v) {
-        --v.x;
-        --v.y;
-        return v;
-    }
-    vec2(T) ?--(vec2(T)& v) {
-        vec2(T) copy = v;
-        --v;
-        return copy;
-    }
-    }
-
-    // +
-    forall(| add(T)) {
-    vec2(T) ?+?(vec2(T) u, vec2(T) v) {
-        return [u.x + v.x, u.y + v.y];
-    }
-    vec2(T)& ?+=?(vec2(T)& u, vec2(T) v) {
-        u = u + v;
-        return u;
-    }
-    }
-
-    forall(| { T ++?(T&); }) {
-    vec2(T)& ++?(vec2(T)& v) {
-        ++v.x;
-        ++v.y;
-        return v;
-    }
-    vec2(T) ?++(vec2(T)& v) {
-        vec2(T) copy = v;
-        ++v;
-        return copy;
-    }
-    }
-
-    // *
-    forall(| multiply(T)) {
-    vec2(T) ?*?(vec2(T) v, T scalar) with (v) {
-        return [x * scalar, y * scalar];
-    }
-    vec2(T) ?*?(T scalar, vec2(T) v) {
-        return v * scalar;
-    }
-    vec2(T) ?*?(vec2(T) u, vec2(T) v) {
-        return [u.x * v.x, u.y * v.y];
-    }
-    vec2(T)& ?*=?(vec2(T)& v, T scalar) {
-        v = v * scalar;
-        return v;
-    }
-    vec2(T) ?*=?(vec2(T)& u, vec2(T) v) {
-        u = u * v;
-        return u;
-    }
-    }
-
-    // /
-    forall(| divide(T)) {
-    vec2(T) ?/?(vec2(T) v, T scalar) with (v) {
-        return [x / scalar, y / scalar];
-    }
-    vec2(T) ?/?(vec2(T) u, vec2(T) v) {
-        return [u.x / v.x, u.y / v.y];
-    }
-    vec2(T)& ?/=?(vec2(T)& v, T scalar) {
-        v = v / scalar;
-        return v;
-    }
-    vec2(T) ?/=?(vec2(T)& u, vec2(T) v) {
-        u = u / v;
-        return u;
-    }
-    }
-
-    // %
-    forall(| { T ?%?(T,T); }) {
-    vec2(T) ?%?(vec2(T) v, T scalar) with (v) {
-        return [x % scalar, y % scalar];
-    }
-    vec2(T)& ?%=?(vec2(T)& u, T scalar) {
-        u = u % scalar;
-        return u;
-    }
-    vec2(T) ?%?(vec2(T) u, vec2(T) v) {
-        return [u.x % v.x, u.y % v.y];
-    }
-    vec2(T)& ?%=?(vec2(T)& u, vec2(T) v) {
-        u = u % v;
-        return u;
-    }
-    }
-
-    // &
-    forall(| { T ?&?(T,T); }) {
-    vec2(T) ?&?(vec2(T) v, T scalar) with (v) {
-        return [x & scalar, y & scalar];
-    }
-    vec2(T)& ?&=?(vec2(T)& u, T scalar) {
-        u = u & scalar;
-        return u;
-    }
-    vec2(T) ?&?(vec2(T) u, vec2(T) v) {
-        return [u.x & v.x, u.y & v.y];
-    }
-    vec2(T)& ?&=?(vec2(T)& u, vec2(T) v) {
-        u = u & v;
-        return u;
-    }
-    }
-
-    // |
-    forall(| { T ?|?(T,T); }) {
-    vec2(T) ?|?(vec2(T) v, T scalar) with (v) {
-        return [x | scalar, y | scalar];
-    }
-    vec2(T)& ?|=?(vec2(T)& u, T scalar) {
-        u = u | scalar;
-        return u;
-    }
-    vec2(T) ?|?(vec2(T) u, vec2(T) v) {
-        return [u.x | v.x, u.y | v.y];
-    }
-    vec2(T)& ?|=?(vec2(T)& u, vec2(T) v) {
-        u = u | v;
-        return u;
-    }
-    }
-
-    // ^
-    forall(| { T ?^?(T,T); }) {
-    vec2(T) ?^?(vec2(T) v, T scalar) with (v) {
-        return [x ^ scalar, y ^ scalar];
-    }
-    vec2(T)& ?^=?(vec2(T)& u, T scalar) {
-        u = u ^ scalar;
-        return u;
-    }
-    vec2(T) ?^?(vec2(T) u, vec2(T) v) {
-        return [u.x ^ v.x, u.y ^ v.y];
-    }
-    vec2(T)& ?^=?(vec2(T)& u, vec2(T) v) {
-        u = u ^ v;
-        return u;
-    }
-    }
-
-    // <<
-    forall(| { T ?<<?(T,T); }) {
-    vec2(T) ?<<?(vec2(T) v, T scalar) with (v) {
-        return [x << scalar, y << scalar];
-    }
-    vec2(T)& ?<<=?(vec2(T)& u, T scalar) {
-        u = u << scalar;
-        return u;
-    }
-    vec2(T) ?<<?(vec2(T) u, vec2(T) v) {
-        return [u.x << v.x, u.y << v.y];
-    }
-    vec2(T)& ?<<=?(vec2(T)& u, vec2(T) v) {
-        u = u << v;
-        return u;
-    }
-    }
-
-    // >>
-    forall(| { T ?>>?(T,T); }) {
-    vec2(T) ?>>?(vec2(T) v, T scalar) with (v) {
-        return [x >> scalar, y >> scalar];
-    }
-    vec2(T)& ?>>=?(vec2(T)& u, T scalar) {
-        u = u >> scalar;
-        return u;
-    }
-    vec2(T) ?>>?(vec2(T) u, vec2(T) v) {
-        return [u.x >> v.x, u.y >> v.y];
-    }
-    vec2(T)& ?>>=?(vec2(T)& u, vec2(T) v) {
-        u = u >> v;
-        return u;
-    }
-    }
-
-    // ~
-    forall(| { T ~?(T); })
-    vec2(T) ~?(vec2(T) v) with (v) {
-        return [~v.x, ~v.y];
-    }
-
-    // relational
-    forall(| equality(T)) {
-    bool ?==?(vec2(T) u, vec2(T) v) with (u) {
-        return x == v.x && y == v.y;
-    }
-    bool ?!=?(vec2(T) u, vec2(T) v) {
-        return !(u == v);
-    }
-    }
-
-    // Geometric functions
-    forall(| add(T) | multiply(T))
-    T dot(vec2(T) u, vec2(T) v) {
-        return u.x * v.x + u.y * v.y;
-    }
-
-    } // static inline
-}
-
-forall(dtype ostype, otype T | writeable(T, ostype)) {
-    ostype & ?|?(ostype & os, vec2(T) v) with (v) {
-        return os | '<' | x | ',' | y | '>';
-    }
-    void ?|?(ostype & os, vec2(T) v ) with (v) {
-        (ostype &)(os | v); ends(os);
-    }
-}
Index: bcfa/src/vec/vec3.hfa
===================================================================
--- libcfa/src/vec/vec3.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,297 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2021 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// io/types.hfa --
-//
-// Author           : Dimitry Kobets
-// Created On       :
-// Last Modified By :
-// Last Modified On :
-// Update Count     :
-//
-
-#pragma once
-
-#include <iostream.hfa>
-#include "vec.hfa"
-
-forall (otype T) {
-    struct vec3 {
-        T x, y, z;
-    };
-}
-
-forall (otype T) {
-    static inline {
-
-    void ?{}(vec3(T)& v, T x, T y, T z) {
-        v.[x, y, z] = [x, y, z];
-    }
-
-    forall(| zero_assign(T))
-    void ?{}(vec3(T)& vec, zero_t) with (vec) {
-        x = y = z = 0;
-    }
-
-    void ?{}(vec3(T)& vec, T val) with (vec) {
-        x = y = z = val;
-    }
-
-    void ?{}(vec3(T)& vec, vec3(T) other) with (vec) {
-        [x,y,z] = other.[x,y,z];
-    }
-
-    void ?=?(vec3(T)& vec, vec3(T) other) with (vec) {
-        [x,y,z] = other.[x,y,z];
-    }
-    forall(| zero_assign(T))
-    void ?=?(vec3(T)& vec, zero_t) with (vec) {
-        x = y = z = 0;
-    }
-
-    // Primitive mathematical operations
-
-    // -
-    forall(| subtract(T)) {
-    vec3(T) ?-?(vec3(T) u, vec3(T) v) {
-        return [u.x - v.x, u.y - v.y, u.z - v.z];
-    }
-    vec3(T)& ?-=?(vec3(T)& u, vec3(T) v) {
-        u = u - v;
-        return u;
-    }
-    }
-    forall(| negate(T)) {
-    vec3(T) -?(vec3(T) v) with (v) {
-        return [-x, -y, -z];
-    }
-    }
-    forall(| { T --?(T&); }) {
-    vec3(T)& --?(vec3(T)& v) {
-        --v.x;
-        --v.y;
-        --v.z;
-        return v;
-    }
-    vec3(T) ?--(vec3(T)& v) {
-        vec3(T) copy = v;
-        --v;
-        return copy;
-    }
-    }
-
-    // +
-    forall(| add(T)) {
-    vec3(T) ?+?(vec3(T) u, vec3(T) v) {
-        return [u.x + v.x, u.y + v.y, u.z + v.z];
-    }
-    vec3(T)& ?+=?(vec3(T)& u, vec3(T) v) {
-        u = u + v;
-        return u;
-    }
-    }
-
-    forall(| { T ++?(T&); }) {
-    vec3(T)& ++?(vec3(T)& v) {
-        ++v.x;
-        ++v.y;
-        ++v.z;
-        return v;
-    }
-    vec3(T) ?++(vec3(T)& v) {
-        vec3(T) copy = v;
-        ++v;
-        return copy;
-    }
-    }
-
-    // *
-    forall(| multiply(T)) {
-    vec3(T) ?*?(vec3(T) v, T scalar) with (v) {
-        return [x * scalar, y * scalar, z * scalar];
-    }
-    vec3(T) ?*?(T scalar, vec3(T) v) {
-        return v * scalar;
-    }
-    vec3(T) ?*?(vec3(T) u, vec3(T) v) {
-        return [u.x * v.x, u.y * v.y, u.z * v.z];
-    }
-    vec3(T)& ?*=?(vec3(T)& v, T scalar) {
-        v = v * scalar;
-        return v;
-    }
-    vec3(T)& ?*=?(vec3(T)& u, vec3(T) v) {
-        u = u * v;
-        return u;
-    }
-    }
-
-    // /
-    forall(| divide(T)) {
-    vec3(T) ?/?(vec3(T) v, T scalar) with (v) {
-        return [x / scalar, y / scalar, z / scalar];
-    }
-    vec3(T) ?/?(vec3(T) u, vec3(T) v) {
-        return [u.x / v.x, u.y / v.y, u.z / v.z];
-    }
-    vec3(T)& ?/=?(vec3(T)& v, T scalar) {
-        v = v / scalar;
-        return v;
-    }
-    vec3(T)& ?/=?(vec3(T)& u, vec3(T) v) {
-        u = u / v;
-        return u;
-    }
-    }
-
-    // %
-    forall(| { T ?%?(T,T); }) {
-    vec3(T) ?%?(vec3(T) v, T scalar) with (v) {
-        return [x % scalar, y % scalar, z % scalar];
-    }
-    vec3(T)& ?%=?(vec3(T)& u, T scalar) {
-        u = u % scalar;
-        return u;
-    }
-    vec3(T) ?%?(vec3(T) u, vec3(T) v) {
-        return [u.x % v.x, u.y % v.y, u.z % v.z];
-    }
-    vec3(T)& ?%=?(vec3(T)& u, vec3(T) v) {
-        u = u % v;
-        return u;
-    }
-    }
-
-    // &
-    forall(| { T ?&?(T,T); }) {
-    vec3(T) ?&?(vec3(T) v, T scalar) with (v) {
-        return [x & scalar, y & scalar, z & scalar];
-    }
-    vec3(T)& ?&=?(vec3(T)& u, T scalar) {
-        u = u & scalar;
-        return u;
-    }
-    vec3(T) ?&?(vec3(T) u, vec3(T) v) {
-        return [u.x & v.x, u.y & v.y, u.z & v.z];
-    }
-    vec3(T)& ?&=?(vec3(T)& u, vec3(T) v) {
-        u = u & v;
-        return u;
-    }
-    }
-
-    // |
-    forall(| { T ?|?(T,T); }) {
-    vec3(T) ?|?(vec3(T) v, T scalar) with (v) {
-        return [x | scalar, y | scalar, z | scalar];
-    }
-    vec3(T)& ?|=?(vec3(T)& u, T scalar) {
-        u = u | scalar;
-        return u;
-    }
-    vec3(T) ?|?(vec3(T) u, vec3(T) v) {
-        return [u.x | v.x, u.y | v.y, u.z | v.z];
-    }
-    vec3(T)& ?|=?(vec3(T)& u, vec3(T) v) {
-        u = u | v;
-        return u;
-    }
-    }
-
-    // ^
-    forall(| { T ?^?(T,T); }) {
-    vec3(T) ?^?(vec3(T) v, T scalar) with (v) {
-        return [x ^ scalar, y ^ scalar, z ^ scalar];
-    }
-    vec3(T)& ?^=?(vec3(T)& u, T scalar) {
-        u = u ^ scalar;
-        return u;
-    }
-    vec3(T) ?^?(vec3(T) u, vec3(T) v) {
-        return [u.x ^ v.x, u.y ^ v.y, u.z ^ v.z];
-    }
-    vec3(T)& ?^=?(vec3(T)& u, vec3(T) v) {
-        u = u ^ v;
-        return u;
-    }
-    }
-
-    // <<
-    forall(| { T ?<<?(T,T); }) {
-    vec3(T) ?<<?(vec3(T) v, T scalar) with (v) {
-        return [x << scalar, y << scalar, z << scalar];
-    }
-    vec3(T)& ?<<=?(vec3(T)& u, T scalar) {
-        u = u << scalar;
-        return u;
-    }
-    vec3(T) ?<<?(vec3(T) u, vec3(T) v) {
-        return [u.x << v.x, u.y << v.y, u.z << v.z];
-    }
-    vec3(T)& ?<<=?(vec3(T)& u, vec3(T) v) {
-        u = u << v;
-        return u;
-    }
-    }
-
-    // >>
-    forall(| { T ?>>?(T,T); }) {
-    vec3(T) ?>>?(vec3(T) v, T scalar) with (v) {
-        return [x >> scalar, y >> scalar, z >> scalar];
-    }
-    vec3(T)& ?>>=?(vec3(T)& u, T scalar) {
-        u = u >> scalar;
-        return u;
-    }
-    vec3(T) ?>>?(vec3(T) u, vec3(T) v) {
-        return [u.x >> v.x, u.y >> v.y, u.z >> v.z];
-    }
-    vec3(T)& ?>>=?(vec3(T)& u, vec3(T) v) {
-        u = u >> v;
-        return u;
-    }
-    }
-
-    // ~
-    forall(| { T ~?(T); })
-    vec3(T) ~?(vec3(T) v) with (v) {
-        return [~v.x, ~v.y, ~v.z];
-    }
-
-    // relational
-    forall(| equality(T)) {
-    bool ?==?(vec3(T) u, vec3(T) v) with (u) {
-        return x == v.x && y == v.y && z == v.z;
-    }
-    bool ?!=?(vec3(T) u, vec3(T) v) {
-        return !(u == v);
-    }
-    }
-
-    // Geometric functions
-    forall(| add(T) | multiply(T))
-    T dot(vec3(T) u, vec3(T) v) {
-        return u.x * v.x + u.y * v.y + u.z * v.z;
-    }
-
-    forall(| subtract(T) | multiply(T))
-    vec3(T) cross(vec3(T) u, vec3(T) v) {
-        return (vec3(T)){ u.y * v.z - v.y * u.z,
-                          u.z * v.x - v.z * u.x,
-                          u.x * v.y - v.x * u.y };
-    }
-
-    } // static inline
-}
-
-forall(dtype ostype, otype T | writeable(T, ostype)) {
-    ostype & ?|?(ostype & os, vec3(T) v) with (v) {
-        return os | '<' | x | ',' | y | ',' | z | '>';
-    }
-    void ?|?(ostype & os, vec3(T) v ) with (v) {
-        (ostype &)(os | v); ends(os);
-    }
-}
Index: bcfa/src/vec/vec4.hfa
===================================================================
--- libcfa/src/vec/vec4.hfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,293 +1,0 @@
-//
-// Cforall Version 1.0.0 Copyright (C) 2021 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-//
-// io/types.hfa --
-//
-// Author           : Dimitry Kobets
-// Created On       :
-// Last Modified By :
-// Last Modified On :
-// Update Count     :
-//
-
-#pragma once
-
-#include <iostream.hfa>
-#include "vec.hfa"
-
-forall (otype T) {
-    struct vec4 {
-        T x, y, z, w;
-    };
-}
-
-forall (otype T) {
-    static inline {
-
-    void ?{}(vec4(T)& v, T x, T y, T z, T w) {
-        v.[x, y, z, w] = [x, y, z, w];
-    }
-
-    forall(| zero_assign(T))
-    void ?{}(vec4(T)& vec, zero_t) with (vec) {
-        x = y = z = w = 0;
-    }
-
-    void ?{}(vec4(T)& vec, T val) with (vec) {
-        x = y = z = w = val;
-    }
-
-    void ?{}(vec4(T)& vec, vec4(T) other) with (vec) {
-        [x,y,z,w] = other.[x,y,z,w];
-    }
-
-    void ?=?(vec4(T)& vec, vec4(T) other) with (vec) {
-        [x,y,z,w] = other.[x,y,z,w];
-    }
-    forall(| zero_assign(T))
-    void ?=?(vec4(T)& vec, zero_t) with (vec) {
-        x = y = z = w = 0;
-    }
-
-    // Primitive mathematical operations
-
-    // -
-    forall(| subtract(T)) {
-    vec4(T) ?-?(vec4(T) u, vec4(T) v) {
-        return [u.x - v.x, u.y - v.y, u.z - v.z, u.w - v.w];
-    }
-    vec4(T)& ?-=?(vec4(T)& u, vec4(T) v) {
-        u = u - v;
-        return u;
-    }
-    }
-    forall(| negate(T)) {
-    vec4(T) -?(vec4(T) v) with (v) {
-        return [-x, -y, -z, -w];
-    }
-    }
-    forall(| { T --?(T&); }) {
-    vec4(T)& --?(vec4(T)& v) {
-        --v.x;
-        --v.y;
-        --v.z;
-        --v.w;
-        return v;
-    }
-    vec4(T) ?--(vec4(T)& v) {
-        vec4(T) copy = v;
-        --v;
-        return copy;
-    }
-    }
-
-    // +
-    forall(| add(T)) {
-    vec4(T) ?+?(vec4(T) u, vec4(T) v) {
-        return [u.x + v.x, u.y + v.y, u.z + v.z, u.w + v.w];
-    }
-    vec4(T)& ?+=?(vec4(T)& u, vec4(T) v) {
-        u = u + v;
-        return u;
-    }
-    }
-
-    forall(| { T ++?(T&); }) {
-    vec4(T)& ++?(vec4(T)& v) {
-        ++v.x;
-        ++v.y;
-        ++v.z;
-        ++v.w;
-        return v;
-    }
-    vec4(T) ?++(vec4(T)& v) {
-        vec4(T) copy = v;
-        ++v;
-        return copy;
-    }
-    }
-
-    // *
-    forall(| multiply(T)) {
-    vec4(T) ?*?(vec4(T) v, T scalar) with (v) {
-        return [x * scalar, y * scalar, z * scalar, w * scalar];
-    }
-    vec4(T) ?*?(T scalar, vec4(T) v) {
-        return v * scalar;
-    }
-    vec4(T) ?*?(vec4(T) u, vec4(T) v) {
-        return [u.x * v.x, u.y * v.y, u.z * v.z, u.w * v.w];
-    }
-    vec4(T)& ?*=?(vec4(T)& v, T scalar) {
-        v = v * scalar;
-        return v;
-    }
-    vec4(T)& ?*=?(vec4(T)& u, vec4(T) v) {
-        u = u * v;
-        return u;
-    }
-    }
-
-    // /
-    forall(| divide(T)) {
-    vec4(T) ?/?(vec4(T) v, T scalar) with (v) {
-        return [x / scalar, y / scalar, z / scalar, w / scalar];
-    }
-    vec4(T) ?/?(vec4(T) u, vec4(T) v) {
-        return [u.x / v.x, u.y / v.y, u.z / v.z, u.w / v.w];
-    }
-    vec4(T)& ?/=?(vec4(T)& v, T scalar) {
-        v = v / scalar;
-        return v;
-    }
-    vec4(T)& ?/=?(vec4(T)& u, vec4(T) v) {
-        u = u / v;
-        return u;
-    }
-    }
-
-    // %
-    forall(| { T ?%?(T,T); }) {
-    vec4(T) ?%?(vec4(T) v, T scalar) with (v) {
-        return [x % scalar, y % scalar, z % scalar, w % scalar];
-    }
-    vec4(T)& ?%=?(vec4(T)& u, T scalar) {
-        u = u % scalar;
-        return u;
-    }
-    vec4(T) ?%?(vec4(T) u, vec4(T) v) {
-        return [u.x % v.x, u.y % v.y, u.z % v.z, u.w % v.w];
-    }
-    vec4(T)& ?%=?(vec4(T)& u, vec4(T) v) {
-        u = u % v;
-        return u;
-    }
-    }
-
-    // &
-    forall(| { T ?&?(T,T); }) {
-    vec4(T) ?&?(vec4(T) v, T scalar) with (v) {
-        return [x & scalar, y & scalar, z & scalar, w & scalar];
-    }
-    vec4(T)& ?&=?(vec4(T)& u, T scalar) {
-        u = u & scalar;
-        return u;
-    }
-    vec4(T) ?&?(vec4(T) u, vec4(T) v) {
-        return [u.x & v.x, u.y & v.y, u.z & v.z, u.w & v.w];
-    }
-    vec4(T)& ?&=?(vec4(T)& u, vec4(T) v) {
-        u = u & v;
-        return u;
-    }
-    }
-
-    // |
-    forall(| { T ?|?(T,T); }) {
-    vec4(T) ?|?(vec4(T) v, T scalar) with (v) {
-        return [x | scalar, y | scalar, z | scalar, w | scalar];
-    }
-    vec4(T)& ?|=?(vec4(T)& u, T scalar) {
-        u = u | scalar;
-        return u;
-    }
-    vec4(T) ?|?(vec4(T) u, vec4(T) v) {
-        return [u.x | v.x, u.y | v.y, u.z | v.z, u.w | v.w];
-    }
-    vec4(T)& ?|=?(vec4(T)& u, vec4(T) v) {
-        u = u | v;
-        return u;
-    }
-    }
-
-    // ^
-    forall(| { T ?^?(T,T); }) {
-    vec4(T) ?^?(vec4(T) v, T scalar) with (v) {
-        return [x ^ scalar, y ^ scalar, z ^ scalar, w ^ scalar];
-    }
-    vec4(T)& ?^=?(vec4(T)& u, T scalar) {
-        u = u ^ scalar;
-        return u;
-    }
-    vec4(T) ?^?(vec4(T) u, vec4(T) v) {
-        return [u.x ^ v.x, u.y ^ v.y, u.z ^ v.z, u.w ^ v.w];
-    }
-    vec4(T)& ?^=?(vec4(T)& u, vec4(T) v) {
-        u = u ^ v;
-        return u;
-    }
-    }
-
-    // <<
-    forall(| { T ?<<?(T,T); }) {
-    vec4(T) ?<<?(vec4(T) v, T scalar) with (v) {
-        return [x << scalar, y << scalar, z << scalar, w << scalar];
-    }
-    vec4(T)& ?<<=?(vec4(T)& u, T scalar) {
-        u = u << scalar;
-        return u;
-    }
-    vec4(T) ?<<?(vec4(T) u, vec4(T) v) {
-        return [u.x << v.x, u.y << v.y, u.z << v.z, u.w << v.w];
-    }
-    vec4(T)& ?<<=?(vec4(T)& u, vec4(T) v) {
-        u = u << v;
-        return u;
-    }
-    }
-
-    // >>
-    forall(| { T ?>>?(T,T); }) {
-    vec4(T) ?>>?(vec4(T) v, T scalar) with (v) {
-        return [x >> scalar, y >> scalar, z >> scalar, w >> scalar];
-    }
-    vec4(T)& ?>>=?(vec4(T)& u, T scalar) {
-        u = u >> scalar;
-        return u;
-    }
-    vec4(T) ?>>?(vec4(T) u, vec4(T) v) {
-        return [u.x >> v.x, u.y >> v.y, u.z >> v.z, u.w >> v.w];
-    }
-    vec4(T)& ?>>=?(vec4(T)& u, vec4(T) v) {
-        u = u >> v;
-        return u;
-    }
-    }
-
-    // ~
-    forall(| { T ~?(T); })
-    vec4(T) ~?(vec4(T) v) with (v) {
-        return [~x, ~y, ~z, ~w];
-    }
-
-    // relational
-    forall(| equality(T)) {
-    bool ?==?(vec4(T) u, vec4(T) v) with (u) {
-        return x == v.x && y == v.y && z == v.z && w == v.w;
-    }
-    bool ?!=?(vec4(T) u, vec4(T) v) {
-        return !(u == v);
-    }
-    }
-
-    // Geometric functions
-    forall(| add(T) | multiply(T))
-    T dot(vec4(T) u, vec4(T) v) {
-        return u.x * v.x + u.y * v.y + u.z * v.z + u.w * v.w;
-    }
-
-    } // static inline
-}
-
-forall(dtype ostype, otype T | writeable(T, ostype)) {
-    ostype & ?|?(ostype & os, vec4(T) v) with (v) {
-        return os | '<' | x | ',' | y | ',' | z | ',' | w | '>';
-    }
-    void ?|?(ostype & os, vec4(T) v ) with (v) {
-        (ostype &)(os | v); ends(os);
-    }
-}
-
Index: longrun_tests/Makefile.am
===================================================================
--- longrun_tests/Makefile.am	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ longrun_tests/Makefile.am	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -44,5 +44,5 @@
 	-DTEST_$(shell cat .type | tr a-z A-Z)
 
-TESTS = block coroutine create disjoint enter enter3 locks processor stack wait yield
+TESTS = block coroutine create disjoint enter enter3 processor stack wait yield
 
 # .INTERMEDIATE: $(TESTS)
Index: ngrun_tests/locks.cfa
===================================================================
--- longrun_tests/locks.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,302 +1,0 @@
-#include <stdio.h>
-#include "locks.hfa"
-#include <stdlib.hfa>
-#include <thread.hfa>
-
-const unsigned int num_times = 50000;
-
-multiple_acquisition_lock m;
-condition_variable( multiple_acquisition_lock ) c_m;
-
-single_acquisition_lock s;
-condition_variable( single_acquisition_lock ) c_s;
-
-owner_lock o;
-condition_variable( owner_lock ) c_o;
-
-thread T_C_M_WS1 {};
-
-void main( T_C_M_WS1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(m);
-		if(empty(c_m) && i != num_times - 1) {
-			wait(c_m,m);
-		}else{
-			notify_one(c_m);
-		}
-		unlock(m);
-	}
-}
-
-thread T_C_M_WB1 {};
-
-void main( T_C_M_WB1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(m);
-		if(counter(c_m) == 3 || i == num_times - 1) {
-			notify_all(c_m);
-		}else{
-			wait(c_m,m);
-		}
-		unlock(m);
-	}
-}
-
-thread T_C_S_WS1 {};
-
-void main( T_C_S_WS1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(s);
-		if(empty(c_s) && i != num_times - 1) {
-			wait(c_s,s);
-		}else{
-			notify_one(c_s);
-		}
-		unlock(s);
-	}
-}
-
-thread T_C_S_WB1 {};
-
-void main( T_C_S_WB1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(s);
-		if(counter(c_s) == 3 || i == num_times - 1) {
-			notify_all(c_s);
-		}else{
-			wait(c_s,s);
-		}
-		unlock(s);
-	}
-}
-
-thread T_C_O_WS1 {};
-
-void main( T_C_O_WS1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(o);
-		if(empty(c_o) && i != num_times - 1) {
-			wait(c_o,o);
-		}else{
-			notify_one(c_o);
-		}
-		unlock(o);
-	}
-}
-
-thread T_C_O_WB1 {};
-
-void main( T_C_O_WB1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(o);
-		if(counter(c_o) == 3 || i == num_times - 1) {
-			notify_all(c_o);
-		}else{
-			wait(c_o,o);
-		}
-		unlock(o);
-	}
-}
-
-thread T_C_M_WS2 {};
-
-void main( T_C_M_WS2 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(m);
-		lock(m);
-		lock(m);
-		if(empty(c_m) && i != num_times - 1) {
-			wait(c_m,m);
-		}else{
-			notify_one(c_m);
-		}
-		unlock(m);
-		unlock(m);
-		unlock(m);
-	}
-}
-
-thread T_C_O_WS2 {};
-
-void main( T_C_O_WS2 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(o);
-		lock(o);
-		lock(o);
-		if(empty(c_o) && i != num_times - 1) {
-			wait(c_o,o);
-		}else{
-			notify_one(c_o);
-		}
-		unlock(o);
-		unlock(o);
-		unlock(o);
-	}
-}
-
-thread T_C_NLW {};
-
-void main( T_C_NLW & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		wait(c_o);
-	}
-}
-
-thread T_C_NLS {};
-
-void main( T_C_NLS & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		while (empty(c_o)) { }
-		notify_one(c_o);
-	}
-}
-
-thread T_C_S_WNF {};
-
-void main( T_C_S_WNF & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(s);
-		if(empty(c_s) && i != num_times - 1) {
-			wait(c_s, s, 10);
-		}else{
-			if(!empty(c_s)) assert(front(c_s) == 10);
-			notify_one(c_s);
-		}
-		unlock(s);
-	}
-}
-
-bool done = false;
-
-thread T_C_NLWD {};
-
-void main( T_C_NLWD & this ) {
-	done = false;
-	for (unsigned int i = 0; i < num_times/5; i++) {
-		if (i % 1000 == 0) printf("Iteration: %d\n", i);
-		wait(c_s, 1`ns);
-	}
-	done = true;
-}
-
-thread T_C_WDS {};
-
-void main( T_C_WDS & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		while (empty(c_s) && !done) { }
-		notify_one(c_s);
-		sleep(1`ns);
-		if(done) break;
-	}
-}
-
-thread T_C_LWD {};
-
-void main( T_C_LWD & this ) {
-	done = false;
-	for (unsigned int i = 0; i < num_times/5; i++) {
-		if (i % 1000 == 0) printf("Iteration: %d\n", i);
-		lock(s);
-		wait(c_s, s, 1`ns);
-		unlock(s);
-	}
-	done = true;
-}
-
-thread T_C_LWDS {};
-
-void main( T_C_LWDS & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		while (empty(c_s) && !done) { }
-		lock(s);
-		notify_one(c_s);
-		unlock(s);
-		sleep(1`ns);
-		if(done) break;
-	}
-}
-
-int main() {
-	processor p[2];
-	printf("Start Test 1: multi acquisition lock and condition variable single wait/notify\n");
-	{
-		T_C_M_WS1 t1[2];
-	}
-	printf("Done Test 1\n");
-
-	printf("Start Test 2: multi acquisition lock and condition variable 3 wait/notify all\n");
-	{
-		T_C_M_WB1 t1[4];
-	}
-	printf("Done Test 2\n");
-
-	printf("Start Test 3: single acquisition lock and condition variable single wait/notify\n");
-	{
-		T_C_S_WS1 t1[2];
-	}
-	printf("Done Test 3\n");
-
-	printf("Start Test 4: single acquisition lock and condition variable 3 wait/notify all\n");
-	{
-		T_C_S_WB1 t1[4];
-	}
-	printf("Done Test 4\n");
-
-	printf("Start Test 5: owner lock and condition variable single wait/notify\n");
-	{
-		T_C_O_WS1 t1[2];
-	}
-	printf("Done Test 5\n");
-
-	printf("Start Test 6: owner lock and condition variable 3 wait/notify all\n");
-	{
-		T_C_O_WB1 t1[4];
-	}
-	printf("Done Test 6\n");
-
-	printf("Start Test 7: multi acquisiton lock and condition variable multiple acquire and wait/notify\n");
-	{
-		T_C_M_WS2 t1[2];
-	}
-	printf("Done Test 7\n");
-
-	printf("Start Test 8: owner lock and condition variable multiple acquire and wait/notify\n");
-	{
-		T_C_O_WS2 t1[2];
-	}
-	printf("Done Test 8\n");
-
-	printf("Start Test 9: no lock condition variable wait/notify\n");
-	{
-		T_C_NLW t1;
-		T_C_NLS t2;
-	}
-	printf("Done Test 9\n");
-
-	printf("Start Test 10: locked condition variable wait/notify with front()\n");
-	{
-		T_C_S_WNF t1[2];
-	}
-	printf("Done Test 10\n");
-
-	printf("Start Test 11: unlocked condition variable delay wait\n");
-	{
-		T_C_NLWD t1;
-		T_C_WDS t2;
-	}
-	printf("Done Test 11\n");
-
-	printf("Start Test 12: locked condition variable delay wait with unlocked signal\n");
-	{
-		T_C_LWD t1;
-		T_C_WDS t2;
-	}
-	printf("Done Test 12\n");
-
-	printf("Start Test 13: locked condition variable delay wait with locked signal\n");
-	{
-		T_C_LWD t1;
-		T_C_LWDS t2;
-	}
-	printf("Done Test 13\n");
-}
Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/Convert.cpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -205,10 +205,5 @@
 		ftype->parameters = get<DeclarationWithType>().acceptL(node->params);
 
-		ftype->forall = get<TypeDecl>().acceptL( node->type_params );
-		if (!node->assertions.empty()) {
-			assert(!ftype->forall.empty());
-			// find somewhere to place assertions back, for convenience it is the last slot
-			ftype->forall.back()->assertions = get<DeclarationWithType>().acceptL(node->assertions);
-		}
+		ftype->forall = get<TypeDecl>().acceptL( node->type->forall );
 
 		visitType(node->type, ftype);
@@ -607,6 +602,11 @@
 
 		for (decltype(src->begin()) src_i = src->begin(); src_i != src->end(); src_i++) {
-			rslt->add( src_i->first.typeString(),
+			rslt->add( src_i->first,
 			           get<Type>().accept1(src_i->second) );
+		}
+
+		for (decltype(src->beginVar()) src_i = src->beginVar(); src_i != src->endVar(); src_i++) {
+			rslt->addVar( src_i->first,
+			              get<Expression>().accept1(src_i->second) );
 		}
 
@@ -1212,25 +1212,5 @@
 		// ty->returnVals = get<DeclarationWithType>().acceptL( node->returns );
 		// ty->parameters = get<DeclarationWithType>().acceptL( node->params );
-
-		auto types = get<TypeInstType>().acceptL( node->forall );
-		for (auto t : types) {
-			auto newT = new TypeDecl(*t->baseType);
-			newT->name = t->name; // converted by typeString()
-			for (auto asst : newT->assertions) delete asst;
-			newT->assertions.clear();
-			ty->forall.push_back(newT);
-		}
-		auto assts = get<VariableExpr>().acceptL( node->assertions );
-		if (!assts.empty()) {
-			assert(!types.empty());
-			for (auto asst : assts) {
-				auto newDecl = new ObjectDecl(*strict_dynamic_cast<ObjectDecl*>(asst->var));
-				delete newDecl->type;
-				newDecl->type = asst->result->clone();
-				newDecl->storageClasses.is_extern = true; // hack
-				ty->forall.back()->assertions.push_back(newDecl);
-			}
-		}
-
+		ty->forall = get<TypeDecl>().acceptL( node->forall );
 		return visitType( node, ty );
 	}
@@ -1319,5 +1299,5 @@
 			ty = new TypeInstType{
 				cv( node ),
-				node->typeString(),
+				node->name,
 				get<TypeDecl>().accept1( node->base ),
 				get<Attribute>().acceptL( node->attributes )
@@ -1326,5 +1306,5 @@
 			ty = new TypeInstType{
 				cv( node ),
-				node->typeString(),
+				node->name,
 				node->kind == ast::TypeDecl::Ftype,
 				get<Attribute>().acceptL( node->attributes )
@@ -1451,5 +1431,5 @@
 	/// at conversion stage, all created nodes are guaranteed to be unique, therefore
 	/// const_casting out of smart pointers is permitted.
-	std::unordered_map< const BaseSyntaxNode *, ast::readonly<ast::Node> > cache = {};
+	std::unordered_map< const BaseSyntaxNode *, ast::ptr<ast::Node> > cache = {};
 
 	// Local Utilities:
@@ -1585,16 +1565,4 @@
 		// can function type have attributes? seems not to be the case.
 		// visitType(old->type, ftype);
-
-		// collect assertions and put directly in FunctionDecl
-		std::vector<ast::ptr<ast::DeclWithType>> assertions;
-		for (auto & param: forall) {
-			for (auto & asst: param->assertions) {
-				assertf(asst->unique(), "newly converted decl must be unique");
-				assertions.emplace_back(asst);
-			}
-			auto mut = param.get_and_mutate();
-			assertf(mut == param, "newly converted decl must be unique");
-			mut->assertions.clear();
-		}
 
 		auto decl = new ast::FunctionDecl{
@@ -1616,5 +1584,4 @@
 		cache.emplace( old, decl );
 
-		decl->assertions = std::move(assertions);
 		decl->withExprs = GET_ACCEPT_V(withExprs, Expr);
 		decl->stmts = GET_ACCEPT_1(statements, CompoundStmt);
@@ -2099,12 +2066,8 @@
 	}
 
-	// TypeSubstitution shouldn't exist yet in old.
 	ast::TypeSubstitution * convertTypeSubstitution(const TypeSubstitution * old) {
-		
+
 		if (!old) return nullptr;
-		if (old->empty()) return nullptr;
-		assert(false);
-
-		/*
+
 		ast::TypeSubstitution *rslt = new ast::TypeSubstitution();
 
@@ -2114,6 +2077,10 @@
 		}
 
+		for (decltype(old->beginVar()) old_i = old->beginVar(); old_i != old->endVar(); old_i++) {
+			rslt->addVar( old_i->first,
+			              getAccept1<ast::Expr>(old_i->second) );
+		}
+
 		return rslt;
-		*/
 	}
 
@@ -2643,14 +2610,5 @@
 			ty->params.emplace_back(v->get_type());
 		}
-		// xxx - when will this be non-null?
-		// will have to create dangling (no-owner) decls to be pointed to
-		auto foralls = GET_ACCEPT_V( forall, TypeDecl );
-
-		for (auto & param : foralls) {
-			ty->forall.emplace_back(new ast::TypeInstType(param->name, param));
-			for (auto asst : param->assertions) {
-				ty->assertions.emplace_back(new ast::VariableExpr({}, asst));
-			}
-		}
+		ty->forall = GET_ACCEPT_V( forall, TypeDecl );
 		visitType( old, ty );
 	}
Index: src/AST/Decl.cpp
===================================================================
--- src/AST/Decl.cpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/Decl.cpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -50,22 +50,20 @@
 
 FunctionDecl::FunctionDecl( const CodeLocation & loc, const std::string & name, 
-	std::vector<ptr<TypeDecl>>&& forall,
-	std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
-	CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage,
-	std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs)
-: DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)),
-	type_params(std::move(forall)), stmts( stmts ) {
-	FunctionType * ftype = new FunctionType(static_cast<ArgumentFlag>(isVarArgs));
-	for (auto & param : this->params) {
-		ftype->params.emplace_back(param->get_type());
-	}
-	for (auto & ret : this->returns) {
-		ftype->returns.emplace_back(ret->get_type());
-	}
-	for (auto & tp : this->type_params) {
-		ftype->forall.emplace_back(new TypeInstType(tp->name, tp));
-	}
-	this->type = ftype;
-}
+		std::vector<ptr<TypeDecl>>&& forall,
+		std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
+		CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage,
+		std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs)
+	: DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)),
+	  stmts( stmts ) {
+		  FunctionType * ftype = new FunctionType(static_cast<ArgumentFlag>(isVarArgs));
+		  for (auto & param : this->params) {
+			  ftype->params.emplace_back(param->get_type());
+		  }
+		  for (auto & ret : this->returns) {
+			  ftype->returns.emplace_back(ret->get_type());
+		  }
+		  ftype->forall = std::move(forall);
+		  this->type = ftype;
+	  }
 
 
Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/Decl.hpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -127,11 +127,8 @@
 	std::vector<ptr<DeclWithType>> params;
 	std::vector<ptr<DeclWithType>> returns;
-	std::vector<ptr<TypeDecl>> type_params;
-	std::vector<ptr<DeclWithType>> assertions;
 	// declared type, derived from parameter declarations
 	ptr<FunctionType> type;
 	ptr<CompoundStmt> stmts;
 	std::vector< ptr<Expr> > withExprs;
-
 
 	FunctionDecl( const CodeLocation & loc, const std::string & name, std::vector<ptr<TypeDecl>>&& forall,
Index: src/AST/Expr.cpp
===================================================================
--- src/AST/Expr.cpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/Expr.cpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -206,5 +206,40 @@
 	assert( aggregate->result );
 
-	result = mem->get_type();
+	// Deep copy on result type avoids mutation on transitively multiply referenced object.
+	//
+	// Example, adapted from parts of builtins and bootloader:
+	//
+	// forall(dtype T)
+	// struct __Destructor {
+	//   T * object;
+	//   void (*dtor)(T *);
+	// };
+	//
+	// forall(dtype S)
+	// void foo(__Destructor(S) &d) {
+	//   if (d.dtor) {  // here
+	//   }
+	// }
+	//
+	// Let e be the "d.dtor" guard espression, which is MemberExpr after resolve.  Let d be the
+	// declaration of member __Destructor.dtor (an ObjectDecl), as accessed via the top-level
+	// declaration of __Destructor.  Consider the types e.result and d.type.  In the old AST, one
+	// is a clone of the other.  Ordinary new-AST use would set them up as a multiply-referenced
+	// object.
+	//
+	// e.result: PointerType
+	// .base: FunctionType
+	// .params.front(): ObjectDecl, the anonymous parameter of type T*
+	// .type: PointerType
+	// .base: TypeInstType
+	// let x = that
+	// let y = similar, except start from d.type
+	//
+	// Consider two code lines down, genericSubstitution(...).apply(result).
+	//
+	// Applying this chosen-candidate's type substitution means modifying x, substituting
+	// S for T.  This mutation should affect x and not y.
+
+	result = deepCopy(mem->get_type());
 
 	// substitute aggregate generic parameters into member type
Index: src/AST/ForallSubstitutionTable.cpp
===================================================================
--- src/AST/ForallSubstitutionTable.cpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
+++ src/AST/ForallSubstitutionTable.cpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -0,0 +1,54 @@
+//
+// 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.
+//
+// ForallSubstitutionTable.cpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Thu Jun 27 14:00:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Thu Jun 27 14:00:00 2019
+// Update Count     : 1
+//
+
+#include "ForallSubstitutionTable.hpp"
+
+#include <cassert>
+#include <vector>
+
+#include "Copy.hpp"                // for shallowCopy
+#include "Decl.hpp"
+#include "Node.hpp"
+#include "Type.hpp"
+#include "Visitor.hpp"
+
+namespace ast {
+
+std::vector< ptr< TypeDecl > > ForallSubstitutionTable::clone(
+	const std::vector< ptr< TypeDecl > > & forall, Visitor & v
+) {
+	std::vector< ptr< TypeDecl > > new_forall;
+	new_forall.reserve( forall.size() );
+
+	for ( const ast::TypeDecl * d : forall ) {
+		// create cloned type decl and insert into substitution map before further mutation
+		auto new_d = shallowCopy( d );
+		decls.insert( d, new_d );
+		// perform other mutations and add to output
+		auto newer_d = v.visit( new_d );
+		assert( new_d == newer_d && "Newly cloned TypeDecl must retain identity" );
+		new_forall.emplace_back( new_d );
+	}
+
+	return new_forall;
+}
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/ForallSubstitutionTable.hpp
===================================================================
--- src/AST/ForallSubstitutionTable.hpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
+++ src/AST/ForallSubstitutionTable.hpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -0,0 +1,57 @@
+//
+// 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.
+//
+// ForallSubstitutionTable.hpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Thu Jun 27 14:00:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Thu Jun 27 14:00:00 2019
+// Update Count     : 1
+//
+
+#pragma once
+
+#include <vector>
+
+#include "Node.hpp"  // for ptr
+#include "Common/ScopedMap.h"
+
+namespace ast {
+
+class TypeDecl;
+class Visitor;
+
+/// Wrapper for TypeDecl substitution table
+class ForallSubstitutionTable {
+	ScopedMap< const TypeDecl *, const TypeDecl * > decls;
+
+public:
+	/// Replaces given declaration with value in the table, if present, otherwise returns argument
+	const TypeDecl * replace( const TypeDecl * d ) {
+		auto it = decls.find( d );
+		if ( it != decls.end() ) return it->second;
+		return d;
+	}
+
+	/// Builds a new forall list mutated according to the given visitor
+	std::vector< ptr< TypeDecl > > clone( 
+		const std::vector< ptr< TypeDecl > > & forall, Visitor & v );
+
+	/// Introduces a new lexical scope
+	void beginScope() { decls.beginScope(); }
+
+	/// Concludes a lexical scope
+	void endScope() { decls.endScope(); }
+};
+
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/ForallSubstitutor.hpp
===================================================================
--- src/AST/ForallSubstitutor.hpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
+++ src/AST/ForallSubstitutor.hpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -0,0 +1,70 @@
+//
+// 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.
+//
+// ForallSubstitutor.hpp --
+//
+// Author           : Aaron B. Moss
+// Created On       : Wed Jun 26 15:00:00 2019
+// Last Modified By : Aaron B. Moss
+// Last Modified On : Wed Jun 26 15:00:00 2019
+// Update Count     : 1
+//
+
+#include "Pass.hpp"
+
+namespace ast {
+
+class Expr;
+
+/// Visitor that correctly substitutes TypeDecl while maintaining TypeInstType bindings.
+/// Also has some convenience methods to mutate fields.
+struct ForallSubstitutor : public WithForallSubstitutor, public WithVisitorRef<ForallSubstitutor> {
+	/// Substitute TypeInstType base type
+	readonly< TypeDecl > operator() ( const readonly< TypeDecl > & o ) {
+		return subs.replace( o );
+	}
+	
+	/// Make new forall-list clone
+	FunctionType::ForallList operator() ( const FunctionType::ForallList & o ) {
+		return subs.clone( o, *visitor );
+	}
+
+	template<typename node_t > 
+	std::vector<ptr<node_t>> operator() (const std::vector<ptr<node_t>> & o) {
+		std::vector<ptr<node_t>> n;
+		n.reserve(o.size());
+		for (const node_t * d : o) { n.emplace_back(d->accept(*visitor)); }
+		return n;
+	}
+	
+	/*
+
+	/// Substitute parameter/return type
+	std::vector< ptr< DeclWithType > > operator() ( const std::vector< ptr< DeclWithType > > & o ) {
+		std::vector< ptr< DeclWithType > > n;
+		n.reserve( o.size() );
+		for ( const DeclWithType * d : o ) { n.emplace_back( d->accept( *visitor ) ); }
+		return n;
+	}
+
+	/// Substitute type parameter list
+	std::vector< ptr< Expr > > operator() ( const std::vector< ptr< Expr > > & o ) {
+		std::vector< ptr< Expr > > n;
+		n.reserve( o.size() );
+		for ( const Expr * d : o ) { n.emplace_back( d->accept( *visitor ) ); }
+		return n;
+	}
+
+	*/
+};
+
+} // namespace ast
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/AST/Node.hpp
===================================================================
--- src/AST/Node.hpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/Node.hpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -229,6 +229,5 @@
 	const node_t & operator* () const { _check(); return *node; }
 	explicit operator bool() const { _check(); return node; }
-	operator const node_t * () const & { _check(); return node; }
-	operator const node_t * () && = delete;
+	operator const node_t * () const { _check(); return node; }
 
 	const node_t * release() {
Index: src/AST/Pass.hpp
===================================================================
--- src/AST/Pass.hpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/Pass.hpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -34,4 +34,6 @@
 
 #include "AST/SymbolTable.hpp"
+
+#include "AST/ForallSubstitutionTable.hpp"
 
 // Private prelude header, needed for some of the magic tricks this class pulls off
@@ -64,4 +66,5 @@
 // | WithVisitorRef        - provides an pointer to the templated visitor wrapper
 // | WithSymbolTable       - provides symbol table functionality
+// | WithForallSubstitutor - maintains links between TypeInstType and TypeDecl under mutation
 //
 // Other Special Members:
@@ -255,4 +258,8 @@
 	container_t< ptr<node_t> > call_accept( const container_t< ptr<node_t> > & container );
 
+	/// Mutate forall-list, accounting for presence of type substitution map
+	template<typename node_t>
+	void mutate_forall( const node_t *& );
+
 public:
 	/// Logic to call the accept and mutate the parent if needed, delegates call to accept
@@ -391,4 +398,9 @@
 };
 
+/// Use when the templated visitor needs to keep TypeInstType instances properly linked to TypeDecl
+struct WithForallSubstitutor {
+	ForallSubstitutionTable subs;
+};
+
 }
 
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/Pass.impl.hpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -367,4 +367,20 @@
 	}
 
+
+	template< typename core_t >
+	template< typename node_t >
+	void ast::Pass< core_t >::mutate_forall( const node_t *& node ) {
+		if ( auto subs = __pass::forall::subs( core, 0 ) ) {
+			// tracking TypeDecl substitution, full clone
+			if ( node->forall.empty() ) return;
+
+			node_t * mut = __pass::mutate<core_t>( node );
+			mut->forall = subs->clone( node->forall, *this );
+			node = mut;
+		} else {
+			// not tracking TypeDecl substitution, just mutate
+			maybe_accept( node, &node_t::forall );
+		}
+	}
 }
 
@@ -488,10 +504,9 @@
 			__pass::symtab::addId( core, 0, func );
 			VISIT(
-				// parameter declarations
+				// parameter declarations are now directly here
 				maybe_accept( node, &FunctionDecl::params );
 				maybe_accept( node, &FunctionDecl::returns );
-				// type params and assertions
-				maybe_accept( node, &FunctionDecl::type_params );
-				maybe_accept( node, &FunctionDecl::assertions );
+				// foralls are still in function type
+				maybe_accept( node, &FunctionDecl::type );
 				// First remember that we are now within a function.
 				ValueGuard< bool > oldInFunction( inFunction );
@@ -1743,7 +1758,6 @@
 
 	VISIT({
-		// guard_forall_subs forall_guard { *this, node };
-		// mutate_forall( node );
-		maybe_accept( node, &FunctionType::assertions );
+		guard_forall_subs forall_guard { *this, node };
+		mutate_forall( node );
 		maybe_accept( node, &FunctionType::returns );
 		maybe_accept( node, &FunctionType::params  );
@@ -1967,5 +1981,5 @@
 		{
 			bool mutated = false;
-			std::unordered_map< ast::TypeInstType::TypeEnvKey, ast::ptr< ast::Type > > new_map;
+			std::unordered_map< std::string, ast::ptr< ast::Type > > new_map;
 			for ( const auto & p : node->typeEnv ) {
 				guard_symtab guard { *this };
@@ -1980,4 +1994,20 @@
 			}
 		}
+
+		{
+			bool mutated = false;
+			std::unordered_map< std::string, ast::ptr< ast::Expr > > new_map;
+			for ( const auto & p : node->varEnv ) {
+				guard_symtab guard { *this };
+				auto new_node = p.second->accept( *this );
+				if (new_node != p.second) mutated = true;
+				new_map.insert({ p.first, new_node });
+			}
+			if (mutated) {
+				auto new_node = __pass::mutate<core_t>( node );
+				new_node->varEnv.swap( new_map );
+				node = new_node;
+			}
+		}
 	)
 
Index: src/AST/Pass.proto.hpp
===================================================================
--- src/AST/Pass.proto.hpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/Pass.proto.hpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -413,4 +413,13 @@
 		static inline auto leave( core_t &, long, const ast::FunctionType * ) {}
 
+		// Get the substitution table, if present
+		template<typename core_t>
+		static inline auto subs( core_t & core, int ) -> decltype( &core.subs ) {
+			return &core.subs;
+		}
+
+		template<typename core_t>
+		static inline ast::ForallSubstitutionTable * subs( core_t &, long ) { return nullptr; }
+
 		// Replaces a TypeInstType's base TypeDecl according to the table
 		template<typename core_t>
Index: src/AST/Print.cpp
===================================================================
--- src/AST/Print.cpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/Print.cpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -155,13 +155,4 @@
 	}
 
-	void print( const ast::FunctionType::AssertionList & assts ) {
-		if (assts.empty()) return;
-		os << "with assertions" << endl;
-		++indent;
-		printAll(assts);
-		os << indent;
-		--indent;
-	}
-
 	void print( const std::vector<ptr<Attribute>> & attrs ) {
 		if ( attrs.empty() ) return;
@@ -215,5 +206,6 @@
 	void preprint( const ast::NamedTypeDecl * node ) {
 		if ( ! node->name.empty() ) {
-			os << node->name << ": ";
+			if( deterministic_output && isUnboundType(node->name) ) os << "[unbound]:";
+			else os << node->name << ": ";
 		}
 
@@ -269,5 +261,4 @@
 	void preprint( const ast::FunctionType * node ) {
 		print( node->forall );
-		print( node->assertions );
 		print( node->qualifiers );
 	}
@@ -1384,5 +1375,5 @@
 	virtual const ast::Type * visit( const ast::TypeInstType * node ) override final {
 		preprint( node );
-		const auto & _name = deterministic_output && isUnboundType(node) ? "[unbound]" : node->typeString();
+		const auto & _name = deterministic_output && isUnboundType(node) ? "[unbound]" : node->name;
 		os << "instance of type " << _name
 		   << " (" << (node->kind == ast::TypeDecl::Ftype ? "" : "not ") << "function type)";
@@ -1511,7 +1502,15 @@
 		os << indent << "Types:" << endl;
 		for ( const auto& i : *node ) {
-			os << indent+1 << i.first.typeString() << " -> ";
+			os << indent+1 << i.first << " -> ";
 			indent += 2;
 			safe_print( i.second );
+			indent -= 2;
+			os << endl;
+		}
+		os << indent << "Non-types:" << endl;
+		for ( auto i = node->beginVar(); i != node->endVar(); ++i ) {
+			os << indent+1 << i->first << " -> ";
+			indent += 2;
+			safe_print( i->second );
 			indent -= 2;
 			os << endl;
Index: src/AST/SymbolTable.cpp
===================================================================
--- src/AST/SymbolTable.cpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/SymbolTable.cpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -414,11 +414,5 @@
 
 void SymbolTable::addFunction( const FunctionDecl * func ) {
-	for (auto & td : func->type_params) {
-		addType(td);
-	}
-	for (auto & asst : func->assertions) {
-		addId(asst);
-	}
-	// addTypes( func->type->forall );
+	addTypes( func->type->forall );
 	addIds( func->returns );
 	addIds( func->params );
Index: src/AST/Type.cpp
===================================================================
--- src/AST/Type.cpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/Type.cpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -21,4 +21,5 @@
 
 #include "Decl.hpp"
+#include "ForallSubstitutor.hpp" // for substituteForall
 #include "Init.hpp"
 #include "Common/utility.h"      // for copy, move
@@ -91,5 +92,24 @@
 // GENERATED END
 
+// --- ParameterizedType
+
+void FunctionType::initWithSub(
+	const FunctionType & o, Pass< ForallSubstitutor > & sub
+) {
+	forall = sub.core( o.forall );
+}
+
 // --- FunctionType
+
+
+FunctionType::FunctionType( const FunctionType & o )
+: Type( o.qualifiers, copy( o.attributes ) ), returns(), params(),
+  isVarArgs( o.isVarArgs ) {
+	Pass< ForallSubstitutor > sub;
+	initWithSub( o, sub );           // initialize substitution map
+	returns = sub.core( o.returns ); // apply to return and parameter types
+	params = sub.core( o.params );
+}
+
 namespace {
 	bool containsTtype( const std::vector<ptr<Type>> & l ) {
@@ -179,5 +199,16 @@
 		// TODO: once TypeInstType representation is updated, it should properly check
 		// if the context id is filled. this is a temporary hack for now
-		return typeInst->formal_usage > 0;
+		return isUnboundType(typeInst->name);
+	}
+	return false;
+}
+
+bool isUnboundType(const std::string & tname) {
+	// xxx - look for a type name produced by renameTyVars.
+
+	// TODO: once TypeInstType representation is updated, it should properly check
+	// if the context id is filled. this is a temporary hack for now
+	if (std::count(tname.begin(), tname.end(), '_') >= 3) {
+		return true;
 	}
 	return false;
Index: src/AST/Type.hpp
===================================================================
--- src/AST/Type.hpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/Type.hpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -36,4 +36,6 @@
 
 template< typename T > class Pass;
+
+struct ForallSubstitutor;
 
 class Type : public Node {
@@ -270,9 +272,10 @@
 /// Type of a function `[R1, R2](*)(P1, P2, P3)`
 class FunctionType final : public Type {
-public:
-	using ForallList = std::vector<ptr<TypeInstType>>;
-	using AssertionList = std::vector<ptr<VariableExpr>>;
+	protected:
+	/// initializes forall with substitutor
+	void initWithSub( const FunctionType & o, Pass< ForallSubstitutor > & sub );
+public:
+	using ForallList = std::vector<ptr<TypeDecl>>;
 	ForallList forall;
-	AssertionList assertions;
 
 	std::vector<ptr<Type>> returns;
@@ -289,5 +292,5 @@
 	: Type(q), returns(), params(), isVarArgs(va) {}
 
-	FunctionType( const FunctionType & o ) = default;
+	FunctionType( const FunctionType & o );
 
 	/// true if either the parameters or return values contain a tttype
@@ -394,26 +397,5 @@
 public:
 	readonly<TypeDecl> base;
-	// previously from renameTyVars; now directly use integer fields instead of synthesized strings
-	// a nonzero value of formal_usage indicates a formal type (only used in function type)
-	// a zero value of formal_usage indicates an actual type (referenced inside body of parametric structs and functions)
 	TypeDecl::Kind kind;
-	int formal_usage = 0;
-	int expr_id = 0;
-
-	// compact representation used for map lookups.
-	struct TypeEnvKey { 
-		const TypeDecl * base;
-		int formal_usage;
-		int expr_id;
-
-		TypeEnvKey() = default;
-		TypeEnvKey(const TypeDecl * base, int formal_usage = 0, int expr_id = 0): base(base), formal_usage(formal_usage), expr_id(expr_id) {}
-		TypeEnvKey(const TypeInstType & inst): base(inst.base), formal_usage(inst.formal_usage), expr_id(inst.expr_id) {}
-		std::string typeString() const { return std::string("_") + std::to_string(formal_usage) + "_" + std::to_string(expr_id) + "_" + base->name; }
-		bool operator==(const TypeEnvKey & other) const { return base == other.base && formal_usage == other.formal_usage && expr_id == other.expr_id; }
-
-	};
-
-	bool operator==(const TypeInstType & other) const { return base == other.base && formal_usage == other.formal_usage && expr_id == other.expr_id; }
 
 	TypeInstType(
@@ -427,7 +409,4 @@
 	TypeInstType( const TypeInstType & o ) = default;
 
-	TypeInstType( const TypeEnvKey & key )
-	: BaseInstType(key.base->name), base(key.base), kind(key.base->kind), formal_usage(key.formal_usage), expr_id(key.expr_id) {}
-
 	/// sets `base`, updating `kind` correctly
 	void set_base( const TypeDecl * );
@@ -439,9 +418,4 @@
 
 	const Type * accept( Visitor & v ) const override { return v.visit( this ); }
-
-	std::string typeString() const { 
-		if (formal_usage > 0) return std::string("_") + std::to_string(formal_usage) + "_" + std::to_string(expr_id) + "_" + name; 
-		else return name;
-	}
 private:
 	TypeInstType * clone() const override { return new TypeInstType{ *this }; }
@@ -536,18 +510,6 @@
 
 bool isUnboundType(const Type * type);
-
-}
-
-namespace std {
-	template<>
-	struct hash<typename ast::TypeInstType::TypeEnvKey> {
-		size_t operator() (const ast::TypeInstType::TypeEnvKey & x) const {
-			const size_t p = 1000007;
-			size_t res = reinterpret_cast<size_t>(x.base);
-			res = p * res + x.formal_usage;
-			res = p * res + x.expr_id;
-			return res;
-		} 
-	};
+bool isUnboundType(const std::string & tname);
+
 }
 
Index: src/AST/TypeEnvironment.cpp
===================================================================
--- src/AST/TypeEnvironment.cpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/TypeEnvironment.cpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -52,5 +52,5 @@
 	for ( const auto & i : open ) {
 		if ( first ) { first = false; } else { out << ' '; }
-		out << i.first.typeString() << "(" << i.second << ")";
+		out << i.first << "(" << i.second << ")";
 	}
 }
@@ -62,9 +62,6 @@
 		if(first) first = false;
 		else out << " ";
-
-		if( deterministic_output ) out << "[unbound]";
-		else out << "_" << var.formal_usage << "_" << var.expr_id << "_";
-
-		out << var.base->name;
+		if( deterministic_output && isUnboundType(var) ) out << "[unbound]";
+		else out << var;
 	}
 	out << ")";
@@ -82,5 +79,5 @@
 }
 
-const EqvClass * TypeEnvironment::lookup( const TypeInstType::TypeEnvKey & var ) const {
+const EqvClass * TypeEnvironment::lookup( const std::string & var ) const {
 	for ( ClassList::const_iterator i = env.begin(); i != env.end(); ++i ) {
 		if ( i->vars.find( var ) != i->vars.end() ) return &*i;
@@ -109,5 +106,5 @@
 
 void TypeEnvironment::add( const FunctionType::ForallList & tyDecls ) {
-	for ( auto & tyDecl : tyDecls ) {
+	for ( const TypeDecl * tyDecl : tyDecls ) {
 		env.emplace_back( tyDecl );
 	}
@@ -122,14 +119,12 @@
 void TypeEnvironment::writeToSubstitution( TypeSubstitution & sub ) const {
 	for ( const auto & clz : env ) {
-		TypeInstType::TypeEnvKey clzRep;
-		bool first = true;
+		std::string clzRep;
 		for ( const auto & var : clz.vars ) {
 			if ( clz.bound ) {
 				sub.add( var, clz.bound );
-			} else if ( first ) {
+			} else if ( clzRep.empty() ) {
 				clzRep = var;
-				first = false;
 			} else {
-				sub.add( var, new TypeInstType{ clzRep } );
+				sub.add( var, new TypeInstType{ clzRep, clz.data.kind } );
 			}
 		}
@@ -146,8 +141,8 @@
 	struct Occurs : public ast::WithVisitorRef<Occurs> {
 		bool result;
-		std::unordered_set< TypeInstType::TypeEnvKey > vars;
+		std::set< std::string > vars;
 		const TypeEnvironment & tenv;
 
-		Occurs( const TypeInstType::TypeEnvKey & var, const TypeEnvironment & env )
+		Occurs( const std::string & var, const TypeEnvironment & env )
 		: result( false ), vars(), tenv( env ) {
 			if ( const EqvClass * clz = tenv.lookup( var ) ) {
@@ -159,7 +154,7 @@
 
 		void previsit( const TypeInstType * typeInst ) {
-			if ( vars.count( *typeInst ) ) {
+			if ( vars.count( typeInst->name ) ) {
 				result = true;
-			} else if ( const EqvClass * clz = tenv.lookup( *typeInst ) ) {
+			} else if ( const EqvClass * clz = tenv.lookup( typeInst->name ) ) {
 				if ( clz->bound ) {
 					clz->bound->accept( *visitor );
@@ -170,5 +165,5 @@
 
 	/// true if `var` occurs in `ty` under `env`
-	bool occurs( const Type * ty, const TypeInstType::TypeEnvKey & var, const TypeEnvironment & env ) {
+	bool occurs( const Type * ty, const std::string & var, const TypeEnvironment & env ) {
 		Pass<Occurs> occur{ var, env };
 		maybe_accept( ty, occur );
@@ -285,10 +280,10 @@
 	// remove references from bound type, so that type variables can only bind to value types
 	ptr<Type> target = bindTo->stripReferences();
-	auto tyvar = open.find( *typeInst );
+	auto tyvar = open.find( typeInst->name );
 	assert( tyvar != open.end() );
 	if ( ! tyVarCompatible( tyvar->second, target ) ) return false;
-	if ( occurs( target, *typeInst, *this ) ) return false;
-
-	auto it = internal_lookup( *typeInst );
+	if ( occurs( target, typeInst->name, *this ) ) return false;
+
+	auto it = internal_lookup( typeInst->name );
 	if ( it != env.end() ) {
 		if ( it->bound ) {
@@ -313,5 +308,5 @@
 	} else {
 		env.emplace_back(
-			*typeInst, target, widen.first && widen.second, data );
+			typeInst->name, target, widen.first && widen.second, data );
 	}
 	return true;
@@ -323,6 +318,6 @@
 		WidenMode widen, const SymbolTable & symtab
 ) {
-	auto c1 = internal_lookup( *var1 );
-	auto c2 = internal_lookup( *var2 );
+	auto c1 = internal_lookup( var1->name );
+	auto c2 = internal_lookup( var2->name );
 
 	// exit early if variables already bound together
@@ -338,5 +333,5 @@
 	if ( c1 != env.end() ) {
 		if ( c1->bound ) {
-			if ( occurs( c1->bound, *var2, *this ) ) return false;
+			if ( occurs( c1->bound, var2->name, *this ) ) return false;
 			type1 = c1->bound;
 		}
@@ -345,5 +340,5 @@
 	if ( c2 != env.end() ) {
 		if ( c2->bound ) {
-			if ( occurs( c2->bound, *var1, *this ) ) return false;
+			if ( occurs( c2->bound, var1->name, *this ) ) return false;
 			type2 = c2->bound;
 		}
@@ -383,15 +378,15 @@
 	} else if ( c1 != env.end() ) {
 		// var2 unbound, add to env[c1]
-		c1->vars.emplace( *var2 );
+		c1->vars.emplace( var2->name );
 		c1->allowWidening = widen1;
 		c1->data.isComplete |= data.isComplete;
 	} else if ( c2 != env.end() ) {
 		// var1 unbound, add to env[c2]
-		c2->vars.emplace( *var1 );
+		c2->vars.emplace( var1->name );
 		c2->allowWidening = widen2;
 		c2->data.isComplete |= data.isComplete;
 	} else {
 		// neither var bound, create new class
-		env.emplace_back( *var1, *var2, widen1 && widen2, data );
+		env.emplace_back( var1->name, var2->name, widen1 && widen2, data );
 	}
 
@@ -457,5 +452,5 @@
 }
 
-TypeEnvironment::ClassList::iterator TypeEnvironment::internal_lookup( const TypeInstType::TypeEnvKey & var ) {
+TypeEnvironment::ClassList::iterator TypeEnvironment::internal_lookup( const std::string & var ) {
 	for ( ClassList::iterator i = env.begin(); i != env.end(); ++i ) {
 		if ( i->vars.count( var ) ) return i;
Index: src/AST/TypeEnvironment.hpp
===================================================================
--- src/AST/TypeEnvironment.hpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/TypeEnvironment.hpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -55,7 +55,7 @@
 /// recorded. More investigation is needed.
 struct AssertCompare {
-	bool operator()( const VariableExpr * d1, const VariableExpr * d2 ) const {
-		int cmp = d1->var->name.compare( d2->var->name );
-		return cmp < 0 || ( cmp == 0 && d1->result < d2->result );
+	bool operator()( const DeclWithType * d1, const DeclWithType * d2 ) const {
+		int cmp = d1->name.compare( d2->name );
+		return cmp < 0 || ( cmp == 0 && d1->get_type() < d2->get_type() );
 	}
 };
@@ -70,8 +70,8 @@
 
 /// Set of assertions pending satisfaction
-using AssertionSet = std::map< const VariableExpr *, AssertionSetValue, AssertCompare >;
+using AssertionSet = std::map< readonly<DeclWithType>, AssertionSetValue, AssertCompare >;
 
 /// Set of open variables
-using OpenVarSet = std::unordered_map< TypeInstType::TypeEnvKey, TypeDecl::Data >;
+using OpenVarSet = std::unordered_map< std::string, TypeDecl::Data >;
 
 /// Merges one set of open vars into another
@@ -89,5 +89,5 @@
 /// they bind to.
 struct EqvClass {
-	std::unordered_set< TypeInstType::TypeEnvKey > vars;
+	std::set< std::string > vars;
 	ptr<Type> bound;
 	bool allowWidening;
@@ -101,13 +101,13 @@
 
 	/// Singleton class constructor from TypeDecl
-	EqvClass( const TypeInstType * inst )
-	: vars{ *inst }, bound(), allowWidening( true ), data( inst->base ) {}
+	EqvClass( const TypeDecl * decl )
+	: vars{ decl->name }, bound(), allowWidening( true ), data( decl ) {}
 
 	/// Singleton class constructor from substitution
-	EqvClass( const TypeInstType::TypeEnvKey & v, const Type * b )
+	EqvClass( const std::string & v, const Type * b )
 	: vars{ v }, bound( b ), allowWidening( false ), data( TypeDecl::Dtype, false ) {}
 
 	/// Single-var constructor (strips qualifiers from bound type)
-	EqvClass( const TypeInstType::TypeEnvKey & v, const Type * b, bool w, const TypeDecl::Data & d )
+	EqvClass( const std::string & v, const Type * b, bool w, const TypeDecl::Data & d )
 	: vars{ v }, bound( b ), allowWidening( w ), data( d ) {
 		reset_qualifiers( bound );
@@ -115,5 +115,5 @@
 
 	/// Double-var constructor
-	EqvClass( const TypeInstType::TypeEnvKey & v, const TypeInstType::TypeEnvKey & u, bool w, const TypeDecl::Data & d )
+	EqvClass( const std::string & v, const std::string & u, bool w, const TypeDecl::Data & d )
 	: vars{ v, u }, bound(), allowWidening( w ), data( d ) {}
 
@@ -131,5 +131,5 @@
 public:
 	/// Finds the equivalence class containing a variable; nullptr for none such
-	const EqvClass * lookup( const TypeInstType::TypeEnvKey & var ) const;
+	const EqvClass * lookup( const std::string & var ) const;
 
 	/// Add a new equivalence class for each type variable
@@ -207,5 +207,5 @@
 
 	/// Private lookup API; returns array index of string, or env.size() for not found
-	ClassList::iterator internal_lookup( const TypeInstType::TypeEnvKey & );
+	ClassList::iterator internal_lookup( const std::string & );
 };
 
Index: src/AST/TypeSubstitution.cpp
===================================================================
--- src/AST/TypeSubstitution.cpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/TypeSubstitution.cpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -39,4 +39,5 @@
 void TypeSubstitution::initialize( const TypeSubstitution &src, TypeSubstitution &dest ) {
 	dest.typeEnv.clear();
+	dest.varEnv.clear();
 	dest.add( src );
 }
@@ -46,23 +47,26 @@
 		typeEnv[ i->first ] = i->second;
 	} // for
-}
-
-void TypeSubstitution::add( const TypeInstType * formalType, const Type *actualType ) {
-	typeEnv[ *formalType ] = actualType;
-}
-
-void TypeSubstitution::add( const TypeInstType::TypeEnvKey & key, const Type * actualType) {
-	typeEnv[ key ] = actualType;
-}
-
-void TypeSubstitution::remove( const TypeInstType * formalType ) {
-	TypeEnvType::iterator i = typeEnv.find( *formalType );
+	for ( VarEnvType::const_iterator i = other.varEnv.begin(); i != other.varEnv.end(); ++i ) {
+		varEnv[ i->first ] = i->second;
+	} // for
+}
+
+void TypeSubstitution::add( std::string formalType, const Type *actualType ) {
+	typeEnv[ formalType ] = actualType;
+}
+
+void TypeSubstitution::addVar( std::string formalExpr, const Expr *actualExpr ) {
+	varEnv[ formalExpr ] = actualExpr;
+}
+
+void TypeSubstitution::remove( std::string formalType ) {
+	TypeEnvType::iterator i = typeEnv.find( formalType );
 	if ( i != typeEnv.end() ) {
-		typeEnv.erase( *formalType );
-	} // if
-}
-
-const Type *TypeSubstitution::lookup( const TypeInstType * formalType ) const {
-	TypeEnvType::const_iterator i = typeEnv.find( *formalType );
+		typeEnv.erase( formalType );
+	} // if
+}
+
+const Type *TypeSubstitution::lookup( std::string formalType ) const {
+	TypeEnvType::const_iterator i = typeEnv.find( formalType );
 
 	// break on not in substitution set
@@ -71,9 +75,11 @@
 	// attempt to transitively follow TypeInstType links.
 	while ( const TypeInstType *actualType = i->second.as<TypeInstType>()) {
+		const std::string& typeName = actualType->name;
+
 		// break cycles in the transitive follow
-		if ( *formalType == *actualType ) break;
+		if ( formalType == typeName ) break;
 
 		// Look for the type this maps to, returning previous mapping if none-such
-		i = typeEnv.find( *actualType );
+		i = typeEnv.find( typeName );
 		if ( i == typeEnv.end() ) return actualType;
 	}
@@ -84,5 +90,5 @@
 
 bool TypeSubstitution::empty() const {
-	return typeEnv.empty();
+	return typeEnv.empty() && varEnv.empty();
 }
 
@@ -92,10 +98,8 @@
 		TypeSubstitution * newEnv;
 		EnvTrimmer( const TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
-		void previsit( FunctionType * ftype ) {
+		void previsit( TypeDecl * tyDecl ) {
 			// transfer known bindings for seen type variables
-			for (auto & formal : ftype->forall) {
-				if ( const Type * t = env->lookup( formal ) ) {
-					newEnv->add( formal, t );
-				}
+			if ( const Type * t = env->lookup( tyDecl->name ) ) {
+				newEnv->add( tyDecl->name, t );
 			}
 		}
@@ -126,8 +130,8 @@
 
 const Type * TypeSubstitution::Substituter::postvisit( const TypeInstType *inst ) {
-	BoundVarsType::const_iterator bound = boundVars.find( *inst );
+	BoundVarsType::const_iterator bound = boundVars.find( inst->name );
 	if ( bound != boundVars.end() ) return inst;
 
-	TypeEnvType::const_iterator i = sub.typeEnv.find( *inst );
+	TypeEnvType::const_iterator i = sub.typeEnv.find( inst->name );
 	if ( i == sub.typeEnv.end() ) {
 		return inst;
@@ -137,5 +141,5 @@
 		// TODO: investigate preventing type variables from being bound to themselves in the first place.
 		if ( const TypeInstType * replacement = i->second.as<TypeInstType>() ) {
-			if ( *inst == *replacement ) {
+			if ( inst->name == replacement->name ) {
 				return inst;
 			}
@@ -152,15 +156,24 @@
 }
 
+const Expr * TypeSubstitution::Substituter::postvisit( const NameExpr * nameExpr ) {
+	VarEnvType::const_iterator i = sub.varEnv.find( nameExpr->name );
+	if ( i == sub.varEnv.end() ) {
+		return nameExpr;
+	} else {
+		subCount++;
+		return i->second;
+	} // if
+}
+
 void TypeSubstitution::Substituter::previsit( const FunctionType * ptype ) {
 	GuardValue( boundVars );
 	// bind type variables from forall-qualifiers
 	if ( freeOnly ) {
-		for ( auto & tyvar : ptype->forall ) {
-				boundVars.insert( *tyvar );
+		for ( const TypeDecl * tyvar : ptype->forall ) {
+				boundVars.insert( tyvar->name );
 		} // for
 	} // if
 }
 
-/*
 void TypeSubstitution::Substituter::handleAggregateType( const BaseInstType * type ) {
 	GuardValue( boundVars );
@@ -171,5 +184,5 @@
 			if ( ! type->params.empty() ) {
 				for ( const TypeDecl * tyvar : decl->params ) {
-					boundVars.insert( *tyvar );
+					boundVars.insert( tyvar->name );
 				} // for
 			} // if
@@ -185,5 +198,4 @@
 	handleAggregateType( aggregateUseType );
 }
-*/
 
 } // namespace ast
Index: src/AST/TypeSubstitution.hpp
===================================================================
--- src/AST/TypeSubstitution.hpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/TypeSubstitution.hpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -69,10 +69,11 @@
 	}
 
-	void add( const TypeInstType * formalType, const Type *actualType );
-	void add( const TypeInstType::TypeEnvKey & key, const Type *actualType );
+	void add( std::string formalType, const Type *actualType );
 	void add( const TypeSubstitution &other );
-	void remove( const TypeInstType * formalType );
-	const Type *lookup( const TypeInstType * formalType ) const;
+	void remove( std::string formalType );
+	const Type *lookup( std::string formalType ) const;
 	bool empty() const;
+
+	void addVar( std::string formalExpr, const Expr *actualExpr );
 
 	template< typename FormalIterator, typename ActualIterator >
@@ -100,6 +101,8 @@
 	friend class Pass;
 
-	typedef std::unordered_map< TypeInstType::TypeEnvKey, ptr<Type> > TypeEnvType;
+	typedef std::unordered_map< std::string, ptr<Type> > TypeEnvType;
+	typedef std::unordered_map< std::string, ptr<Expr> > VarEnvType;
 	TypeEnvType typeEnv;
+	VarEnvType varEnv;
 
   public:
@@ -110,7 +113,10 @@
 	auto   end() const -> decltype( typeEnv.  end() ) { return typeEnv.  end(); }
 
+	auto beginVar()       -> decltype( varEnv.begin() ) { return varEnv.begin(); }
+	auto   endVar()       -> decltype( varEnv.  end() ) { return varEnv.  end(); }
+	auto beginVar() const -> decltype( varEnv.begin() ) { return varEnv.begin(); }
+	auto   endVar() const -> decltype( varEnv.  end() ) { return varEnv.  end(); }
 };
 
-// this is the only place where type parameters outside a function formal may be substituted.
 template< typename FormalIterator, typename ActualIterator >
 void TypeSubstitution::add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin ) {
@@ -123,5 +129,5 @@
 			if ( const TypeExpr *actual = actualIt->template as<TypeExpr>() ) {
 				if ( formal->name != "" ) {
-					typeEnv[ formal ] = actual->type;
+					typeEnv[ formal->name ] = actual->type;
 				} // if
 			} else {
@@ -129,10 +135,11 @@
 			} // if
 		} else {
-			
+			// TODO: type check the formal and actual parameters
+			if ( (*formalIt)->name != "" ) {
+				varEnv[ (*formalIt)->name ] = *actualIt;
+			} // if
 		} // if
 	} // for
 }
-
-
 
 template< typename FormalIterator, typename ActualIterator >
@@ -140,5 +147,4 @@
 	add( formalBegin, formalEnd, actualBegin );
 }
-
 
 } // namespace ast
@@ -158,17 +164,18 @@
 
 		const Type * postvisit( const TypeInstType * aggregateUseType );
+		const Expr * postvisit( const NameExpr * nameExpr );
 
 		/// Records type variable bindings from forall-statements
 		void previsit( const FunctionType * type );
 		/// Records type variable bindings from forall-statements and instantiations of generic types
-		// void handleAggregateType( const BaseInstType * type );
-
-		// void previsit( const StructInstType * aggregateUseType );
-		// void previsit( const UnionInstType * aggregateUseType );
+		void handleAggregateType( const BaseInstType * type );
+
+		void previsit( const StructInstType * aggregateUseType );
+		void previsit( const UnionInstType * aggregateUseType );
 
 		const TypeSubstitution & sub;
 		int subCount = 0;
 		bool freeOnly;
-		typedef std::unordered_set< TypeInstType::TypeEnvKey > BoundVarsType;
+		typedef std::unordered_set< std::string > BoundVarsType;
 		BoundVarsType boundVars;
 
Index: src/AST/module.mk
===================================================================
--- src/AST/module.mk	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/AST/module.mk	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -33,4 +33,7 @@
 	AST/Expr.cpp \
 	AST/Expr.hpp \
+	AST/ForallSubstitutionTable.cpp \
+	AST/ForallSubstitutionTable.hpp \
+	AST/ForallSubstitutor.hpp \
 	AST/FunctionSpec.hpp \
 	AST/Fwd.hpp \
Index: src/GenPoly/GenPoly.cc
===================================================================
--- src/GenPoly/GenPoly.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/GenPoly/GenPoly.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -115,5 +115,5 @@
 		if (!env) return type;
 		if (auto typeInst = dynamic_cast<const ast::TypeInstType*> (type)) {
-			auto newType = env->lookup(typeInst);
+			auto newType = env->lookup(typeInst->name);
 			if (newType) return newType;
 		}
@@ -172,5 +172,5 @@
 
 		if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( type ) ) {
-			return tyVars.find(typeInst->typeString()) != tyVars.end() ? type : nullptr;
+			return tyVars.find(typeInst->name) != tyVars.end() ? type : nullptr;
 		} else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) {
 			return isPolyType( arrayType->base, env );
@@ -552,6 +552,6 @@
 	}
 
-	void addToTyVarMap( const ast::TypeInstType * tyVar, TyVarMap & tyVarMap) {
-		tyVarMap.insert(tyVar->typeString(), convData(ast::TypeDecl::Data{tyVar->base}));
+	void addToTyVarMap( const ast::TypeDecl * tyVar, TyVarMap & tyVarMap) {
+		tyVarMap.insert(tyVar->name, convData(ast::TypeDecl::Data{tyVar}));
 	}
 
Index: src/InitTweak/GenInit.cc
===================================================================
--- src/InitTweak/GenInit.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/InitTweak/GenInit.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -122,32 +122,6 @@
 	};
 
-	struct HoistArrayDimension_NoResolve final : public WithDeclsToAdd, public WithShortCircuiting, public WithGuards {
-		/// hoist dimension from array types in object declaration so that it uses a single
-		/// const variable of type size_t, so that side effecting array dimensions are only
-		/// computed once.
-		static void hoistArrayDimension( std::list< Declaration * > & translationUnit );
-
-		void premutate( ObjectDecl * objectDecl );
-		DeclarationWithType * postmutate( ObjectDecl * objectDecl );
-		void premutate( FunctionDecl *functionDecl );
-		// should not traverse into any of these declarations to find objects
-		// that need to be constructed or destructed
-		void premutate( AggregateDecl * ) { visit_children = false; }
-		void premutate( NamedTypeDecl * ) { visit_children = false; }
-		void premutate( FunctionType * ) { visit_children = false; }
-
-		void hoist( Type * type );
-
-		Type::StorageClasses storageClasses;
-		bool inFunction = false;
-	};
-
 	void genInit( std::list< Declaration * > & translationUnit ) {
-		if (!useNewAST) {
-			HoistArrayDimension::hoistArrayDimension( translationUnit );
-		}
-		else {
-			HoistArrayDimension_NoResolve::hoistArrayDimension( translationUnit );
-		}
+		HoistArrayDimension::hoistArrayDimension( translationUnit );
 		fixReturnStatements( translationUnit );
 
@@ -222,7 +196,9 @@
 
 			// need to resolve array dimensions in order to accurately determine if constexpr
-			ResolvExpr::findSingleExpression( arrayType->dimension, Validate::SizeType->clone(), indexer );
-			// array is variable-length when the dimension is not constexpr
-			arrayType->isVarLen = ! isConstExpr( arrayType->dimension );
+			if (!useNewAST) {
+				ResolvExpr::findSingleExpression( arrayType->dimension, Validate::SizeType->clone(), indexer );
+				// array is variable-length when the dimension is not constexpr
+				arrayType->isVarLen = ! isConstExpr( arrayType->dimension );
+			}
 			// don't need to hoist dimension if it's definitely pure - only need to if there's potential for side effects.
 			// xxx - hoisting has no side effects anyways, so don't skip since we delay resolve
@@ -242,52 +218,4 @@
 
 	void HoistArrayDimension::premutate( FunctionDecl * ) {
-		GuardValue( inFunction );
-		inFunction = true;
-	}
-
-	// precompute array dimension expression, because constructor generation may duplicate it,
-	// which would be incorrect if it is a side-effecting computation.
-	void HoistArrayDimension_NoResolve::hoistArrayDimension( std::list< Declaration * > & translationUnit ) {
-		PassVisitor<HoistArrayDimension_NoResolve> hoister;
-		mutateAll( translationUnit, hoister );
-	}
-
-	void HoistArrayDimension_NoResolve::premutate( ObjectDecl * objectDecl ) {
-		GuardValue( storageClasses );
-		storageClasses = objectDecl->get_storageClasses();
-	}
-
-	DeclarationWithType * HoistArrayDimension_NoResolve::postmutate( ObjectDecl * objectDecl ) {
-		hoist( objectDecl->get_type() );
-		return objectDecl;
-	}
-
-	void HoistArrayDimension_NoResolve::hoist( Type * type ) {
-		// if in function, generate const size_t var
-		static UniqueName dimensionName( "_array_dim" );
-
-		// C doesn't allow variable sized arrays at global scope or for static variables, so don't hoist dimension.
-		if ( ! inFunction ) return;
-		if ( storageClasses.is_static ) return;
-
-		if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) {
-			if ( ! arrayType->get_dimension() ) return; // xxx - recursive call to hoist?
-			// don't need to hoist dimension if it's definitely pure - only need to if there's potential for side effects.
-			// xxx - hoisting has no side effects anyways, so don't skip since we delay resolve
-			// still try to detect constant expressions
-			if ( ! Tuples::maybeImpure( arrayType->dimension ) ) return;
-
-			ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageClasses, LinkageSpec::C, 0, Validate::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) );
-			arrayDimension->get_type()->set_const( true );
-
-			arrayType->set_dimension( new VariableExpr( arrayDimension ) );
-			declsToAddBefore.push_back( arrayDimension );
-
-			hoist( arrayType->get_base() );
-			return;
-		}
-	}
-
-	void HoistArrayDimension_NoResolve::premutate( FunctionDecl * ) {
 		GuardValue( inFunction );
 		inFunction = true;
Index: src/ResolvExpr/AdjustExprType.cc
===================================================================
--- src/ResolvExpr/AdjustExprType.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/AdjustExprType.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -133,5 +133,5 @@
 		const ast::Type * postvisit( const ast::TypeInstType * inst ) {
 			// replace known function-type-variables with pointer-to-function
-			if ( const ast::EqvClass * eqvClass = tenv.lookup( *inst ) ) {
+			if ( const ast::EqvClass * eqvClass = tenv.lookup( inst->name ) ) {
 				if ( eqvClass->data.kind == ast::TypeDecl::Ftype ) {
 					return new ast::PointerType{ inst };
Index: src/ResolvExpr/CandidateFinder.cpp
===================================================================
--- src/ResolvExpr/CandidateFinder.cpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/CandidateFinder.cpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -212,5 +212,7 @@
 		// mark type variable and specialization cost of forall clause
 		convCost.incVar( function->forall.size() );
-		convCost.decSpec( function->assertions.size() );
+		for ( const ast::TypeDecl * td : function->forall ) {
+			convCost.decSpec( td->assertions.size() );
+		}
 
 		return convCost;
@@ -221,9 +223,9 @@
 		ast::AssertionSet & need
 	) {
-		for ( auto & tyvar : type->forall ) {
-			unifiableVars[ *tyvar ] = ast::TypeDecl::Data{ tyvar->base };
-		}
-		for ( auto & assn : type->assertions ) {
-			need[ assn ].isUsed = true;
+		for ( const ast::TypeDecl * tyvar : type->forall ) {
+			unifiableVars[ tyvar->name ] = ast::TypeDecl::Data{ tyvar };
+			for ( const ast::DeclWithType * assn : tyvar->assertions ) {
+				need[ assn ].isUsed = true;
+			}
 		}
 	}
@@ -905,10 +907,5 @@
 			// xxx - is it possible that handleTupleAssignment and main finder both produce candidates?
 			// this means there exists ctor/assign functions with a tuple as first parameter.
-			ResolvMode mode = {
-				true, // adjust
-				!untypedExpr->func.as<ast::NameExpr>(), // prune if not calling by name
-				selfFinder.candidates.empty() // failfast if other options are not found
-			};
-			funcFinder.find( untypedExpr->func, mode );
+			funcFinder.find( untypedExpr->func, selfFinder.candidates.empty() ? ResolvMode::withAdjustment() : ResolvMode::withoutFailFast() );
 			// short-circuit if no candidates
 			// if ( funcFinder.candidates.empty() ) return;
@@ -956,5 +953,5 @@
 						auto inst = dynamic_cast< const ast::TypeInstType * >( funcResult )
 					) {
-						if ( const ast::EqvClass * clz = func->env.lookup( *inst ) ) {
+						if ( const ast::EqvClass * clz = func->env.lookup( inst->name ) ) {
 							if ( auto function = clz->bound.as< ast::FunctionType >() ) {
 								CandidateRef newFunc{ new Candidate{ *func } };
@@ -1080,5 +1077,5 @@
 			assert( toType );
 			toType = resolveTypeof( toType, symtab );
-			// toType = SymTab::validateType( castExpr->location, toType, symtab );
+			toType = SymTab::validateType( castExpr->location, toType, symtab );
 			toType = adjustExprType( toType, tenv, symtab );
 
@@ -1165,5 +1162,5 @@
 
 					if(auto insttype = dynamic_cast<const ast::TypeInstType*>(expr)) {
-						auto td = cand->env.lookup(*insttype);
+						auto td = cand->env.lookup(insttype->name);
 						if(!td) { continue; }
 						expr = td->bound.get();
@@ -1571,5 +1568,5 @@
 				// calculate target type
 				const ast::Type * toType = resolveTypeof( initAlt.type, symtab );
-				// toType = SymTab::validateType( initExpr->location, toType, symtab );
+				toType = SymTab::validateType( initExpr->location, toType, symtab );
 				toType = adjustExprType( toType, tenv, symtab );
 				// The call to find must occur inside this loop, otherwise polymorphic return
Index: src/ResolvExpr/CastCost.cc
===================================================================
--- src/ResolvExpr/CastCost.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/CastCost.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -202,5 +202,5 @@
 ) {
 	if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
-		if ( const ast::EqvClass * eqvClass = env.lookup( *typeInst ) ) {
+		if ( const ast::EqvClass * eqvClass = env.lookup( typeInst->name ) ) {
 			// check cast cost against bound type, if present
 			if ( eqvClass->bound ) {
Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/CommonType.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -713,5 +713,5 @@
 			const ast::Type * base = oPtr->base;
 			if ( auto var = dynamic_cast< const ast::TypeInstType * >( base ) ) {
-				auto entry = open.find( *var );
+				auto entry = open.find( var->name );
 				if ( entry != open.end() ) {
 					ast::AssertionSet need, have;
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/ConversionCost.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -498,5 +498,5 @@
 ) {
 	if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
-		if ( const ast::EqvClass * eqv = env.lookup( *inst ) ) {
+		if ( const ast::EqvClass * eqv = env.lookup( inst->name ) ) {
 			if ( eqv->bound ) {
 				return conversionCost(src, eqv->bound, srcIsLvalue, symtab, env );
@@ -675,9 +675,9 @@
 
 void ConversionCost_new::postvisit( const ast::TypeInstType * typeInstType ) {
-	if ( const ast::EqvClass * eqv = env.lookup( *typeInstType ) ) {
+	if ( const ast::EqvClass * eqv = env.lookup( typeInstType->name ) ) {
 		cost = costCalc( eqv->bound, dst, srcIsLvalue, symtab, env );
 	} else if ( const ast::TypeInstType * dstAsInst =
 			dynamic_cast< const ast::TypeInstType * >( dst ) ) {
-		if ( *typeInstType == *dstAsInst ) {
+		if ( typeInstType->name == dstAsInst->name ) {
 			cost = Cost::zero;
 		}
Index: src/ResolvExpr/FindOpenVars.cc
===================================================================
--- src/ResolvExpr/FindOpenVars.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/FindOpenVars.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -112,16 +112,16 @@
 				// mark open/closed variables
 				if ( nextIsOpen ) {
-					for ( auto & decl : type->forall ) {
-						open[ *decl ] = ast::TypeDecl::Data{ decl->base };
-					}
-					for ( auto & assert : type->assertions ) {
-						need[ assert ].isUsed = false;
+					for ( const ast::TypeDecl * decl : type->forall ) {
+						open[ decl->name ] = ast::TypeDecl::Data{ decl };
+						for ( const ast::DeclWithType * assert : decl->assertions ) {
+							need[ assert ].isUsed = false;
+						}
 					}
 				} else {
-					for ( auto & decl : type->forall ) {
-						closed[ *decl ] = ast::TypeDecl::Data{ decl->base };	
-					}
-					for ( auto & assert : type->assertions ) {
-						have[ assert ].isUsed = false;
+					for ( const ast::TypeDecl * decl : type->forall ) {
+						closed[ decl->name ] = ast::TypeDecl::Data{ decl };
+						for ( const ast::DeclWithType * assert : decl->assertions ) {
+							have[ assert ].isUsed = false;
+						}
 					}
 				}
Index: src/ResolvExpr/PolyCost.cc
===================================================================
--- src/ResolvExpr/PolyCost.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/PolyCost.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -68,5 +68,5 @@
 
 	void previsit( const ast::TypeInstType * type ) {
-		if ( const ast::EqvClass * eqv = env_.lookup( *type ) ) /* && */ if ( eqv->bound ) {
+		if ( const ast::EqvClass * eqv = env_.lookup( type->name ) ) /* && */ if ( eqv->bound ) {
 			if ( const ast::TypeInstType * otherType = eqv->bound.as< ast::TypeInstType >() ) {
 				if ( symtab.lookupType( otherType->name ) ) {
Index: src/ResolvExpr/PtrsAssignable.cc
===================================================================
--- src/ResolvExpr/PtrsAssignable.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/PtrsAssignable.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -134,5 +134,5 @@
 	}
 	void postvisit( const ast::TypeInstType * inst ) {
-		if ( const ast::EqvClass * eqv = typeEnv.lookup( *inst ) ) {
+		if ( const ast::EqvClass * eqv = typeEnv.lookup( inst->name ) ) {
 			if ( eqv->bound ) {
 				// T * = S * for any S depends on the type bound to T
@@ -146,5 +146,5 @@
 		const ast::TypeEnvironment & env ) {
 	if ( const ast::TypeInstType * dstAsInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
-		if ( const ast::EqvClass * eqv = env.lookup( *dstAsInst ) ) {
+		if ( const ast::EqvClass * eqv = env.lookup( dstAsInst->name ) ) {
 			return ptrsAssignable( src, eqv->bound, env );
 		}
Index: src/ResolvExpr/PtrsCastable.cc
===================================================================
--- src/ResolvExpr/PtrsCastable.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/PtrsCastable.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -180,5 +180,5 @@
 					}
 				}
-			} else if ( const ast::EqvClass * eqvClass = env.lookup( *inst ) ) {
+			} else if ( const ast::EqvClass * eqvClass = env.lookup( inst->name ) ) {
 				if ( eqvClass->data.kind == ast::TypeDecl::Ftype ) {
 					return -1;
@@ -283,5 +283,5 @@
 ) {
 	if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
-		if ( const ast::EqvClass * eqvClass = env.lookup( *inst ) ) {
+		if ( const ast::EqvClass * eqvClass = env.lookup( inst->name ) ) {
 			return ptrsAssignable( src, eqvClass->bound, env );
 		}
Index: src/ResolvExpr/RenameVars.cc
===================================================================
--- src/ResolvExpr/RenameVars.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/RenameVars.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -19,4 +19,5 @@
 #include <utility>                 // for pair
 
+#include "AST/ForallSubstitutionTable.hpp"
 #include "AST/Pass.hpp"
 #include "AST/Type.hpp"
@@ -38,10 +39,8 @@
 		int level = 0;
 		int resetCount = 0;
+		ScopedMap< std::string, std::string > nameMap;
+	public:
+		ast::ForallSubstitutionTable subs;
 
-		int next_expr_id = 1;
-		int next_usage_id = 1;
-		ScopedMap< std::string, std::string > nameMap;
-		ScopedMap< std::string, ast::TypeInstType::TypeEnvKey > idMap;
-	public:
 		void reset() {
 			level = 0;
@@ -54,8 +53,4 @@
 				type->name = it->second;
 			}
-		}
-
-		void nextUsage() {
-			++next_usage_id;
 		}
 
@@ -83,13 +78,13 @@
 
 		const ast::TypeInstType * rename( const ast::TypeInstType * type ) {
+			// re-linking of base type handled by WithForallSubstitutor
+
 			// rename
-			auto it = idMap.find( type->name );
-			if ( it != idMap.end() ) {
-				// unconditionally mutate because map will *always* have different name
-				ast::TypeInstType * mut = ast::shallowCopy( type );
-				// reconcile base node since some copies might have been made
-				mut->base = it->second.base;
-				mut->formal_usage = it->second.formal_usage;
-				mut->expr_id = it->second.expr_id;
+			auto it = nameMap.find( type->name );
+			if ( it != nameMap.end() ) {
+				// unconditionally mutate because map will *always* have different name,
+				// if this mutates, will *always* have been mutated by ForallSubstitutor above
+				ast::TypeInstType * mut = ast::mutate( type );
+				mut->name = it->second;
 	            type = mut;
 			}
@@ -98,38 +93,34 @@
 		}
 
-		const ast::FunctionType * openLevel( const ast::FunctionType * type, RenameMode mode ) {
+		const ast::FunctionType * openLevel( const ast::FunctionType * type ) {
 			if ( type->forall.empty() ) return type;
-			idMap.beginScope();
+
+			nameMap.beginScope();
 
 			// Load new names from this forall clause and perform renaming.
-			auto mutType = ast::shallowCopy( type );
-			// assert( type == mutType && "mutated type must be unique from ForallSubstitutor" );
-			for ( auto & td : mutType->forall ) {
-				auto mut = ast::shallowCopy( td.get() );
-				// assert( td == mutDecl && "mutated decl must be unique from ForallSubstitutor" );
+			auto mutType = ast::mutate( type );
+			assert( type == mutType && "mutated type must be unique from ForallSubstitutor" );
+			for ( ast::ptr< ast::TypeDecl > & td : mutType->forall ) {
+				assertf(dynamic_cast<ast::FunctionType *>(mutType), "renaming vars in non-function type");
+				std::ostringstream output;
+				output << "_" << resetCount << "_" << level << "_" << td->name;
+				std::string newname =  output.str();
+				nameMap[ td->name ] = newname;
+				++level;
 
-				if (mode == GEN_EXPR_ID) {
-					mut->expr_id = next_expr_id;
-					mut->formal_usage = -1;
-					++next_expr_id;
-				}
-				else if (mode == GEN_USAGE) {
-					assertf(mut->expr_id, "unfilled expression id in generating candidate type");
-					mut->formal_usage = next_usage_id;
-				}
-				else {
-					assert(false);
-				}
-				idMap[ td->name ] = ast::TypeInstType::TypeEnvKey(*mut);
-				
-				td = mut;
+				ast::TypeDecl * mutDecl = ast::mutate( td.get() );
+				assert( td == mutDecl && "mutated decl must be unique from ForallSubstitutor" );
+				mutDecl->name = newname;
+				// assertion above means `td = mutDecl;` is unnecessary
 			}
+			// assertion above means `type = mutType;` is unnecessary
 
-			return mutType;
+			return type;
 		}
 
 		void closeLevel( const ast::FunctionType * type ) {
 			if ( type->forall.empty() ) return;
-			idMap.endScope();
+
+			nameMap.endScope();
 		}
 	};
@@ -151,9 +142,10 @@
 	};
 
-	struct RenameVars_new : public ast::PureVisitor /*: public ast::WithForallSubstitutor*/ {
-		RenameMode mode;
+	struct RenameVars_new /*: public ast::WithForallSubstitutor*/ {
+		#warning when old RenameVars goes away, replace hack below with global pass inheriting from WithForallSubstitutor
+		ast::ForallSubstitutionTable & subs = renaming.subs;
 
 		const ast::FunctionType * previsit( const ast::FunctionType * type ) {
-			return renaming.openLevel( type, mode );
+			return renaming.openLevel( type );
 		}
 
@@ -171,5 +163,4 @@
 
 		const ast::TypeInstType * previsit( const ast::TypeInstType * type ) {
-			if (mode == GEN_USAGE && !type->formal_usage) return type; // do not rename an actual type
 			return renaming.rename( type );
 		}
@@ -186,17 +177,13 @@
 }
 
-const ast::Type * renameTyVars( const ast::Type * t, RenameMode mode, bool reset ) {
-	// ast::Type *tc = ast::deepCopy(t);
+const ast::Type * renameTyVars( const ast::Type * t ) {
+	ast::Type *tc = ast::deepCopy(t);
 	ast::Pass<RenameVars_new> renamer;
-	renamer.core.mode = mode;
-	if (mode == GEN_USAGE && reset) {
-		renaming.nextUsage();
-	}
-	return t->accept( renamer );
+//	return t->accept( renamer );
+	return tc->accept( renamer );
 }
 
 void resetTyVarRenaming() {
 	renaming.reset();
-	renaming.nextUsage();
 }
 
Index: src/ResolvExpr/RenameVars.h
===================================================================
--- src/ResolvExpr/RenameVars.h	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/RenameVars.h	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -30,16 +30,8 @@
 	/// Provides a consistent renaming of forall type names in a hierarchy by prefixing them with a unique "level" ID
 	void renameTyVars( Type * );
-
-	enum RenameMode {
-		GEN_USAGE, // for type in VariableExpr
-		GEN_EXPR_ID // for type in decl
-	};
-	const ast::Type * renameTyVars( const ast::Type *, RenameMode mode = GEN_USAGE, bool reset = true );
-	
+	const ast::Type * renameTyVars( const ast::Type * );
 
 	/// resets internal state of renamer to avoid overflow
 	void resetTyVarRenaming();
-
-	
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/ResolvMode.h
===================================================================
--- src/ResolvExpr/ResolvMode.h	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/ResolvMode.h	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -23,7 +23,9 @@
 		const bool failFast;         ///< Fail on no resulting alternatives? [true]
 
+	private:
 		constexpr ResolvMode(bool a, bool p, bool ff) 
 		: adjust(a), prune(p), failFast(ff) {}
 
+	public:
 		/// Default settings
 		constexpr ResolvMode() : adjust(false), prune(true), failFast(true) {}
Index: src/ResolvExpr/ResolveAssertions.cc
===================================================================
--- src/ResolvExpr/ResolveAssertions.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/ResolveAssertions.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -397,5 +397,5 @@
 
 	/// Limit to depth of recursion of assertion satisfaction
-	static const int recursionLimit = 7;
+	static const int recursionLimit = 4;
 	/// Maximum number of simultaneously-deferred assertions to attempt concurrent satisfaction of
 	static const int deferLimit = 10;
Index: src/ResolvExpr/ResolveTypeof.cc
===================================================================
--- src/ResolvExpr/ResolveTypeof.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/ResolveTypeof.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -15,5 +15,4 @@
 
 #include "ResolveTypeof.h"
-#include "RenameVars.h"
 
 #include <cassert>               // for assert
@@ -219,5 +218,4 @@
 			mutDecl->mangleName = Mangle::mangle(mutDecl); // do not mangle unnamed variables
 		
-		mutDecl->type = renameTyVars(mutDecl->type, RenameMode::GEN_EXPR_ID);
 		mutDecl->isTypeFixed = true;
 		return mutDecl;
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/Resolver.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -986,4 +986,5 @@
 		};
 	} // anonymous namespace
+
 	/// Check if this expression is or includes a deleted expression
 	const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) {
@@ -1151,4 +1152,5 @@
 			const ast::Expr * untyped, const ast::SymbolTable & symtab
 		) {
+			resetTyVarRenaming();
 			ast::TypeEnvironment env;
 			ast::ptr< ast::Expr > newExpr = resolveInVoidContext( untyped, symtab, env );
@@ -1310,11 +1312,12 @@
 	}
 
-	const ast::Expr * resolveStmtExpr(
+	ast::ptr< ast::Expr > resolveStmtExpr(
 		const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab
 	) {
 		assert( stmtExpr );
 		ast::Pass< Resolver_new > resolver{ symtab };
-		auto ret = mutate(stmtExpr->accept(resolver));
-		strict_dynamic_cast< ast::StmtExpr * >( ret )->computeResult();
+		ast::ptr< ast::Expr > ret = stmtExpr;
+		ret = ret->accept( resolver );
+		strict_dynamic_cast< ast::StmtExpr * >( ret.get_and_mutate() )->computeResult();
 		return ret;
 	}
@@ -1372,17 +1375,15 @@
 			}
 
-			// handle assertions
+			// handle assertions. (seems deep)
 
 			symtab.enterScope();
-			mutType->forall.clear();
-			mutType->assertions.clear();
-			for (auto & typeParam : mutDecl->type_params) {
-				symtab.addType(typeParam);
-				mutType->forall.emplace_back(new ast::TypeInstType(typeParam->name, typeParam));
-			}
-			for (auto & asst : mutDecl->assertions) {
-				asst = fixObjectType(asst.strict_as<ast::ObjectDecl>(), symtab);
-				symtab.addId(asst);
-				mutType->assertions.emplace_back(new ast::VariableExpr(functionDecl->location, asst));
+			for (auto & typeParam : mutType->forall) {
+				auto mutParam = typeParam.get_and_mutate();
+				symtab.addType(mutParam);
+				for (auto & asst : mutParam->assertions) {
+					asst = fixObjectType(asst.strict_as<ast::ObjectDecl>(), symtab);
+					symtab.addId(asst);
+				}
+				typeParam = mutParam;
 			}
 
@@ -1406,6 +1407,4 @@
 			mutType->returns = std::move(returnTypes);
 
-			auto renamedType = strict_dynamic_cast<const ast::FunctionType *>(renameTyVars(mutType, RenameMode::GEN_EXPR_ID));
-
 			std::list<ast::ptr<ast::Stmt>> newStmts;
 			resolveWithExprs (mutDecl->withExprs, newStmts);
@@ -1419,5 +1418,4 @@
 			symtab.leaveScope();
 
-			mutDecl->type = renamedType;
 			mutDecl->mangleName = Mangle::mangle(mutDecl);
 			mutDecl->isTypeFixed = true;
@@ -1536,5 +1534,6 @@
 	const PtrType * handlePtrType( const PtrType * type, const ast::SymbolTable & symtab ) {
 		if ( type->dimension ) {
-			ast::ptr< ast::Type > sizeType = ast::sizeType;
+			#warning should use new equivalent to Validate::SizeType rather than sizeType here
+			ast::ptr< ast::Type > sizeType = new ast::BasicType{ ast::BasicType::LongUnsignedInt };
 			ast::mutate_field(
 				type, &PtrType::dimension,
Index: src/ResolvExpr/Resolver.h
===================================================================
--- src/ResolvExpr/Resolver.h	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/Resolver.h	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -72,6 +72,6 @@
 	ast::ptr< ast::Init > resolveCtorInit(
 		const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab );
-	/// Resolves a statement expression 
-	const ast::Expr * resolveStmtExpr(
+	/// Resolves a statement expression
+	ast::ptr< ast::Expr > resolveStmtExpr(
 		const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab );
 } // namespace ResolvExpr
Index: src/ResolvExpr/SatisfyAssertions.cpp
===================================================================
--- src/ResolvExpr/SatisfyAssertions.cpp	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/SatisfyAssertions.cpp	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -57,8 +57,8 @@
 		ast::UniqueId resnSlot;          ///< Slot for any recursive assertion IDs
 
-		AssnCandidate(
-			const ast::SymbolTable::IdData c, const ast::Type * at, ast::TypeEnvironment && e,
+		AssnCandidate( 
+			const ast::SymbolTable::IdData c, const ast::Type * at, ast::TypeEnvironment && e, 
 			ast::AssertionSet && h, ast::AssertionSet && n, ast::OpenVarSet && o, ast::UniqueId rs )
-		: cdata( c ), adjType( at ), env( std::move( e ) ), have( std::move( h ) ),
+		: cdata( c ), adjType( at ), env( std::move( e ) ), have( std::move( h ) ), 
 		  need( std::move( n ) ), open( std::move( o ) ), resnSlot( rs ) {}
 	};
@@ -69,19 +69,19 @@
 	/// Reference to a single deferred item
 	struct DeferRef {
-		const ast::VariableExpr * expr;
+		const ast::DeclWithType * decl;
 		const ast::AssertionSetValue & info;
 		const AssnCandidate & match;
 	};
-
-	/// Wrapper for the deferred items from a single assertion satisfaction.
+	
+	/// Wrapper for the deferred items from a single assertion satisfaction. 
 	/// Acts like an indexed list of DeferRef
 	struct DeferItem {
-		const ast::VariableExpr * expr;
+		const ast::DeclWithType * decl;
 		const ast::AssertionSetValue & info;
 		AssnCandidateList matches;
 
-		DeferItem(
-			const ast::VariableExpr * d, const ast::AssertionSetValue & i, AssnCandidateList && ms )
-		: expr( d ), info( i ), matches( std::move( ms ) ) {}
+		DeferItem( 
+			const ast::DeclWithType * d, const ast::AssertionSetValue & i, AssnCandidateList && ms )
+		: decl( d ), info( i ), matches( std::move( ms ) ) {}
 
 		bool empty() const { return matches.empty(); }
@@ -89,5 +89,5 @@
 		AssnCandidateList::size_type size() const { return matches.size(); }
 
-		DeferRef operator[] ( unsigned i ) const { return { expr, info, matches[i] }; }
+		DeferRef operator[] ( unsigned i ) const { return { decl, info, matches[i] }; }
 	};
 
@@ -117,18 +117,18 @@
 		/// Initial satisfaction state for a candidate
 		SatState( CandidateRef & c, const ast::SymbolTable & syms )
-		: cand( c ), need(), newNeed(), deferred(), inferred(), costs{ Cost::zero },
+		: cand( c ), need(), newNeed(), deferred(), inferred(), costs{ Cost::zero }, 
 		  symtab( syms ) { need.swap( c->need ); }
-
+		
 		/// Update satisfaction state for next step after previous state
 		SatState( SatState && o, IterateFlag )
-		: cand( std::move( o.cand ) ), need( o.newNeed.begin(), o.newNeed.end() ), newNeed(),
-		  deferred(), inferred( std::move( o.inferred ) ), costs( std::move( o.costs ) ),
+		: cand( std::move( o.cand ) ), need( o.newNeed.begin(), o.newNeed.end() ), newNeed(), 
+		  deferred(), inferred( std::move( o.inferred ) ), costs( std::move( o.costs ) ), 
 		  symtab( o.symtab ) { costs.emplace_back( Cost::zero ); }
-
+		
 		/// Field-wise next step constructor
 		SatState(
-			CandidateRef && c, ast::AssertionSet && nn, InferCache && i, CostVec && cs,
+			CandidateRef && c, ast::AssertionSet && nn, InferCache && i, CostVec && cs, 
 			ast::SymbolTable && syms )
-		: cand( std::move( c ) ), need( nn.begin(), nn.end() ), newNeed(), deferred(),
+		: cand( std::move( c ) ), need( nn.begin(), nn.end() ), newNeed(), deferred(), 
 		  inferred( std::move( i ) ), costs( std::move( cs ) ), symtab( std::move( syms ) )
 		  { costs.emplace_back( Cost::zero ); }
@@ -138,17 +138,17 @@
 	void addToSymbolTable( const ast::AssertionSet & have, ast::SymbolTable & symtab ) {
 		for ( auto & i : have ) {
-			if ( i.second.isUsed ) { symtab.addId( i.first->var ); }
+			if ( i.second.isUsed ) { symtab.addId( i.first ); }
 		}
 	}
 
 	/// Binds a single assertion, updating satisfaction state
-	void bindAssertion(
-		const ast::VariableExpr * expr, const ast::AssertionSetValue & info, CandidateRef & cand,
+	void bindAssertion( 
+		const ast::DeclWithType * decl, const ast::AssertionSetValue & info, CandidateRef & cand, 
 		AssnCandidate & match, InferCache & inferred
 	) {
 		const ast::DeclWithType * candidate = match.cdata.id;
-		assertf( candidate->uniqueId,
+		assertf( candidate->uniqueId, 
 			"Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
-
+		
 		ast::Expr * varExpr = match.cdata.combine( cand->expr->location, cand->cvtCost );
 		varExpr->result = match.adjType;
@@ -156,6 +156,6 @@
 
 		// place newly-inferred assertion in proper location in cache
-		inferred[ info.resnSlot ][ expr->var->uniqueId ] = ast::ParamEntry{
-			candidate->uniqueId, candidate, match.adjType, expr->result, varExpr };
+		inferred[ info.resnSlot ][ decl->uniqueId ] = ast::ParamEntry{
+			candidate->uniqueId, candidate, match.adjType, decl->get_type(), varExpr };
 	}
 
@@ -169,8 +169,8 @@
 
 		std::vector<ast::SymbolTable::IdData> candidates;
-		auto kind = ast::SymbolTable::getSpecialFunctionKind(assn.first->var->name);
+		auto kind = ast::SymbolTable::getSpecialFunctionKind(assn.first->name);
 		if (kind != ast::SymbolTable::SpecialFunctionKind::NUMBER_OF_KINDS) {
 			// prefilter special decls by argument type, if already known
-			ast::ptr<ast::Type> thisArgType = assn.first->result.strict_as<ast::PointerType>()->base
+			ast::ptr<ast::Type> thisArgType = strict_dynamic_cast<const ast::PointerType *>(assn.first->get_type())->base
 				.strict_as<ast::FunctionType>()->params[0]
 				.strict_as<ast::ReferenceType>()->base;
@@ -184,5 +184,5 @@
 		}
 		else {
-			candidates = sat.symtab.lookupId(assn.first->var->name);
+			candidates = sat.symtab.lookupId(assn.first->name);
 		}
 		for ( const ast::SymbolTable::IdData & cdata : candidates ) {
@@ -200,7 +200,7 @@
 			ast::TypeEnvironment newEnv{ sat.cand->env };
 			ast::OpenVarSet newOpen{ sat.cand->open };
-			ast::ptr< ast::Type > toType = assn.first->result;
-			ast::ptr< ast::Type > adjType =
-				renameTyVars( adjustExprType( candidate->get_type(), newEnv, sat.symtab ), GEN_USAGE, false );
+			ast::ptr< ast::Type > toType = assn.first->get_type();
+			ast::ptr< ast::Type > adjType = 
+				renameTyVars( adjustExprType( candidate->get_type(), newEnv, sat.symtab ) );
 
 			// only keep candidates which unify
@@ -213,5 +213,5 @@
 				}
 
-				matches.emplace_back(
+				matches.emplace_back( 
 					cdata, adjType, std::move( newEnv ), std::move( have ), std::move( newNeed ),
 					std::move( newOpen ), crntResnSlot );
@@ -287,9 +287,9 @@
 	};
 
-	/// Replace ResnSlots with InferParams and add alternative to output list, if it meets pruning
+	/// Replace ResnSlots with InferParams and add alternative to output list, if it meets pruning 
 	/// threshold.
-	void finalizeAssertions(
-		CandidateRef & cand, InferCache & inferred, PruneMap & thresholds, CostVec && costs,
-		CandidateList & out
+	void finalizeAssertions( 
+		CandidateRef & cand, InferCache & inferred, PruneMap & thresholds, CostVec && costs, 
+		CandidateList & out 
 	) {
 		// prune if cheaper alternative for same key has already been generated
@@ -308,6 +308,6 @@
 	}
 
-	/// Combo iterator that combines candidates into an output list, merging their environments.
-	/// Rejects an appended candidate if environments cannot be merged. See `Common/FilterCombos.h`
+	/// Combo iterator that combines candidates into an output list, merging their environments. 
+	/// Rejects an appended candidate if environments cannot be merged. See `Common/FilterCombos.h` 
 	/// for description of "combo iterator".
 	class CandidateEnvMerger {
@@ -337,5 +337,5 @@
 					// compute conversion cost from satisfying decl to assertion
 					cost += computeConversionCost(
-						assn.match.adjType, assn.expr->result, false, symtab, env );
+						assn.match.adjType, assn.decl->get_type(), false, symtab, env );
 
 					// mark vars+specialization on function-type assertions
@@ -350,5 +350,7 @@
 					cost.incVar( func->forall.size() );
 
-					cost.decSpec( func->assertions.size() );
+					for ( const ast::TypeDecl * td : func->forall ) {
+						cost.decSpec( td->assertions.size() );
+					}
 				}
 			}
@@ -385,11 +387,11 @@
 
 	/// Limit to depth of recursion of assertion satisfaction
-	static const int recursionLimit = 8;
+	static const int recursionLimit = 4;
 	/// Maximum number of simultaneously-deferred assertions to attempt concurrent satisfaction of
 	static const int deferLimit = 10;
 } // anonymous namespace
 
-void satisfyAssertions(
-	CandidateRef & cand, const ast::SymbolTable & symtab, CandidateList & out,
+void satisfyAssertions( 
+	CandidateRef & cand, const ast::SymbolTable & symtab, CandidateList & out, 
 	std::vector<std::string> & errors
 ) {
@@ -417,20 +419,8 @@
 			if ( it != thresholds.end() && it->second < sat.costs ) goto nextSat;
 
-			// should a limit be imposed? worst case here is O(n^2) but very unlikely to happen.
-			for (unsigned resetCount = 0; ; ++resetCount) {
-				ast::AssertionList next;
-				resetTyVarRenaming();
-				// make initial pass at matching assertions
-				for ( auto & assn : sat.need ) {
-					// fail early if any assertion is not satisfiable
-					if ( ! satisfyAssertion( assn, sat ) ) {
-						next.emplace_back(assn);
-						// goto nextSat;
-					}
-				}
-				// success
-				if (next.empty()) break;
-				// fail if nothing resolves
-				else if (next.size() == sat.need.size()) {
+			// make initial pass at matching assertions
+			for ( auto & assn : sat.need ) {
+				// fail early if any assertion is not satisfiable
+				if ( ! satisfyAssertion( assn, sat ) ) {
 					Indenter tabs{ 3 };
 					std::ostringstream ss;
@@ -438,10 +428,9 @@
 					print( ss, *sat.cand, ++tabs );
 					ss << (tabs-1) << "Could not satisfy assertion:\n";
-					ast::print( ss, next[0].first, tabs );
+					ast::print( ss, assn.first, tabs );
 
 					errors.emplace_back( ss.str() );
 					goto nextSat;
 				}
-				sat.need = std::move(next);
 			}
 
@@ -449,5 +438,5 @@
 				// either add successful match or push back next state
 				if ( sat.newNeed.empty() ) {
-					finalizeAssertions(
+					finalizeAssertions( 
 						sat.cand, sat.inferred, thresholds, std::move( sat.costs ), out );
 				} else {
@@ -462,5 +451,5 @@
 				ss << (tabs-1) << "Too many non-unique satisfying assignments for assertions:\n";
 				for ( const auto & d : sat.deferred ) {
-					ast::print( ss, d.expr, tabs );
+					ast::print( ss, d.decl, tabs );
 				}
 
@@ -471,5 +460,5 @@
 				std::vector< CandidateEnvMerger::OutType > compatible = filterCombos(
 					sat.deferred, CandidateEnvMerger{ sat.cand->env, sat.cand->open, sat.symtab } );
-
+				
 				// fail early if no mutually-compatible assertion satisfaction
 				if ( compatible.empty() ) {
@@ -480,5 +469,5 @@
 					ss << (tabs-1) << "No mutually-compatible satisfaction for assertions:\n";
 					for ( const auto& d : sat.deferred ) {
-						ast::print( ss, d.expr, tabs );
+						ast::print( ss, d.decl, tabs );
 					}
 
@@ -494,5 +483,5 @@
 					// set up next satisfaction state
 					CandidateRef nextCand = std::make_shared<Candidate>(
-						sat.cand->expr, std::move( compat.env ), std::move( compat.open ),
+						sat.cand->expr, std::move( compat.env ), std::move( compat.open ), 
 						ast::AssertionSet{} /* need moved into satisfaction state */,
 						sat.cand->cost, sat.cand->cvtCost );
@@ -500,8 +489,8 @@
 					ast::AssertionSet nextNewNeed{ sat.newNeed };
 					InferCache nextInferred{ sat.inferred };
-
+					
 					CostVec nextCosts{ sat.costs };
 					nextCosts.back() += compat.cost;
-
+								
 					ast::SymbolTable nextSymtab{ sat.symtab };
 
@@ -512,15 +501,15 @@
 						nextNewNeed.insert( match.need.begin(), match.need.end() );
 
-						bindAssertion( r.expr, r.info, nextCand, match, nextInferred );
+						bindAssertion( r.decl, r.info, nextCand, match, nextInferred );
 					}
 
 					// either add successful match or push back next state
 					if ( nextNewNeed.empty() ) {
-						finalizeAssertions(
+						finalizeAssertions( 
 							nextCand, nextInferred, thresholds, std::move( nextCosts ), out );
 					} else {
-						nextSats.emplace_back(
-							std::move( nextCand ), std::move( nextNewNeed ),
-							std::move( nextInferred ), std::move( nextCosts ),
+						nextSats.emplace_back( 
+							std::move( nextCand ), std::move( nextNewNeed ), 
+							std::move( nextInferred ), std::move( nextCosts ), 
 							std::move( nextSymtab ) );
 					}
@@ -534,5 +523,5 @@
 		nextSats.clear();
 	}
-
+	
 	// exceeded recursion limit if reaches here
 	if ( out.empty() ) {
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/ResolvExpr/Unify.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -773,5 +773,5 @@
 
 			const ast::Type * postvisit( const ast::TypeInstType * typeInst ) {
-				if ( const ast::EqvClass * clz = tenv.lookup( *typeInst ) ) {
+				if ( const ast::EqvClass * clz = tenv.lookup( typeInst->name ) ) {
 					// expand ttype parameter into its actual type
 					if ( clz->data.kind == ast::TypeDecl::Ttype && clz->bound ) {
@@ -811,5 +811,5 @@
 		/// Creates a tuple type based on a list of DeclWithType
 		template< typename Iter >
-		static const ast::Type * tupleFromTypes( Iter crnt, Iter end ) {
+		static ast::ptr< ast::Type > tupleFromTypes( Iter crnt, Iter end ) {
 			std::vector< ast::ptr< ast::Type > > types;
 			while ( crnt != end ) {
@@ -821,5 +821,5 @@
 			}
 
-			return new ast::TupleType{ std::move(types) };
+			return { new ast::TupleType{ std::move(types) } };
 		}
 
@@ -888,5 +888,5 @@
 		}
 
-		static void markAssertionSet( ast::AssertionSet & assns, const ast::VariableExpr * assn ) {
+		static void markAssertionSet( ast::AssertionSet & assns, const ast::DeclWithType * assn ) {
 			auto i = assns.find( assn );
 			if ( i != assns.end() ) {
@@ -900,7 +900,9 @@
 			const ast::FunctionType * type
 		) {
-			for ( auto & assert : type->assertions ) {
-				markAssertionSet( assn1, assert );
-				markAssertionSet( assn2, assert );
+			for ( const auto & tyvar : type->forall ) {
+				for ( const ast::DeclWithType * assert : tyvar->assertions ) {
+					markAssertionSet( assn1, assert );
+					markAssertionSet( assn2, assert );
+				}
 			}
 		}
@@ -1028,5 +1030,5 @@
 
 		void postvisit( const ast::TypeInstType * typeInst ) {
-			assert( open.find( *typeInst ) == open.end() );
+			assert( open.find( typeInst->name ) == open.end() );
 			handleRefType( typeInst, type2 );
 		}
@@ -1034,5 +1036,5 @@
 	private:
 		/// Creates a tuple type based on a list of Type
-		static const ast::Type * tupleFromTypes(
+		static ast::ptr< ast::Type > tupleFromTypes(
 			const std::vector< ast::ptr< ast::Type > > & tys
 		) {
@@ -1169,6 +1171,6 @@
 		auto var2 = dynamic_cast< const ast::TypeInstType * >( type2 );
 		ast::OpenVarSet::const_iterator
-			entry1 = var1 ? open.find( *var1 ) : open.end(),
-			entry2 = var2 ? open.find( *var2 ) : open.end();
+			entry1 = var1 ? open.find( var1->name ) : open.end(),
+			entry2 = var2 ? open.find( var2->name ) : open.end();
 		bool isopen1 = entry1 != open.end();
 		bool isopen2 = entry2 != open.end();
Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/SymTab/Mangler.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -671,5 +671,5 @@
 					int dcount = 0, fcount = 0, vcount = 0, acount = 0;
 					mangleName += Encoding::forall;
-					for ( auto & decl : ptype->forall ) {
+					for ( const ast::TypeDecl * decl : ptype->forall ) {
 						switch ( decl->kind ) {
 						case ast::TypeDecl::Kind::Dtype:
@@ -686,11 +686,11 @@
 						} // switch
 						varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
-					} // for
-					for ( auto & assert : ptype->assertions ) {
-						ast::Pass<Mangler_new> sub_mangler(
-							mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );
-						assert->var->accept( sub_mangler );
-						assertionNames.push_back( sub_mangler.core.get_mangleName() );
-						acount++;
+						for ( const ast::DeclWithType * assert : decl->assertions ) {
+							ast::Pass<Mangler_new> sub_mangler(
+								mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );
+							assert->accept( sub_mangler );
+							assertionNames.push_back( sub_mangler.core.get_mangleName() );
+							acount++;
+						} // for
 					} // for
 					mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/SymTab/Validate.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -271,5 +271,5 @@
 	};
 
-	struct InitializerLength {
+	struct ArrayLength : public WithIndexer {
 		/// for array types without an explicit length, compute the length and store it so that it
 		/// is known to the rest of the phases. For example,
@@ -282,9 +282,4 @@
 
 		void previsit( ObjectDecl * objDecl );
-	};
-
-	struct ArrayLength : public WithIndexer {
-		static void computeLength( std::list< Declaration * > & translationUnit );
-
 		void previsit( ArrayType * arrayType );
 	};
@@ -387,10 +382,6 @@
 					FixObjectType::fix, translationUnit);
 			}
-			Stats::Time::TimeCall("Initializer Length",
-				InitializerLength::computeLength, translationUnit);
-			if (!useNewAST) {
-				Stats::Time::TimeCall("Array Length",
-					ArrayLength::computeLength, translationUnit);
-			}
+			Stats::Time::TimeCall("Array Length",
+				ArrayLength::computeLength, translationUnit);
 			Stats::Time::TimeCall("Find Special Declarations",
 				Validate::findSpecialDecls, translationUnit);
@@ -1341,9 +1332,4 @@
 	}
 
-	void InitializerLength::computeLength( std::list< Declaration * > & translationUnit ) {
-		PassVisitor<InitializerLength> len;
-		acceptAll( translationUnit, len );
-	}
-
 	void ArrayLength::computeLength( std::list< Declaration * > & translationUnit ) {
 		PassVisitor<ArrayLength> len;
@@ -1351,5 +1337,5 @@
 	}
 
-	void InitializerLength::previsit( ObjectDecl * objDecl ) {
+	void ArrayLength::previsit( ObjectDecl * objDecl ) {
 		if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->type ) ) {
 			if ( at->dimension ) return;
@@ -1361,12 +1347,14 @@
 
 	void ArrayLength::previsit( ArrayType * type ) {
-		if ( type->dimension ) {
-			// need to resolve array dimensions early so that constructor code can correctly determine
-			// if a type is a VLA (and hence whether its elements need to be constructed)
-			ResolvExpr::findSingleExpression( type->dimension, Validate::SizeType->clone(), indexer );
-
-			// must re-evaluate whether a type is a VLA, now that more information is available
-			// (e.g. the dimension may have been an enumerator, which was unknown prior to this step)
-			type->isVarLen = ! InitTweak::isConstExpr( type->dimension );
+		if (!useNewAST) {
+			if ( type->dimension ) {
+				// need to resolve array dimensions early so that constructor code can correctly determine
+				// if a type is a VLA (and hence whether its elements need to be constructed)
+				ResolvExpr::findSingleExpression( type->dimension, Validate::SizeType->clone(), indexer );
+
+				// must re-evaluate whether a type is a VLA, now that more information is available
+				// (e.g. the dimension may have been an enumerator, which was unknown prior to this step)
+				type->isVarLen = ! InitTweak::isConstExpr( type->dimension );
+			}
 		}
 	}
@@ -1474,6 +1462,4 @@
 		}
 	}
-
-	/*
 
 	/// Associates forward declarations of aggregates with their definitions
@@ -1858,8 +1844,6 @@
 		}
 	};
-	*/
 } // anonymous namespace
 
-/*
 const ast::Type * validateType(
 		const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) {
@@ -1870,5 +1854,4 @@
 	return type->accept( lrt )->accept( fpd );
 }
-*/
 
 } // namespace SymTab
Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ src/Tuples/TupleAssignment.cc	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -504,6 +504,7 @@
 
 			std::vector< ast::ptr< ast::Expr > > match() override {
-				static UniqueName lhsNamer( "__massassign_L" );
-				static UniqueName rhsNamer( "__massassign_R" );
+				// temporary workaround for new and old ast to coexist and avoid name collision
+				static UniqueName lhsNamer( "__massassign_Ln" );
+				static UniqueName rhsNamer( "__massassign_Rn" );
 				// empty tuple case falls into this matcher
 				assert( lhs.empty() ? rhs.empty() : rhs.size() <= 1 );
@@ -534,6 +535,7 @@
 
 			std::vector< ast::ptr< ast::Expr > > match() override {
-				static UniqueName lhsNamer( "__multassign_L" );
-				static UniqueName rhsNamer( "__multassign_R" );
+				// temporary workaround for new and old ast to coexist and avoid name collision
+				static UniqueName lhsNamer( "__multassign_Ln" );
+				static UniqueName rhsNamer( "__multassign_Rn" );
 
 				if ( lhs.size() != rhs.size() ) return {};
Index: tests/.expect/KRfunctions.nast.x86.txt
===================================================================
--- tests/.expect/KRfunctions.nast.x86.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ tests/.expect/KRfunctions.nast.x86.txt	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -86,12 +86,12 @@
     __attribute__ ((unused)) signed int (*_X11_retval_f11PA0i_1)[];
 }
-signed int (*_X3f12FPA0A0i_iPiPi__1(signed int _X1ai_1, signed int *_X1bPi_1, signed int *_X1cPi_1))[][((unsigned int )10)]{
-    __attribute__ ((unused)) signed int (*_X11_retval_f12PA0A0i_1)[][((unsigned int )10)];
+signed int (*_X3f12FPA0A0i_iPiPi__1(signed int _X1ai_1, signed int *_X1bPi_1, signed int *_X1cPi_1))[][((unsigned long int )10)]{
+    __attribute__ ((unused)) signed int (*_X11_retval_f12PA0A0i_1)[][((unsigned long int )10)];
 }
-signed int (*_X3f13FPA0A0i_iPiPi__1(signed int _X1ai_1, signed int *_X1bPi_1, signed int *_X1cPi_1))[][((unsigned int )10)]{
-    __attribute__ ((unused)) signed int (*_X11_retval_f13PA0A0i_1)[][((unsigned int )10)];
+signed int (*_X3f13FPA0A0i_iPiPi__1(signed int _X1ai_1, signed int *_X1bPi_1, signed int *_X1cPi_1))[][((unsigned long int )10)]{
+    __attribute__ ((unused)) signed int (*_X11_retval_f13PA0A0i_1)[][((unsigned long int )10)];
 }
-signed int (*_X3f14FPA0A0i_iPiPi__1(signed int _X1ai_1, signed int *_X1bPi_1, signed int *_X1cPi_1))[][((unsigned int )10)]{
-    __attribute__ ((unused)) signed int (*_X11_retval_f14PA0A0i_1)[][((unsigned int )10)];
+signed int (*_X3f14FPA0A0i_iPiPi__1(signed int _X1ai_1, signed int *_X1bPi_1, signed int *_X1cPi_1))[][((unsigned long int )10)]{
+    __attribute__ ((unused)) signed int (*_X11_retval_f14PA0A0i_1)[][((unsigned long int )10)];
 }
 signed int _X3f15Fi_iii__1(signed int _X1ai_1, signed int _X1bi_1, signed int _X1ci_1){
Index: tests/.expect/attributes.nast.x86.txt
===================================================================
--- tests/.expect/attributes.nast.x86.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ tests/.expect/attributes.nast.x86.txt	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -623,6 +623,6 @@
 __attribute__ ((used,used,used,used)) const signed int *_X3vd3PKi_1;
 __attribute__ ((used,used,unused,used,unused)) const signed int *_X3vd4PKi_1;
-__attribute__ ((used,used,used)) const signed int _X3vd5A0Ki_1[((unsigned int )5)];
-__attribute__ ((used,used,unused,used)) const signed int _X3vd6A0Ki_1[((unsigned int )5)];
+__attribute__ ((used,used,used)) const signed int _X3vd5A0Ki_1[((unsigned long int )5)];
+__attribute__ ((used,used,unused,used)) const signed int _X3vd6A0Ki_1[((unsigned long int )5)];
 __attribute__ ((used,used,used,used)) const signed int (*_X3vd7Fi___1)();
 __attribute__ ((used,used,unused,used,used)) const signed int (*_X3vd8Fi___1)();
@@ -647,6 +647,6 @@
     __attribute__ ((unused,unused,used)) signed int _X2t1i_2;
     __attribute__ ((unused,unused,unused,unused,unused)) signed int **_X2t2PPi_2;
-    __attribute__ ((unused,unused,unused)) signed int _X2t3A0i_2[((unsigned int )5)];
-    __attribute__ ((unused,unused,unused,unused,unused)) signed int **_X2t4A0PPi_2[((unsigned int )5)];
+    __attribute__ ((unused,unused,unused)) signed int _X2t3A0i_2[((unsigned long int )5)];
+    __attribute__ ((unused,unused,unused,unused,unused)) signed int **_X2t4A0PPi_2[((unsigned long int )5)];
     __attribute__ ((unused,unused,unused)) signed int _X2t5Fi___2();
     __attribute__ ((unused,unused,unused,unused)) signed int *_X2t6FPi___2();
@@ -671,5 +671,5 @@
 signed int _X4tpr2Fi_PPi__1(__attribute__ ((unused,unused,unused,unused,unused,unused)) signed int **_X3FooPPi_1);
 signed int _X4tpr3Fi_Pi__1(__attribute__ ((unused,unused,unused)) signed int *_X3FooPi_1);
-signed int _X4tpr4Fi_Fi_Pi___1(__attribute__ ((unused,unused)) signed int (*__anonymous_object1)(signed int __param_0[((unsigned int )5)]));
+signed int _X4tpr4Fi_Fi_Pi___1(__attribute__ ((unused,unused)) signed int (*__anonymous_object1)(signed int __param_0[((unsigned long int )5)]));
 signed int _X4tpr5Fi_Fi____1(__attribute__ ((unused,unused,unused)) signed int (*_X3FooFi___1)());
 signed int _X4tpr6Fi_Fi____1(__attribute__ ((unused,unused,unused)) signed int (*_X3FooFi___1)());
@@ -679,6 +679,6 @@
     __attribute__ ((used,unused)) signed int _X3ad1i_2;
     __attribute__ ((unused,unused,unused)) signed int *_X3ad2Pi_2;
-    __attribute__ ((unused,unused,unused)) signed int _X3ad3A0i_2[((unsigned int )5)];
-    __attribute__ ((unused,unused,unused,unused,unused)) signed int (*_X3ad4PA0i_2)[((unsigned int )10)];
+    __attribute__ ((unused,unused,unused)) signed int _X3ad3A0i_2[((unsigned long int )5)];
+    __attribute__ ((unused,unused,unused,unused,unused)) signed int (*_X3ad4PA0i_2)[((unsigned long int )10)];
     __attribute__ ((unused,unused,unused,unused,used)) signed int _X3ad5i_2;
     __attribute__ ((unused,unused,unused,unused,unused)) signed int _X3ad6Fi___2();
Index: tests/.expect/functions.nast.x86.txt
===================================================================
--- tests/.expect/functions.nast.x86.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ tests/.expect/functions.nast.x86.txt	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -46,9 +46,9 @@
     __attribute__ ((unused)) signed int (*_X11_retval_f10PA0i_1)[];
 }
-signed int (*_X3f11FPA0A0i___1())[][((unsigned int )3)]{
-    __attribute__ ((unused)) signed int (*_X11_retval_f11PA0A0i_1)[][((unsigned int )3)];
-}
-signed int (*_X3f12FPA0A0i___1())[][((unsigned int )3)]{
-    __attribute__ ((unused)) signed int (*_X11_retval_f12PA0A0i_1)[][((unsigned int )3)];
+signed int (*_X3f11FPA0A0i___1())[][((unsigned long int )3)]{
+    __attribute__ ((unused)) signed int (*_X11_retval_f11PA0A0i_1)[][((unsigned long int )3)];
+}
+signed int (*_X3f12FPA0A0i___1())[][((unsigned long int )3)]{
+    __attribute__ ((unused)) signed int (*_X11_retval_f12PA0A0i_1)[][((unsigned long int )3)];
 }
 signed int _X4fII1Fi_i__1(signed int _X1ii_1){
@@ -250,6 +250,6 @@
 signed int _X1fFi_Fi_ii_Fi_i___1(__attribute__ ((unused)) signed int (*__anonymous_object20)(signed int __param_0, signed int __param_1), __attribute__ ((unused)) signed int (*__anonymous_object21)(signed int __param_0)){
     __attribute__ ((unused)) signed int _X9_retval_fi_1;
-    signed int (*(*_X2pcPA0A0PA0A0i_2)[][((unsigned int )10)])[][((unsigned int )3)];
-    signed int (*(*_X1pPA0A0PA0A0i_2)[][((unsigned int )10)])[][((unsigned int )3)];
+    signed int (*(*_X2pcPA0A0PA0A0i_2)[][((unsigned long int )10)])[][((unsigned long int )3)];
+    signed int (*(*_X1pPA0A0PA0A0i_2)[][((unsigned long int )10)])[][((unsigned long int )3)];
     signed int (*(*_X1pPA0Fi_i__2)[])(signed int __param_0);
 }
Index: tests/.expect/multi_list.txt
===================================================================
--- tests/.expect/multi_list.txt	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
+++ tests/.expect/multi_list.txt	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -0,0 +1,4 @@
+9 8 7 6 5 4 3 2 1 0
+0 1 2 3 4 5 6 7 8 9
+9 8 7 6 5 4 3 2 1 0
+9 8 7 6 5 4 3 2 1 0
Index: tests/.expect/queue.txt
===================================================================
--- tests/.expect/queue.txt	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
+++ tests/.expect/queue.txt	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -0,0 +1,8 @@
+empty
+0 2 4 6 8 10 12 14 16 18 
+18 
+18 1 3 5 7 9 11 13 15 17 19 
+empty
+0 0 2 2 4 4 6 6 8 8 10 10 12 12 14 14 16 16 18 18 
+18 18 
+18 18 1 1 3 3 5 5 7 7 9 9 11 11 13 13 15 15 17 17 19 19 
Index: tests/.expect/sequence.txt
===================================================================
--- tests/.expect/sequence.txt	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
+++ tests/.expect/sequence.txt	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -0,0 +1,12 @@
+empty
+0 2 4 6 8 10 12 14 16 18 
+18 
+18 1 3 5 7 9 11 13 15 17 19 
+18 1 
+empty
+0 0 2 2 4 4 6 6 8 8 10 10 12 12 14 14 16 16 18 18 
+18 18 
+18 18 1 1 3 3 5 5 7 7 9 9 11 11 13 13 15 15 17 17 19 19 
+18 18 1 1 
+empty
+18 18 1 1 0 0 2 2 4 4 6 6 8 8 10 10 12 12 14 14 16 16 18 18 
Index: tests/.expect/stack.txt
===================================================================
--- tests/.expect/stack.txt	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
+++ tests/.expect/stack.txt	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -0,0 +1,8 @@
+empty
+18 16 14 12 10 8 6 4 2 0 
+0 
+19 17 15 13 11 9 7 5 3 1 0 
+empty
+18 18 16 16 14 14 12 12 10 10 8 8 6 6 4 4 2 2 0 0 
+0 0 
+19 19 17 17 15 15 13 13 11 11 9 9 7 7 5 5 3 3 1 1 0 0 
Index: tests/Makefile.am
===================================================================
--- tests/Makefile.am	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ tests/Makefile.am	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -103,9 +103,9 @@
 
 mostlyclean-local :
-	find ${builddir} -not -path './__pycache__/*' -path '*.o' -delete
-	find ${builddir} -not -path './__pycache__/*' -path '*/.err/*.log' -delete
-	find ${builddir} -not -path './__pycache__/*' -path '*/.out/*.log' -delete
 	rm -f ${EXTRA_PROGRAMS}
 	rm -rf __pycache__
+	find ${builddir} -path '*.o' -delete
+	find ${builddir} -path '*/.err/*.log' -delete
+	find ${builddir} -path '*/.out/*.log' -delete
 
 distclean-local :
Index: sts/collections/.expect/multi_list.txt
===================================================================
--- tests/collections/.expect/multi_list.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,4 +1,0 @@
-9 8 7 6 5 4 3 2 1 0
-0 1 2 3 4 5 6 7 8 9
-9 8 7 6 5 4 3 2 1 0
-9 8 7 6 5 4 3 2 1 0
Index: sts/collections/.expect/queue.txt
===================================================================
--- tests/collections/.expect/queue.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,26 +1,0 @@
-empty
-0 18
-0 2 4 6 8 10 12 14 16 18 
-18 
--1 18 -2
--1 18 1 3 5 7 9 11 13 15 17 19 -2 
-18 1 3 5 7 9 11 13 15 17 
-18 1 3 5 7 
-empty
-0 1 2 3 4 5 6 7 8 9 
-5 6 7 8 9 
-0 1 2 3 4 
-5 6 7 8 9 0 1 2 3 4 
-empty
-0 18
-0 0 2 2 4 4 6 6 8 8 10 10 12 12 14 14 16 16 18 18 
-18 18 
--1 18 -2
--1 -1 18 18 1 1 3 3 5 5 7 7 9 9 11 11 13 13 15 15 17 17 19 19 -2 -2 
-18 18 1 1 3 3 5 5 7 7 9 9 11 11 13 13 15 15 17 17 
-18 18 1 1 3 3 5 5 7 7 
-empty
-0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 
-5 5 6 6 7 7 8 8 9 9 
-0 0 1 1 2 2 3 3 4 4 
-5 5 6 6 7 7 8 8 9 9 0 0 1 1 2 2 3 3 4 4 
Index: sts/collections/.expect/sequence.txt
===================================================================
--- tests/collections/.expect/sequence.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,29 +1,0 @@
-empty
-0 18
-0 2 4 6 8 10 12 14 16 18 
-18 
--1 18 -2
--1 18 1 3 5 7 9 11 13 15 17 19 -2 
-18 1 3 5 7 9 11 13 15 17 
-18 1 3 5 7 
-empty
-0 1 2 3 4 5 6 7 8 9 
--1 -2 0
--1 -2 9 8 7 6 5 4 3 2 1 0 
-9 8 7 6 5 4 3 2 1 
-4 3 2 1 
-9 8 7 6 5 
-4 3 2 1 9 8 7 6 5 
-empty
-0 18
-0 0 2 2 4 4 6 6 8 8 10 10 12 12 14 14 16 16 18 18 
-18 18 
--1 18 -2
--1 -1 18 18 1 1 3 3 5 5 7 7 9 9 11 11 13 13 15 15 17 17 19 19 -2 -2 
-18 18 1 1 3 3 5 5 7 7 9 9 11 11 13 13 15 15 17 17 
-18 18 1 1 3 3 5 5 7 7 
-empty
-0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 
-5 5 6 6 7 7 8 8 9 9 
-0 0 1 1 2 2 3 3 4 4 
-5 5 6 6 7 7 8 8 9 9 0 0 1 1 2 2 3 3 4 4 
Index: sts/collections/.expect/stack.txt
===================================================================
--- tests/collections/.expect/stack.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,9 +1,0 @@
-empty
-18 16 14 12 10 8 6 4 2 0 
-18
-0 
-19 17 15 13 11 9 7 5 3 1 0 
-empty
-18 18 16 16 14 14 12 12 10 10 8 8 6 6 4 4 2 2 0 0 
-0 0 
-19 19 17 17 15 15 13 13 11 11 9 9 7 7 5 5 3 3 1 1 0 0 
Index: sts/collections/multi_list.cfa
===================================================================
--- tests/collections/multi_list.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,113 +1,0 @@
-#include <fstream.hfa>
-#include <stdlib.hfa>
-#include <bits/stack.hfa>
-#include <bits/queue.hfa>
-#include <bits/sequence.hfa>
-
-struct Task;											// node type
-
-struct TaskDL {
-	inline Seqable;
-	Task & node;
-};
-void ?{}( TaskDL & this, Task & task ) with( this ) {
-	((Seqable &)this){};
-	&node = &task;										// pointer to containing node
-}
-Task & task( TaskDL & this ) with( this ) {				// getter routine for containing node
-	return node;
-}
-
-TaskDL *& Back( TaskDL * n ) {
-	return (TaskDL *)Back( (Seqable *)n );
-}
-
-TaskDL *& Next( TaskDL * n ) {
-	return (TaskDL *)Next( (Colable *)n );
-}
-
-struct TaskSL {
-	inline Colable;
-	Task & node;
-};
-void ?{}( TaskSL & this, Task & task ) with( this ) {
-	((Colable &)this){};
-	&node = &task;										// pointer to containing node
-}
-Task & task( TaskSL & this ) with( this ) {				// getter routine for containing node
-	return node;
-}
-
-TaskSL *& Next( TaskSL * n ) {
-	return (TaskSL *)Next( (Colable *)n );
-}
-
-struct Task {
-	TaskDL clusterRef;									// list of tasks on cluster
-	TaskDL readyRef;									// list of tasks on ready queue
-	TaskSL mutexRef;									// list of tasks on mutex queue
-	int id;
-};
-void ?{}( Task & this, int id ) with( this ) {
-	((TaskDL &)clusterRef){ this };
-	((TaskDL &)readyRef){ this };
-	((TaskSL &)mutexRef){ this };
-	this.id = id;
-}
-
-int main() {
-	Sequence(TaskDL) clustList, readyList;				// task lists
-	Queue(TaskSL) mutexList;
-	enum { Lnth = 10 };
-
-	for ( id; Lnth ) {
-		Task & task = *new( id );						// create task node
-		addHead( clustList, task.clusterRef );			// insert on lists in opposite directions
-		addTail( readyList, task.readyRef );
-		addHead( mutexList, task.mutexRef );
-	}
-
-	SeqIter(TaskDL) sqiter;
-	TaskDL & dl;										// iterator index
-	TaskSL & sl;
-
-	sout | nlOff;
-	for ( over( sqiter, clustList ); sqiter | dl; ) {	// print lists
-		Task & tmp = task( dl ); sout | tmp.id;
-		// sout | task( dl ).id;
-	}
-	sout | nl;
-	for ( over( sqiter, readyList ); sqiter | dl; ) {
-		Task & tmp = task( dl ); sout | tmp.id;
-		// sout | task( dl ).id;
-	}
-	sout | nl;
-	for ( QueueIter(TaskSL) qiter = { mutexList }; qiter | sl; ) {	// print lists
-		Task & tmp = task( sl ); sout | tmp.id;
-		// sout | task( sl ).id;
-	}
-	sout | nl;
-	for ( Lnth ) {										// remove nodes from clustList. mutexList
-		dropHead( clustList );
-		drop( mutexList );
-	}
-	// Simultaneous deletion only safe if all nodes are traversed in same direction.
-	for ( Lnth ) {										// remove nodes from readyList and safe to delete nodes
-		delete( &task( dropHead( readyList ) ) );
-	}
-
-	// Re-purpose Seqable as Colable
-	Stack(TaskDL) mutexStack;
-	for ( id; Lnth ) {
-		Task & task = *new( id );						// create task node
-		push( mutexStack, task.clusterRef );			// insert on lists in opposite directions
-	}
-	for ( StackIter(TaskDL) stiter = { mutexStack }; stiter | dl; ) {
-		Task & tmp = task( dl ); sout | tmp.id;
-		// sout | task( dl ).id;
-	}
-	sout | nl;
-	for ( Lnth ) {										// remove nodes from readyList and safe to delete nodes
-		delete( &task( pop( mutexStack ) ) );
-	}
-}
Index: sts/collections/queue.cfa
===================================================================
--- tests/collections/queue.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,249 +1,0 @@
-#include <fstream.hfa>
-#include <stdlib.hfa>									// new, delete
-#include <bits/queue.hfa>
-
-int main() {
-	// Fred test
-
-	struct Fred {
-		inline Colable;									// Plan 9 inheritance
-		int i;
-	};
-	void ?{}( Fred & fred ) { abort(); }
-	void ?{}( Fred & fred, int p ) with( fred ) {
-		i = p;
-	}
-	Fred *& Next( Fred * n ) {
-		return (Fred *)Next( (Colable *)n );
-	}
-
-	Queue(Fred) fred;
-	QueueIter(Fred) iter = { fred };
-	Fred & f;
-
-	sout | nlOff;										// turn off auto newline
-
-	for ( ; iter | f; ) {							// empty list
-		sout | f.i | ' ';
-	}
-	sout | "empty" | nl;
-	
-	for ( i; 10 ) {
-		add( fred, *new( 2 * i ) );
-	}
-
-	sout | head( fred ).i | tail( fred ).i | nl;
-
-	for ( QueueIter(Fred) iter = { fred }; iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( i; 9 ) {
-		delete( &drop( fred ) );
-	}
-
-	for ( over( iter, fred ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 10 ) {
-		add( fred, *new( 2 * i + 1 ) );
-	}
-
-	Fred * head = new( -1 ), tail = { -2 };
-	addHead( fred, *head );
-	addTail( fred, tail );
-
-	sout | head( fred ).i | succ( fred, head )->i | tail( fred ).i | nl;
-
-	for ( over( iter, fred ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	remove( fred, *head );
-	remove( fred, tail );
-	delete( head );
-	delete( &dropTail( fred ) );
-
-	for ( over( iter, fred ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( i; 5 ) {
-		delete( &dropTail( fred ) );
-	}
-	for ( over( iter, fred ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( over( iter, fred ); iter | f; ) {
-		delete( &remove( fred, f ) );
-	}
-	for ( over( iter, fred ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | "empty" | nl;
-
-	Fred & middle;
-	for ( i; 10 ) {
-		add( fred, *new( i ) );
-		if ( i == 4 ) {
-			&middle = &tail( fred );
-		}
-	}
-	for ( QueueIter(Fred) iter = { fred }; iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	Queue(Fred) fred2;
-
-	split( fred2, fred, middle );
-
-	for ( over( iter, fred ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( over( iter, fred2 ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	transfer( fred, fred2 );
-
-	for ( over( iter, fred ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( over( iter, fred ); iter | f; ) {
-		delete( &f );
-	}
-
-	// Mary test
-
-	struct Mary {
-		inline Fred;									// Plan 9 inheritance
-		int j;
-	};
-	void ?{}( Mary & mary ) { abort(); }
-	void ?{}( Mary & mary, int p ) with( mary ) {
-		((Fred &)mary){ p };
-		j = p;
-	}
-	Mary *& Next( Mary * n ) {
-		return (Mary *)Next( (Fred *)n );
-	}
-
-	Queue(Mary) mary;
-	QueueIter(Mary) iter = { mary };
-	Mary & m;
-
-	for ( ; iter | m; ) {							// empty list
-		sout | m.i | m.j | ' ';
-	}
-	sout | "empty" | nl;
-	
-	for ( i; 10 ) {
-		add( mary, *new( 2 * i ) );
-	}
-
-	sout | head( mary ).i | tail( mary ).i | nl;
-
-	for ( QueueIter(Mary) iter = { mary }; iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 9 ) {
-		delete( &drop( mary ) );
-	}
-
-	for ( over( iter, mary ); iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 10 ) {
-		add( mary, *new( 2 * i + 1 ) );
-	}
-
-	Mary * head = new( -1 ), tail = { -2 };
-	addHead( mary, *head );
-	addTail( mary, tail );
-
-	sout | head( mary ).i | succ( mary, head )->i | tail( mary ).i | nl;
-
-	for ( over( iter, mary ); iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	remove( mary, *head );
-	remove( mary, tail );
-	delete( (Mary *)head );
-	delete( &dropTail( mary ) );
-
-	for ( over( iter, mary ); iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	for ( i; 5 ) {
-		delete( &dropTail( mary ) );
-	}
-	for ( over( iter, mary ); iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	for ( over( iter, mary ); iter | m; ) {
-		delete( &remove( mary, m ) );
-	}
-	for ( over( iter, mary ); iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | "empty" | nl;
-
-	Mary & middle;
-	for ( i; 10 ) {
-		add( mary, *new( i ) );
-		if ( i == 4 ) {
-			&middle = &tail( mary );
-		}
-	}
-	for ( QueueIter(Mary) iter = { mary }; iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	Queue(Mary) mary2;
-
-	split( mary2, mary, middle );
-
-	for ( over( iter, mary ); iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-	for ( over( iter, mary2 ); iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	transfer( mary, mary2 );
-
-	for ( over( iter, mary ); iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	for ( over( iter, mary ); iter | m; ) {
-		delete( &m );
-	}
-}
Index: sts/collections/sequence.cfa
===================================================================
--- tests/collections/sequence.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,275 +1,0 @@
-#include <fstream.hfa>
-#include <stdlib.hfa>									// new, delete
-#include <bits/sequence.hfa>
-
-int main() {
-	// Fred test
-
-	struct Fred {
-		inline Seqable;									// Plan 9 inheritance
-		int i;
-	};
-	void ?{}( Fred & fred ) { abort(); }
-	void ?{}( Fred & fred, int p ) with( fred ) {
-		i = p;
-	}
-	Fred *& Back( Fred * n ) {
-		return (Fred *)Back( (Seqable *)n );
-	}
-	Fred *& Next( Fred * n ) {
-		return (Fred *)Next( (Colable *)n );
-	}
-
-	Sequence(Fred) fred;
-	SeqIter(Fred) iter = { fred };
-	Fred & f;
-
-	sout | nlOff;										// turn off auto newline
-
-	for ( ; iter | f; ) {							// empty list
-		sout | f.i | ' ';
-	}
-	sout | "empty" | nl;
-	
-	for ( i; 10 ) {
-		add( fred, *new( 2 * i ) );
-	}
-
-	sout | head( fred ).i | tail( fred ).i | nl;
-
-	for ( SeqIter(Fred) iter = { fred }; iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( i; 9 ) {
-		delete( &dropHead( fred ) );
-	}
-
-	for ( over( iter, fred ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 10 ) {
-		addTail( fred, *new( 2 * i + 1 ) );
-	}
-
-	Fred * head = new( -1 ), tail = { -2 };
-	addHead( fred, *head );
-	addTail( fred, tail );
-
-	sout | head( fred ).i | succ( fred, head )->i | tail( fred ).i | nl;
-
-	for ( over( iter, fred ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	remove( fred, *head );
-	remove( fred, tail );
-	delete( head );
-	delete( &dropTail( fred ) );
-
-	for ( over( iter, fred ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( i; 5 ) {
-		delete( &dropTail( fred ) );
-	}
-	for ( over( iter, fred ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( over( iter, fred ); iter | f; ) {
-		delete( &remove( fred, f ) );
-	}
-	for ( over( iter, fred ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | "empty" | nl;
-
-	Fred & middle;
-	for ( i; 10 ) {
-		addHead( fred, *new( i ) );						// reverse order
-		if ( i == 5 ) {
-			&middle = &head( fred );
-		}
-	}
-	for ( SeqIterRev(Fred) riter = { fred }; riter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	head = new( -1 );
-	insertBef( fred, *head, head( fred ) );
-	insertAft( fred, *head, tail );
-
-	sout | head( fred ).i | succ( fred, head )->i | tail( fred ).i | nl;
-	for ( over( iter, fred ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	remove( fred, *head );
-	remove( fred, tail );
-	delete( head );
-	delete( &dropTail( fred ) );
-
-	for ( over( iter, fred ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	Sequence(Fred) fred2;
-
-	split( fred2, fred, middle );
-
-	for ( over( iter, fred ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( over( iter, fred2 ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	transfer( fred, fred2 );
-
-	for ( over( iter, fred ); iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( over( iter, fred ); iter | f; ) {
-		delete( &f );
-	}
-
-	// Mary test
-
-	struct Mary {
-		inline Fred;									// Plan 9 inheritance
-		int j;
-	};
-	void ?{}( Mary & mary ) { abort(); }
-	void ?{}( Mary & mary, int p ) with( mary ) {
-		((Fred &)mary){ p };
-		j = p;
-	}
-	Mary *& Back( Mary * n ) {
-		return (Mary *)Back( (Fred *)n );
-	}
-	Mary *& Next( Mary * n ) {
-		return (Mary *)Next( (Fred *)n );
-	}
-
-	Sequence(Mary) mary;
-	SeqIter(Mary) iter = { mary };
-	Mary & m;
-
-	for ( ; iter | m; ) {							// empty list
-		sout | m.i | m.j | ' ';
-	}
-	sout | "empty" | nl;
-	
-	for ( i; 10 ) {
-		add( mary, *new( 2 * i ) );
-	}
-
-	sout | head( mary ).i | tail( mary ).i | nl;
-
-	for ( SeqIter(Mary) iter = { mary }; iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 9 ) {
-		delete( &dropHead( mary ) );
-	}
-
-	for ( over( iter, mary ); iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 10 ) {
-		addTail( mary, *new( 2 * i + 1 ) );
-	}
-
-	Mary * head = new( -1 ), tail = { -2 };
-	addHead( mary, *head );
-	addTail( mary, tail );
-
-	sout | head( mary ).i | succ( mary, head )->i | tail( mary ).i | nl;
-
-	for ( over( iter, mary ); iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	remove( mary, *head );
-	remove( mary, tail );
-	delete( (Mary *)head );
-	delete( &dropTail( mary ) );
-
-	for ( over( iter, mary ); iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	for ( i; 5 ) {
-		delete( &dropTail( mary ) );
-	}
-	for ( over( iter, mary ); iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	for ( over( iter, mary ); iter | m; ) {
-		delete( &remove( mary, m ) );
-	}
-	for ( over( iter, mary ); iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | "empty" | nl;
-
-	Mary & middle;
-	for ( i; 10 ) {
-		add( mary, *new( i ) );
-		if ( i == 4 ) {
-			&middle = &tail( mary );
-		}
-	}
-	for ( SeqIter(Mary) iter = { mary }; iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	Sequence(Mary) mary2;
-
-	split( mary2, mary, middle );
-
-	for ( over( iter, mary ); iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-	for ( over( iter, mary2 ); iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	transfer( mary, mary2 );
-
-	for ( over( iter, mary ); iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	for ( over( iter, mary ); iter | m; ) {
-		delete( &m );
-	}
-}
Index: sts/collections/stack.cfa
===================================================================
--- tests/collections/stack.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,117 +1,0 @@
-#include <fstream.hfa>
-#include <stdlib.hfa>									// new, delete
-#include <bits/stack.hfa>
-
-int main() {
-	// Fred test
-
-	struct Fred {
-		inline Colable;									// Plan 9 inheritance
-		int i;
-	};
-	void ?{}( Fred & fred ) { abort(); }
-	void ?{}( Fred & fred, int p ) with( fred ) {
-		i = p;
-	}
-	Fred *& Next( Fred * n ) {
-		return (Fred *)Next( (Colable *)n );
-	}
-
-	Stack(Fred) fred;
-	StackIter(Fred) inter = { fred };
-	Fred & f;
-
-	sout | nlOff;										// turn off auto newline
-
-	for ( ; inter | f; ) {							// empty list
-		sout | f.i | ' ';
-	}
-	sout | "empty" | nl;
-	
-	for ( i; 10 ) {
-		push( fred, *new( 2 * i ) );
-	}
-
-	for ( StackIter(Fred) iter = { fred }; iter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	sout | head( fred ).i | nl;
-	
-	for ( i; 9 ) {
-		delete( &pop( fred ) );
-	}
-
-	for ( over( inter, fred ); inter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 10 ) {
-		push( fred, *new( 2 * i + 1 ) );
-	}
-	for ( over( inter, fred ); inter | f; ) {
-		sout | f.i | ' ';
-	}
-	sout | nl;
-
-	for ( over( inter, fred ); inter | f; ) {
-		delete( &f );
-	}
-
-	// Mary test
-
-	struct Mary {
-		inline Fred;									// Plan 9 inheritance
-		int j;
-	};
-	void ?{}( Mary & mary ) { abort(); }
-	void ?{}( Mary & mary, int p ) with( mary ) {
-		((Fred &)mary){ p };
-		j = p;
-	}
-
-	Mary *& Next( Mary * n ) {
-		return (Mary *)Next( (Fred *)n );
-	}
-
-	Stack(Mary) mary;
-	StackIter(Mary) maryIter = { mary };
-	Mary & m;
-
-	for ( ; maryIter | m; ) {							// empty list
-		sout | m.i | m.j | ' ';
-	}
-	sout | "empty" | nl;
-	
-	for ( i; 10 ) {
-		push( mary, *new( 2 * i ) );
-	}
-
-	for ( StackIter(Mary) iter = { mary }; iter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 9 ) {
-		delete( &pop( mary ) );
-	}
-
-	for ( over( maryIter, mary ); maryIter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-	
-	for ( i; 10 ) {
-		push( mary, *new( 2 * i + 1 ) );
-	}
-	for ( over( maryIter, mary ); maryIter | m; ) {
-		sout | m.i | m.j | ' ';
-	}
-	sout | nl;
-
-	for ( over( maryIter, mary ); maryIter | m; ) {
-		delete( &m );
-	}
-}
Index: sts/concurrent/futures/.expect/abandon.txt
===================================================================
--- tests/concurrent/futures/.expect/abandon.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,2 +1,0 @@
-start
-done
Index: tests/concurrent/futures/.expect/basic.txt
===================================================================
--- tests/concurrent/futures/.expect/basic.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ tests/concurrent/futures/.expect/basic.txt	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -1,2 +1,1 @@
-start
 done
Index: sts/concurrent/futures/.expect/multi.txt
===================================================================
--- tests/concurrent/futures/.expect/multi.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,2 +1,0 @@
-start
-done
Index: sts/concurrent/futures/.expect/typed.txt
===================================================================
--- tests/concurrent/futures/.expect/typed.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,2 +1,0 @@
-start
-done
Index: sts/concurrent/futures/abandon.cfa
===================================================================
--- tests/concurrent/futures/abandon.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,102 +1,0 @@
-#include <thread.hfa>
-
-enum {NFUTURES = 10};
-
-thread Server {
-	int cnt;
-	future_t * requests[NFUTURES];
-};
-
-void ?{}( Server & this ) {
-	this.cnt = 0;
-	for(i; NFUTURES) {
-		this.requests[i] = 0p;
-	}
-}
-
-void ^?{}( Server & mutex this ) {
-	assert(this.cnt == 0);
-	for(i; NFUTURES) {
-		this.requests[i] = 0p;
-	}
-}
-
-void process( Server & this, int i ) {
-	if( this.requests[i] == 0p ) return;
-	future_t * f = this.requests[i];
-	this.requests[i] = 0p;
-	this.cnt--;
-	fulfil( *f );
-}
-
-void call( Server & mutex this, future_t & f ) {
-	for(i; NFUTURES) {
-		if( this.requests[i] == 0p ) {
-			this.requests[i] = &f;
-			this.cnt++;
-			return;
-		}
-	}
-	abort("Monitor Error");
-}
-
-void main( Server & this ) {
-	unsigned i = 0;
-	for() {
-		waitfor( ^?{} : this ) {
-			break;
-		}
-		or when( this.cnt < NFUTURES ) waitfor( call: this ) {}
-		or else {
-			process( this, i % NFUTURES );
-			i++;
-		}
-	}
-
-	for(i; NFUTURES) {
-		process( this, i );
-	}
-}
-
-Server * the_server;
-thread Worker {};
-
-void thrash(void) {
-	volatile int locals[250];
-	for(i; 250) {
-		locals[i] = 0xdeadbeef;
-	}
-}
-
-void work(int i) {
-	future_t *mine = new();
-	call( *the_server, *mine );
-	if (i % 2 == 0) {
-		abandon( *mine );
-	} else {
-		wait( *mine );
-		delete( mine );
-	}
-}
-
-void main( Worker & ) {
-	for(i;150) {
-		thrash();
-		work(i);
-		thrash();
-	}
-}
-
-int main() {
-	printf( "start\n" );				// non-empty .expect file
-	processor procs[2];
-	{
-		Server server;
-		the_server = &server;
-		{
-			Worker workers[17];
-		}
-	}
-	printf( "done\n" );				// non-empty .expect file
-
-}
Index: tests/concurrent/futures/basic.cfa
===================================================================
--- tests/concurrent/futures/basic.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ tests/concurrent/futures/basic.cfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -1,4 +1,3 @@
 #include <thread.hfa>
-
 enum {NFUTURES = 10};
 
@@ -84,5 +83,4 @@
 
 int main() {
-	printf( "start\n" );				// non-empty .expect file
 	processor procs[2];
 	{
Index: sts/concurrent/futures/multi.cfa
===================================================================
--- tests/concurrent/futures/multi.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,97 +1,0 @@
-#include <thread.hfa>
-#include <future.hfa>
-
-enum {NFUTURES = 10};
-
-thread Server {
-	int cnt, iteration;
-	multi_future(int) * request;
-};
-
-void ?{}( Server & this ) {
-	this.cnt = 0;
-	this.iteration = 0;
-	this.request = 0p;
-}
-
-void ^?{}( Server & mutex this ) {
-	assert(this.cnt == 0);
-    this.request = 0p;
-}
-
-void init( Server & this , multi_future(int) * f ) {
-	this.request = f;
-}
-
-void process( Server & mutex this ) {
-	fulfil( *this.request, this.iteration );
-	this.iteration++;
-}
-
-void call( Server & mutex this ) {
-	this.cnt++;
-}
-
-void finish( Server & mutex this ) { }
-
-void main( Server & this ) {
-	for() {
-		waitfor( ^?{} : this ) {
-			break;
-		}
-		or when( this.cnt < NFUTURES ) waitfor( call: this ) {
-			if (this.cnt == NFUTURES) {
-				process(this);
-			}
-		}
-		or waitfor( finish: this ) {
-			if (this.cnt == NFUTURES) {
-				reset( *this.request );
-				this.cnt = 0;
-			}
-		}
-	}
-
-}
-
-Server * the_server;
-thread Worker {};
-multi_future(int) * shared_future;
-
-void thrash(void) {
-	volatile int locals[250];
-	for(i; 250) {
-		locals[i] = 0xdeadbeef;
-	}
-}
-
-void work(int num) {
-	call( *the_server );
-	int res = wait( *shared_future );
-	if( res != num ) abort();
-	finish( *the_server );
-}
-
-void main( Worker & ) {
-	for (i; 10) {
-		thrash();
-		work(i);
-		thrash();
-	}
-}
-
-int main() {
-	printf( "start\n" );				// non-empty .expect file
-	processor procs[2];
-	shared_future = new();
-	{
-		Server server;
-		the_server = &server;
-		init(server, shared_future);
-		{
-			Worker workers[NFUTURES];
-		}
-	}
-	delete( shared_future );
-	printf( "done\n" );				// non-empty .expect file
-}
Index: sts/concurrent/futures/typed.cfa
===================================================================
--- tests/concurrent/futures/typed.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,97 +1,0 @@
-#include <thread.hfa>
-#include <future.hfa>
-enum {NFUTURES = 10};
-
-thread Server {
-	int cnt;
-	future(int) * requests[NFUTURES];
-};
-
-void ?{}( Server & this ) {
-	this.cnt = 0;
-	for(i; NFUTURES) {
-		this.requests[i] = 0p;
-	}
-}
-
-void ^?{}( Server & mutex this ) {
-	assert(this.cnt == 0);
-	for(i; NFUTURES) {
-		this.requests[i] = 0p;
-	}
-}
-
-void process( Server & this, int i ) {
-	if( this.requests[i] == 0p ) return;
-	future(int) * f = this.requests[i];
-	this.requests[i] = 0p;
-	this.cnt--;
-	fulfil( *f , i);
-}
-
-void call( Server & mutex this, future(int) & f ) {
-	for(i; NFUTURES) {
-		if( this.requests[i] == 0p ) {
-			this.requests[i] = &f;
-			this.cnt++;
-			return;
-		}
-	}
-	abort("Monitor Error");
-}
-
-void main( Server & this ) {
-	unsigned i = 0;
-	for() {
-		waitfor( ^?{} : this ) {
-			break;
-		}
-		or when( this.cnt < NFUTURES ) waitfor( call: this ) {}
-		or else {
-			process( this, i % NFUTURES );
-			i++;
-		}
-	}
-
-	for(i; NFUTURES) {
-		process( this, i );
-	}
-}
-
-Server * the_server;
-thread Worker {};
-
-void thrash(void) {
-	volatile int locals[250];
-	for(i; 250) {
-		locals[i] = 0xdeadbeef;
-	}
-}
-
-void work(void) {
-	future(int) mine;
-	call( *the_server, mine );
-	wait( mine );
-}
-
-void main( Worker & ) {
-	for(150) {
-		thrash();
-		work();
-		thrash();
-	}
-}
-
-int main() {
-	printf( "start\n" );				// non-empty .expect file
-	processor procs[2];
-	{
-		Server server;
-		the_server = &server;
-		{
-			Worker workers[17];
-		}
-	}
-	printf( "done\n" );				// non-empty .expect file
-
-}
Index: tests/errors/.expect/completeType.nast.x64.txt
===================================================================
--- tests/errors/.expect/completeType.nast.x64.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ tests/errors/.expect/completeType.nast.x64.txt	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -12,5 +12,5 @@
       Application of
         Variable Expression: *?: forall
-          instance of type DT (not function type)
+          DT: data type
           function
         ... with parameters
@@ -21,5 +21,5 @@
         ... with resolved type:
           pointer to forall
-            instance of type [unbound] (not function type)
+            [unbound]:data type
             function
           ... with parameters
@@ -41,5 +41,5 @@
     void
   )
-  Environment:([unbound]DT) -> instance of struct A without body (no widening)
+  Environment:([unbound]) -> instance of struct A without body (no widening)
 
 
@@ -47,5 +47,5 @@
       Application of
         Variable Expression: *?: forall
-          instance of type DT (not function type)
+          DT: data type
           function
         ... with parameters
@@ -56,5 +56,5 @@
         ... with resolved type:
           pointer to forall
-            instance of type [unbound] (not function type)
+            [unbound]:data type
             function
           ... with parameters
@@ -76,5 +76,5 @@
     void
   )
-  Environment:([unbound]DT) -> instance of struct B with body (no widening)
+  Environment:([unbound]) -> instance of struct B with body (no widening)
 
 
@@ -113,15 +113,7 @@
 Cost ( 0, 1, 0, 0, 1, -5, 0 ): Application of
             Variable Expression: baz: forall
-              instance of type T (not function type)
-              with assertions
-              Variable Expression: ?=?: pointer to function
-              ... with parameters
-                reference to instance of type T (not function type)
-                instance of type T (not function type)
-              ... returning
-                instance of type T (not function type)
-
-              ... with resolved type:
-                pointer to function
+              T: sized data type
+              ... with assertions
+                ?=?: pointer to function
                 ... with parameters
                   reference to instance of type T (not function type)
@@ -130,23 +122,10 @@
                   instance of type T (not function type)
 
-              Variable Expression: ?{}: pointer to function
-              ... with parameters
-                reference to instance of type T (not function type)
-              ... returning nothing
-
-              ... with resolved type:
-                pointer to function
+                ?{}: pointer to function
                 ... with parameters
                   reference to instance of type T (not function type)
                 ... returning nothing
 
-              Variable Expression: ?{}: pointer to function
-              ... with parameters
-                reference to instance of type T (not function type)
-                instance of type T (not function type)
-              ... returning nothing
-
-              ... with resolved type:
-                pointer to function
+                ?{}: pointer to function
                 ... with parameters
                   reference to instance of type T (not function type)
@@ -154,14 +133,9 @@
                 ... returning nothing
 
-              Variable Expression: ^?{}: pointer to function
-              ... with parameters
-                reference to instance of type T (not function type)
-              ... returning nothing
-
-              ... with resolved type:
-                pointer to function
+                ^?{}: pointer to function
                 ... with parameters
                   reference to instance of type T (not function type)
                 ... returning nothing
+
 
               function
@@ -172,15 +146,7 @@
             ... with resolved type:
               pointer to forall
-                instance of type [unbound] (not function type)
-                with assertions
-                Variable Expression: ?=?: pointer to function
-                ... with parameters
-                  reference to instance of type T (not function type)
-                  instance of type T (not function type)
-                ... returning
-                  instance of type T (not function type)
-
-                ... with resolved type:
-                  pointer to function
+                [unbound]:sized data type
+                ... with assertions
+                  ?=?: pointer to function
                   ... with parameters
                     reference to instance of type [unbound] (not function type)
@@ -189,23 +155,10 @@
                     instance of type [unbound] (not function type)
 
-                Variable Expression: ?{}: pointer to function
-                ... with parameters
-                  reference to instance of type T (not function type)
-                ... returning nothing
-
-                ... with resolved type:
-                  pointer to function
+                  ?{}: pointer to function
                   ... with parameters
                     reference to instance of type [unbound] (not function type)
                   ... returning nothing
 
-                Variable Expression: ?{}: pointer to function
-                ... with parameters
-                  reference to instance of type T (not function type)
-                  instance of type T (not function type)
-                ... returning nothing
-
-                ... with resolved type:
-                  pointer to function
+                  ?{}: pointer to function
                   ... with parameters
                     reference to instance of type [unbound] (not function type)
@@ -213,14 +166,9 @@
                   ... returning nothing
 
-                Variable Expression: ^?{}: pointer to function
-                ... with parameters
-                  reference to instance of type T (not function type)
-                ... returning nothing
-
-                ... with resolved type:
-                  pointer to function
+                  ^?{}: pointer to function
                   ... with parameters
                     reference to instance of type [unbound] (not function type)
                   ... returning nothing
+
 
                 function
@@ -240,20 +188,12 @@
           void
         )
-        Environment:([unbound]T) -> instance of type T (not function type) (no widening)
+        Environment:([unbound]) -> instance of type T (not function type) (no widening)
 
       Could not satisfy assertion:
-Variable Expression: ?=?: pointer to function
+?=?: pointer to function
         ... with parameters
-          reference to instance of type T (not function type)
-          instance of type T (not function type)
+          reference to instance of type [unbound] (not function type)
+          instance of type [unbound] (not function type)
         ... returning
-          instance of type T (not function type)
+          instance of type [unbound] (not function type)
 
-        ... with resolved type:
-          pointer to function
-          ... with parameters
-            reference to instance of type [unbound] (not function type)
-            instance of type [unbound] (not function type)
-          ... returning
-            instance of type [unbound] (not function type)
-
Index: tests/errors/.expect/completeType.nast.x86.txt
===================================================================
--- tests/errors/.expect/completeType.nast.x86.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ tests/errors/.expect/completeType.nast.x86.txt	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -12,5 +12,5 @@
       Application of
         Variable Expression: *?: forall
-          instance of type DT (not function type)
+          DT: data type
           function
         ... with parameters
@@ -21,5 +21,5 @@
         ... with resolved type:
           pointer to forall
-            instance of type [unbound] (not function type)
+            [unbound]:data type
             function
           ... with parameters
@@ -41,5 +41,5 @@
     void
   )
-  Environment:([unbound]DT) -> instance of struct A without body (no widening)
+  Environment:([unbound]) -> instance of struct A without body (no widening)
 
 
@@ -47,5 +47,5 @@
       Application of
         Variable Expression: *?: forall
-          instance of type DT (not function type)
+          DT: data type
           function
         ... with parameters
@@ -56,5 +56,5 @@
         ... with resolved type:
           pointer to forall
-            instance of type [unbound] (not function type)
+            [unbound]:data type
             function
           ... with parameters
@@ -76,5 +76,5 @@
     void
   )
-  Environment:([unbound]DT) -> instance of struct B with body (no widening)
+  Environment:([unbound]) -> instance of struct B with body (no widening)
 
 
@@ -113,15 +113,7 @@
 Cost ( 0, 1, 0, 0, 1, -5, 0 ): Application of
             Variable Expression: baz: forall
-              instance of type T (not function type)
-              with assertions
-              Variable Expression: ?=?: pointer to function
-              ... with parameters
-                reference to instance of type T (not function type)
-                instance of type T (not function type)
-              ... returning
-                instance of type T (not function type)
-
-              ... with resolved type:
-                pointer to function
+              T: sized data type
+              ... with assertions
+                ?=?: pointer to function
                 ... with parameters
                   reference to instance of type T (not function type)
@@ -130,23 +122,10 @@
                   instance of type T (not function type)
 
-              Variable Expression: ?{}: pointer to function
-              ... with parameters
-                reference to instance of type T (not function type)
-              ... returning nothing
-
-              ... with resolved type:
-                pointer to function
+                ?{}: pointer to function
                 ... with parameters
                   reference to instance of type T (not function type)
                 ... returning nothing
 
-              Variable Expression: ?{}: pointer to function
-              ... with parameters
-                reference to instance of type T (not function type)
-                instance of type T (not function type)
-              ... returning nothing
-
-              ... with resolved type:
-                pointer to function
+                ?{}: pointer to function
                 ... with parameters
                   reference to instance of type T (not function type)
@@ -154,14 +133,9 @@
                 ... returning nothing
 
-              Variable Expression: ^?{}: pointer to function
-              ... with parameters
-                reference to instance of type T (not function type)
-              ... returning nothing
-
-              ... with resolved type:
-                pointer to function
+                ^?{}: pointer to function
                 ... with parameters
                   reference to instance of type T (not function type)
                 ... returning nothing
+
 
               function
@@ -172,15 +146,7 @@
             ... with resolved type:
               pointer to forall
-                instance of type [unbound] (not function type)
-                with assertions
-                Variable Expression: ?=?: pointer to function
-                ... with parameters
-                  reference to instance of type T (not function type)
-                  instance of type T (not function type)
-                ... returning
-                  instance of type T (not function type)
-
-                ... with resolved type:
-                  pointer to function
+                [unbound]:sized data type
+                ... with assertions
+                  ?=?: pointer to function
                   ... with parameters
                     reference to instance of type [unbound] (not function type)
@@ -189,23 +155,10 @@
                     instance of type [unbound] (not function type)
 
-                Variable Expression: ?{}: pointer to function
-                ... with parameters
-                  reference to instance of type T (not function type)
-                ... returning nothing
-
-                ... with resolved type:
-                  pointer to function
+                  ?{}: pointer to function
                   ... with parameters
                     reference to instance of type [unbound] (not function type)
                   ... returning nothing
 
-                Variable Expression: ?{}: pointer to function
-                ... with parameters
-                  reference to instance of type T (not function type)
-                  instance of type T (not function type)
-                ... returning nothing
-
-                ... with resolved type:
-                  pointer to function
+                  ?{}: pointer to function
                   ... with parameters
                     reference to instance of type [unbound] (not function type)
@@ -213,14 +166,9 @@
                   ... returning nothing
 
-                Variable Expression: ^?{}: pointer to function
-                ... with parameters
-                  reference to instance of type T (not function type)
-                ... returning nothing
-
-                ... with resolved type:
-                  pointer to function
+                  ^?{}: pointer to function
                   ... with parameters
                     reference to instance of type [unbound] (not function type)
                   ... returning nothing
+
 
                 function
@@ -240,20 +188,12 @@
           void
         )
-        Environment:([unbound]T) -> instance of type T (not function type) (no widening)
+        Environment:([unbound]) -> instance of type T (not function type) (no widening)
 
       Could not satisfy assertion:
-Variable Expression: ?=?: pointer to function
+?=?: pointer to function
         ... with parameters
-          reference to instance of type T (not function type)
-          instance of type T (not function type)
+          reference to instance of type [unbound] (not function type)
+          instance of type [unbound] (not function type)
         ... returning
-          instance of type T (not function type)
+          instance of type [unbound] (not function type)
 
-        ... with resolved type:
-          pointer to function
-          ... with parameters
-            reference to instance of type [unbound] (not function type)
-            instance of type [unbound] (not function type)
-          ... returning
-            instance of type [unbound] (not function type)
-
Index: tests/multi_list.cfa
===================================================================
--- tests/multi_list.cfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
+++ tests/multi_list.cfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -0,0 +1,101 @@
+#include <fstream.hfa>
+#include <stdlib.hfa>
+#include <bits/stack.hfa>
+#include <bits/queue.hfa>
+#include <bits/sequence.hfa>
+
+struct Task;											// node type
+
+struct TaskDL {
+	inline Seqable;
+	Task & node;
+};
+void ?{}( TaskDL & this, Task & task ) with( this ) {
+	((Seqable &)this){};
+	&node = &task;										// pointer to containing node
+}
+Task & task( TaskDL & this ) with( this ) {				// getter routine for containing node
+	return node;
+}
+
+struct TaskSL {
+	inline Colable;
+	Task & node;
+};
+void ?{}( TaskSL & this, Task & task ) with( this ) {
+	((Colable &)this){};
+	&node = &task;										// pointer to containing node
+}
+Task & task( TaskSL & this ) with( this ) {				// getter routine for containing node
+	return node;
+}
+
+struct Task {
+	TaskDL clusterRef;									// list of tasks on cluster
+	TaskDL readyRef;									// list of tasks on ready queue
+	TaskSL mutexRef;									// list of tasks on mutex queue
+	int id;
+};
+void ?{}( Task & this, int id ) with( this ) {
+	((TaskDL &)clusterRef){ this };
+	((TaskDL &)readyRef){ this };
+	((TaskSL &)mutexRef){ this };
+	this.id = id;
+}
+
+int main() {
+	Sequence(TaskDL) clustList, readyList;				// task lists
+	Queue(TaskSL) mutexList;
+	enum { Lnth = 10 };
+
+	for ( id; Lnth ) {
+		Task & task = *new( id );						// create task node
+		addHead( clustList, task.clusterRef );			// insert on lists in opposite directions
+		addTail( readyList, task.readyRef );
+		addHead( mutexList, task.mutexRef );
+	}
+
+	SeqIter(TaskDL) sqiter;
+	TaskDL & dl;										// iterator index
+	TaskSL & sl;
+
+	sout | nlOff;
+	for ( over( sqiter, clustList ); sqiter >> dl; ) {	// print lists
+		Task & tmp = task( dl ); sout | tmp.id;
+		// sout | task( dl ).id;
+	}
+	sout | nl;
+	for ( over( sqiter, readyList ); sqiter >> dl; ) {
+		Task & tmp = task( dl ); sout | tmp.id;
+		// sout | task( dl ).id;
+	}
+	sout | nl;
+	for ( QueueIter(TaskSL) qiter = { mutexList }; qiter >> sl; ) {	// print lists
+		Task & tmp = task( sl ); sout | tmp.id;
+		// sout | task( sl ).id;
+	}
+	sout | nl;
+	for ( Lnth ) {										// remove nodes from clustList. mutexList
+		dropHead( clustList );
+		drop( mutexList );
+	}
+	// Simultaneous deletion only safe if all nodes are traversed in same direction.
+	for ( Lnth ) {										// remove nodes from readyList and safe to delete nodes
+		delete( &task( dropHead( readyList ) ) );
+	}
+
+	// Re-purpose Seqable as Colable
+	Stack(TaskDL) mutexStack;
+	for ( id; Lnth ) {
+		Task & task = *new( id );						// create task node
+		push( mutexStack, task.clusterRef );			// insert on lists in opposite directions
+	}
+	for ( StackIter(TaskDL) stiter = { mutexStack }; stiter >> dl; ) {
+		Task & tmp = task( dl ); sout | tmp.id;
+		// sout | task( dl ).id;
+	}
+	sout | nl;
+	for ( Lnth ) {										// remove nodes from readyList and safe to delete nodes
+		delete( &task( pop( mutexStack ) ) );
+	}
+}
Index: tests/queue.cfa
===================================================================
--- tests/queue.cfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
+++ tests/queue.cfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -0,0 +1,108 @@
+#include <fstream.hfa>
+#include <stdlib.hfa>									// new, delete
+#include <bits/queue.hfa>
+
+int main() {
+	// Fred test
+
+	struct Fred {
+		inline Colable;									// Plan 9 inheritance
+		int i;
+	};
+	void ?{}( Fred & fred ) { abort(); }
+	void ?{}( Fred & fred, int p ) with( fred ) {
+		i = p;
+	}
+
+	Queue(Fred) fred;
+	QueueIter(Fred) fredIter = { fred };
+	Fred & f;
+
+	sout | nlOff;										// turn off auto newline
+
+	for ( ; fredIter >> f; ) {							// empty list
+		sout | f.i | ' ';
+	}
+	sout | "empty" | nl;
+	
+	for ( i; 10 ) {
+		add( fred, *new( 2 * i ) );
+	}
+
+	for ( QueueIter(Fred) iter = { fred }; iter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+
+	for ( i; 9 ) {
+		delete( &drop( fred ) );
+	}
+
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 10 ) {
+		add( fred, *new( 2 * i + 1 ) );
+	}
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		delete( &f );
+	}
+
+	// Mary test
+
+	struct Mary {
+		inline Fred;									// Plan 9 inheritance
+		int j;
+	};
+	void ?{}( Mary & mary ) { abort(); }
+	void ?{}( Mary & mary, int p ) with( mary ) {
+		((Fred &)mary){ p };
+		j = i = p;
+	}
+
+	Queue(Mary) mary;
+	QueueIter(Mary) maryIter = { mary };
+	Mary & m;
+
+	for ( ; maryIter >> m; ) {							// empty list
+		sout | m.i | m.j | ' ';
+	}
+	sout | "empty" | nl;
+	
+	for ( i; 10 ) {
+		add( mary, *new( 2 * i ) );
+	}
+
+	for ( QueueIter(Mary) iter = { mary }; iter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 9 ) {
+		delete( &drop( mary ) );
+	}
+
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 10 ) {
+		add( mary, *new( 2 * i + 1 ) );
+	}
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		delete( &m );
+	}
+}
Index: tests/raii/.expect/ctor-autogen-ERR1.nast.txt
===================================================================
--- tests/raii/.expect/ctor-autogen-ERR1.nast.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ tests/raii/.expect/ctor-autogen-ERR1.nast.txt	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -70,4 +70,5 @@
             ... with environment:
               Types:
+              Non-types:
 
 
Index: tests/sequence.cfa
===================================================================
--- tests/sequence.cfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
+++ tests/sequence.cfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -0,0 +1,138 @@
+#include <fstream.hfa>
+#include <stdlib.hfa>									// new, delete
+#include <bits/sequence.hfa>
+
+int main() {
+	// Fred test
+
+	struct Fred {
+		inline Seqable;									// Plan 9 inheritance
+		int i;
+	};
+	void ?{}( Fred & fred ) { abort(); }
+	void ?{}( Fred & fred, int p ) with( fred ) {
+		i = p;
+	}
+
+	Sequence(Fred) fred;
+	SeqIter(Fred) fredIter = { fred };
+	Fred & f;
+
+	sout | nlOff;										// turn off auto newline
+
+	for ( ; fredIter >> f; ) {							// empty list
+		sout | f.i | ' ';
+	}
+	sout | "empty" | nl;
+	
+	for ( i; 10 ) {
+		add( fred, *new( 2 * i ) );
+	}
+
+	for ( SeqIter(Fred) iter = { fred }; iter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+
+	for ( i; 9 ) {
+		delete( &dropHead( fred ) );
+	}
+
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 10 ) {
+		addTail( fred, *new( 2 * i + 1 ) );
+	}
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+
+	for ( i; 9 ) {
+		delete( &dropTail( fred ) );
+	}
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		delete( &f );
+	}
+
+	// Mary test
+
+	struct Mary {
+		inline Fred;									// Plan 9 inheritance
+		int j;
+	};
+	void ?{}( Mary & mary ) { abort(); }
+	void ?{}( Mary & mary, int p ) with( mary ) {
+		((Fred &)mary){ p };
+		j = p;
+	}
+
+	Sequence(Mary) mary;
+	Sequence(Mary) baz;
+	SeqIter(Mary) maryIter = { mary };
+	Mary & m;
+
+	for ( ; maryIter >> m; ) {							// empty list
+		sout | m.i | m.j | ' ';
+	}
+	sout | "empty" | nl;
+	
+	for ( i; 10 ) {
+		add( mary, *new( 2 * i ) );
+		add( baz, *new( 2 * i ) );
+	}
+
+	for ( SeqIter(Mary) iter = { mary }; iter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 9 ) {
+		delete( &dropHead( mary ) );
+	}
+
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 10 ) {
+		addTail( mary, *new( 2 * i + 1 ) );
+	}
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+
+	for ( i; 9 ) {
+		delete( &dropTail( mary ) );
+	}
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+
+	transfer( mary, baz );
+
+	for ( over( maryIter, baz ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | "empty" | nl;
+
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		delete( &m );
+	}
+}
Index: tests/stack.cfa
===================================================================
--- tests/stack.cfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
+++ tests/stack.cfa	(revision 42f6e07e6f562d26e2a4c552e12cfcd2f2660dce)
@@ -0,0 +1,108 @@
+#include <fstream.hfa>
+#include <stdlib.hfa>									// new, delete
+#include <bits/stack.hfa>
+
+int main() {
+	// Fred test
+
+	struct Fred {
+		inline Colable;									// Plan 9 inheritance
+		int i;
+	};
+	void ?{}( Fred & fred ) { abort(); }
+	void ?{}( Fred & fred, int p ) with( fred ) {
+		i = p;
+	}
+
+	Stack(Fred) fred;
+	StackIter(Fred) fredIter = { fred };
+	Fred & f;
+
+	sout | nlOff;										// turn off auto newline
+
+	for ( ; fredIter >> f; ) {							// empty list
+		sout | f.i | ' ';
+	}
+	sout | "empty" | nl;
+	
+	for ( i; 10 ) {
+		push( fred, *new( 2 * i ) );
+	}
+
+	for ( StackIter(Fred) iter = { fred }; iter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 9 ) {
+		delete( &pop( fred ) );
+	}
+
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 10 ) {
+		push( fred, *new( 2 * i + 1 ) );
+	}
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		sout | f.i | ' ';
+	}
+	sout | nl;
+
+	for ( over( fredIter, fred ); fredIter >> f; ) {
+		delete( &f );
+	}
+
+	// Mary test
+
+	struct Mary {
+		inline Fred;									// Plan 9 inheritance
+		int j;
+	};
+	void ?{}( Mary & mary ) { abort(); }
+	void ?{}( Mary & mary, int p ) with( mary ) {
+		((Fred &)mary){ p };
+		j = i = p;
+	}
+
+	Stack(Mary) mary;
+	StackIter(Mary) maryIter = { mary };
+	Mary & m;
+
+	for ( ; maryIter >> m; ) {							// empty list
+		sout | m.i | m.j | ' ';
+	}
+	sout | "empty" | nl;
+	
+	for ( i; 10 ) {
+		push( mary, *new( 2 * i ) );
+	}
+
+	for ( StackIter(Mary) iter = { mary }; iter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 9 ) {
+		delete( &pop( mary ) );
+	}
+
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+	
+	for ( i; 10 ) {
+		push( mary, *new( 2 * i + 1 ) );
+	}
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		sout | m.i | m.j | ' ';
+	}
+	sout | nl;
+
+	for ( over( maryIter, mary ); maryIter >> m; ) {
+		delete( &m );
+	}
+}
Index: sts/unified_locking/.expect/locks.txt
===================================================================
--- tests/unified_locking/.expect/locks.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,20 +1,0 @@
-Start Test 1: multi acquisition lock and condition variable single wait/notify
-Done Test 1
-Start Test 2: multi acquisition lock and condition variable 3 wait/notify all
-Done Test 2
-Start Test 3: single acquisition lock and condition variable single wait/notify
-Done Test 3
-Start Test 4: single acquisition lock and condition variable 3 wait/notify all
-Done Test 4
-Start Test 5: owner lock and condition variable single wait/notify
-Done Test 5
-Start Test 6: owner lock and condition variable 3 wait/notify all
-Done Test 6
-Start Test 7: multi acquisiton lock and condition variable multiple acquire and wait/notify
-Done Test 7
-Start Test 8: owner lock and condition variable multiple acquire and wait/notify
-Done Test 8
-Start Test 9: no lock condition variable wait/notify
-Done Test 9
-Start Test 10: locked condition variable wait/notify with front()
-Done Test 10
Index: sts/unified_locking/locks.cfa
===================================================================
--- tests/unified_locking/locks.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,303 +1,0 @@
-#include <stdio.h>
-#include "locks.hfa"
-#include <stdlib.hfa>
-#include <thread.hfa>
-
-const unsigned int num_times = 50000;
-
-multiple_acquisition_lock m;
-condition_variable( multiple_acquisition_lock ) c_m;
-
-single_acquisition_lock s;
-condition_variable( single_acquisition_lock ) c_s;
-
-owner_lock o;
-condition_variable( owner_lock ) c_o;
-
-thread T_C_M_WS1 {};
-
-void main( T_C_M_WS1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(m);
-		if(empty(c_m) && i != num_times - 1) {
-			wait(c_m,m);
-		}else{
-			notify_one(c_m);
-		}
-		unlock(m);
-	}
-}
-
-thread T_C_M_WB1 {};
-
-void main( T_C_M_WB1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(m);
-		if(counter(c_m) == 3 || i == num_times - 1) {
-			notify_all(c_m);
-		}else{
-			wait(c_m,m);
-		}
-		unlock(m);
-	}
-}
-
-thread T_C_S_WS1 {};
-
-void main( T_C_S_WS1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(s);
-		if(empty(c_s) && i != num_times - 1) {
-			wait(c_s,s);
-		}else{
-			notify_one(c_s);
-		}
-		unlock(s);
-	}
-}
-
-thread T_C_S_WB1 {};
-
-void main( T_C_S_WB1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(s);
-		if(counter(c_s) == 3 || i == num_times - 1) {
-			notify_all(c_s);
-		}else{
-			wait(c_s,s);
-		}
-		unlock(s);
-	}
-}
-
-thread T_C_O_WS1 {};
-
-void main( T_C_O_WS1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(o);
-		if(empty(c_o) && i != num_times - 1) {
-			wait(c_o,o);
-		}else{
-			notify_one(c_o);
-		}
-		unlock(o);
-	}
-}
-
-thread T_C_O_WB1 {};
-
-void main( T_C_O_WB1 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(o);
-		if(counter(c_o) == 3 || i == num_times - 1) {
-			notify_all(c_o);
-		}else{
-			wait(c_o,o);
-		}
-		unlock(o);
-	}
-}
-
-thread T_C_M_WS2 {};
-
-void main( T_C_M_WS2 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(m);
-		lock(m);
-		lock(m);
-		if(empty(c_m) && i != num_times - 1) {
-			wait(c_m,m);
-		}else{
-			notify_one(c_m);
-		}
-		unlock(m);
-		unlock(m);
-		unlock(m);
-	}
-}
-
-thread T_C_O_WS2 {};
-
-void main( T_C_O_WS2 & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(o);
-		lock(o);
-		lock(o);
-		if(empty(c_o) && i != num_times - 1) {
-			wait(c_o,o);
-		}else{
-			notify_one(c_o);
-		}
-		unlock(o);
-		unlock(o);
-		unlock(o);
-	}
-}
-
-thread T_C_NLW {};
-
-void main( T_C_NLW & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		wait(c_o);
-	}
-}
-
-thread T_C_NLS {};
-
-void main( T_C_NLS & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		while (empty(c_o)) { }
-		notify_one(c_o);
-	}
-}
-
-thread T_C_S_WNF {};
-
-void main( T_C_S_WNF & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		lock(s);
-		if(empty(c_s) && i != num_times - 1) {
-			wait(c_s, s, 10);
-		}else{
-			if(!empty(c_s)) assert(front(c_s) == 10);
-			notify_one(c_s);
-		}
-		unlock(s);
-	}
-}
-
-bool done = false;
-
-thread T_C_NLWD {};
-
-void main( T_C_NLWD & this ) {
-	done = false;
-	for (unsigned int i = 0; i < num_times/5; i++) {
-		if (i % 1000 == 0) printf("Iteration: %d\n", i);
-		wait(c_s, 1`ns);
-	}
-	done = true;
-}
-
-thread T_C_WDS {};
-
-void main( T_C_WDS & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		while (empty(c_s) && !done) { }
-		notify_one(c_s);
-		sleep(1`ns);
-		if(done) break;
-	}
-}
-
-thread T_C_LWD {};
-
-void main( T_C_LWD & this ) {
-	done = false;
-	for (unsigned int i = 0; i < num_times/5; i++) {
-		if (i % 1000 == 0) printf("Iteration: %d\n", i);
-		lock(s);
-		wait(c_s, s, 1`ns);
-		unlock(s);
-	}
-	done = true;
-}
-
-thread T_C_LWDS {};
-
-void main( T_C_LWDS & this ) {
-	for (unsigned int i = 0; i < num_times; i++) {
-		while (empty(c_s) && !done) { }
-		lock(s);
-		notify_one(c_s);
-		unlock(s);
-		sleep(1`ns);
-		if(done) break;
-	}
-}
-
-int main() {
-	processor p[2];
-	printf("Start Test 1: multi acquisition lock and condition variable single wait/notify\n");
-	{
-		T_C_M_WS1 t1[2];
-	}
-	printf("Done Test 1\n");
-
-	printf("Start Test 2: multi acquisition lock and condition variable 3 wait/notify all\n");
-	{
-		T_C_M_WB1 t1[4];
-	}
-	printf("Done Test 2\n");
-
-	printf("Start Test 3: single acquisition lock and condition variable single wait/notify\n");
-	{
-		T_C_S_WS1 t1[2];
-	}
-	printf("Done Test 3\n");
-
-	printf("Start Test 4: single acquisition lock and condition variable 3 wait/notify all\n");
-	{
-		T_C_S_WB1 t1[4];
-	}
-	printf("Done Test 4\n");
-
-	printf("Start Test 5: owner lock and condition variable single wait/notify\n");
-	{
-		T_C_O_WS1 t1[2];
-	}
-	printf("Done Test 5\n");
-
-	printf("Start Test 6: owner lock and condition variable 3 wait/notify all\n");
-	{
-		T_C_O_WB1 t1[4];
-	}
-	printf("Done Test 6\n");
-
-	printf("Start Test 7: multi acquisiton lock and condition variable multiple acquire and wait/notify\n");
-	{
-		T_C_M_WS2 t1[2];
-	}
-	printf("Done Test 7\n");
-
-	printf("Start Test 8: owner lock and condition variable multiple acquire and wait/notify\n");
-	{
-		T_C_O_WS2 t1[2];
-	}
-	printf("Done Test 8\n");
-
-	printf("Start Test 9: no lock condition variable wait/notify\n");
-	{
-		T_C_NLW t1;
-		T_C_NLS t2;
-	}
-	printf("Done Test 9\n");
-
-	printf("Start Test 10: locked condition variable wait/notify with front()\n");
-	{
-		T_C_S_WNF t1[2];
-	}
-	printf("Done Test 10\n");
-
-	// removed to limit test duration. Full test is in long run tests
-	// printf("Start Test 11: unlocked condition variable delay wait\n");
-	// {
-	// 	T_C_NLWD t1;
-	// 	T_C_WDS t2;
-	// }
-	// printf("Done Test 11\n");
-
-	// printf("Start Test 12: locked condition variable delay wait with unlocked signal\n");
-	// {
-	// 	T_C_LWD t1;
-	// 	T_C_WDS t2;
-	// }
-	// printf("Done Test 12\n");
-
-	// printf("Start Test 13: locked condition variable delay wait with locked signal\n");
-	// {
-	// 	T_C_LWD t1;
-	// 	T_C_LWDS t2;
-	// }
-	// printf("Done Test 13\n");
-}
Index: sts/unified_locking/timeout_lock.cfa
===================================================================
--- tests/unified_locking/timeout_lock.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,92 +1,0 @@
-#include <stdio.h>
-#include "locks.hfa"
-#include "alarm.hfa"
-#include <stdlib.hfa>
-#include <thread.hfa>
-#include "kernel.cfa"
-
-multiple_acquisition_lock m;
-condition_variable( multiple_acquisition_lock ) c_m;
-
-semaphore s; // used for barrier like behaviour
-
-const unsigned int NoOfTimes = 20;
-
-void block() {
-	if (s.count == 0) {
-		P(s);
-	} else {
-		V(s);
-	}
-}
-
-thread T1 {};
-
-void main( T1 & this ) {
-	lock(m);
-	wait( c_m, m, 1`s );
-	// printf("Thread: %p timedout\n", active_thread()); // removed since can't expect non deterministic output
-
-	block();
-
-	// Test calls which occur increasingly close to timeout value.
-
-	for ( unsigned int i = 0; i < NoOfTimes + 3; i += 1 ) {
-	    if ( wait( c_m, m, 1`s ) ) { 
-			// printf("Thread: %p signalled\n", active_thread()); // removed since can't expect non deterministic output
-	    } else {
-			// printf("Thread: %p timedout\n", active_thread()); // removed since can't expect non deterministic output
-	    } // if
-
-	    block();
-	} // for
-}
-
-
-thread T2 {};
-
-void main( T2 & this ) {
-	block();
-
-	// Test calls which occur increasingly close to timeout value.
-
-	sleep( 100000000`ns );
-	notify_one(c_m);
-	block();
-
-	sleep( 500000000`ns );
-	notify_one(c_m);
-	block();
-
-	sleep( 900000000`ns );
-	notify_one(c_m);
-	block();
-
-	for ( unsigned int i = 0; i < NoOfTimes; i += 1 ) {
-	    sleep( 999700000`ns );
-		notify_one(c_m);
-	    block();
-	} // for
-}
-
-int main() {
-	processor p[2];
-	printf("Start Test 1: surface testing condition variable timeout routines\n");
-	wait( c_m, 1`ns );														// bool wait( condition_variable(L) & this, Duration duration );	
-	wait( c_m, 10, 1`ns );													// bool wait( condition_variable(L) & this, uintptr_t info, Duration duration );
-	wait( c_m, __kernel_get_time() + 1`ns );								// bool wait( condition_variable(L) & this, Time time );
-	wait( c_m, 10, __kernel_get_time() + 1`ns );							// bool wait( condition_variable(L) & this, uintptr_t info, Time time );
-	lock(m); wait( c_m, m, 1`ns ); unlock(m); 								// bool wait( condition_variable(L) & this, L & l, Duration duration );
-	lock(m); wait( c_m, m, 10, 1`ns ); unlock(m);							// bool wait( condition_variable(L) & this, L & l, uintptr_t info, Duration duration );
-	lock(m); wait( c_m, m, __kernel_get_time() + 1`ns ); unlock(m);			// bool wait( condition_variable(L) & this, L & l, Time time );
-	lock(m); wait( c_m, m, 10, __kernel_get_time() + 1`ns ); unlock(m);		// bool wait( condition_variable(L) & this, L & l, uintptr_t info, Time time );
-	printf("Done Test 1\n");
-
-	printf("Start Test 2: testing timeout vs signalling with varying timeout durations\n");
-	s{ 0 };
-	{
-		T1 t1;
-		T2 t2;
-	}
-	printf("Done Test 2\n");
-}
Index: sts/unified_locking/timeout_lock.txt
===================================================================
--- tests/unified_locking/timeout_lock.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,4 +1,0 @@
-Start Test 1: surface testing condition variable timeout routines
-Done Test 1
-Start Test 2: testing timeout vs signalling with varying timeout durations
-Done Test 2
Index: sts/vector_math/.expect/vec2_double.txt
===================================================================
--- tests/vector_math/.expect/vec2_double.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,2 +1,0 @@
-ctor(x,y):<1.79769313486232e+308,2.2250738585072e-308>
-dot(v2,v3):324.670709736639
Index: sts/vector_math/.expect/vec2_float.txt
===================================================================
--- tests/vector_math/.expect/vec2_float.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,41 +1,0 @@
-ctor(x,y):<1.,2.>
-copy ctor:<1.,2.>
-assignment:<3.,4.2>
-move assignment:<1.,2.>
-zero-init:<0.,0.>
-zero-assign:<0.,0.>
-fill-ctor:<1.23,1.23>
-?-?:<0.02,0.43>
-?-=?:<3.23,-6.57>
--?:<-3.23,6.57>
-?+?:<2.3,2.45>
-?+=?:<2.3,2.45>
-v*s:<4.5,8.25>
-s*v:<4.5,8.25>
-?*=?:<4.5,8.25>
-?*?(vec)<2.64,-17.4>
-?*=?(vec)<2.64,-17.4>
-?/?:<0.666667,-0.0333333>
-?/=?:<0.666667,-0.0333333>
-?/?(vec)<0.545455,-1.93333>
-?/=?(vec)<0.545455,-1.93333>
-++?<2.2,-2.5>
---?<2.2,-2.5>
-?++(part 1)<1.2,-3.5>
-?++(part 2)<2.2,-2.5>
-?--(part 1)<1.2,-3.5>
-?--(part 2)<0.2,-4.5>
-dot_1:0.
-dot_2:8.6
-length:5.
-length_squared:25.
-distance:6.5146
-normalize:<0.882353,-0.470588>
-normalize_2:<1.,0.>
-project:<5.,0.>
-project_2:<5.5,5.5>
-reflect:<-5.,6.>
-refract:<5.,6.>
-refract:<3.7594,4.5592>
-faceforward_nochange:<4.,5.5>
-faceforward_flip:<-4.,-5.5>
Index: sts/vector_math/.expect/vec2_int.txt
===================================================================
--- tests/vector_math/.expect/vec2_int.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,57 +1,0 @@
-ctor(x,y):<1,2>
-copy ctor:<1,2>
-assignment:<3,4>
-move assignment:<1,2>
-zero-init:<0,0>
-zero-assign:<0,0>
-fill-ctor:<123,123>
-?-?:<-1002,17>
-?-=?:<-1002,17>
--?:<1002,-17>
-?+?:<1004,-11>
-?+=?:<1004,-11>
-v*s:<45,825>
-s*v:<45,825>
-?*=?:<45,825>
-?*?(vec)<2,-15>
-?*=?(vec)<2,-15>
-?/?:<7,-3>
-?/=?:<7,-3>
-?/?(vec)<5,-1>
-?/=?(vec)<5,-1>
-++?<2,-2>
---?<2,-2>
-?++(part 1)<1,-3>
-?++(part 2)<2,-2>
-?--(part 1)<1,-3>
-?--(part 2)<0,-4>
-?%?(int)<0,1>
-?%=?(int)<0,1>
-?%?(vec)<-2,3>
-?%=?(vec)<-2,3>
-?&?(int)<0,8>
-?&=?(int)<0,8>
-?&?(vec)<1,6>
-?&=?(vec)<1,6>
-?|?(int)<7,3>
-?|=?(int)<7,3>
-?|?(vec)<7,1>
-?|=?(vec)<7,1>
-?^?(int)<12,0>
-?^=?(int)<12,0>
-?^?(vec)<12,5>
-?^=?(vec)<12,5>
-?<<?(int)<4,2>
-?<<=?(int)<4,2>
-?<<?(vec)<32,4>
-?<<=?(vec)<32,4>
-?>>?(int)<1,0>
-?>>=?(int)<1,0>
-?>>?(vec)<2,1>
-?>>=?(vec)<2,1>
-~?<-6,-3>
-dot_1:0
-dot_2:32
-length_squared:25
-faceforward_nochange:<4,5>
-faceforward_flip:<-4,-5>
Index: sts/vector_math/.expect/vec2_ldouble.txt
===================================================================
--- tests/vector_math/.expect/vec2_ldouble.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,2 +1,0 @@
-ctor(x,y):<1.18973149535723177e+4932,3.36210314311209351e-4932>
-dot(v2,v3):324.670709736639038
Index: sts/vector_math/.expect/vec2_uint.txt
===================================================================
--- tests/vector_math/.expect/vec2_uint.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,2 +1,0 @@
-ctor(x,y):<4294967295,0>
-dot(v2,v3):352
Index: sts/vector_math/.expect/vec3_float.txt
===================================================================
--- tests/vector_math/.expect/vec3_float.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,35 +1,0 @@
-ctor(x,y):<1.,2.,3.>
-copy ctor:<1.,2.,3.>
-assignment:<3.,4.2,-2.>
-move assignment:<1.,2.,3.>
-zero-init:<0.,0.,0.>
-zero-assign:<0.,0.,0.>
-fill-ctor:<1.23,1.23,1.23>
-?-?:<0.02,0.43,-0.999998>
-?-=?:<0.,0.,0.>
--?:<-0.,-0.,-0.>
-?+?:<2.3,2.45,-9.2>
-?+=?:<2.3,2.45,-9.2>
-v*s:<4.5,8.25,300.9>
-s*v:<4.5,8.25,300.9>
-?*=?:<4.5,8.25,300.9>
-?*?(vec):<2.,6.,13.5>
-?*=?(vec):<2.,6.,13.5>
-?/?:<0.666667,-0.0333333,15.>
-?/=?:<0.666667,-0.0333333,15.>
-?/?(vec):<1.,-0.0333333,0.666667>
-?/=?(vec):<1.,-0.0333333,0.666667>
-dot_1:0.
-dot_2:37.8
-cross:<-15.,-2.,39.>
-length:3.74166
-length_squared:14.
-distance:7.48599
-normalize:<0.872964,-0.465581,0.145494>
-project:<0.,0.,0.>
-project_2:<5.88034,0.588034,2.35214>
-reflect:<5.28917,6.,-1.57084>
-refract:<0.613403,0.736083,0.286214>
-refract:<0.461205,0.82471,-0.327329>
-faceforward_nochange:<4.,5.5,2.>
-faceforward_flip:<-4.,-5.5,-2.>
Index: sts/vector_math/.expect/vec3_int.txt
===================================================================
--- tests/vector_math/.expect/vec3_int.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,37 +1,0 @@
-ctor(x,y):<1,2,3>
-copy ctor:<1,2,3>
-?/?(vec)<5,-1,1>
-?/=?(vec)<5,-1,1>
-++?<2,-2,101>
---?<0,-4,99>
-?++(part 1)<1,-3,100>
-?++(part 2)<2,-2,101>
-?--(part 1)<1,-3,100>
-?--(part 2)<0,-4,99>
-?%?(int)<0,1,0>
-?%=?(int)<0,1,0>
-?%?(vec)<-2,3,9>
-?%=?(vec)<-2,3,9>
-?&?(int)<0,0,8>
-?&=?(int)<0,0,8>
-?&?(vec)<1,6,1>
-?&=?(vec)<1,6,1>
-?|?(int)<7,3,7>
-?|=?(int)<7,3,7>
-?|?(vec)<7,1,7>
-?|=?(vec)<7,1,7>
-?^?(int)<12,0,13>
-?^=?(int)<12,0,13>
-?^?(vec)<12,5,9>
-?^=?(vec)<12,5,9>
-?<<?(int)<4,2,8>
-?<<=?(int)<4,2,8>
-?<<?(vec)<32,4,2>
-?<<=?(vec)<32,4,2>
-?>>?(int)<1,0,2>
-?>>=?(int)<1,0,2>
-?>>?(vec)<2,1,2>
-?>>=?(vec)<2,1,2>
-~?<-6,-3,-2>
-dot:4
-length_squared:29
Index: sts/vector_math/.expect/vec4_float.txt
===================================================================
--- tests/vector_math/.expect/vec4_float.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,30 +1,0 @@
-ctor(x,y):<1.,2.,3.,4.>
-copy ctor:<1.,2.,3.,4.>
-assignment:<3.,4.2,-2.,-100.>
-move assignment:<1.,2.,3.,4.>
-zero-init:<0.,0.,0.,0.>
-zero-assign:<0.,0.,0.,0.>
-fill-ctor:<1.23,1.23,1.23,1.23>
-?-?:<0.02,0.43,-0.999998,-1e-06.>
-?-=?:<0.02,0.43,-0.999998,-1e-06.>
--?:<-0.02,-0.43,0.999998,1e-06.>
-?+?:<2.3,2.45,-9.2,-12.5>
-?+=?:<2.3,2.45,-9.2,-12.5>
-v*s:<4.5,8.25,300.9,-6.>
-s*v:<4.5,8.25,300.9,-6.>
-?*=?:<4.5,8.25,300.9,-6.>
-?/?:<0.666667,-0.0333333,15.,-5.>
-?/=?:<0.666667,-0.0333333,15.,-5.>
-dot_1:0.
-dot_2:47.7345
-length:5.47723
-length_squared:30.
-distance:10.9563
-normalize:<0.433872,-0.231399,0.072312,0.867745>
-project:<-0.,-0.,-0.,-1.>
-project_2:<2.91736,0.291736,1.16694,0.583471>
-reflect:<5.26163,6.,-1.19906,1.52327>
-refract:<0.608838,0.730606,0.284084,0.121768>
-refract:<0.457773,0.822893,-0.333534,-0.0452281>
-faceforward_nochange:<4.,5.5,2.,2.>
-faceforward_flip:<4.,5.5,2.,2.>
Index: sts/vector_math/.expect/vec4_int.txt
===================================================================
--- tests/vector_math/.expect/vec4_int.txt	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,37 +1,0 @@
-ctor(x,y):<1,2,3,4>
-copy ctor:<1,2,3,4>
-?/?(vec)<5,-1,1,5>
-?/=?(vec)<5,-1,1,5>
-++?<2,-2,101,2>
---?<0,-4,99,2>
-?++(part 1)<1,-3,100,1>
-?++(part 2)<2,-2,101,2>
-?--(part 1)<1,-3,100,3>
-?--(part 2)<0,-4,99,2>
-?%?(int)<0,1,0,1>
-?%=?(int)<0,1,0,1>
-?%?(vec)<-2,3,9,4>
-?%=?(vec)<-2,3,9,4>
-?&?(int)<0,0,8,8>
-?&=?(int)<0,0,8,8>
-?&?(vec)<1,6,1,5>
-?&=?(vec)<1,6,1,5>
-?|?(int)<7,3,7,10>
-?|=?(int)<7,3,7,10>
-?|?(vec)<7,1,7,10>
-?|=?(vec)<7,1,7,10>
-?^?(int)<12,0,13,8>
-?^=?(int)<12,0,13,8>
-?^?(vec)<12,5,9,10>
-?^=?(vec)<12,5,9,10>
-?<<?(int)<4,2,8,12>
-?<<=?(int)<4,2,8,12>
-?<<?(vec)<32,4,2,8>
-?<<=?(vec)<32,4,2,8>
-?>>?(int)<1,0,2,3>
-?>>=?(int)<1,0,2,3>
-?>>?(vec)<2,1,2,4>
-?>>=?(vec)<2,1,2,4>
-~?<-6,-3,-2,0>
-dot:-11
-length_squared:54
Index: sts/vector_math/glm_equivalents/vec2_float.cc
===================================================================
--- tests/vector_math/glm_equivalents/vec2_float.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,28 +1,0 @@
-#include <glm/glm.hpp>
-#include <iostream>
-
-using namespace glm;
-
-std::ostream& operator<<(std::ostream& os, glm::tvec2<float>& v) {
-    os << "<" << v.x << "," << v.y << ">";
-    return os;
-}
-std::ostream& operator<<(std::ostream& os, glm::tvec2<float>&& v) {
-    os << "<" << v.x << "," << v.y << ">";
-    return os;
-}
-
-float length_squared(glm::tvec2<float> v) {
-    return glm::length(v) * glm::length(v);
-}
-
-tvec2<float> project(glm::tvec2<float> u, glm::tvec2<float> v) {
-    return normalize(v) * dot(u, normalize(v));
-}
-
-int main() {
-    tvec2<float> v1 = {5.f,6.f};
-    tvec2<float> v2 = {0.f,-1.f};
-    std::cout << "refract:" << refract(v1,normalize(v2),1.f) << std::endl;
-    std::cout << "refract:" << refract(v1,normalize(v2),1.f/1.33f) << std::endl;
-}
Index: sts/vector_math/glm_equivalents/vec2_int.cc
===================================================================
--- tests/vector_math/glm_equivalents/vec2_int.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,120 +1,0 @@
-#include <glm/glm.hpp>
-#include <iostream>
-
-using namespace glm;
-
-std::ostream& operator<<(std::ostream& os, glm::tvec2<int>& v) {
-    os << "<" << v.x << "," << v.y << ">";
-    return os;
-}
-std::ostream& operator<<(std::ostream& os, glm::tvec2<int>&& v) {
-    os << "<" << v.x << "," << v.y << ">";
-    return os;
-}
-
-int length_squared(glm::tvec2<float> v) {
-    return dot(v, v);
-}
-
-// tvec2<int> project(glm::tvec2<int> u, glm::tvec2<int> v) {
-//     return normalize(v) * dot(u, normalize(v));
-// }
-
-int main(void) {
-    tvec2<int> v1 = {1,2};
-    std::cout << "ctor(x,y):" << v1 << std::endl;
-
-    tvec2<int> v2 = v1;
-    std::cout << "copy ctor:" << v2 << std::endl;
-
-    v2 = (tvec2<int>){3, 4};
-    std::cout << "assignment:" << v2 << std::endl;
-
-    v2 = v1;
-    std::cout << "move assignment:" << v2 << std::endl;
-
-
-                // NOT SUPPORTED BY GLM
-    // tvec2<int> v3 = 0;
-    // std::cout << "zero-init:" << v3 << std::endl;
-
-    // v1 = 0;
-    // std::cout << "zero-assign:" << v1 << std::endl;
-
-    // tvec2<int> v4 = {1.23f};
-    // std::cout << "fill-ctor:" << v4 << std::endl;
-
-
-    v1 = (tvec2<int>){1, 3};
-    std::cout << "?-?:" << (v1 - (tvec2<int>){1003, -14}) << std::endl;
-
-    v1 -= (tvec2<int>){1003, -14};
-    std::cout << "?-=?:" << v1 << std::endl;
-
-    v1 = -v1;
-    std::cout << "-?:" << v1 << std::endl;
-
-    v1 = (tvec2<int>){1, 3};
-    std::cout << "?+?:" << (v1 + (tvec2<int>){1003, -14}) << std::endl;
-
-    v1 += (tvec2<int>){1003, -14};
-    std::cout << "?+=?:" << v1 << std::endl;
-
-    v1 = (tvec2<int>){15, 275};
-    std::cout << "v*s:" << v1 * 3 << std::endl;
-
-    std::cout << "s*v:" << 3 * v1 << std::endl;
-
-    v1 *= 3;
-    std::cout << "?*=?:" << v1 << std::endl;
-
-    v1 = (tvec2<int>){21, -10};
-    std::cout << "?/?:" << (v1 / 3) << std::endl;
-
-    v1 /= 3;
-    std::cout << "?/=?:" << v1 << std::endl;
-
-    //      FORCE GLM TO FLOAT, BUT WORKS
-    tvec2<float> v1_f = (tvec2<float>){2.f, 3};
-    tvec2<float> v2_f = (tvec2<float>){-3.f, 2.f};
-    std::cout << "dot_1:" << dot(v1_f, v2_f) << std::endl;
-
-    v2_f = (tvec2<float>){13, 2};
-    std::cout << "dot_2:" << dot(v1_f, v2_f) << std::endl;
-
-
-    //      NOT IN GLM BUT
-    //      USES DOT, BUT THAT'S FLOATING-POINT ONLY!
-    std::cout << "length_squared:" << length_squared(v1_f) << std::endl;
-
-    //      FLOATING-POINT ONLY GLM
-    // v1 = (tvec2<int>){100, -101};
-    // v2 = (tvec2<int>){6, 3};
-    // std::cout << "distance:" << distance(v1, v2) << std::endl;
-    //
-    // std::cout << "normalize:" << normalize(v2) << std::endl;
-    //
-    // v1 = (tvec2<int>){1,0};
-    // std::cout << "normalize_2:" << normalize(v1) << std::endl;
-    //
-    // std::cout << "project:" << project((tvec2<int>){5,6}, (tvec2<int>){1, 0}) << std::endl;
-    // std::cout << "project_2:" << project((tvec2<int>){5,6}, (tvec2<int>){1, 1}) << std::endl;
-    //
-    // v1 = (tvec2<int>){5,6};
-    // v2 = (tvec2<int>){1,0};
-    // std::cout << "reflect:" << reflect(v1,v2) << std::endl;
-    //
-    // v2 = (tvec2<int>){0,-1};
-    // std::cout << "refract:" << refract(v1,normalize(v2),1) << std::endl;
-    // std::cout << "refract:" << refract(v1,normalize(v2),1.f/1.33f) << std::endl;
-    //
-    //
-    //      FLOATING-POINT ONLY IN GLM BUT JUST USES DOT SO...
-    tvec2<float> geometric_normal = {5,6};
-    tvec2<float> perturbed_normal = {4,5};
-    tvec2<float> eyeline = {-1,0};
-    std::cout << "faceforward_nochange:" << faceforward(perturbed_normal, eyeline, geometric_normal) << std::endl;
-
-    eyeline = (tvec2<int>){1,0};
-    std::cout << "faceforward_flip:" << faceforward(perturbed_normal, eyeline, geometric_normal) << std::endl;
-}
Index: sts/vector_math/glm_equivalents/vec3_float.cc
===================================================================
--- tests/vector_math/glm_equivalents/vec3_float.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,117 +1,0 @@
-#include <glm/glm.hpp>
-#include <iostream>
-#include <ostream>
-
-using namespace glm;
-
-std::ostream& operator<<(std::ostream& os, glm::tvec3<float>& v) {
-    os << "<" << v.x << "," << v.y << "," << v.z << ">";
-    return os;
-}
-std::ostream& operator<<(std::ostream& os, glm::tvec3<float>&& v) {
-    os << "<" << v.x << "," << v.y << "," << v.z << ">";
-    return os;
-}
-
-float length_squared(glm::tvec3<float> v) {
-    return glm::length(v) * glm::length(v);
-}
-
-tvec3<float> project(glm::tvec3<float> u, glm::tvec3<float> v) {
-    return normalize(v) * dot(u, normalize(v));
-}
-
-int main(void) {
-    tvec3<float> v1 = {1.f,2.f,3.f};
-    std::cout << "ctor(x,y):" << v1 << std::endl;
-
-    tvec3<float> v2 = v1;
-    std::cout << "copy ctor:" << v2 << std::endl;
-
-    v2 = (tvec3<float>){3.f, 4.2f, -2.f};
-    std::cout << "assignment:" << v2 << std::endl;
-
-    v2 = v1;
-    std::cout << "move assignment:" << v2 << std::endl;
-
-    // tvec3<float> v3 = 0;
-    // std::cout << "zero-init:" << v3 << std::endl;
-
-    // v1 = 0;
-    // std::cout << "zero-assign:" << v1 << std::endl;
-    //
-    // tvec3<float> v4 = {1.23f};
-    // std::cout << "fill-ctor:" << v4 << std::endl;
-    //
-    v1 = (tvec3<float>){1.23f, 3.43f, 0.000002f};
-    std::cout << "?-?:" << (v1 - (tvec3<float>){1.21f,3,1}) << std::endl;
-
-    v1 -= (tvec3<float>){1.23f, 3.43f, 0.000002f};
-    std::cout << "?-=?:" << v1 << std::endl;
-
-    v1 = -v1;
-    std::cout << "-?:" << v1 << std::endl;
-
-
-
-
-
-    v1 = (tvec3<float>){1.5f, 2.75f, -14.2f};
-    std::cout << "?+?:" << (v1 + (tvec3<float>){0.8f, -0.3f, 5}) << std::endl;
-
-    v1 += (tvec3<float>){0.8f, -0.3f, 5};
-    std::cout << "?+=?:" << v1 << std::endl;
-
-    v1 = (tvec3<float>){1.5f, 2.75f, 100.3f};
-    std::cout << "v*s:" << v1 * 3.f << std::endl;
-
-    std::cout << "s*v:" << 3.f * v1 << std::endl;
-
-    v1 *= 3;
-    std::cout << "?*=?:" << v1 << std::endl;
-
-    v1 = (tvec3<float>){2, -0.1f, 45};
-    std::cout << "?/?:" << (v1 / 3.f) << std::endl;
-
-    v1 /= 3.f;
-    std::cout << "?/=?:" << v1 << std::endl;
-
-
-    v1 = (tvec3<float>){4,2,3};
-    v2 = (tvec3<float>){0,-3,2};
-    std::cout << "dot_1:" << dot(v1, v2) << std::endl;
-
-    v2 = (tvec3<float>){1.3f, -2, 12.2};
-    std::cout << "dot_2:" << dot(v1, v2) << std::endl;
-
-
-    v1 = (tvec3<float>){1,2,3};
-    std::cout << "length:" << length(v1) << std::endl;
-
-    std::cout << "length_squared:" << length_squared(v1) << std::endl;
-
-    v2 = (tvec3<float>){6, -3.2f, 1};
-    std::cout << "distance:" << distance(v1, v2) << std::endl;
-
-    std::cout << "normalize:" << normalize(v2) << std::endl;
-
-    std::cout << "project:" << project((tvec3<float>){5,6,0}, (tvec3<float>){0, 0, 1}) << std::endl;
-    std::cout << "project_2:" << project((tvec3<float>){5,6,3.2f}, (tvec3<float>){10, 1, 4}) << std::endl;
-
-    v1 = (tvec3<float>){5,6,2.333f};
-    v2 = (tvec3<float>){1,0,-13.5f};
-    std::cout << "reflect:" << reflect(v1,normalize(v2)) << std::endl;
-
-    v2 = (tvec3<float>){0,-1,2};
-    std::cout << "refract:" << refract(normalize(v1),normalize(v2),1.f) << std::endl;
-    std::cout << "refract:" << refract(normalize(v1),normalize(v2),1.f/1.33f) << std::endl;
-
-    tvec3<float> geometric_normal = {5,6,1};
-    tvec3<float> perturbed_normal = {4,5.5f,2};
-    tvec3<float> eyeline = {-1,0.002f,-1.0345f};
-    std::cout << "faceforward_nochange:" << faceforward(perturbed_normal, eyeline, geometric_normal) << std::endl;
-
-    eyeline = (tvec3<float>){1,0.002f,-1.0345f};
-    std::cout << "faceforward_flip:" << faceforward(perturbed_normal, eyeline, geometric_normal) << std::endl;
-}
-
Index: sts/vector_math/glm_equivalents/vec4_float.cc
===================================================================
--- tests/vector_math/glm_equivalents/vec4_float.cc	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,114 +1,0 @@
-#include <glm/glm.hpp>
-#include <iostream>
-#include <ostream>
-
-using namespace glm;
-
-std::ostream& operator<<(std::ostream& os, glm::tvec4<float>& v) {
-    os << "<" << v.x << "," << v.y << "," << v.z << "," << v.w << ">";
-    return os;
-}
-std::ostream& operator<<(std::ostream& os, glm::tvec4<float>&& v) {
-    os << "<" << v.x << "," << v.y << "," << v.z << "," << v.w << ">";
-    return os;
-}
-
-float length_squared(glm::tvec4<float> v) {
-    return glm::length(v) * glm::length(v);
-}
-
-tvec4<float> project(glm::tvec4<float> u, glm::tvec4<float> v) {
-    return normalize(v) * dot(u, normalize(v));
-}
-
-int main(void) {
-    tvec4<float> v1 = {1.f,2.f,3.f,4.f};
-    std::cout << "ctor(x,y):" << v1 << std::endl;
-
-    tvec4<float> v2 = v1;
-    std::cout << "copy ctor:" << v2 << std::endl;
-
-    v2 = (tvec4<float>){3.f,4.2f,-2.f,-100.f};
-    std::cout << "assignment:" << v2 << std::endl;
-
-    v2 = v1;
-    std::cout << "move assignment:" << v2 << std::endl;
-
-    // tvec4<float> v3 = 0;
-    // std::cout << "zero-init:" << v3 << std::endl;
-
-    // v1 = 0;
-    // std::cout << "zero-assign:" << v1 << std::endl;
-    //
-    // tvec4<float> v4 = {1.23f};
-    // std::cout << "fill-ctor:" << v4 << std::endl;
-    //
-    v1 = (tvec4<float>){1.23f, 3.43f, 0.000002f, -0.000002f};
-    std::cout << "?-?:" << (v1 - (tvec4<float>){1.21f,3,1,-0.000001f}) << std::endl;
-
-    v1 -= (tvec4<float>){1.21f,3,1,-0.000001f};
-    std::cout << "?-=?:" << v1 << std::endl;
-
-    v1 = -v1;
-    std::cout << "-?:" << v1 << std::endl;
-
-
-    v1 = (tvec4<float>){1.5f, 2.75f, -14.2f, -13.5f};
-    std::cout << "?+?:" << (v1 + (tvec4<float>){0.8f, -0.3f, 5, 1}) << std::endl;
-
-    v1 += (tvec4<float>){0.8f, -0.3f, 5, 1};
-    std::cout << "?+=?:" << v1 << std::endl;
-
-    v1 = (tvec4<float>){1.5f, 2.75f, 100.3f, -2.f};
-    std::cout << "v*s:" << v1 * 3.f << std::endl;
-
-    std::cout << "s*v:" << 3.f * v1 << std::endl;
-
-    v1 *= 3;
-    std::cout << "?*=?:" << v1 << std::endl;
-
-    v1 = (tvec4<float>){2, -0.1f, 45, -15};
-    std::cout << "?/?:" << (v1 / 3.f) << std::endl;
-
-    v1 /= 3.f;
-    std::cout << "?/=?:" << v1 << std::endl;
-
-
-    v1 = (tvec4<float>){4,3,2,1};
-    v2 = (tvec4<float>){0,4,-3,-6};
-    std::cout << "dot_1:" << dot(v1, v2) << std::endl;
-
-    v2 = (tvec4<float>){1.3f, -2, 12.2, 24.1345};
-    std::cout << "dot_2:" << dot(v1, v2) << std::endl;
-
-
-    v1 = (tvec4<float>){1,2,3,4};
-    std::cout << "length:" << length(v1) << std::endl;
-
-    std::cout << "length_squared:" << length_squared(v1) << std::endl;
-
-    v2 = (tvec4<float>){6, -3.2f, 1, 12};
-    std::cout << "distance:" << distance(v1, v2) << std::endl;
-
-    std::cout << "normalize:" << normalize(v2) << std::endl;
-
-    std::cout << "project:" << project((tvec4<float>){5,6,0,-1}, (tvec4<float>){0, 0, 0, 1}) << std::endl;
-    std::cout << "project_2:" << project((tvec4<float>){5,6,3.2f,-16.75f}, (tvec4<float>){10, 1, 4, 2}) << std::endl;
-
-    v1 = (tvec4<float>){5,6,2.333f,1};
-    v2 = (tvec4<float>){1,0,-13.5f,2};
-    std::cout << "reflect:" << reflect(v1,normalize(v2)) << std::endl;
-
-    v2 = (tvec4<float>){0,-1,2,0.5f};
-    std::cout << "refract:" << refract(normalize(v1),normalize(v2),1.f) << std::endl;
-    std::cout << "refract:" << refract(normalize(v1),normalize(v2),1.f/1.33f) << std::endl;
-
-    tvec4<float> geometric_normal = {5,6,1,2};
-    tvec4<float> perturbed_normal = {4,5.5f,2,2};
-    tvec4<float> eyeline = {-1,0.002f,-1.0345f,-2};
-    std::cout << "faceforward_nochange:" << faceforward(perturbed_normal, eyeline, geometric_normal) << std::endl;
-
-    eyeline = (tvec4<float>){1,0.002f,-1.0345f,-2};
-    std::cout << "faceforward_flip:" << faceforward(perturbed_normal, eyeline, geometric_normal) << std::endl;
-}
-
Index: sts/vector_math/vec2_double.cfa
===================================================================
--- tests/vector_math/vec2_double.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,12 +1,0 @@
-#include <vec/vec2.hfa>
-#include <fstream.hfa>
-#include <limits.hfa>
-
-int main(void) {
-    vec2(double) v1 = {(double)MAX,(double)MIN};
-    sout | "ctor(x,y):" | v1;
-
-    vec2(double) v2 = {3.4144423, -1.2342315};
-    vec2(double) v3 = {100.23125123, 14.23};
-    sout | "dot(v2,v3):" | dot(v2, v3);
-}
Index: sts/vector_math/vec2_float.cfa
===================================================================
--- tests/vector_math/vec2_float.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,127 +1,0 @@
-#include <vec/vec2.hfa>
-#include <fstream.hfa>
-
-int main(void) {
-    vec2(float) v1 = {1.f,2.f};
-    sout | "ctor(x,y):" | v1;
-
-    vec2(float) v2 = v1;
-    sout | "copy ctor:" | v2;
-
-    v2 = (vec2(float)){3.f, 4.2f};
-    sout | "assignment:" | v2;
-
-    v2 = v1;
-    sout | "move assignment:" | v2;
-
-    vec2(float) v3 = 0;
-    sout | "zero-init:" | v3;
-
-    v1 = 0;
-    sout | "zero-assign:" | v1;
-
-    vec2(float) v4 = {1.23f};
-    sout | "fill-ctor:" | v4;
-
-    v1 = (vec2(float)){1.23f, 3.43f};
-    sout | "?-?:" | (v1 - (vec2(float)){1.21f,3});
-
-    v1 -= (vec2(float)){-2, 10};
-    sout | "?-=?:" | v1;
-
-    v1 = -v1;
-    sout | "-?:" | v1;
-
-    v1 = (vec2(float)){1.5f, 2.75f};
-    sout | "?+?:" | (v1 + (vec2(float)){0.8f, -0.3f});
-
-    v1 += (vec2(float)){0.8f, -0.3f};
-    sout | "?+=?:" | v1;
-
-    v1 = (vec2(float)){1.5f, 2.75f};
-    sout | "v*s:" | v1 * 3.f;
-
-    sout | "s*v:" | 3.f * v1;
-
-    v1 *= 3;
-    sout | "?*=?:" | v1;
-
-    {
-        vec2(float) u = {1.2f, -5.8f};
-        vec2(float) v = {2.2f, 3};
-        sout | "?*?(vec)" | (u * v);
-        sout | "?*=?(vec)" | (u *= v);
-    }
-
-
-    v1 = (vec2(float)){2, -0.1f};
-    sout | "?/?:" | (v1 / 3);
-
-    v1 /= 3;
-    sout | "?/=?:" | v1;
-
-    {
-        vec2(float) u = {1.2f, -5.8f};
-        vec2(float) v = {2.2f, 3};
-        sout | "?/?(vec)" | (u / v);
-        sout | "?/=?(vec)" | (u /= v);
-    }
-
-    {
-        vec2(float) u = {1.2f, -3.5f};
-        sout | "++?" | ++u;
-    }
-    {
-        vec2(float) u = {1.2f, -3.5f};
-        sout | "--?" | ++u;
-    }
-    {
-        vec2(float) u = {1.2f, -3.5f};
-        sout | "?++(part 1)" | u++;
-        sout | "?++(part 2)" | u;
-    }
-    {
-        vec2(float) u = {1.2f, -3.5f};
-        sout | "?--(part 1)" | u--;
-        sout | "?--(part 2)" | u;
-    }
-
-    v1 = (vec2(float)){2, 3};
-    v2 = (vec2(float)){-3, 2};
-    sout | "dot_1:" | dot(v1, v2);
-
-    v2 = (vec2(float)){1.3f, 2};
-    sout | "dot_2:" | dot(v1, v2);
-
-    v1 = (vec2(float)){4, 3};
-    sout | "length:" | length(v1);
-
-    sout | "length_squared:" | length_squared(v1);
-
-    v2 = (vec2(float)){6, -3.2f};
-    sout | "distance:" | distance(v1, v2);
-
-    sout | "normalize:" | normalize(v2);
-
-    v1 = (vec2(float)){1,0};
-    sout | "normalize_2:" | normalize(v1);
-
-    sout | "project:" | project((vec2(float)){5,6}, (vec2(float)){1, 0});
-    sout | "project_2:" | project((vec2(float)){5,6}, (vec2(float)){1, 1});
-
-    v1 = (vec2(float)){5,6};
-    v2 = (vec2(float)){1,0};
-    sout | "reflect:" | reflect(v1,v2);
-
-    v2 = (vec2(float)){0,-1};
-    sout | "refract:" | refract(v1,normalize(v2),1.f);
-    sout | "refract:" | refract(v1,normalize(v2),1.f/1.33f);
-
-    vec2(float) geometric_normal = {5,6};
-    vec2(float) perturbed_normal = {4,5.5f};
-    vec2(float) eyeline = {-1,0.002f};
-    sout | "faceforward_nochange:" | faceforward(perturbed_normal, eyeline, geometric_normal);
-
-    eyeline = (vec2(float)){1,0.002f};
-    sout | "faceforward_flip:" | faceforward(perturbed_normal, eyeline, geometric_normal);
-}
Index: sts/vector_math/vec2_int.cfa
===================================================================
--- tests/vector_math/vec2_int.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,191 +1,0 @@
-#include <vec/vec2.hfa>
-#include <fstream.hfa>
-#include <limits.hfa>
-
-int main(void) {
-    vec2(int) v1 = {1,2};
-    sout | "ctor(x,y):" | v1;
-
-    vec2(int) v2 = v1;
-    sout | "copy ctor:" | v2;
-
-    v2 = (vec2(int)){3, 4};
-    sout | "assignment:" | v2;
-
-    v2 = v1;
-    sout | "move assignment:" | v2;
-
-    vec2(int) v3 = 0;
-    sout | "zero-init:" | v3;
-
-    v1 = 0;
-    sout | "zero-assign:" | v1;
-
-    vec2(int) v4 = {123};
-    sout | "fill-ctor:" | v4;
-
-    v1 = (vec2(int)){1, 3};
-    sout | "?-?:" | (v1 - (vec2(int)){1003, -14});
-
-    v1 -= (vec2(int)){1003, -14};
-    sout | "?-=?:" | v1;
-
-    v1 = -v1;
-    sout | "-?:" | v1;
-
-    v1 = (vec2(int)){1, 3};
-    sout | "?+?:" | (v1 + (vec2(int)){1003, -14});
-
-    v1 += (vec2(int)){1003, -14};
-    sout | "?+=?:" | v1;
-
-    v1 = (vec2(int)){15, 275};
-    sout | "v*s:" | v1 * 3;
-
-    sout | "s*v:" | 3 * v1;
-
-    v1 *= 3;
-    sout | "?*=?:" | v1;
-
-    {
-        vec2(int) u = {1, -5};
-        vec2(int) v = {2, 3};
-        sout | "?*?(vec)" | (u * v);
-        sout | "?*=?(vec)" | (u *= v);
-    }
-
-    v1 = (vec2(int)){21, -10};
-    sout | "?/?:" | (v1 / 3);
-
-    v1 /= 3;
-    sout | "?/=?:" | v1;
-
-    {
-        vec2(int) u = {11, -5};
-        vec2(int) v = {2, 3};
-        sout | "?/?(vec)" | (u / v);
-        sout | "?/=?(vec)" | (u /= v);
-    }
-
-    {
-        vec2(int) u = {1, -3};
-        sout | "++?" | ++u;
-    }
-    {
-        vec2(int) u = {1, -3};
-        sout | "--?" | ++u;
-    }
-    {
-        vec2(int) u = {1, -3};
-        sout | "?++(part 1)" | u++;
-        sout | "?++(part 2)" | u;
-    }
-    {
-        vec2(int) u = {1, -3};
-        sout | "?--(part 1)" | u--;
-        sout | "?--(part 2)" | u;
-    }
-
-    // %
-    {
-        vec2(int) u = {-12, 123};
-        sout | "?%?(int)" | (u % 2);
-        sout | "?%=?(int)" | (u %= 2);
-    }
-    {
-        vec2(int) u = {-12, 27};
-        vec2(int) v = {5, 4};
-        sout | "?%?(vec)" | (u % v);
-        sout | "?%=?(vec)" | (u %= v);
-    }
-
-
-    // &
-    {
-        vec2(int) u = {5, 8};
-        sout | "?&?(int)" | (u & (1 << 3));
-        sout | "?&=?(int)" | (u &= (1 << 3));
-    }
-    {
-        vec2(int) u = {5, 6};
-        vec2(int) v = {3, 7};
-        sout | "?&?(vec)" | (u & v);
-        sout | "?&=?(vec)" | (u &= v);
-    }
-
-    // |
-    {
-        vec2(int) u = {5, 1};
-        sout | "?|?(int)" | (u | 2);
-        sout | "?|=?(int)" | (u |= 2);
-    }
-    {
-        vec2(int) u = {5, 1};
-        vec2(int) v = {2, 1};
-        sout | "?|?(vec)" | (u | v);
-        sout | "?|=?(vec)" | (u |= v);
-    }
-
-    // ^
-    {
-        vec2(int) u = {9, 5};
-        sout | "?^?(int)" | (u ^ 5);
-        sout | "?^=?(int)" | (u ^= 5);
-    }
-    {
-        vec2(int) u = {9, 5};
-        vec2(int) v = {5, 0};
-        sout | "?^?(vec)" | (u ^ v);
-        sout | "?^=?(vec)" | (u ^= v);
-    }
-
-    // <<
-    {
-        vec2(int) u = {2, 1};
-        sout | "?<<?(int)" | (u << 1);
-        sout | "?<<=?(int)" | (u <<= 1);
-    }
-    {
-        vec2(int) u = {1, 1};
-        vec2(int) v = {5, 2};
-        sout | "?<<?(vec)" | (u << v);
-        sout | "?<<=?(vec)" | (u <<= v);
-    }
-
-    // >>
-    {
-        vec2(int) u = {2, 1};
-        sout | "?>>?(int)" | (u >> 1);
-        sout | "?>>=?(int)" | (u >>= 1);
-    }
-    {
-        vec2(int) u = {5, 7};
-        vec2(int) v = {1, 2};
-        sout | "?>>?(vec)" | (u >> v);
-        sout | "?>>=?(vec)" | (u >>= v);
-    }
-
-    // ~
-    {
-        vec2(int) u = {5, 2};
-        sout | "~?" | (~u);
-    }
-
-    v1 = (vec2(int)){2, 3};
-    v2 = (vec2(int)){-3, 2};
-    sout | "dot_1:" | dot(v1, v2);
-
-    v2 = (vec2(int)){13, 2};
-    sout | "dot_2:" | dot(v1, v2);
-
-    v1 = (vec2(int)){4, 3};
-    sout | "length_squared:" | length_squared(v1);
-
-    vec2(int) geometric_normal = {5,6};
-    vec2(int) perturbed_normal = {4,5};
-    vec2(int) eyeline = {-1,0};
-    sout | "faceforward_nochange:" | faceforward(perturbed_normal, eyeline, geometric_normal);
-
-    eyeline = (vec2(int)){1,0};
-    sout | "faceforward_flip:" | faceforward(perturbed_normal, eyeline, geometric_normal);
-}
Index: sts/vector_math/vec2_ldouble.cfa
===================================================================
--- tests/vector_math/vec2_ldouble.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,12 +1,0 @@
-#include <vec/vec2.hfa>
-#include <fstream.hfa>
-#include <limits.hfa>
-
-int main(void) {
-    vec2(long double) v1 = {(long double)MAX,(long double)MIN};
-    sout | "ctor(x,y):" | v1;
-
-    vec2(long double) v2 = {3.4144423, -1.2342315};
-    vec2(long double) v3 = {100.23125123, 14.23};
-    sout | "dot(v2,v3):" | dot(v2, v3);
-}
Index: sts/vector_math/vec2_uint.cfa
===================================================================
--- tests/vector_math/vec2_uint.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,12 +1,0 @@
-#include <vec/vec2.hfa>
-#include <fstream.hfa>
-#include <limits.hfa>
-
-int main(void) {
-    vec2(unsigned) v1 = {(unsigned)MAX,(unsigned)MIN};
-    sout | "ctor(x,y):" | v1;
-
-    vec2(unsigned) v2 = {3, 4};
-    vec2(unsigned) v3 = {100, 13};
-    sout | "dot(v2,v3):" | dot(v2, v3);
-}
Index: sts/vector_math/vec3_float.cfa
===================================================================
--- tests/vector_math/vec3_float.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,107 +1,0 @@
-#include <vec/vec3.hfa>
-#include <fstream.hfa>
-
-int main(void) {
-    vec3(float) v1 = {1.f,2.f,3.f};
-    sout | "ctor(x,y):" | v1;
-
-    vec3(float) v2 = v1;
-    sout | "copy ctor:" | v2;
-
-    v2 = (vec3(float)){3.f, 4.2f, -2.f};
-    sout | "assignment:" | v2;
-
-    v2 = v1;
-    sout | "move assignment:" | v2;
-
-    vec3(float) v3 = 0;
-    sout | "zero-init:" | v3;
-
-    v1 = 0;
-    sout | "zero-assign:" | v1;
-
-    vec3(float) v4 = {1.23f};
-    sout | "fill-ctor:" | v4;
-
-    v1 = (vec3(float)){1.23f, 3.43f, 0.000002f};
-    sout | "?-?:" | (v1 - (vec3(float)){1.21f,3,1});
-
-    v1 -= (vec3(float)){1.23f, 3.43f, 0.000002f};
-    sout | "?-=?:" | v1;
-
-    v1 = -v1;
-    sout | "-?:" | v1;
-
-    v1 = (vec3(float)){1.5f, 2.75f, -14.2f};
-    sout | "?+?:" | (v1 + (vec3(float)){0.8f, -0.3f, 5});
-
-    v1 += (vec3(float)){0.8f, -0.3f, 5};
-    sout | "?+=?:" | v1;
-
-    v1 = (vec3(float)){1.5f, 2.75f, 100.3f};
-    sout | "v*s:" | v1 * 3.f;
-
-    sout | "s*v:" | 3.f * v1;
-
-    v1 *= 3;
-    sout | "?*=?:" | v1;
-
-    {
-        vec3(float) u = {1, 2, 3};
-        vec3(float) v = {2, 3, 4.5f};
-        sout | "?*?(vec):" | (u * v);
-        sout | "?*=?(vec):" | (u *= v);
-    }
-
-    v1 = (vec3(float)){2, -0.1f, 45};
-    sout | "?/?:" | (v1 / 3.f);
-
-    v1 /= 3.f;
-    sout | "?/=?:" | v1;
-
-    {
-        vec3(float) u = {2, -0.1f, 3};
-        vec3(float) v = {2, 3, 4.5f};
-        sout | "?/?(vec):" | (u / v);
-        sout | "?/=?(vec):" | (u /= v);
-    }
-
-    v1 = (vec3(float)){4,2,3};
-    v2 = (vec3(float)){0,-3,2};
-    sout | "dot_1:" | dot(v1, v2);
-
-    v2 = (vec3(float)){1.3f, -2, 12.2f};
-    sout | "dot_2:" | dot(v1, v2);
-
-    v2 = cross((vec3(float)){3,-3,1},(vec3(float)){4,9,2});
-    sout | "cross:" | v2;
-
-    v1 = (vec3(float)){1,2,3};
-    sout | "length:" | length(v1);
-
-    sout | "length_squared:" | length_squared(v1);
-
-    v2 = (vec3(float)){6, -3.2f, 1};
-    sout | "distance:" | distance(v1, v2);
-
-    sout | "normalize:" | normalize(v2);
-
-    sout | "project:" | project((vec3(float)){5,6,0}, (vec3(float)){0, 0, 1});
-    sout | "project_2:" | project((vec3(float)){5,6,3.2f}, (vec3(float)){10, 1, 4});
-
-    v1 = (vec3(float)){5,6,2.333f};
-    v2 = (vec3(float)){1,0,-13.5f};
-    sout | "reflect:" | reflect(v1,v2);
-
-    v2 = (vec3(float)){0,-1,2};
-    sout | "refract:" | refract(normalize(v1),normalize(v2),1.f);
-    sout | "refract:" | refract(normalize(v1),normalize(v2),1.f/1.33f);
-
-    vec3(float) geometric_normal = {5,6,1};
-    vec3(float) perturbed_normal = {4,5.5f,2};
-    vec3(float) eyeline = {-1,0.002f,-1.0345f};
-    sout | "faceforward_nochange:" | faceforward(perturbed_normal, eyeline, geometric_normal);
-
-    eyeline = (vec3(float)){1,0.002f,-1.0345f};
-    sout | "faceforward_flip:" | faceforward(perturbed_normal, eyeline, geometric_normal);
-}
Index: sts/vector_math/vec3_int.cfa
===================================================================
--- tests/vector_math/vec3_int.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,130 +1,0 @@
-#include <vec/vec3.hfa>
-#include <fstream.hfa>
-#include <limits.hfa>
-
-int main(void) {
-    vec3(int) v1 = {1,2,3};
-    sout | "ctor(x,y):" | v1;
-
-    vec3(int) v2 = v1;
-    sout | "copy ctor:" | v2;
-
-    {
-        vec3(int) u = {11, -5, 7};
-        vec3(int) v = {2, 3, 7};
-        sout | "?/?(vec)" | (u / v);
-        sout | "?/=?(vec)" | (u /= v);
-    }
-
-    {
-        vec3(int) u = {1, -3, 100};
-        sout | "++?" | ++u;
-    }
-
-    {
-        vec3(int) u = {1, -3, 100};
-        sout | "--?" | --u;
-    }
-    {
-        vec3(int) u = {1, -3, 100};
-        sout | "?++(part 1)" | u++;
-        sout | "?++(part 2)" | u;
-    }
-    {
-        vec3(int) u = {1, -3, 100};
-        sout | "?--(part 1)" | u--;
-        sout | "?--(part 2)" | u;
-    }
-
-    // %
-    {
-        vec3(int) u = {-12, 123, 100};
-        sout | "?%?(int)" | (u % 2);
-        sout | "?%=?(int)" | (u %= 2);
-    }
-    {
-        vec3(int) u = {-12, 27, 100};
-        vec3(int) v = {5, 4, 13};
-        sout | "?%?(vec)" | (u % v);
-        sout | "?%=?(vec)" | (u %= v);
-    }
-
-
-    // &
-    {
-        vec3(int) u = {5, 1, 8};
-        sout | "?&?(int)" | (u & (1 << 3));
-        sout | "?&=?(int)" | (u &= (1 << 3));
-    }
-    {
-        vec3(int) u = {5, 6, 5};
-        vec3(int) v = {3, 7, 3};
-        sout | "?&?(vec)" | (u & v);
-        sout | "?&=?(vec)" | (u &= v);
-    }
-
-    // |
-    {
-        vec3(int) u = {5, 1, 5};
-        sout | "?|?(int)" | (u | 2);
-        sout | "?|=?(int)" | (u |= 2);
-    }
-    {
-        vec3(int) u = {5, 1, 5};
-        vec3(int) v = {2, 1, 2};
-        sout | "?|?(vec)" | (u | v);
-        sout | "?|=?(vec)" | (u |= v);
-    }
-
-    // ^
-    {
-        vec3(int) u = {9, 5, 8};
-        sout | "?^?(int)" | (u ^ 5);
-        sout | "?^=?(int)" | (u ^= 5);
-    }
-    {
-        vec3(int) u = {9, 5, 8};
-        vec3(int) v = {5, 0, 1};
-        sout | "?^?(vec)" | (u ^ v);
-        sout | "?^=?(vec)" | (u ^= v);
-    }
-
-    // <<
-    {
-        vec3(int) u = {2, 1, 4};
-        sout | "?<<?(int)" | (u << 1);
-        sout | "?<<=?(int)" | (u <<= 1);
-    }
-    {
-        vec3(int) u = {1, 1, 1};
-        vec3(int) v = {5, 2, 1};
-        sout | "?<<?(vec)" | (u << v);
-        sout | "?<<=?(vec)" | (u <<= v);
-    }
-
-    // >>
-    {
-        vec3(int) u = {2, 1, 4};
-        sout | "?>>?(int)" | (u >> 1);
-        sout | "?>>=?(int)" | (u >>= 1);
-    }
-    {
-        vec3(int) u = {5, 7, 8};
-        vec3(int) v = {1, 2, 2};
-        sout | "?>>?(vec)" | (u >> v);
-        sout | "?>>=?(vec)" | (u >>= v);
-    }
-
-    // ~
-    {
-        vec3(int) u = {5, 2, 1};
-        sout | "~?" | (~u);
-    }
-
-    v1 = (vec3(int)){2, 3, 4};
-    v2 = (vec3(int)){13, 2, -7};
-    sout | "dot:" | dot(v1, v2);
-
-    v1 = (vec3(int)){2,3,4};
-    sout | "length_squared:" | length_squared(v1);
-}
Index: sts/vector_math/vec4_float.cfa
===================================================================
--- tests/vector_math/vec4_float.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,90 +1,0 @@
-#include <vec/vec4.hfa>
-#include <fstream.hfa>
-
-int main(void) {
-    vec4(float) v1 = {1.f,2.f,3.f,4.f};
-    sout | "ctor(x,y):" | v1;
-
-    vec4(float) v2 = v1;
-    sout | "copy ctor:" | v2;
-
-    v2 = (vec4(float)){3.f,4.2f,-2.f,-100.f};
-    sout | "assignment:" | v2;
-
-    v2 = v1;
-    sout | "move assignment:" | v2;
-
-    vec4(float) v3 = 0;
-    sout | "zero-init:" | v3;
-
-    v1 = 0;
-    sout | "zero-assign:" | v1;
-
-    vec4(float) v4 = {1.23f};
-    sout | "fill-ctor:" | v4;
-
-    v1 = (vec4(float)){1.23f, 3.43f, 0.000002f, -0.000002f};
-    sout | "?-?:" | (v1 - (vec4(float)){1.21f,3,1,-0.000001f});
-
-    v1 -= (vec4(float)){1.21f,3,1,-0.000001f};
-    sout | "?-=?:" | v1;
-
-    v1 = -v1;
-    sout | "-?:" | v1;
-
-    v1 = (vec4(float)){1.5f, 2.75f, -14.2f, -13.5f};
-    sout | "?+?:" | (v1 + (vec4(float)){0.8f, -0.3f, 5, 1});
-
-    v1 += (vec4(float)){0.8f, -0.3f, 5, 1};
-    sout | "?+=?:" | v1;
-
-    v1 = (vec4(float)){1.5f, 2.75f, 100.3f, -2.f};
-    sout | "v*s:" | v1 * 3.f;
-
-    sout | "s*v:" | 3.f * v1;
-
-    v1 *= 3;
-    sout | "?*=?:" | v1;
-
-    v1 = (vec4(float)){2, -0.1f, 45, -15};
-    sout | "?/?:" | (v1 / 3.f);
-
-    v1 /= 3.f;
-    sout | "?/=?:" | v1;
-
-    v1 = (vec4(float)){4,3,2,1};
-    v2 = (vec4(float)){0,4,-3,-6};
-    sout | "dot_1:" | dot(v1, v2);
-
-    v2 = (vec4(float)){1.3f, -2, 12.2f, 24.1345f};
-    sout | "dot_2:" | dot(v1, v2);
-
-    v1 = (vec4(float)){1,2,3,4};
-    sout | "length:" | length(v1);
-
-    sout | "length_squared:" | length_squared(v1);
-
-    v2 = (vec4(float)){6, -3.2f, 1, 12};
-    sout | "distance:" | distance(v1, v2);
-
-    sout | "normalize:" | normalize(v2);
-
-    sout | "project:" | project((vec4(float)){5,6,0,-1}, (vec4(float)){0, 0, 0, 1});
-    sout | "project_2:" | project((vec4(float)){5,6,3.2f,-16.75f}, (vec4(float)){10, 1, 4, 2});
-
-    v1 = (vec4(float)){5,6,2.333f,1};
-    v2 = (vec4(float)){1,0,-13.5f,2};
-    sout | "reflect:" | reflect(v1,v2);
-
-    v2 = (vec4(float)){0,-1,2,0.5f};
-    sout | "refract:" | refract(normalize(v1),normalize(v2),1.f);
-    sout | "refract:" | refract(normalize(v1),normalize(v2),1.f/1.33f);
-
-    vec4(float) geometric_normal = {5,6,1,2};
-    vec4(float) perturbed_normal = {4,5.5f,2,2};
-    vec4(float) eyeline = {-1,0.002f,-1.0345f,-2};
-    sout | "faceforward_nochange:" | faceforward(perturbed_normal, eyeline, geometric_normal);
-
-    eyeline = (vec4(float)){1,0.002f,-1.0345f,-2};
-    sout | "faceforward_flip:" | faceforward(perturbed_normal, eyeline, geometric_normal);
-}
Index: sts/vector_math/vec4_int.cfa
===================================================================
--- tests/vector_math/vec4_int.cfa	(revision 2b4daf23cdfb724c24a5ed13d7d20d9fe2c80590)
+++ 	(revision )
@@ -1,130 +1,0 @@
-#include <vec/vec4.hfa>
-#include <fstream.hfa>
-#include <limits.hfa>
-
-int main(void) {
-    vec4(int) v1 = {1,2,3,4};
-    sout | "ctor(x,y):" | v1;
-
-    vec4(int) v2 = v1;
-    sout | "copy ctor:" | v2;
-
-    {
-        vec4(int) u = {11, -5, 7, 11};
-        vec4(int) v = {2, 3, 7, 2};
-        sout | "?/?(vec)" | (u / v);
-        sout | "?/=?(vec)" | (u /= v);
-    }
-
-    {
-        vec4(int) u = {1, -3, 100, 1};
-        sout | "++?" | ++u;
-    }
-
-    {
-        vec4(int) u = {1, -3, 100, 3};
-        sout | "--?" | --u;
-    }
-    {
-        vec4(int) u = {1, -3, 100, 1};
-        sout | "?++(part 1)" | u++;
-        sout | "?++(part 2)" | u;
-    }
-    {
-        vec4(int) u = {1, -3, 100, 3};
-        sout | "?--(part 1)" | u--;
-        sout | "?--(part 2)" | u;
-    }
-
-    // %
-    {
-        vec4(int) u = {-12, 123, 100, 5};
-        sout | "?%?(int)" | (u % 2);
-        sout | "?%=?(int)" | (u %= 2);
-    }
-    {
-        vec4(int) u = {-12, 27, 100, 14};
-        vec4(int) v = {5, 4, 13, 5};
-        sout | "?%?(vec)" | (u % v);
-        sout | "?%=?(vec)" | (u %= v);
-    }
-
-
-    // &
-    {
-        vec4(int) u = {5, 1, 8, 15};
-        sout | "?&?(int)" | (u & (1 << 3));
-        sout | "?&=?(int)" | (u &= (1 << 3));
-    }
-    {
-        vec4(int) u = {5, 6, 5, 13};
-        vec4(int) v = {3, 7, 3, 7};
-        sout | "?&?(vec)" | (u & v);
-        sout | "?&=?(vec)" | (u &= v);
-    }
-
-    // |
-    {
-        vec4(int) u = {5, 1, 5, 8};
-        sout | "?|?(int)" | (u | 2);
-        sout | "?|=?(int)" | (u |= 2);
-    }
-    {
-        vec4(int) u = {5, 1, 5, 2};
-        vec4(int) v = {2, 1, 2, 8};
-        sout | "?|?(vec)" | (u | v);
-        sout | "?|=?(vec)" | (u |= v);
-    }
-
-    // ^
-    {
-        vec4(int) u = {9, 5, 8, 13};
-        sout | "?^?(int)" | (u ^ 5);
-        sout | "?^=?(int)" | (u ^= 5);
-    }
-    {
-        vec4(int) u = {9, 5, 8, 13};
-        vec4(int) v = {5, 0, 1, 7};
-        sout | "?^?(vec)" | (u ^ v);
-        sout | "?^=?(vec)" | (u ^= v);
-    }
-
-    // <<
-    {
-        vec4(int) u = {2, 1, 4, 6};
-        sout | "?<<?(int)" | (u << 1);
-        sout | "?<<=?(int)" | (u <<= 1);
-    }
-    {
-        vec4(int) u = {1, 1, 1, 4};
-        vec4(int) v = {5, 2, 1, 1};
-        sout | "?<<?(vec)" | (u << v);
-        sout | "?<<=?(vec)" | (u <<= v);
-    }
-
-    // >>
-    {
-        vec4(int) u = {2, 1, 4, 6};
-        sout | "?>>?(int)" | (u >> 1);
-        sout | "?>>=?(int)" | (u >>= 1);
-    }
-    {
-        vec4(int) u = {5, 7, 8, 32};
-        vec4(int) v = {1, 2, 2, 3};
-        sout | "?>>?(vec)" | (u >> v);
-        sout | "?>>=?(vec)" | (u >>= v);
-    }
-
-    // ~
-    {
-        vec4(int) u = {5, 2, 1, -1};
-        sout | "~?" | (~u);
-    }
-
-    v1 = (vec4(int)){2, 3, 4, 5};
-    v2 = (vec4(int)){13, 2, -7, -3};
-    sout | "dot:" | dot(v1, v2);
-
-    v1 = (vec4(int)){2,3,4,5};
-    sout | "length_squared:" | length_squared(v1);
-}
