/// <summary>Extract an existing tag to a file</summary>
        /// <param name="tag_datum">index of tag to extract</param>
        /// <param name="base_directory">Root directory to extract the tag to</param>
        /// <param name="name_override">Optional, if not null, this is the name of the file we store the tag in</param>
        /// <returns>false if it can't save the tag</returns>
        public bool Extract(Blam.DatumIndex tag_datum, string base_directory, string name_override)
        {
            Blam.DatumIndex handle = Open(tag_datum);
            if (handle != Blam.DatumIndex.Null)
            {
                TagManager tm = Array[handle];
                try {
                    tm.OpenForExtract(base_directory, name_override);
                    tm.Extract();
                }
                catch (Exception ex) { extractionTrace.WriteLine("Couldn't extract tag: '{0}'{1}{2}", tm.Name, Program.NewLine, ex); return(false); }
            }
            else
            {
                return(false);
            }

            return(true);
        }
        bool Extract(Blam.CacheExtractionInfo cei, Blam.DatumIndex tag_datum, bool remove_from_state)
        {
            if (remove_from_state)
            {
                // don't process it if it's already been done
                if (cacheFile.ExtractionState.Processed(tag_datum))
                {
                    return(true);
                }
                cacheFile.ExtractionState.Dequeue(tag_datum);
            }
            cacheFile.ExtractionState.CurrentTag = tag_datum;

            Blam.CacheIndex.Item ci = cacheFile.Index.Tags[tag_datum.Index];

            bool error = false;

            Blam.DatumIndex handle = Open(tag_datum);
            if (handle != Blam.DatumIndex.Null)
            {
                // we're about to extract, update our depth level
                cei.ExtractionDepth++;
                TagManager tm = Array[handle];

                #region read the tag from the cache
                try { tm.OpenForExtract(cei.Arguments.OutputDirectory, null); }
                catch (Exception ex) { extractionTrace.WriteLine("Failed to read tag, aborting extraction...'{0}.{1}'{2}{3}", tm.Name, tm.GroupTag.Name, Program.NewLine, ex); error = true; }
                #endregion

                #region if no errors
                if (!error)
                {
                    try { tm.Extract(); }
                    catch (Exception ex) { extractionTrace.WriteLine("Failed to write tag, aborting extraction...'{0}.{1}'{2}{3}", tm.Name, tm.GroupTag.Name, Program.NewLine, ex); error = true; }

                    tm.Close();
                }

                // something bad happened, so make sure we don't keep any bad tags
                if (error)
                {
                    System.IO.File.Delete(Path.Combine(cei.Arguments.OutputDirectory, tm.Name));
                }

                // process dependents if we want to
                if (!error && cei.Arguments.WithDependents)
                {
                    error = !ExtractWithDependents(cei, tm);
                }
                #endregion

                // we're done with the extraction process, update depth level
                cei.ExtractionDepth--;

                // create and write database
                if (cei.Arguments.OutputDatabase && cei.ExtractionDepth == 0)
                {
                    ExtractWriteTagDatabases(cei, tm);
                }

                Unload(handle);
            }
            else
            {
                error = true;
            }

            return(!error);
        }