Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 3fb9a83871b00e72feca47d02062581a9d40610d)
+++ src/Common/PassVisitor.h	(revision 676cc8c10b531c20e738c19b145abe63e6b2dc9e)
@@ -220,13 +220,17 @@
 	void set_env( TypeSubstitution * env ) { set_env_impl( pass, env, 0); }
 
+	void visitStatementList( std::list< Statement* > &statements );
 	void mutateStatementList( std::list< Statement* > &statements );
+
+	Statement * visitStatement( Statement * stmt );
 	Statement * mutateStatement( Statement * stmt );
+
+	void visitExpression( Expression * expr );
 	Expression * mutateExpression( Expression * expr );
 
-private:
-	TypeSubstitution * env;
-
-	std::list< Statement* > stmtsToAdd;
-	std::list< Statement* > stmtsToAddAfter;
+
+	TypeSubstitution ** 		get_env_ptr    () { return env_impl             ( pass, 0); }
+	std::list< Statement* > * 	get_beforeStmts() { return stmtsToAddBefore_impl( pass, 0); }
+	std::list< Statement* > * 	get_afterStmts () { return stmtsToAddAfter_impl ( pass, 0); }
 };
 
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 3fb9a83871b00e72feca47d02062581a9d40610d)
+++ src/Common/PassVisitor.impl.h	(revision 676cc8c10b531c20e738c19b145abe63e6b2dc9e)
@@ -20,27 +20,74 @@
 	MUTATE_END( type, node );   \
 
+
+
+template<typename T>
+static inline bool empty( T * ptr ) {
+	return !ptr || ptr->empty();
+}
+
+typedef std::list< Statement * > StmtList_t;
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visitStatementList( std::list< Statement * > & statements ) {
+	SemanticError errors;
+
+	StmtList_t* beforeStmts = get_beforeStmts();
+	StmtList_t* afterStmts  = get_afterStmts();
+
+	for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
+		if ( !empty( afterStmts ) ) { statements.splice( i, *afterStmts ); }
+		try {
+			*i = (*i)->accept( *this );
+		} catch ( SemanticError &e ) {
+			errors.append( e );
+		}
+		if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); }
+	}
+
+	if ( !empty( afterStmts ) ) { statements.splice( statements.end(), *afterStmts ); }
+	if ( !errors.isEmpty() ) { throw errors; }
+}
+
 template< typename pass_type >
 void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
 	SemanticError errors;
 
+	StmtList_t* beforeStmts = get_beforeStmts();
+	StmtList_t* afterStmts  = get_afterStmts();
+
 	for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
-		if ( ! stmtsToAddAfter.empty() ) {
-			statements.splice( i, stmtsToAddAfter );
-		} // if
+		if ( !empty( afterStmts ) ) { statements.splice( i, *afterStmts ); }
 		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;
+		}
+		if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); }
 	}
+
+	if ( !empty( afterStmts ) ) { statements.splice( statements.end(), *afterStmts ); }
+	if ( !errors.isEmpty() ) { throw errors; }
+}
+
+template< typename pass_type >
+Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) {
+	// don't want statements from outer CompoundStmts to be added to this CompoundStmt
+	ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
+	ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
+	ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
+
+	Statement *newStmt = maybeVisit( stmt, *this );
+
+	StmtList_t* beforeStmts = get_beforeStmts();
+	StmtList_t* afterStmts  = get_afterStmts();
+
+	if( empty(beforeStmts) && empty(afterStmts) ) { return newStmt; }
+
+	CompoundStmt *compound = new CompoundStmt( noLabels );
+	if( !empty(beforeStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *beforeStmts ); }
+	compound->get_kids().push_back( newStmt );
+	if( !empty(afterStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *afterStmts ); }
+	return compound;
 }
 
@@ -48,23 +95,34 @@
 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 );
-	set_env( env );
-
-	stmtsToAdd.clear();
-	stmtsToAddAfter.clear();
+	ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
+	ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
+	ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
 
 	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;
