Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/CodeGen/CodeGenerator.cc	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -885,4 +885,6 @@
 
 	void CodeGenerator::postvisit( CaseStmt * caseStmt ) {
+		updateLocation( caseStmt );
+		output << indent;
 		if ( caseStmt->isDefault()) {
 			output << "default";
@@ -1026,4 +1028,13 @@
 } // namespace CodeGen
 
+std::ostream & operator<<( std::ostream & out, const BaseSyntaxNode * node ) {
+	if ( node ) {
+		node->print( out );
+	} else {
+		out << "nullptr";
+	}
+	return out;
+}
+
 // Local Variables: //
 // tab-width: 4 //
Index: src/Concurrency/Waitfor.cc
===================================================================
--- src/Concurrency/Waitfor.cc	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/Concurrency/Waitfor.cc	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -27,5 +27,5 @@
 #include "InitTweak/InitTweak.h"   // for getPointerBase
 #include "Parser/LinkageSpec.h"    // for Cforall
-#include "SymTab/AddVisit.h"       // for acceptAndAdd
+#include "ResolvExpr/Resolver.h"   // for findVoidExpression
 #include "SynTree/Constant.h"      // for Constant
 #include "SynTree/Declaration.h"   // for StructDecl, FunctionDecl, ObjectDecl
@@ -112,5 +112,5 @@
 	//=============================================================================================
 
-	class GenerateWaitForPass final : public WithStmtsToAdd {
+	class GenerateWaitForPass final : public WithIndexer {
 	  public:
 
@@ -129,6 +129,6 @@
 		void         init( ObjectDecl * acceptables, int index, WaitForStmt::Clause & clause, CompoundStmt * stmt );
 		Expression * init_timeout( Expression *& time, Expression *& time_cond, bool has_else, Expression *& else_cond, CompoundStmt * stmt );
-		Expression * call();
-		void choose();
+		Expression * call(size_t count, ObjectDecl * acceptables, Expression * timeout, CompoundStmt * stmt);
+		void         choose( WaitForStmt * waitfor, Expression  * result, CompoundStmt * stmt );
 
 		static void implement( std::list< Declaration * > & translationUnit ) {
@@ -142,8 +142,4 @@
 		StructDecl          * decl_acceptable = nullptr;
 		StructDecl          * decl_monitor    = nullptr;
-		DeclarationWithType * decl_m_func     = nullptr;
-		DeclarationWithType * decl_m_count    = nullptr;
-		DeclarationWithType * decl_m_monitors = nullptr;
-		DeclarationWithType * decl_m_isdtor   = nullptr;
 
 		static std::unique_ptr< Type > generic_func;
@@ -152,4 +148,5 @@
 		UniqueName namer_acc = "__acceptables_"s;
 		UniqueName namer_tim = "__timeout_"s;
+		UniqueName namer_ret = "__return_"s;
 	};
 
@@ -167,5 +164,5 @@
 	namespace {
 		Expression * makeOpIndex( DeclarationWithType * array, unsigned long index ) {
-			return new ApplicationExpr(
+			return new UntypedExpr(
 				new NameExpr( "?[?]" ),
 				{
@@ -177,5 +174,5 @@
 
 		Expression * makeOpAssign( Expression * lhs, Expression * rhs ) {
-			return new ApplicationExpr(
+			return new UntypedExpr(
 					new NameExpr( "?=?" ),
 					{ lhs, rhs }
@@ -183,22 +180,21 @@
 		}
 
-		Expression * makeOpMember( Expression * sue, DeclarationWithType * mem ) {
-			return new MemberExpr( mem, sue );
-		}
-
-		Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, DeclarationWithType * member, Expression * value ) {
-			return new ExprStmt(
-				noLabels,
-				makeOpAssign(
-					makeOpMember(
-						makeOpIndex(
-							object,
-							index
-						),
-						member
+		Expression * makeOpMember( Expression * sue, const std::string & mem ) {
+			return new UntypedMemberExpr( new NameExpr( mem ), sue );
+		}
+
+		Statement * makeAccStatement( DeclarationWithType * object, unsigned long index, const std::string & member, Expression * value, const SymTab::Indexer & indexer ) {
+			std::unique_ptr< Expression > expr( makeOpAssign(
+				makeOpMember(
+					makeOpIndex(
+						object,
+						index
 					),
-					value
-				)
-			);
+					member
+				),
+				value
+			) );
+
+			return new ExprStmt( noLabels, ResolvExpr::findVoidExpression( expr.get(), indexer ) );
 		}
 
@@ -208,4 +204,19 @@
 			return new ConstantExpr( Constant::from_bool( ifnull ) );
 		}
+
+		VariableExpr * extractVariable( Expression * func ) {
+			if( VariableExpr * var = dynamic_cast< VariableExpr * >( func ) ) {
+				return var;
+			}
+
+			CastExpr * cast = strict_dynamic_cast< CastExpr * >( func );
+			return strict_dynamic_cast< VariableExpr * >( cast->arg );
+		}
+
+		Expression * detectIsDtor( Expression * func ) {
+			VariableExpr * typed_func = extractVariable( func );
+			bool is_dtor = InitTweak::isDestructor( typed_func->var );
+			return new ConstantExpr( Constant::from_bool( is_dtor ) );
+		}
 	};
 
@@ -216,5 +227,5 @@
 
 	void GenerateWaitForPass::premutate( FunctionDecl * decl) {
-		if( decl->name != "__accept_internal" ) return;
+		if( decl->name != "__waitfor_internal" ) return;
 
 		decl_waitfor = decl;
@@ -227,11 +238,4 @@
 			assert( !decl_acceptable );
 			decl_acceptable = decl;
-			for( Declaration * field : decl_acceptable->members ) {
-				     if( field->name == "func"    ) decl_m_func     = strict_dynamic_cast< DeclarationWithType * >( field );
-				else if( field->name == "count"   ) decl_m_count    = strict_dynamic_cast< DeclarationWithType * >( field );
-				else if( field->name == "monitor" ) decl_m_monitors = strict_dynamic_cast< DeclarationWithType * >( field );
-				else if( field->name == "is_dtor" ) decl_m_isdtor   = strict_dynamic_cast< DeclarationWithType * >( field );
-			}
-
 		}
 		else if( decl->name == "monitor_desc" ) {
@@ -242,6 +246,4 @@
 
 	Statement * GenerateWaitForPass::postmutate( WaitForStmt * waitfor ) {
-		return waitfor;
-
 		if( !decl_monitor || !decl_acceptable ) throw SemanticError( "waitfor keyword requires monitors to be in scope, add #include <monitor>", waitfor );
 
@@ -265,7 +267,7 @@
 		);
 
-		// Expression * result  = call( acceptables, timeout, orelse, stmt );
-
-		// choose( waitfor, result );
+		Expression * result = call( waitfor->clauses.size(), acceptables, timeout, stmt );
+
+		choose( waitfor, result, stmt );
 
 		return stmt;
@@ -274,9 +276,6 @@
 	ObjectDecl * GenerateWaitForPass::declare( unsigned long count, CompoundStmt * stmt )
 	{
-		ObjectDecl * acceptables = new ObjectDecl(
+		ObjectDecl * acceptables = ObjectDecl::newObject(
 			namer_acc.newName(),
-			noStorage,
-			LinkageSpec::Cforall,
-			nullptr,
 			new ArrayType(
 				noQualifiers,
@@ -299,14 +298,14 @@
 	ObjectDecl * GenerateWaitForPass::declMon( WaitForStmt::Clause & clause, CompoundStmt * stmt ) {
 
-		ObjectDecl * mon = new ObjectDecl(
+		ObjectDecl * mon = ObjectDecl::newObject(
 			namer_mon.newName(),
-			noStorage,
-			LinkageSpec::Cforall,
-			nullptr,
 			new ArrayType(
 				noQualifiers,
-				new StructInstType(
+				new PointerType(
 					noQualifiers,
-					decl_monitor
+					new StructInstType(
+						noQualifiers,
+						decl_monitor
+					)
 				),
 				new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ),
@@ -316,5 +315,21 @@
 			new ListInit(
 				map_range < std::list<Initializer*> > ( clause.target.arguments, [this](Expression * expr ){
-					return new SingleInit( expr );
+					Expression * untyped = new CastExpr(
+						new UntypedExpr(
+							new NameExpr( "get_monitor" ),
+							{ expr }
+						),
+						new PointerType(
+							noQualifiers,
+							new StructInstType(
+								noQualifiers,
+								decl_monitor
+							)
+						)
+					);
+
+					Expression * init = ResolvExpr::findSingleExpression( untyped, indexer );
+					delete untyped;
+					return new SingleInit( init );
 				})
 			)
@@ -330,9 +345,11 @@
 		ObjectDecl * monitors = declMon( clause, stmt );
 
+		Type * fptr_t = new PointerType( noQualifiers, new FunctionType( noQualifiers, true ) );
+
 		CompoundStmt * compound = new CompoundStmt( noLabels );
-		compound->push_back( makeAccStatement( acceptables, index, decl_m_func    , clause.target.function ) );
-		compound->push_back( makeAccStatement( acceptables, index, decl_m_count   , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ) ) );
-		compound->push_back( makeAccStatement( acceptables, index, decl_m_monitors, new VariableExpr( monitors ) ) );
-		compound->push_back( makeAccStatement( acceptables, index, decl_m_isdtor  , new ConstantExpr( Constant::from_bool( true ) ) ) );
+		compound->push_back( makeAccStatement( acceptables, index, "is_dtor" , detectIsDtor( clause.target.function )                                    , indexer ) );
+		compound->push_back( makeAccStatement( acceptables, index, "func"    , new CastExpr( clause.target.function, fptr_t )                            , indexer ) );
+		compound->push_back( makeAccStatement( acceptables, index, "monitors", new VariableExpr( monitors )                                              , indexer ) );
+		compound->push_back( makeAccStatement( acceptables, index, "count"   , new ConstantExpr( Constant::from_ulong( clause.target.arguments.size() ) ), indexer ) );
 
 		stmt->push_back( new IfStmt(
@@ -355,9 +372,6 @@
 		CompoundStmt * stmt
 	) {
-		ObjectDecl * timeout = new ObjectDecl(
+		ObjectDecl * timeout = ObjectDecl::newObject(
 			namer_tim.newName(),
-			noStorage,
-			LinkageSpec::Cforall,
-			nullptr,
 			new BasicType(
 				noQualifiers,
@@ -374,5 +388,5 @@
 			stmt->push_back( new IfStmt(
 				noLabels,
-				safeCond( else_cond ),
+				safeCond( time_cond ),
 				new ExprStmt(
 					noLabels,
@@ -407,4 +421,99 @@
 		return new VariableExpr( timeout );
 	}
+
+	Expression * GenerateWaitForPass::call(
+		size_t count,
+		ObjectDecl * acceptables,
+		Expression * timeout,
+		CompoundStmt * stmt
+	) {
+		ObjectDecl * decl = ObjectDecl::newObject(
+			namer_ret.newName(),
+			new BasicType(
+				noQualifiers,
+				BasicType::LongLongUnsignedInt
+			),
+			new SingleInit(
+				new UntypedExpr(
+					VariableExpr::functionPointer( decl_waitfor ),
+					{
+						new ConstantExpr( Constant::from_ulong( count ) ),
+						new VariableExpr( acceptables ),
+						timeout
+					}
+				)
+			)
+		);
+
+		stmt->push_back( new DeclStmt( noLabels, decl ) );
+
+		return new VariableExpr( decl );
+	}
+
+	void GenerateWaitForPass::choose(
+		WaitForStmt * waitfor,
+		Expression  * result,
+		CompoundStmt * stmt
+	) {
+		SwitchStmt * swtch = new SwitchStmt(
+			noLabels,
+			result,
+			std::list<Statement *>()
+		);
+
+		unsigned long i = 0;
+		for( auto & clause : waitfor->clauses ) {
+			swtch->statements.push_back(
+				new CaseStmt(
+					noLabels,
+					new ConstantExpr( Constant::from_ulong( i++ ) ),
+					{
+						clause.statement,
+						new BranchStmt(
+							noLabels,
+							"",
+							BranchStmt::Break
+						)
+					}
+				)
+			);
+		}
+
+		if(waitfor->timeout.statement) {
+			swtch->statements.push_back(
+				new CaseStmt(
+					noLabels,
+					new ConstantExpr( Constant::from_ulong( i++ ) ),
+					{
+						waitfor->timeout.statement,
+						new BranchStmt(
+							noLabels,
+							"",
+							BranchStmt::Break
+						)
+					}
+				)
+			);
+		}
+
+		if(waitfor->orelse.statement) {
+			swtch->statements.push_back(
+				new CaseStmt(
+					noLabels,
+					new ConstantExpr( Constant::from_ulong( i++ ) ),
+					{
+						waitfor->orelse.statement,
+						new BranchStmt(
+							noLabels,
+							"",
+							BranchStmt::Break
+						)
+					}
+				)
+			);
+		}
+
+		stmt->push_back( swtch );
+	}
 };
 
Index: src/Parser/StatementNode.cc
===================================================================
--- src/Parser/StatementNode.cc	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/Parser/StatementNode.cc	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -234,5 +234,5 @@
 		target,
 		maybeMoveBuild<Statement >( stmt ),
-		maybeMoveBuild<Expression>( when )
+		notZeroExpr( maybeMoveBuild<Expression>( when ) )
 	});
 
@@ -250,8 +250,8 @@
 	delete targetExpr;
 
-	node->clauses.push_back( WaitForStmt::Clause{
+	node->clauses.insert( node->clauses.begin(), WaitForStmt::Clause{
 		std::move( target ),
 		maybeMoveBuild<Statement >( stmt ),
-		maybeMoveBuild<Expression>( when )
+		notZeroExpr( maybeMoveBuild<Expression>( when ) )
 	});
 
@@ -265,9 +265,9 @@
 		node->timeout.time      = maybeMoveBuild<Expression>( timeout );
 		node->timeout.statement = maybeMoveBuild<Statement >( stmt    );
-		node->timeout.condition = maybeMoveBuild<Expression>( when    );
+		node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) );
 	}
 	else {
-		node->orelse.statement  = maybeMoveBuild<Statement >( stmt    );
-		node->orelse.condition  = maybeMoveBuild<Expression>( when    );
+		node->orelse.statement  = maybeMoveBuild<Statement >( stmt );
+		node->orelse.condition  = notZeroExpr( maybeMoveBuild<Expression>( when ) );
 	}
 
@@ -280,17 +280,11 @@
 	node->timeout.time      = maybeMoveBuild<Expression>( timeout );
 	node->timeout.statement = maybeMoveBuild<Statement >( stmt    );
-	node->timeout.condition = maybeMoveBuild<Expression>( when    );
+	node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) );
 
 	node->orelse.statement = maybeMoveBuild<Statement >( else_stmt );
-	node->orelse.condition = maybeMoveBuild<Expression>( else_when );
+	node->orelse.condition  = notZeroExpr( maybeMoveBuild<Expression>( else_when ) );
 
 	return node;
 }
-
-// WaitForStmt::Target build_waitfor( const std::string * name, ExpressionNode * arguments ) {
-// 	 return WaitForStmt::Clause{
-
-// 	 };
-// }
 
 Statement *build_compound( StatementNode *first ) {
Index: src/Parser/parserutility.cc
===================================================================
--- src/Parser/parserutility.cc	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/Parser/parserutility.cc	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -29,4 +29,5 @@
 
 Expression *notZeroExpr( Expression *orig ) {
+	if( !orig ) return nullptr;
 	UntypedExpr *comparison = new UntypedExpr( new NameExpr( "?!=?" ) );
 	comparison->get_args().push_back( orig );
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -144,12 +144,12 @@
 			expr->get_result()->accept( global_renamer );
 		}
-
-		void referenceToRvalueConversion( Expression *& expr ) {
-			if ( dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
-				// cast away reference from expr
-				expr = new CastExpr( expr, expr->get_result()->stripReferences()->clone() );
-			}
-		}
 	} // namespace
+
+	void referenceToRvalueConversion( Expression *& expr ) {
+		if ( dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
+			// cast away reference from expr
+			expr = new CastExpr( expr, expr->get_result()->stripReferences()->clone() );
+		}
+	}
 
 	template< typename InputIterator, typename OutputIterator >
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/ResolvExpr/AlternativeFinder.h	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -50,4 +50,9 @@
 		const SymTab::Indexer &get_indexer() const { return indexer; }
 		const TypeEnvironment &get_environ() const { return env; }
+
+		/// Runs a new alternative finder on each element in [begin, end)
+		/// and writes each alternative finder to out.
+		template< typename InputIterator, typename OutputIterator >
+		void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
 	  private:
 		virtual void visit( ApplicationExpr *applicationExpr );
@@ -81,8 +86,4 @@
 		virtual void visit( StmtExpr *stmtExpr );
 		virtual void visit( UntypedInitExpr *initExpr );
-		/// Runs a new alternative finder on each element in [begin, end)
-		/// and writes each alternative finder to out.
-		template< typename InputIterator, typename OutputIterator >
-		void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
 
 		/// Adds alternatives for anonymous members
@@ -108,4 +109,5 @@
 
 	Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env );
+	void referenceToRvalueConversion( Expression *& expr );
 
 	template< typename InputIterator, typename OutputIterator >
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/ResolvExpr/Resolver.cc	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -40,4 +40,5 @@
 #include "SynTree/Visitor.h"             // for acceptAll, maybeAccept
 #include "typeops.h"                     // for extractResultType
+#include "Unify.h"                       // for unify
 
 using namespace std;
@@ -71,4 +72,5 @@
 		void previsit( ThrowStmt *throwStmt );
 		void previsit( CatchStmt *catchStmt );
+		void previsit( WaitForStmt * stmt );
 
 		void previsit( SingleInit *singleInit );
@@ -116,26 +118,26 @@
 	}
 
+	Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
+		TypeEnvironment env;
+		AlternativeFinder finder( indexer, env );
+		finder.find( untyped );
+		#if 0
+		if ( finder.get_alternatives().size() != 1 ) {
+			std::cout << "untyped expr is ";
+			untyped->print( std::cout );
+			std::cout << std::endl << "alternatives are:";
+			for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
+				i->print( std::cout );
+			} // for
+		} // if
+		#endif
+		assertf( finder.get_alternatives().size() == 1, "findSingleExpression: must have exactly one alternative at the end." );
+		Alternative &choice = finder.get_alternatives().front();
+		Expression *newExpr = choice.expr->clone();
+		finishExpr( newExpr, choice.env );
+		return newExpr;
+	}
+
 	namespace {
-		Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
-			TypeEnvironment env;
-			AlternativeFinder finder( indexer, env );
-			finder.find( untyped );
-#if 0
-			if ( finder.get_alternatives().size() != 1 ) {
-				std::cout << "untyped expr is ";
-				untyped->print( std::cout );
-				std::cout << std::endl << "alternatives are:";
-				for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
-					i->print( std::cout );
-				} // for
-			} // if
-#endif
-			assertf( finder.get_alternatives().size() == 1, "findSingleExpression: must have exactly one alternative at the end." );
-			Alternative &choice = finder.get_alternatives().front();
-			Expression *newExpr = choice.expr->clone();
-			finishExpr( newExpr, choice.env );
-			return newExpr;
-		}
-
 		bool isIntegralType( Type *type ) {
 			if ( dynamic_cast< EnumInstType * >( type ) ) {
@@ -391,4 +393,207 @@
 	}
 
+	inline void resolveAsIf( Expression *& expr, SymTab::Indexer & indexer ) {
+		if( !expr ) return;
+		Expression * newExpr = findSingleExpression( expr, indexer );
+		delete expr;
+		expr = newExpr;
+	}
+
+	inline void resolveAsType( Expression *& expr, Type * type, SymTab::Indexer & indexer ) {
+		if( !expr ) return;
+		Expression * newExpr = findSingleExpression( new CastExpr( expr, type ), indexer );
+		delete expr;
+		expr = newExpr;
+	}
+
+	template< typename iterator_t >
+	inline bool advance_to_mutex( iterator_t & it, const iterator_t & end ) {
+		while( it != end && !(*it)->get_type()->get_mutex() ) {
+			it++;
+		}
+
+		return it != end;
+	}
+
+	void Resolver::previsit( WaitForStmt * stmt ) {
+		visit_children = false;
+
+		// Resolve all clauses first
+		for( auto& clause : stmt->clauses ) {
+
+			TypeEnvironment env;
+			AlternativeFinder funcFinder( indexer, env );
+
+			// Find all alternatives for a function in canonical form
+			funcFinder.findWithAdjustment( clause.target.function );
+
+			if ( funcFinder.get_alternatives().empty() ) {
+				stringstream ss;
+				ss << "Use of undeclared indentifier '";
+				ss << strict_dynamic_cast<NameExpr*>( clause.target.function )->name;
+				ss << "' in call to waitfor";
+				throw SemanticError( ss.str() );
+			}
+
+			// Find all alternatives for all arguments in canonical form
+			std::list< AlternativeFinder > argAlternatives;
+			funcFinder.findSubExprs( clause.target.arguments.begin(), clause.target.arguments.end(), back_inserter( argAlternatives ) );
+
+			// List all combinations of arguments
+			std::list< AltList > possibilities;
+			combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
+
+			AltList                func_candidates;
+			std::vector< AltList > args_candidates;
+
+			// For every possible function :
+			// 	try matching the arguments to the parameters
+			// 	not the other way around because we have more arguments than parameters
+			SemanticError errors;
+			for ( Alternative & func : funcFinder.get_alternatives() ) {
+				try {
+					PointerType * pointer = dynamic_cast< PointerType* >( func.expr->get_result()->stripReferences() );
+					if( !pointer ) {
+						throw SemanticError( "candidate not viable: not a pointer type\n", func.expr->get_result() );
+					}
+
+					FunctionType * function = dynamic_cast< FunctionType* >( pointer->get_base() );
+					if( !function ) {
+						throw SemanticError( "candidate not viable: not a function type\n", pointer->get_base() );
+					}
+
+
+					{
+						auto param     = function->parameters.begin();
+						auto param_end = function->parameters.end();
+
+						if( !advance_to_mutex( param, param_end ) ) {
+							throw SemanticError("candidate function not viable: no mutex parameters\n", function);
+						}
+					}
+
+					Alternative newFunc( func );
+					// Strip reference from function
+					referenceToRvalueConversion( newFunc.expr );
+
+					// For all the set of arguments we have try to match it with the parameter of the current function alternative
+					for ( auto & argsList : possibilities ) {
+
+						try {
+							// Declare data structures need for resolution
+							OpenVarSet openVars;
+							AssertionSet resultNeed, resultHave;
+							TypeEnvironment resultEnv;
+
+							// Load type variables from arguemnts into one shared space
+							simpleCombineEnvironments( argsList.begin(), argsList.end(), resultEnv );
+
+							// Make sure we don't widen any existing bindings
+							for ( auto & i : resultEnv ) {
+								i.allowWidening = false;
+							}
+
+							// Find any unbound type variables
+							resultEnv.extractOpenVars( openVars );
+
+							auto param     = function->parameters.begin();
+							auto param_end = function->parameters.end();
+
+							// For every arguments of its set, check if it matches one of the parameter
+							// The order is important
+							for( auto & arg : argsList ) {
+
+								// Ignore non-mutex arguments
+								if( !advance_to_mutex( param, param_end ) ) {
+									// We ran out of parameters but still have arguments
+									// this function doesn't match
+									throw SemanticError("candidate function not viable: too many mutex arguments\n", function);
+								}
+
+								// Check if the argument matches the parameter type in the current scope
+								if( ! unify( (*param)->get_type(), arg.expr->get_result(), resultEnv, resultNeed, resultHave, openVars, this->indexer ) ) {
+									// Type doesn't match
+									stringstream ss;
+									ss << "candidate function not viable: no known convertion from '";
+									arg.expr->get_result()->print( ss );
+									ss << "' to '";
+									(*param)->get_type()->print( ss );
+									ss << "'\n";
+									throw SemanticError(ss.str(), function);
+								}
+
+								param++;
+							}
+
+							// All arguments match !
+
+							// Check if parameters are missing
+							if( advance_to_mutex( param, param_end ) ) {
+								// We ran out of arguments but still have parameters left
+								// this function doesn't match
+								throw SemanticError("candidate function not viable: too few mutex arguments\n", function);
+							}
+
+							// All parameters match !
+
+							// Finish the expressions to tie in the proper environments
+							finishExpr( newFunc.expr, resultEnv );
+							for( Alternative & alt : argsList ) {
+								finishExpr( alt.expr, resultEnv );
+							}
+
+							// This is a match store it and save it for later
+							func_candidates.push_back( newFunc );
+							args_candidates.push_back( argsList );
+
+						}
+						catch( SemanticError &e ) {
+							errors.append( e );
+						}
+					}
+				}
+				catch( SemanticError &e ) {
+					errors.append( e );
+				}
+			}
+
+			// Make sure we got the right number of arguments
+			if( func_candidates.empty() )    { SemanticError top( "No alternatives for function in call to waitfor"  ); top.append( errors ); throw top; }
+			if( args_candidates.empty() )    { SemanticError top( "No alternatives for arguments in call to waitfor" ); top.append( errors ); throw top; }
+			if( func_candidates.size() > 1 ) { SemanticError top( "Ambiguous function in call to waitfor"            ); top.append( errors ); throw top; }
+			if( args_candidates.size() > 1 ) { SemanticError top( "Ambiguous arguments in call to waitfor"           ); top.append( errors ); throw top; }
+
+
+			// Swap the results from the alternative with the unresolved values.
+			// Alternatives will handle deletion on destruction
+			std::swap( clause.target.function, func_candidates.front().expr );
+			for( auto arg_pair : group_iterate( clause.target.arguments, args_candidates.front() ) ) {
+				std::swap ( std::get<0>( arg_pair), std::get<1>( arg_pair).expr );
+			}
+
+			// Resolve the conditions as if it were an IfStmt
+			// Resolve the statments normally
+			resolveAsIf( clause.condition, this->indexer );
+			clause.statement->accept( *visitor );
+		}
+
+
+		if( stmt->timeout.statement ) {
+			// Resolve the timeout as an size_t for now
+			// Resolve the conditions as if it were an IfStmt
+			// Resolve the statments normally
+			resolveAsType( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer );
+			resolveAsIf  ( stmt->timeout.condition, this->indexer );
+			stmt->timeout.statement->accept( *visitor );
+		}
+
+		if( stmt->orelse.statement ) {
+			// Resolve the conditions as if it were an IfStmt
+			// Resolve the statments normally
+			resolveAsIf( stmt->orelse.condition, this->indexer );
+			stmt->orelse.statement->accept( *visitor );
+		}
+	}
+
 	template< typename T >
 	bool isCharType( T t ) {
Index: src/ResolvExpr/Resolver.h
===================================================================
--- src/ResolvExpr/Resolver.h	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/ResolvExpr/Resolver.h	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -29,6 +29,7 @@
 	/// Checks types and binds syntactic constructs to typed representations
 	void resolve( std::list< Declaration * > translationUnit );
-	Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
-	Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer );
+	Expression * resolveInVoidContext( Expression *expr   , const SymTab::Indexer &indexer );
+	Expression * findVoidExpression  ( Expression *untyped, const SymTab::Indexer &indexer );
+	Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer );
 	void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer );
 	void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer );
Index: src/SymTab/Mangler.cc
===================================================================
--- src/SymTab/Mangler.cc	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/SymTab/Mangler.cc	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -307,4 +307,7 @@
 			mangleName << "V";
 		} // if
+		if ( type->get_mutex() ) {
+			mangleName << "M";
+		} // if
 		// Removed due to restrict not affecting function compatibility in GCC
 //		if ( type->get_isRestrict() ) {
Index: src/SynTree/BaseSyntaxNode.h
===================================================================
--- src/SynTree/BaseSyntaxNode.h	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/SynTree/BaseSyntaxNode.h	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -26,6 +26,8 @@
 
 	virtual void accept( Visitor & v ) = 0;
-  virtual void print( std::ostream & os, int indent = 0 ) const = 0;
+  	virtual void print( std::ostream & os, int indent = 0 ) const = 0;
 };
+
+std::ostream & operator<<( std::ostream & out, const BaseSyntaxNode * node );
 
 // Local Variables: //
Index: src/SynTree/Declaration.cc
===================================================================
--- src/SynTree/Declaration.cc	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/SynTree/Declaration.cc	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -59,13 +59,4 @@
 }
 
-std::ostream & operator<<( std::ostream & out, const Declaration * decl ) {
-	if ( decl ){
-		decl->print( out );
-	} else {
-		out << "nullptr";
-	}
-	return out;
-}
-
 
 AsmDecl::AsmDecl( AsmStmt *stmt ) : Declaration( "", Type::StorageClasses(), LinkageSpec::C ), stmt( stmt ) {
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/SynTree/Declaration.h	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -62,7 +62,7 @@
 	void fixUniqueId( void );
 	virtual Declaration *clone() const = 0;
-	virtual void accept( Visitor &v ) = 0;
+	virtual void accept( Visitor &v ) override = 0;
 	virtual Declaration *acceptMutator( Mutator &m ) = 0;
-	virtual void print( std::ostream &os, int indent = 0 ) const = 0;
+	virtual void print( std::ostream &os, int indent = 0 ) const override = 0;
 	virtual void printShort( std::ostream &os, int indent = 0 ) const = 0;
 
@@ -106,6 +106,6 @@
 	//void set_functionSpecifiers( Type::FuncSpecifiers newValue ) { fs = newValue; }
 
-	virtual DeclarationWithType *clone() const = 0;
-	virtual DeclarationWithType *acceptMutator( Mutator &m ) = 0;
+	virtual DeclarationWithType *clone() const override = 0;
+	virtual DeclarationWithType *acceptMutator( Mutator &m )  override = 0;
 
 	virtual Type * get_type() const = 0;
@@ -128,6 +128,6 @@
 	virtual ~ObjectDecl();
 
-	virtual Type * get_type() const { return type; }
-	virtual void set_type(Type *newType) { type = newType; }
+	virtual Type * get_type() const override { return type; }
+	virtual void set_type(Type *newType) override { type = newType; }
 
 	Initializer *get_init() const { return init; }
@@ -139,9 +139,9 @@
 	static ObjectDecl * newObject( const std::string & name, Type * type, Initializer * init );
 
-	virtual ObjectDecl *clone() const { return new ObjectDecl( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual DeclarationWithType *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
-	virtual void printShort( std::ostream &os, int indent = 0 ) const;
+	virtual ObjectDecl *clone() const override { return new ObjectDecl( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual DeclarationWithType *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
+	virtual void printShort( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -157,6 +157,6 @@
 	virtual ~FunctionDecl();
 
-	Type * get_type() const { return type; }
-	virtual void set_type(Type * t) { type = strict_dynamic_cast< FunctionType* >( t ); }
+	virtual Type * get_type() const override { return type; }
+	virtual void set_type(Type * t) override { type = strict_dynamic_cast< FunctionType* >( t ); }
 
 	FunctionType * get_functionType() const { return type; }
@@ -165,9 +165,9 @@
 	void set_statements( CompoundStmt *newValue ) { statements = newValue; }
 
-	virtual FunctionDecl *clone() const { return new FunctionDecl( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual DeclarationWithType *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
-	virtual void printShort( std::ostream &os, int indent = 0 ) const;
+	virtual FunctionDecl *clone() const override { return new FunctionDecl( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual DeclarationWithType *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
+	virtual void printShort( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -190,7 +190,7 @@
 	virtual std::string typeString() const = 0;
 
-	virtual NamedTypeDecl *clone() const = 0;
-	virtual void print( std::ostream &os, int indent = 0 ) const;
-	virtual void printShort( std::ostream &os, int indent = 0 ) const;
+	virtual NamedTypeDecl *clone() const override = 0;
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
+	virtual void printShort( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -227,11 +227,11 @@
 	TypeDecl * set_sized( bool newValue ) { sized = newValue; return this; }
 
-	virtual std::string typeString() const;
+	virtual std::string typeString() const override;
 	virtual std::string genTypeString() const;
 
-	virtual TypeDecl *clone() const { return new TypeDecl( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
+	virtual TypeDecl *clone() const override { return new TypeDecl( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 
   private:
@@ -245,9 +245,9 @@
 	TypedefDecl( const TypedefDecl &other ) : Parent( other ) {}
 
-	virtual std::string typeString() const;
-
-	virtual TypedefDecl *clone() const { return new TypedefDecl( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual std::string typeString() const override;
+
+	virtual TypedefDecl *clone() const override { return new TypedefDecl( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
   private:
 };
@@ -274,6 +274,6 @@
 	AggregateDecl * set_body( bool body ) { AggregateDecl::body = body; return this; }
 
-	virtual void print( std::ostream &os, int indent = 0 ) const;
-	virtual void printShort( std::ostream &os, int indent = 0 ) const;
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
+	virtual void printShort( std::ostream &os, int indent = 0 ) const override;
   protected:
 	virtual std::string typeString() const = 0;
@@ -290,10 +290,10 @@
 	bool is_thread() { return kind == DeclarationNode::Thread; }
 
-	virtual StructDecl *clone() const { return new StructDecl( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
+	virtual StructDecl *clone() const override { return new StructDecl( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
   private:
 	DeclarationNode::Aggregate kind;
-	virtual std::string typeString() const;
+	virtual std::string typeString() const override;
 };
 
@@ -304,9 +304,9 @@
 	UnionDecl( const UnionDecl &other ) : Parent( other ) {}
 
-	virtual UnionDecl *clone() const { return new UnionDecl( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-  private:
-	virtual std::string typeString() const;
+	virtual UnionDecl *clone() const override { return new UnionDecl( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+  private:
+	virtual std::string typeString() const override;
 };
 
@@ -317,9 +317,9 @@
 	EnumDecl( const EnumDecl &other ) : Parent( other ) {}
 
-	virtual EnumDecl *clone() const { return new EnumDecl( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-  private:
-	virtual std::string typeString() const;
+	virtual EnumDecl *clone() const override { return new EnumDecl( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+  private:
+	virtual std::string typeString() const override;
 };
 
@@ -332,9 +332,9 @@
 	TraitDecl( const TraitDecl &other ) : Parent( other ) {}
 
-	virtual TraitDecl *clone() const { return new TraitDecl( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Declaration *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-  private:
-	virtual std::string typeString() const;
+	virtual TraitDecl *clone() const override { return new TraitDecl( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+  private:
+	virtual std::string typeString() const override;
 };
 
@@ -350,12 +350,11 @@
 	void set_stmt( AsmStmt *newValue ) { stmt = newValue; }
 
-	virtual AsmDecl *clone() const { return new AsmDecl( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual AsmDecl *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
-	virtual void printShort( std::ostream &os, int indent = 0 ) const;
-};
-
-std::ostream & operator<<( std::ostream & out, const Declaration * decl );
+	virtual AsmDecl *clone() const override { return new AsmDecl( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual AsmDecl *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
+	virtual void printShort( std::ostream &os, int indent = 0 ) const override;
+};
+
 std::ostream & operator<<( std::ostream & os, const TypeDecl::Data & data );
 
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/SynTree/Expression.cc	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -741,14 +741,4 @@
 }
 
-
-std::ostream & operator<<( std::ostream & out, const Expression * expr ) {
-	if ( expr ) {
-		expr->print( out );
-	} else {
-		out << "nullptr";
-	}
-	return out;
-}
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/Expression.h
===================================================================
--- src/SynTree/Expression.h	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/SynTree/Expression.h	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -821,7 +821,4 @@
 };
 
-
-std::ostream & operator<<( std::ostream & out, const Expression * expr );
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/Initializer.cc
===================================================================
--- src/SynTree/Initializer.cc	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/SynTree/Initializer.cc	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -137,22 +137,4 @@
 }
 
-std::ostream & operator<<( std::ostream & out, const Initializer * init ) {
-	if ( init ) {
-		init->print( out );
-	} else {
-		out << "nullptr";
-	}
-	return out;
-}
-
-std::ostream & operator<<( std::ostream & out, const Designation * des ) {
-	if ( des ) {
-		des->print( out );
-	} else {
-		out << "nullptr";
-	}
-	return out;
-}
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/Initializer.h
===================================================================
--- src/SynTree/Initializer.h	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/SynTree/Initializer.h	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -38,7 +38,7 @@
 
 	virtual Designation * clone() const { return new Designation( *this ); };
-	virtual void accept( Visitor &v ) { v.visit( this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
 	virtual Designation * acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -55,7 +55,7 @@
 
 	virtual Initializer *clone() const = 0;
-	virtual void accept( Visitor &v ) = 0;
+	virtual void accept( Visitor &v ) override = 0;
 	virtual Initializer *acceptMutator( Mutator &m ) = 0;
-	virtual void print( std::ostream &os, int indent = 0 ) const = 0;
+	virtual void print( std::ostream &os, int indent = 0 ) const override = 0;
   private:
 	bool maybeConstructed;
@@ -75,8 +75,8 @@
 	void set_value( Expression *newValue ) { value = newValue; }
 
-	virtual SingleInit *clone() const { return new SingleInit( *this); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
+	virtual SingleInit *clone() const override { return new SingleInit( *this); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -103,8 +103,8 @@
 	const_iterator end() const { return initializers.end(); }
 
-	virtual ListInit *clone() const { return new ListInit( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
+	virtual ListInit *clone() const override { return new ListInit( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -129,8 +129,8 @@
 	Initializer * get_init() const { return init; }
 
-	ConstructorInit *clone() const { return new ConstructorInit( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
+	ConstructorInit *clone() const override { return new ConstructorInit( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 
   private:
@@ -140,7 +140,4 @@
 };
 
-std::ostream & operator<<( std::ostream & out, const Initializer * init );
-std::ostream & operator<<( std::ostream & out, const Designation * des );
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/Statement.cc
===================================================================
--- src/SynTree/Statement.cc	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/SynTree/Statement.cc	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -168,5 +168,5 @@
 }
 
-SwitchStmt::SwitchStmt( std::list<Label> labels, Expression * condition, std::list<Statement *> &statements ):
+SwitchStmt::SwitchStmt( std::list<Label> labels, Expression * condition, const std::list<Statement *> &statements ):
 	Statement( labels ), condition( condition ), statements( statements ) {
 }
@@ -196,5 +196,5 @@
 }
 
-CaseStmt::CaseStmt( std::list<Label> labels, Expression *condition, std::list<Statement *> &statements, bool deflt ) throw ( SemanticError ) :
+CaseStmt::CaseStmt( std::list<Label> labels, Expression *condition, const std::list<Statement *> &statements, bool deflt ) throw ( SemanticError ) :
 	Statement( labels ), condition( condition ), stmts( statements ), _isDefault( deflt ) {
 	if ( isDefault() && condition != 0 )
@@ -497,13 +497,4 @@
 }
 
-std::ostream & operator<<( std::ostream & out, const Statement * statement ) {
-	if ( statement ) {
-		statement->print( out );
-	} else {
-		out << "nullptr";
-	}
-	return out;
-}
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/Statement.h
===================================================================
--- src/SynTree/Statement.h	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/SynTree/Statement.h	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -44,7 +44,7 @@
 
 	virtual Statement *clone() const = 0;
-	virtual void accept( Visitor &v ) = 0;
+	virtual void accept( Visitor &v ) override = 0;
 	virtual Statement *acceptMutator( Mutator &m ) = 0;
-	virtual void print( std::ostream &os, int indent = 0 ) const;
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -61,8 +61,8 @@
 	void push_front( Statement * stmt ) { kids.push_front( stmt ); }
 
-	virtual CompoundStmt *clone() const { return new CompoundStmt( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual CompoundStmt *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
+	virtual CompoundStmt *clone() const override { return new CompoundStmt( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual CompoundStmt *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -72,8 +72,8 @@
 	NullStmt( std::list<Label> labels );
 
-	virtual NullStmt *clone() const { return new NullStmt( *this ); }
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual NullStmt *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
+	virtual NullStmt *clone() const override { return new NullStmt( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual NullStmt *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -89,8 +89,8 @@
 	void set_expr( Expression *newValue ) { expr = newValue; }
 
-	virtual ExprStmt *clone() const { return new ExprStmt( *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;
+	virtual ExprStmt *clone() const override { return new ExprStmt( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -146,8 +146,8 @@
 	void set_elsePart( Statement *newValue ) { elsePart = newValue; }
 
-	virtual IfStmt *clone() const { return new IfStmt( *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;
+	virtual IfStmt *clone() const override { return new IfStmt( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -157,5 +157,5 @@
 	std::list<Statement *> statements;
 
-	SwitchStmt( std::list<Label> labels, Expression *condition, std::list<Statement *> &statements );
+	SwitchStmt( std::list<Label> labels, Expression *condition, const std::list<Statement *> &statements );
 	SwitchStmt( const SwitchStmt &other );
 	virtual ~SwitchStmt();
@@ -166,9 +166,9 @@
 	std::list<Statement *> & get_statements() { return statements; }
 
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-
-	virtual SwitchStmt *clone() const { return new SwitchStmt( *this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+
+	virtual SwitchStmt *clone() const override { return new SwitchStmt( *this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 
 };
@@ -179,5 +179,5 @@
 	std::list<Statement *> stmts;
 
-	CaseStmt( std::list<Label> labels, Expression *conditions, std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);
+	CaseStmt( std::list<Label> labels, Expression *conditions, const std::list<Statement *> &stmts, bool isdef = false ) throw(SemanticError);
 	CaseStmt( const CaseStmt &other );
 	virtual ~CaseStmt();
@@ -194,9 +194,9 @@
 	void set_statements( std::list<Statement *> &newValue ) { stmts = newValue; }
 
-	virtual void accept( Visitor &v ) { v.visit( this ); }
-	virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
-
-	virtual CaseStmt *clone() const { return new CaseStmt( *this ); }
-	virtual void print( std::ostream &os, int indent = 0 ) const;
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+
+	virtual CaseStmt *clone() const override { return new CaseStmt( *this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
   private:
 	bool _isDefault;
@@ -221,8 +221,8 @@
 	void set_isDoWhile( bool newValue ) { isDoWhile = newValue; }
 
-	virtual WhileStmt *clone() const { return new WhileStmt( *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;
+	virtual WhileStmt *clone() const override { return new WhileStmt( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -247,8 +247,8 @@
 	void set_body( Statement *newValue ) { body = newValue; }
 
-	virtual ForStmt *clone() const { return new ForStmt( *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;
+	virtual ForStmt *clone() const override { return new ForStmt( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -276,8 +276,8 @@
 	const char *get_typename() { return brType[ type ]; }
 
-	virtual BranchStmt *clone() const { return new BranchStmt( *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;
+	virtual BranchStmt *clone() const override { return new BranchStmt( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
   private:
 	static const char *brType[];
@@ -295,8 +295,8 @@
 	void set_expr( Expression *newValue ) { expr = newValue; }
 
-	virtual ReturnStmt *clone() const { return new ReturnStmt( *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;
+	virtual ReturnStmt *clone() const override { return new ReturnStmt( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -319,8 +319,8 @@
 	void set_target( Expression * newTarget ) { target = newTarget; }
 
-	virtual ThrowStmt *clone() const { return new ThrowStmt( *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;
+	virtual ThrowStmt *clone() const override { return new ThrowStmt( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -342,8 +342,8 @@
 	void set_finally( FinallyStmt *newValue ) { finallyBlock = newValue; }
 
-	virtual TryStmt *clone() const { return new TryStmt( *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;
+	virtual TryStmt *clone() const override { return new TryStmt( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -370,8 +370,8 @@
 	void set_body( Statement *newValue ) { body = newValue; }
 
-	virtual CatchStmt *clone() const { return new CatchStmt( *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;
+	virtual CatchStmt *clone() const override { return new CatchStmt( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -387,8 +387,8 @@
 	void set_block( CompoundStmt *newValue ) { block = newValue; }
 
-	virtual FinallyStmt *clone() const { return new FinallyStmt( *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;
+	virtual FinallyStmt *clone() const override { return new FinallyStmt( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -424,8 +424,8 @@
 	} 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;
+	virtual WaitForStmt *clone() const override { return new WaitForStmt( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 
 };
@@ -444,8 +444,8 @@
 	void set_decl( Declaration *newValue ) { decl = newValue; }
 
-	virtual DeclStmt *clone() const { return new DeclStmt( *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;
+	virtual DeclStmt *clone() const override { return new DeclStmt( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
 };
 
@@ -466,12 +466,9 @@
 	void set_callStmt( Statement * newValue ) { callStmt = newValue; }
 
-	virtual ImplicitCtorDtorStmt *clone() const { return new ImplicitCtorDtorStmt( *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;
-};
-
-
-std::ostream & operator<<( std::ostream & out, const Statement * statement );
+	virtual ImplicitCtorDtorStmt *clone() const override { return new ImplicitCtorDtorStmt( *this ); }
+	virtual void accept( Visitor &v ) override { v.visit( this ); }
+	virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
+	virtual void print( std::ostream &os, int indent = 0 ) const override;
+};
 
 // Local Variables: //
Index: src/SynTree/Type.cc
===================================================================
--- src/SynTree/Type.cc	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/SynTree/Type.cc	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -99,13 +99,4 @@
 const Type::Qualifiers noQualifiers;
 
-std::ostream & operator<<( std::ostream & out, const Type * type ) {
-	if ( type ) {
-		type->print( out );
-	} else {
-		out << "nullptr";
-	} // if
-	return out;
-}
-
 // Local Variables: //
 // tab-width: 4 //
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/SynTree/Type.h	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -192,11 +192,11 @@
 	VoidType( const Type::Qualifiers & tq, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
 
-	virtual unsigned size() const { return 0; };
-	virtual bool isComplete() const { return false; }
-
-	virtual VoidType *clone() const { return new VoidType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, int indent = 0 ) const;
+	virtual unsigned size() const override { return 0; };
+	virtual bool isComplete() const override { return false; }
+
+	virtual VoidType *clone() const override { return new VoidType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const override;
 };
 
@@ -235,8 +235,8 @@
 	void set_kind( Kind newValue ) { kind = newValue; }
 
-	virtual BasicType *clone() const { return new BasicType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, int indent = 0 ) const;
+	virtual BasicType *clone() const override { return new BasicType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const override;
 
 	bool isInteger() const;
@@ -268,10 +268,10 @@
 	bool is_array() const { return isStatic || isVarLen || dimension; }
 
-	virtual bool isComplete() const { return ! isVarLen; }
-
-	virtual PointerType *clone() const { return new PointerType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, int indent = 0 ) const;
+	virtual bool isComplete() const override { return ! isVarLen; }
+
+	virtual PointerType *clone() const override { return new PointerType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const override;
 };
 
@@ -296,10 +296,10 @@
 	void set_isStatic( bool newValue ) { isStatic = newValue; }
 
-	virtual bool isComplete() const { return ! isVarLen; }
-
-	virtual ArrayType *clone() const { return new ArrayType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, int indent = 0 ) const;
+	virtual bool isComplete() const override { return ! isVarLen; }
+
+	virtual ArrayType *clone() const override { return new ArrayType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const override;
 };
 
@@ -315,15 +315,15 @@
 	void set_base( Type *newValue ) { base = newValue; }
 
-	virtual int referenceDepth() const;
+	virtual int referenceDepth() const override;
 
 	// Since reference types act like value types, their size is the size of the base.
 	// This makes it simple to cast the empty tuple to a reference type, since casts that increase
 	// the number of values are disallowed.
-	virtual unsigned size() const { return base->size(); }
-
-	virtual ReferenceType *clone() const { return new ReferenceType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, int indent = 0 ) const;
+	virtual unsigned size() const override { return base->size(); }
+
+	virtual ReferenceType *clone() const override { return new ReferenceType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const override;
 };
 
@@ -349,8 +349,8 @@
 	bool isTtype() const;
 
-	virtual FunctionType *clone() const { return new FunctionType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, int indent = 0 ) const;
+	virtual FunctionType *clone() const override { return new FunctionType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const override;
 };
 
@@ -371,8 +371,8 @@
 	void set_hoistType( bool newValue ) { hoistType = newValue; }
 
-	virtual ReferenceToType *clone() const = 0;
-	virtual void accept( Visitor & v ) = 0;
-	virtual Type *acceptMutator( Mutator & m ) = 0;
-	virtual void print( std::ostream & os, int indent = 0 ) const;
+	virtual ReferenceToType *clone() const override = 0;
+	virtual void accept( Visitor & v ) override = 0;
+	virtual Type *acceptMutator( Mutator & m ) override = 0;
+	virtual void print( std::ostream & os, int indent = 0 ) const override;
 
 	virtual void lookup( __attribute__((unused)) const std::string & name, __attribute__((unused)) std::list< Declaration* > & foundDecls ) const {}
@@ -398,17 +398,17 @@
 	std::list<TypeDecl*> * get_baseParameters();
 
-	virtual bool isComplete() const;
+	virtual bool isComplete() const override;
 
 	/// Looks up the members of this struct named "name" and places them into "foundDecls".
 	/// Clones declarations into "foundDecls", caller responsible for freeing
-	void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const;
-
-	virtual StructInstType *clone() const { return new StructInstType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
-
-	virtual void print( std::ostream & os, int indent = 0 ) const;
+	void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override;
+
+	virtual StructInstType *clone() const override { return new StructInstType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+
+	virtual void print( std::ostream & os, int indent = 0 ) const override;
   private:
-	virtual std::string typeString() const;
+	virtual std::string typeString() const override;
 };
 
@@ -430,17 +430,17 @@
 	std::list< TypeDecl * > * get_baseParameters();
 
-	virtual bool isComplete() const;
+	virtual bool isComplete() const override;
 
 	/// looks up the members of this union named "name" and places them into "foundDecls"
 	/// Clones declarations into "foundDecls", caller responsible for freeing
-	void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const;
-
-	virtual UnionInstType *clone() const { return new UnionInstType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
-
-	virtual void print( std::ostream & os, int indent = 0 ) const;
+	void lookup( const std::string & name, std::list< Declaration* > & foundDecls ) const override;
+
+	virtual UnionInstType *clone() const override { return new UnionInstType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+
+	virtual void print( std::ostream & os, int indent = 0 ) const override;
   private:
-	virtual std::string typeString() const;
+	virtual std::string typeString() const override;
 };
 
@@ -459,11 +459,11 @@
 	void set_baseEnum( EnumDecl *newValue ) { baseEnum = newValue; }
 
-	virtual bool isComplete() const;
-
-	virtual EnumInstType *clone() const { return new EnumInstType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
+	virtual bool isComplete() const override;
+
+	virtual EnumInstType *clone() const override { return new EnumInstType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
   private:
-	virtual std::string typeString() const;
+	virtual std::string typeString() const override;
 };
 
@@ -480,11 +480,11 @@
 	~TraitInstType();
 
-	virtual bool isComplete() const;
-
-	virtual TraitInstType *clone() const { return new TraitInstType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
+	virtual bool isComplete() const override;
+
+	virtual TraitInstType *clone() const override { return new TraitInstType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
   private:
-	virtual std::string typeString() const;
+	virtual std::string typeString() const override;
 };
 
@@ -507,12 +507,12 @@
 	void set_isFtype( bool newValue ) { isFtype = newValue; }
 
-	virtual bool isComplete() const;
-
-	virtual TypeInstType *clone() const { return new TypeInstType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, int indent = 0 ) const;
+	virtual bool isComplete() const override;
+
+	virtual TypeInstType *clone() const override { return new TypeInstType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const override;
   private:
-	virtual std::string typeString() const;
+	virtual std::string typeString() const override;
 };
 
@@ -530,5 +530,5 @@
 
 	std::list<Type *> & get_types() { return types; }
-	virtual unsigned size() const { return types.size(); };
+	virtual unsigned size() const override { return types.size(); };
 
 	// For now, this is entirely synthetic -- tuple types always have unnamed members.
@@ -539,15 +539,15 @@
 	iterator end() { return types.end(); }
 
-	virtual Type * getComponent( unsigned i ) {
+	virtual Type * getComponent( unsigned i ) override {
 		assertf( i < size(), "TupleType::getComponent: index %d must be less than size %d", i, size() );
 		return *(begin()+i);
 	}
 
-	// virtual bool isComplete() const { return true; } // xxx - not sure if this is right, might need to recursively check complete-ness
-
-	virtual TupleType *clone() const { return new TupleType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, int indent = 0 ) const;
+	// virtual bool isComplete() const override { return true; } // xxx - not sure if this is right, might need to recursively check complete-ness
+
+	virtual TupleType *clone() const override { return new TupleType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const override;
 };
 
@@ -563,10 +563,10 @@
 	void set_expr( Expression *newValue ) { expr = newValue; }
 
-	virtual bool isComplete() const { assert( false ); return false; }
-
-	virtual TypeofType *clone() const { return new TypeofType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, int indent = 0 ) const;
+	virtual bool isComplete() const override { assert( false ); return false; }
+
+	virtual TypeofType *clone() const override { return new TypeofType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const override;
 };
 
@@ -592,10 +592,10 @@
 	void set_isType( bool newValue ) { isType = newValue; }
 
-	virtual bool isComplete() const { assert( false ); } // xxx - not sure what to do here
-
-	virtual AttrType *clone() const { return new AttrType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, int indent = 0 ) const;
+	virtual bool isComplete() const override { assert( false ); } // xxx - not sure what to do here
+
+	virtual AttrType *clone() const override { return new AttrType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const override;
 };
 
@@ -606,10 +606,10 @@
 	VarArgsType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
 
-	virtual bool isComplete() const{ return true; } // xxx - is this right?
-
-	virtual VarArgsType *clone() const { return new VarArgsType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, int indent = 0 ) const;
+	virtual bool isComplete() const override{ return true; } // xxx - is this right?
+
+	virtual VarArgsType *clone() const override { return new VarArgsType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const override;
 };
 
@@ -620,8 +620,8 @@
 	ZeroType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
 
-	virtual ZeroType *clone() const { return new ZeroType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, int indent = 0 ) const;
+	virtual ZeroType *clone() const override { return new ZeroType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const override;
 };
 
@@ -632,11 +632,9 @@
 	OneType( Type::Qualifiers tq, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
 
-	virtual OneType *clone() const { return new OneType( *this ); }
-	virtual void accept( Visitor & v ) { v.visit( this ); }
-	virtual Type *acceptMutator( Mutator & m ) { return m.mutate( this ); }
-	virtual void print( std::ostream & os, int indent = 0 ) const;
-};
-
-std::ostream & operator<<( std::ostream & out, const Type * type );
+	virtual OneType *clone() const override { return new OneType( *this ); }
+	virtual void accept( Visitor & v ) override { v.visit( this ); }
+	virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
+	virtual void print( std::ostream & os, int indent = 0 ) const override;
+};
 
 // Local Variables: //
Index: src/libcfa/concurrency/monitor
===================================================================
--- src/libcfa/concurrency/monitor	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/libcfa/concurrency/monitor	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -21,4 +21,9 @@
 #include "invoke.h"
 #include "stdlib"
+
+trait is_monitor(dtype T) {
+	monitor_desc * get_monitor( T & );
+	void ^?{}( T & mutex );
+};
 
 static inline void ?{}(monitor_desc & this) {
@@ -106,5 +111,5 @@
 };
 
-int __accept_internal( unsigned short count, __acceptable_t * acceptables );
+int __waitfor_internal( unsigned short count, __acceptable_t * acceptables, int duration );
 
 // Local Variables: //
Index: src/libcfa/concurrency/monitor.c
===================================================================
--- src/libcfa/concurrency/monitor.c	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/libcfa/concurrency/monitor.c	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -398,5 +398,5 @@
 //-----------------------------------------------------------------------------
 // Internal scheduling
-int __accept_internal( unsigned short acc_count, __acceptable_t * acceptables ) {
+int __waitfor_internal( unsigned short acc_count, __acceptable_t * acceptables ) {
 	thread_desc * thrd = this_thread;
 
Index: src/tests/.expect/sched-ext-parse.txt
===================================================================
--- src/tests/.expect/sched-ext-parse.txt	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
+++ src/tests/.expect/sched-ext-parse.txt	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -0,0 +1,18 @@
+/tmp/ccxbaJ5L.o: In function `__foo__F___1':
+/home/tdelisle/workspace/cforall/main/src/tests/sched-ext-parse.c:69: undefined reference to `__f1__F_MR2sM__1'
+/home/tdelisle/workspace/cforall/main/src/tests/sched-ext-parse.c:75: undefined reference to `____waitfor_internal__Fi_UsP15s__acceptable_ti__1'
+/home/tdelisle/workspace/cforall/main/src/tests/sched-ext-parse.c:91: undefined reference to `__f1__F_MR2sM__1'
+/home/tdelisle/workspace/cforall/main/src/tests/sched-ext-parse.c:97: undefined reference to `____waitfor_internal__Fi_UsP15s__acceptable_ti__1'
+/home/tdelisle/workspace/cforall/main/src/tests/sched-ext-parse.c:113: undefined reference to `__f2__F_MR2sM__1'
+/home/tdelisle/workspace/cforall/main/src/tests/sched-ext-parse.c:119: undefined reference to `____waitfor_internal__Fi_UsP15s__acceptable_ti__1'
+/home/tdelisle/workspace/cforall/main/src/tests/sched-ext-parse.c:135: undefined reference to `__f2__F_MR2sMMR2sM__1'
+/home/tdelisle/workspace/cforall/main/src/tests/sched-ext-parse.c:143: undefined reference to `____waitfor_internal__Fi_UsP15s__acceptable_ti__1'
+/home/tdelisle/workspace/cforall/main/src/tests/sched-ext-parse.c:164: undefined reference to `__f3__F_MR2sM__1'
+/home/tdelisle/workspace/cforall/main/src/tests/sched-ext-parse.c:172: undefined reference to `____waitfor_internal__Fi_UsP15s__acceptable_ti__1'
+/home/tdelisle/workspace/cforall/main/src/tests/sched-ext-parse.c:203: undefined reference to `____waitfor_internal__Fi_UsP15s__acceptable_ti__1'
+/home/tdelisle/workspace/cforall/main/src/tests/sched-ext-parse.c:245: undefined reference to `____waitfor_internal__Fi_UsP15s__acceptable_ti__1'
+/home/tdelisle/workspace/cforall/main/src/tests/sched-ext-parse.c:279: undefined reference to `__f1__F_MR2sM__1'
+/home/tdelisle/workspace/cforall/main/src/tests/sched-ext-parse.c:287: undefined reference to `____waitfor_internal__Fi_UsP15s__acceptable_ti__1'
+/home/tdelisle/workspace/cforall/main/src/tests/sched-ext-parse.c:321: undefined reference to `__f2__F_MR2sMMR2sM__1'
+/home/tdelisle/workspace/cforall/main/src/tests/sched-ext-parse.c:331: undefined reference to `____waitfor_internal__Fi_UsP15s__acceptable_ti__1'
+collect2: error: ld returned 1 exit status
Index: src/tests/sched-ext-parse.c
===================================================================
--- src/tests/sched-ext-parse.c	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/tests/sched-ext-parse.c	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -80,5 +80,5 @@
 		16;
 	}
- 	or waitfor( f1, a, a ) {
+ 	or waitfor( f2, a, a ) {
 		17;
 	}
Index: src/tests/sched-ext.c
===================================================================
--- src/tests/sched-ext.c	(revision 47b5b6376ade4e44d786f34c4ff34e1a3d2973c0)
+++ src/tests/sched-ext.c	(revision f980549499dd9f5a48208ae3e7a8b2fa305ddede)
@@ -45,5 +45,5 @@
 	acceptable.monitors      = &a;
 
-	__accept_internal( 1, &acceptable );
+	__waitfor_internal( 1, &acceptable );
 
 	sout | "Accepted" | endl;
