Index: doc/working/exception/impl/exception.c
===================================================================
--- doc/working/exception/impl/exception.c	(revision bf70aa95b89eb2a7499a5dca8acfa765fa5c2867)
+++ doc/working/exception/impl/exception.c	(revision 838ef08a861624326cedc08c004590769c5eae2b)
@@ -22,6 +22,7 @@
 
 void __throw_resume(exception except) {
-	void noop() { printf("do nothing\n");}
-	struct __cleanup_hook __blarg __attribute__((cleanup(noop)));
+
+	// DEBUG
+	printf("Throwing resumption exception %d\n", except);
 
 	struct __try_resume_node * original_head = shared_stack.current_resume;
@@ -45,24 +46,229 @@
 }
 
-/* __try_resume_node functions:
- * Currently I was planning to generate this code inline, and even if I don't
- * putting it in the header so it can be inlined might be worth while.
- * And if we put them in Cforall code we can use the operators.
- */
-void __try_resume_node_new(struct __try_resume_node * node,
-		_Bool (*handler)(exception except)) {
-	node->next = shared_stack.top_resume;
-	shared_stack.top_resume = node;
-	node->try_to_handle = handler;
-}
-
-void __try_resume_node_delete(struct __try_resume_node * node) {
-	shared_stack.top_resume = node->next;
-}
-
 
 // TERMINATION ===============================================================
 
 // Requires -fexceptions to work.
