protected override void Validate(ValidationResult result, string startPath, List <string> ignorePaths)
        {
            var paths = EditorHelper.GetAssetsPathsByFilter(ValidationConfig.SO_FILTER_KEY,
                                                            startPath,
                                                            ignorePaths);
            var allSo = new List <ScriptableObject>();

            for (int i = 0; i < paths.Count; i++)
            {
                var asset = AssetDatabase.LoadAssetAtPath <ScriptableObject>(paths[i]);
                if (asset == null)
                {
                    result.Add(GetType(), $"Asset at path {paths[i]} is not a valid ScriptableObject");
                }
                else
                {
                    allSo.Add(asset);
                }
            }

            var fieldInstanceData = ValidationHelper.GetValidateableFields(allSo);

            try
            {
                foreach (var instanceData in fieldInstanceData)
                {
                    EditorUtility.DisplayProgressBar("Validate ScriptableObjects", instanceData.ToString(),
                                                     (float)fieldInstanceData.IndexOf(instanceData) / fieldInstanceData.Count);

                    if (EditorHelper.UnityObjectIsNull(instanceData.Instance))
                    {
                        var soName = instanceData?.Obj != null?instanceData.Obj.ToString() : "";

                        var soNameLog = string.IsNullOrEmpty(soName)
                            ? ""
                            : $"ScriptableObject name: {soName}\n";

                        var log =
                            $"Field is null.\n" +
                            soNameLog +
                            $"SO type: {instanceData.FieldInfo.DeclaringType}\n" +
                            $"Field type: {instanceData.FieldInfo.FieldType}\n" +
                            $"Field name: {instanceData.FieldInfo.Name}\n";

                        result.Add(GetType(), log, instanceData);
                    }
                }
            }
            catch (Exception e)
            {
                ValidationLogsHelper.AddValidationInternalErrorLog(typeof(ScriptableObjectsValidation), result, e);
            }

            EditorUtility.ClearProgressBar();
        }
        protected override void Validate(ValidationResult result, string startPath, List <string> ignorePaths)
        {
            var prefabPaths = EditorHelper.GetAssetsPathsByFilter(ValidationConfig.PREFABS_FILTER_KEY,
                                                                  startPath,
                                                                  ignorePaths);

            //todo: change 'Contains' to 'EndsWith'?
            var abstractPaths = prefabPaths.Where(x => x.Contains("Abstract")).ToList();

            foreach (var abstractPath in abstractPaths)
            {
                prefabPaths.Remove(abstractPath);
            }

            var prefabs = new List <GameObject>();

            for (int i = 0; i < prefabPaths.Count; i++)
            {
                EditorUtility.DisplayProgressBar("Validate Prefabs", $"Loading {prefabPaths[i]}",
                                                 (float)i / prefabPaths.Count);
                prefabs.Add(AssetDatabase.LoadAssetAtPath <GameObject>(prefabPaths[i]));
            }

            EditorUtility.DisplayProgressBar("Validate Prefabs", "Getting Prefabs fields", 0.99f);

            var fieldInstanceData = ValidationHelper.GetValidateableFields(prefabs.ToArray());

            try
            {
                foreach (var instanceData in fieldInstanceData)
                {
                    EditorUtility.DisplayProgressBar("Validate Prefabs", instanceData.Obj.ToString(),
                                                     (float)fieldInstanceData.IndexOf(instanceData) / fieldInstanceData.Count);
                    if (EditorHelper.UnityObjectIsNull(instanceData.Instance))
                    {
                        var log =
                            $"Field is null.\n" +
                            $"Source prefab name: {instanceData.Component.name}\n" +
                            $"Component name: {instanceData.Component.GetType()}\n" +
                            $"Field type: {instanceData.FieldInfo.FieldType}\n" +
                            $"Field name: {instanceData.FieldInfo.Name}\n" +
                            $"(Game)Object name: {(instanceData.Obj is GameObject go ? go.name : instanceData.Obj)}\n";

                        result.Add(GetType(), log, instanceData);
                    }
                }
            }
            catch (Exception e)
            {
                ValidationLogsHelper.AddValidationInternalErrorLog(typeof(PrefabsValidation), result, e);
            }

            EditorUtility.ClearProgressBar();
        }
        protected override void Validate(ValidationResult result, string startPath, List <string> ignorePaths)
        {
            if (IsAnyOpenSceneModified())
            {
                var popupAnswer = EditorUtility.DisplayDialogComplex("Scenes validation", "Do you want to save open scenes (not saved changes will be discarded)?", "Yes", "No", "Cancel");

                if (popupAnswer == 0) //clicked 'Yes'
                {
                    EditorSceneManager.SaveOpenScenes();
                }
                else if (popupAnswer == 1) //clicked 'No'
                {
                }
                else if (popupAnswer == 2) //clicked 'Cancel'
                {
                    return;
                }
            }

            var currentScenePath    = SceneManager.GetActiveScene().path;
            var allOpenedScenePaths = GetLoadedScenesPaths();

            var scenePaths = EditorHelper.GetAssetsPathsByFilter(ValidationConfig.SCENES_FILTER_KEY,
                                                                 startPath,
                                                                 ignorePaths);

            scenePaths = scenePaths.Where(x => !ValidationHelper.Config.OutOfValidationSceneNames.Any(y => x.Contains(y))).ToList();

            var uniqueInstanceData = new List <FieldInstanceData>();

            foreach (var scenePath in scenePaths)
            {
                EditorUtility.DisplayProgressBar("Validate scenes", scenePath,
                                                 (float)scenePaths.IndexOf(scenePath) / scenePaths.Count);
                var scene = EditorSceneManager.OpenScene(scenePath);
                if (!scene.IsValid())
                {
                    Debug.Log($"Invalid scene: {scene.path}");
                    continue;
                }

                var fieldInstanceData = ValidationHelper.GetValidateableFields(scene);

                //Scenes validation needs to check for repetitions in every scene, because we cannot pass all scenes to get fields from them at once.
                //They have to be passed one by one. Because of that, we cannot filter repetitive fields inside the logic
                //that gets them -> it doesn't have all of them.
                var scenesUniqueInstanceData = new List <FieldInstanceData>();
                foreach (var instanceData in fieldInstanceData)
                {
                    if (scenesUniqueInstanceData.Any(x => x.Instance == instanceData.Instance && x.FieldInfo == instanceData.FieldInfo && x.Obj == instanceData.Obj))
                    {
                        continue;
                    }

                    scenesUniqueInstanceData.Add(instanceData);
                }

                var withError = new List <FieldInstanceData>();

                try
                {
                    foreach (var instanceData in scenesUniqueInstanceData)
                    {
                        if (uniqueInstanceData.Any(x => x.Instance == instanceData.Instance && x.FieldInfo == instanceData.FieldInfo && x.Obj == instanceData.Obj))
                        {
                            continue;
                        }

                        uniqueInstanceData.Add(instanceData);

                        if (EditorHelper.UnityObjectIsNull(instanceData.Instance))
                        {
                            var log =
                                $"Field is null.\n" +
                                $"Scene name: {scene.name}\n" +
                                $"GameObject name: {instanceData.Component.gameObject.name}\n" +
                                $"Component name: {instanceData.Component.GetType()}\n" +
                                $"Field type: {instanceData.FieldInfo.FieldType}\n" +
                                $"Field name: {instanceData.FieldInfo.Name}\n";

                            result.Add(GetType(), log, instanceData);

                            withError.Add(instanceData);
                        }
                    }
                }
                catch (Exception e)
                {
                    ValidationLogsHelper.AddValidationInternalErrorLog(typeof(ScenesValidation), result, e);
                }
            }

            EditorUtility.ClearProgressBar();

            EditorSceneManager.OpenScene(currentScenePath, OpenSceneMode.Single);
            foreach (var path in allOpenedScenePaths)
            {
                if (EditorSceneManager.GetSceneByPath(path).isLoaded)
                {
                    continue;
                }
                EditorSceneManager.OpenScene(path, OpenSceneMode.Additive);
            }
        }