src/main/java/org/eiichiro/bootleg/AbstractRequest.java
@SuppressWarnings("unchecked")
	protected Object parameter(Type type, String name,
			Function<String, Object> value,
			Function<String, Collection<Object>> values) {
		if (name != null && !name.isEmpty()) {
			// Named parameter construction.
			if (Types.isArray(type)) {
				// Named array type.
				logger.debug("Array type [" + type + "] is not supported in ["
						+ getClass() + "]");
			} else if (Types.isCollection(type)) {
				// Named collection type.
				if (Types.isSupportedCollection(type)) {
					Collection<Object> objects = values.apply(name);
					
					if (objects == null) {
						logger.debug("Collection named [" + name + "] not found");
					} else {
						Class<?> elementType = Types.getElementType(type);
						boolean coreValueType = Types.isCoreValueType(elementType);
						
						if (!coreValueType && !Types.isUserDefinedValueType(elementType)) {
							// Named collection of user-defined object.
							logger.debug("Collection element type ["
									+ elementType + "] is not supported in ["
									+ getClass() + "]");
						} else {
							try {
								Class<?> implementationType = Types.getDefaultImplementationType(type);
								Collection<Object> collection = (Collection<Object>) implementationType.newInstance();
								
								for (Object object : objects) {
									// Named collection of core value type.
									// Named collection of user-defined value type.
									Object convert = (coreValueType) ? convert(object, elementType)
											: convertUserDefinedValueType(object, elementType);
									
									if (convert != null
											&& ClassUtils.primitiveToWrapper(elementType).isAssignableFrom(convert.getClass())) {
										collection.add(convert);
									} else {
										logger.debug("Parameter [" + convert
												+ "] cannot be converted to ["
												+ elementType + "]");
									}
								}
								
								return (!collection.isEmpty()) ? collection : null;
							} catch (Exception e) {
								logger.debug("Cannot instantiate ["
										+ Types.getDefaultImplementationType(type)
										+ "] (Default implementation type of ["
										+ type + "])", e);
							}
						}
					}
					
				} else {
					logger.debug("Parameter type [" + type
							+ "] is not supported in [" + getClass() + "]");
				}
				
			} else if (Types.isCoreValueType(type)) {
				// Named core value type.
				Class<?> rawType = Types.getRawType(type);
				Object object = value.apply(name);
				
				if (object == null) {
					logger.debug("Value named [" + name + "] not found");
				} else {
					Object convert = convert(object, rawType);
					
					if (convert != null 
							&& ClassUtils.primitiveToWrapper(rawType).isAssignableFrom(convert.getClass())) {
						return convert;
					} else {
						logger.warn("Parameter [" + convert
								+ "] cannot be converted to [" + type + "]");
					}
				}
				
			} else if (Types.isUserDefinedValueType(type)) {
				// Named user-defined value type.
				Object object = value.apply(name);
				Class<?> rawType = Types.getRawType(type);
				
				if (object == null) {
					logger.debug("Value named [" + name + "] not found");
				} else {
					Object userDefinedValueType = convertUserDefinedValueType(object, rawType);
					
					if (userDefinedValueType == null) {
						logger.warn("Parameter [" + object
								+ "] cannot be converted to [" + type + "]");
					}
					
					return userDefinedValueType;
				}
				
			} else {
				// Named user-defined object type.
				Object object = value.apply(name);
				
				if (object == null) {
					logger.debug("Value named [" + name + "] not found");
				} else if (Types.getRawType(type).isAssignableFrom(object.getClass())) {
					return object;
				} else {
					logger.warn("Parameter [" + object
							+ "] cannot be converted to [" + type + "]");
				}
			}
			
		} else {
			// Non-named parameter construction.
			if (Types.isArray(type) || Types.isCollection(type)
					|| Types.isCoreValueType(type)
					|| Types.isUserDefinedValueType(type)) {
				// Not named array type.
				// Not named collection (of core value type or user-defined object type).
				// Not named core value type.
				// Not named user-defined value type.
				logger.debug("Non-named parameter type [" + type
						+ "] is not supported in [" + getClass() + "]");
			} else {
				// Not named user-defined object type.
				Class<?> rawType = Types.getRawType(type);
				
				try {
					Object instance = rawType.newInstance();
					
					for (Field field : rawType.getDeclaredFields()) {
						Object object = parameter(field.getGenericType(), field.getName(), value, values);
						
						if (object != null) {
							field.setAccessible(true);
							field.set(instance, object);
						}
					}
					
					return instance;
				} catch (Exception e) {
					logger.warn("Cannot instantiate [" + type + "]", e);
				}
			}
		}
		
		return null;
	}
