private static ObjectComparisonMismatch CompareNodes(GraphNode leftNode, GraphNode rightNode)
        {
            // check if one of the nodes is null while the other is not
            if ((leftNode.ObjectValue == null && rightNode.ObjectValue != null) ||
                (leftNode.ObjectValue != null && rightNode.ObjectValue == null))
            {
                var mismatch = new ObjectComparisonMismatch(
                    leftNode,
                    rightNode,
                    ObjectComparisonMismatchType.ObjectValuesDoNotMatch);
                return(mismatch);
            }

            if (leftNode.ObjectValue != null && rightNode.ObjectValue != null)
            {
                // compare types
                if (leftNode.ObjectType != rightNode.ObjectType)
                {
                    var mismatch = new ObjectComparisonMismatch(
                        leftNode,
                        rightNode,
                        ObjectComparisonMismatchType.ObjectTypesDoNotMatch);
                    return(mismatch);
                }

                // compare primitives, strings, datatimes, guids
                if (leftNode.ObjectType.IsPrimitive ||
                    leftNode.ObjectType == typeof(string) ||
                    leftNode.ObjectType == typeof(DateTime) ||
                    leftNode.ObjectType == typeof(Guid))
                {
                    if (!leftNode.ObjectValue.Equals(rightNode.ObjectValue))
                    {
                        var mismatch = new ObjectComparisonMismatch(
                            leftNode,
                            rightNode,
                            ObjectComparisonMismatchType.ObjectValuesDoNotMatch);
                        return(mismatch);
                    }

                    return(null);
                }
            }

            if (leftNode.ObjectValue != null && rightNode.ObjectValue != null)
            {
                TypeFilter f = (a, b) => true;

                var iComparable = leftNode.ObjectType.FindInterfaces(f, null)
                                  .FirstOrDefault(i => i.IsGenericType &&
                                                  i.GetGenericTypeDefinition() == typeof(IComparable <>) &&
                                                  i.GetGenericArguments()[0] == rightNode.ObjectType);

                if (iComparable != null)
                {
                    var result = (int)iComparable.GetMethods()[0].Invoke(leftNode.ObjectValue, new[] { rightNode.ObjectValue });

                    if (result != 0)
                    {
                        var mismatch = new ObjectComparisonMismatch(
                            leftNode,
                            rightNode,
                            ObjectComparisonMismatchType.ObjectValuesDoNotMatch);
                        return(mismatch);
                    }
                }
            }

            // compare the child count
            if (leftNode.Children.Count != rightNode.Children.Count)
            {
                var type = leftNode.Children.Count > rightNode.Children.Count
            ? ObjectComparisonMismatchType.RightNodeHasFewerChildren
            : ObjectComparisonMismatchType.LeftNodeHasFewerChildren;

                var mismatch = new ObjectComparisonMismatch(
                    leftNode,
                    rightNode,
                    type);
                return(mismatch);
            }

            // No mismatch //
            return(null);
        }