From a215d009fed8bae6f3566e08f19f3de753c098e1 Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Fri, 26 Aug 2022 15:19:05 +0900
Subject: [PATCH 1/9] Update `Remove`/`RemoveRange`/`RemoveAll` calls in line
 with framework changes

---
 osu.Game.Rulesets.Catch/UI/Catcher.cs                       | 6 +++---
 osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs           | 6 +++---
 osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs      | 2 +-
 osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs  | 2 +-
 osu.Game.Rulesets.Osu.Tests/TestSceneFollowPoints.cs        | 4 ++--
 .../Objects/Drawables/DrawableOsuHitObject.cs               | 2 +-
 .../Objects/Drawables/DrawableTaikoHitObject.cs             | 6 +++---
 .../Visual/Background/TestSceneSeasonalBackgroundLoader.cs  | 2 +-
 .../Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs        | 2 +-
 osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorHost.cs    | 2 +-
 osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs       | 4 ++--
 osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs             | 4 ++--
 osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs   | 2 +-
 .../Visual/Online/TestSceneLeaderboardModSelector.cs        | 2 +-
 .../Visual/SongSelect/TestSceneBeatmapMetadataDisplay.cs    | 2 +-
 .../Visual/UserInterface/TestSceneLogoTrackingContainer.cs  | 2 +-
 .../Screens/TestSceneGameplayScreen.cs                      | 2 +-
 osu.Game.Tournament/Screens/Drawings/Components/Group.cs    | 2 +-
 .../Screens/Drawings/Components/ScrollingTeamContainer.cs   | 4 ++--
 .../Screens/Drawings/Components/VisualiserContainer.cs      | 2 +-
 .../Screens/Editors/TournamentEditorScreen.cs               | 2 +-
 osu.Game/Graphics/Containers/SectionsContainer.cs           | 2 +-
 .../Graphics/Containers/SelectionCycleFillFlowContainer.cs  | 2 +-
 osu.Game/Graphics/UserInterface/BarGraph.cs                 | 2 +-
 osu.Game/Graphics/UserInterface/TwoLayerButton.cs           | 4 ++--
 osu.Game/Overlays/Chat/ChannelList/ChannelList.cs           | 2 +-
 osu.Game/Overlays/Chat/DrawableChannel.cs                   | 2 +-
 osu.Game/Rulesets/UI/JudgementContainer.cs                  | 2 +-
 .../Screens/Edit/Compose/Components/BlueprintContainer.cs   | 2 +-
 .../Components/HitObjectOrderedSelectionContainer.cs        | 4 ++--
 .../Components/Timeline/TimelineBlueprintContainer.cs       | 2 +-
 osu.Game/Screens/Menu/IntroTriangles.cs                     | 3 +--
 .../Lounge/Components/DrawableRoomParticipantsList.cs       | 4 ++--
 .../Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs  | 2 +-
 osu.Game/Screens/Ranking/ResultsScreen.cs                   | 2 +-
 osu.Game/Skinning/SkinnableSound.cs                         | 2 +-
 osu.Game/Skinning/SkinnableTargetContainer.cs               | 2 +-
 osu.Game/Tests/Visual/OsuGameTestScene.cs                   | 5 +----
 osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs        | 2 +-
 39 files changed, 52 insertions(+), 56 deletions(-)

diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs
index efc841dfac..61fefcfd99 100644
--- a/osu.Game.Rulesets.Catch/UI/Catcher.cs
+++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs
@@ -271,8 +271,8 @@ namespace osu.Game.Rulesets.Catch.UI
                     SetHyperDashState();
             }
 
-            caughtObjectContainer.RemoveAll(d => d.HitObject == drawableObject.HitObject);
-            droppedObjectTarget.RemoveAll(d => d.HitObject == drawableObject.HitObject);
+            caughtObjectContainer.RemoveAll(d => d.HitObject == drawableObject.HitObject, false);
+            droppedObjectTarget.RemoveAll(d => d.HitObject == drawableObject.HitObject, false);
         }
 
         /// <summary>
@@ -430,7 +430,7 @@ namespace osu.Game.Rulesets.Catch.UI
         {
             var droppedObject = getDroppedObject(caughtObject);
 
-            caughtObjectContainer.Remove(caughtObject);
+            caughtObjectContainer.Remove(caughtObject, false);
 
             droppedObjectTarget.Add(droppedObject);
 
diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs
index 6ab6a59293..d255937fed 100644
--- a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs
+++ b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs
@@ -93,15 +93,15 @@ namespace osu.Game.Rulesets.Catch.UI
             switch (entry.Animation)
             {
                 case CatcherTrailAnimation.Dashing:
-                    dashTrails.Remove(drawable);
+                    dashTrails.Remove(drawable, false);
                     break;
 
                 case CatcherTrailAnimation.HyperDashing:
-                    hyperDashTrails.Remove(drawable);
+                    hyperDashTrails.Remove(drawable, false);
                     break;
 
                 case CatcherTrailAnimation.HyperDashAfterImage:
-                    hyperDashAfterImages.Remove(drawable);
+                    hyperDashAfterImages.Remove(drawable, false);
                     break;
             }
         }
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs
index 3c24e91d54..6a94e5d371 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs
@@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Mania.Mods
                 HitObjectContainer hoc = column.HitObjectArea.HitObjectContainer;
                 Container hocParent = (Container)hoc.Parent;
 
