// NEW
        public override void PerturbShape(TLayout layout, IList <TNode> chain, bool updateLayout)
        {
            var canBePerturbed = chain
                                 .Where(x => !LevelDescription.GetRoomDescription(x).IsCorridor) // TODO: handle better
                                 .Where(x => RoomShapesHandler.CanPerturbShapeDoNotUse(x))
                                 .ToList();

            if (canBePerturbed.Count == 0)
            {
                return;
            }

            PerturbShape(layout, canBePerturbed.GetRandom(Random), updateLayout);
        }
        /// <summary>
        /// Perturbs non corridor rooms until a valid layout is found.
        /// Then tries to use a greedy algorithm to lay out corridor rooms.
        /// </summary>
        /// <param name="layout"></param>
        /// <param name="chain"></param>
        /// <param name="updateLayout"></param>
        public override void PerturbLayout(TLayout layout, IList <TNode> chain, bool updateLayout)
        {
            // TODO: change
            var nonCorridors = chain.Where(x => !LevelDescription.GetRoomDescription(x).IsCorridor).ToList();

            if (Random.NextDouble() < 0.4f)
            {
                PerturbShape(layout, nonCorridors, updateLayout);
            }
            else
            {
                var random = nonCorridors.GetRandom(Random);
                PerturbPosition(layout, random, updateLayout);
            }
        }
        /// <summary>
        /// Greedily adds only non corridor nodes to the layout.
        /// </summary>
        /// <param name="layout"></param>
        /// <param name="chain"></param>
        /// <param name="updateLayout"></param>
        public override void AddChain(TLayout layout, IList <TNode> chain, bool updateLayout, out int iterationsCount)
        {
            iterationsCount = 0;
            var rooms = chain.Where(x => !LevelDescription.GetRoomDescription(x).IsCorridor);

            foreach (var room in rooms)
            {
                AddNodeGreedily(layout, room, out var addNodeIterations);
                iterationsCount += addNodeIterations;
            }

            if (updateLayout)
            {
                UpdateLayout(layout);
            }
        }
        /// <summary>
        /// Greedily adds corridors from a given chain to the layout.
        /// </summary>
        /// <param name="layout"></param>
        /// <param name="chain"></param>
        /// <returns></returns>
        private bool AddCorridors(TLayout layout, IEnumerable <TNode> chain)
        {
            var clone     = layout.SmartClone();
            var corridors = chain.Where(x => LevelDescription.GetRoomDescription(x).IsCorridor).ToList();

            foreach (var corridor in corridors)
            {
                if (!AddCorridorGreedily(clone, corridor))
                {
                    return(false);
                }
            }

            foreach (var corridor in corridors)
            {
                clone.GetConfiguration(corridor, out var configuration);
                layout.SetConfiguration(corridor, configuration);
            }

            return(true);
        }