Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision ea156ae77e5077f52dce5b9271017e97af22e2ef)
+++ src/Concurrency/Keywords.cc	(revision 549c006f5f7e2f45d09672b9abae0dfe3809c271)
@@ -196,4 +196,5 @@
 		std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
 		void validate( DeclarationWithType * );
+		void addDtorStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
 		void addStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
 
@@ -206,4 +207,5 @@
 	  	StructDecl* monitor_decl = nullptr;
 		StructDecl* guard_decl = nullptr;
+		StructDecl* dtor_guard_decl = nullptr;
 
 		static std::unique_ptr< Type > generic_func;
@@ -229,4 +231,5 @@
 
 		void postvisit( FunctionDecl * decl );
+		void previsit ( StructDecl   * decl );
 
 		void addStartStatement( FunctionDecl * decl, DeclarationWithType * param );
@@ -236,4 +239,8 @@
 			acceptAll( translationUnit, impl );
 		}
+
+	  private :
+		bool thread_ctor_seen = false;
+		StructDecl * thread_decl = nullptr;
 	};
 
@@ -403,4 +410,10 @@
 		if( mutexArgs.empty() ) return;
 
+		if( CodeGen::isConstructor(decl->name) ) throw SemanticError( "constructors cannot have mutex parameters", decl );
+
+		bool isDtor = CodeGen::isDestructor( decl->name );
+
+		if( isDtor && mutexArgs.size() != 1 ) throw SemanticError( "destructors can only have 1 mutex argument", decl );
+
 		for(auto arg : mutexArgs) {
 			validate( arg );
@@ -412,6 +425,12 @@
 		if( !monitor_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
 		if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
-
-		addStatments( decl, body, mutexArgs );
+		if( !dtor_guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
+
+		if( isDtor ) {
+			addDtorStatments( decl, body, mutexArgs );
+		}
+		else {
+			addStatments( decl, body, mutexArgs );
+		}
 	}
 
@@ -425,4 +444,8 @@
 			assert( !guard_decl );
 			guard_decl = decl;
+		}
+		else if( decl->name == "monitor_dtor_guard_t" ) {
+			assert( !dtor_guard_decl );
+			dtor_guard_decl = decl;
 		}
 	}
@@ -457,4 +480,55 @@
 		//Make sure that typed isn't mutex
 		if( base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );
+	}
+
+	void MutexKeyword::addDtorStatments( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
+		Type * arg_type = args.front()->get_type()->clone();
+		arg_type->set_mutex( false );
+
+		ObjectDecl * monitors = new ObjectDecl(
+			"__monitor",
+			noStorage,
+			LinkageSpec::Cforall,
+			nullptr,
+			new PointerType(
+				noQualifiers,
+				new StructInstType(
+					noQualifiers,
+					monitor_decl
+				)
+			),
+			new SingleInit( new UntypedExpr(
+				new NameExpr( "get_monitor" ),
+				{  new CastExpr( new VariableExpr( args.front() ), arg_type ) }
+			))
+		);
+
+		assert(generic_func);
+
+		//in reverse order :
+		// monitor_guard_t __guard = { __monitors, #, func };
+		body->push_front(
+			new DeclStmt( noLabels, new ObjectDecl(
+				"__guard",
+				noStorage,
+				LinkageSpec::Cforall,
+				nullptr,
+				new StructInstType(
+					noQualifiers,
+					dtor_guard_decl
+				),
+				new ListInit(
+					{
+						new SingleInit( new AddressExpr( new VariableExpr( monitors ) ) ),
+						new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone() ) )
+					},
+					noDesignators,
+					true
+				)
+			))
+		);
+
+		//monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
+		body->push_front( new DeclStmt( noLabels, monitors) );
 	}
 
@@ -523,10 +597,27 @@
 	// General entry routine
 	//=============================================================================================
+	void ThreadStarter::previsit( StructDecl * decl ) {
+		if( decl->name == "thread_desc" && decl->body ) {
+			assert( !thread_decl );
+			thread_decl = decl;
+		}
+	}
+
 	void ThreadStarter::postvisit(FunctionDecl * decl) {
 		if( ! CodeGen::isConstructor(decl->name) ) return;
+
+		Type * typeof_this = InitTweak::getTypeofThis(decl->type);
+		StructInstType * ctored_type = dynamic_cast< StructInstType * >( typeof_this );
+		if( ctored_type && ctored_type->baseStruct == thread_decl ) {
+			thread_ctor_seen = true;
+		}
 
 		DeclarationWithType * param = decl->get_functionType()->get_parameters().front();
 		auto type  = dynamic_cast< StructInstType * >( InitTweak::getPointerBase( param->get_type() ) );
 		if( type && type->get_baseStruct()->is_thread() ) {
+			if( !thread_decl || !thread_ctor_seen ) {
+				throw SemanticError("thread keyword requires threads to be in scope, add #include <thread>");
+			}
+
 			addStartStatement( decl, param );
 		}
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision ea156ae77e5077f52dce5b9271017e97af22e2ef)
+++ src/InitTweak/InitTweak.cc	(revision 549c006f5f7e2f45d09672b9abae0dfe3809c271)
@@ -270,15 +270,15 @@
 	}
 
