Index: Jenkinsfile
===================================================================
--- Jenkinsfile	(revision c1398e48a1e93cff3edc8dfe33ad1453eead9738)
+++ Jenkinsfile	(revision 08c07801e1668d4ca42622537be1cac070b58ab4)
@@ -130,6 +130,6 @@
 			//Run the tests from the tests directory
 			if ( Settings.RunAllTests ) {
-				sh 'make --no-print-directory -C tests timeouts="--timeout=600" all-tests debug=yes'
-				sh 'make --no-print-directory -C tests timeouts="--timeout=600" all-tests debug=no '
+				sh 'make --no-print-directory -C tests timeouts="--timeout=1200" all-tests debug=yes'
+				sh 'make --no-print-directory -C tests timeouts="--timeout=1200" all-tests debug=no '
 			}
 			else {
Index: doc/papers/concurrency/Paper.tex
===================================================================
--- doc/papers/concurrency/Paper.tex	(revision c1398e48a1e93cff3edc8dfe33ad1453eead9738)
+++ doc/papers/concurrency/Paper.tex	(revision 08c07801e1668d4ca42622537be1cac070b58ab4)
@@ -2705,39 +2705,7 @@
 \label{results}
 
-To verify the implementation of the \CFA runtime, a series of microbenchmarks are performed comparing \CFA with Java OpenJDK-9, Go 1.9.2 and \uC 7.0.0.
-The benchmark computer is an AMD Opteron\texttrademark\ 6380 NUMA 64-core, 8 socket, 2.5 GHz processor, running Ubuntu 16.04.6 LTS, and \uC/\CFA are compiled with gcc 6.5.
-
-\begin{comment}
-\begin{table}
-\centering
-\caption{Experiment environment}
-\label{t:machine}
-
-\begin{tabular}{|l|r||l|r|}
-\hline
-Architecture		& x86\_64 				& NUMA node(s) 	& 8 \\
-\hline
-CPU op-mode(s)		& 32-bit, 64-bit 		& Model name 	& AMD Opteron\texttrademark\ Processor 6380 \\
-\hline
-Byte Order			& Little Endian 		& CPU Freq 		& 2.5 GHz \\
-\hline
-CPU(s)				& 64 					& L1d cache 	& 16 KiB \\
-\hline
-Thread(s) per core	& 2 					& L1i cache 	& 64 KiB \\
-\hline
-Core(s) per socket	& 8 					& L2 cache 		& 2048 KiB \\
-\hline
-Socket(s)			& 4 					& L3 cache 		& 6144 KiB \\
-\hline
-\hline
-Operating system	& Ubuntu 16.04.3 LTS	& Kernel		& Linux 4.4-97-generic \\
-\hline
-gcc					& 6.3	 				& \CFA			& 1.0.0 \\
-\hline
-Java				& OpenJDK-9 			& Go			& 1.9.2 \\
-\hline
-\end{tabular}
-\end{table}
-\end{comment}
+To verify the implementation of the \CFA runtime, a series of microbenchmarks are performed comparing \CFA with pthreads, Java OpenJDK-9, Go 1.12.6 and \uC 7.0.0.
+For comparison, the package must be multi-processor (M:N), which excludes libdill/libmil~\cite{libdill} (M:1)), and use a shared-memory programming model, \eg not message passing.
+The benchmark computer is an AMD Opteron\texttrademark\ 6380 NUMA 64-core, 8 socket, 2.5 GHz processor, running Ubuntu 16.04.6 LTS, and \CFA/\uC are compiled with gcc 6.5.
 
 All benchmarks are run using the following harness.
@@ -2749,4 +2717,5 @@
 Each benchmark is performed @N@ times, where @N@ varies depending on the benchmark;
 the total time is divided by @N@ to obtain the average time for a benchmark.
+Each benchmark experiment is run 31 times.
 All omitted tests for other languages are functionally identical to the \CFA tests and available online~\cite{CforallBenchMarks}.
 
@@ -2779,12 +2748,115 @@
 \begin{tabular}[t]{@{}r*{3}{D{.}{.}{5.2}}@{}}
 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
