/**
 * Copyright (c) 2013, 2017 CEA LIST & LIFL 
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *   Cedric Dumoulin  Cedric.dumoulin@lifl.fr - Initial API and implementation
 *   Quentin Le Menez quentin.lemenez@cea.fr
 * 
 */
package org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.provider;

import java.util.ArrayList;
import java.util.Collection;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;

import org.eclipse.emf.edit.provider.ChangeNotifier;
import org.eclipse.emf.edit.provider.ComposeableAdapterFactory;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.IChangeNotifier;
import org.eclipse.emf.edit.provider.IDisposable;
import org.eclipse.emf.edit.provider.IEditingDomainItemProvider;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.provider.IItemPropertySource;
import org.eclipse.emf.edit.provider.INotifyChangedListener;
import org.eclipse.emf.edit.provider.IStructuredItemContentProvider;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;

import org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.util.LayersAdapterFactory;

/**
 * This is the factory that is used to provide the interfaces needed to support Viewers.
 * The adapters generated by this factory convert EMF adapter notifications into calls to {@link #fireNotifyChanged fireNotifyChanged}.
 * The adapters also support Eclipse property sheets.
 * Note that most of the adapters are shared among multiple instances.
 * <!-- begin-user-doc -->
 * <!-- end-user-doc -->
 * @generated
 */
