protected void Refresh()
        {
            // Empty the page defensively
            gvMilestoneProgress.DataSource = null;
            gvMilestoneProgress.DataBind();

            pnlOverallProgress.Visible = false;
            ClearCookie();

            if (cmbMilestones.SelectedIndex == 0 || String.IsNullOrEmpty(cmbMilestoneGroup.SelectedValue) || Milestones.FirstOrDefault(mg => mg.GroupName.CompareCurrentCulture(cmbMilestoneGroup.SelectedValue) == 0) == null)
            {
                return;
            }

            MilestoneGroup mgSel = Milestones.FirstOrDefault(mg => mg.GroupName.CompareCurrentCulture(cmbMilestoneGroup.SelectedValue) == 0);

            if (mgSel == null || cmbMilestones.SelectedIndex > mgSel.Milestones.Count || cmbMilestones.SelectedIndex == 0)
            {
                return;
            }

            MilestoneProgress mp = mgSel.Milestones[cmbMilestones.SelectedIndex - 1];

            SetCookie();

            if (!mp.HasData)
            {
                mp.Username = TargetUser;
            }

            lblRatingOverallDisclaimer.Text = mp.GeneralDisclaimer.Linkify();
            pnlRatingDisclaimer.Visible     = !String.IsNullOrEmpty(lblRatingOverallDisclaimer.Text);

            gvMilestoneProgress.DataSource = mp.ComputedMilestones;
            gvMilestoneProgress.DataBind();

            pnlOverallProgress.Visible = true;
            int cMilestones    = 0;
            int cMetMilestones = 0;

            foreach (MilestoneItem mi in mp.ComputedMilestones)
            {
                cMilestones++;
                if (mi.IsSatisfied)
                {
                    cMetMilestones++;
                }
            }
            lblOverallProgress.Text = String.Format(CultureInfo.CurrentCulture, Resources.MilestoneProgress.OverallProgressTemplate, cMetMilestones, cMilestones);
            lblPrintHeader.Text     = String.Format(CultureInfo.CurrentCulture, Resources.MilestoneProgress.RatingProgressPrintHeaderTemplate, mp.Title, Profile.GetUser(TargetUser).UserFullName, DateTime.Now.Date.ToShortDateString());
        }
        protected void UpdateMilestones()
        {
            MilestoneGroup mgeCustom = null;

            foreach (MilestoneGroup mg in Milestones)
            {
                if (mg is CustomRatingsGroup)
                {
                    mgeCustom = mg as CustomRatingsGroup;
                    break;
                }
            }

            if (mgeCustom != null)
            {
                Milestones = MilestoneProgress.AvailableProgressItems(TargetUser);
                // Refresh the milestones to reflect the current milestone or group of milestones.
                cmbMilestoneGroup_SelectedIndexChanged(cmbMilestoneGroup, new EventArgs());
            }
        }
        protected void cmbMilestoneGroup_SelectedIndexChanged(object sender, EventArgs e)
        {
            cmbMilestones.Items.Clear();
            ListItem li = new ListItem(Resources.MilestoneProgress.RatingUnknown, String.Empty)
            {
                Selected = true
            };

            cmbMilestones.Items.Add(li);

            MilestoneGroup mgSel = Milestones.FirstOrDefault(mg => mg.GroupName.CompareCurrentCulture(cmbMilestoneGroup.SelectedValue) == 0);

            if (mgSel != null)
            {
                cmbMilestones.DataSource = mgSel.Milestones;
                cmbMilestones.DataBind();
            }

            // Only show the "Add/Edit" ratings box if custom ratings is selected AND viewing your own milestones
            pnlAddEdit.Visible = mgSel is CustomRatingsGroup && Page.User.Identity.Name.CompareCurrentCultureIgnoreCase(TargetUser) == 0;

            Refresh();
        }