Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision e4bc98687ec0b391b64128355d71f42a2251ca97)
@@ -469,11 +469,12 @@
 			std::cerr << std::endl;
 		)
-		std::list< DeclarationWithType* > candidates;
+		std::list< SymTab::Indexer::IdData > candidates;
 		decls.lookupId( curDecl->get_name(), candidates );
 ///   if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; }
-		for ( std::list< DeclarationWithType* >::const_iterator candidate = candidates.begin(); candidate != candidates.end(); ++candidate ) {
+		for ( const auto & data : candidates ) {
+			DeclarationWithType * candidate = data.id;
 			PRINT(
 				std::cerr << "inferRecursive: candidate is ";
-				(*candidate)->print( std::cerr );
+				candidate->print( std::cerr );
 				std::cerr << std::endl;
 			)
@@ -482,5 +483,5 @@
 			TypeEnvironment newEnv( newAlt.env );
 			OpenVarSet newOpenVars( openVars );
-			Type *adjType = (*candidate)->get_type()->clone();
+			Type *adjType = candidate->get_type()->clone();
 			adjustExprType( adjType, newEnv, indexer );
 			adjType->accept( global_renamer );
@@ -500,6 +501,5 @@
 				Alternative newerAlt( newAlt );
 				newerAlt.env = newEnv;
-				assertf( (*candidate)->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( *candidate ).c_str() );
-				DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) );
+				assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
 
 				// everything with an empty idChain was pulled in by the current assertion.
@@ -516,5 +516,5 @@
 				// DOESN'T WORK: grandchild nodes conflict with their cousins
 				//if ( newNeedParents[ curDecl->get_uniqueId() ][ candDecl->get_uniqueId() ]++ > recursionParentLimit ) continue;
-				Expression *varExpr = new VariableExpr( candDecl );
+				Expression *varExpr = data.combine();
 				delete varExpr->get_result();
 				varExpr->set_result( adjType->clone() );
@@ -522,6 +522,6 @@
 					std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
 					curDecl->print( std::cerr );
-					std::cerr << " with declaration " << (*candidate)->get_uniqueId() << " ";
-					(*candidate)->print( std::cerr );
+					std::cerr << " with declaration " << candidate->get_uniqueId() << " ";
+					candidate->print( std::cerr );
 					std::cerr << std::endl;
 				)
@@ -532,5 +532,5 @@
 				}
 				// XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
-				(*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( (*candidate)->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
+				(*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
 				inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, /*newNeedParents,*/ level, indexer, out );
 			} else {
@@ -1317,16 +1317,17 @@
 
 	void AlternativeFinder::visit( NameExpr *nameExpr ) {
-		std::list< DeclarationWithType* > declList;
+		std::list< SymTab::Indexer::IdData > declList;
 		indexer.lookupId( nameExpr->get_name(), declList );
 		PRINT( std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl; )
-		for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) {
-			VariableExpr newExpr( *i );
-			alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) );
+		for ( auto & data : declList ) {
+			Expression * newExpr = data.combine();
+			// xxx - add in extra cost for with-statement exprs?
+			alternatives.push_back( Alternative( newExpr, env, Cost::zero ) );
 			PRINT(
 				std::cerr << "decl is ";
-				(*i)->print( std::cerr );
+				data.id->print( std::cerr );
 				std::cerr << std::endl;
 				std::cerr << "newExpr is ";
-				newExpr.print( std::cerr );
+				newExpr->print( std::cerr );
 				std::cerr << std::endl;
 			)
@@ -1420,21 +1421,25 @@
 	}
 
-	void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) {
-		// assume no polymorphism
-		// assume no implicit conversions
-		assert( function->get_parameters().size() == 1 );
-		PRINT(
-			std::cerr << "resolvAttr: funcDecl is ";
-			funcDecl->print( std::cerr );
-			std::cerr << " argType is ";
-			argType->print( std::cerr );
-			std::cerr << std::endl;
-		)
-		if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
-			alternatives.push_back( Alternative( new AttrExpr( new VariableExpr( funcDecl ), argType->clone() ), env, Cost::zero ) );
-			for ( std::list< DeclarationWithType* >::iterator i = function->get_returnVals().begin(); i != function->get_returnVals().end(); ++i ) {
-				alternatives.back().expr->set_result( (*i)->get_type()->clone() );
-			} // for
-		} // if
+	namespace {
+		void resolveAttr( SymTab::Indexer::IdData data, FunctionType *function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) {
+			// assume no polymorphism
+			// assume no implicit conversions
+			assert( function->get_parameters().size() == 1 );
+			PRINT(
+				std::cerr << "resolvAttr: funcDecl is ";
+				data.id->print( std::cerr );
+				std::cerr << " argType is ";
+				argType->print( std::cerr );
+				std::cerr << std::endl;
+			)
+			const SymTab::Indexer & indexer = finder.get_indexer();
+			AltList & alternatives = finder.get_alternatives();
+			if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
+				alternatives.push_back( Alternative( new AttrExpr( data.combine(), argType->clone() ), env, Cost::zero ) );
+				for ( DeclarationWithType * retVal : function->returnVals ) {
+					alternatives.back().expr->result = retVal->get_type()->clone();
+				} // for
+			} // if
+		}
 	}
 
@@ -1443,14 +1448,15 @@
 		NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
 		assert( nameExpr );
-		std::list< DeclarationWithType* > attrList;
+		std::list< SymTab::Indexer::IdData > attrList;
 		indexer.lookupId( nameExpr->get_name(), attrList );
 		if ( attrExpr->get_isType() || attrExpr->get_expr() ) {
-			for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
+			for ( auto & data : attrList ) {
+				DeclarationWithType * id = data.id;
 				// check if the type is function
-				if ( FunctionType *function = dynamic_cast< FunctionType* >( (*i)->get_type() ) ) {
+				if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) {
 					// assume exactly one parameter
 					if ( function->get_parameters().size() == 1 ) {
 						if ( attrExpr->get_isType() ) {
-							resolveAttr( *i, function, attrExpr->get_type(), env );
+							resolveAttr( data, function, attrExpr->get_type(), env, *this );
 						} else {
 							AlternativeFinder finder( indexer, env );
@@ -1458,5 +1464,5 @@
 							for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
 								if ( choice->expr->get_result()->size() == 1 ) {
-									resolveAttr(*i, function, choice->expr->get_result(), choice->env );
+									resolveAttr(data, function, choice->expr->get_result(), choice->env, *this );
 								} // fi
 							} // for
@@ -1466,7 +1472,6 @@
 			} // for
 		} else {
-			for ( std::list< DeclarationWithType* >::iterator i = attrList.begin(); i != attrList.end(); ++i ) {
-				VariableExpr newExpr( *i );
-				alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) );
+			for ( auto & data : attrList ) {
+				alternatives.push_back( Alternative( data.combine(), env, Cost::zero ) );
 				renameTypes( alternatives.back().expr );
 			} // for
Index: src/ResolvExpr/AlternativeFinder.h
===================================================================
--- src/ResolvExpr/AlternativeFinder.h	(revision 3ca540ff8fca8be28ec085a72a11b96bf920dd76)
+++ src/ResolvExpr/AlternativeFinder.h	(revision e4bc98687ec0b391b64128355d71f42a2251ca97)
@@ -142,5 +142,4 @@
 		template< typename OutputIterator >
 		void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out );
-		void resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env );
 
 		const SymTab::Indexer &indexer;
