internal void IterateMemberList(ReflectionWalkerCallback callback, Type targetType, object targetObject, object mirrorObject, string objectName, FieldInfoCollection memberInfoCollection)
        {
            foreach (MemberInfo memberInfo in memberInfoCollection)
            {
                if (IsExcludedPropertyName(Options, memberInfo.Name))
                {
                    continue;
                }

                if (IsExcludedType(Options, memberInfo))
                {
                    continue;
                }

                bool   targetPropertySwallowedException;
                object targetPropertyValue = InvokeMember(targetType, targetObject, memberInfo, Options.BindingFlags, true, out targetPropertySwallowedException);
                object mirrorPropertyValue = null;

                if (_mirrorInUse)
                {
                    bool mirrorPropertySwallowedExpection;
                    mirrorPropertyValue = InvokeMember(targetType, mirrorObject, memberInfo, Options.BindingFlags, true, out mirrorPropertySwallowedExpection);
                }

                if (targetPropertyValue != null && !IsSimpleType(targetPropertyValue.GetType()))
                {
                    InnerWalk(callback, targetPropertyValue, mirrorPropertyValue, objectName + "." + memberInfo.Name);
                }
                else
                {
                    callback(targetType, targetObject, mirrorObject, memberInfo, objectName);
                }
            }
        }
        private void InnerWalk(ReflectionWalkerCallback callback, object targetObject, object mirrorObject, string objectName)
        {
            _currentTraversalDepth++;

            if (targetObject != null && _currentTraversalDepth <= Options.MaximumTraversalDepth)
            {
                Type targetType = targetObject.GetType();

                IEnumerable targetAsEnumerable = targetObject as IEnumerable;
                bool        isEnumerable       = targetAsEnumerable != null;

                FieldInfoCollection memberInfoCollection = GetWalkablePropertiesAndFields(targetType);

                if (memberInfoCollection.Count == 0 && !isEnumerable)
                {
                    callback(targetType, targetObject, mirrorObject, null, objectName);
                }

                if (isEnumerable)
                {
                    WalkCollection(callback, targetType, targetObject, mirrorObject, objectName);

                    // Check to see whether we should continue in this method and enumerate all properties
                    if (!Options.EnumerateAllCollectionProperties)
                    {
                        return;
                    }
                }

                IterateMemberList(callback, targetType, targetObject, mirrorObject, objectName, memberInfoCollection);
            }

            _currentTraversalDepth--;
        }
        private void WalkCollection(
            ReflectionWalkerCallback callback
            , Type targetType
            , object targetObject
            , object mirrorObject
            , string objectName)
        {
            if (targetObject is string)
            {
                callback(targetType, targetObject, mirrorObject, null, objectName);
                return;
            }

            IEnumerable targetAsEnumerable = targetObject as IEnumerable;
            IList       targetAsList       = targetObject as IList;

            FieldInfoCollection fields = GetWalkablePropertiesAndFields(targetType);

            MemberInfo countField  = fields.Find(f => f.Name == "Count");
            MemberInfo lengthField = fields.Find(f => f.Name == "Length");

            if (countField != null)
            {
                callback(targetType, targetObject, mirrorObject, countField, objectName);
            }

            if (lengthField != null)
            {
                callback(targetType, targetObject, mirrorObject, lengthField, objectName);
            }

            if (targetAsList != null)
            {
                for (int i = 0; i < targetAsList.Count; i++)
                {
                    object innerTarget = targetAsList[i];

                    if (innerTarget == null)
                    {
                        Console.WriteLine("CodeGenWalker skipping list item {0} since the inner target is null", i);
                        continue;
                    }

                    bool   isSimpleType      = IsSimpleType(innerTarget.GetType());
                    object innerMirrorTarget = null;

                    if (mirrorObject != null)
                    {
                        innerMirrorTarget = ((IList)mirrorObject)[i];
                    }

                    string objectNameWithIndexer = string.Format("{0}[{1}]", objectName, i);

                    if (IsOfType(innerTarget, Options.UpcastTypes))
                    {
                        objectNameWithIndexer = GetUpCastTargetName(innerTarget, objectNameWithIndexer);
                    }

                    if (isSimpleType)
                    {
                        // THIS WILL ALWAYS BREAK MOFO
                        callback(targetType, innerTarget, innerMirrorTarget, null, objectNameWithIndexer);
                    }
                    else
                    {
                        InnerWalk(callback, innerTarget, innerMirrorTarget, objectNameWithIndexer);
                    }
                }
            }
            else if (targetAsEnumerable != null)
            {
                throw TestMonkeyException.Create("Object Inspector doesn't work with pure IEnumerables: " + objectName);
            }
        }
 internal void Walk(ReflectionWalkerCallback callback, object targetObject, object mirrorObject, string objectName)
 {
     _currentTraversalDepth = 0;
     _mirrorInUse           = mirrorObject != null;
     InnerWalk(callback, targetObject, mirrorObject, objectName);
 }