internal bool Matches()
        {
            var match = this.compared.SingleOrDefault(x => x.HasCompared(this.Expected.Value, this.Actual.Value));

            if (match != null)
            {
                return(match.IsEqual);
            }

            var comparedPair = new ComparedPair(this.Expected.Value, this.Actual.Value);

            this.compared.Add(comparedPair);
            if (this.Expected.Value == null && this.Actual.Value == null)
            {
                comparedPair.IsEqual = true;
                return(true);
            }

            if (this.Expected.Value == null || this.Actual.Value == null)
            {
                comparedPair.IsEqual = false;
                return(false);
            }

            if (this.Expected is ComparedIEnumerable && this.Actual is ComparedIEnumerable)
            {
                comparedPair.IsEqual = false;
                return(false);
            }

            if (this.Type.IsEquatable())
            {
                comparedPair.IsEqual = object.Equals(this.Expected.Value, this.Actual.Value);
                return(comparedPair.IsEqual);
            }

            if (this.Children.Any(child => !child.Matches()))
            {
                comparedPair.IsEqual = false;
                return(false);
            }

            comparedPair.IsEqual = true;
            return(true);
        }
        internal bool Matches()
        {
            var match = this.compared.SingleOrDefault(x => x.HasCompared(this.Expected.Value, this.Actual.Value));
            if (match != null)
            {
                return match.IsEqual;
            }

            var comparedPair = new ComparedPair(this.Expected.Value, this.Actual.Value);
            this.compared.Add(comparedPair);
            if (this.Expected.Value == null && this.Actual.Value == null)
            {
                comparedPair.IsEqual = true;
                return true;
            }

            if (this.Expected.Value == null || this.Actual.Value == null)
            {
                comparedPair.IsEqual = false;
                return false;
            }

            if (this.Expected is ComparedIEnumerable && this.Actual is ComparedIEnumerable)
            {
                comparedPair.IsEqual = false;
                return false;
            }

            if (this.Type.IsEquatable())
            {
                comparedPair.IsEqual = object.Equals(this.Expected.Value, this.Actual.Value);
                return comparedPair.IsEqual;
            }

            if (this.Children.Any(child => !child.Matches()))
            {
                comparedPair.IsEqual = false;
                return false;
            }

            comparedPair.IsEqual = true;
            return true;
        }