public static DVD Parse(StreamReader output)
        {
            DVD thisDVD = new DVD();

            while (!output.EndOfStream)
            {
                if ((char)output.Peek() == '+')
                    thisDVD.m_titles.AddRange(Title.ParseList(output.ReadToEnd()));
                else
                    output.ReadLine();
            }

            return thisDVD;
        }
        public static void RipTVEpisodes(string PathToHandBrakeCLI, string HandBrakeQuality, string PathToVirtualCloneDrive, string DVDDriveLetter, string DVDID, string ISOFile, string OutputDirectory, string TVServerDirectory, string DiscNumber, string PluginName, string PluginType,
            bool Log, StreamWriter swWriteLog)
        {
            ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Path to HandBrake: " + PathToHandBrakeCLI);
            ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Path to Virtual Clone Drive: " + PathToVirtualCloneDrive);
            ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - DVD drive letter: " + DVDDriveLetter);
            ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - DVDID: " + DVDID);
            ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - ISOFile: " + ISOFile);
            ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Output directory: " + OutputDirectory);

            string DVDTitle = "";
            string TitleNum = "";
            string FileTitle = "";
            string chapterStart = "";
            string chapterEnd = "";
            string vcdDrive = "";

            //Reset Variables to original
            String OutputDirectory2 = OutputDirectory;
            String DVDID2 = DVDID;

            if (ISOFile != "")
            {
                ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Processing temporary ISO file");

                //UNMOUNT PREVIOUS ISO
                try
                {
                    ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Unmounting previous ISO file");
                    Process UVCD = new Process();
                    UVCD.StartInfo.FileName = PathToVirtualCloneDrive;
                    UVCD.StartInfo.Arguments = "/u";
                    UVCD.StartInfo.CreateNoWindow = true;
                    UVCD.StartInfo.UseShellExecute = false;
                    UVCD.Start();
                    UVCD.WaitForExit();
                }
                catch (Exception e)
                {
                    ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Error on OnMessage #2: " + e.ToString());
                }

                //Load ISO
                try
                {
                    //Launch Virtual CloneDrive
                    if (ISOFile != "")
                    {
                        ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Mounting current ISO file");
                        string ISOName = Path.GetFullPath(ISOFile);
                        Process VCD = new Process();
                        VCD.StartInfo.FileName = PathToVirtualCloneDrive;
                        VCD.StartInfo.Arguments = "\"" + ISOName + "\"";
                        VCD.StartInfo.CreateNoWindow = true;
                        VCD.StartInfo.UseShellExecute = false;
                        VCD.Start();
                        VCD.WaitForExit();

                        //SEE IF VIRTUAL DRIVE EXISTS
                        bool vDriveExists = false;
                        while (vDriveExists == false)
                        {
                            ManagementClass mgmt = new ManagementClass("Win32_CDROMDrive");
                            ManagementObjectCollection objCol = mgmt.GetInstances();
                            foreach (ManagementObject obj in objCol)
                            {
                                string DriveID = obj.Properties["Id"].Value.ToString();
                                string DriveCaption = obj.Properties["Caption"].Value.ToString();
                                ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - CD-Rom info: " + DriveID + " " + DriveCaption);
                                string[] virtualDriveIDs = { "elby", "clonedrive" };
                                foreach (string v in virtualDriveIDs)
                                {
                                    if (DriveCaption.ToLower().Contains(v))
                                    {
                                        vcdDrive = DriveID.Substring(0, 1);
                                        ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Virtual drive found: " + vcdDrive);
                                        vDriveExists = true;
                                        break;
                                    }
                                }
                            }
                        }

                        //WAIT FOR VIRTUAL CLONE DRIVE TO BECOME AVAILABLE
                        while (!Directory.Exists(vcdDrive + ":\\VIDEO_TS"))
                        {
                            //WAIT FOR ISO TO LOAD AND BECOME AVAILABLE
                        }
                    }
                }
                catch (Exception e)
                {
                    ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Error on OnMessage #3: " + e.ToString());
                }
                try
                {
                    if (OutputDirectory2 == "")
                    {
                        OutputDirectory2 = Path.GetDirectoryName(ISOFile);
                    }
                }
                catch (Exception e)
                {
                    ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Error on OnMessage #4: " + e.ToString());
                }
            }

            //GET DVD TITLE
            DVDTitle = ToolBox.DVDWebUtils.DVDTitle(DVDID, Log, swWriteLog);
            if (DVDTitle.Contains(":"))
            {
                int Pos = DVDTitle.IndexOf(":");
                String S2 = DVDTitle.Remove(Pos);
                DVDTitle = S2.Trim();
            }
            ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - DVD title: " + DVDTitle);

            //GET RUN TIMES FROM ALL TITLES AND CHAPTERS AND AVERAGE TO DETERMINE TARGET
            DVD thisDVD = new DVD();
            List<Title> titlelist = new List<Title>();
            List<TimeSpan> TitleRunTimes = new List<TimeSpan>();
            TimeSpan AveRunTime = new TimeSpan();

            try
            {
                //READ DVD AND WRITE TEXT FILE TO BE PARSED
                if (ISOFile != "")
                {
                    DVDDriveLetter = vcdDrive;
                }
                GetDVDInfo(DVDDriveLetter + ":\\VIDEO_TS", PathToHandBrakeCLI, DVDDriveLetter, PluginName, PluginType, Log, swWriteLog);

                //GET TITLE LIST
                try
                {
                    string DataDir = ToolBox.MeedioUtils.GetPluginDataDir(PluginName, PluginType);
                    string dvdInfoPath = Path.Combine(DataDir, "dvdinfo.txt");
                    ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[Handbrake] - Parsing DVD...");
                    using (StreamReader srDVD = new StreamReader(dvdInfoPath, Encoding.GetEncoding("iso-8859-1")))
                    {
                        thisDVD = DVD.Parse(srDVD);
                        titlelist = thisDVD.Titles;
                        ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[Handbrake] - Number of titles on DVD: " + titlelist.Count.ToString());
                        foreach (Title t in titlelist)
                        {
                            TitleRunTimes.Add(t.Duration);
                            ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[Handbrake] - Title: " + t.TitleNumber.ToString() + " " + t.Duration.ToString());
                        }
                    }
                }
                catch (Exception e)
                {
                    ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Error parsing title info: " + e.ToString());
                }

                //GET AVERAGE TITLE LENGTH
                AveRunTime = ToolBox.TimeDateUtils.AverageTimeSpan(TitleRunTimes);
                ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Average run time: " + AveRunTime.ToString());
            }
            catch (Exception e)
            {
                ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Error getting average run time: " + e.ToString());
            }

            //ESTIMATE EPISODE NUMBER
            List<Title> episodeList = new List<Title>();
            foreach (Title t in titlelist)
            {
                if (t.Duration.Ticks > (AveRunTime.Ticks * .8) && t.Duration.Ticks < (AveRunTime.Ticks * 1.2))
                {
                    episodeList.Add(t);
                }
            }
            int iDiscNumber = Convert.ToInt16(DiscNumber);
            int EpisodesPerDVD = episodeList.Count;
            int EpisodeNumber = 0;
            if (iDiscNumber == 1)
            {
                EpisodeNumber = 1;
            }
            if (iDiscNumber > 1)
            {
                EpisodeNumber = ((iDiscNumber - 1) * EpisodesPerDVD) + 1;
            }
            ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Estimated episode number: " + EpisodeNumber.ToString());

            //Create Handbrake CLI
            ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - 80% of Ave Ticks: " + (AveRunTime.Ticks * .8));
            ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - 120% of Ave Ticks: " + (AveRunTime.Ticks * 1.2));
            foreach (Title t in episodeList)
            {
                ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Title number " + t.TitleNumber + "Ticks: " + t.Duration.Ticks);
                try
                {
                    chapterStart = "1";
                    chapterEnd = t.Chapters.Count.ToString();
                    TitleNum = t.TitleNumber.ToString();
                    string EpisodeName = ToolBox.Handbrake2.EpisodeTitle(OutputDirectory, TVServerDirectory, EpisodeNumber, Log, swWriteLog);
                    if (EpisodeName != "")
                    {
                        FileTitle = EpisodeName;
                    }
                    if (EpisodeName == "")
                    {
                        FileTitle = "Title " + t.TitleNumber.ToString();
                    }
                    ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Episode name: " + FileTitle);

                    if (HandBrakeQuality == "")
                    {
                        HandBrakeQuality = ".7";
                    }
                    string root = PathToHandBrakeCLI.Remove(3);
                    string pathwithoutRoot = PathToHandBrakeCLI.Substring(3, PathToHandBrakeCLI.Length - 3);
                    string HBCLI = root + "\"" + pathwithoutRoot + "\" -i \"" + DVDDriveLetter + ":\\VIDEO_TS\"  -t " + TitleNum + " -c " + chapterStart + "-" + chapterEnd + " -o \"" + OutputDirectory2 + "\\" + FileTitle + ".mkv\" -e x264 -E ac3 -p  -q 0" + HandBrakeQuality + " -2  -T  -x ref=3:mixed-refs:bframes=6:bime:weightb:b-rdo:direct=auto:b-pyramid:me=umh:subme=7:analyse=all:8x8dct:trellis=1:no-fast-pskip -D 1 -v ";
                    ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Command line: " + HBCLI);

                    if (!File.Exists(OutputDirectory2 + "\\" + FileTitle + ".mkv"))
                    {
                        ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Output: " + OutputDirectory2 + "\\" + FileTitle + ".mkv");
                        //Launch Handbrake
                        ProcessStartInfo HBinfo = new ProcessStartInfo("cmd", "/C " + HBCLI);
                        Process hb = new Process();
                        hb.StartInfo = HBinfo;
                        hb.StartInfo.CreateNoWindow = false;
                        hb.StartInfo.UseShellExecute = false;
                        hb.Start();
                        hb.WaitForExit();
                    }
                }
                catch (Exception e)
                {
                    ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Error on OnMessage #6: " + e.ToString());
                }
            }
            //UNMOUNT ISO
            try
            {
                ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Unmounting ISO file");
                Process UVCD = new Process();
                UVCD.StartInfo.FileName = PathToVirtualCloneDrive;
                UVCD.StartInfo.Arguments = "/u";
                UVCD.StartInfo.CreateNoWindow = true;
                UVCD.StartInfo.UseShellExecute = false;
                UVCD.Start();
                UVCD.WaitForExit();
            }
            catch (Exception e)
            {
                ToolBox.MeedioUtils.LogEntry(Log, swWriteLog, "[HandBrake] - Error on OnMessage: " + e.ToString());
            }
        }