Index: src/CodeGen/CodeGenerator.cc
===================================================================
--- src/CodeGen/CodeGenerator.cc	(revision 7ebaa561f92e838ec05df234d5162f761db9e87f)
+++ src/CodeGen/CodeGenerator.cc	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -182,4 +182,5 @@
 			genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() );
 			output << ")" << endl;
+			output << indent;
 		}
 
@@ -321,6 +322,10 @@
 	void CodeGenerator::visit( __attribute__((unused)) ConstructorInit * init ){
 		assertf( ! genC, "ConstructorInit nodes should not reach code generation." );
-		// xxx - generate something reasonable for constructor/destructor pairs
-		output << "<ctorinit>";
+		// pseudo-output for constructor/destructor pairs
+		output << "<ctorinit>{" << std::endl << ++indent << "ctor: ";
+		maybeAccept( init->get_ctor(), *this );
+		output << ", " << std::endl << indent << "dtor: ";
+		maybeAccept( init->get_dtor(), *this );
+		output << std::endl << --indent << "}";
 	}
 
Index: src/CodeGen/CodeGenerator.h
===================================================================
--- src/CodeGen/CodeGenerator.h	(revision 7ebaa561f92e838ec05df234d5162f761db9e87f)
+++ src/CodeGen/CodeGenerator.h	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -20,4 +20,6 @@
 #include <ostream>                // for ostream, operator<<
 #include <string>                 // for string
+
+#include "Common/Indenter.h"      // for Indenter
 
 #include "SynTree/Declaration.h"  // for DeclarationWithType (ptr only), Fun...
