private bool OnFileBeginExtraction(VextractStatusData Status)
        {
            if (CancelPressed)
                return true;

            lock(lockFilesBufferObject)
            {
                //Log.AddLogText(Status.CurrentFile + "...");
                //SetProgressValue(Status.PercentComplete);
                filesBuffer += String.Format(formatStr,
                    Status.CurrentFile, Status.FilesTotal - Status.FilesDone, Environment.NewLine);
                percentageValue = Status.PercentComplete;
            }

            return false;
        }
        /// <summary>
        /// Extracts all files from the VPK files that match the given pattern.
        /// </summary>
        /// <param name="Pattern">The filename pattern to match and extract.</param>
        /// <param name="OutputDirectory">The directory to extract the files to.</param>
        /// <param name="Exemptions">A string array of patterns to exempt.</param>
        /// <param name="SkeletonOnly">If true, creates directories instead of extracting files.</param>
        /// <returns>The number of files extracted.</returns>
        public int ExtractFiles(string Pattern, string OutputDirectory, string[] Exemptions, bool SkeletonOnly)
        {
            int filesExtracted = 0;
            VPKIndex index;
            VextractStatusData status = new VextractStatusData();

            try
            {
                index = VPKIndex.Load();
            }
            catch (FileNotFoundException)
            {
                throw new Exceptions.VPKIndexNotFound();
            }

            VPKIndexEntry[] files = index.FindFiles(Pattern, Exemptions);
            decimal length = Decimal.Round((decimal)files.Length, 0);   // Used to avoid re-casting from int during the percentage calculations
            int intLength = files.Length;

            status.FilesTotal = intLength;

            for(int i = 0; i < intLength; i++)
            {
                VPKIndexEntry currentEntry = files[i];

                if (OnFileBeginExtraction != null)
                {
                    // Determine percentage complete
                    status.PercentComplete = (int)Decimal.Round((decimal)i / length * 100M, 0);
                    status.FilesDone = filesExtracted;
                    status.CurrentFile = currentEntry.FileName;
                    bool cancel = OnFileBeginExtraction(status);
                    if (cancel)
                        break;
                }

                // Attempt to open output file.
                string directoryPart = getDirectory(currentEntry.FileName);
                string destDirectory = String.Format("{0}\\{1}", OutputDirectory, directoryPart)
                    .Replace("/", "\\");

                if (Directory.Exists(destDirectory) == false)
                {
                    // Attempt to create the directory.
                    try
                    {
                        Directory.CreateDirectory(destDirectory);
                    }
                    catch
                    {
                        // Creation failed, skip file
                        continue;
                    }
                }

                if (SkeletonOnly == false)
                {
                    byte[] fileContents = currentEntry.GetContents();
                    if (fileContents.Length == 0)
                        continue;

                    string outputFile = String.Format("{0}\\{1}", OutputDirectory, currentEntry.FileName)
                        .Replace("/", "\\");

                    if (Directory.Exists(outputFile))
                    {
                        // The destination was incorrectly created as a directory. Delete it.
                        if (Directory.GetFiles(outputFile).Length == 0)
                            Directory.Delete(outputFile);
                    }

                    File.WriteAllBytes(outputFile, fileContents);

                    filesExtracted++;
                }
            }

            VPKIndexEntry.Close();

            return filesExtracted;
        }