private NamedTypeSymbol RetargetNamedTypeDefinitionFromUnderlyingAssembly(NamedTypeSymbol type)
            {
                // The type is defined in the underlying assembly.
                var module = type.ContainingModule;

                if (ReferenceEquals(module, this.UnderlyingModule))
                {
                    Debug.Assert(module.Ordinal == 0);
                    Debug.Assert(!type.IsExplicitDefinitionOfNoPiaLocalType);
                    var container = type.ContainingType;

                    while ((object)container != null)
                    {
                        if (container.IsExplicitDefinitionOfNoPiaLocalType)
                        {
                            // Types nested into local types are not supported.
                            return((NamedTypeSymbol)this.SymbolMap.GetOrAdd(type, new UnsupportedMetadataTypeSymbol()));
                        }

                        container = container.ContainingType;
                    }

                    return((NamedTypeSymbol)this.SymbolMap.GetOrAdd(type, _retargetingModule._createRetargetingNamedType));
                }
                else
                {
                    // The type is defined in one of the added modules
                    Debug.Assert(module.Ordinal > 0);
                    CSharpModuleSymbol addedModule = (CSharpModuleSymbol)this.RetargetingAssembly.Modules[module.Ordinal];
                    Debug.Assert(ReferenceEquals(((CSharpModuleSymbol)module).Module, addedModule.Module));
                    return(RetargetNamedTypeDefinition((CSharpNamedTypeSymbol)type, addedModule));
                }
            }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="underlyingAssembly">
        /// The underlying AssemblySymbol, cannot be an instance of RetargetingAssemblySymbol.
        /// </param>
        /// <param name="isLinked">
        /// Assembly is /l-ed by compilation that is using it as a reference.
        /// </param>
        internal RetargetingAssemblySymbol(SourceAssemblySymbol underlyingAssembly, bool isLinked)
        {
            Debug.Assert((object)underlyingAssembly != null);

            _underlyingAssembly = underlyingAssembly;

            ModuleSymbol[] modules = new ModuleSymbol[underlyingAssembly.Modules.Length];

            modules[0] = new RetargetingModuleSymbol(this, (SourceModuleSymbol)underlyingAssembly.Modules[0]);

            for (int i = 1; i < underlyingAssembly.Modules.Length; i++)
            {
                CSharpModuleSymbol under = (CSharpModuleSymbol)underlyingAssembly.Modules[i];
                modules[i] = new CSharpModuleSymbol(this, under.UnderlyingModule, i);
            }

            _modules  = modules.AsImmutableOrNull();
            _isLinked = isLinked;
        }
            private static NamedTypeSymbol RetargetNamedTypeDefinition(CSharpNamedTypeSymbol type, CSharpModuleSymbol addedModule)
            {
                Debug.Assert(!type.ContainingModule.Equals(addedModule) &&
                             ReferenceEquals(((CSharpModuleSymbol)type.ContainingModule).Module, addedModule.Module));

                TypeSymbol cached;

                if (addedModule.CSharpSymbolMap.TryGetSymbol(type.CSharpSymbol, out cached))
                {
                    return((NamedTypeSymbol)cached);
                }

                NamedTypeSymbol result;

                NamedTypeSymbol  containingType = type.ContainingType;
                MetadataTypeName mdName;

                if ((object)containingType != null)
                {
                    // Nested type.  We need to retarget
                    // the enclosing type and then go back and get the type we are interested in.

                    NamedTypeSymbol scope = RetargetNamedTypeDefinition((CSharpNamedTypeSymbol)containingType, addedModule);

                    mdName = MetadataTypeName.FromTypeName(type.MetadataName, forcedArity: type.Arity);
                    result = scope.LookupMetadataType(ref mdName);
                    Debug.Assert((object)result != null && result.Arity == type.Arity);
                }
                else
                {
                    string namespaceName = type.ContainingNamespace.ToDisplayString(SymbolDisplayFormat.QualifiedNameOnlyFormat);
                    mdName = MetadataTypeName.FromNamespaceAndTypeName(namespaceName, type.MetadataName, forcedArity: type.Arity);
                    result = addedModule.LookupTopLevelMetadataType(ref mdName);

                    Debug.Assert(result.Arity == type.Arity);
                }

                return(result);
            }