--- a/cmajor++/Cm/Cm.Core/Object.hpp
+++ b/cmajor++/Cm/Cm.Core/Object.hpp
@@ -104,15 +104,24 @@
     object
 };
 
-enum class TypeCheckingPhase { not_typechecked, typechecking_started, typechecking_complete };
+enum class TypeCheckingPhase 
+{ 
+    not_typechecked,        // object is not yet type checked
+    typechecking_started,   // signature of object is type checked
+    typechecking_complete   // body of object is type checked
+};
 
 const int compoundExit  = -1;
 const int noExitEntry = -2;
 
 enum class InstantiationStatus
 {
-    not_instantiated, instantiate, instantiating, instantiated, present
-};
+    not_instantiated,   // object is not instantiated
+    instantiated,       // object is instantiated
+    present             // object is instantiated in used library
+};
+
+const char* GetInstantiationStatusStr(InstantiationStatus instantiationStatus);
 
 class Object: public std::enable_shared_from_this<Object>
 {
@@ -125,6 +134,7 @@
     const std::string& Name() const { return name; }
     virtual void SetName(const std::string& newName);
     virtual std::string FullName() const;
+    void SetFullNameCache(const std::string& fullName_) const { fullNameCache = fullName_; }
     virtual std::string FullNameWithConstraint() const { return FullName(); }
     virtual std::string FullTypeName() const { return FullName(); }
     virtual std::string ArchetypeName() const { return FullName(); }
@@ -150,6 +160,7 @@
     virtual void AddToScope(bool set);
     virtual void TypeCheckName(TypeCheckContext& context);
     virtual void TypeCheckSignature(TypeCheckContext& context);
+    virtual void TypeCheckDeferred(TypeCheckContext& context);
     virtual void TypeCheckBody(TypeCheckContext& context);
     virtual ArgumentCategory GetArgumentCategory() const { return ArgumentCategory::rvalue; }
     virtual ObjectPtr Instantiate(ExpressionList& templateArguments, TypeCheckContext& context);
@@ -303,16 +314,16 @@
     void SetIrObject(Llvm::Ir::ObjectPtr irObject_) { irObject = irObject_; }
     void SetLibrary(LibraryPtr library_) { library = library_; }
     LibraryPtr GetLibrary() const { return library; }
-    virtual void SetCompilationUnit(CompilationUnitPtr compilationUnit_) { compilationUnit = compilationUnit_; }
-    CompilationUnitPtr GetCompilationUnit() const { return compilationUnit.lock(); }
-    void SetCompilationUnitInstantiatedFrom(CompilationUnitPtr compilationUnitInstantiatedFrom_) { compilationUnitInstantiatedFrom = compilationUnitInstantiatedFrom_; }
-    CompilationUnitPtr GetCompilationUnitInstantiatedFrom() const { return compilationUnitInstantiatedFrom.lock(); }
+    virtual void SetCompilationUnit(CompilationUnitPtr) {}
+    virtual CompilationUnitPtr GetCompilationUnit() const { return CompilationUnitPtr(); }
+    virtual void SetCompilationUnitInstantiatedFrom(CompilationUnitPtr) {}
+    virtual CompilationUnitPtr GetCompilationUnitInstantiatedFrom() const { return CompilationUnitPtr(); }
     Llvm::Ir::ObjectPtr GetIrObject() const { return irObject; }
     virtual GenResult Gen(Ir& ir, GenFlags flags);
     virtual void Generate(Ir& ir, GenResult& result);
     virtual void GenerateIntermediateCode(CodeFormatter& formatter);
-    virtual void CollectExternalObjects(CompilationUnitPtr compilationUnit, ObjectSet& externalObjects, bool deep);
-    virtual void GenerateExternalDeclaration(CodeFormatter& formatter);
+    virtual void CollectExternalObjects(CompilationUnitPtr compilationUnit);
+    virtual void GenerateExternalDeclarations(CodeFormatter& formatter, CompilationUnitPtr forCompilationUnit);
     virtual void GenerateLibraryDeclarations(CodeFormatter& formatter);
     virtual void Evaluate(ObjectStack& stack);
     void SetIndex(int index_) { index = index_; }
@@ -323,7 +334,6 @@
     virtual std::string InstanceFileName() const { return TypeDocName(); }
     virtual void SetInstanceFileName(const std::string& instanceFileName);
     void AddArchetypes(const ExpressionList& archetypes_, ConceptPtr concept);
-    virtual void CheckIfCanThrow(bool& canThrow, TypeCheckContext& context);
     virtual void Print(CodeFormatter& formatter);
     virtual void AddArgumentsToContext(TypeCheckContext& context) {}
     virtual ObjectPtr ResolveDelegateArgs(ScopeLookupSet& scopes, bool& scopesSet, bool& resolveDelegate);
@@ -338,6 +348,7 @@
 private:
     bool disposed;
     std::string name;
+    mutable std::string fullNameCache;
     Position pos;
     Position originalPos;
     WeakScopePtr enclosingScope;
@@ -351,10 +362,7 @@
     bool addedToScope;
     LibraryPtr library;
     Llvm::Ir::ObjectPtr irObject;
-    WeakCompilationUnitPtr compilationUnit;
-    WeakCompilationUnitPtr compilationUnitInstantiatedFrom;
     int index;
-    std::set<std::pair<CompilationUnitPtr, bool>> externalObjectCollectionInfo;
     ExpressionList archetypes;
     std::vector<ConceptPtr> concepts;
     std::string libraryName;