public bool CompareItem(object expected, object actual, PropertyPathItem propertyPath)
        {
            var valueComparison = new ValueComparison(propertyPath, expected, actual);
            valueComparison.AreSame = true;

            var previousComparison = this.comparisons.SingleOrDefault(x => x.Equals(valueComparison));
            if (previousComparison != null)
            {
                this.Log.Log(LogLevel.Info, valueComparison, "The comparison between these values has already been done, skipping the property.");
                return previousComparison.AreSame;
            }
            else
            {
                this.comparisons.Add(valueComparison);
            }

            var comparator = this.Rules.GetComparator(valueComparison);

            if (this.Rules.IsIgnored(valueComparison))
            {
                this.Log.Log(LogLevel.Info, valueComparison, "{0}: The property is ignored", valueComparison.PropertyPath);
            }
            else if (!this.IsNullComparisonMatch(expected, actual))
            {
                this.AddDifference(valueComparison);
                valueComparison.AreSame = false;
            }
            else if (ReferenceEquals(expected, null) && ReferenceEquals(actual, null))
            {
            }
            else if (ReferenceEquals(expected, actual))
            {
            }
            // ReSharper disable once PossibleNullReferenceException
            else if (expected.GetType() != actual.GetType())
            {
                valueComparison.Message = string.Format(
                    "The types do not match, the expected type is {0} but the actual one is {1}.",
                    expected.GetType(),
                    actual.GetType());

                this.AddDifference(valueComparison);
                valueComparison.AreSame = false;
            }
            else
            {
                valueComparison.AreSame = comparator.Compare(this, valueComparison);
            }

            return valueComparison.AreSame;
        }
 public PropertyPathItem(string itemDescription, PropertyPathItem parentPropertyPathItem, bool descriptionIsCollectionItem = true)
 {
     this.descriptionIsCollectionItem = descriptionIsCollectionItem;
     this.ParentProperty = parentPropertyPathItem;
     this.ItemDescription = itemDescription;
 }
 public ValueComparison(PropertyPathItem propertyPath, object expected, object actual)
 {
     this.PropertyPathItem = propertyPath;
     this.ExpectedValue = expected;
     this.ActualValue = actual;
 }
 public PropertyPathItem(PropertyInfo propertyInfo, PropertyPathItem parentPropertyPathItem)
 {
     this.ParentProperty = parentPropertyPathItem;
     this.ItemDescription = propertyInfo.Name;
     this.PropertyInfo = propertyInfo;
 }