// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
// * with the License.  You may obtain a copy of the License at                                                              *
// *                                                                                                                         *
// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
// *                                                                                                                         *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
// * specific language governing permissions and limitations under the License.                                              *
// ***************************************************************************************************************************
package org.apache.juneau.httppart;

import static java.util.Collections.*;
import static org.apache.juneau.httppart.HttpPartDataType.*;
import static org.apache.juneau.httppart.HttpPartFormat.*;
import static org.apache.juneau.internal.ExceptionUtils.*;
import static org.apache.juneau.internal.StringUtils.*;

import java.lang.annotation.*;
import java.lang.reflect.*;
import java.math.*;
import java.util.*;
import java.util.concurrent.atomic.*;
import java.util.regex.*;

import org.apache.juneau.*;
import org.apache.juneau.collections.*;
import org.apache.juneau.http.annotation.*;
import org.apache.juneau.internal.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.reflect.*;

/**
 * Represents an OpenAPI schema definition.
 *
 * <p>
 * The schema definition can be applied to any HTTP parts such as bodies, headers, query/form parameters, and URL path parts.
 * <br>The API is generic enough to apply to any path part although some attributes may only applicable for certain parts.
 *
 * <p>
 * Schema objects are created via builders instantiated through the {@link #create()} method.
 *
 * <p>
 * This class is thread safe and reusable.
 *
 * <ul class='seealso'>
 * 	<li class='link'>{@doc OpenApiDetails}
 * </ul>
 */
public class HttpPartSchema {

	//-------------------------------------------------------------------------------------------------------------------
	// Predefined instances
	//-------------------------------------------------------------------------------------------------------------------

	/** Reusable instance of this object, all default settings. */
	public static final HttpPartSchema DEFAULT = HttpPartSchema.create().allowEmptyValue(true).build();

	/** Boolean type */
	public static final HttpPartSchema T_BOOLEAN = HttpPartSchema.tBoolean().build();

	/** File type */
	public static final HttpPartSchema T_FILE = HttpPartSchema.tFile().build();

	/** Integer type */
	public static final HttpPartSchema T_INTEGER = HttpPartSchema.tInteger().build();

	/** Int32 type */
	public static final HttpPartSchema T_INT32 = HttpPartSchema.tInt32().build();

	/** Int64 type */
	public static final HttpPartSchema T_INT64 = HttpPartSchema.tInt64().build();

	/** No type */
	public static final HttpPartSchema T_NONE = HttpPartSchema.tNone().build();

	/** Number type */
	public static final HttpPartSchema T_NUMBER = HttpPartSchema.tNumber().build();

	/** Float type */
	public static final HttpPartSchema T_FLOAT = HttpPartSchema.tFloat().build();

	/** Double type */
	public static final HttpPartSchema T_DOUBLE = HttpPartSchema.tDouble().build();

	/** String type */
	public static final HttpPartSchema T_STRING = HttpPartSchema.tString().build();

	/** Byte type */
	public static final HttpPartSchema T_BYTE = HttpPartSchema.tByte().build();

	/** Binary type */
	public static final HttpPartSchema T_BINARY = HttpPartSchema.tBinary().build();

	/** Spaced binary type */
	public static final HttpPartSchema T_BINARY_SPACED = HttpPartSchema.tBinarySpaced().build();

	/** Date type */
	public static final HttpPartSchema T_DATE = HttpPartSchema.tDate().build();

	/** Date-time type */
	public static final HttpPartSchema T_DATETIME = HttpPartSchema.tDateTime().build();

	/** UON-formated simple type */
	public static final HttpPartSchema T_UON = HttpPartSchema.tUon().build();

	/** Array type */
	public static final HttpPartSchema T_ARRAY = HttpPartSchema.tArray().build();

	/** Comma-delimited array type */
	public static final HttpPartSchema T_ARRAY_CSV = HttpPartSchema.tArrayCsv().build();

	/** Pipe-delimited array type */
	public static final HttpPartSchema T_ARRAY_PIPES = HttpPartSchema.tArrayPipes().build();

	/** Space-delimited array type */
	public static final HttpPartSchema T_ARRAY_SSV = HttpPartSchema.tArraySsv().build();

	/** Tab-delimited array type */
	public static final HttpPartSchema T_ARRAY_TSV = HttpPartSchema.tArrayTsv().build();

	/** UON-formatted array type */
	public static final HttpPartSchema T_ARRAY_UON = HttpPartSchema.tArrayUon().build();

	/** Multi-part array type */
	public static final HttpPartSchema T_ARRAY_MULTI = HttpPartSchema.tArrayMulti().build();

	/** Object type */
	public static final HttpPartSchema T_OBJECT = HttpPartSchema.tObject().build();

	/** Comma-delimited object type */
	public static final HttpPartSchema T_OBJECT_CSV = HttpPartSchema.tObjectCsv().build();

	/** Pipe-delimited object type */
	public static final HttpPartSchema T_OBJECT_PIPES = HttpPartSchema.tObjectPipes().build();

	/** Space-delimited object type */
	public static final HttpPartSchema T_OBJECT_SSV = HttpPartSchema.tObjectSsv().build();

	/** Tab-delimited object type */
	public static final HttpPartSchema T_OBJECT_TSV = HttpPartSchema.tObjectTsv().build();

	/** UON-formated object type */
	public static final HttpPartSchema T_OBJECT_UON = HttpPartSchema.tObjectUon().build();


	final String name;
	final Set<Integer> codes;
	final String _default;
	final Set<String> _enum;
	final Map<String,HttpPartSchema> properties;
	final boolean allowEmptyValue, exclusiveMaximum, exclusiveMinimum, required, uniqueItems, skipIfEmpty;
	final HttpPartCollectionFormat collectionFormat;
	final HttpPartDataType type;
	final HttpPartFormat format;
	final Pattern pattern;
	final HttpPartSchema items, additionalProperties;
	final Number maximum, minimum, multipleOf;
	final Long maxLength, minLength, maxItems, minItems, maxProperties, minProperties;
	final Class<? extends HttpPartParser> parser;
	final Class<? extends HttpPartSerializer> serializer;
	final ClassMeta<?> parsedType;

