/**
 * <copyright>
 * </copyright>
 *
 * $Id$
 */
package test.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 test.util.TestAdapterFactory;

/**
 * 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 TestItemProviderAdapterFactory extends TestAdapterFactory 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 TestItemProviderAdapterFactory() {
        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 test.TestSuite} instances.
     * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
     * @generated
     */
  protected TestSuiteItemProvider testSuiteItemProvider;

  /**
     * This creates an adapter for a {@link test.TestSuite}.
     * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
     * @generated
     */
  @Override
  public Adapter createTestSuiteAdapter() {
        if (testSuiteItemProvider == null) {
            testSuiteItemProvider = new TestSuiteItemProvider(this);
        }

        return testSuiteItemProvider;
    }

  /**
     * This keeps track of the one adapter used for all {@link test.ExceptionTestResult} instances.
     * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
     * @generated
     */
  protected ExceptionTestResultItemProvider exceptionTestResultItemProvider;

  /**
     * This creates an adapter for a {@link test.ExceptionTestResult}.
     * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
     * @generated
     */
  @Override
  public Adapter createExceptionTestResultAdapter() {
        if (exceptionTestResultItemProvider == null) {
            exceptionTestResultItemProvider = new ExceptionTestResultItemProvider(this);
        }

        return exceptionTestResultItemProvider;
    }

  /**
     * This keeps track of the one adapter used for all {@link test.ValidationErrorTestResult} instances.
     * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
     * @generated
     */
  protected ValidationErrorTestResultItemProvider validationErrorTestResultItemProvider;

  /**
     * This creates an adapter for a {@link test.ValidationErrorTestResult}.
     * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
     * @generated
     */
  @Override
  public Adapter createValidationErrorTestResultAdapter() {
        if (validationErrorTestResultItemProvider == null) {
            validationErrorTestResultItemProvider = new ValidationErrorTestResultItemProvider(this);
        }

        return validationErrorTestResultItemProvider;
    }

  /**
     * This keeps track of the one adapter used for all {@link test.ConsoleOutputTestResult} instances.
     * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
     * @generated
     */
  protected ConsoleOutputTestResultItemProvider consoleOutputTestResultItemProvider;

  /**
     * This creates an adapter for a {@link test.ConsoleOutputTestResult}.
     * <!-- begin-user-doc -->
   * <!-- end-user-doc -->
     * @generated
     */
  @Override
  public Adapter createConsoleOutputTestResultAdapter() {
        if (consoleOutputTestResultItemProvider == null) {
            consoleOutputTestResultItemProvider = new ConsoleOutputTestResultItemProvider(this);
        }

        return consoleOutputTestResultItemProvider;
    }

  /**
     * This keeps track of the one adapter used for all {@link test.EGFTestCase} instances.
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    protected EGFTestCaseItemProvider egfTestCaseItemProvider;

/**
     * This creates an adapter for a {@link test.EGFTestCase}.
     * <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     * @generated
     */
    @Override
    public Adapter createEGFTestCaseAdapter() {
        if (egfTestCaseItemProvider == null) {
            egfTestCaseItemProvider = new EGFTestCaseItemProvider(this);
        }

        return egfTestCaseItemProvider;
    }

/**
     * This keeps track of the one adapter used for all {@link test.FileOutputTestResult} instances.
     * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
     * @generated
     */
	protected FileOutputTestResultItemProvider fileOutputTestResultItemProvider;

/**
     * This creates an adapter for a {@link test.FileOutputTestResult}.
     * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
     * @generated
     */
	@Override
	public Adapter createFileOutputTestResultAdapter() {
        if (fileOutputTestResultItemProvider == null) {
            fileOutputTestResultItemProvider = new FileOutputTestResultItemProvider(this);
        }

        return fileOutputTestResultItemProvider;
    }

/**
     * 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 (testSuiteItemProvider != null) testSuiteItemProvider.dispose();
        if (exceptionTestResultItemProvider != null) exceptionTestResultItemProvider.dispose();
        if (validationErrorTestResultItemProvider != null) validationErrorTestResultItemProvider.dispose();
        if (consoleOutputTestResultItemProvider != null) consoleOutputTestResultItemProvider.dispose();
        if (egfTestCaseItemProvider != null) egfTestCaseItemProvider.dispose();
        if (fileOutputTestResultItemProvider != null) fileOutputTestResultItemProvider.dispose();
    }

}
