/*******************************************************************************
 * Copyright (c) 2005 Oracle Corporation.
 * 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:
 *    Ian Trimble - initial API and implementation
 *******************************************************************************/ 
package org.eclipse.jst.jsf.core.jsfappconfig;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EContentAdapter;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.facesconfig.emf.ApplicationType;
import org.eclipse.jst.jsf.facesconfig.emf.FacesConfigType;
import org.eclipse.jst.jsf.facesconfig.emf.FromViewIdType;
import org.eclipse.jst.jsf.facesconfig.emf.NavigationRuleType;
import org.eclipse.jst.jsf.facesconfig.emf.PropertyResolverType;
import org.eclipse.jst.jsf.facesconfig.emf.VariableResolverType;

/**
 * JSFAppConfigManager provides an entry point to an entire JSF application
 * configuration, which is defined in one or more application configuration
 * resource files.
 * 
 * <p><b>Provisional API - subject to change</b></p>
 * 
 * @author Ian Trimble - Oracle
 */
public class JSFAppConfigManager implements IResourceChangeListener {

	/**
	 * Key that is used for the IProject instance's session property that
	 * holds a JSFAppConfigManager instance.
	 */
	public static final QualifiedName KEY_SESSIONPROPERTY =
		new QualifiedName(JSFCorePlugin.PLUGIN_ID, "JSFAppConfigManager"); //$NON-NLS-1$

	/**
	 * IProject instance to which this JSFAppConfigManager instance is keyed.
	 */
	protected IProject project = null;

	/**
	 * Collection of {@link IJSFAppConfigLocater} instances.
	 */
	protected List configLocaters = null;

	/**
	 * Collection of {@link IJSFAppConfigProvidersChangeListener} instances.
	 */
	protected List configProvidersChangeListeners = null;

	/**
	 * Map of application configuration model EMF classes to
	 * {@link IFacesConfigChangeListener} instances.
	 */
	protected Map facesConfigChangeListeners = null;

	/**
	 * Single {@link FacesConfigChangeAdapter} instance.
	 */
	protected FacesConfigChangeAdapter facesConfigChangeAdapter = null;

	/**
	 * Gets a JSFAppConfigManager instance that is keyed to the passed IProject
	 * parameter. May return null if the project is not valid or if a
	 * CoreException is thrown while attempting to get or set the instance as
	 * a session property.
	 * 
	 * @param project IProject instance to which the returned
	 * JSFAppConfigManager instance is keyed.
	 * @return JSFAppConfigManager instance, or null.
	 */
	public static synchronized JSFAppConfigManager getInstance(IProject project) {
		JSFAppConfigManager manager = null;
		if (JSFAppConfigUtils.isValidJSFProject(project)) {
			manager = getFromSessionProperty(project);
			if (manager == null) {
				manager = new JSFAppConfigManager(project);
			}
		}
		return manager;
	}

	/**
	 * Attempts to get a JSFAppConfigManager instance from a session property
	 * of the passed IProject instance. Will return null if the session
	 * property has not yet been set.
	 * 
	 * @param project IProject instance from which to retrieve the
	 * JSFAppConfigManager instance.
	 * @return JSFAppConfigManager instance, or null.
	 */
	protected static JSFAppConfigManager getFromSessionProperty(IProject project) {
		JSFAppConfigManager manager = null;
		try {
			Object obj = project.getSessionProperty(KEY_SESSIONPROPERTY);
			if (obj instanceof JSFAppConfigManager) {
				manager = (JSFAppConfigManager)obj;
			}
		} catch(CoreException ce) {
			//log error
			JSFCorePlugin.log(IStatus.ERROR, ce.getLocalizedMessage(), ce);
		}
		return manager;
	}

	/**
	 * Sets this JSFAppConfigManager instance as a session property of its
	 * IProject instance.
	 */
	protected void setAsSessionProperty() {
		if (project != null && project.isAccessible()) {
			try {
				project.setSessionProperty(KEY_SESSIONPROPERTY, this);
			} catch(CoreException ce) {
				//log error
				JSFCorePlugin.log(IStatus.ERROR, ce.getLocalizedMessage(), ce);
			}
		}
	}

