protected override void OnLayerSelectionChanged(LayerSelectionChangedEventArgs args)
        {
            base.OnLayerSelectionChanged(args);
            Tileset         tileset      = this.SelectedTileset.Res;
            VisualLayerNode selectedNode = args.SelectedNodeTag as VisualLayerNode;

            // Update global editor selection, so an Object Inspector can pick up the layer for editing
            if (selectedNode != null)
            {
                DualityEditorApp.Select(this, new ObjectSelection(new object[] { selectedNode.VisualLayer }));
            }
            else
            {
                DualityEditorApp.Deselect(this, obj => obj is TilesetRenderInput);
            }

            // Update the TilesetView to show the appropriate layer
            if (tileset != null)
            {
                int layerIndex = (selectedNode != null) ?
                                 tileset.RenderConfig.IndexOf(selectedNode.VisualLayer) :
                                 -1;

                if (layerIndex == -1)
                {
                    layerIndex = 0;
                }

                this.TilesetView.DisplayedConfigIndex = layerIndex;
            }
        }
        /// <inheritdoc />
        public override void AddLayer()
        {
            base.AddLayer();
            Tileset tileset = this.SelectedTileset.Res;

            if (tileset == null)
            {
                return;
            }

            // Determine which texture IDs are already present, so we can
            // derive which one we'll pick as a default for creating a new one.
            bool hasMainTex       = false;
            int  highestCustomTex = -1;

            for (int i = 0; i < tileset.RenderConfig.Count; i++)
            {
                if (tileset.RenderConfig[i].Id == TilesetRenderInput.MainTexId)
                {
                    hasMainTex = true;
                }
                else if (tileset.RenderConfig[i].Id.StartsWith(TilesetRenderInput.CustomTexId))
                {
                    string customTexIndexString = tileset.RenderConfig[i].Id.Substring(
                        TilesetRenderInput.CustomTexId.Length,
                        tileset.RenderConfig[i].Id.Length - TilesetRenderInput.CustomTexId.Length);

                    int customTexIndex;
                    if (!int.TryParse(customTexIndexString, out customTexIndex))
                    {
                        customTexIndex = 0;
                    }

                    highestCustomTex = Math.Max(highestCustomTex, customTexIndex);
                }
            }

            // Decide upon an id for our new layer
            string layerId;
            string layerName;

            if (!hasMainTex)
            {
                layerId   = TilesetRenderInput.MainTexId;
                layerName = TilesetRenderInput.MainTexName;
            }
            else
            {
                layerId   = TilesetRenderInput.CustomTexId + (highestCustomTex + 1).ToString();
                layerName = TilesetRenderInput.CustomTexName;
            }

            // Create a new layer using an UndoRedo action
            TilesetRenderInput newLayer = new TilesetRenderInput
            {
                Id   = layerId,
                Name = layerName
            };

            UndoRedoManager.Do(new AddTilesetConfigLayerAction <TilesetRenderInput>(
                                   tileset,
                                   TilemapsReflectionInfo.Property_Tileset_RenderConfig,
                                   newLayer));

            // Select the newly created visual layer
            VisualLayerNode modelNode = this.treeModel
                                        .Nodes
                                        .OfType <VisualLayerNode>()
                                        .FirstOrDefault(n => n.VisualLayer == newLayer);

            this.SelectLayer(modelNode);
        }