Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision ab904dc2d88885a200b84e36078cc551c9a2472f)
+++ src/Common/PassVisitor.h	(revision 296b2be7a18b667ebf2c07a42e6925eddfa07c77)
@@ -1,3 +1,5 @@
 #pragma once
+
+#include <stack>
 
 #include "SynTree/Mutator.h"
@@ -11,54 +13,5 @@
 #include "SynTree/Constant.h"
 
-//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-// Deep magic (a.k.a template meta programming) to make the templated visitor work
-// Basically the goal is to make 2 previsit_impl
-// 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of 
-//     'pass.previsit( node )' that compiles will be used for that node for that type
-//     This requires that this option only compile for passes that actually define an appropriate visit.
-//     SFINAE will make sure the compilation errors in this function don't halt the build.
-//     See http://en.cppreference.com/w/cpp/language/sfinae for details on SFINAE
-// 2 - Since the first implementation might not be specilizable, the second implementation exists and does nothing.
-//     This is needed only to eliminate the need for passes to specify any kind of handlers.
-//     The second implementation only works because it has a lower priority. This is due to the bogus last parameter.
-//     The second implementation takes a long while the first takes an int. Since the caller always passes an literal 0
-//     the first implementation takes priority in regards to overloading.
-// Mutator functions work along the same principal
-//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-// Visit
-template<typename pass_type, typename node_type>
-static inline auto previsit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.previsit( node ), void() ) {
-	pass.previsit( node );
-}
-
-template<typename pass_type, typename node_type>
-static inline void previsit_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) {}
-
-
-template<typename pass_type, typename node_type>
-static inline auto postvisit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.postvisit( node ), void() ) {
-	pass.postvisit( node );
-}
-
-template<typename pass_type, typename node_type>
-static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) {}
-
-// Mutate
-template<typename pass_type, typename node_type>
-static inline auto premutate_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.premutate( node ), void() ) {
-	return pass.premutate( node );
-}
-
-template<typename pass_type, typename node_type>
-static inline void premutate_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) {}
-
-
-template<typename return_type, typename pass_type, typename node_type>
-static inline auto postmutate_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.postmutate( node ) ) {
-	return pass.postmutate( node );
-}
-
-template<typename return_type, typename pass_type, typename node_type>
-static inline return_type postmutate_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) { return node; }
+#include "PassVisitor.proto.h"
 
 //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -256,31 +209,22 @@
 
 private:
-	template<typename node_type> 
-	auto call_previsit ( node_type * node ) 
-		-> decltype( previsit_impl ( pass, node, 0 ), void() ) 
-	{ 
-		previsit_impl ( pass, node, 0 ); 
-	}
-
-	template<typename node_type> 
-	auto call_postvisit( node_type * node )
-		-> decltype( postvisit_impl( pass, node, 0 ), void() ) 
-	{ 
-		postvisit_impl( pass, node, 0 ); 
-	}
-
-	template<typename node_type>
-	auto call_premutate ( node_type * node )
-		-> decltype( premutate_impl( pass, node, 0 ), void() )
-	{
-		premutate_impl( pass, node, 0 );
-	}
-
-	template<typename return_type, typename node_type>
-	auto call_postmutate ( node_type * node )
-		-> decltype( postmutate_impl<return_type>( pass, node, 0 ) )
-	{
-		return postmutate_impl<return_type>( pass, node, 0 );
-	}
+	template<typename node_type> void call_previsit ( node_type * node ) { previsit_impl ( pass, node, 0 ); }
+	template<typename node_type> void call_postvisit( node_type * node ) { postvisit_impl( pass, node, 0 ); }
+
+	template<typename node_type> void call_premutate ( node_type * node ) { premutate_impl( pass, node, 0 ); }
+	template<typename return_type, typename node_type> return_type call_postmutate ( node_type * node ) { return postmutate_impl<return_type>( pass, node, 0 ); }
+
+	void call_beginScope() { begin_scope_impl( pass, 0 ); }
+	void call_endScope  () { end_scope_impl  ( pass, 0 ); }
+
+	void mutateStatementList( std::list< Statement* > &statements );
+	Statement * mutateStatement( Statement * stmt );
+	Expression * mutateExpression( Expression * expr );
+
+private:
+	TypeSubstitution * env;
+
+	std::list< Statement* > stmtsToAdd;
+	std::list< Statement* > stmtsToAddAfter;
 };
 
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision ab904dc2d88885a200b84e36078cc551c9a2472f)
+++ src/Common/PassVisitor.impl.h	(revision 296b2be7a18b667ebf2c07a42e6925eddfa07c77)
@@ -1,3 +1,11 @@
 #pragma once
