Index: src/AST/Pass.hpp
===================================================================
--- src/AST/Pass.hpp	(revision 1a4323ef209668602a57f374c8cbda3c31f45452)
+++ src/AST/Pass.hpp	(revision 2b59f556da930033369d1ca9b86be75a4b277ff7)
@@ -201,4 +201,5 @@
 	container_t< ptr<node_t> > call_accept( const container_t< ptr<node_t> > & container );
 
+public:
 	/// Logic to call the accept and mutate the parent if needed, delegates call to accept
 	template<typename node_t, typename parent_t, typename child_t>
Index: src/ResolvExpr/CurrentObject.cc
===================================================================
--- src/ResolvExpr/CurrentObject.cc	(revision 1a4323ef209668602a57f374c8cbda3c31f45452)
+++ src/ResolvExpr/CurrentObject.cc	(revision 2b59f556da930033369d1ca9b86be75a4b277ff7)
@@ -20,4 +20,7 @@
 #include <string>                      // for string, operator<<, allocator
 
+#include "AST/Expr.hpp"                // for InitAlternative
+#include "AST/Init.hpp"                // for Designation
+#include "AST/Node.hpp"                // for readonly
 #include "Common/Indenter.h"           // for Indenter, operator<<
 #include "Common/SemanticError.h"      // for SemanticError
@@ -585,18 +588,40 @@
 	public:
 		virtual ~MemberIterator() {}
+
+		/// retrieve the list of possible (Type,Designation) pairs for the current position in the 
+		/// current object
+		virtual std::vector< InitAlternative > operator* () const = 0;
+	
+	protected:
+		/// helper for operator*; aggregates must add designator to each init alternative, but 
+		/// adding designators in operator* creates duplicates
+		virtual std::vector< InitAlternative > first() const = 0;
 	};
 
 	/// Iterates "other" types (e.g. basic, pointer) which do not change at list initializer entry
 	class SimpleIterator final : public MemberIterator {
-		const Type * type = nullptr;
-	public:
-		SimpleIterator( const Type * t ) : type( t ) {}
-	};
-
-	CurrentObject::CurrentObject( const ast::Type * type ) : objStack() {
-		objStack.emplace_back( new SimpleIterator{ type } );
-	}
-
-	#warning ast::CurrentObject port incomplete
+		CodeLocation location;
+		readonly< Type > type = nullptr;
+	public:
+		SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {}
+
+		std::vector< InitAlternative > operator* () const override { return first(); }
+
+	protected:
+		std::vector< InitAlternative > first() const override {
+			if ( type ) return { InitAlternative{ type, new Designation{ location } } };
+			return {};
+		}
+	};
+
+	CurrentObject::CurrentObject( const CodeLocation & loc, const Type * type ) : objStack() {
+		objStack.emplace_back( new SimpleIterator{ loc, type } );
+	}
+
+	std::vector< InitAlternative > CurrentObject::getOptions() {
+		PRINT( std::cerr << "____getting current options" << std::endl; )
+		assertf( ! objStack.empty(), "objstack empty in getOptions" );
+		return **objStack.back();
+	}
 }
 
Index: src/ResolvExpr/CurrentObject.h
===================================================================
--- src/ResolvExpr/CurrentObject.h	(revision 1a4323ef209668602a57f374c8cbda3c31f45452)
+++ src/ResolvExpr/CurrentObject.h	(revision 2b59f556da930033369d1ca9b86be75a4b277ff7)
@@ -20,4 +20,6 @@
 #include <stack>  // for stack
 #include <vector>
+
+#include "Common/CodeLocation.h"
 
 class Designation;
@@ -69,5 +71,9 @@
 	public:
 		CurrentObject() = default;
