private static void FindAllSchemas(object obj, HashSet <object> checkedObjects, Dictionary <string, JsonSchema4> schemas, ITypeResolver typeResolver, string typeNameHint)
        {
            if (obj == null || obj is string || checkedObjects.Contains(obj))
            {
                return;
            }

            var schema = obj as JsonSchema4;

            if (schema != null)
            {
                schema = schema.ActualSchema;

                if (schema.Type.HasFlag(JsonObjectType.Object) && schemas.Values.All(s => s != schema))
                {
                    var typeName = typeResolver.GetOrGenerateTypeName(schema, typeNameHint);
                    schemas.Add(typeName, schema);
                }
            }

            checkedObjects.Add(obj);

            if (obj is IDictionary)
            {
                foreach (var key in ((IDictionary)obj).Keys)
                {
                    FindAllSchemas(((IDictionary)obj)[key], checkedObjects, schemas, typeResolver, key as string);
                }
            }
            else if (obj is IEnumerable)
            {
                foreach (var item in (IEnumerable)obj)
                {
                    FindAllSchemas(item, checkedObjects, schemas, typeResolver, null);
                }
            }
            else
            {
                foreach (var property in ReflectionCache.GetProperties(obj.GetType()).Where(p => p.CustomAttributes.JsonIgnoreAttribute == null))
                {
                    var value = property.PropertyInfo.GetValue(obj);
                    if (value != null)
                    {
                        FindAllSchemas(value, checkedObjects, schemas, typeResolver, property.PropertyInfo.Name);
                    }
                }
            }
        }