/*******************************************************************************
 * 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.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.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);
	}

	/**
	 * 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();
		}
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
	 */
	public void resourceChanged(IResourceChangeEvent event) {
		IResourceDelta delta = event.getDelta();
		if (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;
	}

	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#finalize()
	 */
	protected void finalize() {
		//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);
		}
	}

}
