Index: driver/cfa.cc
===================================================================
--- driver/cfa.cc	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ driver/cfa.cc	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -10,6 +10,6 @@
 // Created On       : Tue Aug 20 13:44:49 2002
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Jan 31 16:48:03 2020
-// Update Count     : 421
+// Last Modified On : Mon May 18 13:26:26 2020
+// Update Count     : 424
 //
 
@@ -301,8 +301,4 @@
 	} // for
 
-	#ifdef __x86_64__
-	args[nargs++] = "-mcx16";							// allow double-wide CAA
-	#endif // __x86_64__
-
 	#ifdef __DEBUG_H__
 	cerr << "args:";
@@ -419,4 +415,8 @@
 		args[nargs++] = "-lcfa";
 		args[nargs++] = "-Wl,--pop-state";
+		#ifdef __x86_64__
+		args[nargs++] = "-mcx16";						// allow double-wide CAS
+		args[nargs++] = "-latomic";
+		#endif // __x86_64__
 		args[nargs++] = "-pthread";
 		args[nargs++] = "-ldl";
Index: libcfa/src/Makefile.am
===================================================================
--- libcfa/src/Makefile.am	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ libcfa/src/Makefile.am	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -11,6 +11,6 @@
 ## Created On       : Sun May 31 08:54:01 2015
 ## Last Modified By : Peter A. Buhr
-## Last Modified On : Mon Mar 16 18:07:59 2020
-## Update Count     : 242
+## Last Modified On : Sun May 17 21:10:26 2020
+## Update Count     : 243
 ###############################################################################
 
@@ -39,7 +39,8 @@
 #----------------------------------------------------------------------------------------------------------------
 if BUILDLIB
-headers_nosrc = bitmanip.hfa math.hfa gmp.hfa time_t.hfa bits/align.hfa bits/containers.hfa bits/defs.hfa bits/debug.hfa bits/locks.hfa containers/list.hfa
+headers_nosrc = bitmanip.hfa math.hfa gmp.hfa time_t.hfa clock.hfa \
+		bits/align.hfa bits/containers.hfa bits/defs.hfa bits/debug.hfa bits/locks.hfa containers/list.hfa
 headers = fstream.hfa iostream.hfa iterator.hfa limits.hfa rational.hfa time.hfa stdlib.hfa common.hfa \
-	  containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa
+		containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/stackLockFree.hfa containers/vector.hfa
 
 libsrc = startup.cfa interpose.cfa bits/debug.cfa assert.cfa exception.c virtual.c heap.cfa ${headers:.hfa=.cfa}
Index: libcfa/src/Makefile.in
===================================================================
--- libcfa/src/Makefile.in	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ libcfa/src/Makefile.in	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -241,5 +241,5 @@
 	containers/maybe.hfa containers/pair.hfa containers/result.hfa \
 	containers/vector.hfa bitmanip.hfa math.hfa gmp.hfa time_t.hfa \
-	bits/align.hfa bits/containers.hfa bits/defs.hfa \
+	clock.hfa bits/align.hfa bits/containers.hfa bits/defs.hfa \
 	bits/debug.hfa bits/locks.hfa containers/list.hfa \
 	concurrency/coroutine.hfa concurrency/thread.hfa \
@@ -465,8 +465,10 @@
 
 #----------------------------------------------------------------------------------------------------------------
-@BUILDLIB_TRUE@headers_nosrc = bitmanip.hfa math.hfa gmp.hfa time_t.hfa bits/align.hfa bits/containers.hfa bits/defs.hfa bits/debug.hfa bits/locks.hfa containers/list.hfa
+@BUILDLIB_TRUE@headers_nosrc = bitmanip.hfa math.hfa gmp.hfa time_t.hfa clock.hfa \
+@BUILDLIB_TRUE@		bits/align.hfa bits/containers.hfa bits/defs.hfa bits/debug.hfa bits/locks.hfa containers/list.hfa
+
 @BUILDLIB_FALSE@headers = 
 @BUILDLIB_TRUE@headers = fstream.hfa iostream.hfa iterator.hfa limits.hfa rational.hfa time.hfa stdlib.hfa common.hfa \
-@BUILDLIB_TRUE@	  containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa
+@BUILDLIB_TRUE@		containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa
 
 @BUILDLIB_FALSE@libsrc = 
Index: libcfa/src/concurrency/io.cfa
===================================================================
--- libcfa/src/concurrency/io.cfa	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ libcfa/src/concurrency/io.cfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -124,5 +124,4 @@
 
 		// Like head/tail but not seen by the kernel
-		volatile uint32_t alloc;
 		volatile uint32_t * ready;
 		uint32_t ready_cnt;
@@ -141,7 +140,8 @@
 			struct {
 				struct {
-					volatile unsigned long long int val;
+					volatile unsigned long long int rdy;
+					volatile unsigned long long int csm;
+					volatile unsigned long long int avl;
 					volatile unsigned long long int cnt;
-					volatile unsigned long long int block;
 				} submit_avg;
 				struct {
@@ -150,4 +150,9 @@
 					volatile unsigned long long int block;
 				} look_avg;
+				struct {
+					volatile unsigned long long int val;
+					volatile unsigned long long int cnt;
+					volatile unsigned long long int block;
+				} alloc_avg;
 			} stats;
 		#endif
@@ -279,5 +284,11 @@
 		sq.dropped = (         uint32_t *)(((intptr_t)sq.ring_ptr) + params.sq_off.dropped);
 		sq.array   = (         uint32_t *)(((intptr_t)sq.ring_ptr) + params.sq_off.array);
-		sq.alloc = *sq.tail;
+
+		{
+			const uint32_t num = *sq.num;
+			for( i; num ) {
+				sq.sqes[i].user_data = 0ul64;
+			}
+		}
 
 		if( io_flags & CFA_CLUSTER_IO_POLLER_THREAD_SUBMITS ) {
@@ -322,10 +333,14 @@
 		// Initialize statistics
 		#if !defined(__CFA_NO_STATISTICS__)
-			this.io->submit_q.stats.submit_avg.val   = 0;
-			this.io->submit_q.stats.submit_avg.cnt   = 0;
-			this.io->submit_q.stats.submit_avg.block = 0;
+			this.io->submit_q.stats.submit_avg.rdy = 0;
+			this.io->submit_q.stats.submit_avg.csm = 0;
+			this.io->submit_q.stats.submit_avg.avl = 0;
+			this.io->submit_q.stats.submit_avg.cnt = 0;
 			this.io->submit_q.stats.look_avg.val   = 0;
 			this.io->submit_q.stats.look_avg.cnt   = 0;
 			this.io->submit_q.stats.look_avg.block = 0;
+			this.io->submit_q.stats.alloc_avg.val   = 0;
+			this.io->submit_q.stats.alloc_avg.cnt   = 0;
+			this.io->submit_q.stats.alloc_avg.block = 0;
 			this.io->completion_q.stats.completed_avg.val = 0;
 			this.io->completion_q.stats.completed_avg.slow_cnt = 0;
@@ -384,4 +399,5 @@
 					this.ready_queue.head = 1p;
 					thrd.next = 0p;
+					__cfaabi_dbg_debug_do( thrd.unpark_stale = true );
 
 					// Fixup the thread state
@@ -426,4 +442,8 @@
 			if(this.print_stats) {
 				with(this.io->submit_q.stats, this.io->completion_q.stats) {
+					double avgrdy = ((double)submit_avg.rdy) / submit_avg.cnt;
+					double avgcsm = ((double)submit_avg.csm) / submit_avg.cnt;
+					double avgavl = ((double)submit_avg.avl) / submit_avg.cnt;
+
 					double lavgv = 0;
 					double lavgb = 0;
@@ -433,20 +453,35 @@
 					}
 
+					double aavgv = 0;
+					double aavgb = 0;
+					if(alloc_avg.cnt != 0) {
+						aavgv = ((double)alloc_avg.val  ) / alloc_avg.cnt;
+						aavgb = ((double)alloc_avg.block) / alloc_avg.cnt;
+					}
+
 					__cfaabi_bits_print_safe( STDOUT_FILENO,
 						"----- I/O uRing Stats -----\n"
 						"- total submit calls     : %'15llu\n"
-						"- avg submit             : %'18.2lf\n"
-						"- pre-submit block %%     : %'18.2lf\n"
+						"- avg ready entries      : %'18.2lf\n"
+						"- avg submitted entries  : %'18.2lf\n"
+						"- avg available entries  : %'18.2lf\n"
 						"- total ready search     : %'15llu\n"
 						"- avg ready search len   : %'18.2lf\n"
 						"- avg ready search block : %'18.2lf\n"
+						"- total alloc search     : %'15llu\n"
+						"- avg alloc search len   : %'18.2lf\n"
+						"- avg alloc search block : %'18.2lf\n"
 						"- total wait calls       : %'15llu   (%'llu slow, %'llu fast)\n"
 						"- avg completion/wait    : %'18.2lf\n",
 						submit_avg.cnt,
-						((double)submit_avg.val) / submit_avg.cnt,
-						(100.0 * submit_avg.block) / submit_avg.cnt,
+						avgrdy,
+						avgcsm,
+						avgavl,
 						look_avg.cnt,
 						lavgv,
 						lavgb,
+						alloc_avg.cnt,
+						aavgv,
+						aavgb,
 						completed_avg.slow_cnt + completed_avg.fast_cnt,
 						completed_avg.slow_cnt,  completed_avg.fast_cnt,
@@ -494,5 +529,5 @@
 
 			// If the poller thread also submits, then we need to aggregate the submissions which are ready
-			uint32_t * tail = ring.submit_q.tail;
+			uint32_t tail = *ring.submit_q.tail;
 			const uint32_t mask = *ring.submit_q.mask;
 
@@ -506,18 +541,14 @@
 
 				// If we got a real submission, append it to the list
-				ring.submit_q.array[ ((*tail) + to_submit) & mask ] = idx & mask;
+				ring.submit_q.array[ (tail + to_submit) & mask ] = idx & mask;
 				to_submit++;
 			}
 
 			// Increment the tail based on how many we are ready to submit
-			__atomic_fetch_add(tail, to_submit, __ATOMIC_SEQ_CST);
-
-			// update statistics
-			#if !defined(__CFA_NO_STATISTICS__)
-				ring.submit_q.stats.submit_avg.val += to_submit;
-				ring.submit_q.stats.submit_avg.cnt += 1;
-			#endif
-		}
-
+			__atomic_fetch_add(ring.submit_q.tail, to_submit, __ATOMIC_SEQ_CST);
+		}
+
+		const uint32_t smask = *ring.submit_q.mask;
+		uint32_t shead = *ring.submit_q.head;
 		int ret = syscall( __NR_io_uring_enter, ring.fd, to_submit, waitcnt, IORING_ENTER_GETEVENTS, mask, _NSIG / 8);
 		if( ret < 0 ) {
@@ -531,7 +562,33 @@
 		}
 
+		verify( (shead + ret) == *ring.submit_q.head );
+
+		// Release the consumed SQEs
+		for( i; ret ) {
+			uint32_t idx = ring.submit_q.array[ (i + shead) & smask ];
+			ring.submit_q.sqes[ idx ].user_data = 0;
+		}
+
+		uint32_t avail = 0;
+		uint32_t sqe_num = *ring.submit_q.num;
+		for(i; sqe_num) {
+			if( ring.submit_q.sqes[ i ].user_data == 0 ) avail++;
+		}
+
+		// update statistics
+		#if !defined(__CFA_NO_STATISTICS__)
+			ring.submit_q.stats.submit_avg.rdy += to_submit;
+			ring.submit_q.stats.submit_avg.csm += ret;
+			ring.submit_q.stats.submit_avg.avl += avail;
+			ring.submit_q.stats.submit_avg.cnt += 1;
+		#endif
+
 		// Drain the queue
 		unsigned head = *ring.completion_q.head;