public class LayersItemProviderAdapterFactory extends LayersAdapterFactory implements ComposeableAdapterFactory, IChangeNotifier, IDisposable {
	/**
	 * This keeps track of the root adapter factory that delegates to this adapter factory.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected ComposedAdapterFactory parentAdapterFactory;

	/**
	 * This is used to implement {@link org.eclipse.emf.edit.provider.IChangeNotifier}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected IChangeNotifier changeNotifier = new ChangeNotifier();

	/**
	 * This keeps track of all the supported types checked by {@link #isFactoryForType isFactoryForType}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected Collection<Object> supportedTypes = new ArrayList<Object>();

	/**
	 * This constructs an instance.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public LayersItemProviderAdapterFactory() {
		supportedTypes.add(IEditingDomainItemProvider.class);
		supportedTypes.add(IStructuredItemContentProvider.class);
		supportedTypes.add(ITreeItemContentProvider.class);
		supportedTypes.add(IItemLabelProvider.class);
		supportedTypes.add(IItemPropertySource.class);
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerNamedStyle} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected LayerNamedStyleItemProvider layerNamedStyleItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerNamedStyle}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createLayerNamedStyleAdapter() {
		if (layerNamedStyleItemProvider == null) {
			layerNamedStyleItemProvider = new LayerNamedStyleItemProvider(this);
		}

		return layerNamedStyleItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStack} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected LayersStackItemProvider layersStackItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStack}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createLayersStackAdapter() {
		if (layersStackItemProvider == null) {
			layersStackItemProvider = new LayersStackItemProvider(this);
		}

		return layersStackItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStackApplication} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected LayersStackApplicationItemProvider layersStackApplicationItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayersStackApplication}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createLayersStackApplicationAdapter() {
		if (layersStackApplicationItemProvider == null) {
			layersStackApplicationItemProvider = new LayersStackApplicationItemProvider(this);
		}

		return layersStackApplicationItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerStackDescriptorRegistry} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected LayerStackDescriptorRegistryItemProvider layerStackDescriptorRegistryItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerStackDescriptorRegistry}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createLayerStackDescriptorRegistryAdapter() {
		if (layerStackDescriptorRegistryItemProvider == null) {
			layerStackDescriptorRegistryItemProvider = new LayerStackDescriptorRegistryItemProvider(this);
		}

		return layerStackDescriptorRegistryItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.PropertyRegistry} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected PropertyRegistryItemProvider propertyRegistryItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.PropertyRegistry}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createPropertyRegistryAdapter() {
		if (propertyRegistryItemProvider == null) {
			propertyRegistryItemProvider = new PropertyRegistryItemProvider(this);
		}

		return propertyRegistryItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.Property} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected PropertyItemProvider propertyItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.Property}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createPropertyAdapter() {
		if (propertyItemProvider == null) {
			propertyItemProvider = new PropertyItemProvider(this);
		}

		return propertyItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.Metamodel} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected MetamodelItemProvider metamodelItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.Metamodel}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createMetamodelAdapter() {
		if (metamodelItemProvider == null) {
			metamodelItemProvider = new MetamodelItemProvider(this);
		}

		return metamodelItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.TypeRegistry} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected TypeRegistryItemProvider typeRegistryItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.TypeRegistry}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createTypeRegistryAdapter() {
		if (typeRegistryItemProvider == null) {
			typeRegistryItemProvider = new TypeRegistryItemProvider(this);
		}

		return typeRegistryItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link java.util.Map.Entry} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected StringToTypeMapItemProvider stringToTypeMapItemProvider;

	/**
	 * This creates an adapter for a {@link java.util.Map.Entry}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createStringToTypeMapAdapter() {
		if (stringToTypeMapItemProvider == null) {
			stringToTypeMapItemProvider = new StringToTypeMapItemProvider(this);
		}

		return stringToTypeMapItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerDescriptorRegistry} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected LayerDescriptorRegistryItemProvider layerDescriptorRegistryItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerDescriptorRegistry}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createLayerDescriptorRegistryAdapter() {
		if (layerDescriptorRegistryItemProvider == null) {
			layerDescriptorRegistryItemProvider = new LayerDescriptorRegistryItemProvider(this);
		}

		return layerDescriptorRegistryItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerDescriptor} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected LayerDescriptorItemProvider layerDescriptorItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerDescriptor}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createLayerDescriptorAdapter() {
		if (layerDescriptorItemProvider == null) {
			layerDescriptorItemProvider = new LayerDescriptorItemProvider(this);
		}

		return layerDescriptorItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerApplicationFactory} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected LayerApplicationFactoryItemProvider layerApplicationFactoryItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerApplicationFactory}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createLayerApplicationFactoryAdapter() {
		if (layerApplicationFactoryItemProvider == null) {
			layerApplicationFactoryItemProvider = new LayerApplicationFactoryItemProvider(this);
		}

		return layerApplicationFactoryItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.PropertySetterRegistry} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected PropertySetterRegistryItemProvider propertySetterRegistryItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.PropertySetterRegistry}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createPropertySetterRegistryAdapter() {
		if (propertySetterRegistryItemProvider == null) {
			propertySetterRegistryItemProvider = new PropertySetterRegistryItemProvider(this);
		}

		return propertySetterRegistryItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link java.util.Map.Entry} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected StringToPropertySetterItemProvider stringToPropertySetterItemProvider;

	/**
	 * This creates an adapter for a {@link java.util.Map.Entry}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createStringToPropertySetterAdapter() {
		if (stringToPropertySetterItemProvider == null) {
			stringToPropertySetterItemProvider = new StringToPropertySetterItemProvider(this);
		}

		return stringToPropertySetterItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerOperatorDescriptorRegistry} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected LayerOperatorDescriptorRegistryItemProvider layerOperatorDescriptorRegistryItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerOperatorDescriptorRegistry}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createLayerOperatorDescriptorRegistryAdapter() {
		if (layerOperatorDescriptorRegistryItemProvider == null) {
			layerOperatorDescriptorRegistryItemProvider = new LayerOperatorDescriptorRegistryItemProvider(this);
		}

		return layerOperatorDescriptorRegistryItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerOperatorDescriptor} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected LayerOperatorDescriptorItemProvider layerOperatorDescriptorItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LayerOperatorDescriptor}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createLayerOperatorDescriptorAdapter() {
		if (layerOperatorDescriptorItemProvider == null) {
			layerOperatorDescriptorItemProvider = new LayerOperatorDescriptorItemProvider(this);
		}

		return layerOperatorDescriptorItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.PropertyOperator} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected PropertyOperatorItemProvider propertyOperatorItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.PropertyOperator}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createPropertyOperatorAdapter() {
		if (propertyOperatorItemProvider == null) {
			propertyOperatorItemProvider = new PropertyOperatorItemProvider(this);
		}

		return propertyOperatorItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.DefaultPropertyOperator} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected DefaultPropertyOperatorItemProvider defaultPropertyOperatorItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.DefaultPropertyOperator}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createDefaultPropertyOperatorAdapter() {
		if (defaultPropertyOperatorItemProvider == null) {
			defaultPropertyOperatorItemProvider = new DefaultPropertyOperatorItemProvider(this);
		}

		return defaultPropertyOperatorItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link java.util.Map.Entry} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected StringToTypeInstanceMapItemProvider stringToTypeInstanceMapItemProvider;

	/**
	 * This creates an adapter for a {@link java.util.Map.Entry}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createStringToTypeInstanceMapAdapter() {
		if (stringToTypeInstanceMapItemProvider == null) {
			stringToTypeInstanceMapItemProvider = new StringToTypeInstanceMapItemProvider(this);
		}

		return stringToTypeInstanceMapItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.Folder} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected FolderItemProvider folderItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.Folder}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createFolderAdapter() {
		if (folderItemProvider == null) {
			folderItemProvider = new FolderItemProvider(this);
		}

		return folderItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.IntInstance} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected IntInstanceItemProvider intInstanceItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.IntInstance}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createIntInstanceAdapter() {
		if (intInstanceItemProvider == null) {
			intInstanceItemProvider = new IntInstanceItemProvider(this);
		}

		return intInstanceItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.BooleanInstance} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected BooleanInstanceItemProvider booleanInstanceItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.BooleanInstance}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createBooleanInstanceAdapter() {
		if (booleanInstanceItemProvider == null) {
			booleanInstanceItemProvider = new BooleanInstanceItemProvider(this);
		}

		return booleanInstanceItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.StringInstance} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected StringInstanceItemProvider stringInstanceItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.StringInstance}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createStringInstanceAdapter() {
		if (stringInstanceItemProvider == null) {
			stringInstanceItemProvider = new StringInstanceItemProvider(this);
		}

		return stringInstanceItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.IntType} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected IntTypeItemProvider intTypeItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.IntType}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createIntTypeAdapter() {
		if (intTypeItemProvider == null) {
			intTypeItemProvider = new IntTypeItemProvider(this);
		}

		return intTypeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.BooleanType} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected BooleanTypeItemProvider booleanTypeItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.BooleanType}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createBooleanTypeAdapter() {
		if (booleanTypeItemProvider == null) {
			booleanTypeItemProvider = new BooleanTypeItemProvider(this);
		}

		return booleanTypeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.StringType} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected StringTypeItemProvider stringTypeItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.StringType}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createStringTypeAdapter() {
		if (stringTypeItemProvider == null) {
			stringTypeItemProvider = new StringTypeItemProvider(this);
		}

		return stringTypeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.CustomType} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected CustomTypeItemProvider customTypeItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.CustomType}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createCustomTypeAdapter() {
		if (customTypeItemProvider == null) {
			customTypeItemProvider = new CustomTypeItemProvider(this);
		}

		return customTypeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.TopLayerOperator} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected TopLayerOperatorItemProvider topLayerOperatorItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.TopLayerOperator}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createTopLayerOperatorAdapter() {
		if (topLayerOperatorItemProvider == null) {
			topLayerOperatorItemProvider = new TopLayerOperatorItemProvider(this);
		}

		return topLayerOperatorItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.StackedLayerOperator} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected StackedLayerOperatorItemProvider stackedLayerOperatorItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.StackedLayerOperator}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createStackedLayerOperatorAdapter() {
		if (stackedLayerOperatorItemProvider == null) {
			stackedLayerOperatorItemProvider = new StackedLayerOperatorItemProvider(this);
		}

		return stackedLayerOperatorItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.CustomLayerOperator} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected CustomLayerOperatorItemProvider customLayerOperatorItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.CustomLayerOperator}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createCustomLayerOperatorAdapter() {
		if (customLayerOperatorItemProvider == null) {
			customLayerOperatorItemProvider = new CustomLayerOperatorItemProvider(this);
		}

		return customLayerOperatorItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.PropertyIndex} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected PropertyIndexItemProvider propertyIndexItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.PropertyIndex}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createPropertyIndexAdapter() {
		if (propertyIndexItemProvider == null) {
			propertyIndexItemProvider = new PropertyIndexItemProvider(this);
		}

		return propertyIndexItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link java.util.Map.Entry} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected StringToPropertyIndexMapItemProvider stringToPropertyIndexMapItemProvider;

	/**
	 * This creates an adapter for a {@link java.util.Map.Entry}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createStringToPropertyIndexMapAdapter() {
		if (stringToPropertyIndexMapItemProvider == null) {
			stringToPropertyIndexMapItemProvider = new StringToPropertyIndexMapItemProvider(this);
		}

		return stringToPropertyIndexMapItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.SimpleLayerDescriptor} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected SimpleLayerDescriptorItemProvider simpleLayerDescriptorItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.SimpleLayerDescriptor}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createSimpleLayerDescriptorAdapter() {
		if (simpleLayerDescriptorItemProvider == null) {
			simpleLayerDescriptorItemProvider = new SimpleLayerDescriptorItemProvider(this);
		}

		return simpleLayerDescriptorItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.RegExpLayerDescriptor} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected RegExpLayerDescriptorItemProvider regExpLayerDescriptorItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.RegExpLayerDescriptor}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createRegExpLayerDescriptorAdapter() {
		if (regExpLayerDescriptorItemProvider == null) {
			regExpLayerDescriptorItemProvider = new RegExpLayerDescriptorItemProvider(this);
		}

		return regExpLayerDescriptorItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.NullInstance} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected NullInstanceItemProvider nullInstanceItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.NullInstance}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createNullInstanceAdapter() {
		if (nullInstanceItemProvider == null) {
			nullInstanceItemProvider = new NullInstanceItemProvider(this);
		}

		return nullInstanceItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.RegExpLayer} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected RegExpLayerItemProvider regExpLayerItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.RegExpLayer}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createRegExpLayerAdapter() {
		if (regExpLayerItemProvider == null) {
			regExpLayerItemProvider = new RegExpLayerItemProvider(this);
		}

		return regExpLayerItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.Layer} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected LayerItemProvider layerItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.Layer}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createLayerAdapter() {
		if (layerItemProvider == null) {
			layerItemProvider = new LayerItemProvider(this);
		}

		return layerItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.Color} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected ColorItemProvider colorItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.Color}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createColorAdapter() {
		if (colorItemProvider == null) {
			colorItemProvider = new ColorItemProvider(this);
		}

		return colorItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.ColorInstance} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected ColorInstanceItemProvider colorInstanceItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.ColorInstance}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createColorInstanceAdapter() {
		if (colorInstanceItemProvider == null) {
			colorInstanceItemProvider = new ColorInstanceItemProvider(this);
		}

		return colorInstanceItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.FillInstance} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected FillInstanceItemProvider fillInstanceItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.FillInstance}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createFillInstanceAdapter() {
		if (fillInstanceItemProvider == null) {
			fillInstanceItemProvider = new FillInstanceItemProvider(this);
		}

		return fillInstanceItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.Fill} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected FillItemProvider fillItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.Fill}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createFillAdapter() {
		if (fillItemProvider == null) {
			fillItemProvider = new FillItemProvider(this);
		}

		return fillItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.FillPropertySetter} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected FillPropertySetterItemProvider fillPropertySetterItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.FillPropertySetter}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createFillPropertySetterAdapter() {
		if (fillPropertySetterItemProvider == null) {
			fillPropertySetterItemProvider = new FillPropertySetterItemProvider(this);
		}

		return fillPropertySetterItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.IsValidPropertySetter} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected IsValidPropertySetterItemProvider isValidPropertySetterItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.IsValidPropertySetter}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createIsValidPropertySetterAdapter() {
		if (isValidPropertySetterItemProvider == null) {
			isValidPropertySetterItemProvider = new IsValidPropertySetterItemProvider(this);
		}

		return isValidPropertySetterItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.NullPropertySetter} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected NullPropertySetterItemProvider nullPropertySetterItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.NullPropertySetter}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createNullPropertySetterAdapter() {
		if (nullPropertySetterItemProvider == null) {
			nullPropertySetterItemProvider = new NullPropertySetterItemProvider(this);
		}

		return nullPropertySetterItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LineType} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected LineTypeItemProvider lineTypeItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LineType}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createLineTypeAdapter() {
		if (lineTypeItemProvider == null) {
			lineTypeItemProvider = new LineTypeItemProvider(this);
		}

		return lineTypeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LineInstance} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected LineInstanceItemProvider lineInstanceItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LineInstance}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createLineInstanceAdapter() {
		if (lineInstanceItemProvider == null) {
			lineInstanceItemProvider = new LineInstanceItemProvider(this);
		}

		return lineInstanceItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LinePropertySetter} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected LinePropertySetterItemProvider linePropertySetterItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.LinePropertySetter}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createLinePropertySetterAdapter() {
		if (linePropertySetterItemProvider == null) {
			linePropertySetterItemProvider = new LinePropertySetterItemProvider(this);
		}

		return linePropertySetterItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.FontPropertySetter} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected FontPropertySetterItemProvider fontPropertySetterItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.FontPropertySetter}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createFontPropertySetterAdapter() {
		if (fontPropertySetterItemProvider == null) {
			fontPropertySetterItemProvider = new FontPropertySetterItemProvider(this);
		}

		return fontPropertySetterItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.FontInstance} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected FontInstanceItemProvider fontInstanceItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.FontInstance}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createFontInstanceAdapter() {
		if (fontInstanceItemProvider == null) {
			fontInstanceItemProvider = new FontInstanceItemProvider(this);
		}

		return fontInstanceItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.FontType} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected FontTypeItemProvider fontTypeItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.FontType}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createFontTypeAdapter() {
		if (fontTypeItemProvider == null) {
			fontTypeItemProvider = new FontTypeItemProvider(this);
		}

		return fontTypeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.IsVisiblePropertySetter} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected IsVisiblePropertySetterItemProvider isVisiblePropertySetterItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.IsVisiblePropertySetter}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createIsVisiblePropertySetterAdapter() {
		if (isVisiblePropertySetterItemProvider == null) {
			isVisiblePropertySetterItemProvider = new IsVisiblePropertySetterItemProvider(this);
		}

		return isVisiblePropertySetterItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.TopLayerOperatorDescriptor} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected TopLayerOperatorDescriptorItemProvider topLayerOperatorDescriptorItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.TopLayerOperatorDescriptor}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createTopLayerOperatorDescriptorAdapter() {
		if (topLayerOperatorDescriptorItemProvider == null) {
			topLayerOperatorDescriptorItemProvider = new TopLayerOperatorDescriptorItemProvider(this);
		}

		return topLayerOperatorDescriptorItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.StackedLayerOperatorDescriptor} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected StackedLayerOperatorDescriptorItemProvider stackedLayerOperatorDescriptorItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.StackedLayerOperatorDescriptor}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createStackedLayerOperatorDescriptorAdapter() {
		if (stackedLayerOperatorDescriptorItemProvider == null) {
			stackedLayerOperatorDescriptorItemProvider = new StackedLayerOperatorDescriptorItemProvider(this);
		}

		return stackedLayerOperatorDescriptorItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.CustomPropertyOperator} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected CustomPropertyOperatorItemProvider customPropertyOperatorItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.CustomPropertyOperator}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createCustomPropertyOperatorAdapter() {
		if (customPropertyOperatorItemProvider == null) {
			customPropertyOperatorItemProvider = new CustomPropertyOperatorItemProvider(this);
		}

		return customPropertyOperatorItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.AndStackedLayerOperatorDescriptor} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected AndStackedLayerOperatorDescriptorItemProvider andStackedLayerOperatorDescriptorItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.AndStackedLayerOperatorDescriptor}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createAndStackedLayerOperatorDescriptorAdapter() {
		if (andStackedLayerOperatorDescriptorItemProvider == null) {
			andStackedLayerOperatorDescriptorItemProvider = new AndStackedLayerOperatorDescriptorItemProvider(this);
		}

		return andStackedLayerOperatorDescriptorItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.OrStackedLayerOperatorDescriptor} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected OrStackedLayerOperatorDescriptorItemProvider orStackedLayerOperatorDescriptorItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.OrStackedLayerOperatorDescriptor}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createOrStackedLayerOperatorDescriptorAdapter() {
		if (orStackedLayerOperatorDescriptorItemProvider == null) {
			orStackedLayerOperatorDescriptorItemProvider = new OrStackedLayerOperatorDescriptorItemProvider(this);
		}

		return orStackedLayerOperatorDescriptorItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.IsAbstractUmlSetter} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected IsAbstractUmlSetterItemProvider isAbstractUmlSetterItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.IsAbstractUmlSetter}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createIsAbstractUmlSetterAdapter() {
		if (isAbstractUmlSetterItemProvider == null) {
			isAbstractUmlSetterItemProvider = new IsAbstractUmlSetterItemProvider(this);
		}

		return isAbstractUmlSetterItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.AllViewsDerivedLayer} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected AllViewsDerivedLayerItemProvider allViewsDerivedLayerItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.AllViewsDerivedLayer}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createAllViewsDerivedLayerAdapter() {
		if (allViewsDerivedLayerItemProvider == null) {
			allViewsDerivedLayerItemProvider = new AllViewsDerivedLayerItemProvider(this);
		}

		return allViewsDerivedLayerItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.CSSPropertySetter} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected CSSPropertySetterItemProvider cssPropertySetterItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.CSSPropertySetter}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createCSSPropertySetterAdapter() {
		if (cssPropertySetterItemProvider == null) {
			cssPropertySetterItemProvider = new CSSPropertySetterItemProvider(this);
		}

		return cssPropertySetterItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.CSSType} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected CSSTypeItemProvider cssTypeItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.CSSType}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createCSSTypeAdapter() {
		if (cssTypeItemProvider == null) {
			cssTypeItemProvider = new CSSTypeItemProvider(this);
		}

		return cssTypeItemProvider;
	}

	/**
	 * This keeps track of the one adapter used for all {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.CSSInstance} instances.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected CSSInstanceItemProvider cssInstanceItemProvider;

	/**
	 * This creates an adapter for a {@link org.eclipse.papyrus.internal.infra.gmfdiag.layers.model.layers.CSSInstance}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter createCSSInstanceAdapter() {
		if (cssInstanceItemProvider == null) {
			cssInstanceItemProvider = new CSSInstanceItemProvider(this);
		}

		return cssInstanceItemProvider;
	}

	/**
	 * This returns the root adapter factory that contains this factory.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public ComposeableAdapterFactory getRootAdapterFactory() {
		return parentAdapterFactory == null ? this : parentAdapterFactory.getRootAdapterFactory();
	}

	/**
	 * This sets the composed adapter factory that contains this factory.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setParentAdapterFactory(ComposedAdapterFactory parentAdapterFactory) {
		this.parentAdapterFactory = parentAdapterFactory;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean isFactoryForType(Object type) {
		return supportedTypes.contains(type) || super.isFactoryForType(type);
	}

	/**
	 * This implementation substitutes the factory itself as the key for the adapter.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Adapter adapt(Notifier notifier, Object type) {
		return super.adapt(notifier, this);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object adapt(Object object, Object type) {
		if (isFactoryForType(type)) {
			Object adapter = super.adapt(object, type);
			if (!(type instanceof Class<?>) || (((Class<?>)type).isInstance(adapter))) {
				return adapter;
			}
		}

		return null;
	}

	/**
	 * This adds a listener.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void addListener(INotifyChangedListener notifyChangedListener) {
		changeNotifier.addListener(notifyChangedListener);
	}

	/**
	 * This removes a listener.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void removeListener(INotifyChangedListener notifyChangedListener) {
		changeNotifier.removeListener(notifyChangedListener);
	}

	/**
	 * This delegates to {@link #changeNotifier} and to {@link #parentAdapterFactory}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void fireNotifyChanged(Notification notification) {
		changeNotifier.fireNotifyChanged(notification);

		if (parentAdapterFactory != null) {
			parentAdapterFactory.fireNotifyChanged(notification);
		}
	}

	/**
	 * This disposes all of the item providers created by this factory. 
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void dispose() {
		if (layerNamedStyleItemProvider != null) layerNamedStyleItemProvider.dispose();
		if (layersStackItemProvider != null) layersStackItemProvider.dispose();
		if (layersStackApplicationItemProvider != null) layersStackApplicationItemProvider.dispose();
		if (layerStackDescriptorRegistryItemProvider != null) layerStackDescriptorRegistryItemProvider.dispose();
		if (propertyRegistryItemProvider != null) propertyRegistryItemProvider.dispose();
		if (propertyItemProvider != null) propertyItemProvider.dispose();
		if (metamodelItemProvider != null) metamodelItemProvider.dispose();
		if (typeRegistryItemProvider != null) typeRegistryItemProvider.dispose();
		if (stringToTypeMapItemProvider != null) stringToTypeMapItemProvider.dispose();
		if (layerDescriptorRegistryItemProvider != null) layerDescriptorRegistryItemProvider.dispose();
		if (layerDescriptorItemProvider != null) layerDescriptorItemProvider.dispose();
		if (layerApplicationFactoryItemProvider != null) layerApplicationFactoryItemProvider.dispose();
		if (propertySetterRegistryItemProvider != null) propertySetterRegistryItemProvider.dispose();
		if (stringToPropertySetterItemProvider != null) stringToPropertySetterItemProvider.dispose();
		if (layerOperatorDescriptorRegistryItemProvider != null) layerOperatorDescriptorRegistryItemProvider.dispose();
		if (layerOperatorDescriptorItemProvider != null) layerOperatorDescriptorItemProvider.dispose();
		if (propertyOperatorItemProvider != null) propertyOperatorItemProvider.dispose();
		if (defaultPropertyOperatorItemProvider != null) defaultPropertyOperatorItemProvider.dispose();
		if (stringToTypeInstanceMapItemProvider != null) stringToTypeInstanceMapItemProvider.dispose();
		if (folderItemProvider != null) folderItemProvider.dispose();
		if (intInstanceItemProvider != null) intInstanceItemProvider.dispose();
		if (booleanInstanceItemProvider != null) booleanInstanceItemProvider.dispose();
		if (stringInstanceItemProvider != null) stringInstanceItemProvider.dispose();
		if (intTypeItemProvider != null) intTypeItemProvider.dispose();
		if (booleanTypeItemProvider != null) booleanTypeItemProvider.dispose();
		if (stringTypeItemProvider != null) stringTypeItemProvider.dispose();
		if (customTypeItemProvider != null) customTypeItemProvider.dispose();
		if (topLayerOperatorItemProvider != null) topLayerOperatorItemProvider.dispose();
		if (stackedLayerOperatorItemProvider != null) stackedLayerOperatorItemProvider.dispose();
		if (customLayerOperatorItemProvider != null) customLayerOperatorItemProvider.dispose();
		if (propertyIndexItemProvider != null) propertyIndexItemProvider.dispose();
		if (stringToPropertyIndexMapItemProvider != null) stringToPropertyIndexMapItemProvider.dispose();
		if (simpleLayerDescriptorItemProvider != null) simpleLayerDescriptorItemProvider.dispose();
		if (regExpLayerDescriptorItemProvider != null) regExpLayerDescriptorItemProvider.dispose();
		if (nullInstanceItemProvider != null) nullInstanceItemProvider.dispose();
		if (regExpLayerItemProvider != null) regExpLayerItemProvider.dispose();
		if (layerItemProvider != null) layerItemProvider.dispose();
		if (colorItemProvider != null) colorItemProvider.dispose();
		if (colorInstanceItemProvider != null) colorInstanceItemProvider.dispose();
		if (fillInstanceItemProvider != null) fillInstanceItemProvider.dispose();
		if (fillItemProvider != null) fillItemProvider.dispose();
		if (fillPropertySetterItemProvider != null) fillPropertySetterItemProvider.dispose();
		if (isValidPropertySetterItemProvider != null) isValidPropertySetterItemProvider.dispose();
		if (nullPropertySetterItemProvider != null) nullPropertySetterItemProvider.dispose();
		if (lineTypeItemProvider != null) lineTypeItemProvider.dispose();
		if (lineInstanceItemProvider != null) lineInstanceItemProvider.dispose();
		if (linePropertySetterItemProvider != null) linePropertySetterItemProvider.dispose();
		if (fontPropertySetterItemProvider != null) fontPropertySetterItemProvider.dispose();
		if (fontInstanceItemProvider != null) fontInstanceItemProvider.dispose();
		if (fontTypeItemProvider != null) fontTypeItemProvider.dispose();
		if (isVisiblePropertySetterItemProvider != null) isVisiblePropertySetterItemProvider.dispose();
		if (topLayerOperatorDescriptorItemProvider != null) topLayerOperatorDescriptorItemProvider.dispose();
		if (stackedLayerOperatorDescriptorItemProvider != null) stackedLayerOperatorDescriptorItemProvider.dispose();
		if (customPropertyOperatorItemProvider != null) customPropertyOperatorItemProvider.dispose();
		if (andStackedLayerOperatorDescriptorItemProvider != null) andStackedLayerOperatorDescriptorItemProvider.dispose();
		if (orStackedLayerOperatorDescriptorItemProvider != null) orStackedLayerOperatorDescriptorItemProvider.dispose();
		if (isAbstractUmlSetterItemProvider != null) isAbstractUmlSetterItemProvider.dispose();
		if (allViewsDerivedLayerItemProvider != null) allViewsDerivedLayerItemProvider.dispose();
		if (cssPropertySetterItemProvider != null) cssPropertySetterItemProvider.dispose();
		if (cssTypeItemProvider != null) cssTypeItemProvider.dispose();
		if (cssInstanceItemProvider != null) cssInstanceItemProvider.dispose();
	}

}
