/// <summary>
        ///  Gets the KIFINT lookup with the specified known type in the collection.
        /// </summary>
        /// <param name="type">The type of the KIFINT lookup to get.</param>
        /// <returns>The KIFINT lookup with the specified type in the collection.</returns>
        ///
        /// <exception cref="ArgumentException">
        ///  <paramref name="type"/> is not defined or is <see cref="KifintType.Unknown"/>.
        /// </exception>
        /// <exception cref="KeyNotFoundException">
        ///  A known KIFINT lookup of <paramref name="type"/> is not present in the collection.
        /// </exception>
        public KifintLookup this[KifintType type] {
            get {
                ThrowIfUndefinedOrUnknown(type);
                return(knownLookups[type]);
            }
            set {
                ThrowIfUndefinedOrUnknown(type);

                if (knownLookups.TryGetValue(type, out KifintLookup lookup))
                {
                    lookups.Remove(lookup);
                }
                if (value == null)
                {
                    knownLookups.Remove(type);
                }
                else
                {
                    value.Update = Update;
                    lookups.Add(value);
                    knownLookups[type] = value;
                }
                if (type == KifintType.Update)
                {
                    AssignUpdateLookup(value);
                }
                else if (type == KifintType.Image)
                {
                    Image = value;
                }
            }
        }
        /// <summary>
        ///  Decrypts the KIFINT archives using the wildcard search, install directory, and name of executable with the
        ///  V_CODE2 used to decrypt.<para/>
        ///  Using this will initialize with <see cref="KifintType.Unknown"/>.
        /// </summary>
        /// <param name="wildcard">The wildcard name of the files to look for and merge.</param>
        /// <param name="installDir">The installation directory for both the archives and executable.</param>
        /// <param name="vcode2">The V_CODE2 key obtained from the exe, used to decrypt the file names.</param>
        /// <param name="callback">The optional callback for progress made during decryption.</param>
        /// <returns>The <see cref="KifintLookup"/> merged with all loaded archives.</returns>
        ///
        /// <exception cref="ArgumentNullException">
        ///  <paramref name="wildcard"/>, <paramref name="installDir"/>, or <paramref name="vcode2"/> is null.
        /// </exception>
        public static KifintLookup LoadLookup(string wildcard, string installDir, string vcode2,
                                              KifintProgressCallback callback = null)
        {
            if (vcode2 == null)
            {
                throw new ArgumentNullException(nameof(vcode2));
            }
            KifintType   type   = KifintType.Unknown;
            KifintLookup lookup = new KifintLookup(type);

            string[]           files    = Directory.GetFiles(installDir, wildcard);
            KifintProgressArgs progress = new KifintProgressArgs {
                ArchiveType  = type,
                ArchiveIndex = 0,
                ArchiveCount = files.Length,
            };

            foreach (string kifintPath in files)
            {
                progress.ArchiveName = Path.GetFileName(kifintPath);
                using (Stream stream = File.OpenRead(kifintPath))
                    lookup.Merge(LoadLookup(type, stream, kifintPath, vcode2, progress, callback));
                progress.ArchiveIndex++;
            }
            progress.EntryName  = null;
            progress.EntryIndex = 0;
            progress.EntryCount = 0;
            callback?.Invoke(progress);
            return(lookup);
        }
        /// <summary>
        ///  Decrypts the KIFINT archives using the known archive type, install directory, and name of executable with
        ///  the V_CODE2 used to decrypt.
        /// </summary>
        /// <param name="type">The type of archive to look for and decrypt.</param>
        /// <param name="installDir">The installation directory for both the archives and executable.</param>
        /// <param name="vcode2">The V_CODE2 key obtained from the exe, used to decrypt the file names.</param>
        /// <param name="callback">The optional callback for progress made during decryption.</param>
        /// <returns>The <see cref="KifintLookup"/> merged with all loaded archives.</returns>
        ///
        /// <exception cref="ArgumentNullException">
        ///  <paramref name="installDir"/> or <paramref name="vcode2"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        ///  <paramref name="type"/> is <see cref="KifintType.Unknown"/>.
        /// </exception>
        public static KifintLookup LoadLookup(KifintType type, string installDir, string vcode2,
                                              KifintProgressCallback callback = null)
        {
            if (vcode2 == null)
            {
                throw new ArgumentNullException(nameof(vcode2));
            }
            if (type == KifintType.Unknown)
            {
                throw new ArgumentException($"{nameof(type)} cannot be {nameof(KifintType.Unknown)}!", nameof(type));
            }
            KifintLookup lookup       = new KifintLookup(type);
            var          files        = Enumerable.Empty <string>();
            var          wildcardAttr = EnumInfo.GetAttribute <KifintType, KifintWildcardAttribute>(type);

            foreach (string wildcard in wildcardAttr.Wildcards)
            {
                files = files.Concat(Directory.GetFiles(installDir, wildcard));
            }
            //string wildcard = EnumInfo.GetAttribute<KifintType, KifintWildcardAttribute>(type).Wildcard;
            //string[] files = Directory.GetFiles(installDir, wildcard);
            KifintProgressArgs progress = new KifintProgressArgs {
                ArchiveType  = type,
                ArchiveIndex = 0,
                ArchiveCount = files.Count(),
            };

            foreach (string kifintPath in files)
            {
                progress.ArchiveName = Path.GetFileName(kifintPath);
                using (Stream stream = File.OpenRead(kifintPath))
                    lookup.Merge(LoadLookup(type, stream, kifintPath, vcode2, progress, callback));
                progress.ArchiveIndex++;
            }
            progress.EntryName  = null;
            progress.EntryIndex = 0;
            progress.EntryCount = 0;
            callback?.Invoke(progress);
            return(lookup);
        }