public IList<CDDBEntry> GetAlbumMatches()
        {
            // initialise the output list
            IList<CDDBEntry> albums = new List<CDDBEntry>();

            // check the CD first
            if (CheckCDDrive())
            {
                // get the information from the drive to make the match
                string queryString = Drive.GetCDDBQuery();

                // build up the command string
                var commandBuilder = new StringBuilder();
                commandBuilder.Append("?");
                commandBuilder.Append(FreeDBConstants.COMMAND);
                commandBuilder.Append(FreeDBConstants.COMMAND_QUERY);
                commandBuilder.Append("+");
                commandBuilder.Append(queryString);
                commandBuilder.Append("&");
                commandBuilder.Append(GenerateHello());
                commandBuilder.Append("&");
                commandBuilder.Append(GenerateProtocol());

                // make the URL to use
                var urlBuilder = new StringBuilder();
                urlBuilder.Append(FreeDBConstants.URL_FREEDB_MAIN);
                urlBuilder.Append(FreeDBConstants.URL_HTTP_ACCESS);

                // hit up FreeDB for the result
                IList<string> freeDBResponse = Query(urlBuilder.ToString(), commandBuilder.ToString());

                // parse the query
                if (freeDBResponse.Count > 0)
                {
                    // extract the response code
                    ResponseCode responseCode = ExtractResponseCode(freeDBResponse[0]);

                    switch (responseCode)
                    {
                        case ResponseCode.RESPONSE_CODE_DEFAULT:
                            _log.Error("Problem querying album using command: " + commandBuilder);
                            break;
                        case ResponseCode.RESPONSE_CODE_200:
                        case ResponseCode.RESPONSE_CODE_210:
                            _log.Debug("Found album/s");

                            // break up each of the results
                            foreach (string responseLine in freeDBResponse)
                            {
                                string[] lineSegments = responseLine.Split(new[] {' '});
                                string genre = lineSegments[1];
                                string discId = lineSegments[2];

                                // grab each of the artist
                                var artistBuilder = new StringBuilder();
                                int index = 3;
                                for (int i = index; i < lineSegments.Count(); i++)
                                {
                                    // increment the index in the array
                                    index++;
                                    // check it's not the artist/title delimiter
                                    if (lineSegments[i] != "/")
                                    {
                                        artistBuilder.Append(lineSegments[i]);
                                        artistBuilder.Append(" ");
                                    }
                                        // if it is, stop now
                                    else
                                    {
                                        break;
                                    }
                                }
                                string artist = artistBuilder.ToString().Trim();

                                // grab the title
                                var titleBuilder = new StringBuilder();
                                for (int i = index; i < lineSegments.Count(); i++)
                                {
                                    titleBuilder.Append(lineSegments[i]);
                                    titleBuilder.Append(" ");
                                }
                                string title = titleBuilder.ToString().Trim();

                                // create the output object for this listing
                                var result = new CDDBEntry(genre, discId, artist, title);

                                // and add it to the list
                                albums.Add(result);
                            }
                            break;
                        default:
                            _log.Error("Response came back we weren't expecting, handle it");
                            break;
                    }
                }
                Drive.UnLockCD();
            }

            return albums;
        }
        public Album GetTracks(CDDBEntry cddbResult)
        {
            // initialise the album to output
            Album newAlbum = null;

            // build up the command string
            var commandBuilder = new StringBuilder();
            commandBuilder.Append("?");
            commandBuilder.Append(FreeDBConstants.COMMAND);
            commandBuilder.Append(FreeDBConstants.COMMAND_READ);
            commandBuilder.Append("+");
            commandBuilder.Append(cddbResult.Genre);
            commandBuilder.Append("+");
            commandBuilder.Append(cddbResult.DiscID);
            commandBuilder.Append("&");
            commandBuilder.Append(GenerateHello());
            commandBuilder.Append("&");
            commandBuilder.Append(GenerateProtocol());

            // make the URL to use
            var urlBuilder = new StringBuilder();
            urlBuilder.Append(FreeDBConstants.URL_FREEDB_MAIN);
            urlBuilder.Append(FreeDBConstants.URL_HTTP_ACCESS);

            // hit up FreeDB for the result
            IList<string> freeDBResponse = Query(urlBuilder.ToString(), commandBuilder.ToString());

            // parse the query
            if (freeDBResponse.Count > 0)
            {
                // extract the response code
                ResponseCode responseCode = ExtractResponseCode(freeDBResponse[0]);

                switch (responseCode)
                {
                    case ResponseCode.RESPONSE_CODE_DEFAULT:
                        _log.Error("Problem querying album using command: " + commandBuilder);
                        break;
                    case ResponseCode.RESPONSE_CODE_200:
                    case ResponseCode.RESPONSE_CODE_210:
                        _log.Debug("Found track/s");

                        // get a hook to the DB
                        IDBClient db = Database.RetrieveClient();

                        // we'll look for an artist to attach this all to
                        Artist theArtist = Database.RetrieveArtistByName(db, cddbResult.ArtistName);

                        // TODO Check for artists, as opposed to just one

                        // if we don't we'll create one
                        if (null == theArtist)
                        {
                            theArtist = new Artist(cddbResult.ArtistName);
                        }

                        db.Close();

                        // we'll create an album for this with invalid data, we'll fill that out after
                        newAlbum = new Album(cddbResult.Title, theArtist, null, 1900, Compression.Undecided);

                        // a list to keep track of the track lengths in seconds
                        IList<int> trackLengths = new List<int>();

                        // keep track of the track offsets for track lengths
                        int lastTrackOffset = 0;

                        // break up each of the results
                        foreach (string responseLine in freeDBResponse)
                        {
                            // extract the track lengths
                            if (responseLine.Contains("#\t"))
                            {
                                // parse the next offset
                                int newOffset = Int32.Parse(responseLine.Substring(2));

                                // stop the first one being processed
                                if (lastTrackOffset > 0)
                                {
                                    int seconds = (newOffset - lastTrackOffset)/75;
                                    trackLengths.Add(seconds);
                                }

                                // store the new offset
                                lastTrackOffset = newOffset;
                            }

                            // extract the total number of seconds so we can calculate the last tracks length
                            if (responseLine.Contains("# Disc length"))
                            {
                                // parse the total length of the album in seconds
                                int totalLength = Int32.Parse(responseLine.Substring(15, 4));

                                int secondsToDate = lastTrackOffset/75;

                                // extract the length of the last track from this to find out the length of the final track
                                int lastTrackLength = totalLength - secondsToDate;

                                // add this to the lengths
                                trackLengths.Add(lastTrackLength);
                            }

                            // extract the year
                            if (responseLine.Contains("DYEAR"))
                            {
                                string year = responseLine.Substring(6);
                                newAlbum.ReleaseYear = Int32.Parse(year);
                            }

                            // extract a track
                            if (responseLine.Contains("TTITLE"))
                            {
                                // marker for where to parse string to
                                int indexOfSpace = responseLine.IndexOf('=', 6);
                                string numberString = responseLine.Substring(6, (indexOfSpace - 6));

                                int trackNumber = Int32.Parse(numberString) + 1;

                                string trackTitle = responseLine.Substring(indexOfSpace + 1);
                                // create this with no path as it's not currently set
                                var artists = new List<Artist>();
                                artists.Add(theArtist);
                                var newTrack = new Track(trackNumber, artists, newAlbum,
                                                         new Duration(new TimeSpan(0, 0, trackLengths[trackNumber - 1])),
                                                         trackTitle, null);
                                newAlbum.AddTrack(newTrack);
                            }
                        }
                        break;
                    default:
                        _log.Error("Response came back we weren't expecting, handle it");
                        break;
                }
            }

            // pass back the resulting album
            return newAlbum;
        }