Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/Concurrency/Keywords.cc	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -201,5 +201,5 @@
 		std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
 		void validate( DeclarationWithType * );
-		void addStatments( CompoundStmt *, const std::list<DeclarationWithType * > &);
+		void addStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
 
 		static void implement( std::list< Declaration * > & translationUnit ) {
@@ -211,5 +211,14 @@
 	  	StructDecl* monitor_decl = nullptr;
 		StructDecl* guard_decl = nullptr;
+
+		static std::unique_ptr< Type > generic_func;
 	};
+
+	std::unique_ptr< Type > MutexKeyword::generic_func = std::unique_ptr< Type >(
+		new FunctionType(
+			noQualifiers,
+			true
+		)
+	);
 
 	//-----------------------------------------------------------------------------
@@ -395,4 +404,5 @@
 	// Mutex keyword implementation
 	//=============================================================================================
+
 	void MutexKeyword::visit(FunctionDecl* decl) {
 		Visitor::visit(decl);
@@ -411,5 +421,5 @@
 		if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
 
-		addStatments( body, mutexArgs );
+		addStatments( decl, body, mutexArgs );
 	}
 
@@ -458,5 +468,5 @@
 	}
 
-	void MutexKeyword::addStatments( CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
+	void MutexKeyword::addStatments( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
 		ObjectDecl * monitors = new ObjectDecl(
 			"__monitors",
@@ -489,6 +499,8 @@
 		);
 
+		assert(generic_func);
+
 		//in reverse order :
-		// monitor_guard_t __guard = { __monitors, # };
+		// monitor_guard_t __guard = { __monitors, #, func };
 		body->push_front(
 			new DeclStmt( noLabels, new ObjectDecl(
@@ -504,5 +516,6 @@
 					{
 						new SingleInit( new VariableExpr( monitors ) ),
-						new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) )
+						new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) ),
+						new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone() ) )
 					},
 					noDesignators,
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/Parser/ParseNode.h	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -414,4 +414,8 @@
 Statement * build_compound( StatementNode * first );
 Statement * build_asmstmt( bool voltile, ConstantExpr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
+WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
+WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
+WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
+WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
 
 //##############################################################################
Index: src/Parser/StatementNode.cc
===================================================================
--- src/Parser/StatementNode.cc	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/Parser/StatementNode.cc	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -93,5 +93,5 @@
 		elseb = branches.front();
 	} // if
-	
+
 	std::list< Statement * > init;
 	if ( ctl->init != 0 ) {
@@ -207,4 +207,72 @@
 }
 
+WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when ) {
+	auto node = new WaitForStmt();
+
+	WaitForStmt::Target target;
+	target.function = maybeBuild<Expression>( targetExpr );
+	buildMoveList< Expression >( targetExpr, target.arguments );
+	delete targetExpr;
+
+	node->clauses.push_back( WaitForStmt::Clause{
+		target,
+		maybeMoveBuild<Statement >( stmt ),
+		maybeMoveBuild<Expression>( when )
+	});
+
+	return node;
+}
+
+WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when, WaitForStmt * node ) {
+	WaitForStmt::Target target;
+
+	target.function = maybeBuild<Expression>( targetExpr );
+	buildMoveList< Expression >( targetExpr, target.arguments );
+	delete targetExpr;
+
+	node->clauses.push_back( WaitForStmt::Clause{
+		std::move( target ),
+		maybeMoveBuild<Statement >( stmt ),
+		maybeMoveBuild<Expression>( when )
+	});
+
+	return node;
+}
+
+WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when ) {
+	auto node = new WaitForStmt();
+
+	if( timeout ) {
+		node->timeout.time      = maybeMoveBuild<Expression>( timeout );
+		node->timeout.statement = maybeMoveBuild<Statement >( stmt    );
+		node->timeout.condition = maybeMoveBuild<Expression>( when    );
+	}
+	else {
+		node->orelse.statement  = maybeMoveBuild<Statement >( stmt    );
+		node->orelse.condition  = maybeMoveBuild<Expression>( when    );
+	}
+
+	return node;
+}
+
+WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when,  StatementNode * else_stmt, ExpressionNode * else_when ) {
+	auto node = new WaitForStmt();
+
+	node->timeout.time      = maybeMoveBuild<Expression>( timeout );
+	node->timeout.statement = maybeMoveBuild<Statement >( stmt    );
+	node->timeout.condition = maybeMoveBuild<Expression>( when    );
+
+	node->orelse.statement = maybeMoveBuild<Statement >( else_stmt );
+	node->orelse.condition = maybeMoveBuild<Expression>( else_when );
+
+	return node;
+}
+
+// WaitForStmt::Target build_waitfor( const std::string * name, ExpressionNode * arguments ) {
+// 	 return WaitForStmt::Clause{
+
+// 	 };
+// }
+
 Statement *build_compound( StatementNode *first ) {
 	CompoundStmt *cs = new CompoundStmt( noLabels );
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/Parser/parser.yy	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Aug 23 21:08:08 2017
-// Update Count     : 2704
+// Last Modified On : Sat Aug 26 17:50:19 2017
+// Update Count     : 2712
 //
 
@@ -97,4 +97,5 @@
 	DeclarationNode::TypeClass tclass;
 	StatementNode * sn;
+	WaitForStmt * wfs;
 	ConstantExpr * constant;
 	IfCtl * ifctl;
@@ -119,5 +120,5 @@
 %token RESTRICT											// C99
 %token ATOMIC											// C11
-%token FORALL MUTEX VIRTUAL						// CFA
+%token FORALL MUTEX VIRTUAL								// CFA
 %token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED
 %token BOOL COMPLEX IMAGINARY							// C99
@@ -189,17 +190,19 @@
 
 // statements
-%type<sn> labeled_statement				compound_statement			expression_statement		selection_statement
-%type<sn> iteration_statement			jump_statement
-%type<sn> with_statement				exception_statement			asm_statement
-%type<sn> when_clause_opt				waitfor_statement			waitfor_clause				waitfor				timeout
-%type<sn> fall_through_opt				fall_through
-%type<sn> statement						statement_list
-%type<sn> block_item_list				block_item
-%type<sn> with_clause_opt
+%type<sn> statement						labeled_statement			compound_statement
+%type<sn> statement_decl				statement_decl_list			statement_list_nodecl
+%type<sn> selection_statement
+%type<sn> switch_clause_list_opt		switch_clause_list			choose_clause_list_opt		choose_clause_list
 %type<en> case_value
 %type<sn> case_clause					case_value_list				case_label					case_label_list
-%type<sn> switch_clause_list_opt		switch_clause_list			choose_clause_list_opt		choose_clause_list
-%type<sn> handler_clause				finally_clause
+%type<sn> fall_through					fall_through_opt
+%type<sn> iteration_statement			jump_statement
+%type<sn> expression_statement			asm_statement
+%type<sn> with_statement				with_clause_opt
+%type<sn> exception_statement			handler_clause				finally_clause
 %type<catch_kind> handler_key
+%type<en> when_clause					when_clause_opt				waitfor						timeout
+%type<sn> waitfor_statement
+%type<wfs> waitfor_clause
 
 // declarations
@@ -773,16 +776,16 @@
 	  push push
 	  local_label_declaration_opt						// GCC, local labels
-	  block_item_list									// C99, intermix declarations and statements
+	  statement_decl_list								// C99, intermix declarations and statements
 	  pop '}'
 		{ $$ = new StatementNode( build_compound( $5 ) ); }
 	;
 
-block_item_list:										// C99
-	block_item
-	| block_item_list push block_item
+statement_decl_list:									// C99
+	statement_decl
+	| statement_decl_list push statement_decl
 		{ if ( $1 != 0 ) { $1->set_last( $3 ); $$ = $1; } }
 	;
 
-block_item:
+statement_decl:
 	declaration											// CFA, new & old style declarations
 		{ $$ = new StatementNode( $1 ); }
@@ -802,7 +805,7 @@
 	;
 
-statement_list:
+statement_list_nodecl:
 	statement
-	| statement_list statement
+	| statement_list_nodecl statement
 		{ if ( $1 != 0 ) { $1->set_last( $2 ); $$ = $1; } }
 	;
@@ -814,5 +817,5 @@
 
 selection_statement:
-	IF '(' push if_control_expression ')' statement				%prec THEN
+	IF '(' push if_control_expression ')' statement		%prec THEN
 		// explicitly deal with the shift/reduce conflict on if/else
 		{ $$ = new StatementNode( build_if( $4, $6, nullptr ) ); }
@@ -889,7 +892,7 @@
 
 switch_clause_list:										// CFA
-	case_label_list statement_list
+	case_label_list statement_list_nodecl
 		{ $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); }
-	| switch_clause_list case_label_list statement_list
+	| switch_clause_list case_label_list statement_list_nodecl
 		{ $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( $3 ) ) ) ) ); }
 	;
@@ -904,9 +907,9 @@
 	case_label_list fall_through
 		{ $$ = $1->append_last_case( $2 ); }
-	| case_label_list statement_list fall_through_opt
+	| case_label_list statement_list_nodecl fall_through_opt
 		{ $$ = $1->append_last_case( new StatementNode( build_compound( (StatementNode *)$2->set_last( $3 ) ) ) ); }
 	| choose_clause_list case_label_list fall_through
 		{ $$ = (StatementNode *)( $1->set_last( $2->append_last_case( $3 ))); }
-	| choose_clause_list case_label_list statement_list fall_through_opt
+	| choose_clause_list case_label_list statement_list_nodecl fall_through_opt
 		{ $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( (StatementNode *)$3->set_last( $4 ) ) ) ) ) ); }
 	;
@@ -977,41 +980,53 @@
 	;
 
+when_clause:
+	WHEN '(' comma_expression ')'
+		{ $$ = $3; }
+	;
+
 when_clause_opt:
 	// empty
-		{ $$ = nullptr; }								// FIX ME
-	| WHEN '(' comma_expression ')'
-		{ $$ = nullptr; }								// FIX ME
+		{ $$ = nullptr; }
+	| when_clause
 	;
 
 waitfor:
 	WAITFOR '(' identifier ')'
- 		{ $$ = nullptr; }								// FIX ME
+ 		{
+			$$ = new ExpressionNode( new NameExpr( *$3 ) );
+			delete $3;
+		}
 	| WAITFOR '(' identifier ',' argument_expression_list ')'
- 		{ $$ = nullptr; }								// FIX ME
+ 		{
+			$$ = new ExpressionNode( new NameExpr( *$3 ) );
+		  	$$->set_last( $5 );
+			delete $3;
+		}
 	;
 
 timeout:
 	TIMEOUT '(' comma_expression ')'
- 		{ $$ = nullptr; }								// FIX ME
+ 		{ $$ = $3; }
 	;
 
 waitfor_clause:
-	when_clause_opt waitfor statement %prec THEN
- 		{ $$ = nullptr; }								// FIX ME
+	when_clause_opt waitfor statement					%prec THEN
+ 		{ $$ = build_waitfor( $2, $3, $1 ); }
 	| when_clause_opt waitfor statement WOR waitfor_clause
- 		{ $$ = nullptr; }								// FIX ME
-	| when_clause_opt timeout statement %prec THEN
- 		{ $$ = nullptr; }								// FIX ME
+ 		{ $$ = build_waitfor( $2, $3, $1, $5 ); }
+	| when_clause_opt timeout statement					%prec THEN
+ 		{ $$ = build_waitfor_timeout( $2, $3, $1 ); }
 	| when_clause_opt ELSE statement
- 		{ $$ = nullptr; }								// FIX ME
-	| when_clause_opt timeout statement WOR when_clause_opt ELSE statement
- 		{ $$ = nullptr; }								// FIX ME
+ 		{ $$ = build_waitfor_timeout( nullptr, $3, $1 ); }
+		// "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
+	| when_clause_opt timeout statement WOR when_clause ELSE statement
+ 		{ $$ = build_waitfor_timeout( $2, $3, $1, $7, $5 ); }
 	;
 
 waitfor_statement:
-	when_clause_opt waitfor statement %prec THEN
- 		{ $$ = nullptr; }								// FIX ME
+	when_clause_opt waitfor statement					%prec THEN
+ 		{ $$ = new StatementNode( build_waitfor( $2, $3, $1 ) ); }
 	| when_clause_opt waitfor statement WOR waitfor_clause
