/// <summary>
        /// Extract the Stream given.
        /// </summary>
        /// <param name="filename">The filename to use for the stream.</param>
        /// <param name="stream">The Stream to extract from</param>
        /// <param name="opts">The Extractor Options to use.</param>
        /// <returns></returns>
        public IEnumerable <FileEntry> Extract(string filename, Stream stream, ExtractorOptions?opts = null)
        {
            var options  = opts ?? new ExtractorOptions();
            var governor = new ResourceGovernor(options);

            governor.ResetResourceGovernor(stream);
            FileEntry?fileEntry = null;

            try
            {
                fileEntry = new FileEntry(Path.GetFileName(filename), stream);
                governor.ResetResourceGovernor(stream);
            }
            catch (Exception ex)
            {
                Logger.Debug(ex, "Failed to extract file {0}", filename);
            }

            if (fileEntry != null)
            {
                foreach (var result in Extract(fileEntry, opts, governor))
                {
                    governor.GovernorStopwatch.Stop();
                    yield return(result);

                    governor.GovernorStopwatch.Start();
                }
            }
            governor.GovernorStopwatch.Stop();
        }
        /// <summary>
        /// Extract from a FileEntry.
        /// </summary>
        /// <param name="fileEntry">The FileEntry containing the Conteant stream to parse.</param>
        /// <param name="opts">The ExtractorOptions to use</param>
        /// <param name="governor">The Resource governor to use (or null to create a new one).</param>
        /// <returns>The FileEntries found.</returns>
        public IEnumerable <FileEntry> Extract(FileEntry fileEntry, ExtractorOptions?opts = null, ResourceGovernor?governor = null)
        {
            var options  = opts ?? new ExtractorOptions();
            var Governor = governor;

            if (Governor == null)
            {
                Governor = new ResourceGovernor(options);
                Governor.ResetResourceGovernor(fileEntry.Content);
            }
            Logger.Trace("ExtractFile({0})", fileEntry.FullPath);
            Governor.CurrentOperationProcessedBytesLeft -= fileEntry.Content.Length;
            Governor.CheckResourceGovernor();
            IEnumerable <FileEntry> result = Array.Empty <FileEntry>();
            var useRaw = false;

            try
            {
                var type = MiniMagic.DetectFileType(fileEntry);
                if (type == ArchiveFileType.UNKNOWN || !Extractors.ContainsKey(type))
                {
                    useRaw = true;
                    result = new[]
                    {
                        fileEntry
                    };
                }
                else
                {
                    result = Extractors[type].Extract(fileEntry, options, Governor);
                }
            }
            catch (Exception ex)
            {
                Logger.Debug(ex, "Error extracting {0}: {1}", fileEntry.FullPath, ex.Message);
                useRaw = true;

                result = new[] {
                    fileEntry
                };
            }

            // After we are done with an archive subtract its bytes. Contents have been counted now separately
            if (!useRaw)
            {
                Governor.CurrentOperationProcessedBytesLeft += fileEntry.Content.Length;
            }

            return(result);
        }