	/**
	 * Instantiates a new builder for this object.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder create() {
		return new HttpPartSchemaBuilder();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>BOOLEAN</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tBoolean() {
		return create().tBoolean();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>FILE</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tFile() {
		return create().tFile();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>INTEGER</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tInteger() {
		return create().tInteger();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>INTEGER</jsf>).format(HttpPartFormat.<jsf>INT32</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tInt32() {
		return create().tInteger().fInt32();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>INTEGER</jsf>).format(HttpPartFormat.<jsf>INT64</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tInt64() {
		return create().tInteger().fInt64();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>NONE</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tNone() {
		return create().tNone();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>NUMBER</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tNumber() {
		return create().tNumber();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>NUMBER</jsf>).format(HttpPartFormat.<jsf>FLOAT</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tFloat() {
		return create().tNumber().fFloat();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>NUMBER</jsf>).format(HttpPartFormat.<jsf>DOUBLE</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tDouble() {
		return create().tNumber().fDouble();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>STRING</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tString() {
		return create().tString();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>STRING</jsf>).format(HttpPartFormat.<jsf>BYTE</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tByte() {
		return create().tString().fByte();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>STRING</jsf>).format(HttpPartFormat.<jsf>BINARY</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tBinary() {
		return create().tString().fBinary();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>STRING</jsf>).format(HttpPartFormat.<jsf>BINARY_SPACED</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tBinarySpaced() {
		return create().tString().fBinarySpaced();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>STRING</jsf>).format(HttpPartFormat.<jsf>DATE</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tDate() {
		return create().tString().fDate();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>STRING</jsf>).format(HttpPartFormat.<jsf>DATE_TIME</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tDateTime() {
		return create().tString().fDateTime();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>STRING</jsf>).format(HttpPartFormat.<jsf>UON</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tUon() {
		return create().tString().fUon();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>ARRAY</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tArray() {
		return create().tArray();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>ARRAY</jsf>).items(items)</c>.
	 *
	 * @param items The schema of the array items.
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tArray(HttpPartSchemaBuilder items) {
		return create().tArray().items(items);
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>ARRAY</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>CSV</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tArrayCsv() {
		return create().tArray().cfCsv();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>ARRAY</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>CSV</jsf>).items(items)</c>.
	 *
	 * @param items The schema of the array items.
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tArrayCsv(HttpPartSchemaBuilder items) {
		return create().tArray().cfCsv().items(items);
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>ARRAY</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>PIPES</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tArrayPipes() {
		return create().tArray().cfPipes();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>ARRAY</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>PIPES</jsf>).items(items)</c>.
	 *
	 * @param items The schema of the array items.
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tArrayPipes(HttpPartSchemaBuilder items) {
		return create().tArray().cfPipes().items(items);
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>ARRAY</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>SSV</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tArraySsv() {
		return create().tArray().cfSsv();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>ARRAY</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>SSV</jsf>).items(items)</c>.
	 *
	 * @param items The schema of the array items.
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tArraySsv(HttpPartSchemaBuilder items) {
		return create().tArray().cfSsv().items(items);
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>ARRAY</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>TSV</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tArrayTsv() {
		return create().tArray().cfTsv();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>ARRAY</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>TSV</jsf>).items(items)</c>.
	 *
	 * @param items The schema of the array items.
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tArrayTsv(HttpPartSchemaBuilder items) {
		return create().tArray().cfTsv().items(items);
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>ARRAY</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>UONC</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tArrayUon() {
		return create().tArray().cfUon();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>ARRAY</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>UONC</jsf>).items(items)</c>.
	 *
	 * @param items The schema of the array items.
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tArrayUon(HttpPartSchemaBuilder items) {
		return create().tArray().cfUon().items(items);
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>ARRAY</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>MULTI</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tArrayMulti() {
		return create().tArray().cfMulti();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>ARRAY</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>MULTI</jsf>).items(items)</c>.
	 *
	 * @param items The schema of the array items.
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tArrayMulti(HttpPartSchemaBuilder items) {
		return create().tArray().cfMulti().items(items);
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>OBJECT</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tObject() {
		return create().tObject();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>OBJECT</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>CSV</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tObjectCsv() {
		return create().tObject().cfCsv();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>OBJECT</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>PIPES</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tObjectPipes() {
		return create().tObject().cfPipes();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>OBJECT</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>SSV</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tObjectSsv() {
		return create().tObject().cfSsv();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>OBJECT</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>TSV</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tObjectTsv() {
		return create().tObject().cfTsv();
	}

	/**
	 * Shortcut for <c><jsm>create</jsm>().type(HttpPartDataType.<jsf>OBJECT</jsf>).collectionFormat(HttpPartCollectionFormat.<jsf>UON</jsf>)</c>.
	 *
	 * @return A new builder for this object.
	 */
	public static HttpPartSchemaBuilder tObjectUon() {
		return create().tObject().cfUon();
	}

	/**
	 * Finds the schema information for the specified method parameter.
	 *
	 * <p>
	 * This method will gather all the schema information from the annotations at the following locations:
	 * <ul>
	 * 	<li>The method parameter.
	 * 	<li>The method parameter class.
	 * 	<li>The method parameter parent classes and interfaces.
	 * </ul>
	 *
	 * @param c
	 * 	The annotation to look for.
	 * 	<br>Valid values:
	 * 	<ul>
	 * 		<li>{@link Body}
	 * 		<li>{@link Header}
	 * 		<li>{@link Query}
	 * 		<li>{@link FormData}
	 * 		<li>{@link Path}
	 * 		<li>{@link Response}
	 * 		<li>{@link ResponseHeader}
	 * 		<li>{@link ResponseBody}
	 * 		<li>{@link HasQuery}
	 * 		<li>{@link HasFormData}
	 * 	</ul>
	 * @param mpi The Java method parameter.
	 * @return The schema information about the parameter.
	 */
	public static HttpPartSchema create(Class<? extends Annotation> c, ParamInfo mpi) {
		return create().apply(c, mpi).build();
	}

