/// <summary>
        /// Adds tree nodes as children for given parent, or, when possible, to a Tag of a parent to be shown in detailed view later.
        /// </summary>
        /// <param name="children">Children tree nodes to be sorted.</param>
        /// <param name="node">Parent node.</param>
        private static void SortOutChildren(IEnumerable <TreeNode> children, TreeNode node)
        {
            var treeNodes       = children as TreeNode[] ?? children.ToArray();
            var forDetailedInfo = treeNodes.Where(ResultsViewer.IsSuitableForDetailedInfo);

            node.Nodes.AddRange(treeNodes.Where(c => !ResultsViewer.IsSuitableForDetailedInfo(c)).ToArray());
            if (forDetailedInfo.Any())
            {
                node.Tag = forDetailedInfo;
            }
        }
        /// <summary>
        /// Returns a sequence of tree nodes that show contents of given object.
        /// </summary>
        /// <param name="nodeToDisplay">Object that needs to be displayed.</param>
        /// <returns>A sequence of tree nodes corresponding to an object.</returns>
        private IList <TreeNode> DisplayResultsRecursive(object nodeToDisplay)
        {
            if (nodeToDisplay == null)
            {
                return(new List <TreeNode>());
            }

            if (nodeToDisplay is string || nodeToDisplay is DateTime)
            {
                return(new List <TreeNode> {
                    new TreeNode(nodeToDisplay.ToString())
                });
            }

            var jObject = nodeToDisplay as JObject;

            if (jObject != null)
            {
                var result = new List <TreeNode>();
                foreach (var children in jObject.Properties().Select(this.DisplayResultsRecursive))
                {
                    result.AddRange(children);
                }

                return(result);
            }

            var jProperty = nodeToDisplay as JProperty;

            if (jProperty != null)
            {
                var node     = new TreeNode(jProperty.Name);
                var children = this.DisplayResultsRecursive(jProperty.Value);
                ResultsViewer.SortOutChildren(children, node);
                return(new List <TreeNode> {
                    node
                });
            }

            var jValue = nodeToDisplay as JValue;

            if (jValue != null)
            {
                return(jValue.Value != null ? new List <TreeNode> {
                    new TreeNode(jValue.Value.ToString())
                } : new List <TreeNode>());
            }

            var iDictionary = nodeToDisplay as IDictionary;

            if (iDictionary != null)
            {
                var result = new List <TreeNode>();
                foreach (var element in iDictionary.Keys)
                {
                    var children = this.DisplayResultsRecursive(iDictionary[element]);
                    var node     = new TreeNode(element.ToString());
                    ResultsViewer.SortOutChildren(children, node);
                    result.Add(node);
                }

                return(result);
            }

            var iEnumerable = nodeToDisplay as IEnumerable;

            if (iEnumerable != null)
            {
                var result = new List <TreeNode>();
                foreach (var element in iEnumerable)
                {
                    var children = this.DisplayResultsRecursive(element);
                    if (children.Count > 1)
                    {
                        var node = new TreeNode(ResultsViewer.GetDisplayedName(element));
                        ResultsViewer.SortOutChildren(children, node);
                        result.Add(node);
                    }
                    else if (children.Count == 1)
                    {
                        result.Add(children.First());
                    }
                }

                return(result);
            }

            if (nodeToDisplay.GetType().GetProperties().Any())
            {
                var result = new List <TreeNode>();

                foreach (var property in nodeToDisplay.GetType().GetProperties())
                {
                    var propertyValue = nodeToDisplay.GetType().GetProperty(property.Name).GetValue(nodeToDisplay, null);
                    var children      = this.DisplayResultsRecursive(propertyValue);
                    if (!children.Any())
                    {
                        // Property is not filled, just dropping it
                        continue;
                    }

                    var node = new TreeNode(property.Name);
                    if (propertyValue is IDictionary)
                    {
                        ResultsViewer.SortOutChildrenForDictionary(children, node);
                    }
                    else
                    {
                        ResultsViewer.SortOutChildren(children, node);
                    }

                    result.Add(node);
                }

                return(result);
            }

            return(new List <TreeNode> {
                new TreeNode(nodeToDisplay.ToString())
            });
        }