/// <summary>
        /// Creates the appropriate kind of type definition (nested or not) and
        /// adds it to the type symbol cache.
        /// </summary>
        private NamedTypeDefinition CreateTypeDefinition(R.INamedTypeSymbol typeSymbol)
        {
            Contract.Requires(typeSymbol != null);

            NamedTypeDefinition cciType;

            if (typeSymbol.ContainingType == null)
            {
                cciType = new NamespaceTypeDefinition()
                {
                    ContainingUnitNamespace = (IUnitNamespace)this.namespaceSymbolCache[typeSymbol.ContainingNamespace],
                    IsPublic = typeSymbol.DeclaredAccessibility == R.CommonAccessibility.Public,
                };
            }
            else
            {
                cciType = new NestedTypeDefinition()
                {
                    ContainingTypeDefinition = (ITypeDefinition)this.typeSymbolCache[typeSymbol.ContainingType],
                    Visibility = TypeMemberVisibility.Private,
                };
            }
            if (typeSymbol.TypeKind == R.CommonTypeKind.Interface)
            {
                cciType.IsAbstract  = true;
                cciType.IsInterface = true;
            }
            else
            {
                cciType.BaseClasses = new List <ITypeReference> {
                    this.Map(typeSymbol.BaseType)
                };
                cciType.IsBeforeFieldInit = true; // REVIEW: How to determine from typeSymbol?
            }
            cciType.IsClass       = typeSymbol.IsReferenceType;
            cciType.IsValueType   = typeSymbol.IsValueType;
            cciType.IsSealed      = typeSymbol.IsSealed;
            cciType.InternFactory = this.host.InternFactory;
            cciType.Locations     = Helper.WrapLocations(typeSymbol.Locations);
            cciType.Name          = this.host.NameTable.GetNameFor(typeSymbol.Name);

            this.typeSymbolCache.Add(typeSymbol, cciType);
            return(cciType);
        }
        private NamedTypeDefinition TranslateMetadata(R.INamedTypeSymbol typeSymbol)
        {
            Contract.Requires(typeSymbol != null);
            Contract.Ensures(Contract.Result <NamedTypeDefinition>() != null);

            NamedTypeDefinition cciType;
            ITypeReference      cciTypeRef;

            if (this.typeSymbolCache.TryGetValue(typeSymbol, out cciTypeRef))
            {
                cciType = (NamedTypeDefinition)cciTypeRef;
            }
            else
            {
                cciType = CreateTypeDefinition(typeSymbol);
            }
            this.module.AllTypes.Add(cciType);

            var mems = new List <ITypeDefinitionMember>();

            foreach (var m in typeSymbol.GetMembers())
            {
                var attributes = this.TranslateMetadata(m.GetAttributes());

                switch (m.Kind)
                {
                case CommonSymbolKind.Field:
                    var field = TranslateMetadata(m as FieldSymbol);
                    field.Attributes = attributes;
                    if (cciType.Fields == null)
                    {
                        cciType.Fields = new List <IFieldDefinition>();
                    }
                    cciType.Fields.Add(field);
                    break;

                case CommonSymbolKind.Method:
                    var methodSymbol = m as MethodSymbol;
                    var meth         = TranslateMetadata(methodSymbol);
                    meth.Attributes = attributes;
                    if (cciType.Methods == null)
                    {
                        cciType.Methods = new List <IMethodDefinition>();
                    }
                    cciType.Methods.Add(meth);
                    break;

                case CommonSymbolKind.NamedType:
                    var namedType = TranslateMetadata((R.INamedTypeSymbol)m);
                    Contract.Assert(namedType is NestedTypeDefinition);
                    var nestedType = (NestedTypeDefinition)namedType;
                    nestedType.Attributes = attributes;
                    if (cciType.NestedTypes == null)
                    {
                        cciType.NestedTypes = new List <INestedTypeDefinition>();
                    }
                    cciType.NestedTypes.Add((NestedTypeDefinition)nestedType);
                    break;

                case CommonSymbolKind.Property:
                    var property = TranslateMetadata(m as PropertySymbol);
                    property.Attributes = attributes;
                    if (cciType.Properties == null)
                    {
                        cciType.Properties = new List <IPropertyDefinition>();
                    }
                    cciType.Properties.Add(property);
                    break;

                default:
                    throw new NotImplementedException();
                }
            }

            if (typeSymbol.IsValueType)
            {
                cciType.Layout = LayoutKind.Sequential;
                if (IteratorHelper.EnumerableIsEmpty(cciType.Fields))
                {
                    cciType.SizeOf = 1;
                }
            }

            return(cciType);
        }