/// <summary>
    /// Determines whether the GAC contains the specified code base URI.
    /// </summary>
    /// <param name="codeBaseUri">The code base URI.</param>
    public static bool Contains(Uri codeBaseUri) {
      Contract.Requires(codeBaseUri != null);
      
      lock (GlobalLock.LockingObject) {
#if COMPACTFX
        var gacKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"\Software\Microsoft\.NETCompactFramework\Installer\Assemblies\Global");
        if (gacKey == null) return false;
        var codeBase = codeBaseUri.AbsoluteUri;
        foreach (var gacName in gacKey.GetValueNames()) {
          var values = gacKey.GetValue(gacName) as string[];
          if (values == null || values.Length == 0) continue;
          if (string.Equals(values[0], codeBase, StringComparison.OrdinalIgnoreCase)) return true;
          if (values.Length > 1 && string.Equals(values[1], codeBase, StringComparison.OrdinalIgnoreCase)) return true;
        }
        return false;
#else
#if __MonoCS__
        IAssemblyEnum assemblyEnum = new MonoAssemblyEnum();
#else
        if (!GlobalAssemblyCache.FusionLoaded) {
          GlobalAssemblyCache.FusionLoaded = true;
          var systemAssembly = typeof(object).Assembly;
          var systemAssemblyLocation = systemAssembly.Location;
          string dir = Path.GetDirectoryName(systemAssemblyLocation)??"";
          GlobalAssemblyCache.LoadLibrary(Path.Combine(dir, "fusion.dll"));
        }
        IAssemblyEnum assemblyEnum;
        int rc = GlobalAssemblyCache.CreateAssemblyEnum(out assemblyEnum, null, null, ASM_CACHE.GAC, 0);
        if (rc < 0 || assemblyEnum == null) return false;
#endif
        IApplicationContext applicationContext;
        IAssemblyName currentName;
        while (assemblyEnum.GetNextAssembly(out applicationContext, out currentName, 0) == 0) {
          //^ assume currentName != null;
          AssemblyName assemblyName = new AssemblyName(currentName);
          string/*?*/ scheme = codeBaseUri.Scheme;
          if (scheme != null && assemblyName.CodeBase.StartsWith(scheme, StringComparison.OrdinalIgnoreCase)) {
            try {
              Uri foundUri = new Uri(assemblyName.CodeBase);
              if (codeBaseUri.Equals(foundUri)) return true;
            } catch (System.ArgumentNullException) {
            } catch (System.UriFormatException) {
            }
          }
        }
        return false;
#endif
      }
    }
    /// <summary>
    /// Returns the original location of the corresponding assembly if available, otherwise returns the location of the shadow copy.
    /// If the corresponding assembly is not in the GAC, null is returned.
    /// </summary>
    public static string/*?*/ GetLocation(AssemblyIdentity assemblyIdentity, IMetadataHost metadataHost) {
      lock (GlobalLock.LockingObject) {
#if COMPACTFX
        var gacKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"\Software\Microsoft\.NETCompactFramework\Installer\Assemblies\Global");
        foreach (var gacName in gacKey.GetValueNames()) {
          if (IdentityMatchesString(assemblyIdentity, gacName)) {
            var values = gacKey.GetValue(gacName) as string[];
            if (values == null || values.Length == 0) continue;
            return values[0];
          }
        }
        return null;
#else
#if __MonoCS__
        IAssemblyEnum assemblyEnum = new MonoAssemblyEnum();
#else
        if (!GlobalAssemblyCache.FusionLoaded) {
          GlobalAssemblyCache.FusionLoaded = true;
          var systemAssembly = typeof(object).Assembly;
          var systemAssemblyLocation = systemAssembly.Location;
          var dir = Path.GetDirectoryName(systemAssemblyLocation)??"";
          GlobalAssemblyCache.LoadLibrary(Path.Combine(dir, "fusion.dll"));
        }
        IAssemblyEnum assemblyEnum;
        int rc = CreateAssemblyEnum(out assemblyEnum, null, null, ASM_CACHE.GAC, 0);
        if (rc < 0 || assemblyEnum == null) return null;
#endif
        IApplicationContext applicationContext;
        IAssemblyName currentName;
        while (assemblyEnum.GetNextAssembly(out applicationContext, out currentName, 0) == 0) {
          //^ assume currentName != null;
          AssemblyName cn = new AssemblyName(currentName);
          if (assemblyIdentity.Equals(new AssemblyIdentity(metadataHost.NameTable.GetNameFor(cn.Name), cn.Culture, cn.Version, cn.PublicKeyToken, ""))) {
            string codeBase = cn.CodeBase;
            if (codeBase != null && codeBase.StartsWith("file://", StringComparison.OrdinalIgnoreCase)) {
              Uri u = new Uri(codeBase, UriKind.Absolute);
              return u.LocalPath;
            }
            return cn.GetLocation();
          }
        }
        return null;
#endif
      }
    }