// 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 getMetaInternal(Type type, Class<? extends MetaElement> elementMetaClass, boolean nullable) {
		PreconditionUtil.assertNotNull("type must not be null", type);

		checkInitialized();

		MetaElement meta = getUniqueElementByType(type, elementMetaClass);
		if (meta == null) {
			synchronized (this) {
				meta = getUniqueElementByType(type, elementMetaClass);
				if (meta == null) {

					boolean wasInitializing = adding;
					if (!wasInitializing) {
						adding = true;
					}

					meta = allocateMeta(type, elementMetaClass, nullable);
					if (meta != null) {
						add(meta);
					}

					if (!wasInitializing) {
						initialize();
					}
				}
			}
		}
		return meta;
	}

// 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 getMetaInternal(Type type, Class<? extends MetaElement> elementMetaClass, boolean nullable) {
		PreconditionUtil.assertNotNull("type must not be null", type);

		checkInitialized();

		MetaElement meta = getUniqueElementByType(type, elementMetaClass);
		if (meta == null) {
			synchronized (this) {
				meta = getUniqueElementByType(type, elementMetaClass);
				if (meta == null) {

					boolean wasInitializing = adding;
					if (!wasInitializing) {
						adding = true;
					}

					meta = allocateMeta(type, elementMetaClass, nullable);
					if (meta != null) {
						add(meta);
					}

					if (!wasInitializing) {
						initialize();
					}
				}
			}
		}
		return meta;
	}

	private MetaElement getUniqueElementByType(Type type, Class<? extends MetaElement> elementMetaClass) {