Index: src/ControlStruct/LabelFixer.cc
===================================================================
--- src/ControlStruct/LabelFixer.cc	(revision 5da9d6a0b5aca7b7b61248b2cd7b794246f1c933)
+++ src/ControlStruct/LabelFixer.cc	(revision f240484f7d94bba0a956c3c0eb848259db6be7ff)
@@ -44,5 +44,5 @@
 
 	void LabelFixer::postvisit( FunctionDecl * functionDecl ) {
-		MLEMutator mlemut( resolveJumps(), generator );
+		PassVisitor<MLEMutator> mlemut( resolveJumps(), generator );
 		functionDecl->acceptMutator( mlemut );
 	}
Index: src/ControlStruct/MLEMutator.cc
===================================================================
--- src/ControlStruct/MLEMutator.cc	(revision 5da9d6a0b5aca7b7b61248b2cd7b794246f1c933)
+++ src/ControlStruct/MLEMutator.cc	(revision f240484f7d94bba0a956c3c0eb848259db6be7ff)
@@ -46,5 +46,5 @@
 	void MLEMutator::fixBlock( std::list< Statement * > &kids ) {
 		for ( std::list< Statement * >::iterator k = kids.begin(); k != kids.end(); k++ ) {
-			*k = (*k)->acceptMutator(*this);
+			*k = (*k)->acceptMutator(*visitor);
 
 			if ( ! get_breakLabel().empty() ) {
@@ -57,6 +57,7 @@
 	}
 
-	CompoundStmt* MLEMutator::mutate( CompoundStmt *cmpndStmt ) {
-		bool labeledBlock = !(cmpndStmt->get_labels().empty());
+	void MLEMutator::premutate( CompoundStmt *cmpndStmt ) {
+		visit_children = false;
+		bool labeledBlock = !(cmpndStmt->labels.empty());
 		if ( labeledBlock ) {
 			Label brkLabel = generator->newLabel("blockBreak", cmpndStmt);
@@ -65,5 +66,5 @@
 
 		// a child statement may set the break label - if they do, attach it to the next statement
-		std::list< Statement * > &kids = cmpndStmt->get_kids();
+		std::list< Statement * > &kids = cmpndStmt->kids;
 		fixBlock( kids );
 
@@ -75,88 +76,6 @@
 			enclosingControlStructures.pop_back();
 		} // if
-
-		return cmpndStmt;
-	}
-
-	template< typename LoopClass >
-	Statement *MLEMutator::handleLoopStmt( LoopClass *loopStmt ) {
-		// remember this as the most recent enclosing loop, then mutate the body of the loop -- this will determine
-		// whether brkLabel and contLabel are used with branch statements and will recursively do the same to nested
-		// loops
-		Label brkLabel = generator->newLabel("loopBreak", loopStmt);
-		Label contLabel = generator->newLabel("loopContinue", loopStmt);
-		enclosingControlStructures.push_back( Entry( loopStmt, brkLabel, contLabel ) );
-		loopStmt->set_body ( loopStmt->get_body()->acceptMutator( *this ) );
-
-		assert( ! enclosingControlStructures.empty() );
-		Entry &e = enclosingControlStructures.back();
-		// sanity check that the enclosing loops have been popped correctly
-		assert ( e == loopStmt );
-
-		// this will take the necessary steps to add definitions of the previous two labels, if they are used.
-		loopStmt->set_body( mutateLoop( loopStmt->get_body(), e ) );
-		enclosingControlStructures.pop_back();
-
-		return loopStmt;
-	}
-
-	Statement *MLEMutator::mutate( CaseStmt *caseStmt ) {
-		caseStmt->set_condition( maybeMutate( caseStmt->get_condition(), *this ) );
-		fixBlock( caseStmt->get_statements() );
-
-		return caseStmt;
-	}
-
-	template< typename IfClass >
-	Statement *MLEMutator::handleIfStmt( IfClass *ifStmt ) {
-		// generate a label for breaking out of a labeled if
-		bool labeledBlock = !(ifStmt->get_labels().empty());
-		if ( labeledBlock ) {
-			Label brkLabel = generator->newLabel("blockBreak", ifStmt);
-			enclosingControlStructures.push_back( Entry( ifStmt, brkLabel ) );
-		} // if
-
-		Parent::mutate( ifStmt );
-
-		if ( labeledBlock ) {
-			if ( ! enclosingControlStructures.back().useBreakExit().empty() ) {
-				set_breakLabel( enclosingControlStructures.back().useBreakExit() );
-			} // if
-			enclosingControlStructures.pop_back();
-		} // if
-		return ifStmt;
-	}
-
-	template< typename SwitchClass >
-	Statement *MLEMutator::handleSwitchStmt( SwitchClass *switchStmt ) {
-		// generate a label for breaking out of a labeled switch
-		Label brkLabel = generator->newLabel("switchBreak", switchStmt);
-		enclosingControlStructures.push_back( Entry(switchStmt, brkLabel) );
-		mutateAll( switchStmt->get_statements(), *this );
-
-		Entry &e = enclosingControlStructures.back();
-		assert ( e == switchStmt );
-
-		// only generate break label if labeled break is used
-		if ( e.isBreakUsed() ) {
-			// for the purposes of keeping switch statements uniform (i.e. all statements that are direct children of a
-			// switch should be CastStmts), append the exit label + break to the last case statement; create a default
-			// case if there are no cases
-			std::list< Statement * > &statements = switchStmt->get_statements();
-			if ( statements.empty() ) {
-				statements.push_back( CaseStmt::makeDefault() );
-			} // if
-
-			if ( CaseStmt * c = dynamic_cast< CaseStmt * >( statements.back() ) ) {
-				Statement * stmt = new BranchStmt( Label("brkLabel"), BranchStmt::Break );
-				stmt->labels.push_back( brkLabel );
-				c->get_statements().push_back( stmt );
-			} else assert(0); // as of this point, all statements of a switch are still CaseStmts
-		} // if
-
-		assert ( enclosingControlStructures.back() == switchStmt );
-		enclosingControlStructures.pop_back();
-		return switchStmt;
-	}
+	}
+
 
 	void addUnused( Statement * stmt, const Label & originalTarget ) {
@@ -179,6 +98,6 @@
 
 
-	Statement *MLEMutator::mutate( BranchStmt *branchStmt ) throw ( SemanticError ) {
-		std::string originalTarget = branchStmt->get_originalTarget();
+	Statement *MLEMutator::postmutate( BranchStmt *branchStmt ) throw ( SemanticError ) {
+		std::string originalTarget = branchStmt->originalTarget;
 
 		std::list< Entry >::reverse_iterator targetEntry;
@@ -215,5 +134,5 @@
 		// branch error checks, get the appropriate label name and create a goto
 		Label exitLabel;
-		switch ( branchStmt->get_type() ) {
+		switch ( branchStmt->type ) {
 		  case BranchStmt::Break:
 				assert( targetEntry->useBreakExit() != "");
@@ -229,5 +148,5 @@
 
 		// add unused attribute to label to silence warnings
-		addUnused( targetEntry->get_controlStructure(), branchStmt->get_originalTarget() );
+		addUnused( targetEntry->get_controlStructure(), branchStmt->originalTarget );
 
 		// transform break/continue statements into goto to simplify later handling of branches
@@ -260,18 +179,99 @@
 	}
 
-	Statement *MLEMutator::mutate( WhileStmt *whileStmt ) {
-		return handleLoopStmt( whileStmt );
-	}
-
-	Statement *MLEMutator::mutate( ForStmt *forStmt ) {
-		return handleLoopStmt( forStmt );
-	}
-
-	Statement *MLEMutator::mutate( IfStmt *ifStmt ) {
-		return handleIfStmt( ifStmt );
-	}
-
-	Statement *MLEMutator::mutate( SwitchStmt *switchStmt ) {
-		return handleSwitchStmt( switchStmt );
+	template< typename LoopClass >
+	void MLEMutator::prehandleLoopStmt( LoopClass * loopStmt ) {
+		// remember this as the most recent enclosing loop, then mutate the body of the loop -- this will determine
+		// whether brkLabel and contLabel are used with branch statements and will recursively do the same to nested
+		// loops
+		Label brkLabel = generator->newLabel("loopBreak", loopStmt);
+		Label contLabel = generator->newLabel("loopContinue", loopStmt);
+		enclosingControlStructures.push_back( Entry( loopStmt, brkLabel, contLabel ) );
+	}
+
+	template< typename LoopClass >
+	Statement * MLEMutator::posthandleLoopStmt( LoopClass * loopStmt ) {
+		assert( ! enclosingControlStructures.empty() );
+		Entry &e = enclosingControlStructures.back();
+		// sanity check that the enclosing loops have been popped correctly
+		assert ( e == loopStmt );
+
+		// this will take the necessary steps to add definitions of the previous two labels, if they are used.
+		loopStmt->set_body( mutateLoop( loopStmt->get_body(), e ) );
+		enclosingControlStructures.pop_back();
+		return loopStmt;
+	}
+
+	void MLEMutator::premutate( WhileStmt * whileStmt ) {
+		return prehandleLoopStmt( whileStmt );
+	}
+
+	void MLEMutator::premutate( ForStmt * forStmt ) {
+		return prehandleLoopStmt( forStmt );
+	}
+
+	Statement * MLEMutator::postmutate( WhileStmt * whileStmt ) {
+		return posthandleLoopStmt( whileStmt );
+	}
+
+	Statement * MLEMutator::postmutate( ForStmt * forStmt ) {
+		return posthandleLoopStmt( forStmt );
+	}
+
+	void MLEMutator::premutate( IfStmt * ifStmt ) {
+		// generate a label for breaking out of a labeled if
+		bool labeledBlock = !(ifStmt->get_labels().empty());
+		if ( labeledBlock ) {
+			Label brkLabel = generator->newLabel("blockBreak", ifStmt);
+			enclosingControlStructures.push_back( Entry( ifStmt, brkLabel ) );
+		} // if
+	}
+
+	Statement * MLEMutator::postmutate( IfStmt * ifStmt ) {
+		bool labeledBlock = !(ifStmt->get_labels().empty());
+		if ( labeledBlock ) {
+			if ( ! enclosingControlStructures.back().useBreakExit().empty() ) {
+				set_breakLabel( enclosingControlStructures.back().useBreakExit() );
+			} // if
+			enclosingControlStructures.pop_back();
+		} // if
+		return ifStmt;
+	}
+
+	void MLEMutator::premutate( CaseStmt *caseStmt ) {
+		visit_children = false;
+		caseStmt->condition = maybeMutate( caseStmt->condition, *visitor );
+		fixBlock( caseStmt->stmts );
+	}
+
+	void MLEMutator::premutate( SwitchStmt *switchStmt ) {
+		// generate a label for breaking out of a labeled switch
+		Label brkLabel = generator->newLabel("switchBreak", switchStmt);
+		enclosingControlStructures.push_back( Entry(switchStmt, brkLabel) );
+	}
+
+	Statement * MLEMutator::postmutate( SwitchStmt * switchStmt ) {
+		Entry &e = enclosingControlStructures.back();
+		assert ( e == switchStmt );
+
+		// only generate break label if labeled break is used
+		if ( e.isBreakUsed() ) {
+			// for the purposes of keeping switch statements uniform (i.e. all statements that are direct children of a
+			// switch should be CastStmts), append the exit label + break to the last case statement; create a default
+			// case if there are no cases
+			std::list< Statement * > &statements = switchStmt->statements;
+			if ( statements.empty() ) {
+				statements.push_back( CaseStmt::makeDefault() );
+			} // if
+
+			if ( CaseStmt * c = dynamic_cast< CaseStmt * >( statements.back() ) ) {
+				Statement * stmt = new BranchStmt( Label("brkLabel"), BranchStmt::Break );
+				stmt->labels.push_back( e.useBreakExit() );
+				c->stmts.push_back( stmt );
+			} else assert(0); // as of this point, all statements of a switch are still CaseStmts
+		} // if
+
+		assert ( enclosingControlStructures.back() == switchStmt );
+		enclosingControlStructures.pop_back();
+		return switchStmt;
 	}
 } // namespace ControlStruct
Index: src/ControlStruct/MLEMutator.h
===================================================================
--- src/ControlStruct/MLEMutator.h	(revision 5da9d6a0b5aca7b7b61248b2cd7b794246f1c933)
+++ src/ControlStruct/MLEMutator.h	(revision f240484f7d94bba0a956c3c0eb848259db6be7ff)
@@ -20,4 +20,5 @@
 #include <string>                  // for string
 
+#include "Common/PassVisitor.h"
 #include "Common/SemanticError.h"  // for SemanticError
 #include "SynTree/Label.h"         // for Label
@@ -26,21 +27,24 @@
 
 namespace ControlStruct {
-class LabelGenerator;
+	class LabelGenerator;
 
-	class MLEMutator : public Mutator {
+	class MLEMutator : public WithVisitorRef<MLEMutator>, public WithShortCircuiting {
 		class Entry;
 
-		typedef Mutator Parent;
 	  public:
 		MLEMutator( std::map<Label, Statement *> *t, LabelGenerator *gen = 0 ) : targetTable( t ), breakLabel(std::string("")), generator( gen ) {}
 		~MLEMutator();
 
-		virtual CompoundStmt *mutate( CompoundStmt *cmpndStmt ) override;
-		virtual Statement *mutate( WhileStmt *whileStmt ) override;
-		virtual Statement *mutate( ForStmt *forStmt ) override;
-		virtual Statement *mutate( BranchStmt *branchStmt ) throw ( SemanticError ) override;
-		virtual Statement *mutate( CaseStmt *caseStmt ) override;
-		virtual Statement *mutate( IfStmt *ifStmt ) override;
-		virtual Statement *mutate( SwitchStmt *switchStmt ) override;
+		void premutate( CompoundStmt *cmpndStmt );
+		Statement * postmutate( BranchStmt *branchStmt ) throw ( SemanticError );
+		void premutate( WhileStmt *whileStmt );
+		Statement * postmutate( WhileStmt *whileStmt );
+		void premutate( ForStmt *forStmt );
+		Statement * postmutate( ForStmt *forStmt );
+		void premutate( CaseStmt *caseStmt );
+		void premutate( IfStmt *ifStmt );
+		Statement * postmutate( IfStmt *ifStmt );
+		void premutate( SwitchStmt *switchStmt );
+		Statement * postmutate( SwitchStmt *switchStmt );
 
 		Statement *mutateLoop( Statement *bodyLoop, Entry &e );
@@ -54,8 +58,8 @@
 				loop( _loop ), breakExit( _breakExit ), contExit( _contExit ), breakUsed(false), contUsed(false) {}
 
-			bool operator==( const Statement *stmt ) { return ( loop == stmt ); }
-			bool operator!=( const Statement *stmt ) { return ( loop != stmt ); }
+			bool operator==( const Statement *stmt ) { return loop == stmt; }
+			bool operator!=( const Statement *stmt ) { return loop != stmt; }
 
-			bool operator==( const Entry &other ) { return ( loop == other.get_controlStructure() ); }
+			bool operator==( const Entry &other ) { return loop == other.get_controlStructure(); }
 
 			Statement *get_controlStructure() const { return loop; }
@@ -78,11 +82,8 @@
 
 		template< typename LoopClass >
-		Statement *handleLoopStmt( LoopClass *loopStmt );
+		void prehandleLoopStmt( LoopClass * loopStmt );
 
-		template< typename IfClass >
-		Statement *handleIfStmt( IfClass *switchStmt );
-
-		template< typename SwitchClass >
-		Statement *handleSwitchStmt( SwitchClass *switchStmt );
+		template< typename LoopClass >
+		Statement * posthandleLoopStmt( LoopClass * loopStmt );
 
 		void fixBlock( std::list< Statement * > &kids );
