Index: src/ResolvExpr/Resolver.cc
===================================================================
--- src/ResolvExpr/Resolver.cc	(revision 6138d0f75a1531a2f79bd02da26e6696c38ac53d)
+++ src/ResolvExpr/Resolver.cc	(revision 8587878e06a1508206324c71c2ca3e9004ba7e31)
@@ -171,4 +171,40 @@
 
 	namespace {
+		/// resolve `untyped` to the expression whose type satisfies `pred` with the lowest cost; kindStr is used for providing better error messages
+		template<typename Pred>
+		void findKindExpression(Expression *& untyped, const SymTab::Indexer & indexer, const std::string & kindStr, Pred pred) {
+			TypeEnvironment env;
+			AlternativeFinder finder( indexer, env );
+			finder.findWithAdjustment( untyped );
+
+			AltList candidates;
+			for ( Alternative & alt : finder.get_alternatives() ) {
+				if ( pred( alt.expr->result ) ) {
+					candidates.push_back( std::move( alt ) );
+				}
+			}
+
+			// choose the lowest cost expression among the candidates
+			AltList winners;
+			findMinCost( candidates.begin(), candidates.end(), back_inserter( winners ) );
+			if ( winners.size() == 0 ) {
+				throw SemanticError( "No reasonable alternatives for " + kindStr + " expression: ", untyped );
+			} else if ( winners.size() != 1 ) {
+				std::ostringstream stream;
+				stream << "Cannot choose between " << winners.size() << " alternatives for " + kindStr +  " expression\n";
+				untyped->print( stream );
+				stream << "Alternatives are:\n";
+				printAlts( winners, stream, 1 );
+				throw SemanticError( stream.str() );
+			}
+
+			// there is one unambiguous interpretation - move the expression into the with statement
+			Alternative & alt = winners.front();
+			finishExpr( alt.expr, alt.env, untyped->env );
+			delete untyped;
+			untyped = alt.expr;
+			alt.expr = nullptr;
+		}
+
 		bool isIntegralType( Type *type ) {
 			if ( dynamic_cast< EnumInstType * >( type ) ) {
@@ -184,37 +220,6 @@
 
 		void findIntegralExpression( Expression *& untyped, const SymTab::Indexer &indexer ) {
-			TypeEnvironment env;
-			AlternativeFinder finder( indexer, env );
-			finder.find( untyped );
-#if 0
-			if ( finder.get_alternatives().size() != 1 ) {
-				std::cout << "untyped expr is ";
-				untyped->print( std::cout );
-				std::cout << std::endl << "alternatives are:";
-				for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
-					i->print( std::cout );
-				} // for
-			} // if
-#endif
-			Expression *newExpr = 0;
-			const TypeEnvironment *newEnv = 0;
-			for ( AltList::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
-				if ( i->expr->get_result()->size() == 1 && isIntegralType( i->expr->get_result() ) ) {
-					if ( newExpr ) {
-						throw SemanticError( "Too many interpretations for case control expression", untyped );
-					} else {
-						newExpr = i->expr->clone();
-						newEnv = &i->env;
-					} // if
-				} // if
-			} // for
-			if ( ! newExpr ) {
-				throw SemanticError( "No interpretations for case control expression", untyped );
-			} // if
-			finishExpr( newExpr, *newEnv, untyped->env );
-			delete untyped;
-			untyped = newExpr;
-		}
-
+			findKindExpression( untyped, indexer, "condition", isIntegralType );
+		}
 	}
 
@@ -311,14 +316,14 @@
 
 	void Resolver::previsit( IfStmt *ifStmt ) {
-		findSingleExpression( ifStmt->condition, indexer );
+		findIntegralExpression( ifStmt->condition, indexer );
 	}
 
 	void Resolver::previsit( WhileStmt *whileStmt ) {
-		findSingleExpression( whileStmt->condition, indexer );
+		findIntegralExpression( whileStmt->condition, indexer );
 	}
 
 	void Resolver::previsit( ForStmt *forStmt ) {
 		if ( forStmt->condition ) {
-			findSingleExpression( forStmt->condition, indexer );
+			findIntegralExpression( forStmt->condition, indexer );
 		} // if
 
@@ -579,38 +584,9 @@
 	}
 
+
 	void Resolver::previsit( WithStmt * withStmt ) {
 		for ( Expression *& expr : withStmt->exprs )  {
-			TypeEnvironment env;
-			AlternativeFinder finder( indexer, env );
-			finder.findWithAdjustment( expr );
-
 			// only struct- and union-typed expressions are viable candidates
-			AltList candidates;
-			for ( Alternative & alt : finder.get_alternatives() ) {
-				if ( isStructOrUnion( alt.expr->result ) ) {
-					candidates.push_back( std::move( alt ) );
-				}
-			}
-
-			// choose the lowest cost expression among the candidates
-			AltList winners;
-			findMinCost( candidates.begin(), candidates.end(), back_inserter( winners ) );
-			if ( winners.size() == 0 ) {
-				throw SemanticError( "No reasonable alternatives for with statement expression: ", expr );
-			} else if ( winners.size() != 1 ) {
-				std::ostringstream stream;
-				stream << "Cannot choose between " << winners.size() << " alternatives for with statement expression\n";
-				expr->print( stream );
-				stream << "Alternatives are:\n";
-				printAlts( winners, stream, 1 );
-				throw SemanticError( stream.str() );
-			}
-
-			// there is one unambiguous interpretation - move the expression into the with statement
-			Alternative & alt = winners.front();
-			finishExpr( alt.expr, alt.env, expr->env );
-			delete expr;
-			expr = alt.expr;
-			alt.expr = nullptr;
+			findKindExpression( expr, indexer, "with statement", isStructOrUnion );
 
 			// if with expression might be impure, create a temporary so that it is evaluated once
