/// <summary>
 /// Populates the list of assembly references.
 /// </summary>
 void LoadAssemblyReferences()
   //^ ensures this.AssemblyReferenceArray != null;
 {
   uint numberOfAssemblyReferences = this.PEFileReader.AssemblyRefTable.NumberOfRows;
   AssemblyReference[] assemblyRefList = new AssemblyReference[numberOfAssemblyReferences + 1];
   for (uint i = 1; i <= numberOfAssemblyReferences; ++i) {
     AssemblyRefRow assemblyRefRow = this.PEFileReader.AssemblyRefTable[i];
     IName assemblyRefName = this.GetNameFromOffset(assemblyRefRow.Name);
     IName cultureName = this.GetNameFromOffset(assemblyRefRow.Culture);
     Version version = new Version(assemblyRefRow.MajorVersion, assemblyRefRow.MinorVersion, assemblyRefRow.BuildNumber, assemblyRefRow.RevisionNumber);
     byte[] publicKeyTokenArray = TypeCache.EmptyByteArray;
     if (assemblyRefRow.PublicKeyOrToken != 0) {
       var publicKeyOrTokenArray = this.PEFileReader.BlobStream[assemblyRefRow.PublicKeyOrToken];
       if ((assemblyRefRow.Flags & AssemblyFlags.PublicKey) == AssemblyFlags.PublicKey && publicKeyOrTokenArray.Length > 0) {
         publicKeyTokenArray = UnitHelper.ComputePublicKeyToken(publicKeyOrTokenArray);
       } else {
         publicKeyTokenArray = publicKeyOrTokenArray;
       }
       if (publicKeyTokenArray.Length != 8) {
         //  Error
       }
     }
     AssemblyIdentity assemblyIdentity = new AssemblyIdentity(assemblyRefName, cultureName.Value, version, publicKeyTokenArray, string.Empty);
     AssemblyReference assemblyReference = new AssemblyReference(this, i, assemblyIdentity, assemblyRefRow.Flags);
     assemblyRefList[i] = assemblyReference;
   }
   this.AssemblyReferenceArray = assemblyRefList;
 }
 //  Caller should lock this.
 internal Assembly/*?*/ ResolveAssemblyRefReference(
   AssemblyReference assemblyReference
 ) {
   Assembly/*?*/ assem = this.ModuleReader.LookupAssembly(this.Module, assemblyReference.UnifiedAssemblyIdentity);
   return assem;
 }
    private AssemblyIdentity GetCoreAssemblySymbolicIdentity() {
      lock (GlobalLock.LockingObject) {
        INameTable nameTable = this.NameTable;
        PeReader peReader = this.ModuleReader;
        int systemKey = nameTable.System.UniqueKey;
        int objectKey = nameTable.Object.UniqueKey;
        int valueTypeKey = nameTable.ValueType.UniqueKey;
        int enumKey = nameTable.Enum.UniqueKey;
        int multicastDelegateKey = nameTable.MulticastDelegate.UniqueKey;
        int arrayKey = nameTable.Array.UniqueKey;
        int attributeKey = nameTable.Attribute.UniqueKey;
        int delegateKey = nameTable.Delegate.UniqueKey;
        int iAsyncResultKey = peReader.IAsyncResult.UniqueKey;
        int iCloneableKey = peReader.ICloneable.UniqueKey;
        int asyncCallbackKey = peReader.AsyncCallback.UniqueKey;
        int attributeUsageAttributeKey = nameTable.AttributeUsageAttribute.UniqueKey;
        int paramArrayAttributeKey = peReader.ParamArrayAttribute.UniqueKey;
        int booleanKey = nameTable.Boolean.UniqueKey;
        int byteKey = nameTable.Byte.UniqueKey;
        int charKey = nameTable.Char.UniqueKey;
        int sByteKey = nameTable.SByte.UniqueKey;
        int int16Key = nameTable.Int16.UniqueKey;
        int uint16Key = nameTable.UInt16.UniqueKey;
        int int32Key = nameTable.Int32.UniqueKey;
        int uint32Key = nameTable.UInt32.UniqueKey;
        int int64Key = nameTable.Int64.UniqueKey;
        int uint64Key = nameTable.UInt64.UniqueKey;
        int stringKey = nameTable.String.UniqueKey;
        int intPtrKey = nameTable.IntPtr.UniqueKey;
        int uintPtrKey = nameTable.UIntPtr.UniqueKey;
        int singleKey = nameTable.Single.UniqueKey;
        int doubleKey = nameTable.Double.UniqueKey;
        int typedReferenceKey = nameTable.TypedReference.UniqueKey;
        int typeKey = nameTable.Type.UniqueKey;
        int dateTimeKey = nameTable.DateTime.UniqueKey;
        int decimalKey = nameTable.Decimal.UniqueKey;
        int dbNullKey = nameTable.DBNull.UniqueKey;
        int runtimeArgumentHandleKey = peReader.RuntimeArgumentHandle.UniqueKey;
        int runtimeFieldHandleKey = peReader.RuntimeFieldHandle.UniqueKey;
        int runtimeMethodHandleKey = peReader.RuntimeMethodHandle.UniqueKey;
        int runtimeTypeHandleKey = peReader.RuntimeTypeHandle.UniqueKey;
        int argIteratorKey = peReader.ArgIterator.UniqueKey;
        int voidKey = nameTable.Void.UniqueKey;
        int mscorlibKey = peReader.Mscorlib.UniqueKey;
        int systemRuntimeKey = peReader.System_Runtime.UniqueKey;
        TypeRefTableReader trTable = this.PEFileReader.TypeRefTable;
        var hitCounts = new uint[trTable.NumberOfRows];
        for (uint i = 1; i <= trTable.NumberOfRows; i++) {
          TypeRefRow tr = trTable[i];
          IName nsName = this.GetNameFromOffset(tr.Namespace);
          if (nsName.UniqueKey != systemKey) continue;
          int tKey = this.GetNameFromOffset(tr.Name).UniqueKey;
          //Look for a lot of different mscorlib types, since an assembly need not reference System.Object or any particular type.
          if (tKey != objectKey && tKey != valueTypeKey && tKey != enumKey && tKey != multicastDelegateKey && tKey != arrayKey &&
            tKey != attributeKey && tKey != delegateKey && tKey != iAsyncResultKey && tKey != iCloneableKey && tKey != asyncCallbackKey &&
            tKey != attributeUsageAttributeKey && tKey != paramArrayAttributeKey && tKey != booleanKey && tKey != byteKey && tKey != charKey &&
            tKey != sByteKey && tKey != int16Key && tKey != uint16Key && tKey != int32Key && tKey != uint32Key && tKey != int64Key &&
            tKey != uint64Key && tKey != stringKey && tKey != intPtrKey && tKey != uintPtrKey && tKey != singleKey && tKey != doubleKey &&
            tKey != typedReferenceKey && tKey != typeKey && tKey != dateTimeKey && tKey != decimalKey && tKey != dbNullKey &&
            tKey != runtimeArgumentHandleKey && tKey != runtimeFieldHandleKey && tKey != runtimeMethodHandleKey &&
            tKey != runtimeTypeHandleKey && tKey != argIteratorKey && tKey != voidKey) continue;
          uint resolutionScopeKind = (tr.ResolutionScope & TokenTypeIds.TokenTypeMask);
          if (resolutionScopeKind != TokenTypeIds.AssemblyRef) continue;
          uint resolutionScopeRowId = (tr.ResolutionScope & TokenTypeIds.RIDMask);
          //Just because this reference looks like a mscorlib type, does not mean that it actually is one. Badly behaved assemblies might reuse mscorlib names.
          //We therefore count the number of references and hope that mscorlib has a majority.
          hitCounts[resolutionScopeRowId-1]++;
          if (tKey == enumKey)
            this.SystemEnumAssembly = this.AssemblyReferenceArray[resolutionScopeRowId];
          else if (tKey == valueTypeKey)
            this.SystemValueTypeAssembly = this.AssemblyReferenceArray[resolutionScopeRowId];
          else if (tKey == multicastDelegateKey)
            this.SystemMulticastDelegateAssembly = this.AssemblyReferenceArray[resolutionScopeRowId];
          else if (tKey == typeKey)
            this.SystemTypeAssembly = this.AssemblyReferenceArray[resolutionScopeRowId];
          else if (tKey == paramArrayAttributeKey)
            this.SystemParamArrayAttributeAssembly = this.AssemblyReferenceArray[resolutionScopeRowId];
        }
        uint maxHits = 0;
        uint rowWithMaxHits = 0;
        for (uint i = 0; i < hitCounts.Length; i++) {
          if (hitCounts[i] > maxHits) {
            maxHits = hitCounts[i];
            rowWithMaxHits = i;
          }
        }
        if (maxHits > 0) {
          return this.AssemblyReferenceArray[rowWithMaxHits+1].AssemblyIdentity;
        }

        TypeDefTableReader tdTable = this.PEFileReader.TypeDefTable;
        for (uint i = 1; i <= tdTable.NumberOfRows; i++) {
          TypeDefRow td = tdTable[i];
          IName nsName = this.GetNameFromOffset(td.Namespace);
          if (nsName.UniqueKey != systemKey) continue;
          int tKey = this.GetNameFromOffset(td.Name).UniqueKey;
          //if you're mscorlib, you have to define System.Object
          if (tKey != objectKey) continue;
          AssemblyIdentity/*?*/ result = this.Module.ModuleIdentity as AssemblyIdentity;
          if (result != null) return result;
          //TODO: error
          break;
        }
        AssemblyRefTableReader arTable = this.PEFileReader.AssemblyRefTable;
        for (uint i = 1; i <= arTable.NumberOfRows; i++) {
          AssemblyRefRow ar = arTable[i];
          int key = this.GetNameFromOffset(ar.Name).UniqueKey;
          if (key != systemRuntimeKey) continue;
          var identity = this.AssemblyReferenceArray[i].AssemblyIdentity;
          if (identity.Version.Major >= 4) return identity;
        }
        for (uint i = 1; i <= arTable.NumberOfRows; i++) {
          AssemblyRefRow ar = arTable[i];
          int key = this.GetNameFromOffset(ar.Name).UniqueKey;
          if (key != mscorlibKey) continue;
          return this.AssemblyReferenceArray[i].AssemblyIdentity;
        }
      }
      return Dummy.AssemblyIdentity;
    }