// Path: katharsis-meta/src/main/java/io/katharsis/meta/model/MetaArrayType.java
// @JsonApiResource(type = "meta/arrayType")
// public class MetaArrayType extends MetaType {
// 
// }
// 
// Path: katharsis-meta/src/main/java/io/katharsis/meta/model/MetaEnumType.java
// @JsonApiResource(type = "meta/enumType")
// public class MetaEnumType extends MetaType {
// 
// }
// 
// Path: katharsis-meta/src/main/java/io/katharsis/meta/model/MetaListType.java
// @JsonApiResource(type = "meta/listType")
// public class MetaListType extends MetaCollectionType {
// 
// }


import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.katharsis.core.internal.utils.MultivaluedMap;
import io.katharsis.core.internal.utils.PreconditionUtil;
import io.katharsis.meta.model.MetaArrayType;
import io.katharsis.meta.model.MetaElement;
import io.katharsis.meta.model.MetaEnumType;
import io.katharsis.meta.model.MetaListType;
import io.katharsis.meta.model.MetaLiteral;
import io.katharsis.meta.model.MetaMapType;
import io.katharsis.meta.model.MetaPrimitiveType;
import io.katharsis.meta.model.MetaSetType;
import io.katharsis.meta.model.MetaType;
import io.katharsis.meta.provider.MetaProvider;
import io.katharsis.meta.provider.MetaProviderContext;

	private MetaElement allocateMeta(Type type, Class<? extends MetaElement> metaClass, boolean nullable) {
		LOGGER.debug("allocate {}", type);

		if (type instanceof Class) {
			MetaElement meta = allocateMetaFromClass(type, metaClass);
			if (meta != null) {
				return meta;
			}
		}

		if (type instanceof ParameterizedType) {
			ParameterizedType paramType = (ParameterizedType) type;
			return allocateMetaFromParamerizedType(paramType, metaClass);
		}

		MetaElement meta = allocateMetaFromFactory(type, metaClass);
		if (meta != null) {
			return meta;
		}

		if (nullable) {
			return null;
		}
		throw new UnsupportedOperationException("unknown type " + type);
	}

	private MetaElement allocateMetaFromClass(Type type, Class<? extends MetaElement> metaClass) {
		Class<?> clazz = (Class<?>) type;
		if (clazz.isEnum()) {
// Path: katharsis-meta/src/main/java/io/katharsis/meta/model/MetaArrayType.java
// @JsonApiResource(type = "meta/arrayType")
// public class MetaArrayType extends MetaType {
// 
// }
// 
// Path: katharsis-meta/src/main/java/io/katharsis/meta/model/MetaEnumType.java
// @JsonApiResource(type = "meta/enumType")
// public class MetaEnumType extends MetaType {
// 
// }
// 
// Path: katharsis-meta/src/main/java/io/katharsis/meta/model/MetaListType.java
// @JsonApiResource(type = "meta/listType")
// public class MetaListType extends MetaCollectionType {
// 
// }


// Path: katharsis-meta/src/main/java/io/katharsis/meta/MetaLookup.java
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.katharsis.core.internal.utils.MultivaluedMap;
import io.katharsis.core.internal.utils.PreconditionUtil;
import io.katharsis.meta.model.MetaArrayType;
import io.katharsis.meta.model.MetaElement;
import io.katharsis.meta.model.MetaEnumType;
import io.katharsis.meta.model.MetaListType;
import io.katharsis.meta.model.MetaLiteral;
import io.katharsis.meta.model.MetaMapType;
import io.katharsis.meta.model.MetaPrimitiveType;
import io.katharsis.meta.model.MetaSetType;
import io.katharsis.meta.model.MetaType;
import io.katharsis.meta.provider.MetaProvider;
import io.katharsis.meta.provider.MetaProviderContext;


	private MetaElement allocateMeta(Type type, Class<? extends MetaElement> metaClass, boolean nullable) {
		LOGGER.debug("allocate {}", type);

		if (type instanceof Class) {
			MetaElement meta = allocateMetaFromClass(type, metaClass);
			if (meta != null) {
				return meta;
			}
		}

		if (type instanceof ParameterizedType) {
			ParameterizedType paramType = (ParameterizedType) type;
			return allocateMetaFromParamerizedType(paramType, metaClass);
		}

		MetaElement meta = allocateMetaFromFactory(type, metaClass);
		if (meta != null) {
			return meta;
		}

		if (nullable) {
			return null;
		}
		throw new UnsupportedOperationException("unknown type " + type);
	}

	private MetaElement allocateMetaFromClass(Type type, Class<? extends MetaElement> metaClass) {
		Class<?> clazz = (Class<?>) type;
		if (clazz.isEnum()) {
			MetaEnumType enumType = new MetaEnumType();