/// <summary>
        /// Sorts and filters all video links (hosters) for a given video
        /// </summary>
        /// <param name="video">The video that is handled</param>
        /// <param name="baseUrl">The base url of the video</param>
        /// <param name="tmp"></param>
        /// <param name="limit">How many playback options are at most shown per hoster (0=all)</param>
        /// <param name="showUnknown">Also show playback options where no hoster is available yet</param>
        /// <returns></returns>
        public string SortPlaybackOptions(VideoInfo video, string baseUrl, string tmp, int limit, bool showUnknown)
        {
            List<PlaybackElement> lst = new List<PlaybackElement>();
            if (video.PlaybackOptions == null) // just one
                lst.Add(new PlaybackElement("100%justone", FormatHosterUrl(tmp)));
            else
                foreach (string name in video.PlaybackOptions.Keys)
                {
                    PlaybackElement element = new PlaybackElement(FormatHosterName(name), FormatHosterUrl(video.PlaybackOptions[name]));
                    element.status = "ns";
                    if (element.server.Equals("videoclipuri") ||
                        HosterFactory.ContainsName(element.server.ToLower().Replace("google", "googlevideo")))
                        element.status = String.Empty;
                    lst.Add(element);
                }

            Dictionary<string, int> counts = new Dictionary<string, int>();
            foreach (PlaybackElement el in lst)
            {
                if (counts.ContainsKey(el.server))
                    counts[el.server]++;
                else
                    counts.Add(el.server, 1);
            }
            Dictionary<string, int> counts2 = new Dictionary<string, int>();
            foreach (string name in counts.Keys)
                if (counts[name] != 1)
                    counts2.Add(name, counts[name]);

            lst.Sort(PlaybackComparer);

            for (int i = lst.Count - 1; i >= 0; i--)
            {
                if (counts2.ContainsKey(lst[i].server))
                {
                    lst[i].dupcnt = counts2[lst[i].server];
                    counts2[lst[i].server]--;
                }
            }

            video.PlaybackOptions = new Dictionary<string, string>();
            bool lastPlaybackOptionUrlPresent = false;

            foreach (PlaybackElement el in lst)
            {
                if (!Uri.IsWellFormedUriString(el.url, System.UriKind.Absolute))
                    el.url = new Uri(new Uri(baseUrl), el.url).AbsoluteUri;

                if ((limit == 0 || el.dupcnt <= limit) && (showUnknown || el.status == null || !el.status.Equals("ns")))
                {
                    video.PlaybackOptions.Add(el.GetName(), el.url);
                    lastPlaybackOptionUrlPresent |= (el.url == lastPlaybackOptionUrl);
                }
            }

            if (lst.Count == 1)
            {
                video.VideoUrl = video.GetPlaybackOptionUrl(lst[0].GetName());
                video.PlaybackOptions = null;
                return video.VideoUrl;
            }

            if (lastPlaybackOptionUrlPresent)
                return lastPlaybackOptionUrl;

            if (lst.Count > 0)
                tmp = lst[0].url;

            return tmp;
        }