	/**
	 * Finds the schema information for the specified method return.
	 *
	 * <p>
	 * This method will gather all the schema information from the annotations at the following locations:
	 * <ul>
	 * 	<li>The method.
	 * 	<li>The method return class.
	 * 	<li>The method return parent classes and interfaces.
	 * </ul>
	 *
	 * @param c
	 * 	The annotation to look for.
	 * 	<br>Valid values:
	 * 	<ul>
	 * 		<li>{@link Body}
	 * 		<li>{@link Header}
	 * 		<li>{@link Query}
	 * 		<li>{@link FormData}
	 * 		<li>{@link Path}
	 * 		<li>{@link Response}
	 * 		<li>{@link ResponseHeader}
	 * 		<li>{@link HasQuery}
	 * 		<li>{@link HasFormData}
	 * 	</ul>
	 * @param m
	 * 	The Java method with the return type being checked.
	 * @return The schema information about the parameter.
	 */
	public static HttpPartSchema create(Class<? extends Annotation> c, Method m) {
		return create().apply(c, m).build();
	}

	/**
	 * Finds the schema information for the specified class.
	 *
	 * <p>
	 * This method will gather all the schema information from the annotations on the class and all parent classes/interfaces.
	 *
	 * @param c
	 * 	The annotation to look for.
	 * 	<br>Valid values:
	 * 	<ul>
	 * 		<li>{@link Body}
	 * 		<li>{@link Header}
	 * 		<li>{@link Query}
	 * 		<li>{@link FormData}
	 * 		<li>{@link Path}
	 * 		<li>{@link Response}
	 * 		<li>{@link ResponseHeader}
	 * 		<li>{@link HasQuery}
	 * 		<li>{@link HasFormData}
	 * 	</ul>
	 * @param t
	 * 	The class containing the parameter.
	 * @return The schema information about the parameter.
	 */
	public static HttpPartSchema create(Class<? extends Annotation> c, java.lang.reflect.Type t) {
		return create().apply(c, t).build();
	}

	/**
	 * Shortcut for calling <c>create().type(type);</c>
	 *
	 * @param type The schema type value.
	 * @return A new builder.
	 */
	public static HttpPartSchemaBuilder create(String type) {
		return create().type(type);
	}

	/**
	 * Shortcut for calling <c>create().type(type).format(format);</c>
	 *
	 * @param type The schema type value.
	 * @param format The schema format value.
	 * @return A new builder.
	 */
	public static HttpPartSchemaBuilder create(String type, String format) {
		return create().type(type).format(format);
	}

	/**
	 * Finds the schema information on the specified annotation.
	 *
	 * @param a
	 * 	The annotation to find the schema information on..
	 * @return The schema information found on the annotation.
	 */
	public static HttpPartSchema create(Annotation a) {
		return create().apply(a).build();
	}

	/**
	 * Finds the schema information on the specified annotation.
	 *
	 * @param a
	 * 	The annotation to find the schema information on..
	 * @param defaultName The default part name if not specified on the annotation.
	 * @return The schema information found on the annotation.
	 */
	public static HttpPartSchema create(Annotation a, String defaultName) {
		return create().name(defaultName).apply(a).build();
	}