-Pthreads				& 28091		& 28073.39	& 163.1		\\
-\CFA Coroutine Lazy		& 6			& 6.07		& 0.26		\\
-\CFA Coroutine Eager	& 520		& 520.61	& 2.04		\\
-\CFA Thread				& 2032		& 2016.29	& 112.07	\\
-\uC Coroutine			& 106		& 107.36	& 1.47		\\
-\uC Thread				& 536.5		& 537.07	& 4.64		\\
-Goroutine				& 3103		& 3086.29	& 90.25		\\
-Java Thread				& 103416.5	& 103732.29	& 1137		\\
+\CFA Coroutine Lazy		& 14.3		& 14.3		& 0.32		\\
+\CFA Coroutine Eager	& 2203.7	& 2205.6	& 26.03		\\
+\CFA Thread				& 1257.8	& 1291.2	& 86.19		\\
+\uC Coroutine			& 92.2		& 91.4		& 1.58		\\
+\uC Thread				& 499.5		& 500.1		& 5.67		\\
+Goroutine				& 4397.0	& 4362.8	& 390.77	\\
+Java Thread				& 107405.0	& 107794.8	& 1601.33	\\
+% Qthreads				& 159.9		& 159.6		& 0.73		\\
+Pthreads				& 32920.9	& 32882.7	& 213.55
+\end{tabular}
+\end{multicols}
+
+
+\paragraph{Internal Scheduling}
+
+Internal scheduling is measured using a cycle of two threads signalling and waiting.
+Figure~\ref{f:int-sched} shows the code for \CFA, with results in Table~\ref{tab:int-sched}.
+Note, the incremental cost of bulk acquire for \CFA, which is largely a fixed cost for small numbers of mutex objects.
+Java scheduling is significantly greater because the benchmark explicitly creates multiple thread in order to prevent the JIT from making the program sequential, \ie removing all locking.
+
+\begin{multicols}{2}
+\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
+\begin{cfa}
+volatile int go = 0;
+@monitor@ M { @condition c;@ } m;
+void __attribute__((noinline))
+do_call( M & @mutex@ a1 ) { @signal( c );@ }
+thread T {};
+void main( T & this ) {
+	while ( go == 0 ) { yield(); }
+	while ( go == 1 ) { do_call( m ); }
+}
+int  __attribute__((noinline))
+do_wait( M & mutex m ) with(m) {
+	go = 1;	// continue other thread
+	BENCH( for ( N ) { @wait( c );@ } );
+	go = 0;	// stop other thread
+	sout | result`ns;
+}
+int main() {
+	T t;
+	do_wait( m );
+}
+\end{cfa}
+\captionof{figure}{\CFA Internal-scheduling benchmark}
+\label{f:int-sched}
+
+\columnbreak
+
+\vspace*{-16pt}
+\captionof{table}{Internal-scheduling comparison (nanoseconds)}
+\label{tab:int-sched}
+\bigskip
+
+\begin{tabular}{@{}r*{3}{D{.}{.}{5.2}}@{}}
+\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
+\CFA @signal@, 1 @monitor@	& 367.0		& 371.5		& 17.34		\\
+\CFA @signal@, 2 @monitor@	& 477.2		& 478.6		& 8.31		\\
+\CFA @signal@, 4 @monitor@	& 725.8		& 734.0		& 17.98		\\
+\uC @signal@				& 322.8		& 323.0 	& 3.64		\\
+Java @notify@				& 16520.0	& 20096.7	& 9378.53	\\
+Pthreads Cond. Variable		& 4931.3	& 5057.0 	& 326.80
+\end{tabular}
+\end{multicols}
+
+
+\paragraph{External Scheduling}
+
+External scheduling is measured using a cycle of two threads calling and accepting the call using the @waitfor@ statement.
+Figure~\ref{f:ext-sched} shows the code for \CFA, with results in Table~\ref{tab:ext-sched}.
+Note, the incremental cost of bulk acquire for \CFA, which is largely a fixed cost for small numbers of mutex objects.
+
+\begin{multicols}{2}
+\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
+\vspace*{-16pt}
+\begin{cfa}
+volatile int go = 0;
+@monitor@ M {} m;
+thread T {};
+void __attribute__((noinline))
+do_call( M & @mutex@ ) {}
+void main( T & ) {
+	while ( go == 0 ) { yield(); }
+	while ( go == 1 ) { do_call( m ); }
+}
+int __attribute__((noinline))
+do_wait( M & @mutex@ m ) {
+	go = 1;	// continue other thread
+	BENCH( for ( N ) { @waitfor( do_call, m );@ } )
+	go = 0;	// stop other thread
+	sout | result`ns;
+}
+int main() {
+	T t;
+	do_wait( m );
+}
+\end{cfa}
+\captionof{figure}{\CFA external-scheduling benchmark}
+\label{f:ext-sched}
+
+\columnbreak
+
+\vspace*{-16pt}
+\captionof{table}{External-scheduling comparison (nanoseconds)}
+\label{tab:ext-sched}
+\begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
+\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
+\CFA @waitfor@, 1 @monitor@	& 366.7		& 369.5	& 7.52	\\
+\CFA @waitfor@, 2 @monitor@	& 453.6		& 455.8	& 12.38	\\
+\CFA @waitfor@, 4 @monitor@	& 671.6		& 672.4	& 14.16	\\
+\uC @_Accept@				& 336.0		& 335.8		& 3.22
 \end{tabular}
 \end{multicols}
