Index: examples/gc_no_raii/.gitignore
===================================================================
--- examples/gc_no_raii/.gitignore	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/.gitignore	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,4 @@
+.tags
+.tags*
+gc-test
+build/
Index: examples/gc_no_raii/bug-repro/assert.c
===================================================================
--- examples/gc_no_raii/bug-repro/assert.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/assert.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,16 @@
+struct gc_object_header{
+ int size;
+};
+
+struct gc_state;
+
+inline _Bool needs_collect(gc_state* state) {
+ return state->used_space > 0;
+}
+
+struct gc_object_header* gc_get_object_for_ref();
+
+inline gc_object_header* gc_get_object_ptr(void* ptr)
+{
+ return 0;
+}
Index: examples/gc_no_raii/bug-repro/blockers/explicit_cast.c
===================================================================
--- examples/gc_no_raii/bug-repro/blockers/explicit_cast.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/blockers/explicit_cast.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,22 @@
+
+#include <stdbool.h>
+#include <stdint.h>
+
+struct gcpointer_t
+{
+	intptr_t ptr;
+	struct gcpointer_t* next;
+};
+
+forall(otype T)
+struct gcpointer
+{
+	gcpointer_t internal;
+};
+
+forall(otype T)
+static inline gcpointer(T) gcmalloc()
+{
+    gcpointer(T) test;
+    return test;
+}
Index: examples/gc_no_raii/bug-repro/blockers/file_scope.c
===================================================================
--- examples/gc_no_raii/bug-repro/blockers/file_scope.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/blockers/file_scope.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,18 @@
+
+#include <stdbool.h>
+#include <stdlib>
+
+#define POOL_SIZE_EXP 24
+#define POOL_SIZE_BYTES 0x1 << POOL_SIZE_EXP
+#define POOL_PTR_MASK ~(POOL_SIZE_BYTES - 1)
+
+#define CARDS_SIZE_EXP 12
+#define CARDS_SIZE_BYTES 0x1 << CARDS_SIZE_EXP
+#define CARDS_OFFSET_MASK (~(CARDS_SIZE_BYTES - 1)) & (POOL_SIZE_BYTES - 1)
+#define CARDS_COUNT POOL_SIZE_BYTES / CARDS_SIZE_BYTES
+
+struct card_table_t
+{
+	size_t count;
+	void* cards_start[CARDS_COUNT];
+};
Index: examples/gc_no_raii/bug-repro/blockers/recursive_realloc.c
===================================================================
--- examples/gc_no_raii/bug-repro/blockers/recursive_realloc.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/blockers/recursive_realloc.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,21 @@
+
+#include <stdbool.h>
+#include <stdlib>
+
+trait allocator_c(otype T, otype allocator_t)
+{
+	void realloc(allocator_t* const, size_t);
+};
+
+forall(otype T)
+struct heap_allocator
+{
+	T* storage;
+	size_t capacity;
+};
+
+forall(otype T)
+inline void realloc(heap_allocator(T) *const this, size_t size)
+{
+	this->storage = (T*)realloc((void*)this->storage, this->capacity);
+}
Index: examples/gc_no_raii/bug-repro/crash.c
===================================================================
--- examples/gc_no_raii/bug-repro/crash.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/crash.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,6 @@
+
+void f()
+{
+ void* obj;
+ (void)obj;
+}
Index: examples/gc_no_raii/bug-repro/deref.c
===================================================================
--- examples/gc_no_raii/bug-repro/deref.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/deref.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,19 @@
+    forall(otype T)
+    struct wrap
+    {
+        T val;
+    };
+
+    forall(otype T)
+    T *? (wrap(T) rhs)
+    {
+        return rhs.val;
+    }
+
+    int main(int argc, char const *argv[])
+    {
+        wrap(int) test;
+        test.val = 3;
+        int i = *test;
+        return 0;
+    }
Index: examples/gc_no_raii/bug-repro/field.c
===================================================================
--- examples/gc_no_raii/bug-repro/field.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/field.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,130 @@
+extern "C" {
+#include <stdbool.h>
+#include <stdint.h>
+}
+
+#include <stdlib>
+
+//------------------------------------------------------------------------------
+//Declaration
+trait allocator_c(otype T, otype allocator_t)
+{
+	void ctor(allocator_t* const);
+	void dtor(allocator_t* const);
+	void realloc(allocator_t* const, size_t);
+	T* data(allocator_t* const);
+};
+
+forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
+struct vector
+{
+	allocator_t storage;
+	size_t size;
+};
+
+int global = 3;
+
+struct card_table_t
+{
+	size_t count;
+	void* cards_start[100];
+};
+
+static inline void ctor(card_table_t* const this)
+{
+	this->count = 0;
+}
+
+struct gc_memory_pool
+{
+	struct memory_pool* mirror;
+	struct memory_pool* next;
+
+	uint8_t type_code;
+
+	card_table_t* cards;
+
+	uint8_t* end_p;
+	uint8_t* free_p;
+	uint8_t start_p[1];
+};
+
+void ctor(	gc_memory_pool *const this,
+		size_t size,
+		gc_memory_pool* next,
+		gc_memory_pool* mirror,
+		uint8_t type
+	);
+
+void dtor(gc_memory_pool *const this);
+
+struct gc_pool_object_iterator
+{
+	struct gc_object_header* object;
+	#ifndef NDEBUG
+		intptr_t lower_limit;
+		intptr_t upper_limit;
+	#endif
+};
+
+void ctor(
+		gc_pool_object_iterator* const this,
+		void* start_object
+		#ifndef NDEBUG
+			, intptr_t pool_start
+			, intptr_t pool_end
+		#endif
+	);
+
+bool ?!=?(const gc_pool_object_iterator lhs, const gc_pool_object_iterator rhs);
+
+gc_pool_object_iterator begin(gc_memory_pool* const this);
+gc_pool_object_iterator end(gc_memory_pool* const);
+
+gc_pool_object_iterator* ++?(gc_pool_object_iterator* it);
+
+const void* *?(const gc_pool_object_iterator it);
+void* *?(gc_pool_object_iterator it);
+
+static inline bool gc_pool_is_from_space(const gc_memory_pool* pool)
+{
+	return false;
+}
+
+void gc_reset_pool(gc_memory_pool* const pool);
+
+static inline size_t gc_pool_size_used(const gc_memory_pool* pool)
+{
+	return pool->free_p - pool->start_p;
+}
+
+static inline size_t gc_pool_size_total(const gc_memory_pool* pool)
+{
+	return pool->end_p - pool->start_p;
+}
+
+static inline size_t gc_pool_size_left(const gc_memory_pool* pool)
+{
+	return pool->end_p - pool->free_p;
+}
+
+void* gc_pool_allocate(gc_memory_pool* const pool, size_t size, bool zero);
+
+gc_pool_object_iterator gc_pool_iterator_for(gc_memory_pool* const pool, void* member);
+
+void ctor(gc_memory_pool *const this, size_t size, gc_memory_pool* next, gc_memory_pool* mirror, uint8_t type)
+{
+	this->mirror = mirror;
+	this->next = next;
+	this->type_code = type;
+
+	this->cards = malloc();
+	ctor(this->cards);
+
+	this->end_p = ((uint8_t*)this) + size;
+	this->free_p = this->start_p;
+
+	// check(gc_pool_of(this) == this);
+	// check(this->cards);
+	// gc_reset_pool(this);
+}
Index: examples/gc_no_raii/bug-repro/find.c
===================================================================
--- examples/gc_no_raii/bug-repro/find.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/find.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,10 @@
+
+void main()
+{
+	int a[3] = {1, 2, 3};
+	int* begin = a;
+	int *const end = begin + 3;
+
+	int* f = find(begin, &end, 2);
+
+}
Index: examples/gc_no_raii/bug-repro/inline.c
===================================================================
--- examples/gc_no_raii/bug-repro/inline.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/inline.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,8 @@
+inline _Bool test(int t){
+	return t == 3;
+}
+
+int main()
+{
+	test(6);
+}
Index: examples/gc_no_raii/bug-repro/malloc.c
===================================================================
--- examples/gc_no_raii/bug-repro/malloc.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/malloc.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,33 @@
+forall(otype T)
+struct wrapper
+{
+    T val;
+};
+
+forall(otype T)
+void ctor(wrapper(T)* this)
+{
+    this->val = 0;
+}
+
+forall(otype T)
+wrapper(T) gcmalloc()
+{
+    wrapper(T) w;
+    ctor(&w);
+    return w;
+}
+
+forall(otype T)
+wrapper(T)* ?=? (wrapper(T)* lhs, wrapper(T)* rhs)
+{
+    lhs->val = rhs->val;
+    return lhs;
+}
+
+int main(int argc, char *argv[])
+{
+    wrapper(int) test;
+    test = gcmalloc();
+    return 0;
+}
Index: examples/gc_no_raii/bug-repro/not_equal.c
===================================================================
--- examples/gc_no_raii/bug-repro/not_equal.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/not_equal.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,10 @@
+
+struct pointer_t
+{
+	void* p;
+};
+
+_Bool operator_not_equal_p(pointer_t* lhs, pointer_t* rhs)
+{
+	return lhs->p == rhs->p;
+}
Index: examples/gc_no_raii/bug-repro/oddtype.c
===================================================================
--- examples/gc_no_raii/bug-repro/oddtype.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/oddtype.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,13 @@
+forall(dtype T)
+struct wrap {
+	int i;
+};
+
+forall(otype T) void ?{}(wrap(T)* this) {}
+forall(otype T) void ?=?(wrap(T)* this) {}
+forall(otype T) void ^?{}(wrap(T)* this) {}
+
+struct List_t {
+	int val;
+	wrap(List_t) next;
+};
Index: examples/gc_no_raii/bug-repro/push_back.c
===================================================================
--- examples/gc_no_raii/bug-repro/push_back.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/push_back.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,16 @@
+#include <stddef.h>
+#include <stdint.h>
+
+#include "push_back.h"
+
+typedef vector(intptr_t*, heap_allocator(intptr_t*)) worklist_t;
+
+void test()
+{
+	worklist_t w;
+	if(!empty(&w))
+	{
+		intptr_t zero = 0;
+		push_back(&w, &zero);
+	}
+}
Index: examples/gc_no_raii/bug-repro/push_back.h
===================================================================
--- examples/gc_no_raii/bug-repro/push_back.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/push_back.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,72 @@
+//------------------------------------------------------------------------------
+//Declaration
+trait allocator_c(otype T, otype allocator_t) {
+	void ctor(allocator_t* const);
+	void dtor(allocator_t* const);
+	void realloc(allocator_t* const, size_t);
+	T* data(allocator_t* const);
+};
+
+forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
+struct vector
+{
+	allocator_t storage;
+	size_t size;
+};
+
+//------------------------------------------------------------------------------
+//Initialization
+forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
+void vector_ctor(vector(T, allocator_t) *const this);
+
+forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
+void dtor(vector(T, allocator_t) *const this);
+
+//------------------------------------------------------------------------------
+//Allocator
+forall(otype T)
+struct heap_allocator
+{
+	T* storage;
+	size_t capacity;
+};
+
+forall(otype T)
+void ctor(heap_allocator(T) *const this);
+
+forall(otype T)
+void dtor(heap_allocator(T) *const this);
+
+forall(otype T)
+void realloc(heap_allocator(T) *const this, size_t size);
+
+forall(otype T)
+inline T* data(heap_allocator(T) *const this)
+{
+	return this->storage;
+}
+
+//------------------------------------------------------------------------------
+//Capacity
+forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
+inline bool empty(vector(T, allocator_t) *const this)
+{
+	return this->size == 0;
+}
+
+forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
+inline bool size(vector(T, allocator_t) *const this)
+{
+	return this->size;
+}
+
+forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
+inline void reserve(vector(T, allocator_t) *const this, size_t size)
+{
+	realloc(&this->storage, this->size+1);
+}
+
+//------------------------------------------------------------------------------
+//Modifiers
+forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
+void push_back(vector(T, allocator_t) *const this, T value);
Index: examples/gc_no_raii/bug-repro/realloc.c
===================================================================
--- examples/gc_no_raii/bug-repro/realloc.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/realloc.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,13 @@
+void* realloc(void*, unsigned long int);
+
+forall(otype T)
+struct wrap
+{
+	T* val;
+};
+
+forall(otype T)
+static inline void realloc(wrap(T) *const this, unsigned long int size)
+{
+	this->val = (T*)realloc((void*)this->val, size);
+}
Index: examples/gc_no_raii/bug-repro/return.c
===================================================================
--- examples/gc_no_raii/bug-repro/return.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/return.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,27 @@
+forall(otype T)
+struct wrapper
+{
+	T value;
+};
+
+forall(otype T)
+wrapper(T) create()
+{
+	wrapper(T) test;
+	return test;
+}
+
+forall(otype T)
+wrapper(T)* ?=?(wrapper(T)* lhs, wrapper(T)* rhs)
+{
+	lhs->value = rhs->value;
+	return lhs;
+}
+
+
+int main(int argc, char const *argv[])
+{
+	wrapper(int) test;
+	test = create();
+	return 0;
+}
Index: examples/gc_no_raii/bug-repro/return_template.c
===================================================================
--- examples/gc_no_raii/bug-repro/return_template.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/return_template.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,17 @@
+forall(otype T)
+struct wrap
+{
+	T value;
+};
+
+forall(otype T) void ?{}(wrap(T)* this);
+forall(otype T) void ?{}(wrap(T)* this, wrap(T)* rhs);
+forall(otype T) void ^?{}(wrap(T)* this);
+forall(otype T) void ?=?(wrap(T)* this, wrap(T)* rhs);
+
+forall(otype T)
+wrap(T) test()
+{
+	wrap(T) tester;
+	return tester;
+}
Index: examples/gc_no_raii/bug-repro/slow_malloc.c
===================================================================
--- examples/gc_no_raii/bug-repro/slow_malloc.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/slow_malloc.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,20 @@
+#include <stdlib>
+
+forall(otype T)
+struct heap_allocator
+{
+	T* storage;
+	size_t capacity;
+};
+
+struct card_table_t
+{
+	unsigned long int count;
+	void* cards_start[1000];
+};
+
+int main(int argc, char const *argv[])
+{
+	card_table_t* t = (card_table_t*)malloc(sizeof(card_table_t));
+	return 0;
+}
Index: examples/gc_no_raii/bug-repro/static_const_local.c
===================================================================
--- examples/gc_no_raii/bug-repro/static_const_local.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/static_const_local.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,6 @@
+typedef unsigned long long size_t;
+
+int main(int argc, char const *argv[]) {
+	static const size_t GROWTH_RATE = 2;
+	return 0;
+}
Index: examples/gc_no_raii/bug-repro/test-assert.cpp
===================================================================
--- examples/gc_no_raii/bug-repro/test-assert.cpp	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/test-assert.cpp	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,9 @@
+#include <cassert>
+#include "../src/tools/checks.h"
+
+int main(int argc, char* argv[])
+{
+	//check(false);
+	assert(false);
+	return 0;
+}
Index: examples/gc_no_raii/bug-repro/void_pointer.c
===================================================================
--- examples/gc_no_raii/bug-repro/void_pointer.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/void_pointer.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,18 @@
+#include <stddef.h>
+#include <stdint.h>
+
+inline void* test(intptr_t address)
+{
+	return (void*)address;
+}
+
+//inline void* test2(void* address)
+//{
+//	return address & 0xFF;
+//}
+
+// inline int test()
+// {
+// 	void* d = 0;
+// 	return (int)d;
+// }
Index: examples/gc_no_raii/bug-repro/while.c
===================================================================
--- examples/gc_no_raii/bug-repro/while.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/while.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,14 @@
+extern void* get_member();
+extern void* get_next();
+
+void main()
+{
+	void* member = get_member();
+	void* start_obj = get_next();
+
+	do
+	{
+		start_obj = (void*) ( ((unsigned long int)start_obj) + sizeof(void*) );
+	}
+	while(start_obj > member || !(start_obj) );
+}
Index: examples/gc_no_raii/bug-repro/zero.c
===================================================================
--- examples/gc_no_raii/bug-repro/zero.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/bug-repro/zero.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,25 @@
+forall(otype T)
+struct wrap
+{
+    T val;
+};
+
+forall(otype T)
+int ?==? (wrap(T) lhs, wrap(T) rhs)
+{
+    return 0;
+}
+
+/*
+struct wrap(int) 0;
+/*/
+forall(otype T)
+struct wrap(T) 0;
+//*/
+
+int main(int argc, char const *argv[])
+{
+    wrap(int) test;
+    if(test == 0) { return 1; }
+    return 0;
+}
Index: examples/gc_no_raii/pool-alloc/allocate-malign.c
===================================================================
--- examples/gc_no_raii/pool-alloc/allocate-malign.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/pool-alloc/allocate-malign.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,30 @@
+/*
+ * Allocation functions (posix_malign)
+ *
+ * Copyright (c) 2014, 2015 Gregor Richards
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+static void *allocPool(size_t size, int mustSucceed)
+{
+    void *ret;
+    if ((errno = posix_memalign(&ret, size, size))) {
+        if (mustSucceed) {
+            perror("posix_memalign");
+            abort();
+        }
+        return NULL;
+    }
+    return ret;
+}
Index: examples/gc_no_raii/pool-alloc/allocate-malloc.c
===================================================================
--- examples/gc_no_raii/pool-alloc/allocate-malloc.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/pool-alloc/allocate-malloc.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,53 @@
+/*
+ * Allocation functions (malloc)
+ *
+ * Copyright (c) 2014, 2015 Gregor Richards
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+static void *allocPool(int mustSucceed)
+{
+    static ggc_mutex_t poolLock = GGC_MUTEX_INITIALIZER;
+    static unsigned char *space = NULL, *spaceEnd = NULL;
+    void *ret;
+
+    /* do we already have some available space? */
+    ggc_mutex_lock_raw(&poolLock);
+    if (!space || space + GGGGC_POOL_BYTES > spaceEnd) {
+        ggc_size_t i;
+
+        /* since we can't pre-align, align by getting as much as we can manage */
+        for (i = 16; i >= 2; i /= 2) {
+            space = malloc(GGGGC_POOL_BYTES * i);
+            if (space) break;
+        }
+        if (!space) {
+            if (mustSucceed) {
+                perror("malloc");
+                abort();
+            }
+            return NULL;
+        }
+        spaceEnd = space + GGGGC_POOL_BYTES * i;
+
+        /* align it */
+        space = (unsigned char *) GGGGC_POOL_OF(space + GGGGC_POOL_BYTES - 1);
+    }
+
+    ret = (struct GGGGC_Pool *) space;
+    space += GGGGC_POOL_BYTES;
+    ggc_mutex_unlock(&poolLock);
+
+    return ret;
+}
Index: examples/gc_no_raii/pool-alloc/allocate-mmap.c
===================================================================
--- examples/gc_no_raii/pool-alloc/allocate-mmap.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/pool-alloc/allocate-mmap.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,44 @@
+/*
+ * Allocation functions (mmap)
+ *
+ * Copyright (c) 2014, 2015 Gregor Richards
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+static void *allocPool(int mustSucceed)
+{
+    unsigned char *space, *aspace;
+    struct GGGGC_Pool *ret;
+
+    /* allocate enough space that we can align it later */
+    space = mmap(NULL, GGGGC_POOL_BYTES*2, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
+    if (space == NULL) {
+        if (mustSucceed) {
+            perror("mmap");
+            abort();
+        }
+        return NULL;
+    }
+
+    /* align it */
+    ret = GGGGC_POOL_OF(space + GGGGC_POOL_BYTES - 1);
+    aspace = (unsigned char *) ret;
+
+    /* free unused space */
+    if (aspace > space)
+        munmap(space, aspace - space);
+    munmap(aspace + GGGGC_POOL_BYTES, space + GGGGC_POOL_BYTES - aspace);
+
+    return ret;
+}
Index: examples/gc_no_raii/pool-alloc/allocate-win-valloc.c
===================================================================
--- examples/gc_no_raii/pool-alloc/allocate-win-valloc.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/pool-alloc/allocate-win-valloc.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,45 @@
+/*
+ * Allocation functions (mmap)
+ *
+ * Copyright (c) 2014, 2015 Gregor Richards
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+static void *allocPool(int mustSucceed)
+{
+    unsigned char *space, *aspace;
+    struct GGGGC_Pool *ret;
+
+    /* allocate enough space that we can align it later */
+    space = (unsigned char *)
+        VirtualAlloc(NULL, GGGGC_POOL_BYTES*2, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
+    if (space == NULL) {
+        if (mustSucceed) {
+            perror("mmap");
+            abort();
+        }
+        return NULL;
+    }
+
+    /* align it */
+    ret = GGGGC_POOL_OF(space + GGGGC_POOL_BYTES - 1);
+    aspace = (unsigned char *) ret;
+
+    /* free unused space */
+    if (aspace > space)
+        VirtualFree(space, aspace - space, MEM_RELEASE);
+    VirtualFree(aspace + GGGGC_POOL_BYTES, space + GGGGC_POOL_BYTES - aspace, MEM_RELEASE);
+
+    return ret;
+}
Index: examples/gc_no_raii/premake4.lua
===================================================================
--- examples/gc_no_raii/premake4.lua	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/premake4.lua	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,82 @@
+#!lua
+
+-- Additional Linux libs: "X11", "Xxf86vm", "Xi", "Xrandr", "stdc++"
+
+includeDirList = {
+	"src/",
+	"../"
+}
+
+libDirectories = {
+
+}
+
+
+if os.get() == "linux" then
+    linkLibs = {
+
+    }
+end
+
+-- Build Options:
+buildOptions = {
+      "-g",
+	"-DTEST_FILE=${test}",
+      "\n  test = gctest",
+	"\n  CC = cfa\n  CXX = cfa", }
+
+solution "GC-no-RAII"
+	configurations  { "debug", "release",
+				"cproc-debug", "cproc-release",
+				"cfa-debug", "cfa-release" }
+
+	project "gc-test"
+		kind "ConsoleApp"
+		language "C"
+		location "build"
+		objdir "build"
+		targetdir "."
+		buildoptions (buildOptions)
+		defines {	"bool=_Bool",
+				"\"true=((_Bool)(const signed int)1)\"",
+				"\"false=((_Bool)(const signed int)0)\"",
+				"_GNU_SOURCE",
+				"__cforall"
+			}
+		libdirs (libDirectories)
+		links (linkLibs)
+		linkoptions (linkOptionList)
+		includedirs (includeDirList)
+		files { "src/**.c", "containers/**.c" }
+
+	configuration "debug"
+		defines { "DEBUG" }
+		flags { "Symbols" }
+
+	configuration "release"
+		defines { "NDEBUG" }
+		flags { "Optimize" }
+
+	configuration "cproc-debug"
+		buildoptions ({"-E"})
+		linkoptions ({"-E"})
+	      defines { "DEBUG" }
+	      flags { "Symbols" }
+
+	configuration "cproc-release"
+		buildoptions ({"-E"})
+		linkoptions ({"-E"})
+	      defines { "DEBUG" }
+	      flags { "Symbols" }
+
+	configuration "cfa-debug"
+		linkoptions ({"-E"})
+		files { "build/cproc-debug/*.o" }
+	      defines { "DEBUG" }
+	      flags { "Symbols" }
+
+	configuration "cfa-release"
+		linkoptions ({"-E"})
+		files { "build/cproc-debug/*.o" }
+	      defines { "DEBUG" }
+	      flags { "Symbols" }
Index: examples/gc_no_raii/src/allocate-pool.c
===================================================================
--- examples/gc_no_raii/src/allocate-pool.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/allocate-pool.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,64 @@
+#define _BSD_SOURCE /* for MAP_ANON */
+#define _DARWIN_C_SOURCE /* for MAP_ANON on OS X */
+
+#ifdef __cforall
+extern "C"{
+#else
+#error missing cfa define
+#endif
+
+/* for standards info */
+#if defined(unix) || defined(__unix) || defined(__unix__) || \
+    (defined(__APPLE__) && defined(__MACH__))
+#include <unistd.h>
+#endif
+
+#if defined(_WIN32)
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#endif
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+
+#if _POSIX_VERSION
+#include <sys/mman.h>
+#endif
+
+/* figure out which allocator to use */
+#if defined(GGGGC_USE_MALLOC)
+#define GGGGC_ALLOCATOR_MALLOC 1
+#include "../pool-alloc/allocate-malloc.c"
+
+#elif _POSIX_ADVISORY_INFO >= 200112L
+#define GGGGC_ALLOCATOR_POSIX_MEMALIGN 1
+#include "../pool-alloc/allocate-malign.c"
+
+#elif defined(MAP_ANON)
+#define GGGGC_ALLOCATOR_MMAP 1
+#include "../pool-alloc/allocate-mmap.c"
+
+#elif defined(_WIN32)
+#define GGGGC_ALLOCATOR_VIRTUALALLOC 1
+#include "../pool-alloc/allocate-win-valloc.c"
+
+#else
+#warning GGGGC: No allocator available other than malloc!
+#define GGGGC_ALLOCATOR_MALLOC 1
+#include "../pool-alloc/allocate-malloc.c"
+
+#endif
+
+void* pal_allocPool(size_t size, int mustSucceed)
+{
+      return allocPool(size, mustSucceed);
+}
+
+#ifdef __cforall
+}
+#endif
Index: examples/gc_no_raii/src/allocate-pool.h
===================================================================
--- examples/gc_no_raii/src/allocate-pool.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/allocate-pool.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,14 @@
+#ifndef _GGGGC_ALlOCATE_POOL_H_
+#define _GGGGC_ALlOCATE_POOL_H_
+
+#ifdef __cforall
+extern "C" {
+#endif
+
+void* pal_allocPool(size_t size, int mustSucceed);
+
+#ifdef __cforall
+}
+#endif
+
+#endif
Index: examples/gc_no_raii/src/gc.h
===================================================================
--- examples/gc_no_raii/src/gc.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/gc.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "gcpointers.h"
+#include "internal/collector.h"
+
+// forall(otype T)
+// static inline gcpointer(T) gcmalloc()
+// {
+//     gcpointer(T) ptr = { gc_allocate(sizeof(T)) };
+//     ptr{};
+//     gc_conditional_collect();
+//     return ptr;
+// }
+
+forall(otype T)
+static inline void gcmalloc(gcpointer(T)* ptr)
+{
+	ptr { gc_allocate(sizeof(T)) };
+	get(ptr) {};
+      gc_conditional_collect();
+}
Index: examples/gc_no_raii/src/gcpointers.c
===================================================================
--- examples/gc_no_raii/src/gcpointers.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/gcpointers.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,147 @@
+#include "gcpointers.h"
+
+// #include "gc.h"
+#include "internal/collector.h"
+#include "internal/object_header.h"
+#include "internal/state.h"
+
+void register_ptr(gcpointer_t* this)
+{
+	if(gcpointer_null(this)) return;
+
+	if(gc_is_managed(this))
+	{
+		gc_object_header* obj = gc_get_object_for_ref(gc_get_state(), (void*)this);
+		check(obj);
+		check(is_valid(obj));
+		check(gc_is_managed(this) == gc_is_managed(obj->type_chain) || !obj->type_chain);
+		this->next = obj->type_chain;
+		obj->type_chain = this;
+		check(is_valid(obj));
+	}
+	else
+	{
+		gc_object_header* obj = gc_get_object_ptr((void*)this->ptr);
+		check(obj);
+		check(is_valid(obj));
+		check(!obj->root_chain || this->ptr == obj->root_chain->ptr);
+		check(!obj->root_chain || gc_is_managed(this) == gc_is_managed(obj->root_chain));
+		this->next = obj->root_chain;
+		obj->root_chain = this;
+		check(is_valid(obj));
+	}
+}
+
+void unregister_ptr(gcpointer_t* this)
+{
+	if(gcpointer_null(this)) return;
+
+	gcpointer_t** prev_next_ptr = gc_find_previous_ref(this);
+	check((*prev_next_ptr) == this);
+
+	(*prev_next_ptr) = this->next;
+}
+
+void ?{}(gcpointer_t* this)
+{
+	this->ptr = (intptr_t)NULL;
+	this->next = NULL;
+}
+
+void ?{}(gcpointer_t* this, void* address)
+{
+	this->ptr = (intptr_t)address;
+	this->next = NULL;
+
+	register_ptr(this);
+}
+
+void ?{}(gcpointer_t* this, gcpointer_t other)
+{
+	this->ptr = other.ptr;
+	this->next = NULL;
+
+	register_ptr(this);
+}
+
+void ^?{}(gcpointer_t* this)
+{
+	unregister_ptr(this);
+}
+
+gcpointer_t ?=?(gcpointer_t* this, gcpointer_t rhs)
+{
+	unregister_ptr(this);
+	this->ptr = rhs.ptr;
+	register_ptr(this);
+
+	return *this;
+}
+
+//Logical operators
+bool gcpointer_equal(const gcpointer_t* this, const gcpointer_t* rhs)
+{
+	return this->ptr == rhs->ptr;
+}
+
+bool gcpointer_not_equal(const gcpointer_t* this, const gcpointer_t* rhs)
+{
+	return this->ptr != rhs->ptr;
+}
+
+bool gcpointer_null(const gcpointer_t* this)
+{
+	return this->ptr == (intptr_t)NULL;
+}
+
+#ifndef NDEBUG
+	bool is_valid(const gcpointer_t* this) {
+		if(gcpointer_null(this)) return true;
+
+		gc_object_header* obj = gc_get_object_ptr((void*)this->ptr);
+		check(obj);
+		check(is_valid(obj));
+		check(!obj->root_chain || this->ptr == obj->root_chain->ptr);
+
+		if( !gc_is_managed(this))
+		{
+			check( !(this->next) || this->ptr == this->next->ptr );
+		}
+
+		return true;
+	}
+#endif
+
+forall(otype T) void ?{}(gcpointer(T)* this) {
+	(&this->internal) {};
+}
+
+forall(otype T) void ?{}(gcpointer(T)* this, void* address) {
+	(&this->internal) { address };
+}
+
+forall(otype T) void ?{}(gcpointer(T)* this, gcpointer(T) other) {
+	(&this->internal) { other.internal };
+}
+
+forall(otype T) void ^?{}(gcpointer(T)* this) {
+	^?{}(&this->internal);
+}
+
+forall(otype T) gcpointer(T) ?=?(gcpointer(T)* this, gcpointer(T) rhs) {
+	this->internal = rhs.internal;
+	return *this;
+}
+//
+// forall(otype T) T *?(gcpointer(T) this);
+
+forall(otype T) T* get(gcpointer(T)* this) {
+	return (T*)this->internal.ptr;
+}
+//
+// //Logical operators
+forall(otype T) int ?!=?(gcpointer(T) this, int zero) {
+	return this.internal.ptr != 0;
+}
+// forall(otype T) int ?!=?(gcpointer(T) this, gcpointer(T) rhs);
+// forall(otype T) int ?==?(gcpointer(T) this, gcpointer(T) rhs);
Index: examples/gc_no_raii/src/gcpointers.h
===================================================================
--- examples/gc_no_raii/src/gcpointers.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/gcpointers.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,51 @@
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+
+forall(dtype T)
+struct gcpointer;
+
+struct gcpointer_t
+{
+	intptr_t ptr;
+	struct gcpointer_t* next;
+};
+
+void ?{}(gcpointer_t* this);
+void ?{}(gcpointer_t* this, void* address);
+void ?{}(gcpointer_t* this, gcpointer_t other);
+void ^?{}(gcpointer_t* this);
+gcpointer_t ?=?(gcpointer_t* this, gcpointer_t rhs);
+
+//Logical operators
+bool gcpointer_equal(gcpointer_t* this, gcpointer_t* rhs);
+bool gcpointer_not_equal(gcpointer_t* this, gcpointer_t* rhs);
+bool gcpointer_null(const gcpointer_t* this);
+
+
+#ifndef NDEBUG
+	bool is_valid(const gcpointer_t* this);
+#endif
+
+forall(dtype T)
+struct gcpointer
+{
+	gcpointer_t internal;
+};
+
+//
+forall(otype T) void ?{}(gcpointer(T)* this);
+forall(otype T) void ?{}(gcpointer(T)* this, void* address);
+forall(otype T) void ?{}(gcpointer(T)* this, gcpointer(T) other);
+forall(otype T) void ^?{}(gcpointer(T)* this);
+forall(otype T) gcpointer(T) ?=?(gcpointer(T)* this, gcpointer(T) rhs);
+
+
+// forall(otype T) T *?(gcpointer(T) this);
+forall(otype T) T* get(gcpointer(T)* this);
+
+//Logical operators
+forall(otype T) int ?!=?(gcpointer(T) this, int zero);
+forall(otype T) int ?!=?(gcpointer(T) this, gcpointer(T) rhs);
+forall(otype T) int ?==?(gcpointer(T) this, gcpointer(T) rhs);
Index: examples/gc_no_raii/src/internal/card_table.h
===================================================================
--- examples/gc_no_raii/src/internal/card_table.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/internal/card_table.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,62 @@
+#pragma once
+
+#include "globals.h"
+#include "tools.h"
+
+static inline size_t card_of(void* address)
+{
+	size_t card = ( ((intptr_t)address) & CARDS_OFFSET_MASK ) >> CARDS_SIZE_EXP;
+	checkf(card < CARDS_COUNT, (const char*)"%lu %lu = (%lx & %lx) >> %lu\n", (size_t)CARDS_COUNT, (size_t)card, (size_t)address, (size_t)CARDS_OFFSET_MASK, (size_t)CARDS_SIZE_EXP);
+	check(card < CARDS_COUNT);
+	return card;
+}
+
+struct card_table_t
+{
+	size_t count;
+	void* cards_start[CARDS_COUNT];
+};
+
+static inline void ?{}(card_table_t* this)
+{
+	this->count = 0;
+}
+
+static inline void ^?{}(card_table_t* this)
+{
+
+}
+
+static inline void* object_at(card_table_t* const this, size_t card_number)
+{
+	return card_number < this->count ? this->cards_start[card_number] : NULL;
+}
+
+static inline void register_object(card_table_t* const this, void* object)
+{
+	size_t card = card_of(object);
+	if(card < this->count)
+	{
+		intptr_t card_obj_add = (intptr_t)object_at(this, card);
+		intptr_t obj_add = (intptr_t)object;
+		if(card_obj_add > obj_add)
+		{
+			this->cards_start[card] = object;
+		}
+	}
+	else
+	{
+		check(card == this->count);
+		this->count++;
+		this->cards_start[card] = object;
+	}
+}
+
+static inline void reset(card_table_t* const this)
+{
+	for(size_t i = 0; i < this->count; i++)
+	{
+		this->cards_start[i] = NULL;
+	}
+	this->count = 0;
+}
Index: examples/gc_no_raii/src/internal/collector.c
===================================================================
--- examples/gc_no_raii/src/internal/collector.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/internal/collector.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,152 @@
+#include "collector.h"
+
+#ifdef __cforall
+extern "C" {
+#endif
+#include <string.h>
+#ifdef __cforall
+}
+#endif
+
+#include <fstream>
+
+#include "state.h"
+#include "gcpointers.h"
+#include "memory_pool.h"
+
+void* gc_finish_alloc_block(void* block, size_t actual_size, size_t target_size);
+void gc_assign_reference(void** ref, gc_object_header* ptr);
+
+gcpointer_t** gc_find_previous_ref(gcpointer_t* target)
+{
+	if(!(target)) return NULL;
+
+	bool managed = gc_is_managed(target);
+	gc_object_header* obj = gc_get_object_ptr((void*)target->ptr);
+
+	check(is_valid(obj));
+
+	gcpointer_t** prev_next_ptr = managed ? &obj->type_chain : &obj->root_chain;
+	while((*prev_next_ptr) && (*prev_next_ptr) != target)
+	{
+		prev_next_ptr = &(*prev_next_ptr)->next;
+	}
+
+	return prev_next_ptr;
+}
+
+void* gc_allocate(size_t target_size)
+{
+	// sout | "Allocating " | target_size | " bytes" | endl;
+
+	size_t size = gc_compute_size(target_size + sizeof(gc_object_header));
+
+	// sout | "Object header size: " | sizeof(gc_object_header) | " bytes" | endl;
+	// sout | "Actual allocation size: " | size | " bytes" | endl;
+
+	check(size < POOL_SIZE_BYTES);
+
+	void* block = NULL;
+	gc_state* gc = gc_get_state();
+
+	if((intptr_t)(block = gc_try_allocate(gc, size))) return gc_finish_alloc_block(block, size, target_size);
+
+	gc_collect(gc);
+
+	if((intptr_t)(block = gc_try_allocate(gc, size))) return gc_finish_alloc_block(block, size, target_size);
+
+	gc_allocate_pool(gc);
+
+	if((intptr_t)(block = gc_try_allocate(gc, size))) return gc_finish_alloc_block(block, size, target_size);
+
+	checkf( (int) 0, "ERROR: allocation in new pool failed");
+
+	return NULL;
+}
+
+void* gc_finish_alloc_block(void* block, size_t actual_size, size_t target_size)
+{
+	intptr_t data = ((intptr_t)block) + sizeof(gc_object_header);
+	void* header = block;
+
+	check( data > ((intptr_t)block));
+	check( data >= ((intptr_t)header));
+	check( gc_is_aligned( (void*)data ) );
+	check( data + target_size <= ((intptr_t)block) + actual_size );
+
+	gc_object_header* obj = placement_ctor(header, actual_size);
+
+	(void)obj; //remove unsused warning since this is for debug
+	check(obj == gc_get_object_ptr( (void*)data ));
+
+	gc_register_allocation(gc_get_state(), actual_size);
+
+	return (void*)data;
+}
+
+void gc_process_reference(void** ref, worklist_t* worklist)
+{
+	check(!gc_is_in_heap(gc_get_state(), ref));
+
+	gc_object_header* ptr = gc_get_object_ptr(*ref);
+	if(ptr)
+	{
+		if(!ptr->is_forwarded)
+		{
+			gc_copy_object(ptr);
+
+			gc_scan_object(ptr->forward, worklist);
+
+			gc_assign_reference(ref, ptr->forward);
+		}
+		else
+		{
+			//duplication to help debug
+			gc_assign_reference(ref, ptr->forward);
+		}
+	}
+}
+
+void gc_assign_reference(void** ref, gc_object_header* ptr)
+{
+	void* address = (void*)(((intptr_t)ptr) + sizeof(gc_object_header));
+
+	gc_write_aligned_ptr(ref, address);
+}
+
+gc_object_header* gc_copy_object(gc_object_header* ptr)
+{
+	check(!ptr->forward);
+	check(!ptr->is_forwarded);
+	check(gc_pool_is_from_space(gc_pool_of(ptr)));
+
+	gc_memory_pool* pool = gc_pool_of(ptr)->mirror;
+
+	void* new_block = gc_pool_allocate(pool, ptr->size, true);
+
+	memcpy(new_block, ptr, ptr->size);
+
+	gc_object_header* fwd_ptr = placement_copy_ctor(new_block, ptr);
+
+	ptr->forward = fwd_ptr;
+	ptr->is_forwarded = true;
+
+	return fwd_ptr;
+}
+
+void gc_scan_object(gc_object_header* object, worklist_t* worklist)
+{
+	gcpointer_t* field = object->type_chain;
+	while(field)
+	{
+		check(((intptr_t)field) > ((intptr_t)object));
+		check(((intptr_t)field) < ((intptr_t)((intptr_t)object) + object->size));
+
+		check(gc_is_in_to_space(gc_get_state(), &field->ptr));
+
+		intptr_t* ref = &field->ptr;
+		push_back(worklist, ref);
+
+		field = field->next;
+	}
+}
Index: examples/gc_no_raii/src/internal/collector.h
===================================================================
--- examples/gc_no_raii/src/internal/collector.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/internal/collector.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,47 @@
+#pragma once
+
+#include <stdlib.h>
+
+#include "tools.h"
+//
+#include "gcpointers.h"
+#include "state.h"
+#include "internal/gc_tools.h"
+#include "internal/globals.h"
+#include "internal/object_header.h"
+#include "internal/state.h"
+#include "tools/worklist.h"
+
+static inline bool gc_is_managed(void* address)
+{
+	return gc_is_in_heap(gc_get_state(), address);
+}
+
+static inline gc_object_header* gc_get_object_ptr(void* ptr)
+{
+	void* clean = gc_get_aligned_ptr(ptr);
+	return ((gc_object_header*)clean) - 1;
+}
+
+static inline struct gc_memory_pool* gc_pool_of(void* address)
+{
+	return (struct gc_memory_pool*)(((intptr_t)address) & POOL_PTR_MASK);
+}
+
+static inline void gc_conditional_collect()
+{
+	if(gc_needs_collect(gc_get_state()))
+	{
+		gc_collect(gc_get_state());
+	}
+}
+
+gcpointer_t** gc_find_previous_ref(gcpointer_t* target);
+
+void* gc_allocate(size_t size);
+
+void gc_process_reference(void** ref, worklist_t* worklist);
+
+struct gc_object_header* gc_copy_object(struct gc_object_header* ptr);
+
+void gc_scan_object(struct gc_object_header* object, worklist_t* worklist);
Index: examples/gc_no_raii/src/internal/gc_tools.h
===================================================================
--- examples/gc_no_raii/src/internal/gc_tools.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/internal/gc_tools.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "tools.h"
+#include "globals.h"
+
+static inline bool gc_is_aligned(void* address)
+{
+	return (((intptr_t)address) & (~OBJECT_PTR_MASK)) == 0;
+}
+
+static inline void* gc_get_aligned_ptr(void* address)
+{
+	return (void*)(((intptr_t)address) & (OBJECT_PTR_MASK));
+}
+
+static inline void* gc_write_aligned_ptr(void** reference, void* address)
+{
+	size_t ref_last_bits = ((intptr_t)*reference) & (~OBJECT_PTR_MASK);
+
+      size_t new_val = ((intptr_t)address) & OBJECT_PTR_MASK;
+
+      (*reference) = (void*)(new_val | ref_last_bits);
+
+	return *reference;
+}
+
+static inline size_t gc_compute_size(size_t size)
+{
+	size_t word_size = ((size - 1) / OBJECT_ALLIGNMENT) + 1;
+	size_t ret = word_size * OBJECT_ALLIGNMENT;
+
+	check(ret >= size);
+	check((ret % OBJECT_ALLIGNMENT) == 0);
+	check( ((size % OBJECT_ALLIGNMENT) != 0) || (ret == size) );
+
+	return ret;
+}
Index: examples/gc_no_raii/src/internal/globals.h
===================================================================
--- examples/gc_no_raii/src/internal/globals.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/internal/globals.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,30 @@
+#pragma once
+
+// #include <stddef.h>
+// #include <stdint.h>
+//
+// static const size_t POOL_SIZE_EXP = 24;
+// static const size_t POOL_SIZE_BYTES = 0x1 << POOL_SIZE_EXP;
+// static const size_t POOL_PTR_MASK = ~(POOL_SIZE_BYTES - 1);
+//
+// static const size_t CARDS_SIZE_EXP = 12;
+// static const size_t CARDS_SIZE_BYTES = 0x1 << CARDS_SIZE_EXP;
+// static const size_t CARDS_OFFSET_MASK = (~(CARDS_SIZE_BYTES - 1)) & (POOL_SIZE_BYTES - 1);
+// static const size_t CARDS_COUNT = POOL_SIZE_BYTES / CARDS_SIZE_BYTES;
+//
+// static const size_t OBJECT_ALLIGNMENT = sizeof(size_t);
+// static const size_t OBJECT_PTR_MASK = ~(OBJECT_ALLIGNMENT - 1);
+
+enum {
+	POOL_SIZE_EXP 	= 24,
+	POOL_SIZE_BYTES 	= 0x1 << POOL_SIZE_EXP,
+	POOL_PTR_MASK 	= ~(POOL_SIZE_BYTES - 1),
+
+	CARDS_SIZE_EXP 	= 12,
+	CARDS_SIZE_BYTES 	= 0x1 << CARDS_SIZE_EXP,
+	CARDS_OFFSET_MASK	= (~(CARDS_SIZE_BYTES - 1)) & (POOL_SIZE_BYTES - 1),
+	CARDS_COUNT 	= POOL_SIZE_BYTES / CARDS_SIZE_BYTES,
+
+	OBJECT_ALLIGNMENT	= sizeof(size_t),
+	OBJECT_PTR_MASK 	= ~(OBJECT_ALLIGNMENT - 1),
+};
Index: examples/gc_no_raii/src/internal/memory_pool.c
===================================================================
--- examples/gc_no_raii/src/internal/memory_pool.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/internal/memory_pool.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,160 @@
+#include "memory_pool.h"
+
+extern "C" {
+	#include <stdlib.h>
+	#include <string.h>
+}
+
+#include "collector.h"
+#include "object_header.h"
+
+const size_t gc_pool_header_size = (size_t)(  &(((gc_memory_pool*)NULL)->start_p) );
+
+void ?{}(gc_memory_pool* this, size_t size, gc_memory_pool* next, gc_memory_pool* mirror, uint8_t type)
+{
+	this->mirror = mirror;
+	this->next = next;
+	this->type_code = type;
+
+	this->cards = ( (card_table_t*)malloc(sizeof(card_table_t)) ){};
+
+	this->end_p = ((uint8_t*)this) + size;
+	this->free_p = this->start_p;
+
+	check( gc_pool_of( (void*)this ) == this);
+	check(this->cards);
+	gc_reset_pool(this);
+}
+
+void ^?{}(gc_memory_pool* this)
+{
+	^(&this->cards){};
+	free(this->cards);
+}
+
+void gc_reset_pool(gc_memory_pool *const this)
+{
+	this->free_p = this->start_p;
+	#ifndef NDEBUG
+		memset(this->start_p, 0xCD, gc_pool_size_total(this));
+	#endif
+
+	check(this->cards);
+	reset(this->cards);
+
+	check(gc_pool_size_left(this) == gc_pool_size_total(this));
+}
+
+void* gc_pool_allocate(gc_memory_pool *const this, size_t size, bool zero)
+{
+	void* ret = this->free_p;
+
+	this->free_p += size;
+
+	if (zero) memset(ret, 0x00, size);
+
+	check(this->cards);
+	register_object(this->cards, ret);
+
+	return ret;
+}
+
+void ?{}(	gc_pool_object_iterator* this,
+		struct gc_object_header* start_object
+		#ifndef NDEBUG
+			, intptr_t pool_start
+			, intptr_t pool_end
+		#endif
+	)
+{
+	this->object = start_object;
+	#ifndef NDEBUG
+		this->lower_limit = pool_start;
+		this->upper_limit = pool_end;
+	#endif
+
+	check( ((intptr_t)start_object) >= this->lower_limit );
+	check( ((intptr_t)start_object) <= this->upper_limit );
+}
+
+void ^?{}( gc_pool_object_iterator* this ) {}
+
+gc_pool_object_iterator gc_pool_iterator_for(gc_memory_pool* const this, void* member)
+{
+	size_t card = card_of(member);
+	intptr_t member_add = (intptr_t)member;
+	intptr_t start_obj;
+
+	do
+	{
+		check(card < CARDS_COUNT);
+		start_obj = (intptr_t)object_at(this->cards, card);
+		check(card != 0 || start_obj);
+		card--;
+	}
+	while(start_obj > member_add || !(start_obj));
+
+	check( start_obj );
+
+	struct gc_object_header* start_obj_typed = (struct gc_object_header*)start_obj;
+
+	return (gc_pool_object_iterator) {
+		start_obj_typed
+		#ifndef NDEBUG
+			, (intptr_t)this->start_p
+			, (intptr_t)this->free_p
+		#endif
+	};
+}
+
+bool ?!=?(const gc_pool_object_iterator lhs, const gc_pool_object_iterator rhs)
+{
+	return lhs.object != rhs.object;
+}
+
+gc_pool_object_iterator begin(gc_memory_pool* const this)
+{
+	struct gc_object_header* start_obj = (struct gc_object_header*)this->start_p;
+	return (gc_pool_object_iterator) {
+		start_obj
+		#ifndef NDEBUG
+			, (intptr_t)this->start_p
+			, (intptr_t)this->free_p
+		#endif
+	};
+}
+
+gc_pool_object_iterator end(gc_memory_pool* const this)
+{
+	return (gc_pool_object_iterator) {
+		(struct gc_object_header*)this->free_p
+		#ifndef NDEBUG
+			, (intptr_t)this->start_p
+			, (intptr_t)this->free_p
+		#endif
+	};
+}
+
+gc_pool_object_iterator* ++?(gc_pool_object_iterator* it)
+{
+	struct gc_object_header* object = it->object;
+	intptr_t next_ptr = ((intptr_t)object) + object->size;
+	check(next_ptr > it->lower_limit);
+	check(next_ptr <= it->upper_limit);
+
+	struct gc_object_header* next_obj = ((struct gc_object_header*)next_ptr);
+	check(next_ptr == it->upper_limit || is_valid(next_obj));
+
+	it->object = next_obj;
+	return it;
+}
+
+const struct gc_object_header* *?(const gc_pool_object_iterator it)
+{
+	return it.object;
+}
+
+struct gc_object_header* *?(gc_pool_object_iterator it)
+{
+	return it.object;
+}
Index: examples/gc_no_raii/src/internal/memory_pool.h
===================================================================
--- examples/gc_no_raii/src/internal/memory_pool.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/internal/memory_pool.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,92 @@
+#pragma once
+
+extern "C" {
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+}
+
+#include "tools.h"
+
+#include "card_table.h"
+#include "globals.h"
+#include "state.h"
+
+struct gc_memory_pool
+{
+	struct memory_pool* mirror;
+	struct memory_pool* next;
+
+	uint8_t type_code;
+
+	card_table_t* cards;
+
+	uint8_t* end_p;
+	uint8_t* free_p;
+	uint8_t start_p[1];
+};
+
+void ?{}(	gc_memory_pool* this,
+		size_t size,
+		gc_memory_pool* next,
+		gc_memory_pool* mirror,
+		uint8_t type
+	);
+
+void ^?{}(gc_memory_pool* this);
+
+struct gc_pool_object_iterator
+{
+	struct gc_object_header* object;
+	#ifndef NDEBUG
+		intptr_t lower_limit;
+		intptr_t upper_limit;
+	#endif
+};
+
+
+void ?{}( 	gc_pool_object_iterator* this,
+		struct gc_object_header* start_object
+		#ifndef NDEBUG
+			, intptr_t pool_start
+			, intptr_t pool_end
+		#endif
+	);
+
+void ^?{}( gc_pool_object_iterator* this );
+
+bool ?!=?(const gc_pool_object_iterator lhs, const gc_pool_object_iterator rhs);
+
+gc_pool_object_iterator begin(gc_memory_pool* const this);
+gc_pool_object_iterator end(gc_memory_pool* const);
+
+gc_pool_object_iterator* ++?(gc_pool_object_iterator* it);
+
+const struct gc_object_header* *?(const gc_pool_object_iterator it);
+struct gc_object_header* *?(gc_pool_object_iterator it);
+
+static inline bool gc_pool_is_from_space(const gc_memory_pool* pool)
+{
+	return gc_from_space_code(gc_get_state()) == pool->type_code;
+}
+
+void gc_reset_pool(gc_memory_pool* const pool);
+
+static inline size_t gc_pool_size_used(const gc_memory_pool* pool)
+{
+	return pool->free_p - pool->start_p;
+}
+
+static inline size_t gc_pool_size_total(const gc_memory_pool* pool)
+{
+	return pool->end_p - pool->start_p;
+}
+
+static inline size_t gc_pool_size_left(const gc_memory_pool* pool)
+{
+	return pool->end_p - pool->free_p;
+}
+
+void* gc_pool_allocate(gc_memory_pool* const pool, size_t size, bool zero);
+
+gc_pool_object_iterator gc_pool_iterator_for(gc_memory_pool* const pool, void* member);
Index: examples/gc_no_raii/src/internal/object_header.c
===================================================================
--- examples/gc_no_raii/src/internal/object_header.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/internal/object_header.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,110 @@
+#include "object_header.h"
+
+#include <stdint.h>
+
+#include "collector.h"
+#include "globals.h"
+#include "gcpointers.h"
+
+void ctor(gc_object_header* const this, size_t inSize)
+{
+	#ifndef NDEBUG
+		this->canary_start = CANARY_VALUE;
+	#endif
+
+	this->size = inSize;
+	this->root_chain = NULL;
+	this->type_chain = NULL;
+	this->forward = NULL;
+	this->is_forwarded = false;
+
+	#ifndef NDEBUG
+		this->canary_end = CANARY_VALUE;
+	#endif
+}
+
+void copy_ctor(gc_object_header* const this, const gc_object_header* const other)
+{
+	#ifndef NDEBUG
+		this->canary_start = CANARY_VALUE;
+	#endif
+
+	this->size = other->size;
+	this->root_chain = other->root_chain;
+	this->type_chain = NULL;
+	this->forward = NULL;
+	this->is_forwarded = false;
+
+	#ifndef NDEBUG
+		this->canary_end = CANARY_VALUE;
+	#endif
+
+	gcpointer_t* root = this->root_chain;
+	while(root)
+	{
+		check(gc_get_object_ptr( (void*)root->ptr ) == other);
+		root->ptr = ((intptr_t)this) + sizeof(gc_object_header);
+
+		check(gc_get_object_ptr( (void*)root->ptr ) == this);
+		root = root->next;
+	}
+
+	gcpointer_t* type = other->type_chain;
+
+	while(type)
+	{
+		check((intptr_t)type < (intptr_t)((intptr_t)other + other->size));
+
+		size_t offset = (intptr_t)type - (intptr_t)other;
+		check(offset < this->size);
+
+		gcpointer_t* member_ptr = (gcpointer_t*)( (intptr_t)this + offset );
+
+		if(!this->type_chain) this->type_chain = member_ptr;
+
+		size_t next_offset = type->next ? (intptr_t)type->next - (intptr_t)other : 0;
+		check(next_offset < this->size);
+
+		gcpointer_t* next_ptr = type->next ? (gcpointer_t*)((intptr_t)this + next_offset) : NULL;
+
+		member_ptr->ptr = type->ptr;
+		member_ptr->next = next_ptr;
+
+		type = type->next;
+	}
+
+	check(is_valid(this));
+}
+
+#ifndef NDEBUG
+	bool is_valid(const gc_object_header* const this)
+	{
+		check((intptr_t)this->canary_start == (intptr_t)CANARY_VALUE);
+		check((intptr_t)this->canary_end == (intptr_t)CANARY_VALUE);
+
+		check(this->is_forwarded == ( (intptr_t)this->forward != (intptr_t)NULL));
+
+		check(this->size < POOL_SIZE_BYTES);
+
+		gcpointer_t* root = this->root_chain;
+		while(root)
+		{
+			checkf(gc_get_object_ptr( (void*)root->ptr ) == this, (const char*)"Expected %lX got %lX\n", gc_get_object_ptr( (void*)root->ptr ), this);
+
+			root = root->next;
+		}
+
+		gcpointer_t* type = this->type_chain;
+		while(type)
+		{
+			check((intptr_t)type > (intptr_t)this);
+			check((intptr_t)type < (intptr_t)(((intptr_t)this) + this->size));
+
+			type = type->next;
+		}
+
+		return true;
+	}
+	#else
+	#error blarg
+#endif
Index: examples/gc_no_raii/src/internal/object_header.h
===================================================================
--- examples/gc_no_raii/src/internal/object_header.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/internal/object_header.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,52 @@
+#pragma once
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "tools.h"
+
+#ifndef NDEBUG
+	static void* const CANARY_VALUE = (void*)0xCAFEBABACAFEBABA;
+#endif
+
+struct gcpointer_t;
+struct gc_object_header;
+
+struct gc_object_header
+{
+	#ifndef NDEBUG
+		void* canary_start;
+	#endif
+
+	size_t		size;
+	gcpointer_t* 	root_chain;
+	gcpointer_t*	type_chain;
+	gc_object_header*	forward;
+	bool			is_forwarded;
+
+	#ifndef NDEBUG
+		void* canary_end;
+	#endif
+};
+
+void ctor(gc_object_header* const this, size_t size);
+void copy_ctor(gc_object_header* const this, const gc_object_header* const other);
+
+static inline gc_object_header* placement_ctor(void* address, size_t size)
+{
+	gc_object_header* const this = (gc_object_header* const) address;
+	ctor(this, size);
+	return this;
+}
+
+static inline gc_object_header* placement_copy_ctor(void* address, const gc_object_header* const other)
+{
+	gc_object_header* const this = (gc_object_header* const) address;
+	copy_ctor(this, other);
+	return this;
+}
+
+#ifndef NDEBUG
+	bool is_valid(const gc_object_header* const this);
+#endif
Index: examples/gc_no_raii/src/internal/state.c
===================================================================
--- examples/gc_no_raii/src/internal/state.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/internal/state.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,312 @@
+#include "state.h"
+
+#include <stdlib>
+
+//general purpouse includes
+#include "tools.h"
+
+//platform abstraction includes
+#include "allocate-pool.h"
+
+//gc internal includes
+#include "collector.h"
+#include "globals.h"
+#include "memory_pool.h"
+#include "object_header.h"
+#include "tools/worklist.h"
+
+void gc_state_swap(gc_state *const this);
+void gc_state_sweep_roots(gc_state *const this, worklist_t* worklist);
+void gc_state_clear(gc_state *const this);
+void gc_state_calc_usage(gc_state *const this);
+
+#ifndef NDEBUG
+	bool gc_state_roots_match(gc_state *const this);
+	bool gc_state_no_from_space_ref(gc_state *const this);
+#endif
+
+static gc_state s;
+
+gc_state* gc_get_state()
+{
+	if(!s.is_initialized) ctor(&s);
+	return &s;
+}
+
+void ctor(gc_state *const this)
+{
+	this->from_code = 0;
+	this->to_space = NULL;
+	this->from_space = NULL;
+	this->total_space = 0;
+	this->used_space = 0;
+	ctor(&this->pools_table);
+
+	gc_allocate_pool(this);
+
+	this->is_initialized = true;
+}
+
+void dtor(gc_state *const this)
+{
+	dtor(&this->pools_table);
+	this->is_initialized = false;
+}
+
+bool gc_is_in_heap(const gc_state* const this, const void* const address)
+{
+	gc_memory_pool* target_pool = gc_pool_of(address);
+
+	gc_memory_pool** first = cbegin(&this->pools_table);
+	gc_memory_pool** last = cend(&this->pools_table);
+	gc_memory_pool** result = find(first, &last, target_pool);
+	return result != last && gc_pool_is_from_space(*result);
+}
+
+bool gc_is_in_to_space(const gc_state* const this, const void* const address)
+{
+	gc_memory_pool* target_pool = gc_pool_of(address);
+
+	gc_memory_pool** first = cbegin(&this->pools_table);
+	gc_memory_pool** last = cend(&this->pools_table);
+	gc_memory_pool** result = find(first, &last, target_pool);
+	return result != last && !gc_pool_is_from_space(*result);
+}
+
+gc_object_header* gc_get_object_for_ref(gc_state* state, void* member)
+{
+	volatile int stage = 0;
+	intptr_t target = ((intptr_t)member);
+	if(!gc_is_in_heap(state, member)) return NULL;
+	stage++;
+
+	gc_memory_pool* pool = gc_pool_of(member);
+	stage++;
+	gc_pool_object_iterator it = gc_pool_iterator_for(pool, member);
+	stage++;
+	gc_pool_object_iterator end = end(pool);
+	stage++;
+
+	while(it != end)
+	{
+		gc_object_header* object = *it;
+		check(object);
+		check( is_valid(object) );
+		{
+			intptr_t start = ((intptr_t)object);
+			intptr_t end = ((intptr_t)start + object->size);
+			if(start < target && end > target)
+			{
+				return object;
+			}
+		}
+		stage++;
+		++it;
+	}
+
+	checkf( (int) 0, "is_in_heap() and iterator_for() return inconsistent data");
+	abort();
+	return NULL;
+}
+
+void* gc_try_allocate(gc_state* const this, size_t size)
+{
+	gc_memory_pool* pool = this->from_space;
+	while(pool != (gc_memory_pool*)0)
+	{
+		if(gc_pool_size_left(pool) > size)
+		{
+			return gc_pool_allocate(pool, size, true);
+		}
+		pool = pool->next;
+	}
+
+	return (void*)0;
+}
+
+void gc_allocate_pool(gc_state *const this)
+{
+	gc_memory_pool* old_from_space = this->from_space;
+      gc_memory_pool* old_to_space = this->to_space;
+
+      this->from_space = (gc_memory_pool*)(pal_allocPool(POOL_SIZE_BYTES, 1));
+      this->to_space   = (gc_memory_pool*)(pal_allocPool(POOL_SIZE_BYTES, 1));
+
+      this->from_space{ POOL_SIZE_BYTES, old_from_space, this->to_space,   this->from_code };
+      this->to_space  { POOL_SIZE_BYTES, old_to_space,   this->from_space, (~this->from_code) & 0x01 };
+
+	this->total_space += gc_pool_size_used(this->from_space);
+
+	push_back(&this->pools_table, this->from_space);
+	push_back(&this->pools_table, this->to_space);
+}
+
+void gc_collect(gc_state* const this)
+{
+	// DEBUG("collecting");
+	// DEBUG("previous usage " << this->used_space << " / " << this->total_space);
+
+	worklist_t worklist;
+	ctor(&worklist);
+	gc_state_sweep_roots(this, &worklist);
+
+	while(!empty(&worklist))
+	{
+		intptr_t* ref = back(&worklist);
+		pop_back(&worklist);
+		gc_process_reference((void**)ref, &worklist);
+	}
+
+	check(gc_state_roots_match(this));
+	check(gc_state_no_from_space_ref(this));
+
+	gc_state_swap(this);
+
+	gc_state_calc_usage(this);
+
+	if(gc_needs_collect(this)) gc_allocate_pool(this);
+
+	// DEBUG("done");
+	dtor(&worklist);
+}
+
+void gc_state_swap(gc_state* const this)
+{
+	swap(&this->from_space, &this->to_space);
+
+	gc_memory_pool* pool = this->to_space;
+	while(pool)
+	{
+		gc_reset_pool(pool);
+		pool = pool->next;
+	}
+
+	this->from_code = (~this->from_code) & 0x01;
+
+	#ifndef NDEBUG
+		{
+			gc_memory_pool* pool = this->from_space;
+			while(pool)
+			{
+				check(gc_pool_is_from_space(pool));
+				pool = pool->next;
+			}
+
+			pool = this->to_space;
+			while(pool)
+			{
+				check(!gc_pool_is_from_space(pool));
+				pool = pool->next;
+			}
+		}
+	#endif
+}
+
+void gc_state_sweep_roots(gc_state* const this, worklist_t* worklist)
+{
+	gc_memory_pool* pool = this->from_space;
+	while(pool)
+	{
+		gc_pool_object_iterator it = begin(pool);
+		gc_pool_object_iterator end = end(pool);
+		for(;it != end; ++it)
+		{
+			gc_object_header* object = *it;
+			if(!object->root_chain) continue;
+
+			gc_copy_object(object);
+
+			gc_scan_object(object->forward, worklist);
+		}
+
+		pool = pool->next;
+	}
+}
+
+void gc_state_clear(gc_state* const this)
+{
+	gc_memory_pool* pool = this->from_space;
+	while(pool)
+	{
+		gc_reset_pool(pool);
+		pool = pool->next;
+	}
+
+	pool = this->to_space;
+	while(pool)
+	{
+		gc_reset_pool(pool);
+		pool = pool->next;
+	}
+}
+
+void gc_state_calc_usage(gc_state* const this)
+{
+	this->total_space = 0;
+	this->used_space = 0;
+
+	gc_memory_pool* pool = this->from_space;
+	while(pool)
+	{
+		size_t size = gc_pool_size_total(pool);
+		size_t used = gc_pool_size_used(pool);
+		check(used <= size);
+		this->total_space += size;
+		this->used_space += used;
+
+		pool = pool->next;
+	}
+}
+
+#ifndef NDEBUG
+	bool gc_state_roots_match(gc_state* const this)
+	{
+		gc_memory_pool* pool = this->to_space;
+		while(pool)
+		{
+			size_t size = 0;
+			gc_pool_object_iterator it = begin(pool);
+			gc_pool_object_iterator end = end(pool);
+			for(;it != end; ++it)
+			{
+				gc_object_header* object = *it;
+				size += object->size;
+
+				gcpointer_t* ptr = object->root_chain;
+				while(ptr)
+				{
+					check(gc_get_object_ptr( (void*)ptr->ptr ) == object);
+					ptr = ptr->next;
+				}
+			}
+
+			checkf(size + gc_pool_size_left(pool) == gc_pool_size_total(pool),
+				(const char*)"expected %lu + %lu == %lu\n",
+				(size_t)size,
+				(size_t)gc_pool_size_left(pool),
+				(size_t)gc_pool_size_total(pool));
+
+			pool = pool->next;
+		}
+
+		return true;
+	}
+
+	bool gc_state_no_from_space_ref(gc_state* const this)
+	{
+		gc_memory_pool* pool = this->to_space;
+		while(pool)
+		{
+			void** potential_ref = (void**)pool->start_p;
+			while(potential_ref < (void**)pool->free_p)
+			{
+				check(!gc_is_in_heap(this, *potential_ref));
+				potential_ref++;
+			}
+
+			pool = pool->next;
+		}
+
+		return true;
+	}
+#endif
Index: examples/gc_no_raii/src/internal/state.h
===================================================================
--- examples/gc_no_raii/src/internal/state.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/internal/state.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,64 @@
+#pragma once
+
+#ifdef __cforall
+extern "C" {
+#endif
+#include <stddef.h>
+#include <stdint.h>
+#ifdef __cforall
+}
+#endif
+#include <fstream>
+#include <vector>
+
+#include "tools.h"
+
+typedef vector(struct gc_memory_pool*, heap_allocator(struct gc_memory_pool*)) pools_table_t;
+
+struct gc_state
+{
+	bool is_initialized;
+	uint8_t from_code;
+	struct gc_memory_pool* to_space;
+	struct gc_memory_pool* from_space;
+
+	size_t total_space;
+	size_t used_space;
+
+	pools_table_t 	pools_table;
+	size_t 		pools_table_count;
+};
+
+void ctor(gc_state* const state);
+
+void dtor(gc_state* const state);
+
+gc_state* gc_get_state();
+
+static inline bool gc_needs_collect(gc_state* state)
+{
+	// sout | "Used Space: " | state->used_space | " bytes" | endl;
+	return state->used_space * 2 > state->total_space;
+}
+
+void gc_collect(gc_state* const this);
+
+void* gc_try_allocate(gc_state* const this, size_t size);
+
+void gc_allocate_pool(gc_state* const state);
+
+bool gc_is_in_heap(const gc_state* const state, const void* const address);
+
+bool gc_is_in_to_space(const gc_state* const state, const void* const address);
+
+static inline uint8_t gc_from_space_code(const gc_state *const this)
+{
+	return this->from_code;
+}
+
+struct gc_object_header* gc_get_object_for_ref(gc_state* state, void*);
+
+static inline void gc_register_allocation(gc_state* state, size_t size)
+{
+	state->used_space += size;
+}
Index: examples/gc_no_raii/src/test_include.c
===================================================================
--- examples/gc_no_raii/src/test_include.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/test_include.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,4 @@
+/* definition to expand macro for string conversion*/
+#define xstr(s) sstr(s)
+#define sstr(s) #s
+#include xstr(../test/TEST_FILE.c)
Index: examples/gc_no_raii/src/tools.h
===================================================================
--- examples/gc_no_raii/src/tools.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/tools.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "tools/checks.h"
+#include "tools/print.h"
+
+// forall(otype T)
+// inline void swap(T* const a, T* const b)
+// {
+// 	T* temp = a;
+// 	*a = *b;
+// 	*b = *temp;
+// }
+
+trait has_equal(otype T)
+{
+	signed int ?==?(T a, T b);
+};
+
+trait InputIterator_t(otype T, otype InputIterator)
+{
+	signed int ?==?(InputIterator a, InputIterator b);
+	signed int ?!=?(InputIterator a, InputIterator b);
+	T *?(InputIterator a);
+	InputIterator ++?(InputIterator* a);
+	InputIterator ?++(InputIterator* a);
+};
+
+forall(otype T | has_equal(T), otype InputIterator | InputIterator_t(T, InputIterator))
+static inline InputIterator find( InputIterator first, const InputIterator* const last, T val)
+{
+	while ( first != *last)
+	{
+		if(*first == val) return first;
+		++first;
+	}
+	return *last;
+}
Index: examples/gc_no_raii/src/tools/checks.h
===================================================================
--- examples/gc_no_raii/src/tools/checks.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/tools/checks.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,29 @@
+#pragma once
+
+#ifdef NDEBUG
+
+#define check(x)
+
+#define checkf(x, format, ...)
+
+#warning no debug checks
+
+#else
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#define check(x) do {\
+	if(!(x)) {\
+		printf("CHECK failed : %s at %s:%i\n", #x, __FILE__, __LINE__);\
+		abort();\
+	}}while( (int)0 )\
+
+#define checkf(x, ...) do {\
+	if(!(x)) {\
+		printf("CHECK failed : %s at %s:%i\n", #x, __FILE__, __LINE__);\
+		printf(__VA_ARGS__);\
+		abort();\
+	}}while( (int)0 )\
+
+#endif //NO_CHECKS
Index: examples/gc_no_raii/src/tools/print.c
===================================================================
--- examples/gc_no_raii/src/tools/print.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/tools/print.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,5 @@
+#include "tools.h"
+
+#ifndef NDEBUG
+	// ofstream *sout = ofstream_stdout();
+#endif
Index: examples/gc_no_raii/src/tools/print.h
===================================================================
--- examples/gc_no_raii/src/tools/print.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/tools/print.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,13 @@
+#pragma once
+
+// #ifndef NDEBUG
+//
+// #include <fstream>
+//
+// #define DEBUG_OUT(x) sout | x | endl;
+//
+// #else
+
+#define DEBUG_OUT(x)
+
+// #endif //NO_CHECKS
Index: examples/gc_no_raii/src/tools/worklist.h
===================================================================
--- examples/gc_no_raii/src/tools/worklist.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/src/tools/worklist.h	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,14 @@
+#pragma once
+
+#ifdef __cforall
+extern "C" {
+#endif
+#include <stddef.h>
+#include <stdint.h>
+#ifdef __cforall
+}
+#endif
+
+#include <vector>
+
+typedef vector(intptr_t*, heap_allocator(intptr_t*)) worklist_t;
Index: examples/gc_no_raii/test/badlll.c
===================================================================
--- examples/gc_no_raii/test/badlll.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/test/badlll.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,71 @@
+#include "gc.h"
+
+#include <stdio.h>
+
+struct List_t
+{
+	gcpointer(List_t) next;
+	int val;
+};
+
+typedef gcpointer(List_t) LLL;
+
+#define MAX (1024 * 1)
+
+LLL buildLLL(int sz)
+{
+	int i = 0;
+	LLL ll0;
+
+	gcmalloc( &ll0 );
+	List_t* ll0_ptr = get( &ll0 );
+	ll0_ptr->val = i;
+	LLL lll = ll0;
+
+	for (i = 1; i < sz; i++)
+	{
+		LLL llc;
+		gcmalloc( &llc );
+		List_t* llc_ptr = get( &llc );
+		llc_ptr->val = i;
+		List_t* lll_ptr = get( &lll );
+		lll_ptr->next = llc;
+
+		lll = llc;
+	}
+
+	check(is_valid( &ll0.internal ));
+
+	return ll0;
+}
+
+void testLLL(LLL lll)
+{
+	unsigned char *counted;
+
+	counted = (unsigned char *) calloc(MAX, sizeof(unsigned char));
+	while (lll)
+	{
+		List_t* lll_ptr = get( &lll );
+		counted[lll_ptr->val]++;
+		if (counted[lll_ptr->val] > 1)
+		{
+			fprintf(stderr, "ERROR! Encountered %d twice!\n", lll_ptr->val);
+			exit(1);
+		}
+		lll = lll_ptr->next;
+	}
+
+	return;
+}
+
+int main(void)
+{
+	LLL mylll;
+
+	mylll = buildLLL(MAX);
+
+	testLLL(mylll);
+
+	return 0;
+}
Index: examples/gc_no_raii/test/gctest.c
===================================================================
--- examples/gc_no_raii/test/gctest.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/test/gctest.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,25 @@
+#include <fstream>
+
+#include "gc.h"
+#include "internal/collector.h"
+
+#warning default test
+
+int main() {
+	sout | "Bonjour au monde!\n";
+
+	gcpointer(int) theInt;
+	gcmalloc(&theInt);
+
+	for(int i = 0; i < 10; i++) {
+		int a;
+		{
+			gcpointer(int) anInt;
+			gcmalloc(&anInt);
+		}
+		int p;
+	}
+
+	gc_collect(gc_get_state());
+	gc_conditional_collect();
+}
Index: examples/gc_no_raii/test/operators.c
===================================================================
--- examples/gc_no_raii/test/operators.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
+++ examples/gc_no_raii/test/operators.c	(revision bf71cfdb7285490eee552b461158846f626cc52f)
@@ -0,0 +1,22 @@
+#include "gc.h"
+
+#include <assert.h>
+
+int main(int argc, char *argv[])
+{
+	gcpointer(int) test, test1;
+
+	if(test != test1) { return 1; }
+	if(test == test1) { return 1; }
+	// if(test == 0)  { return 1; }
+	// if(test != 0)  { return 1; }
+	// if(test) { return 1; }
+
+	// *test.internal.ptr = 3;
+	// int i = *test;
+
+	gcmalloc();
+	// test = gcmalloc();
+
+	return 0;
+}