@SuppressWarnings("unchecked")
	protected Object parameter(Type type, String name,
			Function<String, Object> value,
			Function<String, Collection<Object>> values) {
		if (name != null && !name.isEmpty()) {
			// Named parameter construction.
			if (Types.isArray(type)) {
				// Named array type.
				logger.debug("Array type [" + type + "] is not supported in ["
						+ getClass() + "]");
			} else if (Types.isCollection(type)) {
				// Named collection type.
				if (Types.isSupportedCollection(type)) {
					Collection<Object> objects = values.apply(name);
					
					if (objects == null) {
						logger.debug("Collection named [" + name + "] not found");
					} else {
						Class<?> elementType = Types.getElementType(type);
						boolean coreValueType = Types.isCoreValueType(elementType);
						
						if (!coreValueType && !Types.isUserDefinedValueType(elementType)) {
							// Named collection of user-defined object.
							logger.debug("Collection element type ["
									+ elementType + "] is not supported in ["
									+ getClass() + "]");
						} else {
							try {
								Class<?> implementationType = Types.getDefaultImplementationType(type);
								Collection<Object> collection = (Collection<Object>) implementationType.newInstance();
								
								for (Object object : objects) {
									// Named collection of core value type.
									// Named collection of user-defined value type.
									Object convert = (coreValueType) ? convert(object, elementType)
											: convertUserDefinedValueType(object, elementType);
									
									if (convert != null
											&& ClassUtils.primitiveToWrapper(elementType).isAssignableFrom(convert.getClass())) {
										collection.add(convert);
									} else {
										logger.debug("Parameter [" + convert
												+ "] cannot be converted to ["
												+ elementType + "]");
									}
								}
								
								return (!collection.isEmpty()) ? collection : null;
							} catch (Exception e) {
								logger.debug("Cannot instantiate ["
										+ Types.getDefaultImplementationType(type)
										+ "] (Default implementation type of ["
										+ type + "])", e);
							}
						}
					}
					
				} else {
					logger.debug("Parameter type [" + type
							+ "] is not supported in [" + getClass() + "]");
				}
				
			} else if (Types.isCoreValueType(type)) {
				// Named core value type.
				Class<?> rawType = Types.getRawType(type);
				Object object = value.apply(name);
				
				if (object == null) {
					logger.debug("Value named [" + name + "] not found");
				} else {
					Object convert = convert(object, rawType);
					
					if (convert != null 
							&& ClassUtils.primitiveToWrapper(rawType).isAssignableFrom(convert.getClass())) {
						return convert;
					} else {
						logger.warn("Parameter [" + convert
								+ "] cannot be converted to [" + type + "]");
					}
				}
				
			} else if (Types.isUserDefinedValueType(type)) {
				// Named user-defined value type.
				Object object = value.apply(name);
				Class<?> rawType = Types.getRawType(type);
				
				if (object == null) {
					logger.debug("Value named [" + name + "] not found");
				} else {
					Object userDefinedValueType = convertUserDefinedValueType(object, rawType);
					
					if (userDefinedValueType == null) {
						logger.warn("Parameter [" + object
								+ "] cannot be converted to [" + type + "]");
					}
					
					return userDefinedValueType;
				}
				
			} else {
				// Named user-defined object type.
				Object object = value.apply(name);
				
				if (object == null) {
					logger.debug("Value named [" + name + "] not found");
				} else if (Types.getRawType(type).isAssignableFrom(object.getClass())) {
					return object;
				} else {
					logger.warn("Parameter [" + object
							+ "] cannot be converted to [" + type + "]");
				}
			}
			
		} else {
			// Non-named parameter construction.
			if (Types.isArray(type) || Types.isCollection(type)
					|| Types.isCoreValueType(type)
					|| Types.isUserDefinedValueType(type)) {
				// Not named array type.
				// Not named collection (of core value type or user-defined object type).
				// Not named core value type.
				// Not named user-defined value type.
				logger.debug("Non-named parameter type [" + type
						+ "] is not supported in [" + getClass() + "]");
			} else {
				// Not named user-defined object type.
				Class<?> rawType = Types.getRawType(type);
				
				try {
					Object instance = rawType.newInstance();
					
					for (Field field : rawType.getDeclaredFields()) {
						Object object = parameter(field.getGenericType(), field.getName(), value, values);
						
						if (object != null) {
							field.setAccessible(true);
							field.set(instance, object);
						}
					}
					
					return instance;
				} catch (Exception e) {
					logger.warn("Cannot instantiate [" + type + "]", e);
				}
			}
		}
		
		return null;
	}
