public void BasicReferenceTest()
        {
            var outer = new BasicReferenceTestOuter();
            var inner = new BasicReferenceTestInner();

            outer.Foo = outer.Bar = inner;

            var model = TypeModel.Create();

            model.Add(typeof(BasicReferenceTestOuter), true);
            model.Add(typeof(BasicReferenceTestInner), true);

            Assert.NotNull(outer.Foo);         //, "not null before");
            Assert.Same(outer.Foo, outer.Bar); //, "same before");

            var clone = (BasicReferenceTestOuter)model.DeepClone(outer);

            Assert.NotNull(clone);             //, "clone exists (runtime)");
            Assert.NotSame(outer, clone);      //, "clone is different (runtime)");
            Assert.NotNull(clone.Foo);         //, "not null after (runtime)");
            Assert.Same(clone.Foo, clone.Bar); //, "same after (runtime)");

            model.CompileInPlace();
            clone = (BasicReferenceTestOuter)model.DeepClone(outer);
            Assert.NotNull(clone);             //, "clone exists (compile in place)");
            Assert.NotSame(outer, clone);      //, "clone is different (compile in place)");
            Assert.NotNull(clone.Foo);         //, "not null after (compile in place)");
            Assert.Same(clone.Foo, clone.Bar); //, "same after (compile in place)");

            clone = (BasicReferenceTestOuter)model.Compile().DeepClone(outer);
            Assert.NotNull(clone);             //, "clone exists (full compile)");
            Assert.NotSame(outer, clone);      //, "clone is different (full compile)");
            Assert.NotNull(clone.Foo);         //, "not null after (full compile)");
            Assert.Same(clone.Foo, clone.Bar); //, "same after (full compile)");
        }
        public void RecursiveReferenceTest()
        {
            var outer = new BasicReferenceTestOuter();
            var inner = new BasicReferenceTestInner();
            inner.Self = inner;
            outer.Foo = inner;

            var model = TypeModel.Create();
            model.Add(typeof(BasicReferenceTestOuter), true);
            model.Add(typeof(BasicReferenceTestInner), true);

            Assert.IsNotNull(outer.Foo, "not null before");
            Assert.AreSame(outer.Foo, outer.Foo.Self, "same before");

            var clone = (BasicReferenceTestOuter)model.DeepClone(outer);
            Assert.IsNotNull(clone, "clone exists (runtime)");
            Assert.AreNotSame(outer, clone, "clone is different (runtime)");
            Assert.IsNotNull(clone.Foo, "not null after (runtime)");
            Assert.AreSame(clone.Foo, clone.Foo.Self, "same after (runtime)");

            model.CompileInPlace();
            clone = (BasicReferenceTestOuter)model.DeepClone(outer);
            Assert.IsNotNull(clone, "clone exists (compile in place)");
            Assert.AreNotSame(outer, clone, "clone is different (compile in place)");
            Assert.IsNotNull(clone.Foo, "not null after (compile in place)");
            Assert.AreSame(clone.Foo, clone.Foo.Self, "same after (compile in place)");

            clone = (BasicReferenceTestOuter)model.Compile().DeepClone(outer);
            Assert.IsNotNull(clone, "clone exists (full compile)");
            Assert.AreNotSame(outer, clone, "clone is different (full compile)");
            Assert.IsNotNull(clone.Foo, "not null after (full compile)");
            Assert.AreSame(clone.Foo, clone.Foo.Self, "same after (full compile)");
        }