Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision c1398e48a1e93cff3edc8dfe33ad1453eead9738)
+++ src/AST/Convert.cpp	(revision 67d2b97876c8dbfa06bc7491630118bbab21dfc9)
@@ -1895,6 +1895,6 @@
 		};
 		stmt->orElse = {
-			GET_ACCEPT_1(timeout.statement, Stmt),
-			GET_ACCEPT_1(timeout.condition, Expr),
+			GET_ACCEPT_1(orelse.statement, Stmt),
+			GET_ACCEPT_1(orelse.condition, Expr),
 		};
 
Index: src/AST/Fwd.hpp
===================================================================
--- src/AST/Fwd.hpp	(revision c1398e48a1e93cff3edc8dfe33ad1453eead9738)
+++ src/AST/Fwd.hpp	(revision 67d2b97876c8dbfa06bc7491630118bbab21dfc9)
@@ -10,6 +10,6 @@
 // Created On       : Wed May  8 16:05:00 2019
 // Last Modified By : Andrew Beach
-// Last Modified On : Thr May  9 13:09:00 2019
-// Update Count     : 0
+// Last Modified On : Mon Jun 24 09:48:00 2019
+// Update Count     : 1
 //
 
@@ -129,4 +129,6 @@
 class Attribute;
 
+class SymbolTable;
+class TypeEnvironment;
 class TypeSubstitution;
 
Index: src/ResolvExpr/ConversionCost.cc
===================================================================
--- src/ResolvExpr/ConversionCost.cc	(revision c1398e48a1e93cff3edc8dfe33ad1453eead9738)
+++ src/ResolvExpr/ConversionCost.cc	(revision 67d2b97876c8dbfa06bc7491630118bbab21dfc9)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 07:06:19 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Mon May  6 14:18:22 2019
-// Update Count     : 25
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon Jun 24 13:33:00 2019
+// Update Count     : 26
 //
 
@@ -489,13 +489,303 @@
 	}
 
