/// <summary>
        /// Assigns the generic blueprint and the type arguments to the generic instance type.
        /// </summary>
        /// <param name="conversion"></param>
        /// <param name="converted"></param>
        /// <param name="convertedDeclaringType"></param>
        /// <returns></returns>
        public void Build(ILConversion conversion, ConvertedTypeDefinition_I converted, ConvertedTypeDefinition_I convertedDeclaringType)
        {
            //Done on purpose to find errors
            var typeDefinition = (TypeDefinition)converted.SourceTypeReference;

            System.Reflection.TypeAttributes attributes = Cecil.Metadata.Members.Types.GetTypeAttributes(typeDefinition);

            if (converted is ConvertedTypeDefinitionWithDeclaringType_I withDeclaringType)
            {
                var packingSize = Cecil.GetPackingSize(typeDefinition);

                if (convertedDeclaringType == null)                 // Can occur if passing in a single nested type or if a nested class gets processed before its parents gets
                // processed.
                {
                    if (!(converted.SourceTypeReference is TypeDefinition))
                    {
                        throw new Exception("Expected a type definition");
                    }

                    var semanticDeclaringType = Execution.Types.Ensuring.Ensure(conversion, converted.SourceTypeReference.DeclaringType, null, null);

                    if (!(semanticDeclaringType is ConvertedTypeDefinition_I producedDeclaringType))
                    {
                        throw new Exception($"Expected the declaring type of a nested class to be castable to {typeof(ConvertedTypeDefinition_I)}");
                    }

                    convertedDeclaringType = producedDeclaringType;
                }

                withDeclaringType.DeclaringType = convertedDeclaringType;

                // The plus sign and the parent class name before it needs to be dropped from the full name prior to calling define nested class
                // as the type builder will automatically add them back on based upon the name of the declaring type.
                var fullName = Types.Naming.GetTypeBuilderNestedClassFullName(converted.FullName);

                converted.TypeBuilder = convertedDeclaringType.TypeBuilder.DefineNestedType(fullName, attributes, null, packingSize);
            }
            else
            {
                if (converted.FullName == "<Module>")
                {
                    var x = converted.Module.ModuleBuilder.GetType("<Module>", true);
                }

                converted.TypeBuilder = converted.Module.ModuleBuilder.DefineType(converted.FullName, attributes);
            }

            converted.UnderlyingType = converted.TypeBuilder;

            this.Unified.Types.ExtendWithCrossReference(conversion.RuntimicSystem, converted, converted.UnderlyingType.AssemblyQualifiedName);

            Types.Building.UpdateBuildPhase(converted, BuildPhaseKind.TypeDefined);
        }
        private void Converted_BuildPhase1(ILConversion conversion, StructuralTypeNode structuralInputTypeNode, ConvertedTypeDefinition converted,
                                           ConvertedTypeDefinition_I convertedDeclaringType)
        {
            var typeDefinition = (TypeDefinition)structuralInputTypeNode.CecilTypeReference;

            System.Reflection.TypeAttributes attributes = Cecil.Metadata.Members.Types.GetTypeAttributes(typeDefinition);

            var packingSize = Cecil.GetPackingSize(typeDefinition);

            if (converted is ConvertedTypeDefinitionWithDeclaringType_I withDeclaringType)
            {
                if (convertedDeclaringType == null
                    )                     // Can occur if passing in a single nested type or if a nested class gets processed before its parents gets
                                          // processed.
                {
                    if (!(converted.SourceTypeReference is TypeDefinition))
                    {
                        throw new Exception("Expected a type definition");
                    }

                    var semanticDeclaringType =
                        Execution.Types.Ensuring.Ensure(conversion, converted.SourceTypeReference.DeclaringType, null,
                                                        null);

                    if (!(semanticDeclaringType is ConvertedTypeDefinition_I producedDeclaringType))
                    {
                        throw new Exception(
                                  $"Expected the declaring type of a nested class to be castable to {typeof(ConvertedTypeDefinition_I)}");
                    }

                    convertedDeclaringType = producedDeclaringType;
                }

                withDeclaringType.DeclaringType = convertedDeclaringType;

                // The plus sign and the parent class name before it needs to be dropped from the full name prior to calling define nested class
                // as the type builder will automatically add them back on based upon the name of the declaring type.
                var fullName = Conversion.Metadata.Members.Types.Naming.GetTypeBuilderNestedClassFullName(converted.FullName);

                // The !IsEnum check prevents: [MD]: Error: ClassLayout has parent TypeDef token=0x02000036 marked AutoLayout. [token:0x00000001]
                // The Class or ValueType indexed by Parent shall be SequentialLayout or ExplicitLayout (§II.23.1.15).
                // That is, AutoLayout types shall not own any rows in the ClassLayout table. [ERROR]
                if (typeDefinition.IsValueType && !typeDefinition.IsEnum)
                {
                    converted.TypeBuilder = convertedDeclaringType.TypeBuilder.DefineNestedType(converted.FullName, attributes, null, (PackingSize)typeDefinition.PackingSize, typeDefinition.ClassSize);
                }
                else
                {
                    converted.TypeBuilder = convertedDeclaringType.TypeBuilder.DefineNestedType(fullName, attributes, null, packingSize);
                }
            }
            else
            {
                if (converted.FullName == "Root.Testing.Resources.Models.E01D.Runtimic.Execution.Emitting.Conversion.Inputs.Types.SimpleValueType")
                {
                }

                if (converted.FullName == "<Module>")
                {
                    var x = converted.Module.ModuleBuilder.GetType("<Module>", true);
                }

                // The !IsEnum check prevents: [MD]: Error: ClassLayout has parent TypeDef token=0x02000036 marked AutoLayout. [token:0x00000001]
                // The Class or ValueType indexed by Parent shall be SequentialLayout or ExplicitLayout (§II.23.1.15).
                // That is, AutoLayout types shall not own any rows in the ClassLayout table. [ERROR]
                if (typeDefinition.IsValueType && !typeDefinition.IsEnum)
                {
                    converted.TypeBuilder = converted.Module.ModuleBuilder.DefineType(converted.FullName, attributes, null, (PackingSize)typeDefinition.PackingSize, typeDefinition.ClassSize);
                }
                else
                {
                    converted.TypeBuilder = converted.Module.ModuleBuilder.DefineType(converted.FullName, attributes, null, packingSize);
                }
            }

            converted.UnderlyingType = converted.TypeBuilder;

            //this.Unified.Types.ExtendWithCrossReference(conversion.Model, converted,
            //	converted.UnderlyingType.AssemblyQualifiedName);

            Conversion.Metadata.Members.Types.Building.UpdateBuildPhase(converted, BuildPhaseKind.TypeDefined);
        }