private static void StoreSelectionData(Scene targetScene, ref HashSet <GameObject> alreadySelectedGameObjects)
        {
            if (!SceneKeeperTools.IsSelectionKeeperActive())
            {
                return;
            }

            if (Application.isPlaying && SceneKeeperTools.IsIgnoringPlaytimeSelection())
            {
                return;
            }

            if (!TryGetLastValidSelectionForScene(targetScene, out List <GameObject> selectedGameObjects))
            {
                return;
            }

            SelectionData sceneSelectionData = SceneData.GetOrAddSceneSelectionData(targetScene.path);

            sceneSelectionData.itemPath.Clear();

            for (int i = 0; i < selectedGameObjects.Count; i++)
            {
                GameObject selectedGameObject = selectedGameObjects[i];
                if (selectedGameObject == null)
                {
                    continue;
                }

                sceneSelectionData.itemPath.Add(selectedGameObject.transform.GetPath());

                alreadySelectedGameObjects.Add(selectedGameObject);
            }
        }
        private static void RestoreSelectionData(Scene scene, ref HashSet <string> alreadySelectedGameObjectPaths)
        {
            if (!SceneKeeperTools.IsSelectionKeeperActive())
            {
                return;
            }

            if (!SceneData.TryGetSceneSelectionData(scene.path, out SelectionData resultSelectionData))
            {
                return;
            }

            List <Object> selectedObjects = new List <Object>();

            for (int i = 0; i < resultSelectionData.itemPath.Count; i++)
            {
                string targetItemPath = resultSelectionData.itemPath[i];
                if (TryToFindBySceneRootObjects(scene, targetItemPath, out GameObject targetGameObject))
                {
                    selectedObjects.Add(targetGameObject);
                    alreadySelectedGameObjectPaths.Add(targetItemPath);
                }
            }

            if (selectedObjects.Count > 0)
            {
                Selection.objects = selectedObjects.ToArray();
            }
        }
        private static void OnSelectionChanged()
        {
            if (!SceneKeeperTools.IsSelectionKeeperActive())
            {
                return;
            }

            if (!UnityHierarchyTools.IsHierarchyWindowOpen())
            {
                return;
            }

            if (Selection.objects.Length == 0)
            {
                if (EditorWindow.focusedWindow == UnityHierarchyTools.HierarchyWindow)
                {
                    for (int i = 0; i < SceneManager.sceneCount; i++)
                    {
                        Scene scene = SceneManager.GetSceneAt(i);
                        if (!SelectionHistory.ContainsKey(scene))
                        {
                            continue;
                        }

                        SelectionHistory[scene].Clear();
                    }
                }
                return;
            }

            ClearedSceneChangeLists.Clear();
            for (int i = 0; i < Selection.objects.Length; i++)
            {
                Object selectedObject = Selection.objects[i];
                if (selectedObject is GameObject selectedGameObject)
                {
                    Scene selectedGameObjectScene = selectedGameObject.scene;

                    if (!SelectionHistory.ContainsKey(selectedGameObjectScene))
                    {
                        SelectionHistory.Add(selectedGameObjectScene, new List <GameObject>());
                    }
                    else
                    {
                        if (!ClearedSceneChangeLists.Contains(selectedGameObjectScene))
                        {
                            SelectionHistory[selectedGameObjectScene].Clear();
                            ClearedSceneChangeLists.Add(selectedGameObjectScene);
                        }
                    }

                    SelectionHistory[selectedGameObjectScene].Add(selectedGameObject);
                }
            }
        }
        private static void StoreHierarchyData(Scene targetScene, ref HashSet <GameObject> alreadySelectedGameObjects)
        {
            if (EditorApplication.isPlayingOrWillChangePlaymode)
            {
                return;
            }

            if (!SceneKeeperTools.IsHierarchyKeeperActive())
            {
                return;
            }

            int[] expandedItemIDs = UnityHierarchyTools.GetExpandedItems();

            HierarchyData data = SceneData.GetOrAddSceneData(targetScene.path);

            data.itemsPath.Clear();

            for (int i = 0; i < expandedItemIDs.Length; i++)
            {
                int    instanceID = expandedItemIDs[i];
                Object targetObj  = EditorUtility.InstanceIDToObject(instanceID);

                if (targetObj == null)
                {
                    continue;
                }

                if (targetObj.hideFlags.HasFlag(HideFlags.HideInHierarchy) ||
                    targetObj.hideFlags.HasFlag(HideFlags.NotEditable) ||
                    targetObj.hideFlags.HasFlag(HideFlags.HideAndDontSave))
                {
                    continue;
                }

                if (targetObj is GameObject gameObject)
                {
                    if (alreadySelectedGameObjects.Contains(gameObject))
                    {
                        continue;
                    }

                    string scenePath = gameObject.scene.path;

                    if (!string.Equals(targetScene.path, scenePath, StringComparison.OrdinalIgnoreCase))
                    {
                        continue;
                    }

                    data.itemsPath.Add(gameObject.transform.GetPath());
                }
            }
        }
        private static void RestoreHierarchyData(Scene scene, ref HashSet <string> alreadySelectedGameObjectPaths)
        {
            if (!SceneKeeperTools.IsHierarchyKeeperActive())
            {
                return;
            }

            for (int i = 0; i < SceneData.alwaysExpanded.Count; i++)
            {
                string alwaysExpandedItemPath = SceneData.alwaysExpanded[i];
                if (TryToFindInAllOpenScenes(alwaysExpandedItemPath, out GameObject targetGameObject))
                {
                    alreadySelectedGameObjectPaths.Add(alwaysExpandedItemPath);
                    UnityHierarchyTools.SetExpanded(targetGameObject.GetInstanceID(), true);
                }
            }

            if (!SceneData.TryGetSceneData(scene.path, out HierarchyData sceneHierarchyData))
            {
                return;
            }

            UnityHierarchyTools.SetExpanded(scene.handle, true);

            for (int i = 0; i < sceneHierarchyData.itemsPath.Count; i++)
            {
                string expandedItemPath = sceneHierarchyData.itemsPath[i];

                if (alreadySelectedGameObjectPaths.Contains(expandedItemPath))
                {
                    continue;
                }

                if (!TryToFindBySceneRootObjects(scene, expandedItemPath, out GameObject gameObjectAtPath))
                {
                    continue;
                }

                UnityHierarchyTools.SetExpanded(gameObjectAtPath.GetInstanceID(), true);
            }
        }