public override ISolution Apply(ISolution solution, Configuration configuration)
        {
            IOrientedTree tree     = (IOrientedTree)solution;
            TwoOperands   operands = (TwoOperands)configuration;

            List <bool> branching = tree.Branching;
            List <int>  order     = tree.Order;

            int start    = operands.First;
            int traverse = branching[start] == false ? 1 : -1;

            while (branching[start] == branching[start + traverse])
            {
                start += traverse;
            }

            int left = traverse > 0 ? start : start - 1;

            if (left != operands.Second)
            {
                branching = new List <bool>(tree.Branching);
                order     = new List <int>(tree.Order);

                int leafOrder = 0;
                for (int i = 0; i < left; i++)
                {
                    if (!branching[i])
                    {
                        leafOrder++;
                    }
                }

                branching.RemoveRange(left, 2);

                int newOrder = 0;
                for (int i = 0; i < operands.Second; i++)
                {
                    if (!branching[i])
                    {
                        newOrder++;
                    }
                }

                branching.Insert(operands.Second, true);
                branching.Insert(operands.Second, false);

                order.RemoveAt(leafOrder);
                order.Insert(newOrder, tree.Order[leafOrder]);
            }

            return(tree.FetchOrientedTree(order, branching, "full leaf"));
        }
        public override ISolution Apply(ISolution solution, Configuration configuration)
        {
            IOrientedTree tree     = (IOrientedTree)solution;
            TwoOperands   operands = (TwoOperands)configuration;

            List <bool> branching = new List <bool>(tree.Branching);
            List <int>  order     = new List <int>(tree.Order);

            int nodeOpenedAt = -1;
            int nodeClosedAt = -1;
            int opened       = 0;
            int closed       = 0;

            for (int i = 0; i < branching.Count; i++)
            {
                if (branching[i])
                {
                    closed++;
                }
                else
                {
                    opened++;
                }
                if (nodeOpenedAt < 0)
                {
                    if (opened == operands.First + 1)
                    {
                        nodeOpenedAt = i;
                        opened       = 1;
                        closed       = 0;
                    }
                }
                else if (nodeClosedAt < 0)
                {
                    if (opened == closed)
                    {
                        nodeClosedAt = i;
                        break;
                    }
                }
            }

            branching.RemoveAt(nodeClosedAt);
            branching.RemoveAt(nodeOpenedAt);

            int nodeOrder = 0;

            for (int i = 0; i < operands.Second; i++)
            {
                if (!branching[i])
                {
                    nodeOrder++;
                }
            }

            branching.Insert(operands.Second, true);
            branching.Insert(operands.Second, false);
            order.RemoveAt(operands.First);
            order.Insert(nodeOrder, tree.Order[operands.First]);
            return(tree.FetchOrientedTree(order, branching, "full node"));
        }