+
+// Global which defines the current exception
+// Currently an int just to make matching easier
+//int this_exception; (became shared_stack.current_exception)
+
+// We need a piece of storage to raise the exception
+struct _Unwind_Exception this_exception_storage;
+
+// Function needed by force unwind
+// It basically says to unwind the whole stack and then exit when we reach the end of the stack
+static _Unwind_Reason_Code _Stop_Fn(
+		int version,
+		_Unwind_Action actions,
+		_Unwind_Exception_Class exceptionClass,
+		struct _Unwind_Exception * unwind_exception,
+		struct _Unwind_Context * context,
+		void * some_param) {
+	if( actions & _UA_END_OF_STACK  ) exit(1);
+	if( actions & _UA_CLEANUP_PHASE ) return _URC_NO_REASON;
+
+	return _URC_FATAL_PHASE2_ERROR;
+}
+
+// Example throw routine
+void __throw_terminate( int val ) {
+	// Store the current exception
+	shared_stack.current_exception = val;
+
+	// DEBUG
+	printf("Throwing termination exception %d\n", val);
+
+	// Call stdlibc to raise the exception
+	_Unwind_Reason_Code ret = _Unwind_RaiseException( &this_exception_storage );
+
+	// If we reach here it means something happened
+	// For resumption to work we need to find a way to return back to here
+	// Most of them will probably boil down to setting a global flag and making the phase 1 either stop or fail.
+	// Causing an error on purpose may help avoiding unnecessary work but it might have some weird side effects.
+	// If we just pretend no handler was found that would work but may be expensive for no reason since we will always
+	// search the whole stack
+
+	if( ret == _URC_END_OF_STACK ) {
+		// No proper handler was found
+		// This can be handled in several way
+		// C++ calls std::terminate
+		// Here we force unwind the stack, basically raising a cancellation
+		printf("Uncaught exception %p\n", &this_exception_storage);
+
+		ret = _Unwind_ForcedUnwind( &this_exception_storage, _Stop_Fn, (void*)0x22 );
+		printf("UNWIND ERROR %d after force unwind\n", ret);
+		abort();
+	}
+
+	// We did not simply reach the end of the stack without finding a handler,
+	// Something wen't wrong
+	printf("UNWIND ERROR %d after raise exception\n", ret);
+	abort();
+}
+
+// This is our personality routine
+// For every stack frame anotated with ".cfi_personality 0x3,__gcfa_personality_v0"
+// This function will be called twice when unwinding
+// Once in the search phased and once in the cleanup phase
+_Unwind_Reason_Code __gcfa_personality_v0 (
+		int version, _Unwind_Action actions, unsigned long long exceptionClass,
+		struct _Unwind_Exception* unwind_exception,
+		struct _Unwind_Context* context)
+{
+
+	// DEBUG
+	//printf("CFA: 0x%lx\n", _Unwind_GetCFA(context));
+	printf("Personality function (%d, %x, %llu, %p, %p):", version, actions, exceptionClass, unwind_exception, context);
+
+	// If we've reached the end of the stack then there is nothing much we can do...
+	if( actions & _UA_END_OF_STACK ) return _URC_END_OF_STACK;
+
+	// DEBUG
+	if (actions & _UA_SEARCH_PHASE) {
+		printf(" lookup phase");
+	}
+	// DEBUG
+	else if (actions & _UA_CLEANUP_PHASE) {
+		printf(" cleanup phase");
+	}
+	// Just in case, probably can't actually happen
+	else {
+		printf(" error\n");
+		return _URC_FATAL_PHASE1_ERROR;
+	}
+
+	// Get a pointer to the language specific data from which we will read what we need
+	const unsigned char * lsd = (const unsigned char*) _Unwind_GetLanguageSpecificData( context );
+
+	if( !lsd ) {	//Nothing to do, keep unwinding
+		printf(" no LSD");
+		goto UNWIND;
+	}
+
+	// Get the instuction pointer and a reading pointer into the exception table
+	lsda_header_info lsd_info;
+	const unsigned char * cur_ptr = parse_lsda_header( context, lsd, &lsd_info);
+	_Unwind_Ptr instruction_ptr = _Unwind_GetIP( context );
+
+	// Linearly search the table for stuff to do
+	while( cur_ptr < lsd_info.action_table ) {
+		_Unwind_Ptr callsite_start;
+		_Unwind_Ptr callsite_len;
+		_Unwind_Ptr callsite_landing_pad;
+		_uleb128_t  callsite_action;
+
+		// Decode the common stuff we have in here
+		cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_start);
+		cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_len);
+		cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_landing_pad);
+		cur_ptr = read_uleb128 (cur_ptr, &callsite_action);
+
+		// Have we reach the correct frame info yet?
+		if( lsd_info.Start + callsite_start + callsite_len < instruction_ptr ) {
+			//DEBUG BEGIN
+			void * ls = (void*)lsd_info.Start;
+			void * cs = (void*)callsite_start;
+			void * cl = (void*)callsite_len;
+			void * bp = (void*)lsd_info.Start + callsite_start;
+			void * ep = (void*)lsd_info.Start + callsite_start + callsite_len;
+			void * ip = (void*)instruction_ptr;
+			printf("\nfound %p - %p (%p, %p, %p), looking for %p\n", bp, ep, ls, cs, cl, ip);
+			//DEBUG END
+			continue;
+		}
+
+		// Have we gone too far
+		if( lsd_info.Start + callsite_start > instruction_ptr ) {
+			printf(" gone too far");
+			break;
+		}
+
+		// Something to do?
+		if( callsite_landing_pad ) {
+			// Which phase are we in
+			if (actions & _UA_SEARCH_PHASE) {
+				// Search phase, this means we probably found a potential handler and must check if it is a match
+
+				// If we have arbitrarily decided that 0 means nothing to do and 1 means there is a potential handler
+				// This doesn't seem to conflict the gcc default behavior
+				if (callsite_action != 0) {
+					// Now we want to run some code to see if the handler matches
+					// This is the tricky part where we want to the power to run arbitrary code
+					// However, generating a new exception table entry and try routine every time
+					// is way more expansive than we might like
+					// The information we have is :
+					//  - The GR (Series of registers)
+					//    GR1=GP Global Pointer of frame ref by context
+					//  - The instruction pointer
+					//  - The instruction pointer info (???)
+					//  - The CFA (Canonical Frame Address)
+					//  - The BSP (Probably the base stack pointer)
+
+
+					// The current apprach uses one exception table entry per try block
+					_uleb128_t imatcher;
+					// Get the relative offset to the
+					cur_ptr = read_uleb128 (cur_ptr, &imatcher);
+
+					// Get a function pointer from the relative offset and call it
+					// _Unwind_Reason_Code (*matcher)() = (_Unwind_Reason_Code (*)())lsd_info.LPStart + imatcher;					
+
+					_Unwind_Reason_Code (*matcher)() =
+						MATCHER_FROM_CONTEXT(context);
+					int index = matcher(shared_stack.current_exception);
+					_Unwind_Reason_Code ret = (0 == index)
+						? _URC_CONTINUE_UNWIND : _URC_HANDLER_FOUND;
+					shared_stack.current_handler_index = index;
+
+					// Based on the return value, check if we matched the exception
+					if( ret == _URC_HANDLER_FOUND) printf(" handler found\n");
+					else printf(" no handler\n");
+					return ret;
+				}
+
+				// This is only a cleanup handler, ignore it
+				printf(" no action");
+			}
+			else if (actions & _UA_CLEANUP_PHASE) {
+
+				if( (callsite_action != 0) && !(actions & _UA_HANDLER_FRAME) ){
+					// If this is a potential exception handler
+					// but not the one that matched the exception in the seach phase,
+					// just ignore it
+					goto UNWIND;
+				}
+
+				// We need to run some clean-up or a handler
+				// These statment do the right thing but I don't know any specifics at all
+				_Unwind_SetGR( context, __builtin_eh_return_data_regno(0), (_Unwind_Ptr) unwind_exception );
+				_Unwind_SetGR( context, __builtin_eh_return_data_regno(1), 0 );
+
+				// I assume this sets the instruction pointer to the adress of the landing pad
+				// It doesn't actually set it, it only state the value that needs to be set once we return _URC_INSTALL_CONTEXT
+				_Unwind_SetIP( context, lsd_info.LPStart + callsite_landing_pad );
+
+				// DEBUG
+				printf(" action\n");
+
+				// Return have some action to run
+				return _URC_INSTALL_CONTEXT;
+			}
+		}
+
+		// Nothing to do, move along
+		printf(" no landing pad");
+	}
+	// No handling found
+	printf(" table end reached\n");
+
+	// DEBUG
+	UNWIND:
+	printf(" unwind\n");
+
+	// Keep unwinding the stack
+	return _URC_CONTINUE_UNWIND;
+}
 
 // Try statements are hoisted out see comments for details