	/**
	 * Unsets this JSFAppConfigManager instance as a session property of its
	 * IProject instance.
	 */
	protected void unsetAsSessionProperty() {
		if (project != null && project.isAccessible()) {
			try {
				project.setSessionProperty(KEY_SESSIONPROPERTY, null);
			} catch(CoreException ce) {
				//log error
				JSFCorePlugin.log(IStatus.ERROR, ce.getLocalizedMessage(), ce);
			}
		}
	}

	/**
	 * Constructor is private to prevent direct instantiation; call
	 * getInstance(IProject).
	 * 
	 * @param project IProject instance to which the new JSFAppConfigManager
	 * instance is keyed.
	 */
	private JSFAppConfigManager(IProject project) {
		this.project = project;
		initialize();
	}

	/**
	 * Gets this instance's IProject instance.
	 * 
	 * @return This instance's IProject instance.
	 */
	public IProject getProject() {
		return project;
	}

	/**
	 * Initializes instance by:
	 * <ul>
	 *  <li>creating facesConfigChangeListeners collection, </li>
	 * 	<li>creating configProvidersChangeListeners collection, </li>
	 * 	<li>creating and populating configLocaters collection, </li>
	 * 	<li>invoking the startLocating() method on all configLocaters, </li>
	 * 	<li>setting instance as a session property of the IProject instance, </li>
	 *  <li>adding a resource change listener to the workspace.</li>
	 * </ul>
	 */
	protected void initialize() {
		//create collections
		facesConfigChangeListeners = new HashMap();
		configProvidersChangeListeners = new ArrayList();
		configLocaters = new ArrayList();
		//populate initial set of locaters
		populateConfigLocaters();
		//instruct locaters to start locating
		startConfigLocaters();
		//set as session property of project
		setAsSessionProperty();
		//add resource change listener
		IWorkspace workspace = ResourcesPlugin.getWorkspace();
		workspace.addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE | IResourceChangeEvent.PRE_CLOSE | IResourceChangeEvent.PRE_DELETE);
	}

	/**
	 * Populates configLocaters Set with "built-in" set of
	 * {@link IJSFAppConfigLocater} implementations.
	 */
	protected void populateConfigLocaters() {
		//implicit runtime-provided configuration
		IJSFAppConfigLocater implicitRuntimeConfigLocater = new ImplicitRuntimeJSFAppConfigLocater();
		implicitRuntimeConfigLocater.setJSFAppConfigManager(this);
		configLocaters.add(implicitRuntimeConfigLocater);
		//default ("/WEB-INF/faces-config.xml") locater
		IJSFAppConfigLocater defaultConfigLocater = new DefaultJSFAppConfigLocater();
		defaultConfigLocater.setJSFAppConfigManager(this);
		configLocaters.add(defaultConfigLocater);
		//web.xml context-parameter specified locater
		IJSFAppConfigLocater contextParamConfigLocater = new ContextParamSpecifiedJSFAppConfigLocater();
		contextParamConfigLocater.setJSFAppConfigManager(this);
		configLocaters.add(contextParamConfigLocater);
		//runtime classpath locater
		IJSFAppConfigLocater classpathConfigLocater = new RuntimeClasspathJSFAppConfigLocater();
		classpathConfigLocater.setJSFAppConfigManager(this);
		configLocaters.add(classpathConfigLocater);
	}

	/**
	 * Instructs set of {@link IJSFAppConfigLocater} instances to start
	 * locating JSF application configuration resources.
	 */
	protected void startConfigLocaters() {
		Iterator itConfigLocaters = configLocaters.iterator();
		while (itConfigLocaters.hasNext()) {
			IJSFAppConfigLocater configLocater = (IJSFAppConfigLocater)itConfigLocaters.next();
			configLocater.startLocating();
		}
	}

	/**
	 * Instructs set of {@link IJSFAppConfigLocater} instances to stop
	 * locating JSF application configuration resources.
	 */
	protected void stopConfigLocaters() {
		Iterator itConfigLocaters = configLocaters.iterator();
		while (itConfigLocaters.hasNext()) {
			IJSFAppConfigLocater configLocater = (IJSFAppConfigLocater)itConfigLocaters.next();
			configLocater.stopLocating();
			configLocater.dispose();
		}
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
	 */
	public void resourceChanged(IResourceChangeEvent event) {
        if (event.getType() == IResourceChangeEvent.PRE_CLOSE
                || event.getType() == IResourceChangeEvent.PRE_DELETE) {
            // a project is closing - release and cleanup
            final IProject aProject = (IProject) event.getResource();
            if (aProject != null && aProject.equals(this.project)) {
                SafeRunnable.run(new ISafeRunnable() {

                    public void handleException(Throwable exception) {
                        JSFCorePlugin.log("Unexpected Program Error: disposing resources", exception); //$NON-NLS-1$
                    }

                    public void run() throws Exception {
                        dispose();
                    }
                });

                return;
            }
        }

	    IResourceDelta delta = event.getDelta();
		if (delta != null && delta.getKind() == IResourceDelta.CHANGED) {
			IResourceDelta[] removedDeltas = delta.getAffectedChildren(IResourceDelta.REMOVED);
			if (removedDeltas.length == 1) {
				IResourceDelta removedDelta = removedDeltas[0];
				IResource removedResource = removedDelta.getResource();
				if (removedResource != null && removedResource == project) {
					IResourceDelta[] addedDeltas = delta.getAffectedChildren(IResourceDelta.ADDED);
					if (addedDeltas.length == 1) {
						IResourceDelta addedDelta = addedDeltas[0];
						IResource addedResource = addedDelta.getResource();
						if (addedResource instanceof IProject) {
							changeProject((IProject)addedResource);
						}
					}
				}
			}
		}
	}

	/**
	 * Called to respond to a change in the IProject instance to which this
	 * instance belongs. Changes the cached IProject instance, stops all config
	 * locaters, starts all config locaters.
	 * 
	 * @param newProject New IProject instance to which this manager belongs.
	 */
	protected void changeProject(IProject newProject) {
		this.project = newProject;
		stopConfigLocaters();
		startConfigLocaters();
	}

	/**
	 * Adds an instance of {@link IJSFAppConfigProvidersChangeListener}.
	 * 
	 * @param listener An instance of {@link IJSFAppConfigProvidersChangeListener}.
	 * @return true if added, else false.
	 */
	public boolean addJSFAppConfigProvidersChangeListener(IJSFAppConfigProvidersChangeListener listener) {
		return configProvidersChangeListeners.add(listener);
	}

	/**
	 * Removes an instance of {@link IJSFAppConfigProvidersChangeListener}.
	 * 
	 * @param listener an instance of {@link IJSFAppConfigProvidersChangeListener}.
	 * @return true if removed, else false.
	 */
	public boolean removeJSFAppConfigProvidersChangeListener(IJSFAppConfigProvidersChangeListener listener) {
		return configProvidersChangeListeners.remove(listener);
	}

	/**
	 * Notifies all {@link IJSFAppConfigProvidersChangeListener} instances of
	 * a change in the Set of {@link IJSFAppConfigProvider} instances.
	 * 
	 * @param configProvider {@link IJSFAppConfigProvider} instance that has
	 * changed.
	 * @param eventType Event type.
	 */
	public void notifyJSFAppConfigProvidersChangeListeners(IJSFAppConfigProvider configProvider, int eventType) {
		JSFAppConfigProvidersChangeEvent event = new JSFAppConfigProvidersChangeEvent(configProvider, eventType);
		Iterator itListeners = configProvidersChangeListeners.iterator();
		while (itListeners.hasNext()) {
			IJSFAppConfigProvidersChangeListener listener =
				(IJSFAppConfigProvidersChangeListener)itListeners.next();
			listener.changedJSFAppConfigProviders(event);
		}
	}

	/**
	 * Adds an instance of {@link IFacesConfigChangeListener}. <br>
	 * <br>
	 * <b>NOTE:</b> Calling this method will cause all application
	 * configuration models to be loaded, to ensure that a
	 * {@link FacesConfigChangeAdapter} has been added to each model.
	 * 
	 * @param emfClass EMF class in which the listener is interested.
	 * @param listener {@link IFacesConfigChangeListener} instance.
	 * @return Previous {@link IFacesConfigChangeListener}, or null.
	 */
	public Object addFacesConfigChangeListener(Class emfClass, IFacesConfigChangeListener listener) {
		/* 
		 * Get all models, which will ensure that each one has had a
		 * FacesConfigChangeAdapter added to it.
		 */
		getFacesConfigModels();
		return facesConfigChangeListeners.put(emfClass, listener);
	}

	/**
	 * Removes an instance of {@link IFacesConfigChangeListener}.
	 * 
	 * @param emfClass EMF class in which the listener was interested.
	 * @return Removed {@link IFacesConfigChangeListener}, or null.
	 */
	public Object removeFacesConfigChangeListener(Class emfClass) {
		return facesConfigChangeListeners.remove(emfClass);
	}

	/**
	 * Notifies {@link IFacesConfigChangeListener} instances of model changes
	 * in which they registered interest.
	 * 
	 * @param notification EMF {@link Notification} instance that describes the
	 * model change.
	 */
	public void notifyFacesConfigChangeListeners(Notification notification) {
		Object emfFeature = notification.getFeature();
		if (emfFeature instanceof EStructuralFeature) {
			Class emfClass = ((EStructuralFeature)emfFeature).getEType().getInstanceClass();
			IFacesConfigChangeListener listener = (IFacesConfigChangeListener)facesConfigChangeListeners.get(emfClass);
			if (listener != null) {
				listener.notifyChanged(notification);
			}
		}
	}

	/**
	 * Gets all {@link IJSFAppConfigProvider} instances from all
	 * {@link IJSFAppConfigLocater} instances.
	 * 
	 * @return Set of all {@link IJSFAppConfigProvider} instances.
	 */
	public Set getJSFAppConfigProviders() {
		Set allConfigProviders = new LinkedHashSet();
		Iterator itConfigLocaters = configLocaters.iterator();
		while (itConfigLocaters.hasNext()) {
			IJSFAppConfigLocater configLocater = (IJSFAppConfigLocater)itConfigLocaters.next();
			allConfigProviders.addAll(configLocater.getJSFAppConfigProviders());
		}
		return allConfigProviders;
	}

	/**
	 * Gets all {@link FacesConfigType} instances from all
	 * {@link IJSFAppConfigProvider} instances.
	 * 
	 * @return List of all {@link FacesConfigType} instances.
	 */
	public List getFacesConfigModels() {
		List facesConfigModels = new ArrayList();
		Iterator itConfigProviders = getJSFAppConfigProviders().iterator();
		while (itConfigProviders.hasNext()) {
			IJSFAppConfigProvider configProvider = (IJSFAppConfigProvider)itConfigProviders.next();
			FacesConfigType facesConfig = configProvider.getFacesConfigModel();
			if (facesConfig != null) {
				facesConfigModels.add(facesConfig);
			}
		}
		return facesConfigModels;
	}

    /**
     * Disposes of resources by:
     * <ul>
     *  <li>removing a resource change listener to the workspace</li>
     *  <li>removing instance as a session property of the IProject instance</li>
     *  <li>invoking the stopLocating() method on all configLocaters</li>
     *  <li>clearing the configLocaters collection</li>
     *  <li>clearing the configProvidersChangeListeners collection</li>
     *  <li>clearing the facesConfigChangeListeners collection</li>
     * </ul>
     */
    protected void dispose() {
        //remove resource change listener
        IWorkspace workspace = ResourcesPlugin.getWorkspace();
        workspace.removeResourceChangeListener(this);
        //remove session property from project
        unsetAsSessionProperty();
        //instruct locaters to stop locating
        stopConfigLocaters();
        //clear collections
        configLocaters.clear();
        configProvidersChangeListeners.clear();
        facesConfigChangeListeners.clear();
    }

	/**
	 * Gets list of all ManagedBeanType instances from all known faces-config
	 * models; list may be empty.
	 * 
	 * @return List of all ManagedBeanType instances from all known
	 * faces-config models (list may be empty).
	 */
	public List getManagedBeans() {
		List allManagedBeans = new ArrayList();
		List facesConfigs = getFacesConfigModels();
		Iterator itFacesConfigs = facesConfigs.iterator();
		while (itFacesConfigs.hasNext()) {
			FacesConfigType facesConfig = (FacesConfigType)itFacesConfigs.next();
			EList managedBeans = facesConfig.getManagedBean();
			allManagedBeans.addAll(managedBeans);
		}
		return allManagedBeans;
    }

    /**
     * @return List of all variable resolver class names registered. 
     */
    public final List<String> getPropertyResolvers()
    {
        final List<String> allPropertyResolvers = new ArrayList<String>();
        final List applications = getApplications();
        final Iterator appIterator = applications.iterator();
        while (appIterator.hasNext())
        {
            final ApplicationType  application = (ApplicationType) appIterator.next();
            for (final Iterator it = application.getPropertyResolver().iterator(); it.hasNext();)
            {
                final PropertyResolverType propRes = (PropertyResolverType) it.next();
                String propClass = propRes.getTextContent();
                if (propClass != null)
                {
                    propClass = propClass.trim();
                    if (!"".equals(propClass)) //$NON-NLS-1$
                    {
                        allPropertyResolvers.add(propClass);
                    }
                }
            }
        }
        return allPropertyResolvers;
	}

	/**
	 * Gets list of all ValidatorType instances from all known faces-config
	 * models; list may be empty.
	 * 
	 * @return List of all ValidatorType instances from all known faces-config
	 * models (list may be empty).
	 */
	public List getValidators() {
		List allValidators = new ArrayList();
		List facesConfigs = getFacesConfigModels();
		Iterator itFacesConfigs = facesConfigs.iterator();
		while (itFacesConfigs.hasNext()) {
			FacesConfigType facesConfig = (FacesConfigType)itFacesConfigs.next();
			EList validators = facesConfig.getValidator();
			allValidators.addAll(validators);
		}
		return allValidators;
	}

	/**
	 * @return List of all variable resolver class names registered. 
	 */
	public final List<String> getVariableResolvers()
    {
        final List<String> allVariableResolvers = new ArrayList<String>();
        final List applications = getApplications();
        final Iterator appIterator = applications.iterator();
        while (appIterator.hasNext())
        {
            final ApplicationType  application = (ApplicationType) appIterator.next();
            for (final Iterator it = application.getVariableResolver().iterator(); it.hasNext();)
            {
                final VariableResolverType varRes = (VariableResolverType) it.next();
                String varClass = varRes.getTextContent();
                if (varClass != null)
                {
                    varClass = varClass.trim();
                    if (!"".equals(varClass)) //$NON-NLS-1$
                    {
                        allVariableResolvers.add(varClass);
                    }
                }
            }
        }
        return allVariableResolvers;
    }

	/**
	 * Gets list of all ConverterType instances from all known faces-config
	 * models; list may be empty.
	 * 
	 * @return List of all ConverterType instances from all known faces-config
	 * models (list may be empty).
	 */
	public List getConverters() {
		List allConverters = new ArrayList();
		List facesConfigs = getFacesConfigModels();
		Iterator itFacesConfigs = facesConfigs.iterator();
		while (itFacesConfigs.hasNext()) {
			FacesConfigType facesConfig = (FacesConfigType)itFacesConfigs.next();
			EList converters = facesConfig.getConverter();
			allConverters.addAll(converters);
		}
		return allConverters;
	}

	/**
	 * Gets list of all NavigationRuleType instances from all known
	 * faces-config models; list may be empty.
	 * 
	 * @return List of all NavigationRuleType instances from all known
	 * faces-config models (list may be empty).
	 */
	public List getNavigationRules() {
		List allNavigationRules = new ArrayList();
		List facesConfigs = getFacesConfigModels();
		Iterator itFacesConfigs = facesConfigs.iterator();
		while (itFacesConfigs.hasNext()) {
			FacesConfigType facesConfig = (FacesConfigType)itFacesConfigs.next();
			EList navigationRules = facesConfig.getNavigationRule();
			allNavigationRules.addAll(navigationRules);
		}
		return allNavigationRules;
	}

	/**
	 * Gets list of all NavigationRuleType instances from all known
	 * faces-config models where the navigation-rule's from-view-id value
	 * matches the web content folder-relative value of the passed IFile
	 * instance; list may be empty. Matching is performed in the same manner
	 * as for a JSF implementation's default NavigationHandler.
	 * 
	 * @param pageFile IFile instance to match against the from-view-id value
	 * of all NavigationRuleType instances. File is assumed to be relative to
	 * the web content folder, but may be expressed in a more complete form;
	 * its path will be calculated relative to the web content folder.
	 * @return List of all NavigationRuleType instances from all known
	 * faces-config models where the navigation-rule's from-view-id value
	 * matches the web content folder-relative value of the passed IFile
	 * instance (list may be empty).
	 */
	public List getNavigationRulesForPage(IFile pageFile) {
		List navigationRulesForPage = new ArrayList();
		IPath pageFilePath = JSFAppConfigUtils.getWebContentFolderRelativePath(pageFile);
		if (pageFilePath != null) {
			String pageFileString = pageFilePath.toString();
			if (!pageFileString.startsWith("/")) { //$NON-NLS-1$
				pageFileString = "/" + pageFileString; //$NON-NLS-1$
			}
			List navigationRules = getNavigationRules();
			Iterator itNavigationRules = navigationRules.iterator();
			while (itNavigationRules.hasNext()) {
				NavigationRuleType navigationRule = (NavigationRuleType)itNavigationRules.next();
				FromViewIdType fromViewIdType = navigationRule.getFromViewId();
				if (fromViewIdType != null) {
					String fromViewId = fromViewIdType.getTextContent();
					if (fromViewId != null && fromViewId.length() > 0) {
						if (!fromViewId.equals("*")) { //$NON-NLS-1$
							if (fromViewId.equals(pageFileString)) {
								//exact match
								navigationRulesForPage.add(navigationRule);
							} else if (fromViewId.endsWith("*")) { //$NON-NLS-1$
								String prefixFromViewId = fromViewId.substring(0, fromViewId.length() - 1);
								if (pageFileString.startsWith(prefixFromViewId)) {
									//prefix match
									navigationRulesForPage.add(navigationRule);
								}
							}
						} else {
							//from-view-id == "*" - matches all pages
							navigationRulesForPage.add(navigationRule);
						}
					}
				} else {
					//no from-view-id element - matches all pages
					navigationRulesForPage.add(navigationRule);
				}
			}
		}
		return navigationRulesForPage;
	}

	/**
	 * Gets list of all ApplicationType instances from all known
	 * faces-config models; list may be empty.
	 * 
	 * @return List of all ApplicationType instances from all known
	 * faces-config models (list may be empty).
	 */
	public List getApplications() {
		List allApplications = new ArrayList();
		List facesConfigs = getFacesConfigModels();
		Iterator itFacesConfigs = facesConfigs.iterator();
		while (itFacesConfigs.hasNext()) {
			FacesConfigType facesConfig = (FacesConfigType)itFacesConfigs.next();
			EList applications = facesConfig.getApplication();
			allApplications.addAll(applications);
		}
		return allApplications;
	}

	/**
	 * Gets list of all FactoryType instances from all known faces-config
	 * models; list may be empty.
	 * 
	 * @return List of all FactoryType instances from all known faces-config
	 * models (list may be empty).
	 */
	public List getFactories() {
		List allFactories = new ArrayList();
		List facesConfigs = getFacesConfigModels();
		Iterator itFacesConfigs = facesConfigs.iterator();
		while (itFacesConfigs.hasNext()) {
			FacesConfigType facesConfig = (FacesConfigType)itFacesConfigs.next();
			EList factories = facesConfig.getFactory();
			allFactories.addAll(factories);
		}
		return allFactories;
	}

	/**
	 * Gets list of all ComponentType instances from all known faces-config
	 * models; list may be empty.
	 * 
	 * @return List of all ComponentType instances from all known faces-config
	 * models (list may be empty).
	 */
	public List getComponents() {
		List allComponents = new ArrayList();
		List facesConfigs = getFacesConfigModels();
		Iterator itFacesConfigs = facesConfigs.iterator();
		while (itFacesConfigs.hasNext()) {
			FacesConfigType facesConfig = (FacesConfigType)itFacesConfigs.next();
			EList components = facesConfig.getComponent();
			allComponents.addAll(components);
		}
		return allComponents;
	}

	/**
	 * Gets list of all ReferencedBeanType instances from all known
	 * faces-config models; list may be empty.
	 * 
	 * @return List of all ReferencedBeanType instances from all known
	 * faces-config models (list may be empty).
	 */
	public List getReferencedBeans() {
		List allReferencedBeans = new ArrayList();
		List facesConfigs = getFacesConfigModels();
		Iterator itFacesConfigs = facesConfigs.iterator();
		while (itFacesConfigs.hasNext()) {
			FacesConfigType facesConfig = (FacesConfigType)itFacesConfigs.next();
			EList referencedBeans = facesConfig.getReferencedBean();
			allReferencedBeans.addAll(referencedBeans);
		}
		return allReferencedBeans;
	}

	/**
	 * Gets list of all RenderKitType instances from all known faces-config
	 * models; list may be empty.
	 * 
	 * @return List of all RenderKitType instances from all known faces-config
	 * models (list may be empty).
	 */
	public List getRenderKits() {
		List allRenderKits = new ArrayList();
		List facesConfigs = getFacesConfigModels();
		Iterator itFacesConfigs = facesConfigs.iterator();
		while (itFacesConfigs.hasNext()) {
			FacesConfigType facesConfig = (FacesConfigType)itFacesConfigs.next();
			EList renderKits = facesConfig.getRenderKit();
			allRenderKits.addAll(renderKits);
		}
		return allRenderKits;
	}

	/**
	 * Gets list of all LifecycleType instances from all known faces-config
	 * models; list may be empty.
	 * 
	 * @return List of all LifecycleType instances from all known faces-config
	 * models (list may be empty).
	 */
	public List getLifecycles() {
		List allLifecycles = new ArrayList();
		List facesConfigs = getFacesConfigModels();
		Iterator itFacesConfigs = facesConfigs.iterator();
		while (itFacesConfigs.hasNext()) {
			FacesConfigType facesConfig = (FacesConfigType)itFacesConfigs.next();
			EList lifecycles = facesConfig.getLifecycle();
			allLifecycles.addAll(lifecycles);
		}
		return allLifecycles;
	}

    /**
     * @return the list of all resource bundles declared in all the FacesConfig
     * configurations found.
     */
    public List getResourceBundles()
    {
        List allResourceBundles = new ArrayList();
        List facesConfigs = getFacesConfigModels();
        Iterator itFacesConfigs = facesConfigs.iterator();
        while (itFacesConfigs.hasNext()) {
            FacesConfigType facesConfig = (FacesConfigType)itFacesConfigs.next();
            for (final Iterator applicationIt = facesConfig.getApplication().iterator(); applicationIt.hasNext();)
            {
                ApplicationType appType = (ApplicationType) applicationIt.next();
                allResourceBundles.addAll(appType.getResourceBundle());
            }
        }
        return allResourceBundles;
    }
    
	/**
	 * Adds this instance's {@link FacesConfigChangeAdapter} instance to the
	 * passed application configuration model's adapters collection.
	 * 
	 * @param facesConfig Application configuration model's root object.
	 */
	public void addFacesConfigChangeAdapter(FacesConfigType facesConfig) {
		if (facesConfig != null) {
			if (facesConfigChangeAdapter == null) {
				facesConfigChangeAdapter = new FacesConfigChangeAdapter();
			}
			facesConfig.eAdapters().add(facesConfigChangeAdapter);
		}
	}

	/**
	 * Removes this instance's {@link FacesConfigChangeAdapter} instance from
	 * the passed application configuration model's adapters collection.
	 * 
	 * @param facesConfig Application configuration model's root object.
	 */
	public void removeFacesConfigChangeAdapter(FacesConfigType facesConfig) {
		if (facesConfig != null && facesConfigChangeAdapter != null) {
			facesConfig.eAdapters().remove(facesConfigChangeAdapter);
		}
	}

	/**
	 * FacesConfigChangeAdapter is an EMF adapter which provides a mechanism
	 * for notification of changes to features in any application configuration
	 * model for which {@link IFacesConfigChangeListener} instances have
	 * registered an interest.
	 * 
	 * @author Ian Trimble - Oracle
	 */
	class FacesConfigChangeAdapter extends EContentAdapter {
		/*
		 * (non-Javadoc)
		 * @see org.eclipse.emf.ecore.util.EContentAdapter#notifyChanged(org.eclipse.emf.common.notify.Notification)
		 */
		public void notifyChanged(Notification notification) {
			super.notifyChanged(notification);
			notifyFacesConfigChangeListeners(notification);
		}
	}

}
