Index: src/ControlStruct/MLEMutator.cc
===================================================================
--- src/ControlStruct/MLEMutator.cc	(revision ba3706fcc236a2f6c927dc1a9da14313751a7aa4)
+++ src/ControlStruct/MLEMutator.cc	(revision 1449d83d58f534d045be59bb9bcd5ecab96c5519)
@@ -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