-                hocParent.Remove(hoc);
+                hocParent.Remove(hoc, false);
                 hocParent.Add(new PlayfieldCoveringWrapper(hoc).With(c =>
                 {
                     c.RelativeSizeAxes = Axes.Both;
diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs
index 4b6f364831..49ba503cb5 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs
@@ -155,7 +155,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
             else
             {
                 lightContainer.FadeOut(120)
-                              .OnComplete(d => Column.TopLevelContainer.Remove(d));
+                              .OnComplete(d => Column.TopLevelContainer.Remove(d, false));
             }
         }
 
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneFollowPoints.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneFollowPoints.cs
index 305678bb62..1e625cd4e6 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneFollowPoints.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneFollowPoints.cs
@@ -195,7 +195,7 @@ namespace osu.Game.Rulesets.Osu.Tests
             {
                 var drawableObject = getFunc.Invoke();
 
-                hitObjectContainer.Remove(drawableObject);
+                hitObjectContainer.Remove(drawableObject, false);
                 followPointRenderer.RemoveFollowPoints(drawableObject.HitObject);
             });
         }
@@ -212,7 +212,7 @@ namespace osu.Game.Rulesets.Osu.Tests
                 else
                     targetTime = getObject(hitObjectContainer.Count - 1).HitObject.StartTime + 1;
 
-                hitObjectContainer.Remove(toReorder);
+                hitObjectContainer.Remove(toReorder, false);
                 toReorder.HitObject.StartTime = targetTime;
                 hitObjectContainer.Add(toReorder);
             });
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
index 360b28f69f..aedb62dd24 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
@@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
         // This is a bit ugly but we don't have the concept of InternalContent so it'll have to do for now. (https://github.com/ppy/osu-framework/issues/1690)
         protected override void AddInternal(Drawable drawable) => shakeContainer.Add(drawable);
         protected override void ClearInternal(bool disposeChildren = true) => shakeContainer.Clear(disposeChildren);
-        protected override bool RemoveInternal(Drawable drawable) => shakeContainer.Remove(drawable);
+        protected override bool RemoveInternal(Drawable drawable) => shakeContainer.Remove(drawable, true);
 
         protected sealed override double InitialLifetimeOffset => HitObject.TimePreempt;
 
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
index 9bbd3670fa..c0c80eaa4a 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs
@@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
 
             isProxied = true;
 
-            nonProxiedContent.Remove(Content);
+            nonProxiedContent.Remove(Content, false);
             proxiedContent.Add(Content);
         }
 
@@ -70,7 +70,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
 
             isProxied = false;
 
-            proxiedContent.Remove(Content);
+            proxiedContent.Remove(Content, false);
             nonProxiedContent.Add(Content);
         }
 
@@ -141,7 +141,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
             Size = BaseSize = new Vector2(TaikoHitObject.DEFAULT_SIZE);
 
             if (MainPiece != null)
-                Content.Remove(MainPiece);
+                Content.Remove(MainPiece, true);
 
             Content.Add(MainPiece = CreateMainPiece());
         }
diff --git a/osu.Game.Tests/Visual/Background/TestSceneSeasonalBackgroundLoader.cs b/osu.Game.Tests/Visual/Background/TestSceneSeasonalBackgroundLoader.cs
index cce7ae1922..c9920cd01f 100644
--- a/osu.Game.Tests/Visual/Background/TestSceneSeasonalBackgroundLoader.cs
+++ b/osu.Game.Tests/Visual/Background/TestSceneSeasonalBackgroundLoader.cs
@@ -171,7 +171,7 @@ namespace osu.Game.Tests.Visual.Background
             => AddStep("create loader", () =>
             {
                 if (backgroundLoader != null)
-                    Remove(backgroundLoader);
+                    Remove(backgroundLoader, true);
 
                 Add(backgroundLoader = new SeasonalBackgroundLoader());
             });
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs
index d6c49b026e..5c7321fb24 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs
@@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual.Gameplay
             Add(expectedComponentsAdjustmentContainer);
             expectedComponentsAdjustmentContainer.UpdateSubTree();
             var expectedInfo = expectedComponentsContainer.CreateSkinnableInfo();
