public static byte[] AddFileToFolder(Package package, PackageFolder folder, string fileName, byte[] fileContents)
        {
            byte[] ret = null;
            try
            {

                if (package.dj == null || (package.dj != null && package.dj.OpenAgain()))
                {
                    try
                    {
                        if (package.package.CanWrite == false)
                            package.package.OpenAgain();

                        if (package.package.CanWrite)
                        {
                            if (package.package.AddFileToFolder(folder.FolderEntry, fileName, fileContents))
                            {
                                ret = package.package.RebuildPackageInMemory(
                                    new RSAParams(new DJsIO(Resources.KV, true)));
                            }
                        }
                    }
                    finally
                    {
                        package.package.CloseIO();
                    }
                }
            }
            catch { }
            return ret;
        }
        internal PackageFolder(PackageFolder parent, FolderEntry entry, bool readData = true, Package pk = null)
        {
            this.FolderEntry = entry;
            Parent = parent;
            Package = pk;
            Files = new List<PackageFile>();
            Folders = new List<PackageFolder>();

            foreach (var f in entry.GetSubFiles())
            {
                Files.Add(new PackageFile(this, f, readData, pk));
            }

            foreach (var f in entry.GetSubFolders())
            {
                Folders.Add(new PackageFolder(this, f, readData, pk));
            }
        }
        public PackageFile(PackageFolder folder, FileEntry file, bool readData = true, Package pk = null)
        {
            this.FileEntry = file;
            this.Folder = folder;
            this.Package = pk;

                this.data = file.ExtractBytes(readData);
        }
 void ReadData(bool readData = true, Package pk = null)
 {
     rootFolder = new PackageFolder(null, package.RootDirectory, readData, pk);
 }
        public static Package Load(DJsIO dj, bool readData = false)
        {
            Package ret = null;
            try
            {

                STFSPackage pk = null;
                try
                {

                    pk = new STFSPackage(dj, null);
                }
                catch
                {
                    if (pk != null)
                        pk.CloseIO();
                }
                if (pk != null)
                {
                    if (pk.ParseSuccess == true)
                    {
                        ret = new Package(pk, readData, dj);

                    }
                    pk.CloseIO();
                }

            }
            catch { }
            return ret;
        }
        public static byte[] RebuildPackageInMemory(Package package)
        {
            byte[] ret = null;
            try
            {

                if (package.dj == null || (package.dj != null && package.dj.OpenAgain()))
                {
                    try
                    {
                        ret = package.package.RebuildPackageInMemory(
                            new RSAParams(new DJsIO(Resources.KV, true)));
                    }
                    finally
                    {
                        package.package.CloseIO();
                    }
                }
            }
            catch { }
            return ret;
        }
        public static Package Load(byte[] fileBytes, bool loadBytes=false)
        {
            Package ret = null;
            try
            {
                STFSPackage pk = null;
                try
                {
                    pk = new STFSPackage(fileBytes, null);
                }
                catch
                {
                    if (pk != null)
                        pk.CloseIO();
                }
                if (pk != null)
                {
                    if (pk.ParseSuccess == true)
                    {
                        ret = new Package(pk);

                    }
                    pk.CloseIO();
                }

            }
            catch { }
            return ret;
        }
        public static Package Load(string fileName, bool readData = false)
        {
            Package ret = null;
            try
            {

                DJsIO dj = new DJsIO(fileName, DJFileMode.Open, true);
                STFSPackage pk = null;
                try
                {

                    pk = new STFSPackage(dj, null);
                }
                catch
                {
                    if (pk != null)
                        pk.CloseIO();
                }
                if (pk != null)
                {
                    if (pk.ParseSuccess == true)
                    {
                        ret = new Package(pk, readData);

                    }
                    pk.CloseIO();
                }

            }
            catch { }
            return ret;
        }
        public bool LoadPackageIntoTree(Package package, FATXFileEntry file)
        {
            bool ret = false;

            treePackageContentsIsLocal = false;
            treePackageContentsFilePath = "";
            treePackageContentsIsFATXFileEntry = true;
            treePackageContentsFATXFileEntry = file;

            treePackageContents.SuspendLayout();
            treePackageContents.Nodes.Clear();
            treePackageContents.Tag = package;
            try
            {
                ret = AddPackageTreeNodes(treePackageContents.Nodes, package.RootFolder);
            }
            catch { }
            treePackageContents.ExpandAll();
            treePackageContents.ResumeLayout();

            return ret;
        }
        public byte[] GetUpgradesDTAFromPackage(Package pk)
        {
            if (pk == null)
                return null;

            try
            {
                return pk.GetFile("songs_upgrades", "upgrades.dta").Data;
            }
            catch
            {
                return null;
            }
        }
        public PackageFile GetProMidFromPackage(Package pk)
        {
            if (pk == null)
                return null;

            PackageFile upgradeDTA = null;
            try
            {
                upgradeDTA = pk.GetFile("songs_upgrades", "upgrades.dta");
            }
            catch
            {
                return null;
            }

            string proName = DTAGetProFileName(upgradeDTA.Data);

            if (string.IsNullOrEmpty(proName))
            {
                return null;
            }
            else
            {
                proName = proName.Trim('"');

                var s = proName.Split('/');

                if (s == null || s.Length != 2 || s[0] != "songs_upgrades")
                {
                    return null;
                }
                else
                {
                    var proMid = pk.GetFile("songs_upgrades", s[1]);

                    if (proMid == null)
                    {
                        return null;
                    }
                    else
                    {
                        return proMid;
                    }
                }
            }
        }
        public bool CheckConPackage(Package pk, ref List<string> fileErrors, SongCacheItem item)
        {
            try
            {

                if (pk == null)
                {
                    fileErrors.Add("Cannot open CON File");
                    return false;
                }

                PackageFile upgradeDTA = null;
                try
                {
                    upgradeDTA = pk.GetFile("songs_upgrades", "upgrades.dta");
                }
                catch
                {
                    fileErrors.Add("error extracting upgrades.dta");
                    return false;
                }

                if (upgradeDTA == null)
                {
                    fileErrors.Add("Cannot find DTA file in package");
                    return false;
                }

                string upgradeFileData = string.Empty;
                try
                {
                    upgradeFileData = Encoding.ASCII.GetString(upgradeDTA.Data);
                }
                catch
                {
                    fileErrors.Add("error reading upgrades.dta");
                }

                if (string.IsNullOrEmpty(upgradeFileData))
                {
                    fileErrors.Add("upgrades.dta file is empty");
                }
                else
                {

                    string dtaSongID = string.Empty;
                    try
                    {
                        var songIDList = LoadDTAFile(upgradeDTA.Data);
                        if (songIDList.Any())
                        {
                            songIDList.GetSongIDs().FirstOrDefault().GetIfNotNull(x => dtaSongID = x.Value);
                        }
                    }
                    catch { }

                    if (dtaSongID.IsEmpty())
                    {
                        fileErrors.Add("song id missing in upgrades.dta");
                    }
                    else
                    {

                        var g6D = InstrumentDifficulty.INVALID;
                        try
                        {
                            g6D = InstrumentDifficultyUtil.DTAGetGuitarDifficulty(upgradeDTA.Data);
                        }
                        catch { }

                        if (g6D == InstrumentDifficulty.INVALID)
                        {
                            fileErrors.Add("invalid guitar difficulty in upgrades.dta");
                        }

                        var g6B = InstrumentDifficulty.INVALID;
                        try
                        {
                            g6B = InstrumentDifficultyUtil.DTAGetBassDifficulty(upgradeDTA.Data);
                        }
                        catch { }

                        if (g6B == InstrumentDifficulty.INVALID)
                        {
                            fileErrors.Add("invalid bass difficulty in upgrades.dta");
                        }

                        if (!pk.GetFiles("songs_upgrades", ".mid|.midi").Any())
                        {
                            fileErrors.Add("No \".mid\" file found in package");
                        }

                        string shortName = string.Empty;
                        try
                        {
                            shortName = DTAGetSongShortName(upgradeDTA.Data);
                        }
                        catch { }

                        if (shortName.IsEmpty())
                        {
                            fileErrors.Add("Song Name Missing from DTA");
                        }
                        else
                        {

                            string proName = DTAGetProFileName(upgradeDTA.Data);

                            if (proName.IsEmpty())
                            {
                                fileErrors.Add("Missing pro file name in upgrades.dta");
                            }
                            else
                            {
                                proName = proName.Trim('"');

                                var s = proName.Split('/');

                                if (s == null || s.Length != 2 || s[0] != "songs_upgrades")
                                {
                                    fileErrors.Add("Invalid path to pro mid file in upgrades.dta: " + proName);
                                }
                                else
                                {
                                    var proMid = pk.GetFile("songs_upgrades", s[1]);

                                    if (proMid == null)
                                    {
                                        fileErrors.Add("pro midi file set in upgrades.dta not found in package");
                                    }
                                    else
                                    {
                                        var sq = proMid.Data.LoadSequence();
                                        if (sq != null)
                                        {
                                            if (!sq.IsFileTypePro())
                                            {
                                                fileErrors.Add("Unable to open pro midi file from package");
                                            }
                                            else
                                            {

                                                fileErrors.AddRange(VerifySongData(proName, sq, item));

                                            }
                                        }
                                    }
                                }
                            }
                        }

                    }
                }

            }
            catch { }

            return fileErrors.Count == 0;
        }
        public bool CheckCONPackageBytes(Package data, bool silent)
        {
            bool ret = false;

            List<string> fileErrors = new List<string>();
            try
            {
                CheckConPackage(data, ref fileErrors, null);
            }
            catch
            {
                if (silent)
                {
                    WriteBatchResult("Unhandled exception ");
                }
                else
                {
                    MessageBox.Show("Unhandled exception");
                }
            }

            if (fileErrors.Count > 0)
            {
                if (silent)
                {
                    WriteBatchResult("Errors ");
                }
            }
            else
            {
                ret = true;
            }
            var sb = new StringBuilder();
            foreach (string s in fileErrors)
            {
                if (silent)
                {
                    WriteBatchResult(s);
                }
                else
                {
                    sb.AppendLine(s);
                }
            }

            RefreshTracks();

            if (!silent)
            {
                if (fileErrors.Count > 0)
                {
                    OpenNotepad(Encoding.ASCII.GetBytes(sb.ToString()));
                }
                else
                {
                    MessageBox.Show("Check OK");
                }
            }

            return ret;
        }