/// <summary>
        /// Checks if a default scene exists for this game package.
        /// </summary>
        /// <param name="log">The log to output the result of the validation.</param>
        public override void Run(ILogger log)
        {
            if (log == null)
            {
                throw new ArgumentNullException(nameof(log));
            }

            foreach (var package in Session.Packages)
            {
                // Make sure package has its assets loaded
                if (package.State < PackageState.AssetsReady)
                {
                    continue;
                }

                var hasGameExecutable = package.Profiles.SelectMany(profile => profile.ProjectReferences).Any(projectRef => projectRef.Type == ProjectType.Executable);
                if (!hasGameExecutable)
                {
                    continue;
                }

                // Find game settings
                var       gameSettingsAssetItem = package.Assets.Find(GameSettingsAsset.GameSettingsLocation);
                AssetItem defaultScene          = null;

                // If game settings is found, try to find default scene inside
                var defaultSceneRuntime   = ((GameSettingsAsset)gameSettingsAssetItem?.Asset)?.DefaultScene;
                var defaultSceneReference = AttachedReferenceManager.GetAttachedReference(defaultSceneRuntime);
                if (defaultSceneReference != null)
                {
                    // Find it either by Url or Id
                    defaultScene = package.Assets.Find(defaultSceneReference.Id) ?? package.Assets.Find(defaultSceneReference.Url);

                    // Check it is actually a scene asset
                    if (defaultScene != null && !(defaultScene.Asset is SceneAsset))
                    {
                        defaultScene = null;
                    }
                }

                // Find or create default scene
                if (defaultScene == null)
                {
                    defaultScene = package.Assets.Find(GameSettingsAsset.DefaultSceneLocation);
                    if (defaultScene != null && !(defaultScene.Asset is SceneAsset))
                    {
                        defaultScene = null;
                    }
                }

                // Otherwise, try to find any scene
                if (defaultScene == null)
                {
                    defaultScene = package.Assets.FirstOrDefault(x => x.Asset is SceneAsset);
                }

                // Nothing found, let's create an empty one
                if (defaultScene == null)
                {
                    log.Error(package, null, AssetMessageCode.DefaultSceneNotFound, null);

                    var defaultSceneName  = NamingHelper.ComputeNewName(GameSettingsAsset.DefaultSceneLocation, package.Assets, a => a.Location);
                    var defaultSceneAsset = DefaultAssetFactory <SceneAsset> .Create();

                    defaultScene = new AssetItem(defaultSceneName, defaultSceneAsset);
                    package.Assets.Add(defaultScene);
                    defaultScene.IsDirty = true;
                }

                // Create game settings if not done yet
                if (gameSettingsAssetItem == null)
                {
                    log.Error(package, null, AssetMessageCode.AssetForPackageNotFound, GameSettingsAsset.GameSettingsLocation, package.FullPath.GetFileName());

                    var gameSettingsAsset = GameSettingsFactory.Create();

                    gameSettingsAsset.DefaultScene = AttachedReferenceManager.CreateProxyObject <Scene>(defaultScene.Id, defaultScene.Location);

                    gameSettingsAssetItem = new AssetItem(GameSettingsAsset.GameSettingsLocation, gameSettingsAsset);
                    package.Assets.Add(gameSettingsAssetItem);

                    gameSettingsAssetItem.IsDirty = true;
                }
            }
        }
        static void ImportFile(string path, string relativePath, string output)
        {
            string[] arr  = relativePath.Split('.');
            string   name = Path.GetFileNameWithoutExtension(relativePath);

            switch (arr[arr.Length - 1])
            {
            case "jpg":
            case "jpeg":
            case "dds":
            case "tiff":
            case "tif":
            case "psd":
            case "tga":
            case "bmp":
            case "gif":
            case "png":
                break;
                if ((name.ToLower().EndsWith("bump") && !name.ToLower().StartsWith("bump")) || (name.ToLower().EndsWith("normal") && !name.ToLower().StartsWith("normal")))
                {
                    TextureAsset tex = NormalMapTextureFactory.Create();
                    tex.Source = new UFile(relativePath);
                    if (!overwrite && File.Exists($"{output}/{name}{TextureAsset.FileExtension}"))
                    {
                        Console.WriteLine($"{output}/{name}{TextureAsset.FileExtension} exists - not writing.");
                        break;
                    }
                    else
                    {
                        AssetFileSerializer.Save($"{output}/{name}{TextureAsset.FileExtension}", tex, null);
                    }
                }
                else
                {
                    TextureAsset tex = ColorTextureFactory.Create();
                    tex.Source = new UFile(relativePath);
                    if (!overwrite && File.Exists($"{output}/{name}{TextureAsset.FileExtension}"))
                    {
                        Console.WriteLine($"{output}/{name}{TextureAsset.FileExtension} exists - not writing.");
                        break;
                    }
                    AssetFileSerializer.Save($"{output}/{name}{TextureAsset.FileExtension}", tex, null);
                    MaterialAsset mat = DiffuseMaterialFactory.Create();
                    ((ComputeTextureColor)((MaterialDiffuseMapFeature)mat.Attributes.Diffuse).DiffuseMap).Texture = GetTexture(tex);
                    AssetFileSerializer.Save($"{output}/{name}{MaterialAsset.FileExtension}", mat, null);
                }
                break;

            case "dae":
            case "3ds":
            case "obj":
            case "blend":
            case "x":
            case "md2":
            case "md3":
            case "dxf":
            case "fbx":
                if (!overwrite && File.Exists($"{output}/{name}{ModelAsset.FileExtension.Split(';')[0]}"))
                {
                    Console.WriteLine($"{output}/{name}{ModelAsset.FileExtension.Split(';')[0]} exists - not writing.");
                    break;
                }
                ModelAsset model = DefaultAssetFactory <ModelAsset> .Create();

                model.Source = new UFile(relativePath);
                Scene scene = ctx.ImportFile(path, PostProcessSteps.None);
                Dictionary <string, Stride.Rendering.Material> materials = new Dictionary <string, Stride.Rendering.Material>();
                for (int i = 0; i < scene.MaterialCount; i++)
                {
                    if (materials.ContainsKey(scene.Materials[i].Name))
                    {
                        model.Materials.Add(new ModelMaterial()
                        {
                            Name             = scene.Materials[i].Name,
                            MaterialInstance = new MaterialInstance(materials[scene.Materials[i].Name])
                        });
                        continue;
                    }

                    if (!overwrite && File.Exists($"{output}/{scene.Materials[i].Name}{MaterialAsset.FileExtension}"))
                    {
                        Console.WriteLine($"{output}/{scene.Materials[i].Name}{MaterialAsset.FileExtension} exists - not writing parent mesh.");
                        break;
                    }
                    MaterialAsset materialAsset = DiffuseMaterialFactory.Create();

                    // set diffuse (if possible)
                    if (scene.Materials[i].HasTextureDiffuse)
                    {
                        string       diffPath = Path.GetRelativePath(output, Path.Combine(Path.GetDirectoryName(path), scene.Materials[i].TextureDiffuse.FilePath));
                        TextureAsset asset    = ImportTexture(diffPath, TextureType.Diffuse);
                        if (!overwrite && File.Exists($"{output}/{asset.Source.GetFileNameWithoutExtension()}{TextureAsset.FileExtension}"))
                        {
                            Console.WriteLine($"{output}/{asset.Source.GetFileNameWithoutExtension()}{TextureAsset.FileExtension} exists - not writing parent mesh.");
                            break;
                        }
                        AssetFileSerializer.Save($"{output}/{asset.Source.GetFileNameWithoutExtension()}{TextureAsset.FileExtension}", asset, null);
                        Texture tex = GetTexture(asset);
                        SetTexture(materialAsset, tex, TextureType.Diffuse);
                    }

                    // normals
                    if (scene.Materials[i].HasTextureNormal)
                    {
                        string       normPath = Path.GetRelativePath(output, Path.Combine(Path.GetDirectoryName(path), scene.Materials[i].TextureNormal.FilePath));
                        TextureAsset asset    = ImportTexture(normPath, TextureType.Normals);
                        if (!overwrite && File.Exists($"{output}/{asset.Source.GetFileNameWithoutExtension()}{TextureAsset.FileExtension}"))
                        {
                            Console.WriteLine($"{output}/{asset.Source.GetFileNameWithoutExtension()}{TextureAsset.FileExtension} exists - not writing parent mesh.");
                            break;
                        }
                        AssetFileSerializer.Save($"{output}/{asset.Source.GetFileNameWithoutExtension()}{TextureAsset.FileExtension}", asset, null);
                        Texture tex = GetTexture(asset);
                        SetTexture(materialAsset, tex, TextureType.Normals);
                    }


                    AssetFileSerializer.Save($"{output}/{scene.Materials[i].Name}{MaterialAsset.FileExtension}", materialAsset, null);
                    Stride.Rendering.Material material = GetMaterial(materialAsset, scene.Materials[i].Name);
                    model.Materials.Add(new ModelMaterial()
                    {
                        Name             = scene.Materials[i].Name,
                        MaterialInstance = new MaterialInstance(material)
                    });
                    materials.Add(scene.Materials[i].Name, material);
                }
                AssetFileSerializer.Save($"{output}/{name}{ModelAsset.FileExtension.Split(';')[0]}", model, null);
                break;

            default:
                Console.WriteLine($"The file extension \".{arr[arr.Length - 1]}\" is not supported. ({path})");
                break;
            }
        }