/// <summary>
/// Borrows a couple of ideas from
/// http://kosta.apostolou.ca/post/2008/02/How-to-Create-a-TagCloud-Using-LINQ-and-ASPNET.aspx
/// </summary>
void xmlClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null)
    {
        XDocument metadataXML = XDocument.Parse(e.Result); // using Linq for XML to parse out the XML is easier than using XmlReader
        XElement metaDataElement = metadataXML.Element("Metadata");
        var imageItems = from g in metaDataElement.Descendants()
                         where g.Name == "Image"
                         select g;

        listOfImagesTagged = new List<MultiScaleSubImage>();
        listOfAllImages = new List<DZImageReference>();
        var maxTagFrequency = 0;
        string[] tags = null;
        foreach (XElement g in imageItems)
        {
            string tagString = g.Element("Tag").Value.Trim();
            tags = tagString.Split(new char[] { ',', ';' });
            // split the tags up, rather than treat the whole string as 'one'
            if (tags.Length == 0)
            {
                tags = new string[] {"None"};
            }
            int zOrder = int.Parse(g.Element("ZOrder").Value) - 1;

            DZImageReference imageRef = new DZImageReference() { Tag = tagString, zOrder = zOrder, SubImage = msi.SubImages[zOrder] };
            // parse out the tags
            foreach (string tag in tags)
            {
                string cleanTag = tag.Trim();
                if (uniqueTags.ContainsKey(cleanTag))
                {
                    var tagCoutn = Convert.ToInt32(uniqueTags[cleanTag]) + 1;
                    uniqueTags[cleanTag] = tagCount.ToString();
                    if (tagCount > maxTagFrequency) maxTagFrequency = tagCount;
                } 
                else 
                {
                    uniqueTags.Add(cleanTag, "1");
                }
            }
            listOfAllImages.Add(imageRef);
        }
        foreach (string uniqueTag in uniqueTags.Keys)
        {
            ListBoxItem lbi = new ListBoxItem();
            lbi.Content = uniqueTag;
            if (uniqueTag == "None")
            {
                TagListbox.Items.Insert(1, lbi);
            }
            else
            {
                var tagWeight = Convert.ToDouble(uniqueTags[uniqueTag]) / maxTagFrequency * 100;
                lbi.SetValue(ListBoxItem.FontSizeProperty, GetTagSize(tagWeight));
                TagListbox.Items.Add(lbi);
            }
        }
        FilterImages("All");
    }
}
/// <summary>
/// HACK: note hardcoded font sizes 
/// </summary>
public double GetTagSize(double weight)
{
    if (weight >= 99)
        return 16.0;
    else if (weight >= 60)
        return 14.0;
    else if (weight >= 40)
        return 12.0;
    else if (weight >= 20)
        return 10.0;
    else
        return 8.0;
}