-	Type * getThisType( FunctionType * ftype ) {
-		assertf( ftype, "getThisType: nullptr ftype" );
-		ObjectDecl * thisParam = getThisParam( ftype );
+	Type * getTypeofThis( FunctionType * ftype ) {
+		assertf( ftype, "getTypeofThis: nullptr ftype" );
+		ObjectDecl * thisParam = getParamThis( ftype );
 		ReferenceType * refType = strict_dynamic_cast< ReferenceType * >( thisParam->type );
 		return refType->base;
 	}
 
-	ObjectDecl * getThisParam( FunctionType * ftype ) {
-		assertf( ftype, "getThisParam: nullptr ftype" );
+	ObjectDecl * getParamThis( FunctionType * ftype ) {
+		assertf( ftype, "getParamThis: nullptr ftype" );
 		auto & params = ftype->parameters;
-		assertf( ! params.empty(), "getThisParam: ftype with 0 parameters: %s", toString( ftype ).c_str() );
+		assertf( ! params.empty(), "getParamThis: ftype with 0 parameters: %s", toString( ftype ).c_str() );
 		return strict_dynamic_cast< ObjectDecl * >( params.front() );
 	}
Index: src/InitTweak/InitTweak.h
===================================================================
--- src/InitTweak/InitTweak.h	(revision ea156ae77e5077f52dce5b9271017e97af22e2ef)
+++ src/InitTweak/InitTweak.h	(revision 549c006f5f7e2f45d09672b9abae0dfe3809c271)
@@ -31,8 +31,8 @@
 
 	/// returns the base type of the first parameter to a constructor/destructor/assignment function
-	Type * getThisType( FunctionType * ftype );
+	Type * getTypeofThis( FunctionType * ftype );
 
 	/// returns the first parameter of a constructor/destructor/assignment function
-	ObjectDecl * getThisParam( FunctionType * ftype );
+	ObjectDecl * getParamThis( FunctionType * ftype );
 
 	/// transform Initializer into an argument list that can be passed to a call expression
Index: src/libcfa/concurrency/invoke.h
===================================================================
--- src/libcfa/concurrency/invoke.h	(revision ea156ae77e5077f52dce5b9271017e97af22e2ef)
+++ src/libcfa/concurrency/invoke.h	(revision 549c006f5f7e2f45d09672b9abae0dfe3809c271)
@@ -96,5 +96,6 @@
             struct __condition_stack_t signal_stack;  // stack of conditions to run next once we exit the monitor
             unsigned int recursion;                   // monitor routines can be called recursively, we need to keep track of that
-            struct __waitfor_mask_t mask;               // mask used to know if some thread is waiting for something while holding the monitor
+            struct __waitfor_mask_t mask;             // mask used to know if some thread is waiting for something while holding the monitor
+            struct __condition_node_t * dtor_node;    // node used to signal the dtor in a waitfor dtor
       };
 
Index: src/libcfa/concurrency/monitor
===================================================================
--- src/libcfa/concurrency/monitor	(revision ea156ae77e5077f52dce5b9271017e97af22e2ef)
+++ src/libcfa/concurrency/monitor	(revision 549c006f5f7e2f45d09672b9abae0dfe3809c271)
@@ -29,12 +29,17 @@
 static inline void ?{}(monitor_desc & this) {
 	(this.lock){};
-	this.owner = NULL;
 	(this.entry_queue){};
 	(this.signal_stack){};
-	this.recursion = 0;
+	this.owner         = NULL;
+	this.recursion     = 0;
 	this.mask.accepted = NULL;
 	this.mask.clauses  = NULL;
 	this.mask.size     = 0;
+	this.dtor_node     = NULL;
 }
+
+// static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) {
+// 	return ((intptr_t)lhs) < ((intptr_t)rhs);
+// }
 
 struct monitor_guard_t {
@@ -46,10 +51,17 @@
 };
 
-static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) {
-	return ((intptr_t)lhs) < ((intptr_t)rhs);
-}
-
 void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() );
 void ^?{}( monitor_guard_t & this );
+
+
+struct monitor_dtor_guard_t {
+	monitor_desc * m;
+	monitor_desc ** prev_mntrs;
+	unsigned short  prev_count;
+	fptr_t          prev_func;
+};
+
+void ?{}( monitor_dtor_guard_t & this, monitor_desc ** m, void (*func)() );
+void ^?{}( monitor_dtor_guard_t & this );
 
 //-----------------------------------------------------------------------------