	HttpPartSchema(HttpPartSchemaBuilder b) {
		this.name = b.name;
		this.codes = copy(b.codes);
		this._default = b._default;
		this._enum = copy(b._enum);
		this.properties = build(b.properties, b.noValidate);
		this.allowEmptyValue = resolve(b.allowEmptyValue);
		this.exclusiveMaximum = resolve(b.exclusiveMaximum);
		this.exclusiveMinimum = resolve(b.exclusiveMinimum);
		this.required = resolve(b.required);
		this.uniqueItems = resolve(b.uniqueItems);
		this.skipIfEmpty = resolve(b.skipIfEmpty);
		this.collectionFormat = b.collectionFormat;
		this.type = b.type;
		this.format = b.format;
		this.pattern = b.pattern;
		this.items = build(b.items, b.noValidate);
		this.additionalProperties = build(b.additionalProperties, b.noValidate);
		this.maximum = b.maximum;
		this.minimum = b.minimum;
		this.multipleOf = b.multipleOf;
		this.maxItems = b.maxItems;
		this.maxLength = b.maxLength;
		this.maxProperties = b.maxProperties;
		this.minItems = b.minItems;
		this.minLength = b.minLength;
		this.minProperties = b.minProperties;
		this.parser = b.parser;
		this.serializer = b.serializer;

		// Calculate parse type
		Class<?> parsedType = Object.class;
		if (type == ARRAY) {
			if (items != null)
				parsedType = Array.newInstance(items.parsedType.getInnerClass(), 0).getClass();
		} else if (type == BOOLEAN) {
			parsedType = Boolean.class;
		} else if (type == INTEGER) {
			if (format == INT64)
				parsedType = Long.class;
			else
				parsedType = Integer.class;
		} else if (type == NUMBER) {
			if (format == DOUBLE)
				parsedType = Double.class;
			else
				parsedType = Float.class;
		} else if (type == STRING) {
			if (format == BYTE || format == BINARY || format == BINARY_SPACED)
				parsedType = byte[].class;
			else if (format == DATE || format == DATE_TIME)
				parsedType = Calendar.class;
			else
				parsedType = String.class;
		}
		this.parsedType = BeanContext.DEFAULT.getClassMeta(parsedType);

		if (b.noValidate)
			return;

		// Validation.
		List<String> errors = new ArrayList<>();
		AList<String> notAllowed = AList.create();
		boolean invalidFormat = false;
		switch (type) {
			case STRING: {
				notAllowed.appendIf(properties != null, "properties");
				notAllowed.appendIf(additionalProperties != null, "additionalProperties");
				notAllowed.appendIf(exclusiveMaximum, "exclusiveMaximum");
				notAllowed.appendIf(exclusiveMinimum, "exclusiveMinimum");
				notAllowed.appendIf(uniqueItems, "uniqueItems");
				notAllowed.appendIf(collectionFormat != HttpPartCollectionFormat.NO_COLLECTION_FORMAT, "collectionFormat");
				notAllowed.appendIf(items != null, "items");
				notAllowed.appendIf(maximum != null, "maximum");
				notAllowed.appendIf(minimum != null, "minimum");
				notAllowed.appendIf(multipleOf != null, "multipleOf");
				notAllowed.appendIf(maxItems != null, "maxItems");
				notAllowed.appendIf(minItems != null, "minItems");
				notAllowed.appendIf(minProperties != null, "minProperties");
				invalidFormat = ! format.isOneOf(HttpPartFormat.BYTE, HttpPartFormat.BINARY, HttpPartFormat.BINARY_SPACED, HttpPartFormat.DATE, HttpPartFormat.DATE_TIME, HttpPartFormat.PASSWORD, HttpPartFormat.UON, HttpPartFormat.NO_FORMAT);
				break;
			}
			case ARRAY: {
				notAllowed.appendIf(properties != null, "properties");
				notAllowed.appendIf(additionalProperties != null, "additionalProperties");
				notAllowed.appendIf(exclusiveMaximum, "exclusiveMaximum");
				notAllowed.appendIf(exclusiveMinimum, "exclusiveMinimum");
				notAllowed.appendIf(pattern != null, "pattern");
				notAllowed.appendIf(maximum != null, "maximum");
				notAllowed.appendIf(minimum != null, "minimum");
				notAllowed.appendIf(multipleOf != null, "multipleOf");
				notAllowed.appendIf(maxLength != null, "maxLength");
				notAllowed.appendIf(minLength != null, "minLength");
				notAllowed.appendIf(maxProperties != null, "maxProperties");
				notAllowed.appendIf(minProperties != null, "minProperties");
				invalidFormat = ! format.isOneOf(HttpPartFormat.NO_FORMAT, HttpPartFormat.UON);
				break;
			}
			case BOOLEAN: {
				notAllowed.appendIf(! _enum.isEmpty(), "_enum");
				notAllowed.appendIf(properties != null, "properties");
				notAllowed.appendIf(additionalProperties != null, "additionalProperties");
				notAllowed.appendIf(exclusiveMaximum, "exclusiveMaximum");
				notAllowed.appendIf(exclusiveMinimum, "exclusiveMinimum");
				notAllowed.appendIf(uniqueItems, "uniqueItems");
				notAllowed.appendIf(collectionFormat != HttpPartCollectionFormat.NO_COLLECTION_FORMAT, "collectionFormat");
				notAllowed.appendIf(pattern != null, "pattern");
				notAllowed.appendIf(items != null, "items");
				notAllowed.appendIf(maximum != null, "maximum");
				notAllowed.appendIf(minimum != null, "minimum");
				notAllowed.appendIf(multipleOf != null, "multipleOf");
				notAllowed.appendIf(maxItems != null, "maxItems");
				notAllowed.appendIf(maxLength != null, "maxLength");
				notAllowed.appendIf(maxProperties != null, "maxProperties");
				notAllowed.appendIf(minItems != null, "minItems");
				notAllowed.appendIf(minLength != null, "minLength");
				notAllowed.appendIf(minProperties != null, "minProperties");
				invalidFormat = ! format.isOneOf(HttpPartFormat.NO_FORMAT, HttpPartFormat.UON);
				break;
			}
			case FILE: {
				break;
			}
			case INTEGER: {
				notAllowed.appendIf(properties != null, "properties");
				notAllowed.appendIf(additionalProperties != null, "additionalProperties");
				notAllowed.appendIf(uniqueItems, "uniqueItems");
				notAllowed.appendIf(collectionFormat != HttpPartCollectionFormat.NO_COLLECTION_FORMAT, "collectionFormat");
				notAllowed.appendIf(pattern != null, "pattern");
				notAllowed.appendIf(items != null, "items");
				notAllowed.appendIf(maxItems != null, "maxItems");
				notAllowed.appendIf(maxLength != null, "maxLength");
				notAllowed.appendIf(maxProperties != null, "maxProperties");
				notAllowed.appendIf(minItems != null, "minItems");
				notAllowed.appendIf(minLength != null, "minLength");
				notAllowed.appendIf(minProperties != null, "minProperties");
				invalidFormat = ! format.isOneOf(HttpPartFormat.NO_FORMAT, HttpPartFormat.UON, HttpPartFormat.INT32, HttpPartFormat.INT64);
				break;
			}
			case NUMBER: {
				notAllowed.appendIf(properties != null, "properties");
				notAllowed.appendIf(additionalProperties != null, "additionalProperties");
				notAllowed.appendIf(uniqueItems, "uniqueItems");
				notAllowed.appendIf(collectionFormat != HttpPartCollectionFormat.NO_COLLECTION_FORMAT, "collectionFormat");
				notAllowed.appendIf(pattern != null, "pattern");
				notAllowed.appendIf(items != null, "items");
				notAllowed.appendIf(maxItems != null, "maxItems");
				notAllowed.appendIf(maxLength != null, "maxLength");
				notAllowed.appendIf(maxProperties != null, "maxProperties");
				notAllowed.appendIf(minItems != null, "minItems");
				notAllowed.appendIf(minLength != null, "minLength");
				notAllowed.appendIf(minProperties != null, "minProperties");
				invalidFormat = ! format.isOneOf(HttpPartFormat.NO_FORMAT, HttpPartFormat.UON, HttpPartFormat.FLOAT, HttpPartFormat.DOUBLE);
				break;
			}
			case OBJECT: {
				notAllowed.appendIf(exclusiveMaximum, "exclusiveMaximum");
				notAllowed.appendIf(exclusiveMinimum, "exclusiveMinimum");
				notAllowed.appendIf(uniqueItems, "uniqueItems");
				notAllowed.appendIf(pattern != null, "pattern");
				notAllowed.appendIf(items != null, "items");
				notAllowed.appendIf(maximum != null, "maximum");
				notAllowed.appendIf(minimum != null, "minimum");
				notAllowed.appendIf(multipleOf != null, "multipleOf");
				notAllowed.appendIf(maxItems != null, "maxItems");
				notAllowed.appendIf(maxLength != null, "maxLength");
				notAllowed.appendIf(minItems != null, "minItems");
				notAllowed.appendIf(minLength != null, "minLength");
				invalidFormat = ! format.isOneOf(HttpPartFormat.NO_FORMAT);
				break;
			}
			default:
				break;
		}

		if (! notAllowed.isEmpty())
			errors.add("Attributes not allow for type='"+type+"': " + StringUtils.join(notAllowed, ","));
		if (invalidFormat)
			errors.add("Invalid format for type='"+type+"': '"+format+"'");
		if (exclusiveMaximum && maximum == null)
			errors.add("Cannot specify exclusiveMaximum with maximum.");
		if (exclusiveMinimum && minimum == null)
			errors.add("Cannot specify exclusiveMinimum with minimum.");
		if (required && _default != null)
			errors.add("Cannot specify a default value on a required value.");
		if (minLength != null && maxLength != null && maxLength < minLength)
			errors.add("maxLength cannot be less than minLength.");
		if (minimum != null && maximum != null && maximum.doubleValue() < minimum.doubleValue())
			errors.add("maximum cannot be less than minimum.");
		if (minItems != null && maxItems != null && maxItems < minItems)
			errors.add("maxItems cannot be less than minItems.");
		if (minProperties != null && maxProperties != null && maxProperties < minProperties)
			errors.add("maxProperties cannot be less than minProperties.");
		if (minLength != null && minLength < 0)
			errors.add("minLength cannot be less than zero.");
		if (maxLength != null && maxLength < 0)
			errors.add("maxLength cannot be less than zero.");
		if (minItems != null && minItems < 0)
			errors.add("minItems cannot be less than zero.");
		if (maxItems != null && maxItems < 0)
			errors.add("maxItems cannot be less than zero.");
		if (minProperties != null && minProperties < 0)
			errors.add("minProperties cannot be less than zero.");
		if (maxProperties != null && maxProperties < 0)
			errors.add("maxProperties cannot be less than zero.");
		if (type == ARRAY && items != null && items.getType() == OBJECT && (format != UON && format != HttpPartFormat.NO_FORMAT))
			errors.add("Cannot define an array of objects unless array format is 'uon'.");

		if (! errors.isEmpty())
			throw new ContextRuntimeException("Schema specification errors: \n\t" + join(errors, "\n\t"), new Object[0]);
	}