@@ -141,226 +347,4 @@
 	"	.size	__try_terminate, .-__try_terminate\n"
 	"	.ident	\"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n"
-	"	.section	.note.GNU-stack,\"x\",@progbits\n"
+//	"	.section	.note.GNU-stack,\"x\",@progbits\n"
 );
-
-// Global which defines the current exception
-// Currently an int just to make matching easier
-int this_exception;
-
-// We need a piece of storage to raise the exception
-struct _Unwind_Exception this_exception_storage;
-
-// Function needed by force unwind
-// It basically says to unwind the whole stack and then exit when we reach the end of the stack
-static _Unwind_Reason_Code _Stop_Fn(
-		int version,
-		_Unwind_Action actions,
-		_Unwind_Exception_Class exceptionClass,
-		struct _Unwind_Exception * unwind_exception,
-		struct _Unwind_Context * context,
-		void * some_param) {
-	if( actions & _UA_END_OF_STACK  ) exit(1);
-	if( actions & _UA_CLEANUP_PHASE ) return _URC_NO_REASON;
-
-	return _URC_FATAL_PHASE2_ERROR;
-}
-
-// Example throw routine
-void __throw_terminate( int val ) {
-	// Store the current exception
-	this_exception = val;
-
-	// DEBUG
-	printf("Throwing exception %d\n", this_exception);
-
-	// Call stdlibc to raise the exception
-	_Unwind_Reason_Code ret = _Unwind_RaiseException( &this_exception_storage );
-
-	// If we reach here it means something happened
-	// For resumption to work we need to find a way to return back to here
-	// Most of them will probably boil down to setting a global flag and making the phase 1 either stop or fail.
-	// Causing an error on purpose may help avoiding unnecessary work but it might have some weird side effects.
-	// If we just pretend no handler was found that would work but may be expensive for no reason since we will always
-	// search the whole stack
-
-	if( ret == _URC_END_OF_STACK ) {
-		// No proper handler was found
-		// This can be handled in several way
-		// C++ calls std::terminate
-		// Here we force unwind the stack, basically raising a cancellation
-		printf("Uncaught exception %p\n", &this_exception_storage);
-
-		ret = _Unwind_ForcedUnwind( &this_exception_storage, _Stop_Fn, (void*)0x22 );
-		printf("UNWIND ERROR %d after force unwind\n", ret);
-		abort();
-	}
-
-	// We did not simply reach the end of the stack without finding a handler,
-	// Something wen't wrong
-	printf("UNWIND ERROR %d after raise exception\n", ret);
-	abort();
-}
-
-// This is our personality routine
-// For every stack frame anotated with ".cfi_personality 0x3,__gcfa_personality_v0"
-// This function will be called twice when unwinding
-// Once in the search phased and once in the cleanup phase
-_Unwind_Reason_Code __gcfa_personality_v0 (
-		int version, _Unwind_Action actions, unsigned long long exceptionClass,
-		struct _Unwind_Exception* unwind_exception,
-		struct _Unwind_Context* context)
-{
-	printf("CFA: 0x%lx\n", _Unwind_GetCFA(context));
-
-	// DEBUG
-	printf("Personality function (%d, %x, %llu, %p, %p):", version, actions, exceptionClass, unwind_exception, context);
-
-	// If we've reached the end of the stack then there is nothing much we can do...
-	if( actions & _UA_END_OF_STACK ) return _URC_END_OF_STACK;
-
-	// DEBUG
-	if (actions & _UA_SEARCH_PHASE) {
-		printf(" lookup phase");
-	}
-	// DEBUG
-	else if (actions & _UA_CLEANUP_PHASE) {
-		printf(" cleanup phase");
-	}
-	// Just in case, probably can't actually happen
-	else {
-		printf(" error\n");
-		return _URC_FATAL_PHASE1_ERROR;
-	}
-
-	// Get a pointer to the language specific data from which we will read what we need
-	const unsigned char * lsd = (const unsigned char*) _Unwind_GetLanguageSpecificData( context );
-
-	if( !lsd ) {	//Nothing to do, keep unwinding
-		printf(" no LSD");
-		goto UNWIND;
-	}
-
-	// Get the instuction pointer and a reading pointer into the exception table
-	lsda_header_info lsd_info;
-	const unsigned char * cur_ptr = parse_lsda_header( context, lsd, &lsd_info);
-	_Unwind_Ptr instruction_ptr = _Unwind_GetIP( context );
-
-	// Linearly search the table for stuff to do
-	while( cur_ptr < lsd_info.action_table ) {
-		_Unwind_Ptr callsite_start;
-		_Unwind_Ptr callsite_len;
-		_Unwind_Ptr callsite_landing_pad;
-		_uleb128_t  callsite_action;
-
-		// Decode the common stuff we have in here
-		cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_start);
-		cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_len);
-		cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_landing_pad);
-		cur_ptr = read_uleb128 (cur_ptr, &callsite_action);
-
-		// Have we reach the correct frame info yet?
-		if( lsd_info.Start + callsite_start + callsite_len < instruction_ptr ) {
-			//DEBUG BEGIN
-			void * ls = (void*)lsd_info.Start;
-			void * cs = (void*)callsite_start;
-			void * cl = (void*)callsite_len;
-			void * bp = (void*)lsd_info.Start + callsite_start;
-			void * ep = (void*)lsd_info.Start + callsite_start + callsite_len;
-			void * ip = (void*)instruction_ptr;
-			printf("\nfound %p - %p (%p, %p, %p), looking for %p\n", bp, ep, ls, cs, cl, ip);
-			//DEBUG END
-			continue;
-		}
-
-		// Have we gone too far
-		if( lsd_info.Start + callsite_start > instruction_ptr ) {
-			printf(" gone too far");
-			break;
-		}
-
-		// Something to do?
-		if( callsite_landing_pad ) {
-			// Which phase are we in
-			if (actions & _UA_SEARCH_PHASE) {
-				// Search phase, this means we probably found a potential handler and must check if it is a match
-
-				// If we have arbitrarily decided that 0 means nothing to do and 1 means there is a potential handler
-				// This doesn't seem to conflict the gcc default behavior
-				if (callsite_action != 0) {
-					// Now we want to run some code to see if the handler matches
-					// This is the tricky part where we want to the power to run arbitrary code
-					// However, generating a new exception table entry and try routine every time
-					// is way more expansive than we might like
-					// The information we have is :
-					//  - The GR (Series of registers)
-					//    GR1=GP Global Pointer of frame ref by context
-					//  - The instruction pointer
-					//  - The instruction pointer info (???)
-					//  - The CFA (Canonical Frame Address)
-					//  - The BSP (Probably the base stack pointer)
-
-
-					// The current apprach uses one exception table entry per try block
-					_uleb128_t imatcher;
-					// Get the relative offset to the
-					cur_ptr = read_uleb128 (cur_ptr, &imatcher);
-
-					// Get a function pointer from the relative offset and call it
-					// _Unwind_Reason_Code (*matcher)() = (_Unwind_Reason_Code (*)())lsd_info.LPStart + imatcher;					
-
-					_Unwind_Reason_Code (*matcher)() =
-						MATCHER_FROM_CONTEXT(context);
-					int index = matcher(shared_stack.current_exception);
-					_Unwind_Reason_Code ret = (0 == index)
-						? _URC_CONTINUE_UNWIND : _URC_HANDLER_FOUND;
-					shared_stack.current_handler_index = index;
-
-
-					// Based on the return value, check if we matched the exception
-					if( ret == _URC_HANDLER_FOUND) printf(" handler found\n");
-					else printf(" no handler\n");
-					return ret;
-				}
-
-				// This is only a cleanup handler, ignore it
-				printf(" no action");
-			}
-			else if (actions & _UA_CLEANUP_PHASE) {
-
-				if( (callsite_action != 0) && !(actions & _UA_HANDLER_FRAME) ){
-					// If this is a potential exception handler
-					// but not the one that matched the exception in the seach phase,
-					// just ignore it
-					goto UNWIND;
-				}
-
-				// We need to run some clean-up or a handler
-				// These statment do the right thing but I don't know any specifics at all
-				_Unwind_SetGR( context, __builtin_eh_return_data_regno(0), (_Unwind_Ptr) unwind_exception );
-				_Unwind_SetGR( context, __builtin_eh_return_data_regno(1), 0 );
-
-				// I assume this sets the instruction pointer to the adress of the landing pad
-				// It doesn't actually set it, it only state the value that needs to be set once we return _URC_INSTALL_CONTEXT
-				_Unwind_SetIP( context, lsd_info.LPStart + callsite_landing_pad );
-
-				// DEBUG
-				printf(" action\n");
-
-				// Return have some action to run
-				return _URC_INSTALL_CONTEXT;
-			}
-		}
-
-		// Nothing to do, move along
-		printf(" no landing pad");
-	}
-	// No handling found
-	printf(" table end reached\n");
-
-	// DEBUG
-	UNWIND:
-	printf(" unwind\n");
-
-	// Keep unwinding the stack
-	return _URC_CONTINUE_UNWIND;
-}
Index: doc/working/exception/impl/exception.h
===================================================================
--- doc/working/exception/impl/exception.h	(revision bf70aa95b89eb2a7499a5dca8acfa765fa5c2867)
+++ doc/working/exception/impl/exception.h	(revision 838ef08a861624326cedc08c004590769c5eae2b)
@@ -32,3 +32,3 @@
 };
 