-	Cost conversionCost( 
-		const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
-		const ast::TypeEnvironment & env
-	) {
-		#warning unimplemented
-		(void)src; (void)dst; (void)symtab; (void)env;
-		assert(false);
+static int localPtrsAssignable(const ast::Type * t1, const ast::Type * t2,
+		const ast::SymbolTable &, const ast::TypeEnvironment & env ) {
+	return ptrsAssignable( t1, t2, env );
+}
+
+// TODO: This is used for overload resolution. It might be able to be dropped once the old system
+// is removed.
+static Cost localConversionCost(
+	const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
+	const ast::TypeEnvironment & env
+) { return conversionCost( src, dst, symtab, env ); }
+
+Cost conversionCost(
+	const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
+	const ast::TypeEnvironment & env
+) {
+	if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
+		if ( const ast::EqvClass * eqv = env.lookup( inst->name ) ) {
+			if ( eqv->bound ) {
+				return conversionCost(src, eqv->bound, symtab, env );
+			} else {
+				return Cost::infinity;
+			}
+		} else if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) {
+			const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( named );
+			assertf( type, "Unexpected typedef." );
+			if ( type->base ) {
+				return conversionCost( src, type->base, symtab, env ) + Cost::safe;
+			}
+		}
+	}
+	if ( typesCompatibleIgnoreQualifiers( src, dst, symtab, env ) ) {
 		return Cost::zero;
-	}
+	} else if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
+		return Cost::safe;
+	} else if ( const ast::ReferenceType * refType =
+			 dynamic_cast< const ast::ReferenceType * >( dst ) ) {
+		return convertToReferenceCost( src, refType, symtab, env, localPtrsAssignable );
+	} else {
+		ast::Pass<ConversionCost_new> converter( dst, symtab, env, localConversionCost );
+		src->accept( converter );
+		return converter.pass.cost;
+	}
+}
+
+Cost convertToReferenceCost( const ast::Type * src, const ast::Type * dst, int diff,
+		const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
+		NumCostCalculation func ) {
+	if ( 0 < diff ) {
+		Cost cost = convertToReferenceCost(
+			strict_dynamic_cast< const ast::ReferenceType * >( src )->base,
+			dst, (diff - 1), symtab, env, func );
+		cost.incReference();
+		return cost;
+	} else if ( diff < -1 ) {
+		Cost cost = convertToReferenceCost(
+			src, strict_dynamic_cast< const ast::ReferenceType * >( dst )->base,
+			(diff + 1), symtab, env, func );
+		cost.incReference();
+		return cost;
+	} else if ( 0 == diff ) {
+		const ast::ReferenceType * srcAsRef = dynamic_cast< const ast::ReferenceType * >( src );
+		const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
+		if ( srcAsRef && dstAsRef ) {
+			ast::CV::Qualifiers tq1 = srcAsRef->base->qualifiers;
+			ast::CV::Qualifiers tq2 = dstAsRef->base->qualifiers;
+			if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
+					srcAsRef->base, dstAsRef->base, symtab, env ) ) {
+				if ( tq1 == tq2 ) {
+					return Cost::zero;
+				} else {
+					return Cost::safe;
+				}
+			} else {
+				int assignResult = func( srcAsRef->base, dstAsRef->base, symtab, env );
+				if ( 0 < assignResult ) {
+					return Cost::safe;
+				} else if ( assignResult < 0 ) {
+					return Cost::unsafe;
+				}
+			}
+		} else {
+			ast::Pass<ConversionCost_new> converter( dst, symtab, env, localConversionCost );
+			src->accept( converter );
+			return converter.pass.cost;
+		}
+	} else {
+		assert( -1 == diff );
+		const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
+		assert( dstAsRef );
+		if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, symtab, env ) ) {
+			if ( src->is_lvalue() ) {
+				if ( src->qualifiers == dstAsRef->base->qualifiers ) {
+					return Cost::reference;
+				} else if ( src->qualifiers < dstAsRef->base->qualifiers ) {
+					return Cost::safe;
+				} else {
+					return Cost::unsafe;
+				}
+			} else if ( dstAsRef->base->is_const() ) {
+				return Cost::safe;
+			} else {
+				return Cost::unsafe;
+			}
+		}
+	}
+	return Cost::infinity;
+}
+
+Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dst,
+	    const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
+		NumCostCalculation func ) {
+	int sdepth = src->referenceDepth(), ddepth = dst->referenceDepth();
+	return convertToReferenceCost( src, dst, sdepth - ddepth, symtab, env, func );
+}
+
+void ConversionCost_new::postvisit( const ast::VoidType * voidType ) {
+	(void)voidType;
+	cost = Cost::infinity;
+}
+
+void ConversionCost_new::postvisit( const ast::BasicType * basicType ) {
+	if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
+		int tableResult = costMatrix[ basicType->kind ][ dstAsBasic->kind ];
+		if ( tableResult == -1 ) {
+			cost = Cost::unsafe;
+		} else {
+			cost = Cost::zero;
+			cost.incSafe( tableResult );
+			cost.incSign( signMatrix[ basicType->kind ][ dstAsBasic->kind ] );
+		}
+	} else if ( dynamic_cast< const ast::EnumInstType * >( dst ) ) {
+		// xxx - not positive this is correct, but appears to allow casting int => enum
+		cost = Cost::unsafe;
+	}
+}
+
+void ConversionCost_new::postvisit( const ast::PointerType * pointerType ) {
+	if ( const ast::PointerType * dstAsPtr = dynamic_cast< const ast::PointerType * >( dst ) ) {
+		ast::CV::Qualifiers tq1 = pointerType->base->qualifiers;
+		ast::CV::Qualifiers tq2 = dstAsPtr->base->qualifiers;
+		if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
+				pointerType->base, dstAsPtr->base, symtab, env ) ) {
+			if ( tq1 == tq2 ) {
+				cost = Cost::zero;
+			} else {
+				cost = Cost::safe;
+			}
+		} else {
+			int assignResult = ptrsAssignable( pointerType->base, dstAsPtr->base, env );
+			if ( 0 < assignResult && tq1 <= tq2 ) {
+				if ( tq1 == tq2 ) {
+					cost = Cost::safe;
+				} else {
+					cost = Cost::safe + Cost::safe;
+				}
+			} else if ( assignResult < 0 ) {
+				cost = Cost::unsafe;
+			} // else Cost::infinity
+		}
+	}
+}
+
+void ConversionCost_new::postvisit( const ast::ArrayType * arrayType ) {
+	(void)arrayType;
+}
+
+void ConversionCost_new::postvisit( const ast::ReferenceType * refType ) {
+	assert( nullptr == dynamic_cast< const ast::ReferenceType * >( dst ) );
+
+	cost = costCalc( refType->base, dst, symtab, env );
+	if ( refType->base->qualifiers == dst->qualifiers ) {
+		cost.incReference();
+	} else if ( refType->base->qualifiers < dst->qualifiers ) {
+		cost.incSafe();
+	} else {
+		cost.incUnsafe();
+	}
+}
+
+void ConversionCost_new::postvisit( const ast::FunctionType * functionType ) {
+	(void)functionType;
+}
+
+void ConversionCost_new::postvisit( const ast::StructInstType * structInstType ) {
+	if ( const ast::StructInstType * dstAsInst =
+			dynamic_cast< const ast::StructInstType * >( dst ) ) {
+		if ( structInstType->name == dstAsInst->name ) {
+			cost = Cost::zero;
+		}
+	}
+}
+
+void ConversionCost_new::postvisit( const ast::UnionInstType * unionInstType ) {
+	if ( const ast::UnionInstType * dstAsInst =
+			dynamic_cast< const ast::UnionInstType * >( dst ) ) {
+		if ( unionInstType->name == dstAsInst->name ) {
+			cost = Cost::zero;
+		}
+	}
+}
+
+void ConversionCost_new::postvisit( const ast::EnumInstType * enumInstType ) {
+	(void)enumInstType;
+	static const ast::BasicType integer( ast::BasicType::SignedInt );
+	cost = costCalc( &integer, dst, symtab, env );
+	if ( cost < Cost::unsafe ) {
+		cost.incSafe();
+	}
+}
+
+void ConversionCost_new::postvisit( const ast::TraitInstType * traitInstType ) {
+	(void)traitInstType;
+}
+
+void ConversionCost_new::postvisit( const ast::TypeInstType * typeInstType ) {
+	if ( const ast::EqvClass * eqv = env.lookup( typeInstType->name ) ) {
+		cost = costCalc( eqv->bound, dst, symtab, env );
+	} else if ( const ast::TypeInstType * dstAsInst =
+			dynamic_cast< const ast::TypeInstType * >( dst ) ) {
+		if ( typeInstType->name == dstAsInst->name ) {
+			cost = Cost::zero;
+		}
+	} else if ( const ast::NamedTypeDecl * namedType = symtab.lookupType( typeInstType->name ) ) {
+		const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( namedType );
+		assertf( type, "Unexpected typedef.");
+		if ( type->base ) {
+			cost = costCalc( type->base, dst, symtab, env ) + Cost::safe;
+		}
+	}
+}
+
+void ConversionCost_new::postvisit( const ast::TupleType * tupleType ) {
+	Cost c = Cost::zero;
+	if ( const ast::TupleType * dstAsTuple = dynamic_cast< const ast::TupleType * >( dst ) ) {
+		auto srcIt = tupleType->types.begin();
+		auto dstIt = dstAsTuple->types.begin();
+		auto srcEnd = tupleType->types.end();
+		auto dstEnd = dstAsTuple->types.end();
+		while ( srcIt != srcEnd && dstIt != dstEnd ) {
+			Cost newCost = costCalc( *srcIt++, *dstIt++, symtab, env );
+			if ( newCost == Cost::infinity ) {
+				return;
+			}
+			c += newCost;
+		}
+		if ( dstIt != dstEnd ) {
+			cost = Cost::infinity;
+		} else {
+			cost = c;
+		}
+	}
+}
+
+void ConversionCost_new::postvisit( const ast::VarArgsType * varArgsType ) {
+	(void)varArgsType;
+	if ( dynamic_cast< const ast::VarArgsType * >( dst ) ) {
+		cost = Cost::zero;
+	}
+}
+
+void ConversionCost_new::postvisit( const ast::ZeroType * zeroType ) {
+	(void)zeroType;
+	if ( dynamic_cast< const ast::ZeroType * >( dst ) ) {
+		cost = Cost::zero;
+	} else if ( const ast::BasicType * dstAsBasic =
+			dynamic_cast< const ast::BasicType * >( dst ) ) {
+		int tableResult = costMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ];
+		if ( -1 == tableResult ) {
+			cost = Cost::unsafe;
+		} else {
+			cost = Cost::zero;
+			cost.incSafe( tableResult + 1 );
+			cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] );
+		}
+	}
+}
+
+void ConversionCost_new::postvisit( const ast::OneType * oneType ) {
+	(void)oneType;
+	if ( dynamic_cast< const ast::OneType * >( dst ) ) {
+		cost = Cost::zero;
+	} else if ( const ast::BasicType * dstAsBasic =
+			dynamic_cast< const ast::BasicType * >( dst ) ) {
+		int tableResult = costMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ];
+		if ( -1 == tableResult ) {
+			cost = Cost::unsafe;
+		} else {
+			cost = Cost::zero;
+			cost.incSafe( tableResult + 1 );
+			cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] );
+		}
+	} else if ( dynamic_cast< const ast::PointerType * >( dst ) ) {
+		cost = Cost::zero;
+		cost.incSafe( maxIntCost + 2 );
+	}
+}
+
+
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/ConversionCost.h
===================================================================
--- src/ResolvExpr/ConversionCost.h	(revision c1398e48a1e93cff3edc8dfe33ad1453eead9738)
+++ src/ResolvExpr/ConversionCost.h	(revision 67d2b97876c8dbfa06bc7491630118bbab21dfc9)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 09:37:28 2015
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:38:24 2017
-// Update Count     : 4
+// Last Modified By : Andrew Beach
+// Last Modified On : Mon Jun 24 10:00:00 2019
+// Update Count     : 5
 //
 