	/**
	 * Returns the default parsed type for this schema.
	 *
	 * @return The default parsed type for this schema.  Never <jk>null</jk>.
	 */
	public ClassMeta<?> getParsedType() {
		return parsedType;
	}

	/**
	 * Returns the name of the object described by this schema, for example the query or form parameter name.
	 *
	 * @return The name, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#name(String)
	 */
	public String getName() {
		return name;
	}

	/**
	 * Returns the HTTP status code or codes defined on a schema.
	 *
	 * @return
	 * 	The list of HTTP status codes.
	 * 	<br>Never <jk>null</jk>.
	 * @see HttpPartSchemaBuilder#code(int)
	 * @see HttpPartSchemaBuilder#codes(int[])
	 */
	public Set<Integer> getCodes() {
		return codes;
	}

	/**
	 * Returns the HTTP status code or codes defined on a schema.
	 *
	 * @param def The default value if there are no codes defined.
	 * @return
	 * 	The list of HTTP status codes.
	 * 	<br>A singleton set containing the default value if the set is empty.
	 * 	<br>Never <jk>null</jk>.
	 * @see HttpPartSchemaBuilder#code(int)
	 * @see HttpPartSchemaBuilder#codes(int[])
	 */
	public Set<Integer> getCodes(Integer def) {
		return codes.isEmpty() ? Collections.singleton(def) : codes;
	}

	/**
	 * Returns the first HTTP status code on a schema.
	 *
	 * @param def The default value if there are no codes defined.
	 * @return
	 * 	The list of HTTP status codes.
	 * 	<br>A singleton set containing the default value if the set is empty.
	 * 	<br>Never <jk>null</jk>.
	 * @see HttpPartSchemaBuilder#code(int)
	 * @see HttpPartSchemaBuilder#codes(int[])
	 */
	public Integer getCode(Integer def) {
		return codes.isEmpty() ? def : codes.iterator().next();
	}

	/**
	 * Returns the <c>type</c> field of this schema.
	 *
	 * @return The <c>type</c> field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#type(String)
	 */
	public HttpPartDataType getType() {
		return type;
	}

	/**
	 * Returns the <c>type</c> field of this schema.
	 *
	 * @param cm
	 * 	The class meta of the object.
	 * 	<br>Used to auto-detect the type if the type was not specified.
	 * @return The format field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#format(String)
	 */
	public HttpPartDataType getType(ClassMeta<?> cm) {
		if (type != HttpPartDataType.NO_TYPE)
			return type;
		if (cm.isTemporal() || cm.isDateOrCalendar())
			return HttpPartDataType.STRING;
		if (cm.isNumber()) {
			if (cm.isDecimal())
				return HttpPartDataType.NUMBER;
			return HttpPartDataType.INTEGER;
		}
		if (cm.isBoolean())
			return HttpPartDataType.BOOLEAN;
		if (cm.isMapOrBean())
			return HttpPartDataType.OBJECT;
		if (cm.isCollectionOrArray())
			return HttpPartDataType.ARRAY;
		return HttpPartDataType.STRING;
	}

	/**
	 * Returns the <c>default</c> field of this schema.
	 *
	 * @return The default value for this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#_default(String)
	 */
	public String getDefault() {
		return _default;
	}

	/**
	 * Returns the <c>collectionFormat</c> field of this schema.
	 *
	 * @return The <c>collectionFormat</c> field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#collectionFormat(String)
	 */
	public HttpPartCollectionFormat getCollectionFormat() {
		return collectionFormat;
	}

	/**
	 * Returns the <c>format</c> field of this schema.
	 *
	 * @see HttpPartSchemaBuilder#format(String)
	 * @return The <c>format</c> field of this schema, or <jk>null</jk> if not specified.
	 */
	public HttpPartFormat getFormat() {
		return format;
	}

	/**
	 * Returns the <c>format</c> field of this schema.
	 *
	 * @param cm
	 * 	The class meta of the object.
	 * 	<br>Used to auto-detect the format if the format was not specified.
	 * @return The <c>format</c> field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#format(String)
	 */
	public HttpPartFormat getFormat(ClassMeta<?> cm) {
		if (format != HttpPartFormat.NO_FORMAT)
			return format;
		if (cm.isNumber()) {
			if (cm.isDecimal()) {
				if (cm.isDouble())
					return HttpPartFormat.DOUBLE;
				return HttpPartFormat.FLOAT;
			}
			if (cm.isLong())
				return HttpPartFormat.INT64;
			return HttpPartFormat.INT32;
		}
		return format;
	}

	/**
	 * Returns the <c>maximum</c> field of this schema.
	 *
	 * @return The schema for child items of the object represented by this schema, or <jk>null</jk> if not defined.
	 * @see HttpPartSchemaBuilder#items(HttpPartSchemaBuilder)
	 */
	public HttpPartSchema getItems() {
		return items;
	}