-		CurrentObject( const Type * type );
+		CurrentObject( const CodeLocation & loc, const Type * type );
+
+		/// produces a list of alternatives (Type *, Designation *) for the current sub-object's 
+		/// initializer.
+		std::vector< InitAlternative > getOptions();
 	};
 } // namespace ast
Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 1a4323ef209668602a57f374c8cbda3c31f45452)
+++ src/ResolvExpr/Resolver.cc	(revision 2b59f556da930033369d1ca9b86be75a4b277ff7)
@@ -1131,6 +1131,7 @@
 		/// lowest cost, returning the resolved version
 		ast::ptr< ast::Expr > findKindExpression(
-			const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind, 
-			std::function<bool(const Candidate &)> pred, ResolvMode mode = {}
+			const ast::Expr * untyped, const ast::SymbolTable & symtab, 
+			std::function<bool(const Candidate &)> pred = anyCandidate, 
+			const std::string & kind = "", ResolvMode mode = {}
 		) {
 			if ( ! untyped ) return {};
@@ -1148,6 +1149,5 @@
 			assert( untyped && type );
 			const ast::Expr * castExpr = new ast::CastExpr{ untyped->location, untyped, type };
-			ast::ptr< ast::Expr > newExpr = 
-				findKindExpression( castExpr, symtab, "", anyCandidate );
+			ast::ptr< ast::Expr > newExpr = findKindExpression( castExpr, symtab );
 			removeExtraneousCast( newExpr, symtab );
 			return newExpr;
@@ -1173,5 +1173,5 @@
 			const ast::Expr * untyped, const ast::SymbolTable & symtab 
 		) {
-			return findKindExpression( untyped, symtab, "condition", hasIntegralType );
+			return findKindExpression( untyped, symtab, hasIntegralType, "condition" );
 		}
 	}
@@ -1183,5 +1183,5 @@
 
 		ast::ptr< ast::Type > functionReturn = nullptr;
-		ast::CurrentObject currentObject = nullptr;
+		ast::CurrentObject currentObject;
 		bool inEnumDecl = false;
 
@@ -1199,16 +1199,16 @@
 		void previsit( const ast::PointerType * );
 
-		const ast::ExprStmt * previsit( const ast::ExprStmt * );
-		const ast::AsmExpr * previsit( const ast::AsmExpr * );
-		void previsit( const ast::AsmStmt * );
-		const ast::IfStmt * previsit( const ast::IfStmt * );
-		const ast::WhileStmt * previsit( const ast::WhileStmt * );
-		const ast::ForStmt * previsit( const ast::ForStmt * );
+		const ast::ExprStmt *   previsit( const ast::ExprStmt * );
+		const ast::AsmExpr *    previsit( const ast::AsmExpr * );
+		const ast::AsmStmt *    previsit( const ast::AsmStmt * );
+		const ast::IfStmt *     previsit( const ast::IfStmt * );
+		const ast::WhileStmt *  previsit( const ast::WhileStmt * );
+		const ast::ForStmt *    previsit( const ast::ForStmt * );
 		const ast::SwitchStmt * previsit( const ast::SwitchStmt * );
-		const ast::CaseStmt * previsit( const ast::CaseStmt * );
+		const ast::CaseStmt *   previsit( const ast::CaseStmt * );
 		const ast::BranchStmt * previsit( const ast::BranchStmt * );
-		void previsit( const ast::ReturnStmt * );
-		void previsit( const ast::ThrowStmt * );
-		void previsit( const ast::CatchStmt * );
+		const ast::ReturnStmt * previsit( const ast::ReturnStmt * );
+		const ast::ThrowStmt *  previsit( const ast::ThrowStmt * );
+		const ast::CatchStmt *  previsit( const ast::CatchStmt * );
 		void previsit( const ast::WaitForStmt * );
 
@@ -1261,9 +1261,10 @@
 		// selecting the RHS.
 		GuardValue( currentObject );
-		currentObject = ast::CurrentObject{ objectDecl->get_type() };
+		currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
 		if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) {
 			// enumerator initializers should not use the enum type to initialize, since the 
 			// enum type is still incomplete at this point. Use `int` instead.
-			currentObject = ast::CurrentObject{ new ast::BasicType{ ast::BasicType::SignedInt } };
+			currentObject = ast::CurrentObject{ 
+				objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } };
 		}
 	}
@@ -1320,8 +1321,9 @@
 	}
 