-		unsigned tail = __atomic_load_n(ring.completion_q.tail, __ATOMIC_ACQUIRE);
+		unsigned tail = *ring.completion_q.tail;
+		const uint32_t mask = *ring.completion_q.mask;
+
+		// Memory barrier
+		__atomic_thread_fence( __ATOMIC_SEQ_CST );
 
 		// Nothing was new return 0
@@ -542,5 +599,5 @@
 		uint32_t count = tail - head;
 		for(i; count) {
-			unsigned idx = (head + i) & (*ring.completion_q.mask);
+			unsigned idx = (head + i) & mask;
 			struct io_uring_cqe & cqe = ring.completion_q.cqes[idx];
 
@@ -556,8 +613,9 @@
 
 		// Allow new submissions to happen
-		V(ring.submit, count);
+		// V(ring.submit, count);
 
 		// Mark to the kernel that the cqe has been seen
 		// Ensure that the kernel only sees the new value of the head index after the CQEs have been read.
+		__atomic_thread_fence( __ATOMIC_SEQ_CST );
 		__atomic_fetch_add( ring.completion_q.head, count, __ATOMIC_RELAXED );
 
@@ -710,19 +768,44 @@
 //
 
-	static inline [* struct io_uring_sqe, uint32_t] __submit_alloc( struct __io_data & ring ) {
-		// Wait for a spot to be available
-		__attribute__((unused)) bool blocked = P(ring.submit);
-		#if !defined(__CFA_NO_STATISTICS__)
-			__atomic_fetch_add( &ring.submit_q.stats.submit_avg.block, blocked ? 1ul64 : 0ul64, __ATOMIC_RELAXED );
-		#endif
-
-		// Allocate the sqe
-		uint32_t idx = __atomic_fetch_add(&ring.submit_q.alloc, 1ul32, __ATOMIC_SEQ_CST);
-
-		// Mask the idx now to allow make everything easier to check
-		idx &= *ring.submit_q.mask;
-
-		// Return the sqe
-		return [&ring.submit_q.sqes[ idx ], idx];
+	static inline [* struct io_uring_sqe, uint32_t] __submit_alloc( struct __io_data & ring, uint64_t data ) {
+		verify( data != 0 );
+
+		// Prepare the data we need
+		__attribute((unused)) int len   = 0;
+		__attribute((unused)) int block = 0;
+		uint32_t cnt = *ring.submit_q.num;
+		uint32_t mask = *ring.submit_q.mask;
+		uint32_t off = __tls_rand();
+
+		// Loop around looking for an available spot
+		LOOKING: for() {
+			// Look through the list starting at some offset
+			for(i; cnt) {
+				uint64_t expected = 0;
+				uint32_t idx = (i + off) & mask;
+				struct io_uring_sqe * sqe = &ring.submit_q.sqes[idx];
+				volatile uint64_t * udata = &sqe->user_data;
+
+				if( *udata == expected &&
+					__atomic_compare_exchange_n( udata, &expected, data, true, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED ) )
+				{
+					// update statistics
+					#if !defined(__CFA_NO_STATISTICS__)
+						__atomic_fetch_add( &ring.submit_q.stats.alloc_avg.val,   len,   __ATOMIC_RELAXED );
+						__atomic_fetch_add( &ring.submit_q.stats.alloc_avg.block, block, __ATOMIC_RELAXED );
+						__atomic_fetch_add( &ring.submit_q.stats.alloc_avg.cnt,   1,     __ATOMIC_RELAXED );
+					#endif
+
+					// Success return the data
+					return [sqe, idx];
+				}
+				verify(expected != data);
+
+				len ++;
+			}
+
+			block++;
+			yield();
+		}
 	}
 
@@ -742,5 +825,4 @@
 			__attribute((unused)) int len   = 0;
 			__attribute((unused)) int block = 0;
-			uint32_t expected = -1ul32;
 			uint32_t ready_mask = ring.submit_q.ready_cnt - 1;
 			uint32_t off = __tls_rand();
@@ -748,7 +830,9 @@
 				for(i; ring.submit_q.ready_cnt) {
 					uint32_t ii = (i + off) & ready_mask;
+					uint32_t expected = -1ul32;
 					if( __atomic_compare_exchange_n( &ring.submit_q.ready[ii], &expected, idx, true, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED ) ) {
 						break LOOKING;
 					}
+					verify(expected != idx);
 
 					len ++;
@@ -792,5 +876,5 @@
 			// update statistics
 			#if !defined(__CFA_NO_STATISTICS__)
-				ring.submit_q.stats.submit_avg.val += 1;
+				ring.submit_q.stats.submit_avg.csm += 1;
 				ring.submit_q.stats.submit_avg.cnt += 1;
 			#endif
@@ -831,13 +915,13 @@
 
 	#define __submit_prelude \
-		struct __io_data & ring = *active_cluster()->io; \
+		io_user_data data = { 0, active_thread() }; \
+		struct __io_data & ring = *data.thrd->curr_cluster->io; \
 		struct io_uring_sqe * sqe; \
 		uint32_t idx; \
-		[sqe, idx] = __submit_alloc( ring );
+		[sqe, idx] = __submit_alloc( ring, (uint64_t)&data );
 
 	#define __submit_wait \
-		io_user_data data = { 0, active_thread() }; \
 		/*__cfaabi_bits_print_safe( STDERR_FILENO, "Preparing user data %p for %p\n", &data, data.thrd );*/ \
-		sqe->user_data = (uint64_t)&data; \
+		verify( sqe->user_data == (uint64_t)&data ); \
 		__submit( ring, idx ); \
 		park( __cfaabi_dbg_ctx ); \
Index: libcfa/src/concurrency/kernel.cfa
===================================================================
--- libcfa/src/concurrency/kernel.cfa	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ libcfa/src/concurrency/kernel.cfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -648,4 +648,5 @@
 
 	// record activity
+	__cfaabi_dbg_debug_do( char * old_caller = thrd->unpark_caller; )
 	__cfaabi_dbg_record_thrd( *thrd, false, caller );
 
Index: libcfa/src/containers/list.hfa
===================================================================
--- libcfa/src/containers/list.hfa	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ libcfa/src/containers/list.hfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -301,4 +301,41 @@
 		$prev_link(list_pos) = (Telem*) 0p;
 	}
+
+	static inline bool ?`is_empty(dlist(Tnode, Telem) &list) {
+		assert( &list != 0p );
+		$dlinks(Telem) *listLinks = & list.$links;
+		if (listLinks->next.is_terminator) {
+			assert(listLinks->prev.is_terminator);
+			assert(listLinks->next.terminator);
+			assert(listLinks->prev.terminator);
+			return true;
+		} else {
+			assert(!listLinks->prev.is_terminator);
+			assert(listLinks->next.elem);
+			assert(listLinks->prev.elem);
+			return false;
+		}
+	}
+
+	static inline Telem & pop_first(dlist(Tnode, Telem) &list) {
+		assert( &list != 0p );
+		assert( !list`is_empty );
+		$dlinks(Telem) *listLinks = & list.$links;
+		Telem & first = *listLinks->next.elem;
+		Tnode & list_pos_first  = $tempcv_e2n( first );
+		remove(list_pos_first);
+		return first;
+	}
+
+	static inline Telem & pop_last(dlist(Tnode, Telem) &list) {
+		assert( &list != 0p );
+		assert( !list`is_empty );
+		$dlinks(Telem) *listLinks = & list.$links;
+		Telem & last = *listLinks->prev.elem;
+		Tnode & list_pos_last  = $tempcv_e2n( last );
+		remove(list_pos_last);
+		return last;
+	}
+
 }
 
Index: libcfa/src/containers/stackLockFree.hfa
===================================================================
--- libcfa/src/containers/stackLockFree.hfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
+++ libcfa/src/containers/stackLockFree.hfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -0,0 +1,64 @@
+// 
+// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// stackLockFree.hfa -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Wed May 13 20:58:58 2020
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon May 18 13:30:08 2020
+// Update Count     : 55
+// 
+
+#pragma once
+
+#include <stdint.h>
+
+forall( dtype T )
+union Link {
+	struct {									// 32/64-bit x 2
+		T * top;								// pointer to stack top
+		uintptr_t count;						// count each push
+	};
+	#if __SIZEOF_INT128__ == 16
+	__int128									// gcc, 128-bit integer
+	#else
+	uint64_t									// 64-bit integer
+	#endif // __SIZEOF_INT128__ == 16
+	atom;
+}; // Link
+
+forall( otype T | { Link(T) * getNext( T * ); } ) {
+    struct StackLF {
+		Link(T) stack;
+	}; // StackLF
+
+	static inline {
+		void ?{}( StackLF(T) & this ) with(this) { stack.atom = 0; }
+
+		T * top( StackLF(T) & this ) with(this) { return stack.top; }
+
+		void push( StackLF(T) & this, T & n ) with(this) {
+			for () {									// busy wait
+				*getNext( &n ) = stack;					// atomic assignment unnecessary, or use CAA
+			  if ( __atomic_compare_exchange_n( &stack.atom, &getNext( &n )->atom, (Link(T))@{ {&n, getNext( &n )->count + 1} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) break; // attempt to update top node
+			} // for
+		} // push
+
+		T * pop( StackLF(T) & this ) with(this) {
+			Link(T) t @= {};
+			for () {									// busy wait
+				t = stack;								// atomic assignment unnecessary, or use CAA
+			  if ( t.top == 0p ) return 0p;				// empty stack ?
+			  if ( __atomic_compare_exchange_n( &stack.atom, &t.atom, (Link(T))@{ {getNext( t.top )->top, t.count} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) return t.top; // attempt to update top node
+			} // for
+		} // pop
+	} // distribution
+} // distribution
+
+
+// Local Variables: //
+// tab-width: 4 //
+// End: //
Index: libcfa/src/exception.c
===================================================================
--- libcfa/src/exception.c	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ libcfa/src/exception.c	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -10,6 +10,6 @@
 // Created On       : Mon Jun 26 15:13:00 2017
 // Last Modified By : Andrew Beach
-// Last Modified On : Tue Apr 14 12:01:00 2020
-// Update Count     : 18
+// Last Modified On : Thr May 21 12:18:00 2020
+// Update Count     : 20
 //
 
@@ -80,5 +80,5 @@
 }
 
-void __cfaehm_throw_resume(exception_t * except) {
+void __cfaehm_throw_resume(exception_t * except, void (*defaultHandler)(exception_t *)) {
 	struct exception_context_t * context = this_exception_context();
 
@@ -96,9 +96,7 @@
 	}
 
+	// No handler found, fall back to the default operation.
 	__cfadbg_print_safe(exception, "Unhandled exception\n");
-
-	// Fall back to termination:
-	__cfaehm_throw_terminate(except);
-	// TODO: Default handler for resumption.
+	defaultHandler(except);
 }
 
@@ -223,6 +221,5 @@
 
 // Cancel the current stack, prefroming approprate clean-up and messaging.
-static __attribute__((noreturn)) void __cfaehm_cancel_stack(
-		exception_t * exception ) {
+void __cfaehm_cancel_stack( exception_t * exception ) {
 	// TODO: Detect current stack and pick a particular stop-function.
 	_Unwind_Reason_Code ret;
@@ -240,7 +237,14 @@
 }
 
+static void __cfaehm_cleanup_default( exception_t ** except ) {
+	__cfaehm_delete_exception( *except );
+	*except = NULL;
+}
+
 // The exception that is being thrown must already be stored.
-static __attribute__((noreturn)) void __cfaehm_begin_unwind(void) {
-	if ( ! this_exception_context()->current_exception ) {
+static void __cfaehm_begin_unwind(void(*defaultHandler)(exception_t *)) {
+	struct exception_context_t * context = this_exception_context();
+	struct _Unwind_Exception * storage = &this_exception_storage;
+	if ( NULL == context->current_exception ) {
 		printf("UNWIND ERROR missing exception in begin unwind\n");
 		abort();
@@ -248,5 +252,6 @@
 
 	// Call stdlibc to raise the exception
-	_Unwind_Reason_Code ret = _Unwind_RaiseException( &this_exception_storage );
+	__cfadbg_print_safe(exception, "Begin unwinding (storage &p, context %p)\n", storage, context);
+	_Unwind_Reason_Code ret = _Unwind_RaiseException( storage );
 
 	// If we reach here it means something happened. For resumption to work we need to find a way
@@ -257,22 +262,29 @@
 	// the whole stack.
 
+	// We did not simply reach the end of the stack without finding a handler. This is an error.
+	if ( ret != _URC_END_OF_STACK ) {
+		printf("UNWIND ERROR %d after raise exception\n", ret);
+		abort();
+	}
+
 	// No handler found, go to the default operation.
-	// Currently this will always be a cancellation.
-	if ( ret == _URC_END_OF_STACK ) {
-		__cfadbg_print_safe(exception, "Uncaught exception %p\n", &this_exception_storage);
-
-		__cfaehm_cancel_stack(this_exception_context()->current_exception);
-	}
-
-	// We did not simply reach the end of the stack without finding a handler. This is an error.
-	printf("UNWIND ERROR %d after raise exception\n", ret);
+	__cfadbg_print_safe(exception, "Uncaught exception %p\n", storage);
+
+	__attribute__((cleanup(__cfaehm_cleanup_default)))
+	exception_t * exception = context->current_exception;
+	defaultHandler( exception );
+}
+
+void __cfaehm_throw_terminate( exception_t * val, void (*defaultHandler)(exception_t *) ) {
+	__cfadbg_print_safe(exception, "Throwing termination exception\n");
+
+	__cfaehm_allocate_exception( val );
+	__cfaehm_begin_unwind( defaultHandler );
+}
+
+static __attribute__((noreturn)) void __cfaehm_rethrow_adapter( exception_t * except ) {
+	// TODO: Print some error message.
+	(void)except;
 	abort();
-}
-
-void __cfaehm_throw_terminate( exception_t * val ) {
-	__cfadbg_print_safe(exception, "Throwing termination exception\n");
-
-	__cfaehm_allocate_exception( val );
-	__cfaehm_begin_unwind();
 }
 
@@ -280,5 +292,6 @@
 	__cfadbg_print_safe(exception, "Rethrowing termination exception\n");
 
-	__cfaehm_begin_unwind();
+	__cfaehm_begin_unwind( __cfaehm_rethrow_adapter );
+	abort();
 }
 
Index: libcfa/src/exception.h
===================================================================
--- libcfa/src/exception.h	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ libcfa/src/exception.h	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -10,6 +10,6 @@
 // Created On       : Mon Jun 26 15:11:00 2017
 // Last Modified By : Andrew Beach
-// Last Modified On : Fri Mar 27 10:16:00 2020
-// Update Count     : 9
+// Last Modified On : Tue May 19 14:17:00 2020
+// Update Count     : 10
 //
 
@@ -38,8 +38,10 @@
 
 
+void __cfaehm_cancel_stack(exception_t * except) __attribute__((noreturn));
+
 // Used in throw statement translation.
-void __cfaehm_throw_terminate(exception_t * except) __attribute__((noreturn));
+void __cfaehm_throw_terminate(exception_t * except, void (*)(exception_t *));
 void __cfaehm_rethrow_terminate() __attribute__((noreturn));
-void __cfaehm_throw_resume(exception_t * except);
+void __cfaehm_throw_resume(exception_t * except, void (*)(exception_t *));
 
 // Function catches termination exceptions.
@@ -70,3 +72,54 @@
 #ifdef __cforall
 }
+
+// Not all the built-ins can be expressed in C. These can't be
+// implemented in the .c file either so they all have to be inline.
+
+trait is_exception(dtype T) {
+	/* The first field must be a pointer to a virtual table.
+	 * That virtual table must be a decendent of the base exception virtual tab$
+	 */
+	void mark_exception(T *);
+	// This is never used and should be a no-op.
+};
+
+trait is_termination_exception(dtype T | is_exception(T)) {
+	void defaultTerminationHandler(T &);
+};
+
+trait is_resumption_exception(dtype T | is_exception(T)) {
+	void defaultResumptionHandler(T &);
+};
+
+forall(dtype T | is_termination_exception(T))
+static inline void $throw(T & except) {
+	__cfaehm_throw_terminate(
+		(exception_t *)&except,
+		(void(*)(exception_t *))defaultTerminationHandler
+	);
+}
+
+forall(dtype T | is_resumption_exception(T))
+static inline void $throwResume(T & except) {
+	__cfaehm_throw_resume(
+		(exception_t *)&except,
+		(void(*)(exception_t *))defaultResumptionHandler
+	);
+}
+
+forall(dtype T | is_exception(T))
+static inline void cancel_stack(T & except) __attribute__((noreturn)) {
+	__cfaehm_cancel_stack( (exception_t *)&except );
+}
+
+forall(dtype T | is_exception(T))
+static inline void defaultTerminationHandler(T & except) {
+	return cancel_stack( except );
+}
+
+forall(dtype T | is_exception(T))
+static inline void defaultResumptionHandler(T & except) {
+	throw except;
+}
+
 #endif
Index: libcfa/src/exception.hfa
===================================================================
--- libcfa/src/exception.hfa	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ libcfa/src/exception.hfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -10,6 +10,6 @@
 // Created On       : Thu Apr  7 10:25:00 2020
 // Last Modified By : Andrew Beach
-// Last Modified On : Thu Apr  7 10:25:00 2020
-// Update Count     : 0
+// Last Modified On : Tue May 19 14:17:00 2020
+// Update Count     : 2
 //
 
@@ -69,4 +69,5 @@
 #define _VTABLE_DECLARATION(exception_name, parent_name, ...) \
 	struct exception_name; \
+	void mark_exception(exception_name *); \
 	VTABLE_TYPE(exception_name); \
 	extern VTABLE_TYPE(exception_name) VTABLE_NAME(exception_name); \
@@ -85,4 +86,5 @@
 #define VTABLE_INSTANCE(...) _EXC_DISPATCH(_VTABLE_INSTANCE, __VA_ARGS__)
 #define _VTABLE_INSTANCE(exception_name, parent_name, ...) \
+	void mark_exception(exception_name *) {} \
 	void _GLUE2(exception_name,_copy)(exception_name * this, exception_name * other) { \
 		*this = *other; \
Index: libcfa/src/executor.cfa
===================================================================
--- libcfa/src/executor.cfa	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ libcfa/src/executor.cfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -4,35 +4,33 @@
 // buffer.
 
-#include <bits/containers.hfa>
+#include <containers/list.hfa>
 #include <thread.hfa>
 #include <stdio.h>
 
-forall( dtype T )
-monitor Buffer {					// unbounded buffer
-    __queue_t( T ) queue;				// unbounded list of work requests
-    condition delay;
-}; // Buffer
-forall( dtype T | is_node(T) ) {
-    void insert( Buffer( T ) & mutex buf, T * elem ) with(buf) {
-	append( queue, elem );				// insert element into buffer
-	signal( delay );				// restart
-    } // insert
-
-    T * remove( Buffer( T ) & mutex buf ) with(buf) {
-	if ( queue.head != 0 ) wait( delay );			// no request to process ? => wait
-//	return pop_head( queue );
-    } // remove
-} // distribution
-
 struct WRequest {					// client request, no return
     void (* action)( void );
-    WRequest * next;					// intrusive queue field
+    DLISTED_MGD_IMPL_IN(WRequest)
 }; // WRequest
+DLISTED_MGD_IMPL_OUT(WRequest)
 
-WRequest *& get_next( WRequest & this ) { return this.next; }
-void ?{}( WRequest & req ) with(req) { action = 0; next = 0; }
-void ?{}( WRequest & req, void (* action)( void ) ) with(req) { req.action = action; next = 0; }
+void ?{}( WRequest & req ) with(req) { action = 0; }
+void ?{}( WRequest & req, void (* action)( void ) ) with(req) { req.action = action; }
 bool stop( WRequest & req ) { return req.action == 0; }
 void doit( WRequest & req ) { req.action(); }
+
+monitor WRBuffer {					// unbounded buffer
+    dlist( WRequest, WRequest ) queue;			// unbounded list of work requests
+    condition delay;
+}; // WRBuffer
+
+void insert( WRBuffer & mutex buf, WRequest * elem ) with(buf) {
+    insert_last( queue, *elem );			// insert element into buffer
+    signal( delay );				        // restart
+} // insert
+
+WRequest * remove( WRBuffer & mutex buf ) with(buf) {
+    if ( queue`is_empty ) wait( delay );	        // no request to process ? => wait
+    return & pop_first( queue );
+} // remove
 
 // Each worker has its own work buffer to reduce contention between client and server. Hence, work requests arrive and