-extern struct shared_stack_t stared_stack;
+extern struct shared_stack_t shared_stack;
Index: doc/working/exception/impl/test-main.c
===================================================================
--- doc/working/exception/impl/test-main.c	(revision bf70aa95b89eb2a7499a5dca8acfa765fa5c2867)
+++ doc/working/exception/impl/test-main.c	(revision 838ef08a861624326cedc08c004590769c5eae2b)
@@ -1,5 +1,8 @@
 #include "exception.h"
 
+// Use: gcc -fexceptions -Wall -Werror -g exception.c test-main.c
+
 #include <stdio.h>
+#include <stdbool.h>
 
 // Translation Helpers:
@@ -7,4 +10,19 @@
 	struct __cleanup_hook __hidden_hook __attribute__((cleanup(function)))
 
+#define SET_UP_RESUME_NODE(handler_function) \
+	struct __try_resume_node node \
+		__attribute__((cleanup(__try_resume_node_delete))); \
+	__try_resume_node_new(&node, handler_function)
+
+void __try_resume_node_new(struct __try_resume_node * node,
+        _Bool (*handler)(exception except)) {
+    node->next = shared_stack.top_resume;
+    shared_stack.top_resume = node;
+    node->try_to_handle = handler;
+}
+
+void __try_resume_node_delete(struct __try_resume_node * node) {
+    shared_stack.top_resume = node->next;
+}
 
 // Local Print On Exit:
