public virtual void ValidateMembersRecursively(object value, IMemberSelector selector, UnityEngine.Object root, ref List <ValidationResult> results)
        {
            if (results == null)
            {
                results = new List <ValidationResult>();
            }

            if (object.ReferenceEquals(value, null))
            {
                return;
            }

            HashSet <object>     seenReferences = new HashSet <object>(ReferenceEqualityComparer <object> .Default);
            HashSet <MemberInfo> seenMembers    = new HashSet <MemberInfo>(FastMemberComparer.Instance);

            foreach (var member in selector.SelectMembers(value.GetType()))
            {
                var memberValue     = GetMemberValue(member, value, results);
                var memberValueType = memberValue == null?member.GetReturnType() : memberValue.GetType();

                ValidateMemberRecursive(value, member, memberValue, memberValueType, selector, root, new List <ValidationPathStep>()
                {
                    new ValidationPathStep()
                    {
                        Member     = member,
                        Value      = memberValue,
                        StepString = member.Name
                    }
                }, seenReferences, seenMembers, results, 0);
            }
        }
        public virtual void ValidateMembers(object value, IMemberSelector selector, UnityEngine.Object root, bool isCollectionElement, ref List <ValidationResult> results)
        {
            if (results == null)
            {
                results = new List <ValidationResult>();
            }

            if (object.ReferenceEquals(value, null))
            {
                return;
            }

            foreach (var member in selector.SelectMembers(value.GetType()))
            {
                var memberValue     = GetMemberValue(member, value, results);
                var memberValueType = memberValue == null?member.GetReturnType() : memberValue.GetType();

                ValidateMember(value, member, memberValue, memberValueType, root, isCollectionElement, ref results);
            }
        }
        protected virtual void ValidateMemberRecursive(object parentValue, MemberInfo member, object memberValue, Type memberValueType, IMemberSelector selector, UnityEngine.Object root, List <ValidationPathStep> pathSoFar, HashSet <object> seenReferences, HashSet <MemberInfo> seenMembers, List <ValidationResult> results, int scanDepth, bool isInCollection = false)
        {
            if (object.ReferenceEquals(parentValue, null))
            {
                return;
            }

            if (!isInCollection && member.IsStatic() && !seenMembers.Add(member))
            {
                return;
            }

            TempResults.Clear();
            {
                ValidateMember(parentValue, member, memberValue, memberValueType, root, isInCollection, ref TempResults);
                foreach (var result in TempResults)
                {
                    result.Path = pathSoFar.ToArray();
                }
                results.AddRange(TempResults);
            }
            TempResults.Clear();

            if (object.ReferenceEquals(memberValue, null))
            {
                return;
            }
            if (memberValue is UnityEngine.Object && !this.RecurseThroughUnityObjectReferences)
            {
                return;
            }

            if (!(memberValue is string) && !memberValue.GetType().IsPrimitive&& seenReferences.Contains(memberValue))
            {
                return;
            }

            if (scanDepth > this.MaxScanDepth)
            {
                if (this.WarnOnScanDepthReached)
                {
                    results.Add(new ValidationResult()
                    {
                        Message    = "Max scan depth reached",
                        ResultType = ValidationResultType.Warning,
                        Path       = pathSoFar.ToArray()
                    });
                }

                return;
            }

            seenReferences.Add(memberValue);
            scanDepth++;

            if (!TryValidateMemberRecursivelyAsCollection(memberValue, member, selector, root, pathSoFar, seenReferences, seenMembers, results, scanDepth))
            {
                foreach (var childMember in selector.SelectMembers(memberValue.GetType()))
                {
                    var path = pathSoFar.ToList();

                    var childMemberValue     = GetMemberValue(childMember, memberValue, results);
                    var childMemberValueType = childMemberValue == null?childMember.GetReturnType() : childMemberValue.GetType();

                    path.Add(new ValidationPathStep()
                    {
                        Member     = childMember,
                        Value      = childMemberValue,
                        StepString = childMember.Name
                    });

                    ValidateMemberRecursive(memberValue, childMember, childMemberValue, childMemberValueType, selector, root, path, seenReferences, seenMembers, results, scanDepth);
                }
            }
        }