/// <summary>
        /// Compares the properties of two objects of the same type and returns if all properties are equal.
        /// </summary>
        /// <param name="objectA">The first object to compare.</param>
        /// <param name="objectB">The second object to compre.</param>
        /// <param name="ignoreList">A Dictionary to ignore from the comparison where keys is type and vae is list of property names </param>
        /// <returns><c>true</c> if all property values are equal, otherwise <c>false</c>.</returns>
        public static bool AreObjectsEqual(object objectA, object objectB, IgnoreList ignoreList = null)
        {
            bool result;

            if (objectA != null && objectB != null)
            {
                Type objectType;

                objectType = objectA.GetType();

                result = true; // assume by default they are equal

                foreach (PropertyInfo propertyInfo in objectType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanRead && !IsPresentInIgnoreList(ignoreList, objectType, p)))
                {
                    object valueA;
                    object valueB;



                    ParameterInfo[] par = propertyInfo.GetIndexParameters();
                    if (par.Length > 0)
                    {
                        //we shouldn't compare indexed properties
                        continue;
                    }



                    valueA = propertyInfo.GetValue(objectA, null);
                    valueB = propertyInfo.GetValue(objectB, null);

                    // if it is a primative type, value type or implements IComparable, just directly try and compare the value
                    if (CanDirectlyCompare(propertyInfo.PropertyType))
                    {
                        if (!AreValuesEqual(valueA, valueB))
                        {
                            Console.WriteLine("Mismatch with property '{0}.{1}' found. Expected: {2}, was {3}", objectType.FullName, propertyInfo.Name, valueA, valueB);
                            result = false;
                        }
                    }
                    // if it implements IEnumerable, then scan any items
                    else if (typeof(IEnumerable).IsAssignableFrom(propertyInfo.PropertyType))
                    {
                        // null check
                        if (valueA == null && valueB != null || valueA != null && valueB == null)
                        {
                            Console.WriteLine("Mismatch with property '{0}.{1}' found. Expected: {2}, was {3}", objectType.FullName, propertyInfo.Name, valueA, valueB);
                            result = false;
                        }
                        else if (valueA != null && valueB != null)
                        {
                            var valueAcollection = ((IEnumerable)valueA).Cast <object>();
                            var valueBcollection = ((IEnumerable)valueB).Cast <object>();

                            // and if they do, compare each item... this assumes both collections have the same order
                            valueAcollection.ZipLongest(valueBcollection, (first, second) =>
                            {
                                var collectionItemType = first.GetType();

                                if (CanDirectlyCompare(collectionItemType))
                                {
                                    if (!AreValuesEqual(first, second))
                                    {
                                        Console.WriteLine("Item {0} in property collection '{1}.{2}' does not match.", 0, objectType.FullName, propertyInfo.Name);
                                        result = false;
                                    }
                                }
                                else if (!AreObjectsEqual(first, second, ignoreList))
                                {
                                    Console.WriteLine("Item {0} in property collection '{1}.{2}' does not match.", 0, objectType.FullName, propertyInfo.Name);
                                    result = false;
                                }
                                return(true);
                            });

                            //// check the counts to ensure they match
                            //if (collectionItemsCount1 != collectionItemsCount2)
                            //{
                            //    Console.WriteLine("Collection counts for property '{0}.{1}' do not match.", objectType.FullName, propertyInfo.Name);
                            //    result = false;
                            //}
                        }
                    }
                    else if (propertyInfo.PropertyType.IsClass)
                    {
                        if (!AreObjectsEqual(propertyInfo.GetValue(objectA, null), propertyInfo.GetValue(objectB, null), ignoreList))
                        {
                            Console.WriteLine("Mismatch with property '{0}.{1}' found. Expected: {2}, was {3}", objectType.FullName, propertyInfo.Name, valueA, valueB);
                            result = false;
                        }
                    }
                    else
                    {
                        Console.WriteLine("Cannot compare property '{0}.{1}'.", objectType.FullName, propertyInfo.Name);
                        result = false;
                    }
                }
            }
            else
            {
                result = object.Equals(objectA, objectB);
            }

            return(result);
        }