@@ -19,4 +37,5 @@
 #define raii_t __attribute__((cleanup(raii_dtor))) struct raii_base_type
 
+// ===========================================================================
 // Runtime code (post-translation).
 void terminate(int except_value) {
@@ -34,57 +53,382 @@
 // Termination Test: Two handlers: no catch, catch
 void bar() {
-	void bar_try1() {
-		terminate(4);
-	}
-	void bar_catch1(int index, exception except) {
-		switch(except) {
-		case 1:
-			printf("bar caught exception.\n");
-			break;
-		default:
-			printf("INVALID INDEX in bar: %d\n", except);
-		}
-	}
-	int bar_match1(exception except) {
-		if (3 == except) {
-			return 1;
-		} else {
-			return 0;
-		}
-	}
-	__try_terminate(bar_try1, bar_catch1, bar_match1);
+	raii_t a = {"bar function"};
+	{
+		void bar_try1() {
+			terminate(4);
+		}
+		void bar_catch1(int index, exception except) {
+			switch(except) {
+			case 1:
+				printf("bar caught exception 3.\n");
+				break;
+			default:
+				printf("INVALID INDEX in bar: %d (%d)\n", index, except);
+			}
+		}
+		int bar_match1(exception except) {
+			if (3 == except) {
+				return 1;
+			} else {
+				return 0;
+			}
+		}
+		__try_terminate(bar_try1, bar_catch1, bar_match1);
+	}
 }
 
 void foo() {
-	void foo_try1() {
-		bar();
-	}
-	void foo_catch1(int index, exception except) {
-		switch(except) {
-		case 1:
-			printf("foo caught exception 4.\n");
-			break;
-		case 2:
-			printf("foo caught exception 2.\n");
-			break;
-		default:
-			printf("INVALID INDEX in foo: %d\n", except);
-		}
-	}
-	int foo_match1(exception except) {
-		if (4 == except) {
-			return 1;
-		} else if (2 == except) {
-			return 2;
-		} else {
-			return 0;
-		}
-	}
-	__try_terminate(foo_try1, foo_catch1, foo_match1);
-}
-
+	raii_t a = {"foo function"};
+	{
+		void foo_try1() {
+			bar();
+		}
+		void foo_catch1(int index, exception except) {
+			switch(index) {
+			case 1:
+				printf("foo caught exception 4.\n");
+				break;
+			case 2:
+				printf("foo caught exception 2.\n");
+				break;
+			default:
+				printf("INVALID INDEX in foo: %d (%d)\n", index, except);
+			}
+		}
+		int foo_match1(exception except) {
+			if (4 == except) {
+				return 1;
+			} else if (2 == except) {
+				return 2;
+			} else {
+				return 0;
+			}
+		}
+		__try_terminate(foo_try1, foo_catch1, foo_match1);
+	}
+}
+
+// Resumption Two Handler Test: no catch, catch.
+void beta() {
+	raii_t a = {"beta function"};
+	{
+		bool beta_handle1(exception except) {
+			if (3 == except) {
+				printf("beta caught exception 3\n");
+				return true;
+			} else {
+				return false;
+			}
+		}
+		struct __try_resume_node node
+			__attribute__((cleanup(__try_resume_node_delete)));
+		__try_resume_node_new(&node, beta_handle1);
+		{
+			resume(4);
+		}
+	}
+}
+void alpha() {
+	raii_t a = {"alpha function"};
+	{
+		bool alpha_handle1(exception except) {
+			if (2 == except) {
+				printf("alpha caught exception 2\n");
+				return true;
+			} else if (4 == except) {
+				printf("alpha caught exception 4\n");
+				return true;
+			} else {
+				return false;
+			}
+		}
+		struct __try_resume_node node
+			__attribute__((cleanup(__try_resume_node_delete)));
+		__try_resume_node_new(&node, alpha_handle1);
+		{
+			beta();
+		}
+	}
+}
+
+// Finally Test:
+void farewell() {
+	{
+		void farewell_finally1() {
+			printf("See you next time\n");
+		}
+		struct __cleanup_hook __hidden_hook
+			__attribute__((cleanup(farewell_finally1)));
+		{
+			printf("walk out of farewell\n");
+		}
+	}
+}
+
+// Resume-to-Terminate Test:
+void fallback() {
+	{
+		void fallback_try1() {
+			resume(1);
+		}
+		void fallback_catch1(int index, exception except) {
+			switch (index) {
+			case 1:
+				printf("fallback caught termination 1\n");
+				break;
+			default:
+				printf("INVALID INDEX in fallback: %d (%d)\n", index, except);
+			}
+		}
+		int fallback_match1(exception except) {
+			if (1 == except) {
+				return 1;
+			} else {
+				return 0;
+			}
+		}
+		__try_terminate(fallback_try1, fallback_catch1, fallback_match1);
+	}
+}
+
+// Terminate Throw New Exception:
+void terminate_swap() {
+	raii_t a = {"terminate_swap"};
+	{
+		void fn_try1() {
+			terminate(2);
+		}
+		void fn_catch1(int index, exception except) {
+			switch (index) {
+			case 1:
+				terminate(1);
+				break;
+			default:
+				printf("INVALID INDEX in terminate_swap: %d (%d)\n",
+					index, except);
+			}
+		}
+		int fn_match1(exception except) {
+			if (2 == except) {
+				return 1;
+			} else {
+				return 0;
+			}
+		}
+		__try_terminate(fn_try1, fn_catch1, fn_match1);
+	}
+}
+
+void terminate_swapped() {
+	raii_t a = {"terminate_swapped"};
+	{
+		void fn_try1() {
+			terminate_swap();
+		}
+		void fn_catch1(int index, exception except) {
+			switch (index) {
+			case 1:
+				printf("terminate_swapped caught exception 1\n");
+				break;
+			default:
+				printf("INVALID INDEX in terminate_swapped: %d (%d)\n",
+					index, except);
+			}
+		}
+		int fn_match1(exception except) {
+			if (1 == except) {
+				return 1;
+			} else {
+				return 0;
+			}
+		}
+		__try_terminate(fn_try1, fn_catch1, fn_match1);
+	}
+}
+
+// Resume Throw New Exception:
+void resume_swap() {
+	raii_t a = {"terminate_swap"};
+	{
+		bool fn_handle1(exception except) {
+			if (2 == except) {
+				resume(1);
+				return true;
+			} else {
+				return false;
+			}
+		}
+		struct __try_resume_node node
+			__attribute__((cleanup(__try_resume_node_delete)));
+		__try_resume_node_new(&node, fn_handle1);
+		{
+			resume(2);
+		}
+	}
+}
+
+void resume_swapped() {
+	{
+		bool fn_handle1(exception except) {
+			if (1 == except) {
+				printf("resume_swapped caught exception 1\n");
+				return true;
+			} else {
+				return false;
+			}
+		}
+		struct __try_resume_node node
+			__attribute__((cleanup(__try_resume_node_delete)));
+		__try_resume_node_new(&node, fn_handle1);
+		{
+			resume_swap();
+		}
+	}
+}
+
+// Terminate Rethrow:
+// I don't have an implementation for this.
+
+// Resume Rethrow:
+void reresume() {
+	{
+		bool reresume_handle1(exception except) {
+			if (1 == except) {
+				printf("reresume 1 caught exception 1\n");
+				return true;
+			} else {
+				return false;
+			}
+		}
+		struct __try_resume_node node
+			__attribute__((cleanup(__try_resume_node_delete)));
+		__try_resume_node_new(&node, reresume_handle1);
+		{
+			bool reresume_handle2(exception except) {
+				if (1 == except) {
+					printf("reresume 2 caught and rethrows exception 1\n");
+					return false;
+				} else {
+					return false;
+				}
+			}
+			struct __try_resume_node node
+				__attribute__((cleanup(__try_resume_node_delete)));
+			__try_resume_node_new(&node, reresume_handle2);
+			{
+				resume(1);
+			}
+		}
+	}
+}
+
+// Terminate-Resume interaction:
+void fum() {
+	// terminate block, call resume
+	{
+		void fum_try1() {
+			resume(3);
+		}
+		void fum_catch1(int index, exception except) {
+			switch (index) {
+			case 1:
+				printf("fum caught exception 3\n");
+				break;
+			default:
+				printf("INVALID INDEX in fum: %d (%d)\n", index, except);
+			}
+		}
+		int fum_match1(exception except) {
+			if (3 == except) {
+				return 1;
+			} else {
+				return 0;
+			}
+		}
+		__try_terminate(fum_try1, fum_catch1, fum_match1);
+	}
+}
+
+void foe() {
+	// resume block, call terminate
+	{
+		bool foe_handle1(exception except) {
+			if (3 == except) {
+				printf("foe caught exception 3\n");
+				return true;
+			} else {
+				return false;
+			}
+		}
+		struct __try_resume_node node
+			__attribute__((cleanup(__try_resume_node_delete)));
+		__try_resume_node_new(&node, foe_handle1);
+		{
+			terminate(3);
+		}
+	}
+}
+
+void fy() {
+	// terminate block calls fum, call foe
+	{
+		void fy_try1() {
+			foe();
+		}
+		void fy_catch1(int index, exception except) {
+			switch (index) {
+			case 1:
+				printf("fy caught exception 3\n");
+				fum();
+				break;
+			default:
+				printf("INVALID INDEX in fy: %d (%d)\n", index, except);
+			}
+		}
+		int fy_match1(exception except) {
+			if (3 == except) {
+				return 1;
+			} else {
+				return 0;
+			}
+		}
+		__try_terminate(fy_try1, fy_catch1, fy_match1);
+	}
+}
+
+void fee() {
+	// resume block, call fy
+	{
+		bool fee_handle1(exception except) {
+			if (3 == except) {
+				printf("fee caught exception 3\n");
+				return true;
+			} else {
+				return false;
+			}
+		}
+		struct __try_resume_node node
+			__attribute__((cleanup(__try_resume_node_delete)));
+		__try_resume_node_new(&node, fee_handle1);
+		{
+			fy();
+		}
+	}
+}
+
+
+// main: choose which tests to run
 int main(int argc, char * argv[]) {
 	raii_t a = {"main function"};
 
-	foo();
-}
+	foo(); printf("\n");
+	alpha(); printf("\n");
+	farewell(); printf("\n");
+	fallback(); printf("\n");
+	terminate_swapped(); printf("\n");
+	resume_swapped(); printf("\n");
+	reresume(); printf("\n");
+	fee(); printf("\n");
+	// Uncaught termination test.
+	terminate(7);
+}
Index: doc/working/exception/translate.c
===================================================================
--- doc/working/exception/translate.c	(revision bf70aa95b89eb2a7499a5dca8acfa765fa5c2867)
+++ doc/working/exception/translate.c	(revision 838ef08a861624326cedc08c004590769c5eae2b)
@@ -237,5 +237,6 @@
 		}
 		void finally1() {
-			// (Finally, because of timing, also work for resume.)
+			// Finally, because of timing, also works for resume.
+			// However this might not actually be better in any way.
 			__try_resume_cleanup();
 
