private int ApplyPackageDD(string srcPath, int phraseLen, bool removeSus, string rampPath, string cfgPath, out string consoleOutput, bool overWrite = false, bool keepLog = false)
        {
            int            result = 0; // Ends normally with no error
            DLCPackageData packageData;

            consoleOutput = String.Empty;

            try
            {
                using (var psarcOld = new PsarcPackager())
                    packageData = psarcOld.ReadPackage(srcPath);
            }
            catch (Exception ex)
            {
                consoleOutput = "Error Reading : " + srcPath + Environment.NewLine + ex.Message;
                return(-1); // Read Error
            }

            // Update arrangement song info
            foreach (Arrangement arr in packageData.Arrangements)
            {
                if (chkGenArrIds.Checked)
                {
                    // generate new AggregateGraph
                    arr.SongFile = new RocksmithToolkitLib.DLCPackage.AggregateGraph.SongFile()
                    {
                        File = ""
                    };

                    // generate new Arrangement IDs
                    arr.Id       = IdGenerator.Guid();
                    arr.MasterId = RandomGenerator.NextInt();
                }

                // skip vocal and showlight arrangements
                if (arr.ArrangementType == ArrangementType.Vocal || arr.ArrangementType == ArrangementType.ShowLight)
                {
                    continue;
                }

                // validate (QC) RS2014 packageData
                if (packageData.GameVersion == GameVersion.RS2014)
                {
                    // validate existing SongInfo
                    var songXml = Song2014.LoadFromFile(arr.SongXml.File);
                    songXml.ArtistName     = packageData.SongInfo.Artist.GetValidAtaSpaceName();
                    songXml.Title          = packageData.SongInfo.SongDisplayName.GetValidAtaSpaceName();
                    songXml.AlbumName      = packageData.SongInfo.Album.GetValidAtaSpaceName();
                    songXml.ArtistNameSort = packageData.SongInfo.ArtistSort.GetValidSortableName();
                    songXml.SongNameSort   = packageData.SongInfo.SongDisplayNameSort.GetValidSortableName();
                    songXml.AlbumNameSort  = packageData.SongInfo.AlbumSort.GetValidSortableName();
                    songXml.AverageTempo   = Convert.ToSingle(packageData.SongInfo.AverageTempo.ToString().GetValidTempo());
                    songXml.AlbumYear      = packageData.SongInfo.SongYear.ToString().GetValidYear();

                    // update packageData with validated SongInfo
                    packageData.SongInfo.Artist              = songXml.ArtistName;
                    packageData.SongInfo.SongDisplayName     = songXml.Title;
                    packageData.SongInfo.Album               = songXml.AlbumName;
                    packageData.SongInfo.ArtistSort          = songXml.ArtistNameSort;
                    packageData.SongInfo.SongDisplayNameSort = songXml.SongNameSort;
                    packageData.SongInfo.AlbumSort           = songXml.AlbumNameSort;
                    packageData.SongInfo.AverageTempo        = (int)songXml.AverageTempo;
                    packageData.SongInfo.SongYear            = Convert.ToInt32(songXml.AlbumYear);

                    // write updated xml arrangement
                    using (var stream = File.Open(arr.SongXml.File, FileMode.Create))
                        songXml.Serialize(stream, false);

                    // restore arrangment comments
                    Song2014.WriteXmlComments(arr.SongXml.File, arr.XmlComments);
                }

                // apply DD to xml arrangments... 0 = Ends normally with no error
                result = DDCreator.ApplyDD(arr.SongXml.File, phraseLen, removeSus, rampPath, cfgPath, out consoleOutput, true, keepLog);
                if (result == 0)      // Ends normally with no error
                {                     /* DO NOTHING */
                }
                else if (result == 1) // Ends with system error
                {
                    consoleOutput = "DDC System Error: " + Environment.NewLine +
                                    "Arrangment file: " + Path.GetFileName(arr.SongXml.File) + Environment.NewLine +
                                    "CDLC file: " + srcPath;
                    return(result);
                }
                else if (result == 2) // Ends with application error
                {
                    consoleOutput = "DDC Application Error: " + Environment.NewLine +
                                    "Arrangment file: " + Path.GetFileName(arr.SongXml.File) + Environment.NewLine +
                                    "CDLC file: " + srcPath;
                    return(result);
                }

                if (keepLog)
                {
                    var unpackedDir = Path.GetDirectoryName(Path.GetDirectoryName(arr.SongXml.File));
                    var logFiles    = Directory.EnumerateFiles(unpackedDir, "*.log", SearchOption.AllDirectories);
                    var clogDir     = Path.Combine(Path.GetDirectoryName(srcPath), "DDC_Log");
                    var plogDir     = Path.Combine(clogDir, Path.GetFileNameWithoutExtension(srcPath).StripPlatformEndName().Replace("_DD", "").Replace("_NDD", ""));

                    if (!Directory.Exists(clogDir))
                    {
                        Directory.CreateDirectory(clogDir);
                    }

                    IOExtension.DeleteDirectory(plogDir);
                    Directory.CreateDirectory(plogDir);

                    foreach (var logFile in logFiles)
                    {
                        File.Copy(logFile, Path.Combine(plogDir, Path.GetFileName(logFile)));
                    }
                }

                // put arrangment comments in correct order
                Song2014.WriteXmlComments(arr.SongXml.File);
            }

            if (chkGenArrIds.Checked)
            {
                // add comment to ToolkitInfo to identify CDLC
                var arrIdComment = packageData.ToolkitInfo.PackageComment;
                if (String.IsNullOrEmpty(arrIdComment))
                {
                    arrIdComment = TKI_ARRID;
                }
                else if (!arrIdComment.Contains(TKI_ARRID))
                {
                    arrIdComment = arrIdComment + " " + TKI_ARRID;
                }

                packageData.ToolkitInfo.PackageComment = arrIdComment;
            }

            // add comment to ToolkitInfo to identify CDLC
            var remasterComment = packageData.ToolkitInfo.PackageComment;

            if (String.IsNullOrEmpty(remasterComment))
            {
                remasterComment = TKI_REMASTER;
            }
            else if (!remasterComment.Contains(TKI_REMASTER))
            {
                remasterComment = remasterComment + " " + TKI_REMASTER;
            }

            packageData.ToolkitInfo.PackageComment = remasterComment;

            // add default package version if missing
            if (String.IsNullOrEmpty(packageData.ToolkitInfo.PackageVersion))
            {
                packageData.ToolkitInfo.PackageVersion = "1";
            }
            else
            {
                packageData.ToolkitInfo.PackageVersion = packageData.ToolkitInfo.PackageVersion.GetValidVersion();
            }

            // validate packageData (important)
            packageData.Name = packageData.Name.GetValidKey(); // DLC Key

            var destPath = srcPath;

            if (!overWrite)
            {
                destPath = GenerateDdcFilePath(srcPath);
            }

            try
            {
                // regenerates the archive with DDC changes and repairs
                using (var psarcNew = new PsarcPackager(true))
                    psarcNew.WritePackage(destPath, packageData, srcPath);
            }
            catch (Exception ex)
            {
                consoleOutput = "Error Writing: " + srcPath + Environment.NewLine + ex.Message;
                result        = -2; // Write Error
            }

            return(result);
        }
        private int ApplyPackageDD(string filePath, int phraseLen, bool removeSus, string rampPath, string cfgPath, out string consoleOutput, bool overWrite = false, bool keepLog = false)
        {
            int result = 0; // Ends normally with no error
            DLCPackageData packageData;
            consoleOutput = String.Empty;

            try
            {
                using (var psarcOld = new PsarcPackager())
                    packageData = psarcOld.ReadPackage(filePath);
            }
            catch (Exception ex)
            {
                consoleOutput = "Error Reading : " + filePath + Environment.NewLine + ex.Message;
                return -1; // Read Error
            }

            var ddcFilePath = GenerateDdcFilePath(filePath);

            // Update arrangement song info
            foreach (Arrangement arr in packageData.Arrangements)
            {
                if (chkGenArrIds.Checked)
                {
                    // generate new AggregateGraph
                    arr.SongFile = new RocksmithToolkitLib.DLCPackage.AggregateGraph.SongFile() { File = "" };

                    // generate new Arrangement IDs
                    arr.Id = IdGenerator.Guid();
                    arr.MasterId = RandomGenerator.NextInt();
                }

                // skip vocal and showlight arrangements
                if (arr.ArrangementType == ArrangementType.Vocal || arr.ArrangementType == ArrangementType.ShowLight)
                    continue;

                // validate existing SongInfo
                var songXml = Song2014.LoadFromFile(arr.SongXml.File);
                songXml.AlbumYear = packageData.SongInfo.SongYear.ToString().GetValidYear();
                songXml.ArtistName = packageData.SongInfo.Artist.GetValidAtaSpaceName();
                songXml.Title = packageData.SongInfo.SongDisplayName.GetValidAtaSpaceName();
                songXml.AlbumName = packageData.SongInfo.Album.GetValidAtaSpaceName();
                songXml.ArtistNameSort = packageData.SongInfo.ArtistSort.GetValidSortableName();
                songXml.SongNameSort = packageData.SongInfo.SongDisplayNameSort.GetValidSortableName();
                songXml.AlbumNameSort = packageData.SongInfo.AlbumSort.GetValidSortableName();
                songXml.AverageTempo = Convert.ToSingle(packageData.SongInfo.AverageTempo.ToString().GetValidTempo());

                // write updated xml arrangement
                using (var stream = File.Open(arr.SongXml.File, FileMode.Create))
                    songXml.Serialize(stream, false);

                // restore arrangment comments
                Song2014.WriteXmlComments(arr.SongXml.File, arr.XmlComments);

                // apply DD to xml arrangments... 0 = Ends normally with no error
                result = ApplyDD(arr.SongXml.File, phraseLen, removeSus, rampPath, cfgPath, out consoleOutput, true, keepLog);
                if (result == 1) // Ends with system error
                {
                    consoleOutput = "DDC System Error: " + Environment.NewLine +
                       "Arrangment file: " + Path.GetFileName(arr.SongXml.File) + Environment.NewLine +
                       "CDLC file: " + filePath;
                    return result;
                }

                if (result == 2) // Ends with application error
                {
                    consoleOutput = "DDC Application Error: " + Environment.NewLine +
                       "Arrangment file: " + Path.GetFileName(arr.SongXml.File) + Environment.NewLine +
                       "CDLC file: " + filePath;
                    return result;
                }

                if (keepLog)
                {
                    var unpackedDir = Path.GetDirectoryName(Path.GetDirectoryName(arr.SongXml.File));
                    var logFiles = Directory.EnumerateFiles(unpackedDir, "*.log", SearchOption.AllDirectories);
                    var clogDir = Path.Combine(Path.GetDirectoryName(ddcFilePath), "DDC_Log");
                    var plogDir = Path.Combine(clogDir, Path.GetFileNameWithoutExtension(ddcFilePath).StripPlatformEndName().Replace("_DD", "").Replace("_NDD", ""));

                    if (!Directory.Exists(clogDir))
                        Directory.CreateDirectory(clogDir);

                    DirectoryExtension.SafeDelete(plogDir);
                    Directory.CreateDirectory(plogDir);

                    foreach (var logFile in logFiles)
                        File.Copy(logFile, Path.Combine(plogDir, Path.GetFileName(logFile)));
                }

                // put arrangment comments in correct order
                Song2014.WriteXmlComments(arr.SongXml.File);
            }

            if (chkGenArrIds.Checked)
            {
                // add comment to ToolkitInfo to identify CDLC
                var arrIdComment = packageData.ToolkitInfo.PackageComment;
                if (String.IsNullOrEmpty(arrIdComment))
                    arrIdComment = TKI_ARRID;
                else if (!arrIdComment.Contains(TKI_ARRID))
                    arrIdComment = arrIdComment + " " + TKI_ARRID;

                packageData.ToolkitInfo.PackageComment = arrIdComment;
            }

            // add comment to ToolkitInfo to identify CDLC
            var remasterComment = packageData.ToolkitInfo.PackageComment;
            if (String.IsNullOrEmpty(remasterComment))
                remasterComment = TKI_REMASTER;
            else if (!remasterComment.Contains(TKI_REMASTER))
                remasterComment = remasterComment + " " + TKI_REMASTER;

            packageData.ToolkitInfo.PackageComment = remasterComment;

            // add default package version if missing
            if (String.IsNullOrEmpty(packageData.ToolkitInfo.PackageVersion))
                packageData.ToolkitInfo.PackageVersion = "1";
            else
                packageData.ToolkitInfo.PackageVersion = packageData.ToolkitInfo.PackageVersion.GetValidVersion();

            // validate packageData (important)
            packageData.Name = packageData.Name.GetValidKey(); // DLC Key

            try
            {
                // let's not bug user with this ... they should know what they are doing, right?
                //if (File.Exists(ddcFilePath) && !overWrite)
                //    if (MessageBox.Show("Are you sure to overwrite file? " + Path.GetFileName(ddcFilePath), MESSAGEBOX_CAPTION, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No)
                //        return result;

                // regenerates the SNG with the repair and repackages
                using (var psarcNew = new PsarcPackager(true))
                    psarcNew.WritePackage(ddcFilePath, packageData, filePath);
            }
            catch (Exception ex)
            {
                consoleOutput = "Error Writing: " + filePath + Environment.NewLine + ex.Message;
                result = -2; // Write Error
            }

            return result;
        }