Inheritance: IItem
        public void CanConvertABookBackAndForth()
        {
            var book = new Book()
                           {
                               Authors = "Authors",
                               Id = 42,
                               Title = "Title"
                           };

            book.Formats.Add("This is a format");
            book.Formats.Add("another.format");

            var bookConverter = new BookConverter();
            var coreDoc = bookConverter.ToDocument(new CalibreBookSource(), book);

            var convertedBook = (Book)bookConverter.FromDocumentToItem(coreDoc);
            Assert.Equal(book.Authors, convertedBook.Authors);
            Assert.Equal(book.Title, convertedBook.Title);
            Assert.Equal(book.Id, convertedBook.Id);
            Assert.Equal(book.Formats, convertedBook.Formats);
        }
        private IEnumerable<object> GetBooks()
        {
            lock (ProcessLock)
            {
                if (CalibreDbIsRunning())
                    yield break;
            }
            var pathToCalibreDb = Path.Combine(Config.PathToCalibreInstalation, "calibredb.exe");
            if (!File.Exists(pathToCalibreDb))
            {
                Log.Debug("File {0} doesn't exist. Assuming calibre isn't installed.", pathToCalibreDb);
                yield break;
            }

            var outputPath = Path.GetTempFileName() + ".xml";
            try
            {
                lock (ProcessLock)
                {
                    var processStartInfo = new ProcessStartInfo();
                    processStartInfo.FileName = pathToCalibreDb;
                    processStartInfo.UseShellExecute = false;
                    processStartInfo.CreateNoWindow = true;
                    processStartInfo.Arguments = string.Format("catalog \"{0}\"", outputPath);
                    processStartInfo.RedirectStandardError = true;
                    processStartInfo.RedirectStandardOutput = true;
                    if (CalibreDbIsRunning())
                        yield break;
                    _currentCalibreProcess = Process.Start(processStartInfo);
                }

                _currentCalibreProcess.WaitForExit();
                if (_currentCalibreProcess.ExitCode != 0)
                {
                    Log.Warn("Calibredb process exited with {0}", _currentCalibreProcess.ExitCode);
                    Log.Warn("output : " + _currentCalibreProcess.StandardOutput.ReadToEnd());
                    Log.Warn("error : " + _currentCalibreProcess.StandardError.ReadToEnd());
                    yield break;
                }

                _currentCalibreProcess = null;

                var xmlText = File.ReadAllText(outputPath);
                var xml = XDocument.Parse(xmlText);
                foreach (var record in xml.XPathSelectElements("calibredb/record"))
                {
                    Book book = null;
                    try
                    {
                        book = new Book();
                        book.Id = int.Parse(record.Element("id").Value);
                        book.Title = record.Element("title").Value;
                        book.Authors = string.Join(", ", record.XPathSelectElements("authors/author").Select(e => e.Value));
                        foreach (var format in record.XPathSelectElements("formats/format").Select(e => e.Value))
                        {
                            book.Formats.Add(format);
                        }
                    }
                    catch (Exception e)
                    {
                        Log.Error(e, "Error parsing book record {0}", record.ToString());
                    }
                    if(book != null)
                        yield return book;
                }
            }
            finally
            {
                if (File.Exists(outputPath))
                    File.Delete(outputPath);
            }
        }