public IEnumerable <TES4Record> Load(TES4FileLoadScheme scheme)
        {
            Console.Write("Processing " + nameof(TES4File) + " Data...");
            Stopwatch stopwatch = Stopwatch.StartNew();

            using (FileStream contents = GetFile())
            {
                this.FetchTES4(contents);
                while (true)
                {
                    byte[] headerBytes = new byte[TES4Grup.GRUP_HEADER_SIZE];
                    int    read        = contents.Read(headerBytes);
                    if (read == 0)
                    {
                        break;
                    }
                    string headerString = ISO_8859_1.Value.GetString(headerBytes);
                    if (headerString.Substring(0, 4) != "GRUP")
                    {
                        throw new InvalidESFileException("Invalid GRUP magic, found " + headerString.Substring(0, 4));
                    }
                    contents.Seek(-TES4Grup.GRUP_HEADER_SIZE, SeekOrigin.Current);

                    int            grupSize = PHPFunction.UnpackV(headerBytes.Skip(4).Take(4).ToArray());
                    TES4RecordType grupType = TES4RecordType.First(headerString.Substring(8, 4));
                    if (scheme.ShouldLoad(grupType))
                    {
                        TES4GrupLoadScheme?rules = scheme.GetRulesFor(grupType);
                        if (rules == null)
                        {
                            throw new InvalidOperationException(nameof(rules) + " was null for " + nameof(grupType) + " " + grupType.Name + ".");
                        }
                        TES4Grup grup = new TES4Grup();
                        foreach (var loadedRecord in grup.Load(contents, this, rules, true))
                        {
                            yield return(loadedRecord);
                        }
                        if (grup.Type == null)
                        {
                            throw new InvalidOperationException(nameof(grup.Type) + " was null.");
                        }
                        this.grups.Add(grup.Type, grup);
                    }
                    else
                    {
                        contents.Seek(grupSize, SeekOrigin.Current);
                    }
                }
            }
            stopwatch.Stop();
            Console.WriteLine("\rProcessing " + nameof(TES4File) + " Complete (" + stopwatch.ElapsedMilliseconds + " ms)");
        }
        public List <TES4Grup> GetGrup(TES4RecordType type)
        {
            List <TES4Grup> grups = new List <TES4Grup>();

            foreach (var file in this.files)
            {
                TES4Grup grup = file.GetGrup(type);
                if (grup != null)
                {
                    grups.Add(grup);
                }
            }
            return(grups);
        }
        /*
         * @throws InvalidESFileException
         */
        public IEnumerable <ITES4Record> Load(FileStream fileContents, TES4File file, TES4GrupLoadScheme scheme, bool isTopLevelGrup)
        {
            long startPosition = fileContents.Position;

            byte[] headerBytes  = fileContents.Read(GRUP_HEADER_SIZE);
            string headerString = TES4File.ISO_8859_1.Value.GetString(headerBytes);

            if (headerString.Substring(0, 4) != "GRUP")
            {
                throw new InvalidESFileException("Invalid GRUP magic, found " + headerString.Substring(0, 4));
            }

            this.Size = PHPFunction.UnpackV(headerBytes.Skip(4).Take(4).ToArray());
            if (isTopLevelGrup)
            {
                this.Type = TES4RecordType.First(headerString.Substring(8, 4));
            }

            long end = startPosition + this.Size;

            while (fileContents.Position < end)
            {
                //Ineffective lookahead, but oh well
                byte[] nextEntryTypeBytes = new byte[4];
                int    bytesRead          = fileContents.Read(nextEntryTypeBytes);
                if (bytesRead == 0)
                {
                    break;
                }
                fileContents.Seek(-4, SeekOrigin.Current);
                string nextEntryType = TES4File.ISO_8859_1.Value.GetString(nextEntryTypeBytes);
                switch (nextEntryType)
                {
                case "GRUP":
                {
                    TES4Grup nestedGrup = new TES4Grup();
                    foreach (var subrecord in nestedGrup.Load(fileContents, file, scheme, false))
                    {
                        yield return(subrecord);
                    }
                    break;
                }

                default:
                {
                    byte[]         recordHeaderBytes = fileContents.Read(TES4LoadedRecord.RECORD_HEADER_SIZE);
                    string         recordTypeString  = TES4File.ISO_8859_1.Value.GetString(recordHeaderBytes.Take(4).ToArray());
                    TES4RecordType recordType        = TES4RecordType.First(recordTypeString);
                    int            recordSize        = PHPFunction.UnpackV(recordHeaderBytes.Skip(4).Take(4).ToArray());
                    int            recordFlags       = PHPFunction.UnpackV(recordHeaderBytes.Skip(8).Take(4).ToArray());
                    int            recordFormid      = PHPFunction.UnpackV(recordHeaderBytes.Skip(12).Take(4).ToArray());
                    if (scheme.ShouldLoad(recordType))
                    {
                        TES4LoadedRecord record = new TES4LoadedRecord(file, recordType, recordFormid, recordSize, recordFlags);
                        record.Load(fileContents, scheme.GetRulesFor(recordType));
                        this.records.Add(record);
                        yield return(record);
                    }
                    else
                    {
                        fileContents.Seek(recordSize, SeekOrigin.Current);
                    }
                    break;
                }
                }
            }
        }