internal virtual void UpdateSprites(TreeItemState lastState, bool instant)
        {
            //handle hiding
            if (state <= TreeItemState.Hidden)
            {
                if (SpriteCollection[0].Alpha != 0)
                {
                    SpriteCollection.ForEach(p => p.FadeOut(instant ? 0 : 200));
                }
            }
            else if (lastState <= TreeItemState.Hidden)
            {
                int showCount = state >= TreeItemState.ExtrasVisible ? SpriteCollection.Count : AlwaysVisibleSprites;
                for (int i = 0; i < showCount; i++)
                {
                    SpriteCollection[i].FadeInFromZero(instant ? 0 : 200);
                }
            }

            UpdateHorizontalLayout();

            //handle stars
            if ((state >= TreeItemState.ExtrasVisible && lastState < TreeItemState.ExtrasVisible) || (state < TreeItemState.ExtrasVisible && lastState >= TreeItemState.ExtrasVisible))
            {
                float yPadding     = OldLayout ? -3 : 0;
                float thumbPadding = shouldShowThumbnail ? 75 : 5;

                if (state >= TreeItemState.ExtrasVisible)
                {
                    starSpritesBeginIndex      = SpriteCollection.Count;
                    blackStarSpritesBeginIndex = blackSprites.Count;

                    Color backgroundStarColour = new Color(255, 255, 255, 30);
                    for (int i = 0; i < AMOUNT_STARS; ++i)
                    {
                        pSprite star = new pSprite(s_star, Fields.TopLeft, Origins.Centre, Clocks.Game, Vector2.Zero, textTitle.Depth, true, backgroundStarColour, Beatmap)
                        {
                            VectorScale = new Vector2(star_scale, star_scale),
                            Tag         = new Vector2(leftPadding + thumbPadding + (i + 0.5f) * (s_star.DisplayWidth * 0.625f) * star_scale, yPadding + 18),
                            Additive    = true,
                            Alpha       = 0
                        };

                        if (!OldLayout)
                        {
                            star.Scale = 0.35f;
                        }

                        SpriteCollection.Add(star);
                    }

                    for (int i = 0; i < AMOUNT_STARS; ++i)
                    {
                        pSprite star = new pSprite(s_star, Fields.TopLeft, Origins.Centre, Clocks.Game, Vector2.Zero, textTitle.Depth + DEPTH_INCREASE_STEP, true, Color.White, Beatmap)
                        {
                            VectorScale = new Vector2(star_scale, star_scale),
                            Tag         = new Vector2(leftPadding + thumbPadding + (i + 0.5f) * (s_star.DisplayWidth * 0.625f) * star_scale, yPadding + 18),
                        };

                        if (OldLayout)
                        {
                            star.DrawWidth = -(int)(star.Width * i);
                        }
                        else
                        {
                            star.Scale = 0;
                        }

                        SpriteCollection.Add(star);
                        blackSprites.Add(star);
                    }

                    for (int i = 0; i < SpriteCollection.Count; i++)
                    {
                        pSprite p = SpriteCollection[i] as pSprite;

                        if (i >= AlwaysVisibleSprites && (i < starSpritesBeginIndex || i >= starSpritesBeginIndex + AMOUNT_STARS))
                        {
                            // We don't want our background sprites to fade in yet
                            p.FadeIn(instant ? 0 : 300);
                        }
                    }

                    UpdateStarDifficultyDisplay(instant);
                }
                else
                {
                    for (int i = 0; i < SpriteCollection.Count; i++)
                    {
                        pSprite p = SpriteCollection[i] as pSprite;
                        if (i >= AlwaysVisibleSprites)
                        {
                            p.FadeOut(instant ? 0 : 300);
                        }
                    }

                    int starSpritesEndIndex = starSpritesBeginIndex + AMOUNT_STARS * 2;
                    for (int i = starSpritesBeginIndex; i < starSpritesEndIndex; ++i)
                    {
                        SpriteCollection[i].AlwaysDraw = false;
                    }

                    SpriteCollection.RemoveRange(starSpritesBeginIndex, AMOUNT_STARS * 2);
                    blackSprites.RemoveRange(blackStarSpritesBeginIndex, AMOUNT_STARS);

                    currentlyVisibleStars = -1;
                }
            }

            //handle expanded state changes.
            if ((state >= TreeItemState.Expanded && lastState < TreeItemState.Expanded) || (state < TreeItemState.Expanded && lastState >= TreeItemState.Expanded))
            {
                if (state >= TreeItemState.Expanded)
                {
                    if (thumbnail != null)
                    {
                        thumbnail.Additive = false;
                        thumbnail.FadeInFromZero(instant ? 0 : 1000);
                        thumbnail.TimeBeforeLoad = 100;
                        thumbnail.FadeColour(new Color(255, 255, 255, 255), instant ? 0 : 300);
                    }
                }
                else
                {
                    if (thumbnail != null)
                    {
                        thumbnail.Additive       = true;
                        thumbnail.TimeBeforeLoad = 500;
                        thumbnail.FadeColour(new Color(50, 50, 50, 255), instant ? 0 : 300);
                    }
                }

                UpdateHorizontalLayout();
            }

            UpdateUnselectedColour(instant ? 0 : 300);

            //handle active state changes.
            if (state == TreeItemState.Active)
            {
                blackSprites.ForEach(t => { t.InitialColour = BeatmapTreeItem.colourTextActive; });
            }
            else
            {
                blackSprites.ForEach(t =>
                {
                    Color c;
                    if (state <= TreeItemState.ExtrasVisible)
                    {
                        c = colourTextInactive;
                    }
                    else
                    {
                        if (t == textArtist || t == textTitle)
                        {
                            c = colourTextInactiveFaded;
                        }
                        else
                        {
                            c = colourTextInactive;
                        }
                    }

                    t.InitialColour = c;
                });
            }
        }
        protected virtual void PopulateSprites()
        {
            Debug.Assert(SpriteCollection == null && !IsLoaded);

            SpriteCollection = new List <pDrawable>();

            if (Beatmap != null)
            {
                PlayModes?mode = modeOverride;
                if (Beatmap != null && Beatmap.PlayMode != PlayModes.Osu)
                {
                    mode = Beatmap.PlayMode;
                }

                OldLayout = SkinManager.Current.Version < 2.2 && TextureManager.Load(@"menu-button-background").Source != SkinSource.Osu;

                string text  = Beatmap.SortTitleAuto;
                string text2 = Beatmap.Creator.Length > 0 ? Beatmap.Creator : "unknown creator";

                backgroundSprite =
                    new pSprite(s_menuButtonBackground, Fields.TopLeft,
                                Origins.CentreLeft,
                                Clocks.Game,
                                new Vector2((float)Position.X, (float)Position.Y), StartDepth, true, BackgroundColour, this);
                backgroundSprite.HandleInput = true;
                SpriteCollection.Add(backgroundSprite);

                bool thumb = shouldShowThumbnail;

                float xPadding     = OldLayout ? 15 : 5;
                float thumbPadding = thumb ? 75 : 5;
                float yPadding     = OldLayout ? -3 : 0;

                float titleSize = GameBase.TournamentDrawings ? 22 : 16;
                textTitle        = new pText(Name, titleSize, Vector2.Zero, Vector2.Zero, StartDepth + DEPTH_INCREASE_STEP, true, colourTextInactive, false);
                textTitle.Origin = Origins.CentreLeft;
                textTitle.Tag    = new Vector2(thumbPadding, yPadding - (GameBase.Tournament ? 0 : 16));
                blackSprites.Add(textTitle);
                SpriteCollection.Add(textTitle);

                textArtist        = new pText(Beatmap.ArtistAuto + @" // " + Beatmap.Creator, 12, Vector2.Zero, Vector2.Zero, StartDepth + DEPTH_INCREASE_STEP, true, colourTextInactive, false);
                textArtist.Origin = Origins.CentreLeft;
                textArtist.Tag    = new Vector2(thumbPadding + 1, yPadding - 4);
                blackSprites.Add(textArtist);
                if (!GameBase.TournamentDrawings)
                {
                    SpriteCollection.Add(textArtist);
                }


                if (thumb)
                {
                    bool highres = GameBase.WindowManager.Height >= 768;
                    thumbnail = new pSpriteDynamic(General.STATIC_WEB_ROOT_BEATMAP + @"/thumb/" + Beatmap.BeatmapSetId + (highres ? @"l" : @"") + @".jpg", Path.Combine(OsuMain.UserPath, @"Data", @"bt", Beatmap.BeatmapSetId + (highres ? @"l" : @"") + @".jpg"), 500, Vector2.Zero, StartDepth + DEPTH_INCREASE_STEP);
                    if (GameBase.TournamentDrawings)
                    {
                        thumbnail.Url        = string.Empty;
                        thumbnail.LocalCache = Path.Combine(Beatmap.ContainingFolderAbsolute, Beatmap.BackgroundImage);
                        thumbnail.State      = LoadState.Unloaded;
                        thumbnail.OnUnload  += delegate
                        {
                            if (thumbnail != null)
                            {
                                thumbnail.State = LoadState.Unloaded;
                            }
                        };
                    }

                    ((pSpriteDynamic)thumbnail).OnTextureLoaded += delegate
                    {
                        thumbnail.FadeInFromZero(400);
                        if (GameBase.TournamentDrawings)
                        {
                            thumbnail.VectorScale = Vector2.One;
                            thumbnail.Scale       = Math.Min(114f / thumbnail.Width, 85.5f / thumbnail.Height);
                        }
                    };

                    thumbnail.InitialColour = new Color(50, 50, 50, 255);
                    thumbnail.Additive      = true;
                    thumbnail.VectorScale   = new Vector2(1.425f, 1.425f) * (highres ? 0.5f : 1);
                    thumbnail.Origin        = Origins.CentreLeft;
                    thumbnail.Tag           = new Vector2(5.2f, 0.25f);
                    SpriteCollection.Add(thumbnail);
                }

                AlwaysVisibleSprites = SpriteCollection.Count;

                float starScale;
                if (OldLayout)
                {
                    starScale = 0.6f;
                }
                else
                {
                    starScale = 0.8f;
                }

                textDifficulty          = new pText(string.Empty, 12, Vector2.Zero, Vector2.Zero, StartDepth + DEPTH_INCREASE_STEP, true, colourTextInactive, false);
                textDifficulty.Origin   = Origins.CentreLeft;
                textDifficulty.TextBold = true;
                textDifficulty.Tag      = new Vector2(thumbPadding + 1, yPadding + 7);
                blackSprites.Add(textDifficulty);
                SpriteCollection.Add(textDifficulty);

                UpdateDifficultyText();

                if (mode.HasValue)
                {
                    hasMode = true;
                    pTexture modeTexture = null;
                    switch (mode)
                    {
                    case PlayModes.Osu:
                        modeTexture = TextureManager.Load(@"mode-osu-small", SkinSource.Osu);
                        break;

                    case PlayModes.Taiko:
                        modeTexture = TextureManager.Load(@"mode-taiko-small", SkinSource.Osu);
                        break;

                    case PlayModes.CatchTheBeat:
                        modeTexture = TextureManager.Load(@"mode-fruits-small", SkinSource.Osu);
                        break;

                    case PlayModes.OsuMania:
                        modeTexture = TextureManager.Load(@"mode-mania-small", SkinSource.Osu);
                        break;
                    }

                    modeSprite             = new pSprite(modeTexture, Fields.TopLeft, Origins.CentreLeft, Clocks.Game, Vector2.Zero, StartDepth + DEPTH_INCREASE_STEP, true, Color.White);
                    modeSprite.VectorScale = new Vector2(0.8f, 0.8f);
                    modeSprite.Tag         = new Vector2(xPadding + thumbPadding + 1, yPadding - 13);
                    blackSprites.Add(modeSprite);
                    SpriteCollection.Add(modeSprite);
                }

                rankSprite     = new pSprite(null, Origins.CentreLeft, Vector2.Zero, StartDepth + DEPTH_INCREASE_STEP, true, Color.White);
                rankSprite.Tag = new Vector2(xPadding + thumbPadding - 1, yPadding + (hasMode ? 14 : 0));
                SpriteCollection.Add(rankSprite);
                UpdateRank();
            }

            for (int i = 0; i < SpriteCollection.Count; i++)
            {
                SpriteCollection[i].Alpha = 0;
            }
        }