private HttpResponse ContainerItems()
        {
            if (!id2.HasValue || id2.Value == 100)
                return LibraryItems();

            var filter = new FilterExpression<ITrack>(Request.QueryString["query"]);
            var includeSortHeaders = "1".Equals(Request.QueryString["include-sort-headers"]);
            var sort = new SortExpression(Request.QueryString["sort"]);

            using (Player.MediaLibrary.BeginRead())
            {
                var pl = Player.GetContainers().FirstOrDefault(x => x.Id == id2.Value);
                if (pl != null)
                {
                    lock (pl)
                    {
                        var rawItems = filter.Filter(pl.Tracks);

                        var items = rawItems.Select<ITrack, object>(GetTrackItem).ToArray();

                        return new DmapResponse(new
                        {
                            apso = new
                            {
                                mstt = 200,
                                muty = (byte)0,
                                mlcl = items
                            }
                        });
                    }
                }
            }

            return new DmapResponse(new
            {
                apso = new
                {
                    mstt = 200,
                    muty = (byte)0,
                    mlcl = new object[0]
                }
            });
        }
        private HttpResponse CueResponse()
        {
            switch (Request.QueryString["command"])
            {
                case "clear":
                    {
                        Player.ClearPlaybackSource();

                        return new DmapResponse(new
                        {
                            cacr = new
                            {
                                mstt = 200,
                                miid = (Player.ActivePlaylist ?? Player.MediaLibrary).Id
                            }
                        });
                    }

                case "play":
                    {
                        if (!string.IsNullOrEmpty(Request.QueryString["query"]))
                        {
                            var filter = new FilterExpression<ITrack>(Request.QueryString["query"]);
                            var sort = new SortExpression(Request.QueryString["sort"]);

                            using (Player.MediaLibrary.BeginRead())
                            {
                                var items = sort.Sort(filter.Filter(Player.MediaLibrary.Tracks)).ToArray();
                                Player.SetPlaybackSource(items);
                            }
                        }

                        int index;
                        if (string.IsNullOrEmpty(Request.QueryString["index"]) || !int.TryParse(Request.QueryString["index"], out index))
                            index = -1;

                        var track = Player.Play(index);

                        return new DmapResponse(new
                        {
                            cacr = new
                            {
                                mstt = 200,
                                miid = (Player.ActivePlaylist ?? Player.MediaLibrary).Id
                            }
                        });
                    }

                case "add":
                    {
                        if (!string.IsNullOrEmpty(Request.QueryString["query"]))
                        {
                            var filter = new FilterExpression<ITrack>(Request.QueryString["query"]);
                            var sort = new SortExpression(Request.QueryString["sort"]);

                            using (Player.MediaLibrary.BeginRead())
                            {
                                var items = new List<ITrack>();

                                var oldItems = Player.GetPlaybackSource();
                                if (oldItems != null)
                                    items.AddRange(oldItems);
                                var oldCount = items.Count;

                                items.AddRange(sort.Sort(filter.Filter(Player.MediaLibrary.Tracks)));
                                if (items.Count != oldCount)
                                {
                                    Player.SetPlaybackSource(items.ToArray());
                                }
                            }
                        }

                        return new DmapResponse(new
                        {
                            cacr = new
                            {
                                mstt = 200,
                                miid = (Player.ActivePlaylist ?? Player.MediaLibrary).Id
                            }
                        });
                    }

                default:
                    return new NotFoundResponse();
            }
        }
        private HttpResponse LibraryItems()
        {
            var filter = new FilterExpression<ITrack>(Request.QueryString["query"]);
            var includeSortHeaders = "1".Equals(Request.QueryString["include-sort-headers"]);
            var sort = new SortExpression(Request.QueryString["sort"]);

            using (Player.MediaLibrary.BeginRead())
            {
                var rawItems = sort.Sort(filter.Filter(Player.MediaLibrary.Tracks));

                Func<ITrack, string> selector;

                switch (Request.QueryString["sort"])
                {
                    case "album":
                    case "albums":
                        selector = x => x.AlbumArtistName;
                        break;

                    case "artist":
                    case "artists":
                        selector = x => x.AlbumName;
                        break;

                    default:
                        selector = x => x.Title;
                        break;
                }

                var items = rawItems.Select<ITrack, object>(GetTrackItem).ToArray();

                if (items.Length == 0 && !includeSortHeaders)
                {
                    // album not in library, and this is not search

                    using (Player.BeginRead())
                    {
                        if (filter.IsMatch(Player.CurrentTrack))
                            items = new[] { GetTrackItem(Player.CurrentTrack, 0) };
                    }
                }

                return new DmapResponse(new
                {
                    apso = new
                    {
                        mstt = 200,
                        muty = (byte)0,
                        mlcl = items,
                        //mshl = includeSortHeaders ? rawItems.GetShortcuts(selector) : null
                    }
                });
            }
        }
        private HttpResponse QueueEditResponse()
        {
            var command = Request.QueryString["command"];
            int mode = int.Parse(Request.QueryString["mode"]);

            switch (command)
            {
                case "clear":
                    // todo: clear
                    return new NoContentResponse();

                case "add":
                    // todo: add
                    if (!string.IsNullOrEmpty(Request.QueryString["query"]))
                    {
                        var filter = new FilterExpression<ITrack>(Request.QueryString["query"]);
                        var queuefilter = Request.QueryString["queuefilter"];
                        var sort = new SortExpression(Request.QueryString["sort"]);

                        using (Player.MediaLibrary.BeginRead())
                        {
                            var items = new List<ITrack>();
                            var oldCount = 0;

                            if (mode == 3)
                            {
                                // next
                                var oldItems = Player.GetPlaybackSource();
                                if (oldItems != null)
                                    items.AddRange(oldItems);
                                oldCount = items.Count;
                            }

                            if (string.IsNullOrEmpty(queuefilter))
                            {
                                items.AddRange(sort.Sort(filter.Filter(Player.MediaLibrary.Tracks)));
                            }
                            else if (queuefilter.StartsWith("playlist:"))
                            {
                                var playlist = Player.Playlists.FirstOrDefault(x => x.Id == int.Parse(queuefilter.Substring(9)));
                                if (playlist != null)
                                    items.AddRange(sort.Sort(filter.Filter(playlist.Tracks)));
                                else
                                    throw new InvalidOperationException("Playlist with id " + queuefilter.Substring(9) + " not found");
                            }
                            else
                                throw new InvalidOperationException("Unknown queuefilter: " + queuefilter);

                            if (items.Count != oldCount)
                            {
                                Player.SetPlaybackSource(items.ToArray());
                            }
                        }
                    }

                    if (mode == 1)
                    {
                        int index;
                        if (string.IsNullOrEmpty(Request.QueryString["index"]) || !int.TryParse(Request.QueryString["index"], out index))
                            index = -1;

                        var track = Player.Play(index);
                    }

                    return new DmapResponse(new
                    {
                        cacr = new
                        {
                            mstt = 200,
                            miid = (Player.ActivePlaylist ?? Player.MediaLibrary).Id
                        }
                    });

                default:
                    return new NotFoundResponse();
            }
        }