@@ -2825,13 +2897,14 @@
 \begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
-C function		& 2			& 2		& 0		\\
-\CFA generator	& 2			& 2		& 0		\\
-\CFA Coroutine	& 49	& 48.68		& 0.47	\\
-\CFA Thread		& 105	& 105.57	& 1.37	\\
-\uC Coroutine	& 44	& 44		& 0		\\
-\uC Thread		& 100	& 99.29		& 0.96	\\
-Goroutine		& 145	& 147.25	& 4.15	\\
-Java Thread		& 373.5	& 375.14	& 8.72	\\
-Pthreads Thread	& 333.5	& 332.96	& 4.1
+C function		& 1.8		& 1.8	& 0		\\
+\CFA generator	& 2.7		& 2.4	& 0.27	\\
+\CFA Coroutine	& 37.8		& 37.7	& 0.22	\\
+\CFA Thread		& 93.6		& 93.8	& 1.46	\\
+\uC Coroutine	& 52.7		& 52.8	& 0.28	\\
+\uC Thread		& 93.4		& 93.7	& 1.04	\\
+Goroutine		& 140.0		& 139.7	& 2.93	\\
+Java Thread		& 374.0		& 375.8	& 10.38	\\
+% Qthreads Thread	& 159.5		& 159.3	& 0.71	\\
+Pthreads Thread	& 334.4		& 335.0	& 1.95	\\
 \end{tabular}
 \end{multicols}
@@ -2869,113 +2942,11 @@
 \begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
-test and test-and-test lock		& 26		& 26	& 0		\\
-Pthreads Mutex Lock				& 31		& 31.71	& 0.97	\\
-\uC @monitor@ member rtn.		& 31		& 31	& 0		\\
-\CFA @mutex@ function, 1 arg.	& 46		& 46.68	& 0.93	\\
-\CFA @mutex@ function, 2 arg.	& 84		& 85.36	& 1.99	\\
-\CFA @mutex@ function, 4 arg.	& 158		& 161	& 4.22	\\
-Java synchronized method		& 27.5		& 29.79	& 2.93
-\end{tabular}
-\end{multicols}
-
-
-\paragraph{Internal Scheduling}
-
-Internal scheduling is measured using a cycle of two threads signalling and waiting.
-Figure~\ref{f:int-sched} shows the code for \CFA, with results in Table~\ref{tab:int-sched}.
-Note, the incremental cost of bulk acquire for \CFA, which is largely a fixed cost for small numbers of mutex objects.
-Java scheduling is significantly greater because the benchmark explicitly creates multiple thread in order to prevent the JIT from making the program sequential, \ie removing all locking.
-
-\begin{multicols}{2}
-\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
-\begin{cfa}
-volatile int go = 0;
-@monitor@ M { @condition c;@ } m;
-void __attribute__((noinline))
-do_call( M & @mutex@ a1 ) { @signal( c );@ }
-thread T {};
-void main( T & this ) {
-	while ( go == 0 ) { yield(); }
-	while ( go == 1 ) { do_call( m ); }
-}
-int  __attribute__((noinline))
-do_wait( M & mutex m ) with(m) {
-	go = 1;	// continue other thread
-	BENCH( for ( N ) { @wait( c );@ } );
-	go = 0;	// stop other thread
-	sout | result`ns;
-}
-int main() {
-	T t;
-	do_wait( m );
-}
-\end{cfa}
-\captionof{figure}{\CFA Internal-scheduling benchmark}
-\label{f:int-sched}
-
-\columnbreak
-
-\vspace*{-16pt}
-\captionof{table}{Internal-scheduling comparison (nanoseconds)}
-\label{tab:int-sched}
-\bigskip
-
-\begin{tabular}{@{}r*{3}{D{.}{.}{5.2}}@{}}
-\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
-Pthreads Cond. Variable		& 6005		& 5681.43 	& 835.45	\\
-\uC @signal@				& 324		& 325.54 	& 3.02		\\
-\CFA @signal@, 1 @monitor@	& 368.5		& 370.61	& 4.77		\\
-\CFA @signal@, 2 @monitor@	& 467		& 470.5		& 6.79		\\
-\CFA @signal@, 4 @monitor@	& 700.5		& 702.46	& 7.23		\\
-Java @notify@				& 15471		& 172511	& 5689
-\end{tabular}
-\end{multicols}
-
-
-\paragraph{External Scheduling}
-
-External scheduling is measured using a cycle of two threads calling and accepting the call using the @waitfor@ statement.
-Figure~\ref{f:ext-sched} shows the code for \CFA, with results in Table~\ref{tab:ext-sched}.
-Note, the incremental cost of bulk acquire for \CFA, which is largely a fixed cost for small numbers of mutex objects.
-
-\begin{multicols}{2}
-\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
-\vspace*{-16pt}
-\begin{cfa}
-volatile int go = 0;
-@monitor@ M {} m;
-thread T {};
-void __attribute__((noinline))
-do_call( M & @mutex@ ) {}
-void main( T & ) {
-	while ( go == 0 ) { yield(); }
-	while ( go == 1 ) { do_call( m ); }
-}
-int __attribute__((noinline))
-do_wait( M & @mutex@ m ) {
-	go = 1;	// continue other thread
-	BENCH( for ( N ) { @waitfor( do_call, m );@ } )
-	go = 0;	// stop other thread
-	sout | result`ns;
-}
-int main() {
-	T t;
-	do_wait( m );
-}
-\end{cfa}
-\captionof{figure}{\CFA external-scheduling benchmark}
-\label{f:ext-sched}
-
-\columnbreak
-
-\vspace*{-16pt}
-\captionof{table}{External-scheduling comparison (nanoseconds)}
-\label{tab:ext-sched}
-\begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
-\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
-\uC @_Accept@				& 358		& 359.11	& 2.53		\\
-\CFA @waitfor@, 1 @monitor@	& 359		& 360.93	& 4.07		\\
-\CFA @waitfor@, 2 @monitor@	& 450		& 449.39	& 6.62		\\
-\CFA @waitfor@, 4 @monitor@	& 652		& 655.64	& 7.73
+test and test-and-test lock		& 19.1	& 19.0	& 0.36	\\
+\CFA @mutex@ function, 1 arg.	& 46.6	& 46.8	& 0.86	\\
+\CFA @mutex@ function, 2 arg.	& 84.1	& 85.3	& 1.86	\\
+\CFA @mutex@ function, 4 arg.	& 158.6	& 160.7	& 3.07	\\
+\uC @monitor@ member rtn.		& 54.0	& 53.7	& 0.83	\\
+Java synchronized method		& 27.0	& 27.1	& 0.25	\\
+Pthreads Mutex Lock				& 33.6	& 32.7	& 1.12
 \end{tabular}
 \end{multicols}