	/**
	 * Returns the <c>maximum</c> field of this schema.
	 *
	 * @return The <c>maximum</c> field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#maximum(Number)
	 */
	public Number getMaximum() {
		return maximum;
	}

	/**
	 * Returns the <c>minimum</c> field of this schema.
	 *
	 * @return The <c>minimum</c> field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#minimum(Number)
	 */
	public Number getMinimum() {
		return minimum;
	}

	/**
	 * Returns the <c>xxx</c> field of this schema.
	 *
	 * @return The <c>xxx</c> field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#multipleOf(Number)
	 */
	public Number getMultipleOf() {
		return multipleOf;
	}

	/**
	 * Returns the <c>xxx</c> field of this schema.
	 *
	 * @return The <c>xxx</c> field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#pattern(String)
	 */
	public Pattern getPattern() {
		return pattern;
	}

	/**
	 * Returns the <c>xxx</c> field of this schema.
	 *
	 * @return The <c>xxx</c> field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#maxLength(Long)
	 */
	public Long getMaxLength() {
		return maxLength;
	}

	/**
	 * Returns the <c>xxx</c> field of this schema.
	 *
	 * @return The <c>xxx</c> field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#minLength(Long)
	 */
	public Long getMinLength() {
		return minLength;
	}

	/**
	 * Returns the <c>xxx</c> field of this schema.
	 *
	 * @return The <c>xxx</c> field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#maxItems(Long)
	 */
	public Long getMaxItems() {
		return maxItems;
	}

	/**
	 * Returns the <c>xxx</c> field of this schema.
	 *
	 * @return The <c>xxx</c> field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#minItems(Long)
	 */
	public Long getMinItems() {
		return minItems;
	}

	/**
	 * Returns the <c>xxx</c> field of this schema.
	 *
	 * @return The <c>xxx</c> field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#maxProperties(Long)
	 */
	public Long getMaxProperties() {
		return maxProperties;
	}

	/**
	 * Returns the <c>xxx</c> field of this schema.
	 *
	 * @return The <c>xxx</c> field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#minProperties(Long)
	 */
	public Long getMinProperties() {
		return minProperties;
	}

	/**
	 * Returns the <c>exclusiveMaximum</c> field of this schema.
	 *
	 * @return The <c>exclusiveMaximum</c> field of this schema.
	 * @see HttpPartSchemaBuilder#exclusiveMaximum(Boolean)
	 */
	public boolean isExclusiveMaximum() {
		return exclusiveMaximum;
	}

	/**
	 * Returns the <c>exclusiveMinimum</c> field of this schema.
	 *
	 * @return The <c>exclusiveMinimum</c> field of this schema.
	 * @see HttpPartSchemaBuilder#exclusiveMinimum(Boolean)
	 */
	public boolean isExclusiveMinimum() {
		return exclusiveMinimum;
	}

	/**
	 * Returns the <c>uniqueItems</c> field of this schema.
	 *
	 * @return The <c>uniqueItems</c> field of this schema.
	 * @see HttpPartSchemaBuilder#uniqueItems(Boolean)
	 */
	public boolean isUniqueItems() {
		return uniqueItems;
	}

	/**
	 * Returns the <c>required</c> field of this schema.
	 *
	 * @return The <c>required</c> field of this schema.
	 * @see HttpPartSchemaBuilder#required(Boolean)
	 */
	public boolean isRequired() {
		return required;
	}

	/**
	 * Returns the <c>skipIfEmpty</c> field of this schema.
	 *
	 * @return The <c>skipIfEmpty</c> field of this schema.
	 * @see HttpPartSchemaBuilder#skipIfEmpty(Boolean)
	 */
	public boolean isSkipIfEmpty() {
		return skipIfEmpty;
	}

	/**
	 * Returns the <c>allowEmptyValue</c> field of this schema.
	 *
	 * @return The <c>skipIfEmpty</c> field of this schema.
	 * @see HttpPartSchemaBuilder#skipIfEmpty(Boolean)
	 */
	public boolean isAllowEmptyValue() {
		return allowEmptyValue;
	}

	/**
	 * Returns the <c>enum</c> field of this schema.
	 *
	 * @return The <c>enum</c> field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#_enum(Set)
	 */
	public Set<String> getEnum() {
		return _enum;
	}

	/**
	 * Returns the <c>parser</c> field of this schema.
	 *
	 * @return The <c>parser</c> field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#parser(Class)
	 */
	public Class<? extends HttpPartParser> getParser() {
		return parser;
	}

	/**
	 * Returns the <c>serializer</c> field of this schema.
	 *
	 * @return The <c>serializer</c> field of this schema, or <jk>null</jk> if not specified.
	 * @see HttpPartSchemaBuilder#serializer(Class)
	 */
	public Class<? extends HttpPartSerializer> getSerializer() {
		return serializer;
	}

	/**
	 * Throws a {@link ParseException} if the specified pre-parsed input does not validate against this schema.
	 *
	 * @param in The input.
	 * @return The same object passed in.
	 * @throws SchemaValidationException if the specified pre-parsed input does not validate against this schema.
	 */
	public String validateInput(String in) throws SchemaValidationException {
		if (! isValidRequired(in))
			throw new SchemaValidationException("No value specified.");
		if (in != null) {
			if (! isValidAllowEmpty(in))
				throw new SchemaValidationException("Empty value not allowed.");
			if (! isValidPattern(in))
				throw new SchemaValidationException("Value does not match expected pattern.  Must match pattern: {0}", pattern.pattern());
			if (! isValidEnum(in))
				throw new SchemaValidationException("Value does not match one of the expected values.  Must be one of the following: {0}", _enum);
			if (! isValidMaxLength(in))
				throw new SchemaValidationException("Maximum length of value exceeded.");
			if (! isValidMinLength(in))
				throw new SchemaValidationException("Minimum length of value not met.");
		}
		return in;
	}