@@ -40,5 +38,5 @@
 
 thread Worker {
-    Buffer( WRequest ) * requests;
+    WRBuffer * requests;
     unsigned int start, range;
 }; // Worker
@@ -54,5 +52,5 @@
 } // Worker::main
 
-void ?{}( Worker & worker, cluster * wc, Buffer( WRequest ) * requests, unsigned int start, unsigned int range ) {
+void ?{}( Worker & worker, cluster * wc, WRBuffer * requests, unsigned int start, unsigned int range ) {
     (*get_thread(worker)){ *wc };			// create on given cluster
     worker.[requests, start, range] = [requests, start, range];
@@ -62,5 +60,5 @@
     cluster * cluster;					// if workers execute on separate cluster
     processor ** processors;				// array of virtual processors adding parallelism for workers
-    Buffer( WRequest ) * requests;			// list of work requests
+    WRBuffer * requests;			        // list of work requests
     Worker ** workers;					// array of workers executing work requests
     unsigned int nprocessors, nworkers, nmailboxes;	// number of mailboxes/workers/processor tasks
@@ -79,5 +77,5 @@
     cluster = sepClus ? new( "Executor" ) : active_cluster();
     processors = (processor **)anew( nprocessors );
-    requests = anew( nmailboxes );
+    requests = (WRBuffer *)anew( nmailboxes );
     workers = (Worker **)anew( nworkers );
 
@@ -141,5 +139,8 @@
 	for ( i; 3000 ) {
 	    send( exector, workie );
-	    if ( i % 100 ) yield();
+	    if ( i % 100 == 0 ) {
+//              fprintf( stderr, "%d\n", i );
+                yield();
+            }
 	} // for
     }
Index: libcfa/src/heap.cfa
===================================================================
--- libcfa/src/heap.cfa	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ libcfa/src/heap.cfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -10,6 +10,6 @@
 // Created On       : Tue Dec 19 21:58:35 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed May  6 17:29:26 2020
-// Update Count     : 727
+// Last Modified On : Sun May 17 20:58:17 2020
+// Update Count     : 762
 //
 
@@ -128,6 +128,9 @@
 #define LOCKFREE 1
 #define BUCKETLOCK SPINLOCK
-#if BUCKETLOCK == LOCKFREE
-#include <uStackLF.h>
+#if BUCKETLOCK == SPINLOCK
+#elif BUCKETLOCK == LOCKFREE
+#include <stackLockFree.hfa>
+#else
+	#error undefined lock type for bucket lock
 #endif // LOCKFREE
 
@@ -137,6 +140,4 @@
 
 struct HeapManager {
-//	struct FreeHeader;									// forward declaration
-
 	struct Storage {
 		struct Header {									// header
@@ -146,31 +147,31 @@
 						struct {						// 4-byte word => 8-byte header, 8-byte word => 16-byte header
 							#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __SIZEOF_POINTER__ == 4
-							uint32_t padding;			// unused, force home/blocksize to overlay alignment in fake header
+							uint64_t padding;			// unused, force home/blocksize to overlay alignment in fake header
 							#endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __SIZEOF_POINTER__ == 4
 
 							union {
-//								FreeHeader * home;		// allocated block points back to home locations (must overlay alignment)
+								// FreeHeader * home;		// allocated block points back to home locations (must overlay alignment)
 								// 2nd low-order bit => zero filled
 								void * home;			// allocated block points back to home locations (must overlay alignment)
 								size_t blockSize;		// size for munmap (must overlay alignment)
-								#if BUCKLOCK == SPINLOCK
+								#if BUCKETLOCK == SPINLOCK
 								Storage * next;			// freed block points next freed block of same size
 								#endif // SPINLOCK
 							};
+							size_t size;				// allocation size in bytes
 
 							#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_POINTER__ == 4
-							uint32_t padding;			// unused, force home/blocksize to overlay alignment in fake header
+							uint64_t padding;			// unused, force home/blocksize to overlay alignment in fake header
 							#endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && __SIZEOF_POINTER__ == 4
 						};
-						// future code
-						#if BUCKLOCK == LOCKFREE
-						Stack<Storage>::Link next;		// freed block points next freed block of same size (double-wide)
+						#if BUCKETLOCK == LOCKFREE
+						Link(Storage) next;				// freed block points next freed block of same size (double-wide)
 						#endif // LOCKFREE
 					};
 				} real; // RealHeader
+
 				struct FakeHeader {
 					#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-					// 1st low-order bit => fake header & alignment
-					uint32_t alignment;
+					uint32_t alignment;					// 1st low-order bit => fake header & alignment
 					#endif // __ORDER_LITTLE_ENDIAN__
 
@@ -182,5 +183,4 @@
 				} fake; // FakeHeader
 			} kind; // Kind
-			size_t size;								// allocation size in bytes
 		} header; // Header
 		char pad[libAlign() - sizeof( Header )];