- 		{ $$ = nullptr; }								// FIX ME
+ 		{ $$ = new StatementNode( build_waitfor( $2, $3, $1, $5 ) ); }
 	;
 
Index: src/SynTree/Mutator.cc
===================================================================
--- src/SynTree/Mutator.cc	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/SynTree/Mutator.cc	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -32,5 +32,5 @@
 Mutator::~Mutator() {}
 
-DeclarationWithType *Mutator::mutate( ObjectDecl *objectDecl ) {
+DeclarationWithType * Mutator::mutate( ObjectDecl *objectDecl ) {
 	objectDecl->set_type( maybeMutate( objectDecl->get_type(), *this ) );
 	objectDecl->set_init( maybeMutate( objectDecl->get_init(), *this ) );
@@ -39,5 +39,5 @@
 }
 
-DeclarationWithType *Mutator::mutate( FunctionDecl *functionDecl ) {
+DeclarationWithType * Mutator::mutate( FunctionDecl *functionDecl ) {
 	functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
 	functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
@@ -45,5 +45,5 @@
 }
 
-Declaration *Mutator::handleAggregateDecl( AggregateDecl *aggregateDecl ) {
+Declaration * Mutator::handleAggregateDecl( AggregateDecl *aggregateDecl ) {
 	mutateAll( aggregateDecl->get_parameters(), *this );
 	mutateAll( aggregateDecl->get_members(), *this );
@@ -51,25 +51,25 @@
 }
 
-Declaration *Mutator::mutate( StructDecl *aggregateDecl ) {
+Declaration * Mutator::mutate( StructDecl *aggregateDecl ) {
 	handleAggregateDecl( aggregateDecl );
 	return aggregateDecl;
 }
 
-Declaration *Mutator::mutate( UnionDecl *aggregateDecl ) {
+Declaration * Mutator::mutate( UnionDecl *aggregateDecl ) {
 	handleAggregateDecl( aggregateDecl );
 	return aggregateDecl;
 }
 
-Declaration *Mutator::mutate( EnumDecl *aggregateDecl ) {
+Declaration * Mutator::mutate( EnumDecl *aggregateDecl ) {
 	handleAggregateDecl( aggregateDecl );
 	return aggregateDecl;
 }
 
-Declaration *Mutator::mutate( TraitDecl *aggregateDecl ) {
+Declaration * Mutator::mutate( TraitDecl *aggregateDecl ) {
 	handleAggregateDecl( aggregateDecl );
 	return aggregateDecl;
 }
 
-Declaration *Mutator::handleNamedTypeDecl( NamedTypeDecl *typeDecl ) {
+Declaration * Mutator::handleNamedTypeDecl( NamedTypeDecl *typeDecl ) {
 	mutateAll( typeDecl->get_parameters(), *this );
 	mutateAll( typeDecl->get_assertions(), *this );
@@ -78,5 +78,5 @@
 }
 
-TypeDecl *Mutator::mutate( TypeDecl *typeDecl ) {
+TypeDecl * Mutator::mutate( TypeDecl *typeDecl ) {
 	handleNamedTypeDecl( typeDecl );
 	typeDecl->set_init( maybeMutate( typeDecl->get_init(), *this ) );
@@ -84,10 +84,10 @@
 }
 
-Declaration *Mutator::mutate( TypedefDecl *typeDecl ) {
+Declaration * Mutator::mutate( TypedefDecl *typeDecl ) {
 	handleNamedTypeDecl( typeDecl );
 	return typeDecl;
 }
 
-AsmDecl *Mutator::mutate( AsmDecl *asmDecl ) {
+AsmDecl * Mutator::mutate( AsmDecl *asmDecl ) {
 	asmDecl->set_stmt( maybeMutate( asmDecl->get_stmt(), *this ) );
 	return asmDecl;
@@ -95,15 +95,15 @@
 
 
-CompoundStmt *Mutator::mutate( CompoundStmt *compoundStmt ) {
+CompoundStmt * Mutator::mutate( CompoundStmt *compoundStmt ) {
 	mutateAll( compoundStmt->get_kids(), *this );
 	return compoundStmt;
 }
 
-Statement *Mutator::mutate( ExprStmt *exprStmt ) {
+Statement * Mutator::mutate( ExprStmt *exprStmt ) {
 	exprStmt->set_expr( maybeMutate( exprStmt->get_expr(), *this ) );
 	return exprStmt;
 }
 
-Statement *Mutator::mutate( AsmStmt *asmStmt ) {
+Statement * Mutator::mutate( AsmStmt *asmStmt ) {
 	asmStmt->set_instruction( maybeMutate( asmStmt->get_instruction(), *this ) );
 	mutateAll( asmStmt->get_output(), *this );
@@ -113,5 +113,5 @@
 }
 
-Statement *Mutator::mutate( IfStmt *ifStmt ) {
+Statement * Mutator::mutate( IfStmt *ifStmt ) {
 	mutateAll( ifStmt->get_initialization(), *this );
 	ifStmt->set_condition( maybeMutate( ifStmt->get_condition(), *this ) );
@@ -121,5 +121,5 @@
 }
 
-Statement *Mutator::mutate( WhileStmt *whileStmt ) {
+Statement * Mutator::mutate( WhileStmt *whileStmt ) {
 	whileStmt->set_condition( maybeMutate( whileStmt->get_condition(), *this ) );
 	whileStmt->set_body( maybeMutate( whileStmt->get_body(), *this ) );
@@ -127,5 +127,5 @@
 }
 
-Statement *Mutator::mutate( ForStmt *forStmt ) {
+Statement * Mutator::mutate( ForStmt *forStmt ) {
 	mutateAll( forStmt->get_initialization(), *this );
 	forStmt->set_condition( maybeMutate( forStmt->get_condition(), *this ) );
@@ -135,5 +135,5 @@
 }
 
-Statement *Mutator::mutate( SwitchStmt *switchStmt ) {
+Statement * Mutator::mutate( SwitchStmt *switchStmt ) {
 	switchStmt->set_condition( maybeMutate( switchStmt->get_condition(), *this ) );
 	mutateAll( switchStmt->get_statements(), *this );
@@ -141,5 +141,5 @@
 }
 
-Statement *Mutator::mutate( CaseStmt *caseStmt ) {
+Statement * Mutator::mutate( CaseStmt *caseStmt ) {
 	caseStmt->set_condition( maybeMutate( caseStmt->get_condition(), *this ) );
 	mutateAll (caseStmt->get_statements(), *this );
@@ -148,14 +148,14 @@
 }
 
-Statement *Mutator::mutate( BranchStmt *branchStmt ) {
+Statement * Mutator::mutate( BranchStmt *branchStmt ) {
 	return branchStmt;
 }
 
-Statement *Mutator::mutate( ReturnStmt *returnStmt ) {
+Statement * Mutator::mutate( ReturnStmt *returnStmt ) {
 	returnStmt->set_expr( maybeMutate( returnStmt->get_expr(), *this ) );
 	return returnStmt;
 }
 
-Statement *Mutator::mutate( ThrowStmt *throwStmt ) {
+Statement * Mutator::mutate( ThrowStmt *throwStmt ) {
 	throwStmt->set_expr( maybeMutate( throwStmt->get_expr(), *this ) );
 	throwStmt->set_target( maybeMutate( throwStmt->get_target(), *this ) );
@@ -163,5 +163,5 @@
 }
 
-Statement *Mutator::mutate( TryStmt *tryStmt ) {
+Statement * Mutator::mutate( TryStmt *tryStmt ) {
 	tryStmt->set_block( maybeMutate( tryStmt->get_block(), *this ) );
 	mutateAll( tryStmt->get_catchers(), *this );
@@ -170,5 +170,5 @@
 }
 
-Statement *Mutator::mutate( CatchStmt *catchStmt ) {
+Statement * Mutator::mutate( CatchStmt *catchStmt ) {
 	catchStmt->set_decl( maybeMutate( catchStmt->get_decl(), *this ) );
 	catchStmt->set_cond( maybeMutate( catchStmt->get_cond(), *this ) );
@@ -177,19 +177,37 @@
 }
 
-Statement *Mutator::mutate( FinallyStmt *finalStmt ) {
+Statement * Mutator::mutate( FinallyStmt *finalStmt ) {
 	finalStmt->set_block( maybeMutate( finalStmt->get_block(), *this ) );
 	return finalStmt;
 }
 
-NullStmt *Mutator::mutate( NullStmt *nullStmt ) {
+Statement * Mutator::mutate( WaitForStmt *waitforStmt ) {
+	for( auto & clause : waitforStmt->clauses ) {
+		clause.target.function = maybeMutate( clause.target.function, *this );
+		mutateAll( clause.target.arguments, *this );
+
+		clause.statement = maybeMutate( clause.statement, *this );
+		clause.condition = maybeMutate( clause.condition, *this );
+	}
+
+	waitforStmt->timeout.time      = maybeMutate( waitforStmt->timeout.time, *this );
+	waitforStmt->timeout.statement = maybeMutate( waitforStmt->timeout.statement, *this );
+	waitforStmt->timeout.condition = maybeMutate( waitforStmt->timeout.condition, *this );
+	waitforStmt->orelse.statement  = maybeMutate( waitforStmt->orelse.statement, *this );
+	waitforStmt->orelse.condition  = maybeMutate( waitforStmt->orelse.condition, *this );
+
+	return waitforStmt;
+}
+
+NullStmt * Mutator::mutate( NullStmt *nullStmt ) {
 	return nullStmt;
 }
 
-Statement *Mutator::mutate( DeclStmt *declStmt ) {
+Statement * Mutator::mutate( DeclStmt *declStmt ) {
 	declStmt->set_decl( maybeMutate( declStmt->get_decl(), *this ) );
 	return declStmt;
 }
 
-Statement *Mutator::mutate( ImplicitCtorDtorStmt *impCtorDtorStmt ) {
+Statement * Mutator::mutate( ImplicitCtorDtorStmt *impCtorDtorStmt ) {
 	impCtorDtorStmt->set_callStmt( maybeMutate( impCtorDtorStmt->get_callStmt(), *this ) );
 	return impCtorDtorStmt;
@@ -197,5 +215,5 @@
 
 
-Expression *Mutator::mutate( ApplicationExpr *applicationExpr ) {
+Expression * Mutator::mutate( ApplicationExpr *applicationExpr ) {
 	applicationExpr->set_env( maybeMutate( applicationExpr->get_env(), *this ) );
 	applicationExpr->set_result( maybeMutate( applicationExpr->get_result(), *this ) );
@@ -205,5 +223,5 @@
 }
 
-Expression *Mutator::mutate( UntypedExpr *untypedExpr ) {
+Expression * Mutator::mutate( UntypedExpr *untypedExpr ) {
 	untypedExpr->set_env( maybeMutate( untypedExpr->get_env(), *this ) );
 	untypedExpr->set_result( maybeMutate( untypedExpr->get_result(), *this ) );
@@ -212,5 +230,5 @@
 }
 
-Expression *Mutator::mutate( NameExpr *nameExpr ) {
+Expression * Mutator::mutate( NameExpr *nameExpr ) {
 	nameExpr->set_env( maybeMutate( nameExpr->get_env(), *this ) );
 	nameExpr->set_result( maybeMutate( nameExpr->get_result(), *this ) );
@@ -218,5 +236,5 @@
 }
 
-Expression *Mutator::mutate( AddressExpr *addressExpr ) {
+Expression * Mutator::mutate( AddressExpr *addressExpr ) {
 	addressExpr->set_env( maybeMutate( addressExpr->get_env(), *this ) );
 	addressExpr->set_result( maybeMutate( addressExpr->get_result(), *this ) );
@@ -225,5 +243,5 @@
 }
 
-Expression *Mutator::mutate( LabelAddressExpr *labelAddressExpr ) {
+Expression * Mutator::mutate( LabelAddressExpr *labelAddressExpr ) {
 	labelAddressExpr->set_env( maybeMutate( labelAddressExpr->get_env(), *this ) );
 	labelAddressExpr->set_result( maybeMutate( labelAddressExpr->get_result(), *this ) );
@@ -232,5 +250,5 @@
 }
 
-Expression *Mutator::mutate( CastExpr *castExpr ) {
+Expression * Mutator::mutate( CastExpr *castExpr ) {
 	castExpr->set_env( maybeMutate( castExpr->get_env(), *this ) );
 	castExpr->set_result( maybeMutate( castExpr->get_result(), *this ) );
@@ -239,5 +257,5 @@
 }
 
-Expression *Mutator::mutate( VirtualCastExpr *castExpr ) {
+Expression * Mutator::mutate( VirtualCastExpr *castExpr ) {
 	castExpr->set_env( maybeMutate( castExpr->get_env(), *this ) );
 	castExpr->set_result( maybeMutate( castExpr->get_result(), *this ) );
@@ -246,5 +264,5 @@
 }
 
-Expression *Mutator::mutate( UntypedMemberExpr *memberExpr ) {
+Expression * Mutator::mutate( UntypedMemberExpr *memberExpr ) {
 	memberExpr->set_env( maybeMutate( memberExpr->get_env(), *this ) );
 	memberExpr->set_result( maybeMutate( memberExpr->get_result(), *this ) );
@@ -254,5 +272,5 @@
 }
 
-Expression *Mutator::mutate( MemberExpr *memberExpr ) {
+Expression * Mutator::mutate( MemberExpr *memberExpr ) {
 	memberExpr->set_env( maybeMutate( memberExpr->get_env(), *this ) );
 	memberExpr->set_result( maybeMutate( memberExpr->get_result(), *this ) );
@@ -261,5 +279,5 @@
 }
 
-Expression *Mutator::mutate( VariableExpr *variableExpr ) {
+Expression * Mutator::mutate( VariableExpr *variableExpr ) {
 	variableExpr->set_env( maybeMutate( variableExpr->get_env(), *this ) );
 	variableExpr->set_result( maybeMutate( variableExpr->get_result(), *this ) );
@@ -267,5 +285,5 @@
 }
 
-Expression *Mutator::mutate( ConstantExpr *constantExpr ) {
+Expression * Mutator::mutate( ConstantExpr *constantExpr ) {
 	constantExpr->set_env( maybeMutate( constantExpr->get_env(), *this ) );
 	constantExpr->set_result( maybeMutate( constantExpr->get_result(), *this ) );
@@ -274,5 +292,5 @@
 }
 
-Expression *Mutator::mutate( SizeofExpr *sizeofExpr ) {
+Expression * Mutator::mutate( SizeofExpr *sizeofExpr ) {
 	sizeofExpr->set_env( maybeMutate( sizeofExpr->get_env(), *this ) );
 	sizeofExpr->set_result( maybeMutate( sizeofExpr->get_result(), *this ) );
@@ -285,5 +303,5 @@
 }
 
-Expression *Mutator::mutate( AlignofExpr *alignofExpr ) {
+Expression * Mutator::mutate( AlignofExpr *alignofExpr ) {
 	alignofExpr->set_env( maybeMutate( alignofExpr->get_env(), *this ) );
 	alignofExpr->set_result( maybeMutate( alignofExpr->get_result(), *this ) );
@@ -296,5 +314,5 @@
 }
 
-Expression *Mutator::mutate( UntypedOffsetofExpr *offsetofExpr ) {
+Expression * Mutator::mutate( UntypedOffsetofExpr *offsetofExpr ) {
 	offsetofExpr->set_env( maybeMutate( offsetofExpr->get_env(), *this ) );
 	offsetofExpr->set_result( maybeMutate( offsetofExpr->get_result(), *this ) );
@@ -303,5 +321,5 @@
 }
 
-Expression *Mutator::mutate( OffsetofExpr *offsetofExpr ) {
+Expression * Mutator::mutate( OffsetofExpr *offsetofExpr ) {
 	offsetofExpr->set_env( maybeMutate( offsetofExpr->get_env(), *this ) );
 	offsetofExpr->set_result( maybeMutate( offsetofExpr->get_result(), *this ) );
@@ -311,5 +329,5 @@
 }
 
-Expression *Mutator::mutate( OffsetPackExpr *offsetPackExpr ) {
+Expression * Mutator::mutate( OffsetPackExpr *offsetPackExpr ) {
 	offsetPackExpr->set_env( maybeMutate( offsetPackExpr->get_env(), *this ) );
 	offsetPackExpr->set_result( maybeMutate( offsetPackExpr->get_result(), *this ) );
@@ -318,5 +336,5 @@
 }
 
-Expression *Mutator::mutate( AttrExpr *attrExpr ) {
+Expression * Mutator::mutate( AttrExpr *attrExpr ) {
 	attrExpr->set_env( maybeMutate( attrExpr->get_env(), *this ) );
 	attrExpr->set_result( maybeMutate( attrExpr->get_result(), *this ) );
@@ -329,5 +347,5 @@
 }
 
-Expression *Mutator::mutate( LogicalExpr *logicalExpr ) {
+Expression * Mutator::mutate( LogicalExpr *logicalExpr ) {
 	logicalExpr->set_env( maybeMutate( logicalExpr->get_env(), *this ) );
 	logicalExpr->set_result( maybeMutate( logicalExpr->get_result(), *this ) );
@@ -337,5 +355,5 @@
 }
 
-Expression *Mutator::mutate( ConditionalExpr *conditionalExpr ) {
+Expression * Mutator::mutate( ConditionalExpr *conditionalExpr ) {
 	conditionalExpr->set_env( maybeMutate( conditionalExpr->get_env(), *this ) );
 	conditionalExpr->set_result( maybeMutate( conditionalExpr->get_result(), *this ) );
@@ -346,5 +364,5 @@
 }
 
-Expression *Mutator::mutate( CommaExpr *commaExpr ) {
+Expression * Mutator::mutate( CommaExpr *commaExpr ) {
 	commaExpr->set_env( maybeMutate( commaExpr->get_env(), *this ) );
 	commaExpr->set_result( maybeMutate( commaExpr->get_result(), *this ) );
@@ -354,5 +372,5 @@
 }
 
-Expression *Mutator::mutate( TypeExpr *typeExpr ) {
+Expression * Mutator::mutate( TypeExpr *typeExpr ) {
 	typeExpr->set_env( maybeMutate( typeExpr->get_env(), *this ) );
 	typeExpr->set_result( maybeMutate( typeExpr->get_result(), *this ) );
@@ -361,5 +379,5 @@
 }
 
-Expression *Mutator::mutate( AsmExpr *asmExpr ) {
+Expression * Mutator::mutate( AsmExpr *asmExpr ) {
 	asmExpr->set_env( maybeMutate( asmExpr->get_env(), *this ) );
 	asmExpr->set_inout( maybeMutate( asmExpr->get_inout(), *this ) );
@@ -386,5 +404,5 @@
 }
 
-Expression *Mutator::mutate( CompoundLiteralExpr *compLitExpr ) {
+Expression * Mutator::mutate( CompoundLiteralExpr *compLitExpr ) {
 	compLitExpr->set_env( maybeMutate( compLitExpr->get_env(), *this ) );
 	compLitExpr->set_result( maybeMutate( compLitExpr->get_result(), *this ) );
@@ -393,5 +411,5 @@
 }
 
-Expression *Mutator::mutate( RangeExpr *rangeExpr ) {
+Expression * Mutator::mutate( RangeExpr *rangeExpr ) {
 	rangeExpr->set_env( maybeMutate( rangeExpr->get_env(), *this ) );
 	rangeExpr->set_low( maybeMutate( rangeExpr->get_low(), *this ) );
@@ -400,5 +418,5 @@
 }
 
-Expression *Mutator::mutate( UntypedTupleExpr *tupleExpr ) {
+Expression * Mutator::mutate( UntypedTupleExpr *tupleExpr ) {
 	tupleExpr->set_env( maybeMutate( tupleExpr->get_env(), *this ) );
 	tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
@@ -407,5 +425,5 @@
 }
 
-Expression *Mutator::mutate( TupleExpr *tupleExpr ) {
+Expression * Mutator::mutate( TupleExpr *tupleExpr ) {
 	tupleExpr->set_env( maybeMutate( tupleExpr->get_env(), *this ) );
 	tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
@@ -414,5 +432,5 @@
 }
 
-Expression *Mutator::mutate( TupleIndexExpr *tupleExpr ) {
+Expression * Mutator::mutate( TupleIndexExpr *tupleExpr ) {
 	tupleExpr->set_env( maybeMutate( tupleExpr->get_env(), *this ) );
 	tupleExpr->set_result( maybeMutate( tupleExpr->get_result(), *this ) );
@@ -421,5 +439,5 @@
 }
 
-Expression *Mutator::mutate( TupleAssignExpr *assignExpr ) {
+Expression * Mutator::mutate( TupleAssignExpr *assignExpr ) {
 	assignExpr->set_env( maybeMutate( assignExpr->get_env(), *this ) );
 	assignExpr->set_result( maybeMutate( assignExpr->get_result(), *this ) );
@@ -428,5 +446,5 @@
 }
 
-Expression *Mutator::mutate( StmtExpr *stmtExpr ) {
+Expression * Mutator::mutate( StmtExpr *stmtExpr ) {
 	stmtExpr->set_env( maybeMutate( stmtExpr->get_env(), *this ) );
 	stmtExpr->set_result( maybeMutate( stmtExpr->get_result(), *this ) );
@@ -437,5 +455,5 @@
 }
 
-Expression *Mutator::mutate( UniqueExpr *uniqueExpr ) {
+Expression * Mutator::mutate( UniqueExpr *uniqueExpr ) {
 	uniqueExpr->set_env( maybeMutate( uniqueExpr->get_env(), *this ) );
 	uniqueExpr->set_result( maybeMutate( uniqueExpr->get_result(), *this ) );
@@ -444,5 +462,5 @@
 }
 
-Expression *Mutator::mutate( UntypedInitExpr * initExpr ) {
+Expression * Mutator::mutate( UntypedInitExpr * initExpr ) {
 	initExpr->set_env( maybeMutate( initExpr->get_env(), *this ) );
 	initExpr->set_result( maybeMutate( initExpr->get_result(), *this ) );
@@ -452,5 +470,5 @@
 }
 
-Expression *Mutator::mutate( InitExpr * initExpr ) {
+Expression * Mutator::mutate( InitExpr * initExpr ) {
 	initExpr->set_env( maybeMutate( initExpr->get_env(), *this ) );
 	initExpr->set_result( maybeMutate( initExpr->get_result(), *this ) );
@@ -461,15 +479,15 @@
 
 
-Type *Mutator::mutate( VoidType *voidType ) {
+Type * Mutator::mutate( VoidType *voidType ) {
 	mutateAll( voidType->get_forall(), *this );
 	return voidType;
 }
 
-Type *Mutator::mutate( BasicType *basicType ) {
+Type * Mutator::mutate( BasicType *basicType ) {
 	mutateAll( basicType->get_forall(), *this );
 	return basicType;
 }
 
-Type *Mutator::mutate( PointerType *pointerType ) {
+Type * Mutator::mutate( PointerType *pointerType ) {
 	mutateAll( pointerType->get_forall(), *this );
 	pointerType->set_base( maybeMutate( pointerType->get_base(), *this ) );
@@ -477,5 +495,5 @@
 }
 
-Type *Mutator::mutate( ArrayType *arrayType ) {
+Type * Mutator::mutate( ArrayType *arrayType ) {
 	mutateAll( arrayType->get_forall(), *this );
 	arrayType->set_dimension( maybeMutate( arrayType->get_dimension(), *this ) );
@@ -484,5 +502,5 @@
 }
 
-Type *Mutator::mutate( ReferenceType *refType ) {
+Type * Mutator::mutate( ReferenceType * refType ) {
 	mutateAll( refType->get_forall(), *this );
 	refType->set_base( maybeMutate( refType->get_base(), *this ) );
@@ -490,5 +508,5 @@
 }
 
-Type *Mutator::mutate( FunctionType *functionType ) {
+Type * Mutator::mutate( FunctionType * functionType ) {
 	mutateAll( functionType->get_forall(), *this );
 	mutateAll( functionType->get_returnVals(), *this );
@@ -497,5 +515,5 @@
 }
 
-Type *Mutator::handleReferenceToType( ReferenceToType *aggregateUseType ) {
+Type * Mutator::handleReferenceToType( ReferenceToType *aggregateUseType ) {
 	mutateAll( aggregateUseType->get_forall(), *this );
 	mutateAll( aggregateUseType->get_parameters(), *this );
@@ -503,20 +521,20 @@
 }
 
-Type *Mutator::mutate( StructInstType *aggregateUseType ) {
+Type * Mutator::mutate( StructInstType *aggregateUseType ) {
 	handleReferenceToType( aggregateUseType );
 	return aggregateUseType;
 }
 
-Type *Mutator::mutate( UnionInstType *aggregateUseType ) {
+Type * Mutator::mutate( UnionInstType *aggregateUseType ) {
 	handleReferenceToType( aggregateUseType );
 	return aggregateUseType;
 }
 
-Type *Mutator::mutate( EnumInstType *aggregateUseType ) {
+Type * Mutator::mutate( EnumInstType *aggregateUseType ) {
 	handleReferenceToType( aggregateUseType );
 	return aggregateUseType;
 }
 
-Type *Mutator::mutate( TraitInstType *aggregateUseType ) {
+Type * Mutator::mutate( TraitInstType *aggregateUseType ) {
 	handleReferenceToType( aggregateUseType );
 	mutateAll( aggregateUseType->get_members(), *this );
@@ -524,10 +542,10 @@
 }
 
-Type *Mutator::mutate( TypeInstType *aggregateUseType ) {
+Type * Mutator::mutate( TypeInstType *aggregateUseType ) {
 	handleReferenceToType( aggregateUseType );
 	return aggregateUseType;
 }
 
-Type *Mutator::mutate( TupleType *tupleType ) {
+Type * Mutator::mutate( TupleType *tupleType ) {
 	mutateAll( tupleType->get_forall(), *this );
 	mutateAll( tupleType->get_types(), *this );
@@ -536,5 +554,5 @@
 }
 
-Type *Mutator::mutate( TypeofType *typeofType ) {
+Type * Mutator::mutate( TypeofType *typeofType ) {
 	assert( typeofType->get_expr() );
 	typeofType->set_expr( typeofType->get_expr()->acceptMutator( *this ) );
@@ -542,5 +560,5 @@
 }
 
-Type *Mutator::mutate( AttrType *attrType ) {
+Type * Mutator::mutate( AttrType *attrType ) {
 	if ( attrType->get_isType() ) {
 		assert( attrType->get_type() );
@@ -553,15 +571,15 @@
 }
 
-Type *Mutator::mutate( VarArgsType *varArgsType ) {
+Type * Mutator::mutate( VarArgsType *varArgsType ) {
 	mutateAll( varArgsType->get_forall(), *this );
 	return varArgsType;
 }
 
-Type *Mutator::mutate( ZeroType *zeroType ) {
+Type * Mutator::mutate( ZeroType *zeroType ) {
 	mutateAll( zeroType->get_forall(), *this );
 	return zeroType;
 }
 
-Type *Mutator::mutate( OneType *oneType ) {
+Type * Mutator::mutate( OneType *oneType ) {
 	mutateAll( oneType->get_forall(), *this );
 	return oneType;
@@ -569,15 +587,15 @@
 
 
-Designation *Mutator::mutate( Designation * designation ) {
+Designation * Mutator::mutate( Designation * designation ) {
 	mutateAll( designation->get_designators(), *this );
 	return designation;
 }
 
-Initializer *Mutator::mutate( SingleInit *singleInit ) {
+Initializer * Mutator::mutate( SingleInit *singleInit ) {
 	singleInit->set_value( singleInit->get_value()->acceptMutator( *this ) );
 	return singleInit;
 }
 
-Initializer *Mutator::mutate( ListInit *listInit ) {
+Initializer * Mutator::mutate( ListInit *listInit ) {
 	mutateAll( listInit->get_designations(), *this );
 	mutateAll( listInit->get_initializers(), *this );
@@ -585,5 +603,5 @@
 }
 
-Initializer *Mutator::mutate( ConstructorInit *ctorInit ) {
+Initializer * Mutator::mutate( ConstructorInit *ctorInit ) {
 	ctorInit->set_ctor( maybeMutate( ctorInit->get_ctor(), *this ) );
 	ctorInit->set_dtor( maybeMutate( ctorInit->get_dtor(), *this ) );
@@ -593,10 +611,10 @@
 
 
-Subrange *Mutator::mutate( Subrange *subrange ) {
+Subrange * Mutator::mutate( Subrange *subrange ) {
 	return subrange;
 }
 
 
-Constant *Mutator::mutate( Constant *constant ) {
+Constant * Mutator::mutate( Constant *constant ) {
 	return constant;
 }
Index: src/SynTree/Mutator.h
===================================================================
--- src/SynTree/Mutator.h	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/SynTree/Mutator.h	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -49,4 +49,5 @@
 	virtual Statement* mutate( CatchStmt *catchStmt );
 	virtual Statement* mutate( FinallyStmt *catchStmt );
+	virtual Statement* mutate( WaitForStmt *waitforStmt );
 	virtual NullStmt* mutate( NullStmt *nullStmt );
 	virtual Statement* mutate( DeclStmt *declStmt );
Index: src/SynTree/Statement.cc
===================================================================
--- src/SynTree/Statement.cc	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/SynTree/Statement.cc	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -419,4 +419,52 @@
 }
 
+WaitForStmt::WaitForStmt( std::list<Label> labels ) : Statement( labels ) {
+	timeout.time      = nullptr;
+	timeout.statement = nullptr;
+	timeout.condition = nullptr;
+ 	orelse .statement = nullptr;
+	orelse .condition = nullptr;
+}
+
+WaitForStmt::WaitForStmt( const WaitForStmt & other ) : Statement( other ) {
+	clauses.reserve( other.clauses.size() );
+	for( auto & ocl : other.clauses ) {
+		clauses.emplace_back();
+		clauses.back().target.function = ocl.target.function->clone();
+		cloneAll( ocl.target.arguments, clauses.back().target.arguments );
+		clauses.back().statement = ocl.statement->clone();
+		clauses.back().condition = ocl.condition->clone();
+	}
+
+	timeout.time      = other.timeout.time     ->clone();
+	timeout.statement = other.timeout.statement->clone();
+	timeout.condition = other.timeout.condition->clone();
+	orelse .statement = other.orelse .statement->clone();
+	orelse .condition = other.orelse .condition->clone();
+}
+
+WaitForStmt::~WaitForStmt() {
+	for( auto & clause : clauses ) {
+		delete clause.target.function;
+		deleteAll( clause.target.arguments );
+		delete clause.statement;
+		delete clause.condition;
+	}
+
+	delete timeout.time;
+	delete timeout.statement;
+	delete timeout.condition;
+
+	delete orelse.statement;
+	delete orelse.condition;
+}
+
+void WaitForStmt::print( std::ostream &os, int indent ) const {
+	os << "Waitfor Statement" << endl;
+	os << string( indent + 2, ' ' ) << "with block:" << endl;
+	os << string( indent + 4, ' ' );
+	// block->print( os, indent + 4 );
+}
+
 NullStmt::NullStmt( std::list<Label> labels ) : CompoundStmt( labels ) {}
 NullStmt::NullStmt() : CompoundStmt( std::list<Label>() ) {}
Index: src/SynTree/Statement.h
===================================================================
--- src/SynTree/Statement.h	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/SynTree/Statement.h	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -19,4 +19,5 @@
 #include <list>                    // for list
 #include <memory>                  // for allocator
+#include <vector>	                 // for vector
 
 #include "BaseSyntaxNode.h"        // for BaseSyntaxNode
@@ -392,4 +393,42 @@
 };
 
+class WaitForStmt : public Statement {
+  public:
+
+	struct Target {
+		Expression * function;
+		std::list<Expression * > arguments;
+	};
+
+	struct Clause {
+		Target       target;
+		Statement  * statement;
+		Expression * condition;
+	};
+
+	WaitForStmt( std::list<Label> labels = noLabels );
+	WaitForStmt( const WaitForStmt & );
+	virtual ~WaitForStmt();
+
+	std::vector<Clause> clauses;
+
+	struct {
+		Expression * time;
+		Statement  * statement;
+		Expression * condition;
+	} timeout;
+
+	struct {
+		Statement  * statement;
+		Expression * condition;
+	} orelse;
+
+	virtual WaitForStmt *clone() const { return new WaitForStmt( *this ); }
+	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const;
+
+};
+
 
 // represents a declaration that occurs as part of a compound statement
Index: src/SynTree/SynTree.h
===================================================================
--- src/SynTree/SynTree.h	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/SynTree/SynTree.h	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -54,4 +54,5 @@
 class CatchStmt;
 class FinallyStmt;
+class WaitForStmt;
 class NullStmt;
 class DeclStmt;
Index: src/SynTree/Visitor.cc
===================================================================
--- src/SynTree/Visitor.cc	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/SynTree/Visitor.cc	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -155,4 +155,20 @@
 }
 
+void Visitor::visit( WaitForStmt *waitforStmt ) {
+	for( auto & clause : waitforStmt->clauses ) {
+		maybeAccept( clause.target.function, *this );
+		acceptAll( clause.target.arguments, *this );
+
+		maybeAccept( clause.statement, *this );
+		maybeAccept( clause.condition, *this );
+	}
+
+	maybeAccept( waitforStmt->timeout.time, *this );
+	maybeAccept( waitforStmt->timeout.statement, *this );
+	maybeAccept( waitforStmt->timeout.condition, *this );
+	maybeAccept( waitforStmt->orelse.statement, *this );
+	maybeAccept( waitforStmt->orelse.condition, *this );
+}
+
 void Visitor::visit( __attribute__((unused)) NullStmt *nullStmt ) {
 }
Index: src/SynTree/Visitor.h
===================================================================
--- src/SynTree/Visitor.h	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/SynTree/Visitor.h	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -51,4 +51,5 @@
 	virtual void visit( CatchStmt *catchStmt );
 	virtual void visit( FinallyStmt *finallyStmt );
+	virtual void visit( WaitForStmt *waitforStmt );
 	virtual void visit( NullStmt *nullStmt );
 	virtual void visit( DeclStmt *declStmt );
Index: src/initialization.txt
===================================================================
--- src/initialization.txt	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ 	(revision )
@@ -1,71 +1,0 @@
-From the refrat (5.5) we have our specification:
-
-    \section{Initialization} An expression that is used as an
-    \nonterm{initializer} is treated as being cast to the type of the
-    object being initialized.  An expression used in an
-    \nonterm{initializer-list} is treated as being cast to the type of
-    the aggregate member that it initializes.  In either case the cast
-    must have a single unambiguous
-    interpretation\index{interpretations}.
-
-Steps:
-
-- add a member function "void Resolver::visit( SynTree::DeclStmt
-*declStmt )"; for each DeclStmt:
-
-- do what you need to do to establish correspondences between
-expressions in the initializer and pieces of the object to be
-initialized
-
-- for each initializer expression, construct a cast expression that
-casts the value of the expression to the type of the corresponding
-sub-object
-
-- invoke the resolver recursively on each cast expression; it's an invariant
-of the resolver that attempting to resolve a cast expression results either
-in a single resolved expression (corresponding to the unambiguous interpretation
-referred to above) or a thrown SemanticError.
-
-- construct a new initializer from the resolved expressions
-
-You'll undoubtedly have to play with the CodeGen stuff a bit; I
-hacked it to spit out unresolved initializers for file-scope
-declarations so that real programs would compile.  You'll want to make
-sure that resolved initializers for all declarations are being
-generated.
-
-
-------
-
-More recent email: (I am quoted; Richard is the responder)
-> As far as I'm aware, the only way that I could currently get the correct
-> results from the unification engine is by feeding it an expression that
-> looks like "?=?( ((struct Y)x.y).a, 10 )", then picking out the pieces that
-> I need (namely the correct choice for a). Does this seem like a reasonable
-> approach to solve this problem?
-
-No, unfortunately. Initialization isn't being rewritten as assignment,
-so you shouldn't allow the particular selection of assignment
-operators that happen to be in scope (and which may include
-user-defined operators) to guide the type resolution.
-
-I don't think there is any way to rewrite an initializer as a single
-expression and have the resolver just do the right thing. I see the
-algorithm as:
-
-For each alternative interpretation of the designator:
-  Construct an expression that casts the initializer to the type of
-    the designator
-  Construct an AlternativeFinder and use it to find the lowest cost
-    interpretation of the expression
-  Add this interpretation to a list of possibilities
-Go through the list of possibilities and pick the lowest cost
-
-As with many things in the resolver, it's conceptually simple but the
-implementation may be a bit of a pain. It fits in with functions like
-findSingleExpression, findIntegralExpression in Resolver.cc, although
-it will be significantly more complicated than any of the existing
-ones.
-
-
-
Index: src/libcfa/concurrency/invoke.h
===================================================================
--- src/libcfa/concurrency/invoke.h	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/libcfa/concurrency/invoke.h	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -28,4 +28,6 @@
       #define thread_local _Thread_local
 
+      typedef void (*fptr_t)();
+
       struct spinlock {
             volatile int lock;
@@ -50,4 +52,5 @@
             void append( struct __thread_queue_t *, struct thread_desc * );
             struct thread_desc * pop_head( struct __thread_queue_t * );
+            struct thread_desc * remove( struct __thread_queue_t *, struct thread_desc ** );
 
             void ?{}( struct __condition_stack_t & );
@@ -87,13 +90,23 @@
             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 __acceptable_t * acceptables;      // list of acceptable functions, null if any
+            unsigned short acceptable_count;          // number of acceptable functions
+            short accepted_index;                     // the index of the accepted function, -1 if none
+       };
 
       struct thread_desc {
+            // Core threading fields
             struct coroutine_desc cor;                // coroutine body used to store context
             struct monitor_desc mon;                  // monitor body used for mutual exclusion
+
+            // Link lists fields
             struct thread_desc * next;                // instrusive link field for threads
+
+            // Current status related to monitors
             struct monitor_desc ** current_monitors;  // currently held monitors
             unsigned short current_monitor_count;     // number of currently held monitors
-      };
+            fptr_t current_monitor_func;              // last function that acquired monitors
+     };
 
 #endif //_INVOKE_H_
Index: src/libcfa/concurrency/kernel.c
===================================================================
--- src/libcfa/concurrency/kernel.c	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/libcfa/concurrency/kernel.c	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -322,6 +322,6 @@
 void ScheduleThread( thread_desc * thrd ) {
 	// if( !thrd ) return;
-	assert( thrd );
-	assert( thrd->cor.state != Halted );
+	verify( thrd );
+	verify( thrd->cor.state != Halted );
 
 	verify( disable_preempt_count > 0 );
@@ -366,4 +366,5 @@
 
 void BlockInternal( thread_desc * thrd ) {
+	assert(thrd);
 	disable_interrupts();
 	assert( thrd->cor.state != Halted );
@@ -379,4 +380,5 @@
 
 void BlockInternal( spinlock * lock, thread_desc * thrd ) {
+	assert(thrd);
 	disable_interrupts();
 	this_processor->finish.action_code = Release_Schedule;
@@ -666,4 +668,21 @@
 }
 
+thread_desc * remove( __thread_queue_t * this, thread_desc ** it ) {
+	thread_desc * thrd = *it;
+	verify( thrd );
+
+	(*it) = thrd->next;
+
+	if( this->tail == &thrd->next ) {
+		this->tail = it;
+	}
+
+	thrd->next = NULL;
+
+	verify( (this->head == NULL) == (&this->head == this->tail) );
+	verify( *this->tail == NULL );
+	return thrd;
+}
+
 void ?{}( __condition_stack_t & this ) {
 	this.top = NULL;
Index: src/libcfa/concurrency/monitor
===================================================================
--- src/libcfa/concurrency/monitor	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/libcfa/concurrency/monitor	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -23,6 +23,12 @@
 
 static inline void ?{}(monitor_desc & this) {
+	(this.lock){};
 	this.owner = NULL;
+	(this.entry_queue){};
+	(this.signal_stack){};
 	this.recursion = 0;
+	this.acceptables = NULL;
+	this.acceptable_count = 0;
+	this.accepted_index = -1;
 }
 
@@ -32,4 +38,5 @@
 	monitor_desc ** prev_mntrs;
 	unsigned short  prev_count;
+	fptr_t          prev_func;
 };
 
@@ -38,5 +45,5 @@
 }
 
-void ?{}( monitor_guard_t & this, monitor_desc ** m, int count );
+void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() );
 void ^?{}( monitor_guard_t & this );
 
@@ -89,11 +96,14 @@
 uintptr_t front( condition * this );
 
+//-----------------------------------------------------------------------------
+// External scheduling
+
 struct __acceptable_t {
-	void (*func)(void);
+	fptr_t func;
 	unsigned short count;
-	monitor_desc * monitors[1];
+	monitor_desc ** monitors;
 };
 
-void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) );
+int __accept_internal( unsigned short count, __acceptable_t * acceptables );
 
 // Local Variables: //
Index: src/libcfa/concurrency/monitor.c
===================================================================
--- src/libcfa/concurrency/monitor.c	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/libcfa/concurrency/monitor.c	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -25,4 +25,5 @@
 static inline void set_owner( monitor_desc * this, thread_desc * owner );
 static inline thread_desc * next_thread( monitor_desc * this );
+static inline int is_accepted( thread_desc * owner, monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() );
 
 static inline void lock_all( spinlock ** locks, unsigned short count );
@@ -34,8 +35,31 @@
 static inline void restore_recursion( monitor_desc ** ctx, unsigned int * /*in */ recursions, unsigned short count );
 
+static inline void init     ( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );
+static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );
+
 static inline thread_desc * check_condition( __condition_criterion_t * );
 static inline void brand_condition( condition * );
 static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val );
 
+static inline thread_desc * search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count );
+
+//-----------------------------------------------------------------------------
+// Useful defines
+#define wait_ctx(thrd, user_info)                               /* Create the necessary information to use the signaller stack       */ \
+	__condition_node_t waiter = { thrd, count, user_info };   /* Create the node specific to this wait operation                   */ \
+	__condition_criterion_t criteria[count];                  /* Create the creteria this wait operation needs to wake up          */ \
+	init( count, monitors, &waiter, criteria );               /* Link everything together                                          */ \
+
+#define wait_ctx_primed(thrd, user_info)                        /* Create the necessary information to use the signaller stack       */ \
+	__condition_node_t waiter = { thrd, count, user_info };   /* Create the node specific to this wait operation                   */ \
+	__condition_criterion_t criteria[count];                  /* Create the creteria this wait operation needs to wake up          */ \
+	init_push( count, monitors, &waiter, criteria );          /* Link everything together and push it to the AS-Stack              */ \
+
+#define monitor_ctx( mons, cnt )              /* Define that create the necessary struct for internal/external scheduling operations */ \
+	monitor_desc ** monitors = mons;        /* Save the targeted monitors                                                          */ \
+	unsigned short count = cnt;             /* Save the count to a local variable                                                  */ \
+	unsigned int recursions[ count ];       /* Save the current recursion levels to restore them later                             */ \
+	spinlock *   locks     [ count ];       /* We need to pass-in an array of locks to BlockInternal                               */ \
+
 //-----------------------------------------------------------------------------
 // Enter/Leave routines
@@ -43,46 +67,64 @@
 
 extern "C" {
-	void __enter_monitor_desc( monitor_desc * this ) {
+	// Enter single monitor
+	static void __enter_monitor_desc( monitor_desc * this, monitor_desc ** group, int group_cnt, void (*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("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);
-
+		LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
+
+		this->accepted_index = -1;
 		if( !this->owner ) {
-			//No one has the monitor, just take it
+			// No one has the monitor, just take it
 			set_owner( this, thrd );
+
+			LIB_DEBUG_PRINT_SAFE("Kernel :  mon is free \n");
 		}
 		else if( this->owner == thrd) {
-			//We already have the monitor, just not how many times we took it
+			// We already have the monitor, just not how many times we took it
 			verify( this->recursion > 0 );
 			this->recursion += 1;
+
+			LIB_DEBUG_PRINT_SAFE("Kernel :  mon already owned \n");
+		}
+		else if( (this->accepted_index = is_accepted( thrd, this, group, group_cnt, func)) >= 0 ) {
+			// Some one was waiting for us, enter
+			set_owner( this, thrd );
+
+			LIB_DEBUG_PRINT_SAFE("Kernel :  mon accepts \n");
 		}
 		else {
-			//Some one else has the monitor, wait in line for it
+			LIB_DEBUG_PRINT_SAFE("Kernel :  blocking \n");
+
+			// Some one else has the monitor, wait in line for it
 			append( &this->entry_queue, thrd );
-			// LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd);
 			BlockInternal( &this->lock );
 
-			//BlockInternal will unlock spinlock, no need to unlock ourselves
+			LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entered  mon %p\n", thrd, this);
+
+			// BlockInternal will unlock spinlock, no need to unlock ourselves
 			return;
 		}
 
+		LIB_DEBUG_PRINT_SAFE("Kernel : %10p Entered  mon %p\n", thrd, this);
+
+		// Release the lock and leave
 		unlock( &this->lock );
 		return;
 	}
 
-	// leave pseudo code :
-	//	TODO
+	// Leave single monitor
 	void __leave_monitor_desc( monitor_desc * this ) {
+		// Lock the monitor spinlock, lock_yield to reduce contention
 		lock_yield( &this->lock DEBUG_CTX2 );
 
-		// LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i). ", this_thread, this, this->owner, this->recursion);
 		verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread, this->owner, this->recursion );
 
-		//Leaving a recursion level, decrement the counter
+		// Leaving a recursion level, decrement the counter
 		this->recursion -= 1;
 
-		//If we haven't left the last level of recursion
-		//it means we don't need to do anything
+		// If we haven't left the last level of recursion
+		// it means we don't need to do anything
 		if( this->recursion != 0) {
 			unlock( &this->lock );
@@ -90,10 +132,9 @@
 		}
 
+		// Get the next thread, will be null on low contention monitor
 		thread_desc * new_owner = next_thread( this );
 
-		//We can now let other threads in safely
+		// We can now let other threads in safely
 		unlock( &this->lock );
-
-		// LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner);
 
 		//We need to wake-up the thread
@@ -101,6 +142,11 @@
 	}
 
+	// Leave the thread monitor
+	// last routine called by a thread.
+	// Should never return
 	void __leave_thread_monitor( thread_desc * thrd ) {
 		monitor_desc * this = &thrd->mon;
+
+		// Lock the monitor now
 		lock_yield( &this->lock DEBUG_CTX2 );
 
@@ -111,26 +157,33 @@
 		verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion );
 
-		//Leaving a recursion level, decrement the counter
+		// Leaving a recursion level, decrement the counter
 		this->recursion -= 1;
 
-		//If we haven't left the last level of recursion
-		//it means we don't need to do anything
-		if( this->recursion != 0) {
-			unlock( &this->lock );
-			return;
-		}
-
+		// If we haven't left the last level of recursion
+		// it must mean there is an error
+		if( this->recursion != 0) { abortf("Thread internal monitor has unbalanced recursion"); }
+
+		// Fetch the next thread, can be null
 		thread_desc * new_owner = next_thread( this );
 
+		// Leave the thread, this will unlock the spinlock
+		// Use leave thread instead of BlockInternal which is
+		// specialized for this case and supports null new_owner
 		LeaveThread( &this->lock, new_owner );
-	}
-}
-
-static inline void enter(monitor_desc ** monitors, int count) {
+
+		// Control flow should never reach here!
+	}
+}
+
+// Enter multiple monitor
+// relies on the monitor array being sorted
+static inline void enter(monitor_desc ** monitors, int count, void (*func)() ) {
 	for(int i = 0; i < count; i++) {
-		__enter_monitor_desc( monitors[i] );
-	}
-}
-
+		__enter_monitor_desc( monitors[i], monitors, count, func );
+	}
+}
+
+// Leave multiple monitor
+// relies on the monitor array being sorted
 static inline void leave(monitor_desc ** monitors, int count) {
 	for(int i = count - 1; i >= 0; i--) {
@@ -139,24 +192,42 @@
 }
 
-void ?{}( monitor_guard_t & this, monitor_desc ** m, int count ) {
+// Ctor for monitor guard
+// Sorts monitors before entering
+void ?{}( monitor_guard_t & this, monitor_desc ** m, int count, void (*func)() ) {
+	// Store current array
 	this.m = m;
 	this.count = count;
+
+	// Sort monitors based on address -> TODO use a sort specialized for small numbers
 	qsort(this.m, count);
-	enter( this.m, this.count );
-
+
+	// Save previous thread context
 	this.prev_mntrs = this_thread->current_monitors;
 	this.prev_count = this_thread->current_monitor_count;
-
+	this.prev_func  = this_thread->current_monitor_func;
+
+	// Update thread context (needed for conditions)
 	this_thread->current_monitors      = m;
 	this_thread->current_monitor_count = count;
-}
-
+	this_thread->current_monitor_func  = func;
+
+	// Enter the monitors in order
+	enter( this.m, this.count, func );
+}
+
+
+// Dtor for monitor guard
 void ^?{}( monitor_guard_t & this ) {
+	// Leave the monitors in order
 	leave( this.m, this.count );
 
+	// Restore thread context
 	this_thread->current_monitors      = this.prev_mntrs;
 	this_thread->current_monitor_count = this.prev_count;
-}
-
+	this_thread->current_monitor_func  = this.prev_func;
+}
+
+//-----------------------------------------------------------------------------
+// Internal scheduling types
 void ?{}(__condition_node_t & this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info ) {
 	this.waiting_thread = waiting_thread;
@@ -183,35 +254,30 @@
 // Internal scheduling
 void wait( condition * this, uintptr_t user_info = 0 ) {
-	// LIB_DEBUG_PRINT_SAFE("Waiting\n");
-
 	brand_condition( this );
 
-	//Check that everything is as expected
+	// Check that everything is as expected
 	assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );
 	verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
 	verifyf( this->monitor_count < 32u, "Excessive monitor count (%i)", this->monitor_count );
 
-	unsigned short count = this->monitor_count;
-	unsigned int recursions[ count ];		//Save the current recursion levels to restore them later
-	spinlock *   locks     [ count ];		//We need to pass-in an array of locks to BlockInternal
-
-	// LIB_DEBUG_PRINT_SAFE("count %i\n", count);
-
-	__condition_node_t waiter = { (thread_desc*)this_thread, count, user_info };
-
-	__condition_criterion_t criteria[count];
-	for(int i = 0; i < count; i++) {
-		(criteria[i]){ this->monitors[i], &waiter };
-		// LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
-	}
-
-	waiter.criteria = criteria;
+	// Create storage for monitor context
+	monitor_ctx( this->monitors, this->monitor_count );
+
+	// Create the node specific to this wait operation
+	wait_ctx( this_thread, user_info );
+
+	// Append the current wait operation to the ones already queued on the condition
+	// We don't need locks for that since conditions must always be waited on inside monitor mutual exclusion
 	append( &this->blocked, &waiter );
 
-	lock_all( this->monitors, locks, count );
-	save_recursion( this->monitors, recursions, count );
-	//DON'T unlock, ask the kernel to do it
-
-	//Find the next thread(s) to run
+	// Lock all monitors (aggregates the lock them as well)
+	lock_all( monitors, locks, count );
+
+	// DON'T unlock, ask the kernel to do it
+
+	// Save monitor state
+	save_recursion( monitors, recursions, count );
+
+	// Find the next thread(s) to run
 	unsigned short thread_count = 0;
 	thread_desc * threads[ count ];
@@ -220,14 +286,9 @@
 	}
 
+	// Remove any duplicate threads
 	for( int i = 0; i < count; i++) {
-		thread_desc * new_owner = next_thread( this->monitors[i] );
+		thread_desc * new_owner = next_thread( monitors[i] );
 		thread_count = insert_unique( threads, thread_count, new_owner );
 	}
-
-	// LIB_DEBUG_PRINT_SAFE("Will unblock: ");
-	for(int i = 0; i < thread_count; i++) {
-		// LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);
-	}
-	// LIB_DEBUG_PRINT_SAFE("\n");
 
 	// Everything is ready to go to sleep
@@ -235,24 +296,19 @@
 
 
-	//WE WOKE UP
-
-
-	//We are back, restore the owners and recursions
+	// WE WOKE UP
+
+
+	// We are back, restore the owners and recursions
 	lock_all( locks, count );
-	restore_recursion( this->monitors, recursions, count );
+	restore_recursion( monitors, recursions, count );
 	unlock_all( locks, count );
 }
 
 bool signal( condition * this ) {
-	if( is_empty( this ) ) {
-		// LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
-		return false;
-	}
+	if( is_empty( this ) ) { return false; }
 
 	//Check that everything is as expected
 	verify( this->monitors );
 	verify( this->monitor_count != 0 );
-
-	unsigned short count = this->monitor_count;
 
 	//Some more checking in debug
@@ -261,16 +317,17 @@
 		if ( this->monitor_count != this_thrd->current_monitor_count ) {
 			abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->current_monitor_count );
-		} // if
+		}
 
 		for(int i = 0; i < this->monitor_count; i++) {
 			if ( this->monitors[i] != this_thrd->current_monitors[i] ) {
 				abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd->current_monitors[i] );
-			} // if
+			}
 		}
 	);
 
-	//Lock all the monitors
+	unsigned short count = this->monitor_count;
+
+	// Lock all monitors
 	lock_all( this->monitors, NULL, count );
-	// LIB_DEBUG_PRINT_SAFE("Signalling");
 
 	//Pop the head of the waiting queue
@@ -280,11 +337,8 @@
 	for(int i = 0; i < count; i++) {
 		__condition_criterion_t * crit = &node->criteria[i];
-		// LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
 		assert( !crit->ready );
 		push( &crit->target->signal_stack, crit );
 	}
 
-	// LIB_DEBUG_PRINT_SAFE("\n");
-
 	//Release
 	unlock_all( this->monitors, count );
@@ -294,8 +348,5 @@
 
 bool signal_block( condition * this ) {
-	if( !this->blocked.head ) {
-		LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
-		return false;
-	}
+	if( !this->blocked.head ) { return false; }
 
 	//Check that everything is as expected
@@ -303,32 +354,21 @@
 	verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
 
-	unsigned short count = this->monitor_count;
-	unsigned int recursions[ count ];		//Save the current recursion levels to restore them later
-	spinlock *   locks     [ count ];		//We need to pass-in an array of locks to BlockInternal
-
-	lock_all( this->monitors, locks, count );
-
-	//create creteria
-	__condition_node_t waiter = { (thread_desc*)this_thread, count, 0 };
-
-	__condition_criterion_t criteria[count];
-	for(int i = 0; i < count; i++) {
-		(criteria[i]){ this->monitors[i], &waiter };
-		// LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
-		push( &criteria[i].target->signal_stack, &criteria[i] );
-	}
-
-	waiter.criteria = criteria;
+	// Create storage for monitor context
+	monitor_ctx( this->monitors, this->monitor_count );
+
+	// Lock all monitors (aggregates the locks them as well)
+	lock_all( monitors, locks, count );
+
+	// Create the node specific to this wait operation
+	wait_ctx_primed( this_thread, 0 )
 
 	//save contexts
-	save_recursion( this->monitors, recursions, count );
+	save_recursion( monitors, recursions, count );
 
 	//Find the thread to run
 	thread_desc * signallee = pop_head( &this->blocked )->waiting_thread;
 	for(int i = 0; i < count; i++) {
-		set_owner( this->monitors[i], signallee );
-	}
-
-	LIB_DEBUG_PRINT_SAFE( "Waiting on signal block\n" );
+		set_owner( monitors[i], signallee );
+	}
 
 	//Everything is ready to go to sleep
@@ -336,11 +376,10 @@
 
 
-
-
-	LIB_DEBUG_PRINT_SAFE( "Back from signal block\n" );
+	// WE WOKE UP
+
 
 	//We are back, restore the owners and recursions
 	lock_all( locks, count );
-	restore_recursion( this->monitors, recursions, count );
+	restore_recursion( monitors, recursions, count );
 	unlock_all( locks, count );
 
@@ -348,4 +387,5 @@
 }
 
+// Access the user_info of the thread waiting at the front of the queue
 uintptr_t front( condition * this ) {
 	verifyf( !is_empty(this),
@@ -358,28 +398,58 @@
 //-----------------------------------------------------------------------------
 // Internal scheduling
-void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) {
-	// thread_desc * this = this_thread;
-
-	// unsigned short count = this->current_monitor_count;
-	// unsigned int recursions[ count ];		//Save the current recursion levels to restore them later
-	// spinlock *   locks     [ count ];		//We need to pass-in an array of locks to BlockInternal
-
-	// lock_all( this->current_monitors, locks, count );
-
-
-
-
-
-	// // // Everything is ready to go to sleep
-	// // BlockInternal( locks, count, threads, thread_count );
-
-
-	// //WE WOKE UP
-
-
-	// //We are back, restore the owners and recursions
-	// lock_all( locks, count );
-	// restore_recursion( this->monitors, recursions, count );
-	// unlock_all( locks, count );
+int __accept_internal( unsigned short acc_count, __acceptable_t * acceptables ) {
+	thread_desc * thrd = this_thread;
+
+	// Create storage for monitor context
+	monitor_ctx( acceptables->monitors, acceptables->count );
+
+	// Lock all monitors (aggregates the lock them as well)
+	lock_all( monitors, locks, count );
+
+	// Create the node specific to this wait operation
+	wait_ctx_primed( thrd, 0 );
+
+	// Check if the entry queue
+	thread_desc * next = search_entry_queue( acceptables, acc_count, monitors, count );
+
+	LIB_DEBUG_PRINT_SAFE("Owner(s) :");
+	for(int i = 0; i < count; i++) {
+		LIB_DEBUG_PRINT_SAFE(" %p", monitors[i]->owner );
+	}
+	LIB_DEBUG_PRINT_SAFE("\n");
+
+	LIB_DEBUG_PRINT_SAFE("Passing mon to %p\n", next);
+
+	if( !next ) {
+		// Update acceptables on the current monitors
+		for(int i = 0; i < count; i++) {
+			monitors[i]->acceptables = acceptables;
+			monitors[i]->acceptable_count = acc_count;
+		}
+	}
+	else {
+		for(int i = 0; i < count; i++) {
+			set_owner( monitors[i], next );
+		}
+	}
+
+
+	save_recursion( monitors, recursions, count );
+
+
+	// Everything is ready to go to sleep
+	BlockInternal( locks, count, &next, next ? 1 : 0 );
+
+
+	//WE WOKE UP
+
+
+	//We are back, restore the owners and recursions
+	lock_all( locks, count );
+	restore_recursion( monitors, recursions, count );
+	int acc_idx = monitors[0]->accepted_index;
+	unlock_all( locks, count );
+
+	return acc_idx;
 }
 
@@ -415,4 +485,57 @@
 }
 
+static inline int is_accepted( thread_desc * owner, monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() ) {
+	__acceptable_t* accs = this->acceptables; // Optim
+	int acc_cnt = this->acceptable_count;
+
+	// Check if there are any acceptable functions
+	if( !accs ) return -1;
+
+	// If this isn't the first monitor to test this, there is no reason to repeat the test.
+	if( this != group[0] ) return group[0]->accepted_index;
+
+	// For all acceptable functions check if this is the current function.
+	OUT_LOOP:
+	for( int i = 0; i < acc_cnt; i++ ) {
+		__acceptable_t * acc = &accs[i];
+
+		// if function matches, check the monitors
+		if( acc->func == func ) {
+
+			// If the group count is different then it can't be a match
+			if( acc->count != group_cnt ) return -1;
+
+			// Check that all the monitors match
+			for( int j = 0; j < group_cnt; j++ ) {
+				// If not a match, check next function
+				if( acc->monitors[j] != group[j] ) continue OUT_LOOP;
+			}
+
+			// It's a complete match, accept the call
+			return i;
+		}
+	}
+
+	// No function matched
+	return -1;
+}
+
+static inline void init( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) {
+	for(int i = 0; i < count; i++) {
+		(criteria[i]){ monitors[i], waiter };
+	}
+
+	waiter->criteria = criteria;
+}
+
+static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) {
+	for(int i = 0; i < count; i++) {
+		(criteria[i]){ monitors[i], waiter };
+		push( &criteria[i].target->signal_stack, &criteria[i] );
+	}
+
+	waiter->criteria = criteria;
+}
+
 static inline void lock_all( spinlock ** locks, unsigned short count ) {
 	for( int i = 0; i < count; i++ ) {
@@ -505,4 +628,37 @@
 }
 
+
+static inline bool match( __acceptable_t * acc, thread_desc * thrd ) {
+	verify( thrd );
+	verify( acc );
+	if( acc->func != thrd->current_monitor_func ) return false;
+
+	return true;
+}
+
+static inline thread_desc * search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count ) {
+
+	__thread_queue_t * entry_queue = &monitors[0]->entry_queue;
+
+	// For each thread in the entry-queue
+	for(	thread_desc ** thrd_it = &entry_queue->head;
+		*thrd_it;
+		thrd_it = &(*thrd_it)->next)
+	{
+		// For each acceptable check if it matches
+		__acceptable_t * acc_end = acceptables + acc_count;
+		for( __acceptable_t * acc_it = acceptables; acc_it != acc_end; acc_it++ ) {
+			// Check if we have a match
+			if( match( acc_it, *thrd_it ) ) {
+
+				// If we have a match return it
+				// after removeing it from the entry queue
+				return remove( entry_queue, thrd_it );
+			}
+		}
+	}
+
+	return NULL;
+}
 void ?{}( __condition_blocked_queue_t & this ) {
 	this.head = NULL;
Index: src/libcfa/concurrency/preemption.c
===================================================================
--- src/libcfa/concurrency/preemption.c	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/libcfa/concurrency/preemption.c	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -332,5 +332,5 @@
 		assertf(sig == SIGALRM, "Kernel Internal Error, sigwait: Unexpected signal %d (%d : %d)\n", sig, info.si_code, info.si_value.sival_int);
 
-		LIB_DEBUG_PRINT_SAFE("Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int );
+		// LIB_DEBUG_PRINT_SAFE("Kernel : Caught alarm from %d with %d\n", info.si_code, info.si_value.sival_int );
 		// Switch on the code (a.k.a. the sender) to
 		switch( info.si_code )
@@ -340,5 +340,5 @@
 		case SI_TIMER:
 		case SI_KERNEL:
-			LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n");
+			// LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n");
 			lock( &event_kernel->lock DEBUG_CTX2 );
 			tick_preemption();
Index: src/tests/.expect/64/gmp.txt
===================================================================
--- src/tests/.expect/64/gmp.txt	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
+++ src/tests/.expect/64/gmp.txt	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -0,0 +1,276 @@
+constructors
+50000000000000000000 3 50000000000000000003
+x:50000000000000000000 y:3 z:50000000000000000003
+conversions
+y:97
+y:12345678901234567890123456789
+y:3
+y:-3
+y:4
+y:3
+y:3 b:3 si:3
+comparison
+1
+0
+0
+1
+0
+1
+arithmetic
+z:100000000000000000006
+z:50000000000000000000
+z:-3
+z:-450000000000000000000
+z:150000000000000000000
+z:150000000000000000000
+z:16666666666666666666
+16666666666666666666, 2 16666666666666666666, 2
+x:16666666666666666666 y:2
+
+12345678901234567890123456789 12345678901234567890123456789 12345678901234567890123456789
+
+Fibonacci Numbers
+0 0
+1 1
+2 1
+3 2
+4 3
+5 5
+6 8
+7 13
+8 21
+9 34
+10 55
+11 89
+12 144
+13 233
+14 377
+15 610
+16 987
+17 1597
+18 2584
+19 4181
+20 6765
+21 10946
+22 17711
+23 28657
+24 46368
+25 75025
+26 121393
+27 196418
+28 317811
+29 514229
+30 832040
+31 1346269
+32 2178309
+33 3524578
+34 5702887
+35 9227465
+36 14930352
+37 24157817
+38 39088169
+39 63245986
+40 102334155
+41 165580141
+42 267914296
+43 433494437
+44 701408733
+45 1134903170
+46 1836311903
+47 2971215073
+48 4807526976
+49 7778742049
+50 12586269025
+51 20365011074
+52 32951280099
+53 53316291173
+54 86267571272
+55 139583862445
+56 225851433717
+57 365435296162
+58 591286729879
+59 956722026041
+60 1548008755920
+61 2504730781961
+62 4052739537881
+63 6557470319842
+64 10610209857723
+65 17167680177565
+66 27777890035288
+67 44945570212853
+68 72723460248141
+69 117669030460994
+70 190392490709135
+71 308061521170129
+72 498454011879264
+73 806515533049393
+74 1304969544928657
+75 2111485077978050
+76 3416454622906707
+77 5527939700884757
+78 8944394323791464
+79 14472334024676221
+80 23416728348467685
+81 37889062373143906
+82 61305790721611591
+83 99194853094755497
+84 160500643816367088
+85 259695496911122585
+86 420196140727489673
+87 679891637638612258
+88 1100087778366101931
+89 1779979416004714189
+90 2880067194370816120
+91 4660046610375530309
+92 7540113804746346429
+93 12200160415121876738
+94 19740274219868223167
+95 31940434634990099905
+96 51680708854858323072
+97 83621143489848422977
+98 135301852344706746049
+99 218922995834555169026
+100 354224848179261915075
+101 573147844013817084101
+102 927372692193078999176
+103 1500520536206896083277
+104 2427893228399975082453
+105 3928413764606871165730
+106 6356306993006846248183
+107 10284720757613717413913
+108 16641027750620563662096
+109 26925748508234281076009
+110 43566776258854844738105
+111 70492524767089125814114
+112 114059301025943970552219
+113 184551825793033096366333
+114 298611126818977066918552
+115 483162952612010163284885
+116 781774079430987230203437
+117 1264937032042997393488322
+118 2046711111473984623691759
+119 3311648143516982017180081
+120 5358359254990966640871840
+121 8670007398507948658051921
+122 14028366653498915298923761
+123 22698374052006863956975682
+124 36726740705505779255899443
+125 59425114757512643212875125
+126 96151855463018422468774568
+127 155576970220531065681649693
+128 251728825683549488150424261
+129 407305795904080553832073954
+130 659034621587630041982498215
+131 1066340417491710595814572169
+132 1725375039079340637797070384
+133 2791715456571051233611642553
+134 4517090495650391871408712937
+135 7308805952221443105020355490
+136 11825896447871834976429068427
+137 19134702400093278081449423917
+138 30960598847965113057878492344
+139 50095301248058391139327916261
+140 81055900096023504197206408605
+141 131151201344081895336534324866
+142 212207101440105399533740733471
+143 343358302784187294870275058337
+144 555565404224292694404015791808
+145 898923707008479989274290850145
+146 1454489111232772683678306641953
+147 2353412818241252672952597492098
+148 3807901929474025356630904134051
+149 6161314747715278029583501626149
+150 9969216677189303386214405760200
+151 16130531424904581415797907386349
+152 26099748102093884802012313146549
+153 42230279526998466217810220532898
+154 68330027629092351019822533679447
+155 110560307156090817237632754212345
+156 178890334785183168257455287891792
+157 289450641941273985495088042104137
+158 468340976726457153752543329995929
+159 757791618667731139247631372100066
+160 1226132595394188293000174702095995
+161 1983924214061919432247806074196061
+162 3210056809456107725247980776292056
+163 5193981023518027157495786850488117
+164 8404037832974134882743767626780173
+165 13598018856492162040239554477268290
+166 22002056689466296922983322104048463
+167 35600075545958458963222876581316753
+168 57602132235424755886206198685365216
+169 93202207781383214849429075266681969
+170 150804340016807970735635273952047185
+171 244006547798191185585064349218729154
+172 394810887814999156320699623170776339
+173 638817435613190341905763972389505493
+174 1033628323428189498226463595560281832
+175 1672445759041379840132227567949787325
+176 2706074082469569338358691163510069157
+177 4378519841510949178490918731459856482
+178 7084593923980518516849609894969925639
+179 11463113765491467695340528626429782121
+180 18547707689471986212190138521399707760
+181 30010821454963453907530667147829489881
+182 48558529144435440119720805669229197641
+183 78569350599398894027251472817058687522
+184 127127879743834334146972278486287885163
+185 205697230343233228174223751303346572685
+186 332825110087067562321196029789634457848
+187 538522340430300790495419781092981030533
+188 871347450517368352816615810882615488381
+189 1409869790947669143312035591975596518914
+190 2281217241465037496128651402858212007295
+191 3691087032412706639440686994833808526209
+192 5972304273877744135569338397692020533504
+193 9663391306290450775010025392525829059713
+194 15635695580168194910579363790217849593217
+195 25299086886458645685589389182743678652930
+196 40934782466626840596168752972961528246147
+197 66233869353085486281758142155705206899077
+198 107168651819712326877926895128666735145224
+199 173402521172797813159685037284371942044301
+200 280571172992510140037611932413038677189525
+
+Factorial Numbers
+0 1
+1 1
+2 2
+3 6
+4 24
+5 120
+6 720
+7 5040
+8 40320
+9 362880
+10 3628800
+11 39916800
+12 479001600
+13 6227020800
+14 87178291200
+15 1307674368000
+16 20922789888000
+17 355687428096000
+18 6402373705728000
+19 121645100408832000
+20 2432902008176640000
+21 51090942171709440000
+22 1124000727777607680000
+23 25852016738884976640000
+24 620448401733239439360000
+25 15511210043330985984000000
+26 403291461126605635584000000
+27 10888869450418352160768000000
+28 304888344611713860501504000000
+29 8841761993739701954543616000000
+30 265252859812191058636308480000000
+31 8222838654177922817725562880000000
+32 263130836933693530167218012160000000
+33 8683317618811886495518194401280000000
+34 295232799039604140847618609643520000000
+35 10333147966386144929666651337523200000000
+36 371993326789901217467999448150835200000000
+37 13763753091226345046315979581580902400000000
+38 523022617466601111760007224100074291200000000
+39 20397882081197443358640281739902897356800000000
+40 815915283247897734345611269596115894272000000000
Index: src/tests/.expect/gmp.txt
===================================================================
--- src/tests/.expect/gmp.txt	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ 	(revision )
@@ -1,276 +1,0 @@
-constructors
-50000000000000000000 3 50000000000000000003
-x:50000000000000000000 y:3 z:50000000000000000003
-conversions
-y:97
-y:12345678901234567890123456789
-y:3
-y:-3
-y:4
-y:3
-y:3 b:3 si:3
-comparison
-1
-0
-0
-1
-0
-1
-arithmetic
-z:100000000000000000006
-z:50000000000000000000
-z:-3
-z:-450000000000000000000
-z:150000000000000000000
-z:150000000000000000000
-z:16666666666666666666
-16666666666666666666, 2 16666666666666666666, 2
-x:16666666666666666666 y:2
-
-12345678901234567890123456789 12345678901234567890123456789 12345678901234567890123456789
-
-Fibonacci Numbers
-0 0
-1 1
-2 1
-3 2
-4 3
-5 5
-6 8
-7 13
-8 21
-9 34
-10 55
-11 89
-12 144
-13 233
-14 377
-15 610
-16 987
-17 1597
-18 2584
-19 4181
-20 6765
-21 10946
-22 17711
-23 28657
-24 46368
-25 75025
-26 121393
-27 196418
-28 317811
-29 514229
-30 832040
-31 1346269
-32 2178309
-33 3524578
-34 5702887
-35 9227465
-36 14930352
-37 24157817
-38 39088169
-39 63245986
-40 102334155
-41 165580141
-42 267914296
-43 433494437
-44 701408733
-45 1134903170
-46 1836311903
-47 2971215073
-48 4807526976
-49 7778742049
-50 12586269025
-51 20365011074
-52 32951280099
-53 53316291173
-54 86267571272
-55 139583862445
-56 225851433717
-57 365435296162
-58 591286729879
-59 956722026041
-60 1548008755920
-61 2504730781961
-62 4052739537881
-63 6557470319842
-64 10610209857723
-65 17167680177565
-66 27777890035288
-67 44945570212853
-68 72723460248141
-69 117669030460994
-70 190392490709135
-71 308061521170129
-72 498454011879264
-73 806515533049393
-74 1304969544928657
-75 2111485077978050
-76 3416454622906707
-77 5527939700884757
-78 8944394323791464
-79 14472334024676221
-80 23416728348467685
-81 37889062373143906
-82 61305790721611591
-83 99194853094755497
-84 160500643816367088
-85 259695496911122585
-86 420196140727489673
-87 679891637638612258
-88 1100087778366101931
-89 1779979416004714189
-90 2880067194370816120
-91 4660046610375530309
-92 7540113804746346429
-93 12200160415121876738
-94 19740274219868223167
-95 31940434634990099905
-96 51680708854858323072
-97 83621143489848422977
-98 135301852344706746049
-99 218922995834555169026
-100 354224848179261915075
-101 573147844013817084101
-102 927372692193078999176
-103 1500520536206896083277
-104 2427893228399975082453
-105 3928413764606871165730
-106 6356306993006846248183
-107 10284720757613717413913
-108 16641027750620563662096
-109 26925748508234281076009
-110 43566776258854844738105
-111 70492524767089125814114
-112 114059301025943970552219
-113 184551825793033096366333
-114 298611126818977066918552
-115 483162952612010163284885
-116 781774079430987230203437
-117 1264937032042997393488322
-118 2046711111473984623691759
-119 3311648143516982017180081
-120 5358359254990966640871840
-121 8670007398507948658051921
-122 14028366653498915298923761
-123 22698374052006863956975682
-124 36726740705505779255899443
-125 59425114757512643212875125
-126 96151855463018422468774568
-127 155576970220531065681649693
-128 251728825683549488150424261
-129 407305795904080553832073954
-130 659034621587630041982498215
-131 1066340417491710595814572169
-132 1725375039079340637797070384
-133 2791715456571051233611642553
-134 4517090495650391871408712937
-135 7308805952221443105020355490
-136 11825896447871834976429068427
-137 19134702400093278081449423917
-138 30960598847965113057878492344
-139 50095301248058391139327916261
-140 81055900096023504197206408605
-141 131151201344081895336534324866
-142 212207101440105399533740733471
-143 343358302784187294870275058337
-144 555565404224292694404015791808
-145 898923707008479989274290850145
-146 1454489111232772683678306641953
-147 2353412818241252672952597492098
-148 3807901929474025356630904134051
-149 6161314747715278029583501626149
-150 9969216677189303386214405760200
-151 16130531424904581415797907386349
-152 26099748102093884802012313146549
-153 42230279526998466217810220532898
-154 68330027629092351019822533679447
-155 110560307156090817237632754212345
-156 178890334785183168257455287891792
-157 289450641941273985495088042104137
-158 468340976726457153752543329995929
-159 757791618667731139247631372100066
-160 1226132595394188293000174702095995
-161 1983924214061919432247806074196061
-162 3210056809456107725247980776292056
-163 5193981023518027157495786850488117
-164 8404037832974134882743767626780173
-165 13598018856492162040239554477268290
-166 22002056689466296922983322104048463
-167 35600075545958458963222876581316753
-168 57602132235424755886206198685365216
-169 93202207781383214849429075266681969
-170 150804340016807970735635273952047185
-171 244006547798191185585064349218729154
-172 394810887814999156320699623170776339
-173 638817435613190341905763972389505493
-174 1033628323428189498226463595560281832
-175 1672445759041379840132227567949787325
-176 2706074082469569338358691163510069157
-177 4378519841510949178490918731459856482
-178 7084593923980518516849609894969925639
-179 11463113765491467695340528626429782121
-180 18547707689471986212190138521399707760
-181 30010821454963453907530667147829489881
-182 48558529144435440119720805669229197641
-183 78569350599398894027251472817058687522
-184 127127879743834334146972278486287885163
-185 205697230343233228174223751303346572685
-186 332825110087067562321196029789634457848
-187 538522340430300790495419781092981030533
-188 871347450517368352816615810882615488381
-189 1409869790947669143312035591975596518914
-190 2281217241465037496128651402858212007295
-191 3691087032412706639440686994833808526209
-192 5972304273877744135569338397692020533504
-193 9663391306290450775010025392525829059713
-194 15635695580168194910579363790217849593217
-195 25299086886458645685589389182743678652930
-196 40934782466626840596168752972961528246147
-197 66233869353085486281758142155705206899077
-198 107168651819712326877926895128666735145224
-199 173402521172797813159685037284371942044301
-200 280571172992510140037611932413038677189525
-
-Factorial Numbers
-0 1
-1 1
-2 2
-3 6
-4 24
-5 120
-6 720
-7 5040
-8 40320
-9 362880
-10 3628800
-11 39916800
-12 479001600
-13 6227020800
-14 87178291200
-15 1307674368000
-16 20922789888000
-17 355687428096000
-18 6402373705728000
-19 121645100408832000
-20 2432902008176640000
-21 51090942171709440000
-22 1124000727777607680000
-23 25852016738884976640000
-24 620448401733239439360000
-25 15511210043330985984000000
-26 403291461126605635584000000
-27 10888869450418352160768000000
-28 304888344611713860501504000000
-29 8841761993739701954543616000000
-30 265252859812191058636308480000000
-31 8222838654177922817725562880000000
-32 263130836933693530167218012160000000
-33 8683317618811886495518194401280000000
-34 295232799039604140847618609643520000000
-35 10333147966386144929666651337523200000000
-36 371993326789901217467999448150835200000000
-37 13763753091226345046315979581580902400000000
-38 523022617466601111760007224100074291200000000
-39 20397882081197443358640281739902897356800000000
-40 815915283247897734345611269596115894272000000000
Index: src/tests/.expect/ifcond.txt
===================================================================
--- src/tests/.expect/ifcond.txt	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
+++ src/tests/.expect/ifcond.txt	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -0,0 +1,3 @@
+x != 0 correct
+x != 0 && y == 0 incorrect
+x == y correct
Index: src/tests/gmp.c
===================================================================
--- src/tests/gmp.c	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/tests/gmp.c	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -10,7 +10,9 @@
 // Created On       : Tue Apr 19 08:55:51 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug 24 09:33:26 2017
-// Update Count     : 543
+// Last Modified On : Fri Aug 25 12:50:01 2017
+// Update Count     : 544
 // 
+
+// NOTE: UBUNTU DOES NOT SUPPORT GMP MULTILIB, SO ONLY 64-BIT GMP IS TESTED.
 
 #include <gmp>
Index: src/tests/ifcond.c
===================================================================
--- src/tests/ifcond.c	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
+++ src/tests/ifcond.c	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -0,0 +1,46 @@
+//                               -*- Mode: C -*- 
+// 
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+// 
+// ifcond.c -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Sat Aug 26 10:13:11 2017
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Sat Aug 26 11:13:00 2017
+// Update Count     : 11
+// 
+
+#include<fstream>
+
+int f( int r ) { return r; }
+
+int main( void ) {
+	int x = 4, y = 3;
+
+	if ( int x = 1 ) {
+		sout | "x != 0 correct" | endl;
+	} else {
+		sout | "x == 0 incorrect" | endl;
+	} // if
+
+	if ( int x = 4, y = 0 ) {							// FIXME && distribution
+		sout | "x != 0 && y != 0 correct" | endl;
+    } else {
+		sout | "x != 0 && y == 0 incorrect" | endl;
+	} // if
+
+	if ( int x = 5, y = f( x ); x == y ) {
+		sout | "x == y correct" | endl;
+	} else {
+		sout | "x != y incorrect" | endl;
+	} // if
+} // main
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa ifcond.c" //
+// End: //
Index: src/tests/preempt_longrun/stack.c
===================================================================
--- src/tests/preempt_longrun/stack.c	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/tests/preempt_longrun/stack.c	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -15,8 +15,8 @@
 
 void main(worker_t * this) {
-	volatile long p = 5_021_609ul;
-	volatile long a = 326_417ul;
-	volatile long n = 1l;
-	for (volatile long i = 0; i < p; i++) {
+	volatile long long p = 5_021_609ul;
+	volatile long long a = 326_417ul;
+	volatile long long n = 1l;
+	for (volatile long long i = 0; i < p; i++) {
 		n *= a;
 		n %= p;
Index: src/tests/sched-ext.c
===================================================================
--- src/tests/sched-ext.c	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
+++ src/tests/sched-ext.c	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -0,0 +1,89 @@
+#include <fstream>
+#include <kernel>
+#include <monitor>
+#include <stdlib>
+#include <thread>
+
+#include <time.h>
+
+static const unsigned long N = 500ul;
+
+#ifndef PREEMPTION_RATE
+#define PREEMPTION_RATE 10_000ul
+#endif
+
+unsigned int default_preemption() {
+	return PREEMPTION_RATE;
+}
+
+monitor global_t {};
+
+global_t globalA;
+
+thread Acceptor {};
+thread Acceptee {};
+
+volatile bool done;
+
+unsigned rand10() {
+	return (unsigned)rand48() % 10;
+}
+
+//----------------------------------------------------------------------------------------------------
+// Acceptor
+void do_notify( global_t * mutex a );
+
+void do_wait( global_t * mutex a ) {
+	sout | "Waiting to accept" | endl;
+	yield( rand10() );
+
+	sout | "Accepting" | endl;
+
+	__acceptable_t acceptable;
+	acceptable.func          = (fptr_t)do_notify;
+	acceptable.count         = 1;
+	acceptable.monitors      = &a;
+
+	__accept_internal( 1, &acceptable );
+
+	sout | "Accepted" | endl;
+	yield( rand10() );
+}
+
+void main( Acceptor* this ) {
+	for( int i = 0; i < N; i++ ) {
+		do_wait( &globalA );
+		sout | i | endl;
+	}
+
+	done = true;
+}
+
+//----------------------------------------------------------------------------------------------------
+// Acceptee
+void do_notify( global_t * mutex a ) {
+
+}
+
+void main( Acceptee* this ) {
+	while( !done ) {
+		yield( rand10() );
+		do_notify( &globalA );
+		yield( rand10() );
+	}
+}
+
+//----------------------------------------------------------------------------------------------------
+// Main
+int main(int argc, char* argv[]) {
+	done = false;
+	rand48seed( time( NULL ) );
+	printf("%p\n", &globalA);
+	sout | "Starting" | endl;
+	{
+		Acceptor r;
+		Acceptee e[13];
+
+	}
+	sout | "Done" | endl;
+}
Index: src/tests/sched-int-disjoint.c
===================================================================
--- src/tests/sched-int-disjoint.c	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/tests/sched-int-disjoint.c	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -3,4 +3,6 @@
 #include <monitor>
 #include <thread>
+
+#include <time.h>
 
 static const unsigned long N = 10_000ul;
@@ -107,4 +109,5 @@
 // Main loop
 int main(int argc, char* argv[]) {
+	rand48seed( time( NULL ) );
 	all_done = false;
 	processor p;
Index: src/tests/sched-int-wait.c
===================================================================
--- src/tests/sched-int-wait.c	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/tests/sched-int-wait.c	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -5,5 +5,7 @@
 #include <thread>
 
-static const unsigned long N = 10_000ul;
+#include <time.h>
+
+static const unsigned long N = 2_500ul;
 
 #ifndef PREEMPTION_RATE
@@ -119,4 +121,5 @@
 // Main
 int main(int argc, char* argv[]) {
+	rand48seed( time( NULL ) );
 	waiter_left = 4;
 	processor p[2];
Index: src/tests/switch.c
===================================================================
--- src/tests/switch.c	(revision 0c6596fab97091b4f0cf23a9d6e3d78a29ab00f3)
+++ src/tests/switch.c	(revision 7ee1e2f680889bd1007bad91d7b36d00880e948d)
@@ -10,11 +10,11 @@
 // Created On       : Tue Jul 12 06:50:22 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Aug  4 11:44:29 2016
-// Update Count     : 31
+// Last Modified On : Sat Aug 26 10:14:21 2017
+// Update Count     : 33
 // 
 
 int f( int i ) { return i; }
 
-int main() {
+int main( void ) {
 	int i = 0;
 	switch ( i ) case 3 : i = 1;
@@ -100,5 +100,5 @@
 		j = 5;
 	} // choose
-}
+} // main
 
 // Local Variables: //
