public void CopyPropertiesPrimaryOnly()
        {
            var copyTest1 = new CopyTest();
            var copyTest2 = new CopyTest();

            copyTest1.InitSampleValues1();
            copyTest1.CopyProperties(copyTest2, true);

            int count      = 0;
            var type       = copyTest1.GetType();
            var properties = copyTest1.GetType().GetProperties();

            foreach (var property in properties)
            {
                if (Reflection.IsSimpleType(property.PropertyType) && property.Name != "IgnoreThis")
                {
                    count++;
                    Assert.Equal(property.GetValue(copyTest1), property.GetValue(copyTest2));
                }
            }

            // confirm the childarray was not copied
            Assert.Null(copyTest2.ChildArray);
            Assert.Null(copyTest2.ChildList);
            Assert.Null(copyTest2.EnumArray);

            // confirm all properties were tested
            Assert.Equal(count, 17);
        }
        public void CopyPropertiesArrayLists()
        {
            var copyTest1 = new CopyTest();
            var copyTest2 = new CopyTest();

            copyTest1.InitSampleValues1();
            copyTest1.CopyProperties(copyTest2, false);

            int count           = 0;
            int enumerableCount = 0;
            int childValueCount = 0;

            var type       = copyTest1.GetType();
            var properties = copyTest1.GetType().GetProperties();

            foreach (var property in properties)
            {
                if (Reflection.IsSimpleType(property.PropertyType) && property.Name != "IgnoreThis")
                {
                    count++;
                    Assert.Equal(property.GetValue(copyTest1), property.GetValue(copyTest2));
                }

                else if (Reflection.IsNonStringEnumerable(property))
                {
                    var elementType = property.PropertyType.GetElementType();
                    if (elementType == null)
                    {
                        elementType = property.PropertyType.GenericTypeArguments.Length > 0 ? property.PropertyType.GenericTypeArguments[0] : null;
                    }
                    if (elementType == typeof(int))
                    {
                        enumerableCount++;
                        var items1 = (IEnumerable)property.GetValue(copyTest1, null);
                        var items2 = (IEnumerable)property.GetValue(copyTest2, null);

                        var items1Array = items1.Cast <int>().ToArray();
                        var items2Array = items2.Cast <int>().ToArray();

                        for (var i = 0; i < items1Array.Count(); i++)
                        {
                            Assert.Equal(items1Array[i], items2Array[i]);
                        }
                    }
                    else if (elementType == typeof(ChildTest) || elementType == null || elementType == typeof(Object))
                    {
                        enumerableCount++;
                        var items1 = (IEnumerable)property.GetValue(copyTest1, null);
                        var items2 = (IEnumerable)property.GetValue(copyTest2, null);

                        var items1Array = items1.Cast <ChildTest>().ToArray();
                        var items2Array = items2.Cast <ChildTest>().ToArray();

                        Assert.Equal(items1Array.Length, items2Array.Length);

                        for (var i = 0; i < items1Array.Length; i++)
                        {
                            Assert.Equal(items1Array[i].Key, items2Array[i].Key);
                            Assert.Equal(items1Array[i].Name, items2Array[i].Name);
                            Assert.Equal(items1Array[i].Valid, items2Array[i].Valid);
                            Assert.NotEqual(items1Array[i].IgnoreThis, items2Array[i].IgnoreThis);
                        }
                    }
                    else
                    {
                        enumerableCount++;
                    }
                }

                else if (property.Name == "ChildValue")
                {
                    childValueCount++;

                    var item1 = (ChildTest)property.GetValue(copyTest1);
                    var item2 = (ChildTest)property.GetValue(copyTest2);

                    Assert.Equal(item1.Key, item2.Key);
                    Assert.Equal(item1.Name, item2.Name);
                    Assert.Equal(item1.Valid, item2.Valid);
                    Assert.NotEqual(item1.IgnoreThis, item2.IgnoreThis);

                    //the child value is a copy, so we should be able to change value in the source without impacting target
                    item1.Name = "changed name";
                    Assert.NotEqual(item1.Name, item2.Name);
                }

                else if (property.Name == "ChildCopyReference")
                {
                    childValueCount++;

                    var item1 = (ChildTest)property.GetValue(copyTest1);
                    var item2 = (ChildTest)property.GetValue(copyTest2);

                    Assert.Equal(item1.Key, item2.Key);
                    Assert.Equal(item1.Name, item2.Name);
                    Assert.Equal(item1.Valid, item2.Valid);
                    Assert.Equal(item1.IgnoreThis, item2.IgnoreThis); //equal the parent object reference was copied so subproperties will be ignored.

                    //the child value is a reference, so we should be able to change value in the source and this will change target.
                    item1.Name = "changed name";
                    Assert.Equal(item1.Name, item2.Name);
                }

                else if (property.Name == "ChildNullTarget")
                {
                    childValueCount++;

                    var item1 = (ChildTest)property.GetValue(copyTest1);
                    var item2 = (ChildTest)property.GetValue(copyTest2);

                    Assert.Null(item2);
                }

                else if (property.PropertyType == typeof(Object))
                {
                    Assert.Equal(property.GetValue(copyTest1), property.GetValue(copyTest2));
                }
            }

            // confirm all properties were tested
            Assert.Equal(count, 17);
            Assert.Equal(enumerableCount, 8);
            Assert.Equal(childValueCount, 3);

            Assert.Equal(3, copyTest2.EnumArray.Length);
            Assert.Equal(3, copyTest2.NumberArray.Length);
            Assert.Equal(3, copyTest2.NumberList.Count);

            Assert.True(copyTest1.EnumArray.SequenceEqual(copyTest2.EnumArray));
            Assert.True(copyTest1.NumberArray.SequenceEqual(copyTest2.NumberArray));
            Assert.True(copyTest1.NumberList.SequenceEqual(copyTest2.NumberList));
        }