public static void UpdateSimAssetIds()
    {
        SimAssetBank bank = AssetDatabaseX.LoadOrCreateScriptableObjectAsset <SimAssetBank>(ASSET_PATH);

        bank.EditorSimAssets.Clear();

        AssetDatabaseX.LoadPrefabAssetsWithComponentOnRoot <SimAsset>(out List <KeyValuePair <string, GameObject> > loadResult);
        foreach (KeyValuePair <string, GameObject> item in loadResult)
        {
            var prefab = item.Value.GetComponent <SimAsset>();

            ValidateSimAssetIdForPrefab(prefab);

            bank.EditorSimAssets.Add(prefab);
        }

        DebugEditor.LogAssetIntegrity($"[{nameof(SimAssetBankUpdater)}] Updated {typeof(SimAssetBank)}");

        EditorUtility.SetDirty(bank);
        AssetDatabase.SaveAssets();
    }
    static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
    {
        if (AssetPostprocessorUtility.ExitImportLoop(importedAssets, ASSET_PATH, ref s_importLoopCounter))
        {
            return;
        }

        SimAssetBank bank      = null;
        bool         saveAsset = false;

        importedAssets.Where((assetPath) => assetPath.EndsWith(".prefab"))
        .Select((assetPath) => AssetDatabase.LoadAssetAtPath <GameObject>(assetPath))
        .Where((gameObject) => gameObject.GetComponent <SimAsset>() != null)
        .Select((gameObject) => gameObject.GetComponent <SimAsset>())
        .ToList()
        .ForEach((SimAsset prefab) =>
        {
            if (bank == null)
            {
                bank = AssetDatabaseX.LoadOrCreateScriptableObjectAsset <SimAssetBank>(ASSET_PATH);
            }

            saveAsset |= ValidateSimAssetIdForPrefab(prefab);

            if (!bank.EditorSimAssets.Contains(prefab))
            {
                saveAsset = true;
                bank.EditorSimAssets.Add(prefab);

                DebugEditor.LogAssetIntegrity($"Added {prefab.gameObject.name} to {nameof(SimAssetBank)}.");
            }
        });

        if (saveAsset)
        {
            EditorUtility.SetDirty(bank);
            AssetDatabase.SaveAssets();
        }
    }
    static void UpdateMetaData(LogMode logMode)
    {
        SceneMetaDataBank dataAsset = AssetDatabaseX.LoadOrCreateScriptableObjectAsset <SceneMetaDataBank>(ASSET_PATH);

        if (dataAsset == null)
        {
            Debug.LogWarning($"Could not update SceneMetaDataBank. None found at [{ASSET_PATH}]");
            return;
        }

        List <SceneMetaDataBank.SceneMetaData> oldData = dataAsset.SceneMetaDatasInternal;
        List <SceneMetaDataBank.SceneMetaData> newData = new List <SceneMetaDataBank.SceneMetaData>();

        int buildIndex = 0;

        foreach (EditorBuildSettingsScene scene in EditorBuildSettings.scenes)
        {
            SceneMetaDataBank.SceneMetaData metaData = new SceneMetaDataBank.SceneMetaData();

            metaData.AssetGuid  = scene.guid.ToString();
            metaData.Path       = scene.path;
            metaData.Name       = Path.GetFileNameWithoutExtension(scene.path);
            metaData.BuildIndex = buildIndex;

            newData.Add(metaData);
            buildIndex++;
        }

        dataAsset.SceneMetaDatasInternal = newData;

        // fbessette this diff algo could be optimized
        if (logMode == LogMode.Full || logMode == LogMode.ChangesOnly)
        {
            if (oldData != null)
            {
                for (int i = 0; i < oldData.Count; i++)
                {
                    if (newData.FindIndex((x) => x.AssetGuid == oldData[i].AssetGuid) == -1)
                    {
                        DebugEditor.LogAssetIntegrity($"<color=red>Removed scene meta-data:</color> {oldData[i].Name}");
                    }
                }
                for (int i = 0; i < newData.Count; i++)
                {
                    int oldDataIndex = oldData.FindIndex((x) => x.AssetGuid == newData[i].AssetGuid);
                    if (oldDataIndex == -1)
                    {
                        DebugEditor.LogAssetIntegrity($"<color=green>Added scene meta-data:</color> {newData[i].Name}");
                    }
                    else if (oldData[oldDataIndex].ContentEquals(newData[i]) == false)
                    {
                        DebugEditor.LogAssetIntegrity($"<color=green>Updated scene meta-data:</color> {newData[i].Name}");
                    }
                }
            }
            else
            {
                for (int i = 0; i < newData.Count; i++)
                {
                    DebugEditor.LogAssetIntegrity($"<color=green>Added scene meta-data:</color> {newData[i].Name}");
                }
            }
        }

        if (logMode == LogMode.Full)
        {
            DebugEditor.LogAssetIntegrity("Scene meta-data bank updated");
        }

        EditorUtility.SetDirty(dataAsset);
        AssetDatabase.SaveAssets();
    }