@@ -20,4 +20,6 @@
 #include "Cost.h"             // for Cost
 
+#include "AST/Fwd.hpp"
+#include "AST/Pass.hpp"       // for WithShortCircuiting
 #include "Common/PassVisitor.h"
 #include "SynTree/Visitor.h"  // for Visitor
@@ -65,4 +67,47 @@
 	typedef std::function<int(Type *, Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;
 	Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
+
+// Some function pointer types, differ in return type.
+using CostCalculation = std::function<Cost(const ast::Type *, const ast::Type *,
+	const ast::SymbolTable &, const ast::TypeEnvironment &)>;
+using NumCostCalculation = std::function<int(const ast::Type *, const ast::Type *,
+	const ast::SymbolTable &, const ast::TypeEnvironment &)>;
+
+// TODO: When the old ConversionCost is removed, get ride of the _new suffix.
+class ConversionCost_new : public ast::WithShortCircuiting {
+	const ast::Type * dst;
+	const ast::SymbolTable & symtab;
+	const ast::TypeEnvironment & env;
+	CostCalculation costCalc;
+public:
+	Cost cost;
+
+	ConversionCost_new( const ast::Type * dst, const ast::SymbolTable & symtab,
+			const ast::TypeEnvironment & env, CostCalculation costCalc ) :
+		dst( dst ), symtab( symtab ), env( env ), costCalc( costCalc ), cost( Cost::infinity )
+	{}
+
+	void previsit( const ast::Node * ) { visit_children = false; }
+
+	void postvisit( const ast::VoidType * voidType );
+	void postvisit( const ast::BasicType * basicType );
+	void postvisit( const ast::PointerType * pointerType );
+	void postvisit( const ast::ArrayType * arrayType );
+	void postvisit( const ast::ReferenceType * refType );
+	void postvisit( const ast::FunctionType * functionType );
+	void postvisit( const ast::StructInstType * structInstType );
+	void postvisit( const ast::UnionInstType * unionInstType );
+	void postvisit( const ast::EnumInstType * enumInstType );
+	void postvisit( const ast::TraitInstType * traitInstType );
+	void postvisit( const ast::TypeInstType * typeInstType );
+	void postvisit( const ast::TupleType * tupleType );
+	void postvisit( const ast::VarArgsType * varArgsType );
+	void postvisit( const ast::ZeroType * zeroType );
+	void postvisit( const ast::OneType * oneType );
+};
+
+Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dest,
+	const ast::SymbolTable & indexer, const ast::TypeEnvironment & env, NumCostCalculation func );
+
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/PtrsAssignable.cc
===================================================================
--- src/ResolvExpr/PtrsAssignable.cc	(revision c1398e48a1e93cff3edc8dfe33ad1453eead9738)
+++ src/ResolvExpr/PtrsAssignable.cc	(revision 67d2b97876c8dbfa06bc7491630118bbab21dfc9)
@@ -14,4 +14,5 @@
 //
 
+#include "AST/Fwd.hpp"
 #include "Common/PassVisitor.h"
 #include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
@@ -107,4 +108,14 @@
 	void PtrsAssignable::postvisit(  __attribute__((unused)) OneType *oneType ) {}
 
+int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
+		const ast::TypeEnvironment & env ) {
+	#warning unimplemented
+	(void)src;
+	(void)dst;
+	(void)env;
+	assert(0);
+	return 0;
+}
+
 } // namespace ResolvExpr
 
Index: src/ResolvExpr/typeops.h
===================================================================
--- src/ResolvExpr/typeops.h	(revision c1398e48a1e93cff3edc8dfe33ad1453eead9738)
+++ src/ResolvExpr/typeops.h	(revision 67d2b97876c8dbfa06bc7491630118bbab21dfc9)
@@ -94,4 +94,6 @@
 	// in PtrsAssignable.cc
 	int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env );
+	int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
+		const ast::TypeEnvironment & env );
 
 	// in PtrsCastable.cc