	/**
	 * Throws a {@link ParseException} if the specified parsed output does not validate against this schema.
	 *
	 * @param o The parsed output.
	 * @param bc The bean context used to detect POJO types.
	 * @return The same object passed in.
	 * @throws SchemaValidationException if the specified parsed output does not validate against this schema.
	 */
	@SuppressWarnings("rawtypes")
	public <T> T validateOutput(T o, BeanContext bc) throws SchemaValidationException {
		if (o == null) {
			if (! isValidRequired(o))
				throw new SchemaValidationException("Required value not provided.");
			return o;
		}
		ClassMeta<?> cm = bc.getClassMetaForObject(o);
		switch (getType(cm)) {
			case ARRAY: {
				if (cm.isArray()) {
					if (! isValidMinItems(o))
						throw new SchemaValidationException("Minimum number of items not met.");
					if (! isValidMaxItems(o))
						throw new SchemaValidationException("Maximum number of items exceeded.");
					if (! isValidUniqueItems(o))
						throw new SchemaValidationException("Duplicate items not allowed.");
					HttpPartSchema items = getItems();
					if (items != null)
						for (int i = 0; i < Array.getLength(o); i++)
							items.validateOutput(Array.get(o, i), bc);
				} else if (cm.isCollection()) {
					Collection<?> c = (Collection<?>)o;
					if (! isValidMinItems(c))
						throw new SchemaValidationException("Minimum number of items not met.");
					if (! isValidMaxItems(c))
						throw new SchemaValidationException("Maximum number of items exceeded.");
					if (! isValidUniqueItems(c))
						throw new SchemaValidationException("Duplicate items not allowed.");
					HttpPartSchema items = getItems();
					if (items != null)
						for (Object o2 : c)
							items.validateOutput(o2, bc);
				}
				break;
			}
			case INTEGER: {
				if (cm.isNumber()) {
					Number n = (Number)o;
					if (! isValidMinimum(n))
						throw new SchemaValidationException("Minimum value not met.");
					if (! isValidMaximum(n))
						throw new SchemaValidationException("Maximum value exceeded.");
					if (! isValidMultipleOf(n))
						throw new SchemaValidationException("Multiple-of not met.");
				}
				break;
			}
			case NUMBER: {
				if (cm.isNumber()) {
					Number n = (Number)o;
					if (! isValidMinimum(n))
						throw new SchemaValidationException("Minimum value not met.");
					if (! isValidMaximum(n))
						throw new SchemaValidationException("Maximum value exceeded.");
					if (! isValidMultipleOf(n))
						throw new SchemaValidationException("Multiple-of not met.");
				}
				break;
			}
			case OBJECT: {
				if (cm.isMapOrBean()) {
					Map<?,?> m = cm.isMap() ? (Map<?,?>)o : bc.createSession().toBeanMap(o);
					if (! isValidMinProperties(m))
						throw new SchemaValidationException("Minimum number of properties not met.");
					if (! isValidMaxProperties(m))
						throw new SchemaValidationException("Maximum number of properties exceeded.");
					for (Map.Entry e : m.entrySet()) {
						String key = e.getKey().toString();
						HttpPartSchema s2 = getProperty(key);
						if (s2 != null)
							s2.validateOutput(e.getValue(), bc);
					}
				} else if (cm.isBean()) {

				}
				break;
			}
			case BOOLEAN:
			case FILE:
			case STRING:
			case NO_TYPE:
				break;
		}
		return o;
	}

	//-----------------------------------------------------------------------------------------------------------------
	// Helper methods.
	//-----------------------------------------------------------------------------------------------------------------

	private boolean isValidRequired(Object x) {
		return x != null || ! required;
	}

	private boolean isValidMinProperties(Map<?,?> x) {
		return minProperties == null || x.size() >= minProperties;
	}

	private boolean isValidMaxProperties(Map<?,?> x) {
		return maxProperties == null || x.size() <= maxProperties;
	}

	private boolean isValidMinimum(Number x) {
		if (x instanceof Integer || x instanceof AtomicInteger)
			return minimum == null || x.intValue() > minimum.intValue() || (x.intValue() == minimum.intValue() && (! exclusiveMinimum));
		if (x instanceof Short || x instanceof Byte)
			return minimum == null || x.shortValue() > minimum.shortValue() || (x.intValue() == minimum.shortValue() && (! exclusiveMinimum));
		if (x instanceof Long || x instanceof AtomicLong || x instanceof BigInteger)
			return minimum == null || x.longValue() > minimum.longValue() || (x.intValue() == minimum.longValue() && (! exclusiveMinimum));
		if (x instanceof Float)
			return minimum == null || x.floatValue() > minimum.floatValue() || (x.floatValue() == minimum.floatValue() && (! exclusiveMinimum));
		if (x instanceof Double || x instanceof BigDecimal)
			return minimum == null || x.doubleValue() > minimum.doubleValue() || (x.doubleValue() == minimum.doubleValue() && (! exclusiveMinimum));
		return true;
	}

	private boolean isValidMaximum(Number x) {
		if (x instanceof Integer || x instanceof AtomicInteger)
			return maximum == null || x.intValue() < maximum.intValue() || (x.intValue() == maximum.intValue() && (! exclusiveMaximum));
		if (x instanceof Short || x instanceof Byte)
			return maximum == null || x.shortValue() < maximum.shortValue() || (x.intValue() == maximum.shortValue() && (! exclusiveMaximum));
		if (x instanceof Long || x instanceof AtomicLong || x instanceof BigInteger)
			return maximum == null || x.longValue() < maximum.longValue() || (x.intValue() == maximum.longValue() && (! exclusiveMaximum));
		if (x instanceof Float)
			return maximum == null || x.floatValue() < maximum.floatValue() || (x.floatValue() == maximum.floatValue() && (! exclusiveMaximum));
		if (x instanceof Double || x instanceof BigDecimal)
			return maximum == null || x.doubleValue() < maximum.doubleValue() || (x.doubleValue() == maximum.doubleValue() && (! exclusiveMaximum));
		return true;
	}

	private boolean isValidMultipleOf(Number x) {
		if (x instanceof Integer || x instanceof AtomicInteger)
			return multipleOf == null || x.intValue() % multipleOf.intValue() == 0;
		if (x instanceof Short || x instanceof Byte)
			return multipleOf == null || x.shortValue() % multipleOf.shortValue() == 0;
		if (x instanceof Long || x instanceof AtomicLong || x instanceof BigInteger)
			return multipleOf == null || x.longValue() % multipleOf.longValue() == 0;
		if (x instanceof Float)
			return multipleOf == null || x.floatValue() % multipleOf.floatValue() == 0;
		if (x instanceof Double || x instanceof BigDecimal)
			return multipleOf == null || x.doubleValue() % multipleOf.doubleValue() == 0;
		return true;
	}

