/// <summary>
        /// This Methods is used to Generate the complete tree
        /// </summary>
        /// <param name="root"></param>
        /// <returns></returns>
        public ObjectTreeItem CreateTree(ObjectTreeItem root = null)
        {
            //if (treeItem == null)
            //{
            //    return null;
            //}

            if (root == null)
            {
                root = this;
            }

            foreach (var child in CreateChildLayer())
            {
                if (child == null)
                {
                    throw new NullReferenceException();
                }

                Childs.Add(child);

                if (ReferenceEquals(child.Item, root.Item))
                {
                    root.RecursionObjectTreeItems.Add(child);
                }
                else
                {
                    child.CreateTree(root);
                }
            }

            return(root);
        }
        /// <summary>
        /// Replaces recursive references from any child object to <paramref name="rootObject"/> in the <paramref name="rootObject"/> object hierarchy with references
        /// to <paramref name="to"/>.
        /// </summary>
        /// <param name="to"></param>
        /// <param name="rootObject"></param>
        /// <returns>All ObjectTreeItems which have been redirected to <paramref name="to"/></returns>
        public static List <ObjectTreeItem> RedirectRecursions(object rootObject, object to)
        {
            var sourceTree = new ObjectTreeItem(rootObject);
            var resultList = new List <ObjectTreeItem>();

            sourceTree.CreateTree();
            foreach (var recursiveSourceTreeItem in sourceTree.RecursionObjectTreeItems)
            {
                if (!ReferenceEquals(recursiveSourceTreeItem.Item, rootObject))
                {
                    Trace.TraceInformation(sourceTree.ToFormattedString());
                    throw new Exception("<<<< BUG IN OBJECT TREE>>>>>\nExpected Item: \"" + rootObject + "\". Actual Item: \"" + recursiveSourceTreeItem.Parent.Item + "\".");
                }

                if (recursiveSourceTreeItem.MemberInfo.SetValue(recursiveSourceTreeItem.Parent.Item, to))
                {
                    resultList.Add(recursiveSourceTreeItem);
                }
            }
            return(resultList);
        }
        private IEnumerable <ObjectTreeItem> CreateChildLayer()
        {
            if (Item == null)
            {
                yield break;
            }
            else if (Item.GetType().IsPrimitive)
            {
                yield break;
            }
            else if (TypesNotToParse.Any(type => type == Item.GetType()))
            {
                yield break;
            }
            else if (TypesNotToParse.Any(type => type.IsInstanceOfType(Item)))
            {
                yield break;
            }
            else if (
                // handle all IEnumberable types from mscorlib as IEnumberables
                (Item is IEnumerable && Item.GetType().Assembly.GetName().Name == "mscorlib") ||
                // handle all generic types, which derive from special IEnumerables as IEnumberable
                (Item.GetType().IsGenericType&& SpecialIEnumberables.Any(type => type.IsAssignableFrom(Item.GetType().GetGenericTypeDefinition()))) ||
                // handle all self-defined-non-generic types, which derive from special IEnumerables as IEnumberable
                (SpecialIEnumberables.Any(type =>
            {
                var baseType = Item.GetType().FindGenericBaseClassWith(type);
                return(baseType != null && typeof(IEnumerable).IsAssignableFrom(baseType));
            }))
                )
            {
                foreach (var listEntry in (IEnumerable)Item)
                {
                    var childTreeItem = new ObjectTreeItem(listEntry);
                    childTreeItem.Parent = this;
                    //childTreeItem.MemberInfo = fieldInfo;
                    yield return(childTreeItem);
                }
                yield break;
            }

            // Parse fields
            foreach (var fieldInfo in Item.GetType().GetFields())
            {
                var childValue = fieldInfo.GetValue(Item);

                var childTreeItem = new ObjectTreeItem(childValue);
                childTreeItem.Parent     = this;
                childTreeItem.MemberInfo = fieldInfo;
                yield return(childTreeItem);
            }

            // parse Properties
            foreach (var propertyInfo in Item.GetType().GetProperties().Where(info => info.CanRead))
            {
                object childValue = null;
                try
                {
                    childValue = propertyInfo.GetValue(Item);
                }
                catch (TargetInvocationException e)
                {
                    Debug.WriteLine(e);
                }
                catch (TargetParameterCountException e)
                {
                    Debug.WriteLine(e);
                }
                catch (Exception exception)
                {
                    ObjectMergerLogger.GetInstance().Error(exception);
                }

                var childTreeItem = new ObjectTreeItem(childValue);
                childTreeItem.Parent     = this;
                childTreeItem.MemberInfo = propertyInfo;
                yield return(childTreeItem);
            }
        }