/// <inheritdoc/>
        protected internal override void PrepareTileData(IBrushContext context, TileData tile, int variationIndex)
        {
            // Find actual orientation of target tile.
            int actualOrientation = OrientationUtility.DetermineTileOrientation(context.TileSystem, context.Row, context.Column, context.Brush, tile.PaintedRotation);

            // Find nearest match, assume default scenario.
            tile.orientationMask = (byte)this.Tileset.FindClosestOrientation(actualOrientation);

            tile.Procedural   = true;
            tile.tileset      = this.Tileset;
            tile.tilesetIndex = this.Tileset.IndexFromOrientation(tile.orientationMask);

            // Is this an inner tile?
            if ((tile.orientationMask & 0x5A) == 0x5A)
            {
                tile.SolidFlag = this.InnerSolidFlag;
            }
        }
        /// <inheritdoc/>
        protected internal override void PrepareTileData(IBrushContext context, TileData tile, int variationIndex)
        {
            var tileSystem = context.TileSystem;

            // Find actual orientation of target tile.
            int actualOrientation = OrientationUtility.DetermineTileOrientation(tileSystem, context.Row, context.Column, context.Brush, tile.PaintedRotation);
            // Try to find nearest match, assume default scenario.
            int bestOrientation = this.FindClosestOrientationMask(actualOrientation);

            // Select tile for painting using tile brush.
            var orientation = this.FindOrientation(bestOrientation);

            if (orientation == null)
            {
                Debug.LogWarning(string.Format("Brush '{0}' orientation '{1}' not defined", this.name, OrientationUtility.NameFromMask(bestOrientation)));
                return;
            }

            int orientationVariationCount = orientation.VariationCount;

            // Randomize variation?
            if (variationIndex == RANDOM_VARIATION)
            {
                if (!tileSystem.BulkEditMode || tileSystem.IsEndingBulkEditMode)
                {
                    variationIndex = orientation.PickRandomVariationIndex();
                }
            }
            // Negative offset from variations of orientation.
            else if (variationIndex < 0)
            {
                variationIndex = Mathf.Max(0, orientationVariationCount + variationIndex);
            }

            // Ensure variation index is within bounds of orientation!
            int wrappedVariationIndex = variationIndex;

            if (wrappedVariationIndex >= orientationVariationCount)
            {
                wrappedVariationIndex = 0;
            }

            if (orientationVariationCount > 0)
            {
                //
                // Could re-insert following to 'fix' state of randomly selected tiles.
                // Note: Randomization is lost when erasing tiles from mass filled areas.
                //
                //// Persist wrapped variation when painting tile?
                //if (!system.BulkEditMode || system.IsEndingBulkEditMode) {
                //    variationIndex = wrappedVariationIndex;
                //}

                // Fetch nested brush reference (if there is one).
                var nestedBrush = orientation.GetVariation(wrappedVariationIndex) as Brush;
                if (nestedBrush != null)
                {
                    // Prepare tile data using nested brush.
                    nestedBrush.PrepareTileData(context, tile, wrappedVariationIndex);
                }
            }

            tile.orientationMask = (byte)bestOrientation;
            tile.variationIndex  = (byte)variationIndex;

            // Do not attempt automatic rotation where rotation has been manually specified.
            int rotation = tile.PaintedRotation + orientation.Rotation;

            if (rotation > 3)
            {
                rotation -= 4;
            }
            tile.Rotation = rotation;
        }