private JsonSchema GenerateInternal(Type type, Required valueRequired, bool required)
        {
            ValidationUtils.ArgumentNotNull(type, "type");
            string typeId  = this.GetTypeId(type, false);
            string typeId2 = this.GetTypeId(type, true);

            if (!string.IsNullOrEmpty(typeId))
            {
                JsonSchema schema = this._resolver.GetSchema(typeId);
                if (schema != null)
                {
                    if (valueRequired != Required.Always && !JsonSchemaGenerator.HasFlag(schema.Type, JsonSchemaType.Null))
                    {
                        JsonSchema     expr_76 = schema;
                        JsonSchemaType?type2   = expr_76.Type;
                        expr_76.Type = ((!type2.get_HasValue()) ? default(JsonSchemaType?) : new JsonSchemaType?(type2.GetValueOrDefault() | JsonSchemaType.Null));
                    }
                    if (required)
                    {
                        bool?required2 = schema.Required;
                        if (!required2.GetValueOrDefault() || !required2.get_HasValue())
                        {
                            schema.Required = new bool?(true);
                        }
                    }
                    return(schema);
                }
            }
            if (Enumerable.Any <JsonSchemaGenerator.TypeSchema>(this._stack, (JsonSchemaGenerator.TypeSchema tc) => tc.Type == type))
            {
                throw new Exception("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.get_InvariantCulture(), new object[]
                {
                    type
                }));
            }
            JsonContract  jsonContract = this.ContractResolver.ResolveContract(type);
            JsonConverter jsonConverter;

            if ((jsonConverter = jsonContract.Converter) != null || (jsonConverter = jsonContract.InternalConverter) != null)
            {
                JsonSchema schema2 = jsonConverter.GetSchema();
                if (schema2 != null)
                {
                    return(schema2);
                }
            }
            this.Push(new JsonSchemaGenerator.TypeSchema(type, new JsonSchema()));
            if (typeId2 != null)
            {
                this.CurrentSchema.Id = typeId2;
            }
            if (required)
            {
                this.CurrentSchema.Required = new bool?(true);
            }
            this.CurrentSchema.Title       = this.GetTitle(type);
            this.CurrentSchema.Description = this.GetDescription(type);
            if (jsonConverter != null)
            {
                this.CurrentSchema.Type = new JsonSchemaType?(JsonSchemaType.Any);
            }
            else if (jsonContract is JsonDictionaryContract)
            {
                this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Object, valueRequired));
                Type type3;
                Type type4;
                ReflectionUtils.GetDictionaryKeyValueTypes(type, out type3, out type4);
                if (type3 != null && typeof(IConvertible).IsAssignableFrom(type3))
                {
                    this.CurrentSchema.AdditionalProperties = this.GenerateInternal(type4, Required.Default, false);
                }
            }
            else if (jsonContract is JsonArrayContract)
            {
                this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Array, valueRequired));
                this.CurrentSchema.Id   = this.GetTypeId(type, false);
                JsonArrayAttribute jsonArrayAttribute = JsonTypeReflector.GetJsonContainerAttribute(type) as JsonArrayAttribute;
                bool flag = jsonArrayAttribute == null || jsonArrayAttribute.AllowNullItems;
                Type collectionItemType = ReflectionUtils.GetCollectionItemType(type);
                if (collectionItemType != null)
                {
                    this.CurrentSchema.Items = new List <JsonSchema>();
                    this.CurrentSchema.Items.Add(this.GenerateInternal(collectionItemType, flag ? Required.Default : Required.Always, false));
                }
            }
            else if (jsonContract is JsonPrimitiveContract)
            {
                this.CurrentSchema.Type = new JsonSchemaType?(this.GetJsonSchemaType(type, valueRequired));
                JsonSchemaType?type5 = this.CurrentSchema.Type;
                if (type5.GetValueOrDefault() == JsonSchemaType.Integer && type5.get_HasValue() && type.get_IsEnum() && !type.IsDefined(typeof(FlagsAttribute), true))
                {
                    this.CurrentSchema.Enum    = new List <JToken>();
                    this.CurrentSchema.Options = new Dictionary <JToken, string>();
                    EnumValues <long> namesAndValues = EnumUtils.GetNamesAndValues <long>(type);
                    using (IEnumerator <EnumValue <long> > enumerator = namesAndValues.GetEnumerator())
                    {
                        while (enumerator.MoveNext())
                        {
                            EnumValue <long> current = enumerator.get_Current();
                            JToken           jToken  = JToken.FromObject(current.Value);
                            this.CurrentSchema.Enum.Add(jToken);
                            this.CurrentSchema.Options.Add(jToken, current.Name);
                        }
                    }
                }
            }
            else if (jsonContract is JsonObjectContract)
            {
                this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Object, valueRequired));
                this.CurrentSchema.Id   = this.GetTypeId(type, false);
                this.GenerateObjectSchema(type, (JsonObjectContract)jsonContract);
            }
            else if (jsonContract is JsonISerializableContract)
            {
                this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Object, valueRequired));
                this.CurrentSchema.Id   = this.GetTypeId(type, false);
                this.GenerateISerializableContract(type, (JsonISerializableContract)jsonContract);
            }
            else if (jsonContract is JsonStringContract)
            {
                JsonSchemaType jsonSchemaType = ReflectionUtils.IsNullable(jsonContract.UnderlyingType) ? this.AddNullType(JsonSchemaType.String, valueRequired) : JsonSchemaType.String;
                this.CurrentSchema.Type = new JsonSchemaType?(jsonSchemaType);
            }
            else
            {
                if (!(jsonContract is JsonLinqContract))
                {
                    throw new Exception("Unexpected contract type: {0}".FormatWith(CultureInfo.get_InvariantCulture(), new object[]
                    {
                        jsonContract
                    }));
                }
                this.CurrentSchema.Type = new JsonSchemaType?(JsonSchemaType.Any);
            }
            return(this.Pop().Schema);
        }
        private JsonSchema GenerateInternal(Type type, Required valueRequired, bool required)
        {
            ValidationUtils.ArgumentNotNull(type, "type");
            string typeId  = this.GetTypeId(type, false);
            string typeId2 = this.GetTypeId(type, true);

            if (!string.IsNullOrEmpty(typeId))
            {
                JsonSchema schema = this._resolver.GetSchema(typeId);
                if (schema != null)
                {
                    if (valueRequired != Required.Always && !JsonSchemaGenerator.HasFlag(schema.Type, JsonSchemaType.Null))
                    {
                        schema.Type |= JsonSchemaType.Null;
                    }
                    if (required && schema.Required != true)
                    {
                        schema.Required = new bool?(true);
                    }
                    return(schema);
                }
            }
            if (this._stack.Any((JsonSchemaGenerator.TypeSchema tc) => tc.Type == type))
            {
                throw new JsonException("Unresolved circular reference for type '{0}'. Explicitly define an Id for the type using a JsonObject/JsonArray attribute or automatically generate a type Id using the UndefinedSchemaIdHandling property.".FormatWith(CultureInfo.InvariantCulture, type));
            }
            JsonContract  jsonContract = this.ContractResolver.ResolveContract(type);
            JsonConverter jsonConverter;

            if ((jsonConverter = jsonContract.Converter) != null || (jsonConverter = jsonContract.InternalConverter) != null)
            {
                JsonSchema schema2 = jsonConverter.GetSchema();
                if (schema2 != null)
                {
                    return(schema2);
                }
            }
            this.Push(new JsonSchemaGenerator.TypeSchema(type, new JsonSchema()));
            if (typeId2 != null)
            {
                this.CurrentSchema.Id = typeId2;
            }
            if (required)
            {
                this.CurrentSchema.Required = new bool?(true);
            }
            this.CurrentSchema.Title       = this.GetTitle(type);
            this.CurrentSchema.Description = this.GetDescription(type);
            if (jsonConverter != null)
            {
                this.CurrentSchema.Type = new JsonSchemaType?(JsonSchemaType.Any);
            }
            else
            {
                switch (jsonContract.ContractType)
                {
                case JsonContractType.Object:
                    this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Object, valueRequired));
                    this.CurrentSchema.Id   = this.GetTypeId(type, false);
                    this.GenerateObjectSchema(type, (JsonObjectContract)jsonContract);
                    goto IL_51E;

                case JsonContractType.Array:
                    {
                        this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Array, valueRequired));
                        this.CurrentSchema.Id   = this.GetTypeId(type, false);
                        JsonArrayAttribute jsonArrayAttribute = JsonTypeReflector.GetJsonContainerAttribute(type) as JsonArrayAttribute;
                        bool flag = jsonArrayAttribute == null || jsonArrayAttribute.AllowNullItems;
                        Type collectionItemType = ReflectionUtils.GetCollectionItemType(type);
                        if (collectionItemType != null)
                        {
                            this.CurrentSchema.Items = new List <JsonSchema>();
                            this.CurrentSchema.Items.Add(this.GenerateInternal(collectionItemType, (!flag) ? Required.Always : Required.Default, false));
                            goto IL_51E;
                        }
                        goto IL_51E;
                    }

                case JsonContractType.Primitive:
                {
                    this.CurrentSchema.Type = new JsonSchemaType?(this.GetJsonSchemaType(type, valueRequired));
                    if (!(this.CurrentSchema.Type == JsonSchemaType.Integer) || !type.IsEnum() || type.IsDefined(typeof(FlagsAttribute), true))
                    {
                        goto IL_51E;
                    }
                    this.CurrentSchema.Enum = new List <JToken>();
                    EnumValues <long> namesAndValues = EnumUtils.GetNamesAndValues <long>(type);
                    using (IEnumerator <EnumValue <long> > enumerator = namesAndValues.GetEnumerator())
                    {
                        while (enumerator.MoveNext())
                        {
                            EnumValue <long> current = enumerator.Current;
                            JToken           item    = JToken.FromObject(current.Value);
                            this.CurrentSchema.Enum.Add(item);
                        }
                        goto IL_51E;
                    }
                    break;
                }

                case JsonContractType.String:
                    break;

                case JsonContractType.Dictionary:
                {
                    this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Object, valueRequired));
                    Type type2;
                    Type type3;
                    ReflectionUtils.GetDictionaryKeyValueTypes(type, out type2, out type3);
                    if (!(type2 != null))
                    {
                        goto IL_51E;
                    }
                    JsonContract jsonContract2 = this.ContractResolver.ResolveContract(type2);
                    if (jsonContract2.ContractType == JsonContractType.Primitive)
                    {
                        this.CurrentSchema.AdditionalProperties = this.GenerateInternal(type3, Required.Default, false);
                        goto IL_51E;
                    }
                    goto IL_51E;
                }

                case JsonContractType.Dynamic:
                case JsonContractType.Linq:
                    this.CurrentSchema.Type = new JsonSchemaType?(JsonSchemaType.Any);
                    goto IL_51E;

                case JsonContractType.Serializable:
                    this.CurrentSchema.Type = new JsonSchemaType?(this.AddNullType(JsonSchemaType.Object, valueRequired));
                    this.CurrentSchema.Id   = this.GetTypeId(type, false);
                    this.GenerateISerializableContract(type, (JsonISerializableContract)jsonContract);
                    goto IL_51E;

                default:
                    throw new JsonException("Unexpected contract type: {0}".FormatWith(CultureInfo.InvariantCulture, jsonContract));
                }
                JsonSchemaType value = (!ReflectionUtils.IsNullable(jsonContract.UnderlyingType)) ? JsonSchemaType.String : this.AddNullType(JsonSchemaType.String, valueRequired);
                this.CurrentSchema.Type = new JsonSchemaType?(value);
            }
            IL_51E:
            return(this.Pop().Schema);
        }