@@ -191,13 +191,10 @@
 
 	struct FreeHeader {
-		#if BUCKLOCK == SPINLOCK
+		#if BUCKETLOCK == SPINLOCK
 		__spinlock_t lock;								// must be first field for alignment
 		Storage * freeList;
-		#elif BUCKLOCK == LOCKFREE
-		// future code
-		StackLF<Storage> freeList;
 		#else
-			#error undefined lock type for bucket lock
-		#endif // SPINLOCK
+		StackLF(Storage) freeList;
+		#endif // BUCKETLOCK
 		size_t blockSize;								// size of allocations on this list
 	}; // FreeHeader
@@ -211,4 +208,10 @@
 	size_t heapRemaining;								// amount of storage not allocated in the current chunk
 }; // HeapManager
+
+#if BUCKETLOCK == LOCKFREE
+static inline Link(HeapManager.Storage) * getNext( HeapManager.Storage * this ) { return &this->header.kind.real.next; }
+static inline void ?{}( HeapManager.FreeHeader & ) {}
+static inline void ^?{}( HeapManager.FreeHeader & ) {}
+#endif // LOCKFREE
 
 static inline size_t getKey( const HeapManager.FreeHeader & freeheader ) { return freeheader.blockSize; }
@@ -251,4 +254,6 @@
 static bool heapBoot = 0;								// detect recursion during boot
 #endif // __CFA_DEBUG__
+
+// The constructor for heapManager is called explicitly in memory_startup.
 static HeapManager heapManager __attribute__(( aligned (128) )) @= {}; // size of cache line to prevent false sharing
 