Constructs the value of Web endpoint parameter.
Web endpoint parameter declaration falls into the several patterns and
each pattern has the own construction logic as below:
<ol>
<li>Named array type - Unsupported. Always returns <code>null</code>.</li>
<li>Named collection of core value type - Supported. The collection
instance is constructed according to the default implementation type
(See {@code Types#getDefaultImplementationType(Type)}). If the collection
type is not supported (See {@code Types#isSupportedCollection(Type)}),
this method returns <code>null</code>. Each of the collection elements is
constructed from the values that {@code values} has returned as the same
way of the following core value type. If the constructed collection has
no element, this method returns <code>null</code>.</li>
<li>Named collection of user-defined value type - Supported. The
collection instance is constructed according to the default
implementation type (as the same as collection of core value type). Each
of the collection elements is constructed from the values that
{@code values} has returned as the same way of following user-defined
value type.
</li>
<li>Named collection of user-defined object type - Unsupported. Always
returns <code>null</code>.</li>
<li>Named core value type - Supported. The value that {@code value} has
returned is converted to the core value type. If the conversion
failed, returns <code>null</code></li>
<li>Named user-defined value type - Supported. If the value that
{@code value} has returned is assignable to the user-defined value type,
returns it. If the value that {@code value} has returned is
{@code String.class}, this method constructs the user-defined value type
with public constructor that takes one String.class parameter or public
static <code>valueOf(String.class)</code> method. If the conversion
failed, returns <code>null</code>.
</li>
<li>Named user-defined object type - Partially supported. If the value
that {@code value} method has returned is assignable to the user-defined
object type, returns it. Otherwise, returns <code>null</code> (does not
any type conversion). </li>
<li>Not named array type - Unsupported. Always returns <code>null</code>.
</li>
<li>Not named collection of core value type - Unsupported. Always returns
<code>null</code>.</li>
<li>Not named collection of user-defined value type - Unsupported. Always
returns <code>null</code>.</li>
<li>Not named collection of user-defined object type - Unsupported.
Always returns <code>null</code>.</li>
<li>Not named core value type - Unsupported. Always returns
<code>null</code>.</li>
<li>Not named user-defined value type - Unsupported. Always returns
<code>null</code>.</li>
<li>Not named user-defined object type - Supported. First, this method
instantiates the user-defined object instance form public default
constructor, and then constructs each of the instances' fields value
according to the named type construction described above (by invoking
{@code #newParameter(WebContext, Type, String)} with the field
type and field name). If the instantiation is failed, returns <code>null
</code>.
</li>
</ol>
This method is overridable. You can provide your own value construction
to Web endpoint parameter by overriding this method.

@param type The parameter type.
@param name The parameter name.
@param value The {@code Function} that returns the value corresponding to
the specified name from its own source.
The returned value is converted to appropriate parameter type.
@param values The {@code Function} that returns the value corresponding
to the specified name from its own source, as {@code Collection} view.
@return The value of Web endpoint parameter.