//
        // Main routine to resolve a typeReference.
        //
        private static RuntimeTypeInfo TryResolveTypeReference(this TypeReferenceHandle typeReferenceHandle, MetadataReader reader, ref Exception exception)
        {
            TypeReference typeReference   = reader.GetTypeReference(typeReferenceHandle);
            EntityHandle  resolutionScope = typeReference.ResolutionScope;

            if (resolutionScope.IsNil)
            {
                // Search for an entry in the exported type table for this type
                return(TryResolveTypeByName(reader, typeReference.GetFullyQualifiedTypeName(reader), ref exception));
            }

            switch (resolutionScope.Kind)
            {
            case HandleKind.ModuleReference:
                // multi-module assemblies are not supported by this runtime
                exception = new PlatformNotSupportedException();
                return(null);

            case HandleKind.TypeReference:
            {
                // This is a nested type. Find the enclosing type, then search for a matching nested type
                RuntimeTypeInfo enclosingType = ((TypeReferenceHandle)typeReference.ResolutionScope).TryResolveTypeReference(reader, ref exception);
                if (enclosingType == null)
                {
                    Debug.Assert(exception != null);
                    return(null);
                }
                MetadataStringComparer stringComparer = reader.StringComparer;
                foreach (var nestedType in enclosingType.GetNestedTypes())
                {
                    if (stringComparer.Equals(typeReference.Name, nestedType.Name))
                    {
                        if (stringComparer.Equals(typeReference.Namespace, nestedType.Namespace))
                        {
                            return((RuntimeTypeInfo)nestedType.GetTypeInfo());
                        }
                    }
                }
                exception = ReflectionCoreExecution.ExecutionDomain.CreateMissingMetadataException(enclosingType, reader.GetString(typeReference.Name));
                return(null);
            }

            case HandleKind.AssemblyReference:
            {
                string fullName = typeReference.GetFullyQualifiedTypeName(reader);

                RuntimeAssemblyName runtimeAssemblyName = ((AssemblyReferenceHandle)resolutionScope).ToRuntimeAssemblyName(reader);
                RuntimeAssembly     runtimeAssembly;
                exception = RuntimeAssembly.TryGetRuntimeAssembly(runtimeAssemblyName, out runtimeAssembly);
                if (exception != null)
                {
                    return(null);
                }
                RuntimeTypeInfo runtimeType = runtimeAssembly.GetTypeCore(fullName, ignoreCase: false);
                if (runtimeType == null)
                {
                    exception = Helpers.CreateTypeLoadException(fullName, runtimeAssemblyName.FullName);
                    return(null);
                }
                return(runtimeType);
            }

            case HandleKind.ModuleDefinition:
                return(TryResolveTypeByName(reader, typeReference.GetFullyQualifiedTypeName(reader), ref exception));

            default:
                exception = new BadImageFormatException();
                return(null);
            }
        }