Index: src/Parser/DeclarationNode.cc
===================================================================
--- src/Parser/DeclarationNode.cc	(revision 7ebaa561f92e838ec05df234d5162f761db9e87f)
+++ src/Parser/DeclarationNode.cc	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -770,5 +770,5 @@
 DeclarationNode * DeclarationNode::addNewPointer( DeclarationNode * p ) {
 	if ( p ) {
-		assert( p->type->kind == TypeData::Pointer );
+		assert( p->type->kind == TypeData::Pointer || p->type->kind == TypeData::Reference );
 		if ( type ) {
 			switch ( type->kind ) {
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 7ebaa561f92e838ec05df234d5162f761db9e87f)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -815,9 +815,10 @@
 
 	Expression * restructureCast( Expression * argExpr, Type * toType ) {
-		if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() ) {
-			// Argument expression is a tuple and the target type is not void. Cast each member of the tuple
-			// to its corresponding target type, producing the tuple of those cast expressions. If there are
-			// more components of the tuple than components in the target type, then excess components do not
-			// come out in the result expression (but UniqueExprs ensure that side effects will still be done).
+		if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() && ! dynamic_cast<ReferenceType *>( toType ) ) {
+			// Argument expression is a tuple and the target type is not void and not a reference type.
+			// Cast each member of the tuple to its corresponding target type, producing the tuple of those
+			// cast expressions. If there are more components of the tuple than components in the target type,
+			// then excess components do not come out in the result expression (but UniqueExprs ensure that
+			// side effects will still be done).
 			if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) {
 				// expressions which may contain side effects require a single unique instance of the expression.
Index: src/ResolvExpr/CommonType.cc
===================================================================
--- src/ResolvExpr/CommonType.cc	(revision 7ebaa561f92e838ec05df234d5162f761db9e87f)
+++ src/ResolvExpr/CommonType.cc	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -81,13 +81,18 @@
 		CommonType visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
 
-		ReferenceType * refType1 = dynamic_cast< ReferenceType * >( type1 );
-		ReferenceType * refType2 = dynamic_cast< ReferenceType * >( type2 );
-		if ( (refType1 || refType2) && (! refType1 || ! refType2) ) {
-			// handle the case where exactly one of the types is a reference type specially
-			if ( refType1 ) {
-				return handleReference( refType1, type2, widenFirst, widenSecond, indexer, env, openVars );
-			} else if ( refType2 ) {
-				return handleReference( refType2, type1, widenSecond, widenFirst, indexer, env, openVars );
-			}
+		int depth1 = type1->referenceDepth();
+		int depth2 = type2->referenceDepth();
+		if ( depth1 > 0 || depth2 > 0 ) {
+			int diff = depth1-depth2;
+			// TODO: should it be possible for commonType to generate complicated conversions? I would argue no, only conversions that involve types of the same reference level or a difference of 1 should be allowed.
+			if ( diff > 1 || diff < -1 ) return nullptr;
+
+			// special case where one type has a reference depth of 1 larger than the other
+			if ( diff > 0 ) {
+				return handleReference( safe_dynamic_cast<ReferenceType *>( type1 ), type2, widenFirst, widenSecond, indexer, env, openVars );
+			} else if ( diff < 0 ) {
+				return handleReference( safe_dynamic_cast<ReferenceType *>( type2 ), type1, widenSecond, widenFirst, indexer, env, openVars );
+			}
+			// otherwise, both are reference types of the same depth and this is handled by the CommonType visitor.
 		}
 
Index: src/ResolvExpr/Unify.cc
===================================================================
--- src/ResolvExpr/Unify.cc	(revision 7ebaa561f92e838ec05df234d5162f761db9e87f)
+++ src/ResolvExpr/Unify.cc	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -377,4 +377,6 @@
 				} // if
 			} else {
+				common = type1->clone();
+				common->get_qualifiers() = tq1 | tq2;
 				result = true;
 			} // if
Index: src/SynTree/Expression.cc
===================================================================
--- src/SynTree/Expression.cc	(revision 7ebaa561f92e838ec05df234d5162f761db9e87f)
+++ src/SynTree/Expression.cc	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -502,5 +502,5 @@
 }
 
-AsmExpr::AsmExpr( const AsmExpr & other ) : inout( maybeClone( other.inout ) ), constraint( maybeClone( other.constraint ) ), operand( maybeClone( other.operand ) ) {}
+AsmExpr::AsmExpr( const AsmExpr & other ) : Expression( other ), inout( maybeClone( other.inout ) ), constraint( maybeClone( other.constraint ) ), operand( maybeClone( other.operand ) ) {}
 
 
Index: src/SynTree/ReferenceType.cc
===================================================================
--- src/SynTree/ReferenceType.cc	(revision 7ebaa561f92e838ec05df234d5162f761db9e87f)
+++ src/SynTree/ReferenceType.cc	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -19,21 +19,26 @@
 
 ReferenceType::ReferenceType( const Type::Qualifiers &tq, Type *base, const std::list< Attribute * > & attributes )
-  : Type( tq, attributes ), base( base ) {
+	: Type( tq, attributes ), base( base ) {
+	assertf( base, "Reference Type with a null base created." );
 }
 
 ReferenceType::ReferenceType( const ReferenceType &other )
-  : Type( other ), base( maybeClone( other.base ) ) {
+	: Type( other ), base( maybeClone( other.base ) ) {
 }
 
 ReferenceType::~ReferenceType() {
-  delete base;
+	delete base;
+}
+
+int ReferenceType::referenceDepth() const {
+	return base->referenceDepth()+1;
 }
 
 void ReferenceType::print( std::ostream &os, int indent ) const {
-  Type::print( os, indent );
-  os << "reference to ";
-  if ( base ) {
-    base->print( os, indent );
-  } // if
+	Type::print( os, indent );
+	os << "reference to ";
+	if ( base ) {
+		base->print( os, indent );
+	} // if
 }
 
Index: src/SynTree/Type.cc
===================================================================
--- src/SynTree/Type.cc	(revision 7ebaa561f92e838ec05df234d5162f761db9e87f)
+++ src/SynTree/Type.cc	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -81,4 +81,6 @@
 }
 
+int Type::referenceDepth() const { return 0; }
+
 void Type::print( std::ostream &os, int indent ) const {
 	if ( ! forall.empty() ) {
Index: src/SynTree/Type.h
===================================================================
--- src/SynTree/Type.h	(revision 7ebaa561f92e838ec05df234d5162f761db9e87f)
+++ src/SynTree/Type.h	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -163,4 +163,7 @@
 	Type * stripReferences();
 
+	/// return the number of references occuring consecutively on the outermost layer of this type (i.e. do not count references nested within other types)
+	virtual int referenceDepth() const;
+
 	virtual bool isComplete() const { return true; }
 
@@ -304,4 +307,6 @@
 	void set_base( Type *newValue ) { base = newValue; }
 
+	virtual int referenceDepth() const;
+
 	virtual ReferenceType *clone() const { return new ReferenceType( *this ); }
 	virtual void accept( Visitor & v ) { v.visit( this ); }
Index: src/SynTree/TypeExpr.cc
===================================================================
--- src/SynTree/TypeExpr.cc	(revision 7ebaa561f92e838ec05df234d5162f761db9e87f)
+++ src/SynTree/TypeExpr.cc	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -5,5 +5,5 @@
 // file "LICENCE" distributed with Cforall.
 //
-// TypeExpr.cc -- 
+// TypeExpr.cc --
 //
 // Author           : Richard C. Bilson
@@ -21,5 +21,5 @@
 }
 
-TypeExpr::TypeExpr( const TypeExpr &other ) : type( maybeClone( other.type ) ) {
+TypeExpr::TypeExpr( const TypeExpr &other ) : Expression( other ), type( maybeClone( other.type ) ) {
 }
 
Index: src/Tuples/Explode.h
===================================================================
--- src/Tuples/Explode.h	(revision 7ebaa561f92e838ec05df234d5162f761db9e87f)
+++ src/Tuples/Explode.h	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -27,25 +27,7 @@
 
 namespace Tuples {
-	/// helper function used by explode to properly distribute
-	/// '&' across a tuple expression
-	Expression * distributeAddr( Expression * expr );
-
 	/// helper function used by explode
 	template< typename OutputIterator >
 	void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign ) {
-		if ( isTupleAssign ) {
-			// tuple assignment needs AddressExprs to be recursively exploded to easily get at all of the components
-			if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( expr ) ) {
-				ResolvExpr::AltList alts;
-				explodeUnique( addrExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
-				for ( ResolvExpr::Alternative & alt : alts ) {
-					// distribute '&' over all components
-					alt.expr = distributeAddr( alt.expr );
-					*out++ = alt;
-				}
-				// in tuple assignment, still need to handle the other cases, but only if not already handled here (don't want to output too many alternatives)
-				return;
-			}
-		}
 		Type * res = expr->get_result();
 		if ( TupleType * tupleType = dynamic_cast< TupleType * > ( res ) ) {
Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision 7ebaa561f92e838ec05df234d5162f761db9e87f)
+++ src/Tuples/TupleAssignment.cc	(revision e6cee92975ba3e912a537934e3a775bcddc7a9fa)
@@ -77,5 +77,5 @@
 		if ( ! expr ) return false;
 		assert( expr->has_result() );
-		return dynamic_cast< TupleType * >( expr->get_result() );
+		return dynamic_cast< TupleType * >( expr->get_result()->stripReferences() );
 	}
 
@@ -89,10 +89,11 @@
 	}
 
-	bool pointsToTuple( Expression *expr ) {
+	bool refToTuple( Expression *expr ) {
+		assert( expr->get_result() );
 		// also check for function returning tuple of reference types
 		if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
-			return pointsToTuple( castExpr->get_arg() );
-		} else if ( AddressExpr *addr = dynamic_cast< AddressExpr * >( expr) ) {
-			return isTuple( addr->get_arg() );
+			return refToTuple( castExpr->get_arg() );
+		} else {
+			return isTuple( expr );
 		}
 		return false;
@@ -122,5 +123,5 @@
 					const ResolvExpr::Alternative & alt1 = ali->front();
 					auto begin = std::next(ali->begin(), 1), end = ali->end();
-					if ( pointsToTuple(alt1.expr) ) {
+					if ( refToTuple(alt1.expr) ) {
 						if ( isMultAssign( begin, end ) ) {
 							matcher.reset( new MultipleAssignMatcher( *this, *ali ) );
@@ -196,10 +197,7 @@
 			for ( ResolvExpr::Alternative & alt : lhs ) {
 				Expression *& expr = alt.expr;
-				Type * castType = expr->get_result()->clone();
-				Type * type = InitTweak::getPointerBase( castType );
-				assert( type );
+				Type * type = expr->get_result()->clone();
 				type->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
-				type->set_lvalue( true ); // xxx - might not need this
-				expr = new CastExpr( expr, castType );
+				expr = new CastExpr( expr, new ReferenceType( Type::Qualifiers(), type ) );
 			}
 		}
@@ -221,5 +219,5 @@
 		assert( left );
 		std::list< Expression * > args;
-		args.push_back( new AddressExpr( UntypedExpr::createDeref( new VariableExpr( left ) ) ) );
+		args.push_back( new VariableExpr( left ) );
 		// args.push_back( new AddressExpr( new VariableExpr( left ) ) );
 		if ( right ) args.push_back( new VariableExpr( right ) );
@@ -241,9 +239,12 @@
 		assert( expr->has_result() && ! expr->get_result()->isVoid() );
 		ObjectDecl * ret = new ObjectDecl( namer.newName(), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, expr->get_result()->clone(), new SingleInit( expr->clone() ) );
-		ConstructorInit * ctorInit = InitTweak::genCtorInit( ret );
-		ret->set_init( ctorInit );
-		ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object
-		EnvRemover rm; // remove environments from subexpressions of StmtExprs
-		ctorInit->accept( rm );
+		// if expression type is a reference, don't need to construct anything, a simple initializer is sufficient.
+		if ( ! dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
+			ConstructorInit * ctorInit = InitTweak::genCtorInit( ret );
+			ret->set_init( ctorInit );
+			ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object
+			EnvRemover rm; // remove environments from subexpressions of StmtExprs
+			ctorInit->accept( rm );
+		}
 		return ret;
 	}