-            Remove(expectedComponentsAdjustmentContainer);
+            Remove(expectedComponentsAdjustmentContainer, true);
 
             return almostEqual(actualInfo, expectedInfo);
         }
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorHost.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorHost.cs
index 9ad8ac086c..083be3539d 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorHost.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSpectatorHost.cs
@@ -63,7 +63,7 @@ namespace osu.Game.Tests.Visual.Gameplay
         {
             base.TearDownSteps();
             AddStep("stop watching user", () => spectatorClient.StopWatchingUser(dummy_user_id));
-            AddStep("remove test spectator client", () => Remove(spectatorClient));
+            AddStep("remove test spectator client", () => Remove(spectatorClient, false));
         }
     }
 }
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs
index 30c2790fb4..2ec675874b 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs
@@ -91,7 +91,7 @@ namespace osu.Game.Tests.Visual.Gameplay
         private void loadStoryboard(IWorkingBeatmap working)
         {
             if (storyboard != null)
-                storyboardContainer.Remove(storyboard);
+                storyboardContainer.Remove(storyboard, true);
 
             var decoupledClock = new DecoupleableInterpolatingFramedClock { IsCoupled = true };
             storyboardContainer.Clock = decoupledClock;
@@ -106,7 +106,7 @@ namespace osu.Game.Tests.Visual.Gameplay
         private void loadStoryboardNoVideo()
         {
             if (storyboard != null)
-                storyboardContainer.Remove(storyboard);
+                storyboardContainer.Remove(storyboard, true);
 
             var decoupledClock = new DecoupleableInterpolatingFramedClock { IsCoupled = true };
             storyboardContainer.Clock = decoupledClock;
diff --git a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs
index 90e218675c..4473f315b9 100644
--- a/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs
+++ b/osu.Game.Tests/Visual/Menus/TestSceneToolbar.cs
@@ -62,8 +62,8 @@ namespace osu.Game.Tests.Visual.Menus
         [SetUp]
         public void SetUp() => Schedule(() =>
         {
-            Remove(nowPlayingOverlay);
-            Remove(volumeOverlay);
+            Remove(nowPlayingOverlay, false);
+            Remove(volumeOverlay, false);
 
             Children = new Drawable[]
             {
diff --git a/osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs b/osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs
index f5c7ee2f19..2879536034 100644
--- a/osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs
@@ -34,7 +34,7 @@ namespace osu.Game.Tests.Visual.Navigation
 
             AddStep("force save config", () => Game.LocalConfig.Save());
 
-            AddStep("remove game", () => Remove(Game));
+            AddStep("remove game", () => Remove(Game, true));
 
             AddStep("create game again", CreateGame);
 
diff --git a/osu.Game.Tests/Visual/Online/TestSceneLeaderboardModSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneLeaderboardModSelector.cs
index 10d9a5664e..5579ecedbd 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneLeaderboardModSelector.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneLeaderboardModSelector.cs
@@ -60,7 +60,7 @@ namespace osu.Game.Tests.Visual.Online
                             {
                                 if (selected.Text == mod.Acronym)
                                 {
-                                    selectedMods.Remove(selected);
+                                    selectedMods.Remove(selected, true);
                                     break;
                                 }
                             }
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapMetadataDisplay.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapMetadataDisplay.cs
index 27b485156c..c42b51c1a6 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapMetadataDisplay.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapMetadataDisplay.cs
@@ -98,7 +98,7 @@ namespace osu.Game.Tests.Visual.SongSelect
 
                 OsuLogo logo = new OsuLogo { Scale = new Vector2(0.15f) };
 
-                Remove(testDifficultyCache);
+                Remove(testDifficultyCache, false);
 
                 Children = new Drawable[]
                 {
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs
index 558ea01a49..d069e742dd 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs
@@ -259,7 +259,7 @@ namespace osu.Game.Tests.Visual.UserInterface
 
         private void removeFacade()
         {
-            trackingContainer.Remove(logoFacade);
+            trackingContainer.Remove(logoFacade, false);
             visualBox.Colour = Color4.White;
             moveLogoFacade();
         }
diff --git a/osu.Game.Tournament.Tests/Screens/TestSceneGameplayScreen.cs b/osu.Game.Tournament.Tests/Screens/TestSceneGameplayScreen.cs
index 842324d03d..4fc15c365f 100644
--- a/osu.Game.Tournament.Tests/Screens/TestSceneGameplayScreen.cs
+++ b/osu.Game.Tournament.Tests/Screens/TestSceneGameplayScreen.cs
@@ -53,7 +53,7 @@ namespace osu.Game.Tournament.Tests.Screens
         {
             AddStep("setup screen", () =>
             {
-                Remove(chat);
+                Remove(chat, false);
 
                 Children = new Drawable[]
                 {
diff --git a/osu.Game.Tournament/Screens/Drawings/Components/Group.cs b/osu.Game.Tournament/Screens/Drawings/Components/Group.cs
index f50abd6e58..0b1a5328ab 100644
--- a/osu.Game.Tournament/Screens/Drawings/Components/Group.cs
+++ b/osu.Game.Tournament/Screens/Drawings/Components/Group.cs
@@ -93,7 +93,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components
         {
             allTeams.RemoveAll(gt => gt.Team == team);
 
-            if (teams.RemoveAll(gt => gt.Team == team) > 0)
+            if (teams.RemoveAll(gt => gt.Team == team, true) > 0)
             {
                 TeamsCount--;
                 return true;
diff --git a/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs b/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs
index 52c611d323..55555adb80 100644
--- a/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs
+++ b/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs
@@ -170,7 +170,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components
 
             availableTeams.Add(team);
 
-            RemoveAll(c => c is ScrollingTeam);
+            RemoveAll(c => c is ScrollingTeam, false);
             setScrollState(ScrollState.Idle);
         }
 
@@ -186,7 +186,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components
         public void ClearTeams()
         {
             availableTeams.Clear();
-            RemoveAll(c => c is ScrollingTeam);
+            RemoveAll(c => c is ScrollingTeam, true);
             setScrollState(ScrollState.Idle);
         }
 
diff --git a/osu.Game.Tournament/Screens/Drawings/Components/VisualiserContainer.cs b/osu.Game.Tournament/Screens/Drawings/Components/VisualiserContainer.cs
index 15edbb76c1..663162d1ca 100644
--- a/osu.Game.Tournament/Screens/Drawings/Components/VisualiserContainer.cs
+++ b/osu.Game.Tournament/Screens/Drawings/Components/VisualiserContainer.cs
@@ -57,7 +57,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components
             if (allLines.Count == 0)
                 return;
 
-            Remove(allLines.First());
+            Remove(allLines.First(), true);
             allLines.Remove(allLines.First());
         }
 
diff --git a/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs
index 0fefe6f780..8c55026c67 100644
--- a/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs
+++ b/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs
@@ -106,7 +106,7 @@ namespace osu.Game.Tournament.Screens.Editors
                         break;
 
                     case NotifyCollectionChangedAction.Remove:
-                        args.OldItems.Cast<TModel>().ForEach(i => flow.RemoveAll(d => d.Model == i));
+                        args.OldItems.Cast<TModel>().ForEach(i => flow.RemoveAll(d => d.Model == i, true));
                         break;
                 }
             };
diff --git a/osu.Game/Graphics/Containers/SectionsContainer.cs b/osu.Game/Graphics/Containers/SectionsContainer.cs
index c04a5add89..448ecc6b3d 100644
--- a/osu.Game/Graphics/Containers/SectionsContainer.cs
+++ b/osu.Game/Graphics/Containers/SectionsContainer.cs
@@ -70,7 +70,7 @@ namespace osu.Game.Graphics.Containers
                 if (value == footer) return;
 
                 if (footer != null)
-                    scrollContainer.Remove(footer);
+                    scrollContainer.Remove(footer, true);
                 footer = value;
                 if (value == null) return;
 
diff --git a/osu.Game/Graphics/Containers/SelectionCycleFillFlowContainer.cs b/osu.Game/Graphics/Containers/SelectionCycleFillFlowContainer.cs
index 94505d2310..2667b8b8e0 100644
--- a/osu.Game/Graphics/Containers/SelectionCycleFillFlowContainer.cs
+++ b/osu.Game/Graphics/Containers/SelectionCycleFillFlowContainer.cs
@@ -59,7 +59,7 @@ namespace osu.Game.Graphics.Containers
             drawable.StateChanged += state => selectionChanged(drawable, state);
         }
 
-        public override bool Remove(T drawable)
+        public override bool Remove(T drawable, bool disposeImmediately)
             => throw new NotSupportedException($"Cannot remove drawables from {nameof(SelectionCycleFillFlowContainer<T>)}");
 
         private void setSelected(int? value)
diff --git a/osu.Game/Graphics/UserInterface/BarGraph.cs b/osu.Game/Graphics/UserInterface/BarGraph.cs
index f55875ac58..2e9fd6734f 100644
--- a/osu.Game/Graphics/UserInterface/BarGraph.cs
+++ b/osu.Game/Graphics/UserInterface/BarGraph.cs
@@ -74,7 +74,7 @@ namespace osu.Game.Graphics.UserInterface
                 }
 
                 //I'm using ToList() here because Where() returns an Enumerable which can change it's elements afterwards
-                RemoveRange(Children.Where((_, index) => index >= value.Count()).ToList());
+                RemoveRange(Children.Where((_, index) => index >= value.Count()).ToList(), true);
             }
         }
     }
diff --git a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs
index 144b51d3e8..1b8848f3d5 100644
--- a/osu.Game/Graphics/UserInterface/TwoLayerButton.cs
+++ b/osu.Game/Graphics/UserInterface/TwoLayerButton.cs
@@ -64,8 +64,8 @@ namespace osu.Game.Graphics.UserInterface
 
                 X = value.HasFlagFast(Anchor.x2) ? SIZE_RETRACTED.X * shear.X * 0.5f : 0;
 
-                Remove(c1);
-                Remove(c2);
+                Remove(c1, false);
+                Remove(c2, false);
                 c1.Depth = value.HasFlagFast(Anchor.x2) ? 0 : 1;
                 c2.Depth = value.HasFlagFast(Anchor.x2) ? 1 : 0;
                 Add(c1);
diff --git a/osu.Game/Overlays/Chat/ChannelList/ChannelList.cs b/osu.Game/Overlays/Chat/ChannelList/ChannelList.cs
index b3814ca90c..d9f962ca97 100644
--- a/osu.Game/Overlays/Chat/ChannelList/ChannelList.cs
+++ b/osu.Game/Overlays/Chat/ChannelList/ChannelList.cs
@@ -99,7 +99,7 @@ namespace osu.Game.Overlays.Chat.ChannelList
             FillFlowContainer<ChannelListItem> flow = getFlowForChannel(channel);
 
             channelMap.Remove(channel);
-            flow.Remove(item);
+            flow.Remove(item, true);
 
             updateVisibility();
         }
diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs
index c05f456a96..544daf7d2c 100644
--- a/osu.Game/Overlays/Chat/DrawableChannel.cs
+++ b/osu.Game/Overlays/Chat/DrawableChannel.cs
@@ -181,7 +181,7 @@ namespace osu.Game.Overlays.Chat
             {
                 Trace.Assert(updated.Id.HasValue, "An updated message was returned with no ID.");
 
-                ChatLineFlow.Remove(found);
+                ChatLineFlow.Remove(found, false);
                 found.Message = updated;
                 ChatLineFlow.Add(found);
             }
diff --git a/osu.Game/Rulesets/UI/JudgementContainer.cs b/osu.Game/Rulesets/UI/JudgementContainer.cs
index 4336977aa8..471a62cab3 100644
--- a/osu.Game/Rulesets/UI/JudgementContainer.cs
+++ b/osu.Game/Rulesets/UI/JudgementContainer.cs
@@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.UI
 
             // remove any existing judgements for the judged object.
             // this can be the case when rewinding.
-            RemoveAll(c => c.JudgedObject == judgement.JudgedObject);
+            RemoveAll(c => c.JudgedObject == judgement.JudgedObject, false);
 
             base.Add(judgement);
         }
diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
index 540fbf9a72..8b38d9c612 100644
--- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
@@ -292,7 +292,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
             blueprint.Selected -= OnBlueprintSelected;
             blueprint.Deselected -= OnBlueprintDeselected;
 
-            SelectionBlueprints.Remove(blueprint);
+            SelectionBlueprints.Remove(blueprint, true);
 
             if (movementBlueprints?.Contains(blueprint) == true)
                 finishSelectionMovement();
diff --git a/osu.Game/Screens/Edit/Compose/Components/HitObjectOrderedSelectionContainer.cs b/osu.Game/Screens/Edit/Compose/Components/HitObjectOrderedSelectionContainer.cs
index 06af232111..3be1c27129 100644
--- a/osu.Game/Screens/Edit/Compose/Components/HitObjectOrderedSelectionContainer.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/HitObjectOrderedSelectionContainer.cs
@@ -35,10 +35,10 @@ namespace osu.Game.Screens.Edit.Compose.Components
             base.Add(drawable);
         }
 