+
+	StmtList_t* beforeStmts = get_beforeStmts();
+	StmtList_t* afterStmts  = get_afterStmts();
+
+	if( empty(beforeStmts) && empty(afterStmts) ) { return newStmt; }
+
+	CompoundStmt *compound = new CompoundStmt( noLabels );
+	if( !empty(beforeStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *beforeStmts ); }
+	compound->get_kids().push_back( newStmt );
+	if( !empty(afterStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *afterStmts ); }
+	return compound;
+}
+
+
+
+template< typename pass_type >
+void PassVisitor< pass_type >::visitExpression( Expression * expr ) {
+	if( !expr ) return;
+
+	auto env_ptr = get_env_ptr();
+	if ( env_ptr && expr->get_env() ) {
+		*env_ptr = expr->get_env();
 	}
+	// xxx - should env be cloned (or moved) onto the result of the mutate?
+	expr->accept( *this );
 }
 
@@ -73,7 +131,7 @@
 	if( !expr ) return nullptr;
 
-	if ( expr->get_env() ) {
-		env = expr->get_env();
-		set_env( env );
+	auto env_ptr = get_env_ptr();
+	if ( env_ptr && expr->get_env() ) {
+		*env_ptr = expr->get_env();
 	}
 	// xxx - should env be cloned (or moved) onto the result of the mutate?
@@ -488,15 +546,7 @@
 	
 	// 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 );
-	set_env( 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();
+	ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
+	ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
+	ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
 
 	Mutator::mutate( node );
Index: src/Common/PassVisitor.proto.h
===================================================================
--- src/Common/PassVisitor.proto.h	(revision 3fb9a83871b00e72feca47d02062581a9d40610d)
+++ src/Common/PassVisitor.proto.h	(revision 676cc8c10b531c20e738c19b145abe63e6b2dc9e)
@@ -70,10 +70,13 @@
 static inline void end_scope_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) {}
 
-// Env
-template<typename pass_type>
-static inline auto set_env_impl( pass_type& pass, TypeSubstitution * env, __attribute__((unused)) int unused ) ->decltype( pass.env, void() ) {
-	pass.env = env;
-}
+// Fields
+#define FIELD_PTR( type, name )                                                                                                                  \
+template<typename pass_type>                                                                                                                     \
+static inline auto name##_impl( pass_type& pass, __attribute__((unused)) int unused ) ->decltype( &pass.name ) { return &pass.name; }          \
+                                                                                                                                                 \
+template<typename pass_type>                                                                                                                     \
+static inline type * name##_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) { return nullptr;}    \
 
-template<typename pass_type>
-static inline void set_env_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) TypeSubstitution * env, __attribute__((unused)) long unused ) {}
+FIELD_PTR( TypeSubstitution *, env )
+FIELD_PTR( std::list< Statement* >, stmtsToAddBefore )
+FIELD_PTR( std::list< Statement* >, stmtsToAddAfter  )
Index: src/Common/utility.h
===================================================================
--- src/Common/utility.h	(revision 3fb9a83871b00e72feca47d02062581a9d40610d)
+++ src/Common/utility.h	(revision 676cc8c10b531c20e738c19b145abe63e6b2dc9e)
@@ -244,4 +244,24 @@
 	ValueGuard(T& inRef) : old(inRef), ref(inRef) {}
 	~ValueGuard() { ref = old; }
+};
+
+template< typename T >
+struct ValueGuardPtr {
+	T old;
+	T* ref;
+
+	ValueGuardPtr(T * inRef) : old( inRef ? *inRef : T() ), ref(inRef) {}
+	~ValueGuardPtr() { if( ref ) *ref = old; }
+};
+
+template< typename T >
+struct ValueGuardPtr< std::list< T > > {
+	std::list< T > old;
+	std::list< T >* ref;
+
+	ValueGuardPtr( std::list< T > * inRef) : old(), ref(inRef) {
+		if( ref ) { swap( *ref, old ); }
+	}
+	~ValueGuardPtr() { if( ref ) { swap( *ref, old ); } }
 };
 