+
+#define MUTATE_START( node )  \
+	call_premutate( node ); \
+
+
+#define MUTATE_END( type, node )                \
+	return call_postmutate< type * >( node ); \
+
 
 #define VISIT_BODY( node )    \
@@ -6,12 +14,70 @@
 	call_postvisit( node ); \
 
-#define MUTATE_BODY( type, node )                   \
-	call_premutate( node );                       \
-	Mutator::mutate( node );                      \
-	auto ret = call_postmutate< type * >( node ); \
-	return ret;                                   \
-
-
-
+
+#define MUTATE_BODY( type, node ) \
+	MUTATE_START( node );       \
+	Mutator::mutate( node );    \
+	MUTATE_END( type, node );   \
+
+template< typename pass_type >
+void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
+	SemanticError errors;
+
+	for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
+		if ( ! stmtsToAddAfter.empty() ) {
+			statements.splice( i, stmtsToAddAfter );
+		} // if
+		try {
+			*i = (*i)->acceptMutator( *this );
+		} catch ( SemanticError &e ) {
+			errors.append( e );
+		} // try
+		if ( ! stmtsToAdd.empty() ) {
+			statements.splice( i, stmtsToAdd );
+		} // if
+	} // for
+	if ( ! stmtsToAddAfter.empty() ) {
+		statements.splice( statements.end(), stmtsToAddAfter );
+	} // if
+	if ( ! errors.isEmpty() ) {
+		throw errors;
+	}
+}
+
+template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) {
+	// don't want statements from outer CompoundStmts to be added to this CompoundStmt
+	ValueGuard< std::list< Statement* > > oldStmtsToAdd( stmtsToAdd );
+	ValueGuard< std::list< Statement* > > oldStmtsToAddAfter( stmtsToAddAfter );
+	ValueGuard< TypeSubstitution * > oldEnv( env );
+	stmtsToAdd.clear();
+	stmtsToAddAfter.clear();
+
+	Statement *newStmt = maybeMutate( stmt, *this );
+	if ( ! stmtsToAdd.empty() || ! stmtsToAddAfter.empty() ) {
+		CompoundStmt *compound = new CompoundStmt( noLabels );
+		compound->get_kids().splice( compound->get_kids().end(), stmtsToAdd );
+		compound->get_kids().push_back( newStmt );
+		compound->get_kids().splice( compound->get_kids().end(), stmtsToAddAfter );
+		// doEndScope();
+		return compound;
+	} else {
+		return newStmt;
+	}
+}
+
+template< typename pass_type >
+Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) {
+	if( !expr ) return nullptr;
+
+	if ( expr->get_env() ) {
+		env = expr->get_env();
+	}
+	// xxx - should env be cloned (or moved) onto the result of the mutate?
+	return expr->acceptMutator( *this );
+}
+
+
+//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
 template< typename pass_type >
@@ -66,4 +132,15 @@
 
 template< typename pass_type >
+CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) {
+	MUTATE_START( node );
+	call_beginScope();
+
+	mutateStatementList( node->get_kids() );
+
+	call_endScope();
+	MUTATE_END( CompoundStmt, node );
+}
+
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( ExprStmt * node ) {
 	VISIT_BODY( node ); 
@@ -71,4 +148,13 @@
 
 template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) {
+	MUTATE_START( node );
+
+	node->set_expr( mutateExpression( node->get_expr() ) );
+
+	MUTATE_END( Statement, node );
+}
+
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( AsmStmt * node ) {
 	VISIT_BODY( node ); 
@@ -81,4 +167,15 @@
 
 template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
+	MUTATE_START( node ); 
+
+	node->set_condition( mutateExpression( node->get_condition() ) );
+	node->set_thenPart ( mutateStatement ( node->get_thenPart()  ) );
+	node->set_elsePart ( mutateStatement ( node->get_elsePart()  ) );
+
+	MUTATE_END( Statement, node );
+}
+
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( WhileStmt * node ) {
 	VISIT_BODY( node ); 
@@ -86,4 +183,15 @@
 
 template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( WhileStmt * node ) {
+	MUTATE_START( node ); 
+
+	node->set_condition( mutateExpression( node->get_condition() ) );
+	node->set_body( mutateStatement( node->get_body() ) );
+
+	MUTATE_END( Statement, node );
+}
+
+
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( ForStmt * node ) {
 	VISIT_BODY( node ); 
@@ -91,4 +199,16 @@
 
 template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
+	MUTATE_START( node ); 
+
+	mutateAll( node->get_initialization(), *this );
+	node->set_condition(  mutateExpression( node->get_condition() ) );
+	node->set_increment(  mutateExpression( node->get_increment() ) );
+	node->set_body(  mutateStatement( node->get_body() ) );
+
+	MUTATE_END( Statement, node );
+}
+
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( SwitchStmt * node ) {
 	VISIT_BODY( node ); 
@@ -96,4 +216,14 @@
 
 template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {
+	MUTATE_START( node ); 
+	
+	node->set_condition( mutateExpression( node->get_condition() ) );
+	mutateStatementList( node->get_statements() );
+	
+	MUTATE_END( Statement, node );
+}
+
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( CaseStmt * node ) {
 	VISIT_BODY( node ); 
@@ -101,4 +231,14 @@
 
 template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {
+	MUTATE_START( node ); 
+	
+	node->set_condition(  mutateExpression( node->get_condition() ) );
+	mutateStatementList( node->get_statements() );
+	
+	MUTATE_END( Statement, node );
+}
+
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( BranchStmt * node ) {
 	VISIT_BODY( node ); 
@@ -111,4 +251,13 @@
 
 template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) {
+	MUTATE_START( node );
+
+	node->set_expr( mutateExpression( node->get_expr() ) );
+
+	MUTATE_END( Statement, node );
+}
+
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( TryStmt * node ) {
 	VISIT_BODY( node ); 
@@ -116,4 +265,14 @@
 
 template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( TryStmt * node ) {
+	MUTATE_START( node );
+
+	node->set_block(  maybeMutate( node->get_block(), *this ) );
+	mutateAll( node->get_catchers(), *this );
+	
+	MUTATE_END( Statement, node );
+}
+
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( CatchStmt * node ) {
 	VISIT_BODY( node ); 
@@ -121,4 +280,14 @@
 
 template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
+	MUTATE_START( node );
+	
+	node->set_body(  mutateStatement( node->get_body() ) );
+	node->set_decl(  maybeMutate( node->get_decl(), *this ) );
+	
+	MUTATE_END( Statement, node );
+}
+
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( FinallyStmt * node ) {
 	VISIT_BODY( node ); 
@@ -151,4 +320,15 @@
 
 template< typename pass_type >
+Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
+	MUTATE_START( node );
+
+	for ( auto& expr : node->get_args() ) {
+		expr = mutateExpression( expr );
+	}
+
+	MUTATE_END( Expression, node );
+}
+
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( NameExpr * node ) {
 	VISIT_BODY( node ); 
@@ -301,4 +481,25 @@
 
 template< typename pass_type >
+Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
+	MUTATE_START( node );
+	
+	// don't want statements from outer CompoundStmts to be added to this StmtExpr
+	ValueGuard< std::list< Statement* > > oldStmtsToAdd( stmtsToAdd );
+	ValueGuard< std::list< Statement* > > oldStmtsToAddAfter( stmtsToAddAfter );
+	ValueGuard< TypeSubstitution * > oldEnv( env );
+
+	// xxx - not sure if this is needed, along with appropriate reset, but I don't think so...
+	// ValueGuard< TyVarMap > oldScopeTyVars( scopeTyVars );
+
+	stmtsToAdd.clear();
+	stmtsToAddAfter.clear();
+	// scopeTyVars.clear();
+
+	Mutator::mutate( node );
+
+	MUTATE_END( Expression, node );
+}
+
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( UniqueExpr * node ) {
 	VISIT_BODY( node ); 
@@ -388,4 +589,13 @@
 void PassVisitor< pass_type >::visit( SingleInit * node ) {
 	VISIT_BODY( node ); 
+}
+
+template< typename pass_type >
+Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) {
+	MUTATE_START( node );
+
+	node->set_value( mutateExpression( node->get_value() ) );
+
+	MUTATE_END( Initializer, node );
 }
 
@@ -458,14 +668,4 @@
 
 template< typename pass_type >
-CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) {
-	MUTATE_BODY( CompoundStmt, node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) {
-	MUTATE_BODY( Statement, node );
-}
-
-template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
 	MUTATE_BODY( Statement, node );
@@ -473,29 +673,4 @@
 
 template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
-	MUTATE_BODY( Statement, node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( WhileStmt * node ) {
-	MUTATE_BODY( Statement, node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
-	MUTATE_BODY( Statement, node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {
-	MUTATE_BODY( Statement, node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {
-	MUTATE_BODY( Statement, node );
-}
-
-template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) {
 	MUTATE_BODY( Statement, node );
@@ -503,19 +678,4 @@
 
 template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) {
-	MUTATE_BODY( Statement, node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( TryStmt * node ) {
-	MUTATE_BODY( Statement, node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
-	MUTATE_BODY( Statement, node );
-}
-
-template< typename pass_type >
 Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
 	MUTATE_BODY( Statement, node );
@@ -543,9 +703,4 @@
 
 template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
-	MUTATE_BODY( Expression, node );
-}
-
-template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
 	MUTATE_BODY( Expression, node );
@@ -693,9 +848,4 @@
 
 template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
-	MUTATE_BODY( Expression, node );
-}
-
-template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) {
 	MUTATE_BODY( Expression, node );
@@ -780,9 +930,4 @@
 Type * PassVisitor< pass_type >::mutate( OneType * node ) {
 	MUTATE_BODY( Type, node );
-}
-
-template< typename pass_type >
-Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) {
-	MUTATE_BODY( Initializer, node );
 }
 
Index: src/Common/PassVisitor.proto.h
===================================================================
--- src/Common/PassVisitor.proto.h	(revision 296b2be7a18b667ebf2c07a42e6925eddfa07c77)
+++ src/Common/PassVisitor.proto.h	(revision 296b2be7a18b667ebf2c07a42e6925eddfa07c77)
@@ -0,0 +1,70 @@
+#pragma once
+
+//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+// Deep magic (a.k.a template meta programming) to make the templated visitor work
+// Basically the goal is to make 2 previsit_impl
+// 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of 
+//     'pass.previsit( node )' that compiles will be used for that node for that type
+//     This requires that this option only compile for passes that actually define an appropriate visit.
+//     SFINAE will make sure the compilation errors in this function don't halt the build.
+//     See http://en.cppreference.com/w/cpp/language/sfinae for details on SFINAE
+// 2 - Since the first implementation might not be specilizable, the second implementation exists and does nothing.
+//     This is needed only to eliminate the need for passes to specify any kind of handlers.
+//     The second implementation only works because it has a lower priority. This is due to the bogus last parameter.
+//     The second implementation takes a long while the first takes an int. Since the caller always passes an literal 0
+//     the first implementation takes priority in regards to overloading.
+// Mutator functions work along the same principal
+//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+// Visit
+template<typename pass_type, typename node_type>
+static inline auto previsit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.previsit( node ), void() ) {
+	pass.previsit( node );
+}
+
+template<typename pass_type, typename node_type>
+static inline void previsit_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) {}
+
+
+template<typename pass_type, typename node_type>
+static inline auto postvisit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.postvisit( node ), void() ) {
+	pass.postvisit( node );
+}
+
+template<typename pass_type, typename node_type>
+static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) {}
+
+// Mutate
+template<typename pass_type, typename node_type>
+static inline auto premutate_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.premutate( node ), void() ) {
+	return pass.premutate( node );
+}
+
+template<typename pass_type, typename node_type>
+static inline void premutate_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) {}
+
+
+template<typename return_type, typename pass_type, typename node_type>
+static inline auto postmutate_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.postmutate( node ) ) {
+	return pass.postmutate( node );
+}
+
+template<typename return_type, typename pass_type, typename node_type>
+static inline return_type postmutate_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) { return node; }
+
+// Begin/End scope
+template<typename pass_type>
+static inline auto begin_scope_impl( pass_type& pass, __attribute__((unused)) int unused ) ->decltype( pass.beginScope(), void() ) {
+	pass.beginScope();
+}
+
+template<typename pass_type>
+static inline void begin_scope_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) {}
+
+
+template<typename pass_type>
+static inline auto end_scope_impl( pass_type& pass, __attribute__((unused)) int unused ) ->decltype( pass.endScope(), void() ) {
+	pass.endScope();
+}
+
+template<typename pass_type>
+static inline void end_scope_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) {}
