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 SaveFromAllOpenScenes()
        {
            if (!UnityHierarchyTools.IsHierarchyWindowOpen())
            {
                return;
            }

            for (int i = 0; i < SceneManager.sceneCount; i++)
            {
                StoreScenedData(SceneManager.GetSceneAt(i));
            }
        }
        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 RestoreFromAllOpenScenes()
        {
            EditorApplication.update -= RestoreFromAllOpenScenes;

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

            for (int i = 0; i < SceneManager.sceneCount; i++)
            {
                RestoreSceneData(SceneManager.GetSceneAt(i));
            }
        }
        private static void RestoreSceneData(Scene scene)
        {
            if (scene.buildIndex == -1)
            {
                return;
            }

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

            HashSet <string> alreadySelectedGameObjectPaths = new HashSet <string>();

            RestoreSelectionData(scene, ref alreadySelectedGameObjectPaths);
            RestoreHierarchyData(scene, ref alreadySelectedGameObjectPaths);
        }
        private static void StoreScenedData(Scene targetScene)
        {
            if (targetScene.buildIndex == -1)
            {
                return;
            }

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

            HashSet <GameObject> alreadySelectedGameObjects = new HashSet <GameObject>();

            StoreSelectionData(targetScene, ref alreadySelectedGameObjects);
            StoreHierarchyData(targetScene, ref alreadySelectedGameObjects);

            SaveData();
        }
        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);
            }
        }