public void InjectInto__Insert__FunctionNode_Into_RightFunctionNode()
        {
            // start:
            //      (c1)
            //     /    \
            //    (c2)  (f1)
            //   /    \
            //  (f2)  (f3)

            var c1 = new TestConnectiveNode("c1");
            var c2 = new TestConnectiveNode("c2");
            var f1 = new TestPredicateNode("f1");
            var f2 = new TestPredicateNode("f2");
            var f3 = new TestPredicateNode("f3");

            c1.InsertLeft(c2);
            c1.InsertRight(f1);

            c2.InsertLeft(f2);
            c2.InsertRight(f3);

            var tree = new TestExpressionTree();
            tree.ReplaceRootAndSubtree(c1);

            // insert new predicate into f3

            var f4 = new TestPredicateNode("f4");

            tree.InjectInto(f4, f3);

            // end:
            //      (c1)
            //     /    \
            //    (c2)  (f1)
            //   /    \
            //  (f2)  (c3)
            //        /   \
            //     (f3)   (f4)

            Assert.AreSame(tree.Root, c1);
            Assert.AreSame(c1.Left, c2);
            Assert.AreSame(c1.Right, f1);
            Assert.AreSame(c2.Left, f2);

            var c3 = c2.Right;

            Assert.IsNotNull(c3);
            Assert.AreSame(c3.Left, f3);
            Assert.AreSame(c3.Right, f4);

        }
        public void InjectInto__Move_ConnectiveNode_Into_ItsRightChild()
        {
            // start:
            //      (c1)
            //     /    \
            //   (p1)  (p2)

            var c1 = new TestConnectiveNode("c1");
            var p1 = new TestPredicateNode("p1");
            var p2 = new TestPredicateNode("p2");

            c1.InsertLeft(p1);
            c1.InsertRight(p2);

            var tree = new TestExpressionTree();
            tree.ReplaceRootAndSubtree(c1);

            // inject c1 into p2

            tree.InjectInto(c1, p1);

            // end: (no changes)
            //      (c1)
            //     /    \
            //   (p1)  (p2)

            Assert.AreSame(tree.Root, c1);
            Assert.AreSame(c1.Left, p1);
            Assert.AreSame(c1.Right, p2);
        }
        public void InjectInto__Move_ConnectiveNode_Into_FunctionNode_SourceIsRoot()
        {
            // start:
            //           (c1)
            //          /    \
            //        (c2)  (f1)
            //       /    \
            //     (f2)   (f3)

            var c1 = new TestConnectiveNode("c1");
            var c2 = new TestConnectiveNode("c2");
            var f1 = new TestPredicateNode("f1");
            var f2 = new TestPredicateNode("f2");
            var f3 = new TestPredicateNode("f3");

            c1.InsertLeft(c2);
            c1.InsertRight(f1);

            c2.InsertLeft(f2);
            c2.InsertRight(f3);

            var tree = new TestExpressionTree();
            tree.ReplaceRootAndSubtree(c1);

            // move c1 to f3

            tree.InjectInto(c1, f3);

            // end:
            //          (c2)
            //         /   \
            //       (c1)   (f2)
            //       /  \
            //     (f3) (f1)

            Assert.AreSame(tree.Root, c2);
            Assert.AreSame(c2.Left, f2);
            Assert.AreSame(c2.Right, c1);

            Assert.AreSame(c1.Left, f3);
            Assert.AreSame(c1.Right, f1);
        }
        public void InjectInto__FunctionNode_Move_SameParent__SwapsPlaces_RightLeft()
        {
            // start:
            //      (c1)
            //     /    \
            //   (p1)  (p2)

            var c1 = new TestConnectiveNode("c1");
            var p1 = new TestPredicateNode("p1");
            var p2 = new TestPredicateNode("p2");

            c1.InsertLeft(p1);
            c1.InsertRight(p2);

            var tree = new TestExpressionTree();
            tree.ReplaceRootAndSubtree(c1);

            // inject p2 into p1

            tree.InjectInto(p2, p2);

            // end:
            //      (c1)
            //     /    \
            //   (p2)  (p1)

            Assert.AreSame(tree.Root, c1);
            Assert.AreSame(c1.Left, p2);
            Assert.AreSame(c1.Right, p1);
        }
        public void InjectInto__Move_FunctionNode_Into_RightFunctionNode()
        {
            // start:
            //      (c1)
            //     /    \
            //    (c2)  (f1)
            //   /    \
            //  (f2)  (f3)

            var c1 = new TestConnectiveNode("c1");
            var c2 = new TestConnectiveNode("c2");
            var f1 = new TestPredicateNode("f1");
            var f2 = new TestPredicateNode("f2");
            var f3 = new TestPredicateNode("f3");

            c1.InsertLeft(c2);
            c1.InsertRight(f1);

            c2.InsertLeft(f2);
            c2.InsertRight(f3);

            var tree = new TestExpressionTree();
            tree.ReplaceRootAndSubtree(c1);

            // move f1 to f3

            tree.InjectInto(f1, f3);

            // end:
            //    (c2)
            //    /    \
            //  (f2)  (c3)
            //        /   \
            //      (f3) (f1)

            //! c1 is removed from the tree
            //! f1 takes a place of f3
            //! f3 is placed on the opposite side to f1

            Assert.AreSame(tree.Root, c2);
            Assert.AreSame(c2.Left, f2);

            var c3 = c2.Right;
            Assert.AreSame(c3.Parent, c2);


            Assert.AreSame(c3.Left, f3);
            Assert.AreSame(c3.Right, f1);
        }