/// <summary>
        /// Read a CSD and get its document guid
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static Guid GetGuidFromCsd(String fileName)
        {
            Guid ret = Guid.Empty;

            SlideViewer.CSDDocument document        = null;
            BinaryFormatter         binaryFormatter = new BinaryFormatter();
            FileStream stream = null;

            try
            {
                stream   = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                document = (SlideViewer.CSDDocument)binaryFormatter.Deserialize(stream);
                ret      = document.Identifier;
            }
            catch
            {
                Debug.WriteLine("Failed to read: " + fileName);
            }
            finally
            {
                stream.Close();
            }
            return(ret);
        }
		/// <summary>
		/// Save the given presentation to the given file name.
		/// </summary>
		/// <param name="presentation">non-null presentation to save</param>
		/// <param name="fileName">non-null, writable filename</param>
		/// <remarks>may throw any of the same exceptions that File.Create throws</remarks>
		public void SavePresentation(PowerPoint.Presentation presentation, string fileName)
		{
			// TODO: error handling
			System.IO.Stream stream = System.IO.File.Create(fileName);
			IFormatter formatter = new BinaryFormatter();
            SlideViewer.SlideDeck sd = this.MakeSlideDeck(presentation, fileName);
            SlideViewer.CSDDocument csd = new SlideViewer.CSDDocument();
            csd.SetInfo(sd);
            formatter.Serialize(stream, csd);
			stream.Close();
		}
        /// <summary>
        /// Open a CSD and create a directory of jpg images, one per slide.
        /// </summary>
        /// <param name="g"></param>
        /// <param name="file"></param>
        private void processCsd(Guid g, FileInfo file)
        {
            if (stopNow)
            {
                return;
            }

            String tempDirName = Utility.GetTempDir();

            SlideViewer.CSDDocument document        = null;
            BinaryFormatter         binaryFormatter = new BinaryFormatter();
            FileStream stream = null;

            try
            {
                stream   = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                document = (SlideViewer.CSDDocument)binaryFormatter.Deserialize(stream);
            }
            catch (Exception e)
            {
                Debug.WriteLine("Failed to read: " + file.FullName + "; exception text: " + e.ToString());
                log.WriteLine("Error: Failed to read file: " + file.FullName +
                              ".  Possibly the file was produced with an unsupported version of Classroom Presenter.  Exception text: " +
                              e.ToString());
                log.ErrorLevel = 5;
            }
            finally
            {
                stream.Close();
            }

            if (document == null)
            {
                return;
            }


            if (document.DocumentType != "Presentation")
            {
                log.WriteLine("Error: Document type is not Presentation: " + file.FullName);
                log.ErrorLevel = 3;
                progressTracker.CurrentValue += 100;
                return;
            }

            Directory.CreateDirectory(tempDirName);

            int pageNum = 1;
            int ptStart = progressTracker.CurrentValue;

            foreach (SlideViewer.SlideDocument page in document.Pages)
            {
                if (stopNow)
                {
                    break;
                }
                // SlideMode images may be any or all of Student, Instructor, Shared, Default..
                // I think we prefer Default, but will also take Shared.
                if (page.slideImages.Count > 0)
                {
                    object o = null;
                    foreach (String s in page.slideImages.Keys)
                    {
                        if (s == "Default")
                        {
                            o = page.slideImages[s];
                            break;
                        }
                        else if ((s == "Shared") && (o == null))
                        {
                            o = page.slideImages[s];
                        }
                    }
                    //The image may be SerializableImage or just Image, the former for EMF.
                    if (o != null)
                    {
                        Image img = null;
                        if (o is SlideViewer.SerializableImage)
                        {
                            SlideViewer.SerializableImage si = (SlideViewer.SerializableImage)o;
                            img = si.image;
                        }
                        else if (o is System.Drawing.Image)
                        {
                            img = (Image)o;
                        }
                        else
                        {
                            log.WriteLine("Error: Unrecognized image type in deck: " + file.FullName);
                            log.ErrorLevel = 5;
                        }
                        if (img != null)
                        {
                            String outfile = Path.Combine(tempDirName, "slide" + pageNum.ToString() + ".jpg");
                            //The images in EMF format are rather huge.. scale them down.
                            if (img.Size.Width > 1600)
                            {
                                Image img2 = new Bitmap(img, new Size(960, 720));
                                img2.Save(outfile, ImageFormat.Jpeg);
                                //PRI2: the scaled images tend to look like crap. Fix?
                                // try converting to wmf, then to jpg?
                                //this.SaveWithQuality(outfile,img2,100); //<-- no help
                                img2.Dispose();
                                log.WriteLine("Warning: Slide " + pageNum.ToString() + " was scaled. " +
                                              "For better results, use a CSD that was created with WMF format, or specify the " +
                                              "original PPT file.");
                                log.ErrorLevel = 3;
                            }
                            else
                            {
                                img.Save(outfile, System.Drawing.Imaging.ImageFormat.Jpeg);
                            }
                            img.Dispose();
                        }
                    }
                }
                progressTracker.CurrentValue = ((pageNum * 100) / document.Pages.Length) + ptStart;
                pageNum++;
            }
            log.WriteLine("Processed " + (pageNum - 1).ToString() + " pages for " + file.FullName);
            outputDirs.Add(g, tempDirName);
        }