--- a/cmajor++/Cm/Cm.Core/DerivedType.cpp
+++ b/cmajor++/Cm/Cm.Core/DerivedType.cpp
@@ -55,7 +55,7 @@
 
 ReferenceTypeDirectoryPtr ReferenceTypeDirectory::Instance()
 {
-    CM_CORE_ASSERT(instance);
+    CM_CORE_ASSERT(instance, nullptr);
     return instance;
 }
 
@@ -164,11 +164,9 @@
     return ObjectPtr();
 }
 
-void DerivedType::CollectExternalObjects(CompilationUnitPtr compilationUnit, ObjectSet& externalObjects, bool deep)
-{
-    if (ExternalObjectsCollected(compilationUnit, deep)) return;
-    Type::CollectExternalObjects(compilationUnit, externalObjects, deep);
-    baseType.lock()->CollectExternalObjects(compilationUnit, externalObjects, deep);
+void DerivedType::CollectExternalObjects(CompilationUnitPtr compilationUnit)
+{
+    baseType.lock()->CollectExternalObjects(compilationUnit);
 }
 
 ConstType::ConstType(const Position& pos_, const ScopePtr& enclosingScope_, const ScopePtr& fileScope_, const ObjectPtr& baseTypeExpr_):
@@ -197,6 +195,13 @@
     SetIrType(baseType->IrType());
 }
 
+std::string ConstType::FullName() const 
+{ 
+    std::string fullName = "const " + (GetBaseType() ? GetBaseType()->FullName() : GetBaseTypeExpr()->FullName()); 
+    SetFullNameCache(fullName);
+    return fullName;
+}
+
 std::string ConstType::TypeDocName() const
 {
     return GetBaseTypeExpr()->TypeDocName() + ".const";
@@ -284,12 +289,16 @@
             baseType = constType->GetBaseType();
             if (baseType)
             {
-                return "const " + baseType->FullName() + "&";
+                std::string fullName = "const " + baseType->FullName() + "&";
+                SetFullNameCache(fullName);
+                return fullName;
             }
             else
             {
                 ObjectPtr baseTypeExpr = constType->GetBaseTypeExpr();
-                return "const " + baseTypeExpr->FullName() + "&";
+                std::string fullName = "const " + baseTypeExpr->FullName() + "&";
+                SetFullNameCache(fullName);
+                return fullName;
             }
         }
     }
@@ -302,16 +311,22 @@
             baseType = constType->GetBaseType();
             if (baseType)
             {
-                return "const " + baseType->FullName() + "&";
+                std::string fullName = "const " + baseType->FullName() + "&";
+                SetFullNameCache(fullName);
+                return fullName;
             }
             else
             {
                 ObjectPtr baseTypeExpr = constType->GetBaseTypeExpr();
-                return "const " + baseTypeExpr->FullName() + "&";
-            }
-        }
-    }
-    return (GetBaseType() ? GetBaseType()->FullName() : GetBaseTypeExpr()->FullName()) + "&"; 
+                std::string fullName = "const " + baseTypeExpr->FullName() + "&";
+                SetFullNameCache(fullName);
+                return fullName;
+            }
+        }
+    }
+    std::string fullName = (GetBaseType() ? GetBaseType()->FullName() : GetBaseTypeExpr()->FullName()) + "&"; 
+    SetFullNameCache(fullName);
+    return fullName;
 }
 
 void ReferenceType::TypeCheckName(TypeCheckContext& context)
@@ -385,10 +400,10 @@
             SetName(GetBaseType()->FullName() + "&");
         }
         AddToScope(false);
-        bool createCopyCtor = true;
+        bool createCopyCtorAndAssignment = true;
         if (baseType->IsTemplateParameter())
         {
-            createCopyCtor = false;
+            createCopyCtorAndAssignment = false;
         }
         else if (GetBaseType()->IsPointerType())
         {
@@ -396,16 +411,18 @@
             TypePtr baseType = ptrType->GetBaseType();
             if (baseType->IsReferenceType() || baseType->IsPointerType())
             {
-                createCopyCtor = false;
-            }
-        }
-        if (createCopyCtor)
+                createCopyCtorAndAssignment = false;
+            }
+        }
+        if (createCopyCtorAndAssignment)
         {
             FunctionPtr referenceCopyCtor = CreateCopyCtor(thisType);
             std::vector<FunctionPtr> referenceOps;
             referenceOps.push_back(referenceCopyCtor);
             FunctionPtr plainRefCtor = CreatePlainRefCtor(thisType, baseType);
             referenceOps.push_back(plainRefCtor);
+            FunctionPtr referenceAssignment = CreateAssignmentOp(thisType);
+            referenceOps.push_back(referenceAssignment);
             AddFunctionsToScope(referenceOps);
         }
     }