	private boolean isValidAllowEmpty(String x) {
		return allowEmptyValue || isNotEmpty(x);
	}

	private boolean isValidPattern(String x) {
		return pattern == null || pattern.matcher(x).matches();
	}

	private boolean isValidEnum(String x) {
		return _enum.isEmpty() || _enum.contains(x);
	}

	private boolean isValidMinLength(String x) {
		return minLength == null || x.length() >= minLength;
	}

	private boolean isValidMaxLength(String x) {
		return maxLength == null || x.length() <= maxLength;
	}

	private boolean isValidMinItems(Object x) {
		return minItems == null || Array.getLength(x) >= minItems;
	}

	private boolean isValidMaxItems(Object x) {
		return maxItems == null || Array.getLength(x) <= maxItems;
	}

	private boolean isValidUniqueItems(Object x) {
		if (uniqueItems) {
			Set<Object> s = new HashSet<>();
			for (int i = 0; i < Array.getLength(x); i++) {
				Object o = Array.get(x, i);
				if (! s.add(o))
					return false;
			}
		}
		return true;
	}

	private boolean isValidMinItems(Collection<?> x) {
		return minItems == null || x.size() >= minItems;
	}

	private boolean isValidMaxItems(Collection<?> x) {
		return maxItems == null || x.size() <= maxItems;
	}

	private boolean isValidUniqueItems(Collection<?> x) {
		if (uniqueItems && ! (x instanceof Set)) {
			Set<Object> s = new HashSet<>();
			for (Object o : x)
				if (! s.add(o))
					return false;
		}
		return true;
	}

	/**
	 * Returns the schema information for the specified property.
	 *
	 * @param name The property name.
	 * @return The schema information for the specified property, or <jk>null</jk> if properties are not defined on this schema.
	 */
	public HttpPartSchema getProperty(String name) {
		if (properties != null) {
			HttpPartSchema schema = properties.get(name);
			if (schema != null)
				return schema;
		}
		return additionalProperties;
	}

	/**
	 * Returns <jk>true</jk> if this schema has properties associated with it.
	 *
	 * @return <jk>true</jk> if this schema has properties associated with it.
	 */
	public boolean hasProperties() {
		return properties != null || additionalProperties != null;
	}

	private static <T> Set<T> copy(Set<T> in) {
		return in == null ? Collections.emptySet() : unmodifiableSet(new LinkedHashSet<>(in));
	}

	private static Map<String,HttpPartSchema> build(Map<String,Object> in, boolean noValidate) {
		if (in == null)
			return null;
		Map<String,HttpPartSchema> m = new LinkedHashMap<>();
		for (Map.Entry<String,Object> e : in.entrySet()) {
			Object v = e.getValue();
			m.put(e.getKey(), build(v, noValidate));
		}
		return unmodifiableMap(m);
	}

	private static HttpPartSchema build(Object in, boolean noValidate) {
		if (in == null)
			return null;
		if (in instanceof HttpPartSchema)
			return (HttpPartSchema)in;
		return ((HttpPartSchemaBuilder)in).noValidate(noValidate).build();
	}

	//-----------------------------------------------------------------------------------------------------------------
	// Helper methods.
	//-----------------------------------------------------------------------------------------------------------------

	private boolean resolve(Boolean b) {
		return b == null ? false : b;
	}

	final static Set<String> toSet(String[]...s) {
		for (String[] ss : s)
			if (ss != null && ss.length > 0)
				return toSet(joinnl(ss));
		return null;
	}

	final static Set<String> toSet(String s) {
		if (isEmpty(s))
			return null;
		Set<String> set = ASet.of();
		try {
			for (Object o : StringUtils.parseListOrCdl(s))
				set.add(o.toString());
		} catch (ParseException e) {
			throw runtimeException(e);
		}
		return set;
	}

	final static Number toNumber(String...s) {
		try {
			for (String ss : s)
				if (isNotEmpty(ss))
					return parseNumber(ss, Number.class);
			return null;
		} catch (ParseException e) {
			throw runtimeException(e);
		}
	}

	final static OMap toOMap(String[] ss) {
		String s = joinnl(ss);
		if (s.isEmpty())
			return null;
		if (! isJsonObject(s, true))
			s = "{" + s + "}";
		try {
			return OMap.ofJson(s);
		} catch (ParseException e) {
			throw runtimeException(e);
		}
	}

	@Override
	public String toString() {
		try {
			OMap m = new OMap()
				.appendSkipEmpty("name", name)
				.appendSkipEmpty("type", type)
				.appendSkipEmpty("format", format)
				.appendSkipEmpty("codes", codes)
				.appendSkipEmpty("default", _default)
				.appendSkipEmpty("enum", _enum)
				.appendSkipEmpty("properties", properties)
				.appendSkipFalse("allowEmptyValue", allowEmptyValue)
				.appendSkipFalse("exclusiveMaximum", exclusiveMaximum)
				.appendSkipFalse("exclusiveMinimum", exclusiveMinimum)
				.appendSkipFalse("required", required)
				.appendSkipFalse("uniqueItems", uniqueItems)
				.appendSkipFalse("skipIfEmpty", skipIfEmpty)
				.appendIf(collectionFormat != HttpPartCollectionFormat.NO_COLLECTION_FORMAT, "collectionFormat", collectionFormat)
				.appendSkipEmpty("pattern", pattern)
				.appendSkipNull("items", items)
				.appendSkipNull("additionalProperties", additionalProperties)
				.appendSkipMinusOne("maximum", maximum)
				.appendSkipMinusOne("minimum", minimum)
				.appendSkipMinusOne("multipleOf", multipleOf)
				.appendSkipMinusOne("maxLength", maxLength)
				.appendSkipMinusOne("minLength", minLength)
				.appendSkipMinusOne("maxItems", maxItems)
				.appendSkipMinusOne("minItems", minItems)
				.appendSkipMinusOne("maxProperties", maxProperties)
				.appendSkipMinusOne("minProperties", minProperties)
				.append("parsedType", parsedType)
			;
			return m.toString();
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}
}