Index: driver/cc1.cc
===================================================================
--- driver/cc1.cc	(revision c1398e48a1e93cff3edc8dfe33ad1453eead9738)
+++ driver/cc1.cc	(revision 08c07801e1668d4ca42622537be1cac070b58ab4)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// cc1.cc -- 
+// cc1.cc --
 //
 // Author           : Peter A. Buhr
@@ -107,5 +107,5 @@
 	if ( tmpfilefd != -1 ) {							// RACE, file created ?
 		rmtmpfile();									// remove
-		exit( EXIT_FAILURE );							// terminate 
+		exit( EXIT_FAILURE );							// terminate
 	} // if
 } // sigTermHandler
@@ -360,5 +360,5 @@
 
 		#ifdef __DEBUG_H__
-		cerr << "cfa-cpp ncargs: " << o_name << " " << CFA_flag << " " << ncargs << endl;
+		cerr << "cfa-cpp ncargs: " << (o_name ? o_name : "No -o") << " " << CFA_flag << " " << ncargs << endl;
 		for ( int i = 0; cargs[i] != NULL; i += 1 ) {
 			cerr << cargs[i] << " ";
Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision c1398e48a1e93cff3edc8dfe33ad1453eead9738)
+++ src/AST/Convert.cpp	(revision 08c07801e1668d4ca42622537be1cac070b58ab4)
@@ -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 08c07801e1668d4ca42622537be1cac070b58ab4)
@@ -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 08c07801e1668d4ca42622537be1cac070b58ab4)
@@ -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 08c07801e1668d4ca42622537be1cac070b58ab4)
@@ -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 08c07801e1668d4ca42622537be1cac070b58ab4)
@@ -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 08c07801e1668d4ca42622537be1cac070b58ab4)
@@ -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
Index: tests/sum.cfa
===================================================================
--- tests/sum.cfa	(revision c1398e48a1e93cff3edc8dfe33ad1453eead9738)
+++ tests/sum.cfa	(revision 08c07801e1668d4ca42622537be1cac070b58ab4)
@@ -35,4 +35,5 @@
 
 int main( void ) {
+#if 0
 	const int low = 5, High = 15, size = High - low;
 
@@ -121,4 +122,92 @@
 		 | sum( size, gs.x ) | ", check" | (int)s;		// add field array in generic type
 	delete( gs.x );
+#else
+	const int low = 5, High = 15, size = High - low;
+
+	signed char s = 0, a[size], v = (char)low;
+	for ( int i = 0; i < size; i += 1, v += 1hh ) {
+		s += v;
+		a[i] = v;
+	} // for
+	printf( "sum from %d to %d is %hhd, check %hhd\n", low, High,
+		 sum( size, (signed char *)a ), (signed char)s );
+
+	unsigned char s = 0, a[size], v = low;
+	for ( int i = 0; i < size; i += 1, v += 1hhu ) {
+		s += (unsigned char)v;
+		a[i] = (unsigned char)v;
+	} // for
+	printf( "sum from %d to %d is %hhu, check %hhu\n", low, High,
+		 sum( size, (unsigned char *)a ), (unsigned char)s );
+
+	short int s = 0, a[size], v = low;
+	for ( int i = 0; i < size; i += 1, v += 1h ) {
+	 	s += (short int)v;
+	 	a[i] = (short int)v;
+	} // for
+	printf( "sum from %d to %d is %hd, check %hd\n", low, High,
+		 sum( size, (short int *)a ), (short int)s );
+
+	int s = 0, a[size], v = low;
+	for ( int i = 0; i < size; i += 1, v += 1 ) {
+		s += (int)v;
+		a[i] = (int)v;
+	} // for
+	printf( "sum from %d to %d is %d, check %d\n", low, High,
+		 sum( size, (int *)a ), (int)s );
+
+	float s = 0.0f, a[size], v = low / 10.0f;
+	for ( int i = 0; i < size; i += 1, v += 0.1f ) {
+		s += (float)v;
+		a[i] = (float)v;
+	} // for
+	printf( "sum from %g to %g is %g, check %g\n", low / 10.0f, High / 10.0f,
+		 sum( size, (float *)a ), (float)s );
+
+	double s = 0.0, a[size], v = low / 10.0;
+	for ( int i = 0; i < size; i += 1, v += 0.1 ) {
+		s += (double)v;
+		a[i] = (double)v;
+	} // for
+	printf( "sum from %g to %g is %g, check %g\n", low / 10.0f, High / 10.0f,
+		 sum( size, (double *)a ), (double)s );
+
+	struct S { int i, j; };
+	void ?{}( S & s ) { s.[i, j] = 0; }
+	void ?{}( S & s, int i ) { s.[i, j] = [i, 0]; }
+	void ?{}( S & s, int i, int j ) { s.[i, j] = [i, j]; }
+	void ?{}( S & s, zero_t ) { s.[i, j] = 0; }
+	void ?{}( S & s, one_t ) { s.[i, j] = 1; }
+	S ?+?( S t1, S t2 ) { return (S){ t1.i + t2.i, t1.j + t2.j }; }
+	S ?+=?( S & t1, S t2 ) { t1 = t1 + t2; return t1; }
+	S ++?( S & t ) { t += (S){1}; return t; }
+	S ?++( S & t ) { S temp = t; t += (S){1}; return temp; }
+	ofstream & ?|?( ofstream & os, S v ) { return os | v.i | v.j; }
+	void ?|?( ofstream & os, S v ) { (ofstream &)(os | v); nl( os ); }
+
+	S s = (S){0}, a[size], v = { low, low };
+	for ( int i = 0; i < size; i += 1, v += (S){1} ) {
+		s += (S)v;
+		a[i] = (S)v;
+	} // for
+	printf( "sum from %d to %d is %d %d, check %d %d\n", low, High,
+		 sum( size, (S *)a ).[i, j], s.[i, j] );
+
+	forall( otype Impl | sumable( Impl ) )
+	struct GS {
+		Impl * x, * y;
+	};
+	GS(int) gs;
+	// FIX ME, resolution problem with anew not picking up the LH type
+	gs.x = (typeof(gs.x))anew( size );					// create array storage for field
+	s = 0; v = low;
+	for ( int i = 0; i < size; i += 1, v += 1 ) {
+		s += (int)v;
+		gs.x[i] = (int)v;								// set field array in generic type
+	} // for
+	printf( "sum from %d to %d is %d, check %d\n", low, High,
+		 sum( size, gs.x ), (int)s );		// add field array in generic type
+	delete( gs.x );
+#endif
 } // main
 