-        public override bool Remove(SelectionBlueprint<HitObject> drawable)
+        public override bool Remove(SelectionBlueprint<HitObject> drawable, bool disposeImmediately)
         {
             SortInternal();
-            return base.Remove(drawable);
+            return base.Remove(drawable, disposeImmediately);
         }
 
         protected override int Compare(Drawable x, Drawable y)
diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs
index 742e16d5a9..590f92d281 100644
--- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs
@@ -77,7 +77,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
             {
                 if (placementBlueprint != null)
                 {
-                    SelectionBlueprints.Remove(placementBlueprint);
+                    SelectionBlueprints.Remove(placementBlueprint, true);
                     placementBlueprint = null;
                 }
             }
diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs
index d777f78df2..05a6d25303 100644
--- a/osu.Game/Screens/Menu/IntroTriangles.cs
+++ b/osu.Game/Screens/Menu/IntroTriangles.cs
@@ -255,8 +255,7 @@ namespace osu.Game.Screens.Menu
                     {
                         lazerLogo.FadeOut().OnComplete(_ =>
                         {
-                            logoContainerSecondary.Remove(lazerLogo);
-                            lazerLogo.Dispose(); // explicit disposal as we are pushing a new screen and the expire may not get run.
+                            logoContainerSecondary.Remove(lazerLogo, true);
 
                             logo.FadeIn();
 
diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoomParticipantsList.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoomParticipantsList.cs
index 995a0d3397..9e2bd41fd0 100644
--- a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoomParticipantsList.cs
+++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoomParticipantsList.cs
@@ -232,7 +232,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
 
         private void removeUser(APIUser user)
         {
-            avatarFlow.RemoveAll(a => a.User == user);
+            avatarFlow.RemoveAll(a => a.User == user, true);
         }
 
         private void clearUsers()
@@ -250,7 +250,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
             hiddenUsers.Count = hiddenCount;
 
             if (displayedCircles > NumberOfCircles)
-                avatarFlow.Remove(avatarFlow.Last());
+                avatarFlow.Remove(avatarFlow.Last(), true);
             else if (displayedCircles < NumberOfCircles)
             {
                 var nextUser = RecentParticipants.FirstOrDefault(u => avatarFlow.All(a => a.User != u));
diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs
index 6142fc78a8..e6b1942506 100644
--- a/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs
+++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs
@@ -138,7 +138,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
         {
             foreach (var r in rooms)
             {
-                roomFlow.RemoveAll(d => d.Room == r);
+                roomFlow.RemoveAll(d => d.Room == r, true);
 
                 // selection may have a lease due to being in a sub screen.
                 if (!SelectedRoom.Disabled)
diff --git a/osu.Game/Screens/Ranking/ResultsScreen.cs b/osu.Game/Screens/Ranking/ResultsScreen.cs
index 226216b0f0..486df8653f 100644
--- a/osu.Game/Screens/Ranking/ResultsScreen.cs
+++ b/osu.Game/Screens/Ranking/ResultsScreen.cs
@@ -317,7 +317,7 @@ namespace osu.Game.Screens.Ranking
                 var screenSpacePos = detachedPanel.ScreenSpaceDrawQuad.TopLeft;
 
                 // Remove from the local container and re-attach.
-                detachedPanelContainer.Remove(detachedPanel);
+                detachedPanelContainer.Remove(detachedPanel, false);
                 ScorePanelList.Attach(detachedPanel);
 
                 // Move into its original location in the attached container first, then to the final location.
diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs
index c2696c56f3..8f71b40801 100644
--- a/osu.Game/Skinning/SkinnableSound.cs
+++ b/osu.Game/Skinning/SkinnableSound.cs
@@ -151,7 +151,7 @@ namespace osu.Game.Skinning
             bool wasPlaying = IsPlaying;
 
             // Remove all pooled samples (return them to the pool), and dispose the rest.
-            samplesContainer.RemoveAll(s => s.IsInPool);
+            samplesContainer.RemoveAll(s => s.IsInPool, false);
             samplesContainer.Clear();
 
             foreach (var s in samples)
diff --git a/osu.Game/Skinning/SkinnableTargetContainer.cs b/osu.Game/Skinning/SkinnableTargetContainer.cs
index 341a881789..2faaa9a905 100644
--- a/osu.Game/Skinning/SkinnableTargetContainer.cs
+++ b/osu.Game/Skinning/SkinnableTargetContainer.cs
@@ -85,7 +85,7 @@ namespace osu.Game.Skinning
             if (!(component is Drawable drawable))
                 throw new ArgumentException($"Provided argument must be of type {nameof(Drawable)}.", nameof(component));
 
-            content.Remove(drawable);
+            content.Remove(drawable, true);
             components.Remove(component);
         }
 
diff --git a/osu.Game/Tests/Visual/OsuGameTestScene.cs b/osu.Game/Tests/Visual/OsuGameTestScene.cs
index 69a945db34..e47d19fba6 100644
--- a/osu.Game/Tests/Visual/OsuGameTestScene.cs
+++ b/osu.Game/Tests/Visual/OsuGameTestScene.cs
@@ -58,10 +58,7 @@ namespace osu.Game.Tests.Visual
             AddStep("Create new game instance", () =>
             {
                 if (Game?.Parent != null)
-                {
-                    Remove(Game);
-                    Game.Dispose();
-                }
+                    Remove(Game, true);
 
                 RecycleLocalStorage(false);
 
diff --git a/osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs b/osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs
index 797e8363c3..a12459bc4e 100644
--- a/osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs
+++ b/osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs
@@ -67,7 +67,7 @@ namespace osu.Game.Tests.Visual
         protected void ResetPlacement()
         {
             if (CurrentBlueprint != null)
-                Remove(CurrentBlueprint);
+                Remove(CurrentBlueprint, true);
             Add(CurrentBlueprint = CreateBlueprint());
         }
 

From 105aa01e7d414d5e1837d00fd7eb4990895d98c6 Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Mon, 29 Aug 2022 15:49:28 +0900
Subject: [PATCH 2/9] Update usages of `RemoveInternal`

---
 .../Edit/Blueprints/Components/EditablePath.cs                 | 2 +-
 .../Edit/Blueprints/Components/NestedOutlineContainer.cs       | 2 +-
 .../Objects/Drawables/DrawableOsuHitObject.cs                  | 2 +-
 osu.Game/Graphics/Backgrounds/Background.cs                    | 2 +-
 osu.Game/Graphics/Containers/SectionsContainer.cs              | 2 +-
 osu.Game/Rulesets/Judgements/DrawableJudgement.cs              | 2 +-
 .../Objects/Pooling/PooledDrawableWithLifetimeContainer.cs     | 2 +-
 osu.Game/Rulesets/UI/HitObjectContainer.cs                     | 2 +-
 osu.Game/Screens/Play/FailAnimation.cs                         | 3 +--
 osu.Game/Screens/Ranking/ScorePanelTrackingContainer.cs        | 2 +-
 10 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs
index 44d14ec330..8473eda663 100644
--- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs
+++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs
@@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components
         public void UpdateFrom(ScrollingHitObjectContainer hitObjectContainer, JuiceStream hitObject)
         {
             while (path.Vertices.Count < InternalChildren.Count)
-                RemoveInternal(InternalChildren[^1]);
+                RemoveInternal(InternalChildren[^1], true);
 
             while (InternalChildren.Count < path.Vertices.Count)
                 AddInternal(new VertexPiece());
diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/NestedOutlineContainer.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/NestedOutlineContainer.cs
index 431ba331ac..a6f1732bc1 100644
--- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/NestedOutlineContainer.cs
+++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/NestedOutlineContainer.cs
@@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components
                                                      .Where(h => !(h is TinyDroplet)));
 
             while (nestedHitObjects.Count < InternalChildren.Count)
-                RemoveInternal(InternalChildren[^1]);
+                RemoveInternal(InternalChildren[^1], true);
 
             while (InternalChildren.Count < nestedHitObjects.Count)
                 AddInternal(new FruitOutline());
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
index aedb62dd24..6e525071ca 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs
@@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
         // This is a bit ugly but we don't have the concept of InternalContent so it'll have to do for now. (https://github.com/ppy/osu-framework/issues/1690)
         protected override void AddInternal(Drawable drawable) => shakeContainer.Add(drawable);
         protected override void ClearInternal(bool disposeChildren = true) => shakeContainer.Clear(disposeChildren);
-        protected override bool RemoveInternal(Drawable drawable) => shakeContainer.Remove(drawable, true);
+        protected override bool RemoveInternal(Drawable drawable, bool disposeImmediately) => shakeContainer.Remove(drawable, disposeImmediately);
 
         protected sealed override double InitialLifetimeOffset => HitObject.TimePreempt;
 
diff --git a/osu.Game/Graphics/Backgrounds/Background.cs b/osu.Game/Graphics/Backgrounds/Background.cs
index 2dd96bcb09..0899c0706d 100644
--- a/osu.Game/Graphics/Backgrounds/Background.cs
+++ b/osu.Game/Graphics/Backgrounds/Background.cs
@@ -57,7 +57,7 @@ namespace osu.Game.Graphics.Backgrounds
         {
             if (bufferedContainer == null && newBlurSigma != Vector2.Zero)
             {
-                RemoveInternal(Sprite);
+                RemoveInternal(Sprite, false);
 
                 AddInternal(bufferedContainer = new BufferedContainer(cachedFrameBuffer: true)
                 {
diff --git a/osu.Game/Graphics/Containers/SectionsContainer.cs b/osu.Game/Graphics/Containers/SectionsContainer.cs
index 448ecc6b3d..b8a8ea79cc 100644
--- a/osu.Game/Graphics/Containers/SectionsContainer.cs
+++ b/osu.Game/Graphics/Containers/SectionsContainer.cs
@@ -35,7 +35,7 @@ namespace osu.Game.Graphics.Containers
                 if (value == expandableHeader) return;
 
                 if (expandableHeader != null)
-                    RemoveInternal(expandableHeader);
+                    RemoveInternal(expandableHeader, false);
 
                 expandableHeader = value;
 
diff --git a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs
index 0d8b8429d8..7e1196d4ca 100644
--- a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs
+++ b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs
@@ -165,7 +165,7 @@ namespace osu.Game.Rulesets.Judgements
 
             // sub-classes might have added their own children that would be removed here if .InternalChild was used.
             if (JudgementBody != null)
-                RemoveInternal(JudgementBody);
+                RemoveInternal(JudgementBody, true);
 
             AddInternal(JudgementBody = new SkinnableDrawable(new GameplaySkinComponent<HitResult>(type), _ =>
                 CreateDefaultJudgement(type), confineMode: ConfineMode.NoScaling)
diff --git a/osu.Game/Rulesets/Objects/Pooling/PooledDrawableWithLifetimeContainer.cs b/osu.Game/Rulesets/Objects/Pooling/PooledDrawableWithLifetimeContainer.cs
index 07a80895e6..d5b4390ce8 100644
--- a/osu.Game/Rulesets/Objects/Pooling/PooledDrawableWithLifetimeContainer.cs
+++ b/osu.Game/Rulesets/Objects/Pooling/PooledDrawableWithLifetimeContainer.cs
@@ -132,7 +132,7 @@ namespace osu.Game.Rulesets.Objects.Pooling
         /// <remarks>
         /// Invoked when the entry became dead.
         /// </remarks>
-        protected virtual void RemoveDrawable(TEntry entry, TDrawable drawable) => RemoveInternal(drawable);
+        protected virtual void RemoveDrawable(TEntry entry, TDrawable drawable) => RemoveInternal(drawable, false);
 
         private void entryCrossedBoundary(LifetimeEntry lifetimeEntry, LifetimeBoundaryKind kind, LifetimeBoundaryCrossingDirection direction)
         {
diff --git a/osu.Game/Rulesets/UI/HitObjectContainer.cs b/osu.Game/Rulesets/UI/HitObjectContainer.cs
index 589b585643..bbced9e58c 100644
--- a/osu.Game/Rulesets/UI/HitObjectContainer.cs
+++ b/osu.Game/Rulesets/UI/HitObjectContainer.cs
@@ -124,7 +124,7 @@ namespace osu.Game.Rulesets.UI
 
             unbindStartTime(drawable);
 
-            RemoveInternal(drawable);
+            RemoveInternal(drawable, false);
         }
 
         #endregion
diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs
index 7275b369c3..a4b4bf4d2b 100644
--- a/osu.Game/Screens/Play/FailAnimation.cs
+++ b/osu.Game/Screens/Play/FailAnimation.cs
@@ -166,8 +166,7 @@ namespace osu.Game.Screens.Play
             if (filters.Parent == null)
                 return;
 
-            RemoveInternal(filters);
-            filters.Dispose();
+            RemoveInternal(filters, true);
         }
 
         protected override void Update()
diff --git a/osu.Game/Screens/Ranking/ScorePanelTrackingContainer.cs b/osu.Game/Screens/Ranking/ScorePanelTrackingContainer.cs
index e55c4530b4..b4d6d481ef 100644
--- a/osu.Game/Screens/Ranking/ScorePanelTrackingContainer.cs
+++ b/osu.Game/Screens/Ranking/ScorePanelTrackingContainer.cs
@@ -34,7 +34,7 @@ namespace osu.Game.Screens.Ranking
             if (InternalChildren.Count == 0)
                 throw new InvalidOperationException("Score panel container is not attached.");
 
-            RemoveInternal(Panel);
+            RemoveInternal(Panel, false);
         }
 
         /// <summary>

From 22c18d9a81cfdb1e777b09ff4bfb6fa42170be67 Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Thu, 1 Sep 2022 23:03:28 +0900
Subject: [PATCH 3/9] Update framework

---
 osu.Android.props        | 2 +-
 osu.Game/osu.Game.csproj | 2 +-
 osu.iOS.props            | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/osu.Android.props b/osu.Android.props
index 85857771a5..219912425f 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -52,7 +52,7 @@
   </ItemGroup>
   <ItemGroup>
     <PackageReference Include="ppy.osu.Game.Resources" Version="2022.831.0" />
-    <PackageReference Include="ppy.osu.Framework.Android" Version="2022.825.0" />
+    <PackageReference Include="ppy.osu.Framework.Android" Version="2022.901.0" />
   </ItemGroup>
   <ItemGroup Label="Transitive Dependencies">
     <!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index f757fd77b9..43e3076f5c 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -36,7 +36,7 @@
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
     </PackageReference>
     <PackageReference Include="Realm" Version="10.15.1" />
-    <PackageReference Include="ppy.osu.Framework" Version="2022.825.0" />
+    <PackageReference Include="ppy.osu.Framework" Version="2022.901.0" />
     <PackageReference Include="ppy.osu.Game.Resources" Version="2022.831.0" />
     <PackageReference Include="Sentry" Version="3.20.1" />
     <PackageReference Include="SharpCompress" Version="0.32.2" />
diff --git a/osu.iOS.props b/osu.iOS.props
index 9fcc3753eb..0f0bf2848c 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -61,7 +61,7 @@
     <Reference Include="System.Net.Http" />
   </ItemGroup>
   <ItemGroup Label="Package References">
-    <PackageReference Include="ppy.osu.Framework.iOS" Version="2022.825.0" />
+    <PackageReference Include="ppy.osu.Framework.iOS" Version="2022.901.0" />
     <PackageReference Include="ppy.osu.Game.Resources" Version="2022.831.0" />
   </ItemGroup>
   <!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net6.0) -->
@@ -84,7 +84,7 @@
     <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.14" />
     <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="5.0.14" />
     <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
-    <PackageReference Include="ppy.osu.Framework" Version="2022.825.0" />
+    <PackageReference Include="ppy.osu.Framework" Version="2022.901.0" />
     <PackageReference Include="SharpCompress" Version="0.32.1" />
     <PackageReference Include="NUnit" Version="3.13.3" />
     <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />

From c9dec473d3e4ef96d093da510b2b4f666512ed05 Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Thu, 1 Sep 2022 23:05:07 +0900
Subject: [PATCH 4/9] Update virtual track logic to match framework changes

---
 osu.Game/Tests/Visual/OsuTestScene.cs | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs
index 5a297fd109..5055153691 100644
--- a/osu.Game/Tests/Visual/OsuTestScene.cs
+++ b/osu.Game/Tests/Visual/OsuTestScene.cs
@@ -404,9 +404,9 @@ namespace osu.Game.Tests.Visual
 
                 public IEnumerable<string> GetAvailableResources() => throw new NotImplementedException();
 
-                public Track GetVirtual(double length = double.PositiveInfinity)
+                public Track GetVirtual(double length = double.PositiveInfinity, string name = "virtual")
                 {
-                    var track = new TrackVirtualManual(referenceClock) { Length = length };
+                    var track = new TrackVirtualManual(referenceClock, name) { Length = length };
                     AddItem(track);
                     return track;
                 }
@@ -421,7 +421,8 @@ namespace osu.Game.Tests.Visual
 
                 private bool running;
 
-                public TrackVirtualManual(IFrameBasedClock referenceClock)
+                public TrackVirtualManual(IFrameBasedClock referenceClock, string name = "virtual")
+                    : base(name)
                 {
                     this.referenceClock = referenceClock;
                     Length = double.PositiveInfinity;

From 7eaa4c5ccd89ff88c691f9bddf7cc30eea8a64f9 Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Thu, 1 Sep 2022 23:05:34 +0900
Subject: [PATCH 5/9] Update new usages of `Remove` / `RemoveInternal`

---
 osu.Game/Overlays/NotificationOverlayToastTray.cs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/osu.Game/Overlays/NotificationOverlayToastTray.cs b/osu.Game/Overlays/NotificationOverlayToastTray.cs
index 4417b5e0d0..c47a61eac1 100644
--- a/osu.Game/Overlays/NotificationOverlayToastTray.cs
+++ b/osu.Game/Overlays/NotificationOverlayToastTray.cs
@@ -126,13 +126,13 @@ namespace osu.Game.Overlays
             Debug.Assert(notification.Parent == toastFlow);
 
             // Temporarily remove from flow so we can animate the position off to the right.
-            toastFlow.Remove(notification);
+            toastFlow.Remove(notification, false);
             AddInternal(notification);
 
             notification.MoveToOffset(new Vector2(400, 0), NotificationOverlay.TRANSITION_LENGTH, Easing.OutQuint);
             notification.FadeOut(NotificationOverlay.TRANSITION_LENGTH, Easing.OutQuint).OnComplete(_ =>
             {
-                RemoveInternal(notification);
+                RemoveInternal(notification, false);
                 ForwardNotificationToPermanentStore?.Invoke(notification);
 
                 notification.FadeIn(300, Easing.OutQuint);

From a70fc10d06ffb1f03ee0aaf895a5eeb978da5333 Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Fri, 2 Sep 2022 16:30:04 +0900
Subject: [PATCH 6/9] Fix mock track construction failure

---
 osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs
index 9fdd49823e..50e6087526 100644
--- a/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs
+++ b/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs
@@ -7,10 +7,12 @@ using System.Linq;
 using Moq;
 using NUnit.Framework;
 using osu.Framework.Audio.Track;
+using osu.Framework.Timing;
 using osu.Game.Beatmaps;
 using osu.Game.Rulesets.Edit;
 using osu.Game.Rulesets.Edit.Checks;
 using osu.Game.Rulesets.Objects;
+using osu.Game.Tests.Visual;
 
 namespace osu.Game.Tests.Editing.Checks
 {
@@ -109,7 +111,7 @@ namespace osu.Game.Tests.Editing.Checks
         /// <param name="audioBitrate">The bitrate of the audio file the beatmap uses.</param>
         private Mock<IWorkingBeatmap> getMockWorkingBeatmap(int? audioBitrate)
         {
-            var mockTrack = new Mock<Track>();
+            var mockTrack = new Mock<OsuTestScene.ClockBackedTestWorkingBeatmap.TrackVirtualManual>(new FramedClock(), "virtual");
             mockTrack.SetupGet(t => t.Bitrate).Returns(audioBitrate);
 
             var mockWorkingBeatmap = new Mock<IWorkingBeatmap>();

From 8c50ccc48e973e86c2a3381d7fae69ae5e8c401a Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Fri, 2 Sep 2022 16:37:39 +0900
Subject: [PATCH 7/9] Fix incorrect specification in `SectionsContainer`

---
 osu.Game/Graphics/Containers/SectionsContainer.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/osu.Game/Graphics/Containers/SectionsContainer.cs b/osu.Game/Graphics/Containers/SectionsContainer.cs
index b8a8ea79cc..583f1385c1 100644
--- a/osu.Game/Graphics/Containers/SectionsContainer.cs
+++ b/osu.Game/Graphics/Containers/SectionsContainer.cs
@@ -35,7 +35,7 @@ namespace osu.Game.Graphics.Containers
                 if (value == expandableHeader) return;
 
                 if (expandableHeader != null)
-                    RemoveInternal(expandableHeader, false);
+                    RemoveInternal(expandableHeader, true);
 
                 expandableHeader = value;
 

From 778d767a1288fe8daaa1c814f9b42bad62283dae Mon Sep 17 00:00:00 2001
From: Salman Ahmed <frenzibyte@gmail.com>
Date: Sat, 3 Sep 2022 15:02:56 +0300
Subject: [PATCH 8/9] Revert disposal on `SectionsContainer` properties

---
 osu.Game/Graphics/Containers/SectionsContainer.cs | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/osu.Game/Graphics/Containers/SectionsContainer.cs b/osu.Game/Graphics/Containers/SectionsContainer.cs
index 583f1385c1..97e9ff88b5 100644
--- a/osu.Game/Graphics/Containers/SectionsContainer.cs
+++ b/osu.Game/Graphics/Containers/SectionsContainer.cs
@@ -35,7 +35,7 @@ namespace osu.Game.Graphics.Containers
                 if (value == expandableHeader) return;
 
                 if (expandableHeader != null)
-                    RemoveInternal(expandableHeader, true);
+                    RemoveInternal(expandableHeader, false);
 
                 expandableHeader = value;
 
@@ -55,6 +55,7 @@ namespace osu.Game.Graphics.Containers
 
                 fixedHeader?.Expire();
                 fixedHeader = value;
+
                 if (value == null) return;
 
                 AddInternal(fixedHeader);
@@ -70,8 +71,10 @@ namespace osu.Game.Graphics.Containers
                 if (value == footer) return;
 
                 if (footer != null)
-                    scrollContainer.Remove(footer, true);
+                    scrollContainer.Remove(footer, false);
+
                 footer = value;
+
                 if (value == null) return;
 
                 footer.Anchor |= Anchor.y2;

From b43995269ad724ecf2ee352bb147fa3b363872d8 Mon Sep 17 00:00:00 2001
From: Salman Ahmed <frenzibyte@gmail.com>
Date: Sat, 3 Sep 2022 15:17:46 +0300
Subject: [PATCH 9/9] Dispose `ScrollingTeam`s on removal

---
 .../Screens/Drawings/Components/ScrollingTeamContainer.cs       | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs b/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs
index 55555adb80..8092c24ccb 100644
--- a/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs
+++ b/osu.Game.Tournament/Screens/Drawings/Components/ScrollingTeamContainer.cs
@@ -170,7 +170,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components
 
             availableTeams.Add(team);
 
-            RemoveAll(c => c is ScrollingTeam, false);
+            RemoveAll(c => c is ScrollingTeam, true);
             setScrollState(ScrollState.Idle);
         }