-	void Resolver_new::previsit( const ast::AsmStmt * asmStmt ) {
-		#warning unimplemented; Resolver port in progress
-		(void)asmStmt;
-		assert(false);
+	const ast::AsmStmt * Resolver_new::previsit( const ast::AsmStmt * asmStmt ) {
+		visitor->maybe_accept( asmStmt, &ast::AsmStmt::input );
+		visitor->maybe_accept( asmStmt, &ast::AsmStmt::output );
+		visit_children = false;
+		return asmStmt;
 	}
 
@@ -1355,5 +1357,5 @@
 			switchStmt, &ast::SwitchStmt::cond, 
 			findIntegralExpression( switchStmt->cond, symtab ) );
-		currentObject = ast::CurrentObject{ switchStmt->cond->result };
+		currentObject = ast::CurrentObject{ switchStmt->location, switchStmt->cond->result };
 		return switchStmt;
 	}
@@ -1361,6 +1363,20 @@
 	const ast::CaseStmt * Resolver_new::previsit( const ast::CaseStmt * caseStmt ) {
 		if ( caseStmt->cond ) {
-			#warning unimplemented, depends on currentObject implementation
-			assert(false);
+			std::vector< ast::InitAlternative > initAlts = currentObject.getOptions();
+			assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral "
+				"expression." );
+			
+			const ast::Expr * untyped = 
+				new ast::CastExpr{ caseStmt->location, caseStmt->cond, initAlts.front().type };
+			ast::ptr< ast::Expr > newExpr = findKindExpression( untyped, symtab );
+			
+			// case condition cannot have a cast in C, so it must be removed here, regardless of 
+			// whether it would perform a conversion.
+			if ( const ast::CastExpr * castExpr = newExpr.as< ast::CastExpr >() ) {
+				ast::ptr< ast::TypeSubstitution > env = castExpr->env;
+				newExpr.set_and_mutate( castExpr->arg )->env = env;
+			}
+			
+			caseStmt = ast::mutate_field( caseStmt, &ast::CaseStmt::cond, newExpr );
 		}
 		return caseStmt;
@@ -1381,20 +1397,37 @@
 	}
 
-	void Resolver_new::previsit( const ast::ReturnStmt * returnStmt ) {
-		#warning unimplemented; Resolver port in progress
-		(void)returnStmt;
-		assert(false);
-	}
-
-	void Resolver_new::previsit( const ast::ThrowStmt * throwStmt ) {
-		#warning unimplemented; Resolver port in progress
-		(void)throwStmt;
-		assert(false);
-	}
-
-	void Resolver_new::previsit( const ast::CatchStmt * catchStmt ) {
-		#warning unimplemented; Resolver port in progress
-		(void)catchStmt;
-		assert(false);
+	const ast::ReturnStmt * Resolver_new::previsit( const ast::ReturnStmt * returnStmt ) {
+		visit_children = false;
+		if ( returnStmt->expr ) {
+			returnStmt = ast::mutate_field(
+				returnStmt, &ast::ReturnStmt::expr, 
+				findSingleExpression( returnStmt->expr, functionReturn, symtab ) );
+		}
+		return returnStmt;
+	}
+
+	const ast::ThrowStmt * Resolver_new::previsit( const ast::ThrowStmt * throwStmt ) {
+		visit_children = false;
+		if ( throwStmt->expr ) {
+			const ast::StructDecl * exceptionDecl = 
+				symtab.lookupStruct( "__cfaabi_ehm__base_exception_t" );
+			assert( exceptionDecl );
+			ast::ptr< ast::Type > exceptType = 
+				new ast::PointerType{ new ast::StructInstType{ exceptionDecl } };
+			throwStmt = ast::mutate_field(
+				throwStmt, &ast::ThrowStmt::expr, 
+				findSingleExpression( throwStmt->expr, exceptType, symtab ) );
+		}
+		return throwStmt;
+	}
+
+	const ast::CatchStmt * Resolver_new::previsit( const ast::CatchStmt * catchStmt ) {
+		if ( catchStmt->cond ) {
+			ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool };
+			catchStmt = ast::mutate_field( 
+				catchStmt, &ast::CatchStmt::cond, 
+				findSingleExpression( catchStmt->cond, boolType, symtab ) );
+		}
+		return catchStmt;
 	}
 