Index: src/libcfa/concurrency/monitor.c
===================================================================
--- src/libcfa/concurrency/monitor.c	(revision ea156ae77e5077f52dce5b9271017e97af22e2ef)
+++ src/libcfa/concurrency/monitor.c	(revision 549c006f5f7e2f45d09672b9abae0dfe3809c271)
@@ -94,5 +94,5 @@
 		}
 		else if( this->owner == thrd) {
-			// We already have the monitor, just not how many times we took it
+			// We already have the monitor, just note how many times we took it
 			verify( this->recursion > 0 );
 			this->recursion += 1;
@@ -127,4 +127,63 @@
 		unlock( &this->lock );
 		return;
+	}
+
+	static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) {
+		// Lock the monitor spinlock, lock_yield to reduce contention
+		lock_yield( &this->lock DEBUG_CTX2 );
+		thread_desc * thrd = this_thread;
+
+		LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner);
+
+
+		if( !this->owner ) {
+			LIB_DEBUG_PRINT_SAFE("Kernel : Destroying free mon %p\n", this);
+
+			// No one has the monitor, just take it
+			set_owner( this, thrd );
+
+			unlock( &this->lock );
+			return;
+		}
+		else if( this->owner == thrd) {
+			// We already have the monitor... but where about to destroy it so the nesting will fail
+			// Abort!
+			abortf("Attempt to destroy monitor %p by thread \"%.256s\" (%p) in nested mutex.");
+		}
+
+		int count = 1;
+		monitor_desc ** monitors = &this;
+		__monitor_group_t group = { &this, 1, func };
+		if( is_accepted( this, group) ) {
+			LIB_DEBUG_PRINT_SAFE("Kernel :  mon accepts dtor, block and signal it \n");
+
+			// Reset mask
+			reset_mask( this );
+
+			// Create the node specific to this wait operation
+			wait_ctx_primed( this_thread, 0 )
+
+			// Some one else has the monitor, wait for him to finish and then run
+			BlockInternal( &this->lock );
+
+			// Some one was waiting for us, enter
+			set_owner( this, thrd );
+		}
+		else {
+			LIB_DEBUG_PRINT_SAFE("Kernel :  blocking \n");
+
+			wait_ctx( this_thread, 0 )
+			this->dtor_node = &waiter;
+
+			// Some one else has the monitor, wait in line for it
+			append( &this->entry_queue, thrd );
+			BlockInternal( &this->lock );
+
+			// BlockInternal will unlock spinlock, no need to unlock ourselves
+			return;
+		}
+
+		LIB_DEBUG_PRINT_SAFE("Kernel : Destroying %p\n", this);
+
 	}
 
@@ -158,4 +217,16 @@
 	}
 
+	// Leave single monitor for the last time
+	void __leave_dtor_monitor_desc( monitor_desc * this ) {
+		LIB_DEBUG_DO(
+			if( this_thread != this->owner ) {
+				abortf("Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, this_thread, this->owner);
+			}
+			if( this->recursion != 1 ) {
+				abortf("Destroyed monitor %p has %d outstanding nested calls.\n", this, this->recursion - 1);
+			}
+		)
+	}
+
 	// Leave the thread monitor
 	// last routine called by a thread.
@@ -210,5 +281,5 @@
 // Ctor for monitor guard
 // Sorts monitors before entering
-void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() ) {
+void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, fptr_t func ) {
 	// Store current array
 	this.m = m;
@@ -246,4 +317,36 @@
 
 	// LIB_DEBUG_PRINT_SAFE("MGUARD : left\n");
+
+	// Restore thread context
+	this_thread->monitors.list = this.prev_mntrs;
+	this_thread->monitors.size = this.prev_count;
+	this_thread->monitors.func = this.prev_func;
+}
+
+
+// Ctor for monitor guard
+// Sorts monitors before entering
+void ?{}( monitor_dtor_guard_t & this, monitor_desc ** m, fptr_t func ) {
+	// Store current array
+	this.m = *m;
+
+	// Save previous thread context
+	this.prev_mntrs = this_thread->monitors.list;
+	this.prev_count = this_thread->monitors.size;
+	this.prev_func  = this_thread->monitors.func;
+
+	// Update thread context (needed for conditions)
+	this_thread->monitors.list = m;
+	this_thread->monitors.size = 1;
+	this_thread->monitors.func = func;
+
+	__enter_monitor_dtor( this.m, func );
+}
+
+
+// Dtor for monitor guard
+void ^?{}( monitor_dtor_guard_t & this ) {
+	// Leave the monitors in order
+	__leave_dtor_monitor_desc( this.m );
 
 	// Restore thread context
@@ -448,5 +551,13 @@
 			*mask.accepted = index;
 			if( mask.clauses[index].is_dtor ) {
-				#warning case not implemented
+				verifyf( mask.clauses[index].size == 1        , "ERROR: Accepted dtor has more than 1 mutex parameter." );
+
+				monitor_desc * mon2dtor = mask.clauses[index].list[0];
+				verifyf( mon2dtor->dtor_node, "ERROR: Accepted monitor has no dtor_node." );
+
+				__condition_criterion_t * dtor_crit = mon2dtor->dtor_node->criteria;
+				push( &mon2dtor->signal_stack, dtor_crit );
+
+				unlock_all( locks, count );
 			}
 			else {