@@ -354,11 +359,4 @@
 
 
-// static inline void noMemory() {
-// 	abort( "Heap memory exhausted at %zu bytes.\n"
-// 		   "Possible cause is very large memory allocation and/or large amount of unfreed storage allocated by the program or system/library routines.",
-// 		   ((char *)(sbrk( 0 )) - (char *)(heapManager.heapBegin)) );
-// } // noMemory
-
-
 // thunk problem
 size_t Bsearchl( unsigned int key, const unsigned int * vals, size_t dim ) {
@@ -406,4 +404,11 @@
 
 
+// static inline void noMemory() {
+// 	abort( "Heap memory exhausted at %zu bytes.\n"
+// 		   "Possible cause is very large memory allocation and/or large amount of unfreed storage allocated by the program or system/library routines.",
+// 		   ((char *)(sbrk( 0 )) - (char *)(heapManager.heapBegin)) );
+// } // noMemory
+
+
 static inline void checkAlign( size_t alignment ) {
 	if ( alignment < libAlign() || ! libPow2( alignment ) ) {
@@ -433,5 +438,6 @@
 
 
-static inline bool headers( const char name[] __attribute__(( unused )), void * addr, HeapManager.Storage.Header *& header, HeapManager.FreeHeader *& freeElem, size_t & size, size_t & alignment ) with ( heapManager ) {
+static inline bool headers( const char name[] __attribute__(( unused )), void * addr, HeapManager.Storage.Header *& header, HeapManager.FreeHeader *& freeElem,
+							size_t & size, size_t & alignment ) with( heapManager ) {
 	header = headerAddr( addr );
 
@@ -465,5 +471,5 @@
 
 
-static inline void * extend( size_t size ) with ( heapManager ) {
+static inline void * extend( size_t size ) with( heapManager ) {
 	lock( extlock __cfaabi_dbg_ctx2 );
 	ptrdiff_t rem = heapRemaining - size;
@@ -496,5 +502,5 @@
 
 
-static inline void * doMalloc( size_t size ) with ( heapManager ) {
+static inline void * doMalloc( size_t size ) with( heapManager ) {
 	HeapManager.Storage * block;						// pointer to new block of storage
 
@@ -529,14 +535,14 @@
 		// Spin until the lock is acquired for this particular size of block.
 
-		#if defined( SPINLOCK )
+		#if BUCKETLOCK == SPINLOCK
 		lock( freeElem->lock __cfaabi_dbg_ctx2 );
 		block = freeElem->freeList;						// remove node from stack
 		#else
-		block = freeElem->freeList.pop();
-		#endif // SPINLOCK
+		block = pop( freeElem->freeList );
+		#endif // BUCKETLOCK
 		if ( unlikely( block == 0p ) ) {				// no free block ?
-			#if defined( SPINLOCK )
+			#if BUCKETLOCK == SPINLOCK
 			unlock( freeElem->lock );
-			#endif // SPINLOCK
+			#endif // BUCKETLOCK
 
 			// Freelist for that size was empty, so carve it out of the heap if there's enough left, or get some more
@@ -544,10 +550,10 @@
 
 			block = (HeapManager.Storage *)extend( tsize );	// mutual exclusion on call
-  if ( unlikely( block == 0p ) ) return 0p;
-		#if defined( SPINLOCK )
+	if ( unlikely( block == 0p ) ) return 0p;
+		#if BUCKETLOCK == SPINLOCK
 		} else {
 			freeElem->freeList = block->header.kind.real.next;
 			unlock( freeElem->lock );
-		#endif // SPINLOCK
+		#endif // BUCKETLOCK
 		} // if
 
@@ -572,5 +578,5 @@
 	} // if
 
-	block->header.size = size;							// store allocation size
+	block->header.kind.real.size = size;				// store allocation size
 	void * addr = &(block->data);						// adjust off header to user bytes
 
@@ -591,5 +597,5 @@
 
 
-static inline void doFree( void * addr ) with ( heapManager ) {
+static inline void doFree( void * addr ) with( heapManager ) {
 	#ifdef __CFA_DEBUG__
 	if ( unlikely( heapManager.heapBegin == 0p ) ) {
@@ -623,5 +629,5 @@
 		free_storage += size;
 		#endif // __STATISTICS__
-		#if defined( SPINLOCK )
+		#if BUCKETLOCK == SPINLOCK
 		lock( freeElem->lock __cfaabi_dbg_ctx2 );		// acquire spin lock
 		header->kind.real.next = freeElem->freeList;	// push on stack
@@ -629,6 +635,6 @@
 		unlock( freeElem->lock );						// release spin lock
 		#else
-		freeElem->freeList.push( *(HeapManager.Storage *)header );
-		#endif // SPINLOCK
+		push( freeElem->freeList, *(HeapManager.Storage *)header );
+		#endif // BUCKETLOCK
 	} // if
 
@@ -645,5 +651,5 @@
 
 
-size_t prtFree( HeapManager & manager ) with ( manager ) {
+size_t prtFree( HeapManager & manager ) with( manager ) {
 	size_t total = 0;
 	#ifdef __STATISTICS__
@@ -657,9 +663,11 @@
 		#endif // __STATISTICS__
 
-		#if defined( SPINLOCK )
+		#if BUCKETLOCK == SPINLOCK
 		for ( HeapManager.Storage * p = freeLists[i].freeList; p != 0p; p = p->header.kind.real.next ) {
 		#else
-		for ( HeapManager.Storage * p = freeLists[i].freeList.top(); p != 0p; p = p->header.kind.real.next.top ) {
-		#endif // SPINLOCK
+		for ( HeapManager.Storage * p = top( freeLists[i].freeList ); p != 0p; /* p = getNext( p )->top */) {
+			typeof(p) temp = getNext( p )->top;			// FIX ME: direct assignent fails, initialization works
+			p = temp;
+		#endif // BUCKETLOCK
 			total += size;
 			#ifdef __STATISTICS__
@@ -681,5 +689,5 @@
 
 
-static void ?{}( HeapManager & manager ) with ( manager ) {
+static void ?{}( HeapManager & manager ) with( manager ) {
 	pageSize = sysconf( _SC_PAGESIZE );
 
@@ -1095,5 +1103,5 @@
 			header = realHeader( header );				// backup from fake to real header
 		} // if
-		return header->size;
+		return header->kind.real.size;
 	} // malloc_size
 
@@ -1105,6 +1113,6 @@
 			header = realHeader( header );				// backup from fake to real header
 		} // if
-		size_t ret = header->size;
-		header->size = size;
+		size_t ret = header->kind.real.size;
+		header->kind.real.size = size;
 		return ret;
 	} // $malloc_size_set
Index: libcfa/src/stdlib.hfa
===================================================================
--- libcfa/src/stdlib.hfa	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ libcfa/src/stdlib.hfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -10,6 +10,6 @@
 // Created On       : Thu Jan 28 17:12:35 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Apr 16 22:44:05 2020
-// Update Count     : 432
+// Last Modified On : Wed May 13 17:23:51 2020
+// Update Count     : 435
 //
 
@@ -23,11 +23,13 @@
 // Reduce includes by explicitly defining these routines.
 extern "C" {
+	void * aalloc( size_t dim, size_t elemSize );		// CFA heap
+	void * resize( void * oaddr, size_t size );			// CFA heap
 	void * memalign( size_t align, size_t size );		// malloc.h
+	void * amemalign( size_t align, size_t dim, size_t elemSize ); // CFA heap
+	void * cmemalign( size_t align, size_t noOfElems, size_t elemSize ); // CFA heap
+	size_t malloc_size( void * addr );					// CFA heap
 	size_t malloc_usable_size( void * ptr );			// malloc.h
-	size_t malloc_size( void * addr );					// CFA heap
-	void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); // CFA heap
 	void * memset( void * dest, int fill, size_t size ); // string.h
 	void * memcpy( void * dest, const void * src, size_t size ); // string.h
-	void * resize( void * oaddr, size_t size );			// CFA heap
 } // extern "C"
 
@@ -52,4 +54,9 @@
 	} // malloc
 
+	T * aalloc( size_t dim ) {
+		if ( _Alignof(T) <= libAlign() ) return (T *)(void *)aalloc( dim, (size_t)sizeof(T) ); // CFA aalloc
+		else return (T *)amemalign( _Alignof(T), dim, sizeof(T) );
+	} // aalloc
+
 	T * calloc( size_t dim ) {
 		if ( _Alignof(T) <= libAlign() )return (T *)(void *)calloc( dim, sizeof(T) ); // C calloc
@@ -57,4 +64,8 @@
 	} // calloc
 
+	T * resize( T * ptr, size_t size ) {				// CFA realloc, eliminate return-type cast
+		return (T *)(void *)resize( (void *)ptr, size ); // C realloc
+	} // resize
+
 	T * realloc( T * ptr, size_t size ) {				// CFA realloc, eliminate return-type cast
 		return (T *)(void *)realloc( (void *)ptr, size ); // C realloc
@@ -65,4 +76,8 @@
 	} // memalign
 
+	T * amemalign( size_t align, size_t dim ) {
+		return (T *)amemalign( align, dim, sizeof(T) );	// CFA amemalign
+	} // amemalign
+
 	T * cmemalign( size_t align, size_t dim  ) {
 		return (T *)cmemalign( align, dim, sizeof(T) );	// CFA cmemalign
@@ -86,6 +101,5 @@
 
 	T * alloc( size_t dim ) {
-		if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( dim * (size_t)sizeof(T) );
-		else return (T *)memalign( _Alignof(T), dim * sizeof(T) );
+		return aalloc( dim );
 	} // alloc
 
@@ -106,6 +120,5 @@
 			return (T *)(void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
 		} else {
-			struct __Unknown {};
-			return alloc( (__Unknown *)ptr, dim );		// reuse, cheat making T/S different types
+			return resize( ptr, dim * sizeof(T) );		// resize
 		} // if
 	} // alloc
@@ -148,5 +161,5 @@
 	} // alloc_align
 
-	T * alloc_align( T ptr[], size_t align ) {			// aligned realloc array
+	T * alloc_align( T * ptr, size_t align ) {			// aligned realloc array
 		return (T *)(void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc
 	} // alloc_align
Index: src/ControlStruct/ExceptTranslate.cc
===================================================================
--- src/ControlStruct/ExceptTranslate.cc	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ src/ControlStruct/ExceptTranslate.cc	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -10,6 +10,6 @@
 // Created On       : Wed Jun 14 16:49:00 2017
 // Last Modified By : Andrew Beach
-// Last Modified On : Fri Mar 27 11:58:00 2020
-// Update Count     : 13
+// Last Modified On : Thr May 21 13:18:00 2020
+// Update Count     : 15
 //
 
@@ -64,16 +64,123 @@
 	}
 
-	class ExceptionMutatorCore : public WithGuards {
-		enum Context { NoHandler, TerHandler, ResHandler };
-
-		// Also need to handle goto, break & continue.
-		// They need to be cut off in a ResHandler, until we enter another
-		// loop, switch or the goto stays within the function.
-
-		Context cur_context;
-
-		// The current (innermost) termination handler exception declaration.
-		ObjectDecl * handler_except_decl;
-
+	class ThrowMutatorCore : public WithGuards {
+		ObjectDecl * terminate_handler_except;
+		enum Context { NoHandler, TerHandler, ResHandler } cur_context;
+
+		// The helper functions for code/syntree generation.
+		Statement * create_either_throw(
+			ThrowStmt * throwStmt, const char * throwFunc );
+		Statement * create_terminate_rethrow( ThrowStmt * throwStmt );
+		Statement * create_resume_rethrow( ThrowStmt * throwStmt );
+
+	public:
+		ThrowMutatorCore() :
+			terminate_handler_except( nullptr ),
+			cur_context( NoHandler )
+		{}
+
+		void premutate( CatchStmt *catchStmt );
+		Statement * postmutate( ThrowStmt *throwStmt );
+	};
+
+	// ThrowStmt Mutation Helpers
+
+	Statement * ThrowMutatorCore::create_either_throw(
+			ThrowStmt * throwStmt, const char * throwFunc ) {
+		// `throwFunc`( `throwStmt->get_name()` );
+		UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) );
+		call->get_args().push_back( throwStmt->get_expr() );
+		throwStmt->set_expr( nullptr );
+		delete throwStmt;
+		return new ExprStmt( call );
+	}
+
+	Statement * ThrowMutatorCore::create_terminate_rethrow(
+			ThrowStmt *throwStmt ) {
+		// { `terminate_handler_except` = 0p; __rethrow_terminate(); }
+		assert( nullptr == throwStmt->get_expr() );
+		assert( terminate_handler_except );
+
+		CompoundStmt * result = new CompoundStmt();
+		result->labels =  throwStmt->labels;
+		result->push_back( new ExprStmt( UntypedExpr::createAssign(
+			nameOf( terminate_handler_except ),
+			new ConstantExpr( Constant::null(
+				//new PointerType(
+				//	noQualifiers,
+					terminate_handler_except->get_type()->clone()
+				//	)
+				) )
+			) ) );
+		result->push_back( new ExprStmt(
+			new UntypedExpr( new NameExpr( "__cfaehm_rethrow_terminate" ) )
+			) );
+		delete throwStmt;
+		return result;
+	}
+
+	Statement * ThrowMutatorCore::create_resume_rethrow(
+			ThrowStmt *throwStmt ) {
+		// return false;
+		Statement * result = new ReturnStmt(
+			new ConstantExpr( Constant::from_bool( false ) )
+			);
+		result->labels = throwStmt->labels;
+		delete throwStmt;
+		return result;
+	}
+
+	// Visiting/Mutating Functions
+
+	void ThrowMutatorCore::premutate( CatchStmt *catchStmt ) {
+		// Validate the statement's form.
+		ObjectDecl * decl = dynamic_cast<ObjectDecl *>( catchStmt->get_decl() );
+		// Also checking the type would be nice.
+		if ( decl ) {
+			// Pass.
+		} else if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
+			SemanticError(catchStmt->location, "catch must have exception type");
+		} else {
+			SemanticError(catchStmt->location, "catchResume must have exception type");
+		}
+
+		// Track the handler context.
+		GuardValue( cur_context );
+		if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
+			cur_context = TerHandler;
+
+			GuardValue( terminate_handler_except );
+			terminate_handler_except = decl;
+		} else {
+			cur_context = ResHandler;
+		}
+	}
+
+	Statement * ThrowMutatorCore::postmutate( ThrowStmt *throwStmt ) {
+		// Ignoring throwStmt->get_target() for now.
+		if ( ThrowStmt::Terminate == throwStmt->get_kind() ) {
+			if ( throwStmt->get_expr() ) {
+				return create_either_throw( throwStmt, "$throw" );
+			} else if ( TerHandler == cur_context ) {
+				return create_terminate_rethrow( throwStmt );
+			} else {
+				abort("Invalid throw in %s at %i\n",
+					throwStmt->location.filename.c_str(),
+					throwStmt->location.first_line);
+			}
+		} else {
+			if ( throwStmt->get_expr() ) {
+				return create_either_throw( throwStmt, "$throwResume" );
+			} else if ( ResHandler == cur_context ) {
+				return create_resume_rethrow( throwStmt );
+			} else {
+				abort("Invalid throwResume in %s at %i\n",
+					throwStmt->location.filename.c_str(),
+					throwStmt->location.first_line);
+			}
+		}
+	}
+
+	class TryMutatorCore {
 		// The built in types used in translation.
 		StructDecl * except_decl;
@@ -82,10 +189,4 @@
 
 		// The many helper functions for code/syntree generation.
-		Statement * create_given_throw(
-			const char * throwFunc, ThrowStmt * throwStmt );
-		Statement * create_terminate_throw( ThrowStmt * throwStmt );
-		Statement * create_terminate_rethrow( ThrowStmt * throwStmt );
-		Statement * create_resume_throw( ThrowStmt * throwStmt );
-		Statement * create_resume_rethrow( ThrowStmt * throwStmt );
 		CompoundStmt * take_try_block( TryStmt * tryStmt );
 		FunctionDecl * create_try_wrapper( CompoundStmt * body );
@@ -121,7 +222,5 @@
 
 	public:
-		ExceptionMutatorCore() :
-			cur_context( NoHandler ),
-			handler_except_decl( nullptr ),
+		TryMutatorCore() :
 			except_decl( nullptr ), node_decl( nullptr ), hook_decl( nullptr ),
 			try_func_t( noQualifiers, false ),
@@ -132,5 +231,4 @@
 		{}
 
-		void premutate( CatchStmt *catchStmt );
 		void premutate( StructDecl *structDecl );
 		Statement * postmutate( ThrowStmt *throwStmt );
@@ -138,5 +236,5 @@
 	};
 
-	void ExceptionMutatorCore::init_func_types() {
+	void TryMutatorCore::init_func_types() {
 		assert( except_decl );
 
@@ -196,66 +294,7 @@
 	}
 
-	// ThrowStmt Mutation Helpers
-
-	Statement * ExceptionMutatorCore::create_given_throw(
-			const char * throwFunc, ThrowStmt * throwStmt ) {
-		// `throwFunc`( `throwStmt->get_name` );
-		UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) );
-		call->get_args().push_back( throwStmt->get_expr() );
-		throwStmt->set_expr( nullptr );
-		delete throwStmt;
-		return new ExprStmt( call );
-	}
-
-	Statement * ExceptionMutatorCore::create_terminate_throw(
-			ThrowStmt *throwStmt ) {
-		// __throw_terminate( `throwStmt->get_name()` ); }
-		return create_given_throw( "__cfaehm_throw_terminate", throwStmt );
-	}
-
-	Statement * ExceptionMutatorCore::create_terminate_rethrow(
-			ThrowStmt *throwStmt ) {
-		// { `handler_except_decl` = NULL; __rethrow_terminate(); }
-		assert( nullptr == throwStmt->get_expr() );
-		assert( handler_except_decl );
-
-		CompoundStmt * result = new CompoundStmt();
-		result->labels =  throwStmt->labels;
-		result->push_back( new ExprStmt( UntypedExpr::createAssign(
-			nameOf( handler_except_decl ),
-			new ConstantExpr( Constant::null(
-				new PointerType(
-					noQualifiers,
-					handler_except_decl->get_type()->clone()
-					)
-				) )
-			) ) );
-		result->push_back( new ExprStmt(
-			new UntypedExpr( new NameExpr( "__cfaehm_rethrow_terminate" ) )
-			) );
-		delete throwStmt;
-		return result;
-	}
-
-	Statement * ExceptionMutatorCore::create_resume_throw(
-			ThrowStmt *throwStmt ) {
-		// __throw_resume( `throwStmt->get_name` );
-		return create_given_throw( "__cfaehm_throw_resume", throwStmt );
-	}
-
-	Statement * ExceptionMutatorCore::create_resume_rethrow(
-			ThrowStmt *throwStmt ) {
-		// return false;
-		Statement * result = new ReturnStmt(
-			new ConstantExpr( Constant::from_bool( false ) )
-			);
-		result->labels = throwStmt->labels;
-		delete throwStmt;
-		return result;
-	}
-
 	// TryStmt Mutation Helpers
 
-	CompoundStmt * ExceptionMutatorCore::take_try_block( TryStmt *tryStmt ) {
+	CompoundStmt * TryMutatorCore::take_try_block( TryStmt *tryStmt ) {
 		CompoundStmt * block = tryStmt->get_block();
 		tryStmt->set_block( nullptr );
@@ -263,5 +302,5 @@
 	}
 
-	FunctionDecl * ExceptionMutatorCore::create_try_wrapper(
+	FunctionDecl * TryMutatorCore::create_try_wrapper(
 			CompoundStmt *body ) {
 
@@ -270,5 +309,5 @@
 	}
 
-	FunctionDecl * ExceptionMutatorCore::create_terminate_catch(
+	FunctionDecl * TryMutatorCore::create_terminate_catch(
 			CatchList &handlers ) {
 		std::list<CaseStmt *> handler_wrappers;
@@ -350,5 +389,5 @@
 	// Create a single check from a moddified handler.
 	// except_obj is referenced, modded_handler will be freed.
-	CompoundStmt * ExceptionMutatorCore::create_single_matcher(
+	CompoundStmt * TryMutatorCore::create_single_matcher(
 			DeclarationWithType * except_obj, CatchStmt * modded_handler ) {
 		// {
@@ -388,5 +427,5 @@
 	}
 
-	FunctionDecl * ExceptionMutatorCore::create_terminate_match(
+	FunctionDecl * TryMutatorCore::create_terminate_match(
 			CatchList &handlers ) {
 		// int match(exception * except) {
@@ -425,5 +464,5 @@
 	}
 
-	CompoundStmt * ExceptionMutatorCore::create_terminate_caller(
+	CompoundStmt * TryMutatorCore::create_terminate_caller(
 			FunctionDecl * try_wrapper,
 			FunctionDecl * terminate_catch,
@@ -443,5 +482,5 @@
 	}
 
-	FunctionDecl * ExceptionMutatorCore::create_resume_handler(
+	FunctionDecl * TryMutatorCore::create_resume_handler(
 			CatchList &handlers ) {
 		// bool handle(exception * except) {
@@ -480,5 +519,5 @@
 	}
 
-	CompoundStmt * ExceptionMutatorCore::create_resume_wrapper(
+	CompoundStmt * TryMutatorCore::create_resume_wrapper(
 			Statement * wraps,
 			FunctionDecl * resume_handler ) {
@@ -524,7 +563,7 @@
 	}
 
-	FunctionDecl * ExceptionMutatorCore::create_finally_wrapper(
+	FunctionDecl * TryMutatorCore::create_finally_wrapper(
 			TryStmt * tryStmt ) {
-		// void finally() { <finally code> }
+		// void finally() { `finally->block` }
 		FinallyStmt * finally = tryStmt->get_finally();
 		CompoundStmt * body = finally->get_block();
@@ -537,8 +576,8 @@
 	}
 
-	ObjectDecl * ExceptionMutatorCore::create_finally_hook(
+	ObjectDecl * TryMutatorCore::create_finally_hook(
 			FunctionDecl * finally_wrapper ) {
 		// struct __cfaehm_cleanup_hook __finally_hook
-		//   	__attribute__((cleanup( finally_wrapper )));
+		//   	__attribute__((cleanup( `finally_wrapper` )));
 
 		// Make Cleanup Attribute.
@@ -565,29 +604,5 @@
 
 	// Visiting/Mutating Functions
-	void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {
-		// Validate the Statement's form.
-		ObjectDecl * decl =
-			dynamic_cast<ObjectDecl *>( catchStmt->get_decl() );
-		if ( decl && true /* check decl->get_type() */ ) {
-			// Pass.
-		} else if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
-			SemanticError(catchStmt->location, "catch must have exception type");
-		} else {
-			SemanticError(catchStmt->location, "catchResume must have exception type");
-		}
-
-		// Track the handler context.
-		GuardValue( cur_context );
-		if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
-			cur_context = TerHandler;
-
-			GuardValue( handler_except_decl );
-			handler_except_decl = decl;
-		} else {
-			cur_context = ResHandler;
-		}
-	}
-
-	void ExceptionMutatorCore::premutate( StructDecl *structDecl ) {
+	void TryMutatorCore::premutate( StructDecl *structDecl ) {
 		if ( !structDecl->has_body() ) {
 			// Skip children?
@@ -604,35 +619,12 @@
 			hook_decl = structDecl;
 		}
-		// Later we might get the exception type as well.
-	}
-
-	Statement * ExceptionMutatorCore::postmutate( ThrowStmt *throwStmt ) {
-		assert( except_decl );
-
-		// Ignoring throwStmt->get_target() for now.
-		if ( ThrowStmt::Terminate == throwStmt->get_kind() ) {
-			if ( throwStmt->get_expr() ) {
-				return create_terminate_throw( throwStmt );
-			} else if ( TerHandler == cur_context ) {
-				return create_terminate_rethrow( throwStmt );
-			} else {
-				abort("Invalid throw in %s at %i\n",
-					throwStmt->location.filename.c_str(),
-					throwStmt->location.first_line);
-			}
-		} else {
-			if ( throwStmt->get_expr() ) {
-				return create_resume_throw( throwStmt );
-			} else if ( ResHandler == cur_context ) {
-				return create_resume_rethrow( throwStmt );
-			} else {
-				abort("Invalid throwResume in %s at %i\n",
-					throwStmt->location.filename.c_str(),
-					throwStmt->location.first_line);
-			}
-		}
-	}
-
-	Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) {
+	}
+
+	Statement * TryMutatorCore::postmutate( ThrowStmt * ) {
+		// All throws should be removed by this point.
+		assert( false );
+	}
+
+	Statement * TryMutatorCore::postmutate( TryStmt *tryStmt ) {
 		assert( except_decl );
 		assert( node_decl );
@@ -688,7 +680,12 @@
 	}
 
-	void translateEHM( std::list< Declaration *> & translationUnit ) {
-		PassVisitor<ExceptionMutatorCore> translator;
+	void translateThrows( std::list< Declaration *> & translationUnit ) {
+		PassVisitor<ThrowMutatorCore> translator;
 		mutateAll( translationUnit, translator );
 	}
+
+	void translateTries( std::list< Declaration *> & translationUnit ) {
+		PassVisitor<TryMutatorCore> translator;
+		mutateAll( translationUnit, translator );
+	}
 }
Index: src/ControlStruct/ExceptTranslate.h
===================================================================
--- src/ControlStruct/ExceptTranslate.h	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ src/ControlStruct/ExceptTranslate.h	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -9,7 +9,7 @@
 // Author           : Andrew Beach
 // Created On       : Tus Jun 06 10:13:00 2017
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:19:23 2017
-// Update Count     : 4
+// Last Modified By : Andrew Beach
+// Last Modified On : Tus May 19 11:47:00 2020
+// Update Count     : 5
 //
 
@@ -21,7 +21,14 @@
 
 namespace ControlStruct {
-	void translateEHM( std::list< Declaration *> & translationUnit );
-	// Converts exception handling structures into their underlying C code.  Translation does use the exception
-	// handling header, make sure it is visible wherever translation occurs.
+	void translateThrows( std::list< Declaration *> & translationUnit );
+	/* Replaces all throw & throwResume statements with function calls.
+	 * These still need to be resolved, so call this before the reslover.
+	 */
+
+	void translateTries( std::list< Declaration *> & translationUnit );
+	/* Replaces all try blocks (and their many clauses) with function definitions and calls.
+	 * This uses the exception built-ins to produce typed output and should take place after
+	 * the resolver.
+	 */
 }
 
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ src/main.cc	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -9,7 +9,7 @@
 // Author           : Peter Buhr and Rob Schluntz
 // Created On       : Fri May 15 23:12:02 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Feb  8 08:33:50 2020
-// Update Count     : 633
+// Last Modified By : Andrew Beach
+// Last Modified On : Tue May 19 12:03:00 2020
+// Update Count     : 634
 //
 
@@ -312,4 +312,5 @@
 		} // if
 
+		PASS( "Translate Throws", ControlStruct::translateThrows( translationUnit ) );
 		PASS( "Fix Labels", ControlStruct::fixLabels( translationUnit ) );
 		PASS( "Fix Names", CodeGen::fixNames( translationUnit ) );
@@ -354,5 +355,5 @@
 		PASS( "Expand Unique Expr", Tuples::expandUniqueExpr( translationUnit ) ); // xxx - is this the right place for this? want to expand ASAP so tha, sequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused
 
-		PASS( "Translate EHM" , ControlStruct::translateEHM( translationUnit ) );
+		PASS( "Translate Tries" , ControlStruct::translateTries( translationUnit ) );
 
 		PASS( "Gen Waitfor" , Concurrency::generateWaitFor( translationUnit ) );
Index: tests/errors/.expect/completeType.txt
===================================================================
--- tests/errors/.expect/completeType.txt	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ tests/errors/.expect/completeType.txt	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -132,8 +132,8 @@
 ?=?: pointer to function
         ... with parameters
-          reference to instance of type _104_0_T (not function type)
-          instance of type _104_0_T (not function type)
+          reference to instance of type _108_0_T (not function type)
+          instance of type _108_0_T (not function type)
         ... returning
-          _retval__operator_assign: instance of type _104_0_T (not function type)
+          _retval__operator_assign: instance of type _108_0_T (not function type)
           ... with attributes:
             Attribute with name: unused
Index: tests/exceptions/.expect/defaults.txt
===================================================================
--- tests/exceptions/.expect/defaults.txt	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
+++ tests/exceptions/.expect/defaults.txt	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -0,0 +1,4 @@
+Should be printed.
+jump catch handler.
+jump default handler.
+Catch unhandled_exception.
Index: tests/exceptions/conditional.cfa
===================================================================
--- tests/exceptions/conditional.cfa	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ tests/exceptions/conditional.cfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -56,5 +56,5 @@
 
 	try {
-		throw &exc;
+		throw exc;
 	} catch (num_error * error ; 3 == error->virtual_table->code( error )) {
 		caught_num_error(3, error);
@@ -64,5 +64,5 @@
 
 	try {
-		throwResume &exc;
+		throwResume exc;
 	} catchResume (num_error * error ; 3 == error->virtual_table->code( error )) {
 		caught_num_error(3, error);
Index: tests/exceptions/data-except.cfa
===================================================================
--- tests/exceptions/data-except.cfa	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ tests/exceptions/data-except.cfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -28,5 +28,5 @@
 
 	try {
-		throw &except;
+		throw except;
 	} catch (paired * exc) {
 		printf("%s(%d, %d)\n", paired_msg(exc), exc->first, exc->second);
@@ -37,5 +37,5 @@
 
 	try {
-		throwResume &except;
+		throwResume except;
 	} catchResume (paired * exc) {
 		printf("%s(%d, %d)\n", paired_msg(exc), exc->first, exc->second);
Index: tests/exceptions/defaults.cfa
===================================================================
--- tests/exceptions/defaults.cfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
+++ tests/exceptions/defaults.cfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -0,0 +1,75 @@
+// Tests for providing new default operations.
+
+#include <string.h>
+#include <exception.hfa>
+
+DATA_EXCEPTION(log_message)(
+	char * msg;
+);
+
+void ?{}(log_message & this, char * msg) {
+	VTABLE_INIT(this, log_message);
+	this.msg = msg;
+}
+
+char * get_log_message(log_message * this) {
+	return this->msg;
+}
+
+VTABLE_INSTANCE(log_message)(get_log_message);
+
+// Logging messages don't have to be handled.
+void defaultResumptionHandler(log_message &) {}
+
+// And should never be used to terminate computation.
+void defaultTerminationHandler(log_message &) = void;
+
+void log_test(void) {
+	// We can catch log:
+	try {
+		throwResume (log_message){(char *)"Should be printed.\n"};
+	} catchResume (log_message * this) {
+		printf(this->virtual_table->msg(this));
+	}
+	// But we don't have to:
+	throwResume (log_message){(char *)"Should not be printed.\n"};
+}
+
+// I don't have a good use case for doing the same with termination.
+TRIVIAL_EXCEPTION(jump);
+void defaultTerminationHandler(jump &) {
+	printf("jump default handler.\n");
+}
+
+void jump_test(void) {
+	try {
+		throw (jump){};
+	} catch (jump * this) {
+		printf("jump catch handler.\n");
+	}
+	throw (jump){};
+}
+
+TRIVIAL_EXCEPTION(first);
+TRIVIAL_EXCEPTION(unhandled_exception);
+
+void unhandled_test(void) {
+	forall(dtype T | is_exception(T))
+	void defaultTerminationHandler(T &) {
+		throw (unhandled_exception){};
+	}
+	void defaultTerminationHandler(unhandled_exception &) {
+		abort();
+	}
+	try {
+		throw (first){};
+	} catch (unhandled_exception * t) {
+		printf("Catch unhandled_exception.\n");
+	}
+}
+
+int main(int argc, char * argv[]) {
+	log_test();
+	jump_test();
+	unhandled_test();
+}
Index: tests/exceptions/finally.cfa
===================================================================
--- tests/exceptions/finally.cfa	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ tests/exceptions/finally.cfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -12,5 +12,5 @@
 		try {
 			printf("termination throw\n");
-			throw &exc;
+			throw exc;
 		} finally {
 			loud_exit a = "termination inner finally";
@@ -28,5 +28,5 @@
 		try {
 			printf("resumption throw\n");
-			throwResume &exc;
+			throwResume exc;
 		} finally {
 			loud_exit a = "resumption inner finally";
Index: tests/exceptions/interact.cfa
===================================================================
--- tests/exceptions/interact.cfa	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ tests/exceptions/interact.cfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -10,5 +10,5 @@
 	// Resume falls back to terminate.
 	try {
-		throwResume &(star){};
+		throwResume (star){};
 	} catch (star *) {
 		printf("caught as termination\n");
@@ -17,5 +17,5 @@
 	try {
 		loud_region a = "try block with resume throw";
-		throwResume &(star){};
+		throwResume (star){};
 	} catch (star *) {
 		printf("caught as termination\n");
@@ -29,5 +29,5 @@
 	try {
 		try {
-			throw &(star){};
+			throw (star){};
 		} catchResume (star *) {
 			printf("resume catch on terminate\n");
@@ -43,5 +43,5 @@
 	try {
 		try {
-			throwResume &(star){};
+			throwResume (star){};
 		} catch (star *) {
 			printf("terminate catch on resume\n");
@@ -58,5 +58,5 @@
 		try {
 			try {
-				throw &(star){};
+				throw (star){};
 			} catchResume (star *) {
 				printf("inner resume catch (error)\n");
@@ -64,5 +64,5 @@
 		} catch (star * error) {
 			printf("termination catch, will resume\n");
-			throwResume error;
+			throwResume *error;
 		}
 	} catchResume (star *) {
@@ -75,5 +75,5 @@
 		try {
 			try {
-				throwResume &(star){};
+				throwResume (star){};
 			} catch (star *) {
 				printf("inner termination catch\n");
@@ -81,5 +81,5 @@
 		} catchResume (star * error) {
 			printf("resumption catch, will terminate\n");
-			throw error;
+			throw *error;
 		}
 	} catch (star *) {
@@ -94,10 +94,10 @@
 				try {
 					printf("throwing resume moon\n");
-					throwResume &(moon){};
+					throwResume (moon){};
 				} catch (star *) {
 					printf("termination catch\n");
 				}
 				printf("throwing resume star\n");
-				throwResume &(star){};
+				throwResume (star){};
 			} catchResume (star *) {
 				printf("resumption star catch\n");
@@ -105,5 +105,5 @@
 		} catchResume (moon *) {
 			printf("resumption moon catch, will terminate\n");
-			throw &(star){};
+			throw (star){};
 		}
 	} catchResume (star *) {
Index: tests/exceptions/resume.cfa
===================================================================
--- tests/exceptions/resume.cfa	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ tests/exceptions/resume.cfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -14,5 +14,5 @@
 		loud_exit a = "simple try clause";
 		printf("simple throw\n");
-		throwResume &(zen){};
+		throwResume (zen){};
 		printf("end of try clause\n");
 	} catchResume (zen * error) {
@@ -24,5 +24,5 @@
 	// Throw catch-all test.
 	try {
-		throwResume &(zen){};
+		throwResume (zen){};
 	} catchResume (exception_t * error) {
 		printf("catch-all\n");
@@ -33,5 +33,5 @@
 	try {
 		printf("throwing child exception\n");
-		throwResume &(moment_of){};
+		throwResume (moment_of){};
 	} catchResume (zen *) {
 		printf("inner parent match\n");
@@ -44,5 +44,5 @@
 	try {
 		try {
-			throwResume &(yin){};
+			throwResume (yin){};
 		} catchResume (zen *) {
 			printf("caught yin as zen\n");
@@ -60,5 +60,5 @@
 			loud_exit a = "rethrow inner try";
 			printf("rethrow inner try\n");
-			throwResume &(zen){};
+			throwResume (zen){};
 		} catchResume (zen *) {
 			loud_exit a = "rethrowing catch clause";
@@ -75,8 +75,8 @@
 	try {
 		try {
-			throwResume &(yin){};
+			throwResume (yin){};
 		} catchResume (yin *) {
 			printf("caught yin, will throw yang\n");
-			throwResume &(yang){};
+			throwResume (yang){};
 		} catchResume (yang *) {
 			printf("caught exception from same try\n");
@@ -91,10 +91,10 @@
 		try {
 			printf("throwing first exception\n");
-			throwResume &(yin){};
+			throwResume (yin){};
 		} catchResume (yin *) {
 			printf("caught first exception\n");
 			try {
 				printf("throwing second exception\n");
-				throwResume &(yang){};
+				throwResume (yang){};
 			} catchResume (yang *) {
 				printf("caught second exception\n");
@@ -112,10 +112,10 @@
 	try {
 		try {
-			throwResume &(zen){};
-			throwResume &(zen){};
+			throwResume (zen){};
+			throwResume (zen){};
 		} catchResume (zen *) {
 			printf("inner catch\n");
 		}
-		throwResume &(zen){};
+		throwResume (zen){};
 	} catchResume (zen *) {
 		printf("outer catch\n");
Index: tests/exceptions/terminate.cfa
===================================================================
--- tests/exceptions/terminate.cfa	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ tests/exceptions/terminate.cfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -14,5 +14,5 @@
 		loud_exit a = "simple try clause";
 		printf("simple throw\n");
-		throw &(zen){};
+		throw (zen){};
 		printf("end of try clause\n");
 	} catch (zen * error) {
@@ -24,5 +24,5 @@
 	// Throw catch-all test.
 	try {
-		throw &(zen){};
+		throw (zen){};
 	} catch (exception_t * error) {
 		printf("catch-all\n");
@@ -33,5 +33,5 @@
 	try {
 		printf("throwing child exception\n");
-		throw &(moment_of){};
+		throw (moment_of){};
 	} catch (zen *) {
 		printf("inner parent match\n");
@@ -44,5 +44,5 @@
 	try {
 		try {
-			throw &(yin){};
+			throw (yin){};
 		} catch (zen *) {
 			printf("caught yin as zen\n");
@@ -60,5 +60,5 @@
 			loud_exit a = "rethrow inner try";
 			printf("rethrow inner try\n");
-			throw &(zen){};
+			throw (zen){};
 		} catch (zen *) {
 			loud_exit a = "rethrowing catch clause";
@@ -75,8 +75,8 @@
 	try {
 		try {
-			throw &(yin){};
+			throw (yin){};
 		} catch (yin *) {
 			printf("caught yin, will throw yang\n");
-			throw &(yang){};
+			throw (yang){};
 		} catch (yang *) {
 			printf("caught exception from same try\n");
@@ -91,10 +91,10 @@
 		try {
 			printf("throwing first exception\n");
-			throw &(yin){};
+			throw (yin){};
 		} catch (yin *) {
 			printf("caught first exception\n");
 			try {
 				printf("throwing second exception\n");
-				throw &(yang){};
+				throw (yang){};
 			} catch (yang *) {
 				printf("caught second exception\n");
@@ -112,10 +112,10 @@
 	try {
 		try {
-			throw &(zen){};
-			throw &(zen){};
+			throw (zen){};
+			throw (zen){};
 		} catch (zen *) {
 			printf("inner catch\n");
 		}
-		throw &(zen){};
+		throw (zen){};
 	} catch (zen *) {
 		printf("outer catch\n");
Index: tests/list/.expect/dlist-insert-remove.txt
===================================================================
--- tests/list/.expect/dlist-insert-remove.txt	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ tests/list/.expect/dlist-insert-remove.txt	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -1464,2 +1464,316 @@
 0.7
 -
+
+~~~~~~~~~~ End removal tests on Headed List: First ~~~~~~~~~~
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Test 16-i.  Modifying Freds on MINE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+==== fred by MINE before 
+1.7
+2.7
+3.7
+-
+1.7
+-
+3.7
+-
+3.7
+2.7
+1.7
+-
+==== fred by YOURS before 
+1.7
+2.7
+3.7
+-
+1.7
+-
+3.7
+-
+3.7
+2.7
+1.7
+-
+==== fred by MINE after 
+2.7
+3.7
+-
+2.7
+-
+3.7
+-
+3.7
+2.7
+-
+==== fred by YOURS after 
+1.7
+2.7
+3.7
+-
+1.7
+-
+3.7
+-
+3.7
+2.7
+1.7
+-
+==== fred by MINE after 
+1.7
+-
+1.7
+-
+-
+-
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Test 16-ii.  Modifying Freds on YOURS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+==== fred by MINE before 
+1.7
+2.7
+3.7
+-
+1.7
+-
+3.7
+-
+3.7
+2.7
+1.7
+-
+==== fred by YOURS before 
+1.7
+2.7
+3.7
+-
+1.7
+-
+3.7
+-
+3.7
+2.7
+1.7
+-
+==== fred by MINE after 
+1.7
+2.7
+3.7
+-
+1.7
+-
+3.7
+-
+3.7
+2.7
+1.7
+-
+==== fred by YOURS after 
+2.7
+3.7
+-
+2.7
+-
+3.7
+-
+3.7
+2.7
+-
+==== fred by YOURS after 
+1.7
+-
+1.7
+-
+-
+-
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Test 16-iii.  Modifying Maries
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+==== mary before 
+1.7
+2.7
+3.7
+-
+1.7
+-
+3.7
+-
+3.7
+2.7
+1.7
+-
+==== mary after 
+2.7
+3.7
+-
+2.7
+-
+3.7
+-
+3.7
+2.7
+-
+==== mary after 
+1.7
+-
+1.7
+-
+-
+-
+
+~~~~~~~~~~ End removal tests on Headed List: Last ~~~~~~~~~~
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Test 17-i.  Modifying Freds on MINE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+==== fred by MINE before 
+1.7
+2.7
+3.7
+-
+1.7
+-
+3.7
+-
+3.7
+2.7
+1.7
+-
+==== fred by YOURS before 
+1.7
+2.7
+3.7
+-
+1.7
+-
+3.7
+-
+3.7
+2.7
+1.7
+-
+==== fred by MINE after 
+1.7
+2.7
+-
+1.7
+-
+2.7
+-
+2.7
+1.7
+-
+==== fred by YOURS after 
+1.7
+2.7
+3.7
+-
+1.7
+-
+3.7
+-
+3.7
+2.7
+1.7
+-
+==== fred by MINE after 
+3.7
+-
+3.7
+-
+-
+-
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Test 17-ii.  Modifying Freds on YOURS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+==== fred by MINE before 
+1.7
+2.7
+3.7
+-
+1.7
+-
+3.7
+-
+3.7
+2.7
+1.7
+-
+==== fred by YOURS before 
+1.7
+2.7
+3.7
+-
+1.7
+-
+3.7
+-
+3.7
+2.7
+1.7
+-
+==== fred by MINE after 
+1.7
+2.7
+3.7
+-
+1.7
+-
+3.7
+-
+3.7
+2.7
+1.7
+-
+==== fred by YOURS after 
+1.7
+2.7
+-
+1.7
+-
+2.7
+-
+2.7
+1.7
+-
+==== fred by YOURS after 
+3.7
+-
+3.7
+-
+-
+-
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Test 17-iii.  Modifying Maries
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+==== mary before 
+1.7
+2.7
+3.7
+-
+1.7
+-
+3.7
+-
+3.7
+2.7
+1.7
+-
+==== mary after 
+1.7
+2.7
+-
+1.7
+-
+2.7
+-
+2.7
+1.7
+-
+==== mary after 
+3.7
+-
+3.7
+-
+-
+-
Index: tests/list/dlist-insert-remove.cfa
===================================================================
--- tests/list/dlist-insert-remove.cfa	(revision 2802824140076a430c44546624325795e3ff40dd)
+++ tests/list/dlist-insert-remove.cfa	(revision 0e4df2ee2dfcfc551fd46578d5fe06b0fe7ff0b0)
@@ -1187,4 +1187,214 @@
 ////////////////////////////////////////////////////////////
 //
+// Section 4f
+//
+// Test cases of pop_first, pop_last
+//
+// Example of call-side user code
+//
+////////////////////////////////////////////////////////////
+
+// These cases assume element removal at first-last is correct
+
+void test__pop_first__fred_mine() {
+
+	fred f1 = {1.7};
+	fred f2 = {2.7};
+	fred f3 = {3.7};
+
+	dlist(fred_in_mine, fred) flm;
+	insert_last(flm, f1);
+	insert_last(flm, f2);
+	insert_last(flm, f3);
+
+	dlist(fred_in_yours, fred) fly;
+	insert_last(fly, f1);
+	insert_last(fly, f2);
+	insert_last(fly, f3);
+
+	printMyFreddies(flm`first, flm`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 
+	printYourFreddies(fly`first, fly`last, 1);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 
+
+	verify(validate(fly));
+	verify(validate(flm));
+
+	fred & popped = pop_first(flm);
+
+	verify(validate(fly));
+	verify(validate(flm));
+
+	printMyFreddies(flm`first, flm`last, 0);     // 2.7, 3.7;       2.7;  3.7;  3.7, 2.7      (modified)
+	printYourFreddies(fly`first, fly`last, 0);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 (unmodified)
+
+	// observe f1 is now solo in mine; in yours, it was just traversed
+	printMyFreddies(f1, *0p, 0);    // 1.7; 1.7; ;
+
+	assert( &popped == & f1 );
+}
+
+void test__pop_first__fred_yours() {
+
+	fred f1 = {1.7};
+	fred f2 = {2.7};
+	fred f3 = {3.7};
+
+	dlist(fred_in_mine, fred) flm;
+	insert_last(flm, f1);
+	insert_last(flm, f2);
+	insert_last(flm, f3);
+
+	dlist(fred_in_yours, fred) fly;
+	insert_last(fly, f1);
+	insert_last(fly, f2);
+	insert_last(fly, f3);
+
+	printMyFreddies(flm`first, flm`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 
+	printYourFreddies(fly`first, fly`last, 1);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 
+
+	verify(validate(fly));
+	verify(validate(flm));
+
+	fred & popped = pop_first(fly);
+
+	verify(validate(fly));
+	verify(validate(flm));
+
+	printMyFreddies(flm`first, flm`last, 0);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 (unmodified)
+	printYourFreddies(fly`first, fly`last, 0);   // 2.7, 3.7;       2.7;  3.7;  3.7, 2.7      (modified)
+
+	// observe f1 is now solo in yours; in mine, it was just traversed
+	printYourFreddies(f1, *0p, 0);    // 1.7; 1.7; ;
+
+	assert( &popped == &f1 );
+}
+
+void test__pop_first__maries() {
+
+	mary m1 = {1.7};
+	mary m2 = {2.7};
+	mary m3 = {3.7};
+
+	dlist(mary, mary) ml;
+	insert_last(ml, m1);
+	insert_last(ml, m2);
+	insert_last(ml, m3);
+
+	printMariatheotokos(ml`first, ml`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 
+
+	verify(validate(ml));
+
+	mary & popped = pop_first(ml);
+
+	verify(validate(ml));
+
+	printMariatheotokos(ml`first, ml`last, 0);     // 2.7, 3.7;       2.7;  3.7;  3.7, 2.7      (modified)
+
+	// observe m1 is now solo
+	printMariatheotokos(m1, *0p, 0);               // 1.7; 1.7; ;
+
+	assert( &popped == &m1 );
+}
+
+void test__pop_last__fred_mine() {
+
+	fred f1 = {1.7};
+	fred f2 = {2.7};
+	fred f3 = {3.7};
+
+	dlist(fred_in_mine, fred) flm;
+	insert_last(flm, f1);
+	insert_last(flm, f2);
+	insert_last(flm, f3);
+
+	dlist(fred_in_yours, fred) fly;
+	insert_last(fly, f1);
+	insert_last(fly, f2);
+	insert_last(fly, f3);
+
+	printMyFreddies(flm`first, flm`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 
+	printYourFreddies(fly`first, fly`last, 1);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 
+
+	verify(validate(fly));
+	verify(validate(flm));
+
+	fred & popped = pop_last(flm);
+
+	verify(validate(fly));
+	verify(validate(flm));
+
+	printMyFreddies(flm`first, flm`last, 0);     // 1.7, 2.7;       1.7;  2.7;  2.7, 1.7      (modified)
+	printYourFreddies(fly`first, fly`last, 0);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 (unmodified)
+
+	// observe f3 is now solo in mine; in yours, it was just traversed
+	printMyFreddies(f3, *0p, 0);    // 3.7; 3.7; ;
+
+	assert( &popped == & f3 );
+}
+
+void test__pop_last__fred_yours() {
+
+	fred f1 = {1.7};
+	fred f2 = {2.7};
+	fred f3 = {3.7};
+
+	dlist(fred_in_mine, fred) flm;
+	insert_last(flm, f1);
+	insert_last(flm, f2);
+	insert_last(flm, f3);
+
+	dlist(fred_in_yours, fred) fly;
+	insert_last(fly, f1);
+	insert_last(fly, f2);
+	insert_last(fly, f3);
+
+	printMyFreddies(flm`first, flm`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 
+	printYourFreddies(fly`first, fly`last, 1);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 
+
+	verify(validate(fly));
+	verify(validate(flm));
+
+	fred & popped = pop_last(fly);
+
+	verify(validate(fly));
+	verify(validate(flm));
+
+	printMyFreddies(flm`first, flm`last, 0);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 (unmodified)
+	printYourFreddies(fly`first, fly`last, 0);   // 1.7, 2.7;       1.7;  2.7;  2.7, 1.7      (modified)
+
+	// observe f3 is now solo in yours; in mine, it was just traversed
+	printYourFreddies(f3, *0p, 0);    // 3.7; 3.7; ;
+
+	assert( &popped == & f3 );
+}
+
+void test__pop_last__maries() {
+
+	mary m1 = {1.7};
+	mary m2 = {2.7};
+	mary m3 = {3.7};
+
+	dlist(mary, mary) ml;
+	insert_last(ml, m1);
+	insert_last(ml, m2);
+	insert_last(ml, m3);
+
+	printMariatheotokos(ml`first, ml`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 
+
+	verify(validate(ml));
+
+	mary & popped = pop_last(ml);
+
+	verify(validate(ml));
+
+	printMariatheotokos(ml`first, ml`last, 0);     // 1.7, 1.7;       1.7;  2.7;  2.7, 1.7      (modified)
+
+	// observe m1 is now solo
+	printMariatheotokos(m3, *0p, 0);               // 3.7; 3.7; ;
+
+	assert( &popped == &m3 );
+}
+
+////////////////////////////////////////////////////////////
+//
 // Section 5
 //
@@ -1422,4 +1632,42 @@
 	test__remove_of_sole__mary();
 
+	sout | "";
+	sout | "~~~~~~~~~~ End removal tests on Headed List: First ~~~~~~~~~~";
+	sout | "";
+
+	sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
+	sout | "Test 16-i.  Modifying Freds on MINE";
+	sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
+	test__pop_first__fred_mine();
+
+	sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
+	sout | "Test 16-ii.  Modifying Freds on YOURS";
+	sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
+	test__pop_first__fred_yours();
+
+	sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
+	sout | "Test 16-iii.  Modifying Maries";
+	sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
+	test__pop_first__maries();
+
+	sout | "";
+	sout | "~~~~~~~~~~ End removal tests on Headed List: Last ~~~~~~~~~~";
+	sout | "";
+
+	sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
+	sout | "Test 17-i.  Modifying Freds on MINE";
+	sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
+	test__pop_last__fred_mine();
+
+	sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
+	sout | "Test 17-ii.  Modifying Freds on YOURS";
+	sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
+	test__pop_last__fred_yours();
+
+	sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
+	sout | "Test 17-iii.  Modifying Maries";
+	sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
+	test__pop_last__maries();
+
 	return 0;
 }
