/*******************************************************************************
 * Copyright (c) 2004, 2006 Sybase, Inc. and others.
 *
 * 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.facesconfig.ui;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.EventObject;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
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.IResourceDeltaVisitor;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.commands.CommandStackListener;
import org.eclipse.gef.editparts.ZoomManager;
import org.eclipse.gef.ui.actions.ActionRegistry;
import org.eclipse.gef.ui.actions.EditorPartAction;
import org.eclipse.gef.ui.actions.SaveAction;
import org.eclipse.gef.ui.actions.UpdateAction;
import org.eclipse.gef.ui.views.palette.PaletteView;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jst.jsf.common.ui.internal.actions.IOpenPage;
import org.eclipse.jst.jsf.core.IJSFCoreConstants;
import org.eclipse.jst.jsf.facesconfig.edit.provider.FacesConfigItemProviderAdapterFactory;
import org.eclipse.jst.jsf.facesconfig.emf.FacesConfigType;
import org.eclipse.jst.jsf.facesconfig.ui.page.ComponentsPage;
import org.eclipse.jst.jsf.facesconfig.ui.page.IntroductionPage;
import org.eclipse.jst.jsf.facesconfig.ui.page.ManagedBeanPage;
import org.eclipse.jst.jsf.facesconfig.ui.page.OthersPage;
import org.eclipse.jst.jsf.facesconfig.ui.page.OverviewPage;
import org.eclipse.jst.jsf.facesconfig.ui.page.WaitForLoadPage;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.DelegatingZoomManager;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.PageflowEditor;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.command.DelegatingCommandStack;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.command.EMFCommandStackGEFAdapter;
import org.eclipse.jst.jsf.facesconfig.ui.pageflow.layout.PageflowLayoutManager;
import org.eclipse.jst.jsf.facesconfig.ui.preference.GEMPreferences;
import org.eclipse.jst.jsf.facesconfig.util.FacesConfigArtifactEdit;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorActionBarContributor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.dialogs.SaveAsDialog;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.editor.IFormPage;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.ide.IGotoMarker;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.ui.StructuredTextEditor;

/**
 * This is the main editor for the faces-config file.  Note that the model
 * load can involve long-running socket operations (shouldn't but can),
 * so the editor UI is load asynchronously.  This is means that any 
 * operations that need to be executed on editor open should be run
 * using AddPagesTask.pageSafeExecute() to ensure that they occur
 * after all editor pages have finished loading.
 * 
 * @author sfshi
 * 
 */
public class FacesConfigEditor extends FormEditor implements
		IEditingDomainProvider, ISelectionProvider {

    /**
     * This editor's ID.  TODO: this should prob be in plugin.properties?
     */
    public static final String EDITOR_ID = "org.eclipse.jst.jsf.facesconfig.ui.FacesConfigEditor"; //$NON-NLS-1$
    
    
    /**
     * Page id for Source page.   Used for testing only.
     */
    public static final String SOURCE_PAGE_ID = "SourcePageId"; //$NON-NLS-1$
	/**
	 * editing domain that is used to track all changes to the model
	 */
	private AdapterFactoryEditingDomain editingDomain;

	/**
	 * adapter factory used for providing views of the model
	 */
	private ComposedAdapterFactory adapterFactory;

	private int overviewPageID;

	/** id of the pageflowPage */
	private int pageflowPageID;

	private int managedBeanPageID;

	private int componentsPageID;

	private int othersPageID;

	private int sourcePageId;

	private PageflowEditor pageflowPage;

	private OverviewPage overviewPage;

	/** The source text editor. */
	private StructuredTextEditor sourcePage;

	private Collection selectionChangedListeners = new ArrayList();

	private ISelection editorSelection = StructuredSelection.EMPTY;

	private IContentOutlinePage outlinePage;

	private IProject currentProject;

	private boolean isWebProject;
	
	private ModelLoader        _modelLoader;
	
	/**
	 * only true once dispose() has been called
	 * used to signal that the editor was disposed.
	 */
	private boolean _isDisposed; // = false;
	
    /**
     * Used to load editor pages when the model is loaded
     */
    private final AddPagesTask     _addPagesTask = new AddPagesTask();
        
	/**
	 * Default constructor
	 */
	public FacesConfigEditor() {
		initializeEMF();
	}

	/**
	 * This listens for workspace changes. <!-- begin-user-doc --> <!--
	 * end-user-doc -->
	 * 
	 * @generated
	 */
	protected IResourceChangeListener resourceChangeListener = new IResourceChangeListener() {
		public void resourceChanged(IResourceChangeEvent event) {
			// Only listening to these.
			// if (event.getType() == IResourceDelta.POST_CHANGE)
			{
				IResourceDelta delta = event.getDelta();
				try {
					class ResourceDeltaVisitor implements IResourceDeltaVisitor {
						protected ResourceSet resourceSet = editingDomain
								.getResourceSet();

						@SuppressWarnings("hiding") 
                        protected Collection changedResources = new ArrayList();

						@SuppressWarnings("hiding") 
                        protected Collection removedResources = new ArrayList();

						public boolean visit(IResourceDelta delta_) {
							if (delta_.getFlags() != IResourceDelta.MARKERS
									&& delta_.getResource().getType() == IResource.FILE) {
								if ((delta_.getKind() & (IResourceDelta.CHANGED | IResourceDelta.REMOVED)) != 0) {
									Resource resource = resourceSet
											.getResource(URI.createURI(delta_
													.getFullPath().toString()),
													false);
									if (resource != null) {
										if ((delta_.getKind() & IResourceDelta.REMOVED) != 0) {
											removedResources.add(resource);
										} else {
											changedResources.add(resource);
										}
									}
								}
							}

							return true;
						}

						public Collection getChangedResources() {
							return changedResources;
						}

						public Collection getRemovedResources() {
							return removedResources;
						}
					}

					ResourceDeltaVisitor visitor = new ResourceDeltaVisitor();
					delta.accept(visitor);

					if (!visitor.getRemovedResources().isEmpty()) {
						removedResources.addAll(visitor.getRemovedResources());
						if (!isDirty()) {
							getSite().getShell().getDisplay().asyncExec(
									new Runnable() {
										public void run() {
											getSite().getPage().closeEditor(
													FacesConfigEditor.this,
													false);
											FacesConfigEditor.this.dispose();
										}
									});
						}
					}

					if (!visitor.getChangedResources().isEmpty()) {
						changedResources.addAll(visitor.getChangedResources());
					}
				} catch (CoreException exception) {
					// log it.
					EditorPlugin.getDefault().getLog().log(
							new Status(IStatus.ERROR, EditorPlugin
									.getPluginId(), IStatus.OK, exception
									.getMessage() == null ? "" : exception //$NON-NLS-1$
									.getMessage(), exception));
				}
			}
		}
	};

	/**
	 * Resources that have been removed since last activation.
	 * 
	 * @generated
	 */
	Collection removedResources = new ArrayList();

	/**
	 * Resources that have been changed since last activation.
	 * 
	 * @generated
	 */
	Collection changedResources = new ArrayList();

	/**
	 * Resources that have been saved.
	 * 
	 * @generated
	 */
	Collection savedResources = new ArrayList();

	/**
	 * Initializes the EMF support.
	 */
	private void initializeEMF() {
		// create an adapter factory that yields item providers
		List factories = new ArrayList();
		factories.add(new ResourceItemProviderAdapterFactory());
		factories.add(new FacesConfigItemProviderAdapterFactory());
		factories.add(new ReflectiveItemProviderAdapterFactory());
		adapterFactory = new ComposedAdapterFactory(factories);

		// create the command stack that will notify this editor as commands are
		// executed
		BasicCommandStack commandStack = new BasicCommandStack();
		commandStack
				.addCommandStackListener(new org.eclipse.emf.common.command.CommandStackListener() {
					public void commandStackChanged(final EventObject event) {
						getContainer().getShell().getDisplay().asyncExec(
								new Runnable() {
									public void run() {
										editorDirtyStateChanged();
										getActionBarContributor()
												.updateActionBars();
									}
								});
					}
				});
		// commandStack.addCommandStackListener(this);
		// create the editing domain with a special command stack
		editingDomain = new AdapterFactoryEditingDomain(adapterFactory,
				commandStack, new HashMap());
	}

	/*
	 * @see org.eclipse.ui.IEditorPart#init(org.eclipse.ui.IEditorSite,
	 *      org.eclipse.ui.IEditorInput)
	 */
	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException {
		try {
			super.init(site, input);
		} catch (Exception e) {
			MessageDialog.openError(null,
					EditorMessages.FacesConfigEditor_Error_OpenModel_Title,
					EditorMessages.FacesConfigEditor_Error_OpenModel);
			throw new PartInitException(
					EditorMessages.FacesConfigEditor_Error_OpenModel);
		}

		setPartName(input.getName());
		if (!isValidInput(input)) {
			PlatformUI.getWorkbench().getActiveWorkbenchWindow()
					.getActivePage().openEditor(input,
							"org.eclipse.ui.DefaultTextEditor"); //$NON-NLS-1$

			close(false);
			return;
		}

		//Bug 291054 - faces-config should be checked out if the user tries to modify it
		if (input instanceof IFileEditorInput) {
			IFile file = ((IFileEditorInput)input).getFile();
			if (file.isReadOnly()) {
				file.getWorkspace().validateEdit(new IFile[]{file}, site != null ? site.getShell() : null);
			}
		}

		//Bug 191494 - Unable to switch pages in faces config editor without mouse
		// Activate plugin context
		IContextService contextService = (IContextService) getSite()
				.getService(IContextService.class);
		contextService
				.activateContext("org.eclipse.jst.jsf.facesconfig.editorContext"); //$NON-NLS-1$

		createActions();

		ResourcesPlugin.getWorkspace().addResourceChangeListener(
				resourceChangeListener, IResourceChangeEvent.POST_CHANGE);
	}

	/*
	 * @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput)
	 */
	protected void setInput(IEditorInput input) 
	{
        isWebProject = matches(input);
        super.setInput(input);

		IFile inputFile = (IFile) input.getAdapter(IFile.class);
		if (inputFile != null) 
		{
			final IProject project = inputFile.getProject();
			final IPath inputPath = inputFile.getFullPath();
			
			_modelLoader = new ModelLoader(); 
			_modelLoader.load(project, inputPath, isWebProject, _addPagesTask);
		}
	}


	protected void addPages() 
	{
	    // try loading wait page
	    // if we get to here before model load completes,
	    // then wait page will give the user the indication
	    // that something is happening in the background before
	    // the editor full loads.
	    // if the model is already loaded, this call should do nothing
	    _addPagesTask.maybeAddWaitPage();
	}

	/**
	 * This runnable is used to used to manage the loading of the 
	 * editor pages for editor in a deferred fashion.  Because the model
	 * loading for this editor can be noticably long and (unfortunately)
	 * may involve socket calls that block, loadModel(), runs this on a
	 * separate thread. This class is intended to be used in two ways:
	 * 
	 * 1) by the model loading code to signal it is finished by executing
	 * the run() via a display.asyncExec().
	 * 
	 * 2) by the addPages() call back on the the main editor as a way to
	 * load a "Please wait for loading" page if the loading is still running
	 * by the time the editor is ready to visualize itself.
	 * 
	 * Note that in both cases methods of this class *must* be running on the
	 * main display thread.
	 * 
	 * @author cbateman
	 *
	 */
	private class AddPagesTask extends ModelLoader.ModelLoaderComplete
	{
	    private final AtomicBoolean    _arePagesLoaded = new AtomicBoolean(false);     // set to true when the regular editor pages are loaded
	    private FormPage               _waitPage;
	    private List<Runnable>         _deferredRunnables = new ArrayList<Runnable>();
	    
	    /**
	     * If the editor pages are loaded, runnable.run() is invoked immediately
	     * If the editor pages are not loaded yet, runnable is queued and will be 
	     * executed in the order they are added immediately after the pages are loaded
	     * 
	     * @param runnable
	     */
	    public synchronized void pageSafeExecute(Runnable runnable)
	    {
	        if (!_isDisposed)
	        {
    	        if (!_arePagesLoaded.get())
    	        {
    	            _deferredRunnables.add(runnable);
    	        }
    	        else
    	        {
    	            runnable.run();
    	        }
	        }
	    }
	    
        /**
         * @return true if the pages are loaded
         */
        public synchronized boolean getArePagesLoaded() 
        {
            return _arePagesLoaded.get();
        }
        
        /**
         * Remove the wait page if present.
         */
        public synchronized void removeWaitPage()
        {
            if (_waitPage != null 
            		&& !_waitPage.getPartControl().isDisposed()) 
            {
                int index = _waitPage.getIndex();
                
                if (index >= 0)
                {
                    removePage(index);
                }
            }
        }
        
        /**
         * Add the wait page if the main pages aren't already loaded
         */
        public synchronized void maybeAddWaitPage()
        {
            // only load the wait page if the other pages haven't been loaded
            if (!getArePagesLoaded())
            {
                _waitPage = new WaitForLoadPage(FacesConfigEditor.this, "WaitForLoad", EditorMessages.FacesConfigEditor_WaitForLoad_EditorTabTitle); //$NON-NLS-1$
                
                try
                {
                    addPage(0,_waitPage);
                }
                catch(PartInitException pie)
                {
                    _waitPage =null;
                    EditorPlugin.getDefault().getLog().log(
                            new Status(IStatus.ERROR, EditorPlugin.getPluginId(),
                                    IStatus.OK, pie.getMessage() == null ? "" : pie //$NON-NLS-1$
                                            .getMessage(), pie));
                }
            }
        }

        /**
         * Must be run on the UI thread
         */
        public void doRun(FacesConfigArtifactEdit  edit) 
        {
            synchronized(this)
            {
                // ensure wait page gets removed
                removeWaitPage();
                
                if (!getArePagesLoaded()
                        && !_isDisposed)  // NOTE: we assume that access to variable does not need to
                                          // to be synchronous since this method must 
                                          // be run on the UI thread.  The only way
                                          // that isDisposed should be true is if model loading took a long
                                          // time and the user closed the editor before it completed (trigger dispose to be called)
                {
                    try 
                    {
                        if (isWebProject && edit != null && edit.getFacesConfig() != null) 
                        {
                            // only add the intro editor if the preference
                            // is set to do so.
                            if (GEMPreferences.getShowIntroEditor())
                            {
                                IntroductionPage page1 = new IntroductionPage(FacesConfigEditor.this);
                                addPage(page1, FacesConfigEditor.this.getEditorInput());
                            }
                            
                            overviewPage = new OverviewPage(FacesConfigEditor.this);
                            overviewPageID = addPage(overviewPage, FacesConfigEditor.this.getEditorInput());
        
                            // Page flow
                            createAndAddPageflowPage();
        
                            // pages
                            IFormPage managedBeanPage = new ManagedBeanPage(FacesConfigEditor.this);
                            managedBeanPageID = addPage(managedBeanPage, FacesConfigEditor.this.getEditorInput());
                            IFormPage componentsPage = new ComponentsPage(FacesConfigEditor.this);
                            componentsPageID = addPage(componentsPage, FacesConfigEditor.this.getEditorInput());
                            IFormPage othersPage = new OthersPage(FacesConfigEditor.this);
                            othersPageID = addPage(othersPage, FacesConfigEditor.this.getEditorInput());
                        }
        
                        sourcePage = new StructuredTextEditor();
                        sourcePage.setEditorPart(FacesConfigEditor.this);
                        sourcePageId = addPage(sourcePage, FacesConfigEditor.this.getEditorInput());
                        setPageText(sourcePageId, EditorMessages.FacesConfigEditor_Source_TabName);
                        sourcePage.update();

                        /*
                         * Bug 335276 - compile errors with near M5 platform
                         * 
                         * Code previously added to address Bug 263806 relied on internal classes
                         * that have since been removed. Bug 263806 no longer requires the code that
                         * was added in order to function correctly, and so the old fix for Bug
                         * 263806 has simply been removed.
                         */

                        // default active page to 0
                        setActivePage(0);

                        // execute deferred runnables
                        for (Runnable runnable : _deferredRunnables)
                        {
                            runnable.run();
                        }
                        
                        // flag the fact that the regular editor pages have been added
                        _arePagesLoaded.set(true);
                    } catch (PartInitException e) {
                        EditorPlugin.getDefault().getLog().log(
                                new Status(IStatus.ERROR, EditorPlugin.getPluginId(),
                                        IStatus.OK, e.getMessage() == null ? "" : e //$NON-NLS-1$
                                                .getMessage(), e));
                    }
                }
            }
        }
	}
	
	/**
	 * Creates the pageflow page of the multi-page editor.
	 * @throws PartInitException 
	 */
	protected void createAndAddPageflowPage() throws PartInitException {
		pageflowPage = new PageflowEditor(this);
		pageflowPageID = addPage(pageflowPage, getEditorInput());
		setPageText(pageflowPageID,
				EditorMessages.FacesConfigEditor_Pageflow_TabName);
		addPageActionRegistry(pageflowPage);
		pageflowPage.getModelsTransform().setFacesConfig(getFacesConfig());
		pageflowPage.getModelsTransform().setPageflow(
				pageflowPage.getPageflow());
		boolean fornew = pageflowPage.getModelsTransform()
				.updatePageflowModelFromEMF();
		pageflowPage.setGraphicalViewerContents(pageflowPage.getPageflow());
		if (fornew) {
			PageflowLayoutManager.getInstance().layoutPageflow(
					pageflowPage.getPageflow());
		}
		pageflowPage.getModelsTransform().setListenToNotify(true);
	}

	/**
	 * TODO: this is used only for testing
	 * @return the page flow editor
	 */
	public PageflowEditor getPageflowPage() {
		return pageflowPage;
	}

	/**
	 * get the action's registry of sub pages.
	 * @param page 
	 * 
	 */
	protected void addPageActionRegistry(IEditorPart page) {
		if (page != null) {
			ActionRegistry pageActionRegisty = (ActionRegistry) page
					.getAdapter(ActionRegistry.class);
			if (pageActionRegisty != null) {
				for (Iterator iter = pageActionRegisty.getActions(); iter
						.hasNext();) {
					getActionRegistry().registerAction((IAction) iter.next());
				}
			}
		}
	}

	/** the editor's action registry */
	private ActionRegistry actionRegistry = null;

	/**
	 * Returns the action registry of this editor.
	 * 
	 * @return - the action registry
	 */
	protected ActionRegistry getActionRegistry() {
		if (null == actionRegistry)
			actionRegistry = new ActionRegistry();

		return actionRegistry;
	}

	/**
	 * Returns the root object of the configuration model.
	 * 
	 * @return the root object.  Should not, but may return null.
	 */
	public FacesConfigType getFacesConfig() 
	{
	    FacesConfigArtifactEdit  edit = _modelLoader.getEdit();
	    if (edit != null)
	    {
	        return edit.getFacesConfig();
	    }
	    return null;
	}

	/*
	 * @see org.eclipse.ui.ISaveablePart#isDirty()
	 */
	public boolean isDirty() { 
		return ((BasicCommandStack) editingDomain.getCommandStack()) 
				.isSaveNeeded()
				|| super.isDirty(); 
	}

	/**
	 * This class listens for command stack changes of the pages contained in
	 * this editor and decides if the editor is dirty or not.
	 */
	private class MultiPageCommandStackListener implements CommandStackListener {

		/** the observed command stacks */
		private List commandStacks = new ArrayList(2);

		/** to get the editorpart from command stack */
		private HashMap mapEditorCommandStack = new HashMap();

		private boolean saveLocation = false;

		/**
		 * Adds a <code>CommandStack</code> to observe.
		 * 
		 * @param commandStack
		 * @param editor 
		 */
		public void addCommandStack(CommandStack commandStack,
				IEditorPart editor) {
			if (commandStack == null)
				return;

			if (mapEditorCommandStack.get(commandStack) == editor)
				return;

			commandStacks.add(commandStack);
			commandStack.addCommandStackListener(this);
			mapEditorCommandStack.put(commandStack, editor);
		}

		/**
		 * set the dirty status for the models of different editor
		 * 
		 * @param editor -
		 *            editor, e.g., pageflow or databinding page.
		 * @param dirty -
		 *            true or false
		 */
		private void setEditorDirty(IEditorPart editor, boolean dirty) {
            // do nothing
		}

		/** the list of action ids that are to CommandStack actions */
		private List stackActionIDs = new ArrayList();

		/**
		 * Updates the specified actions.
		 * 
		 * @param actionIds -
		 *            the list of ids of actions to update
		 */
		private void updateActions(List actionIds) {
			for (Iterator ids = actionIds.iterator(); ids.hasNext();) {
				IAction action = getActionRegistry().getAction(ids.next());
				if (null != action && action instanceof UpdateAction) {
					((UpdateAction) action).update();
				}
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see CommandStackListener#commandStackChanged(java.util.EventObject)
		 */
		public void commandStackChanged(EventObject event) {
			// enable or disable the actions
			updateActions(stackActionIDs);
			if (((CommandStack) event.getSource()).isDirty()) {
				// set the editor's model dirty status
				setEditorDirty((IEditorPart) mapEditorCommandStack
						.get(event.getSource()), true);
				// at least one command stack is dirty,
				// so the multi page editor is dirty too
				setDirty(true);
			} else {
				// set the editor's model dirty status, if it is from not save
				// location.
				if (!saveLocation) {
					setEditorDirty((IEditorPart) mapEditorCommandStack
							.get(event.getSource()), true);
					setDirty(true);
				} else {
					setDirty(false);
				}
			}
		}

		/** the pageflow page editor's dirty state */
		private boolean isDirty = false;

		/**
		 * Changes the dirty state.
		 * 
		 * @param dirty -
		 *            dirty state
		 */
		public void setDirty(boolean dirty) {
			if (isDirty != dirty) {
				isDirty = dirty;
				firePropertyChange(IEditorPart.PROP_DIRTY);
			}
		}

		/**
		 * Disposed the listener
		 */
		public void dispose() {
			for (Iterator stacks = commandStacks.iterator(); stacks.hasNext();) {
				((CommandStack) stacks.next()).removeCommandStackListener(this);
			}
			commandStacks.clear();
		}

		/**
		 * Marks every observed command stack beeing saved. This method should
		 * be called whenever the editor/model was saved.
		 */
		public void markSaveLocations() {
			saveLocation = true;
			for (Iterator stacks = commandStacks.iterator(); stacks.hasNext();) {
				CommandStack stack = (CommandStack) stacks.next();
				stack.markSaveLocation();
			}
			saveLocation = false;
		}

		/**
		 * Flushes every observed command stack and resets the save location to
		 * zero.
		 */
//		public void flush() {
//			for (Iterator stacks = commandStacks.iterator(); stacks.hasNext();) {
//				CommandStack stack = (CommandStack) stacks.next();
//				stack.flush();
//			}
//		}
	}

	/** the <code>CommandStackListener</code> */
	private MultiPageCommandStackListener multiPageCommandStackListener = null;

	/**
	 * Returns the global command stack listener.
	 * 
	 * @return the <code>CommandStackListener</code>
	 */
	protected MultiPageCommandStackListener getMultiPageCommandStackListener() {
		if (null == multiPageCommandStackListener)
			multiPageCommandStackListener = new MultiPageCommandStackListener();

		return multiPageCommandStackListener;
	}

	/*
	 * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void doSave(IProgressMonitor monitor) {
		// do the work within an operation because this is a long running
		// activity that modifies the workbench
		WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
			public void execute(IProgressMonitor monitor_) {
				try {
					if (isWebProject &&
					        _modelLoader.getEdit() != null) {
						// modelResource.save(Collections.EMPTY_MAP);
						Resource deploymentDescriptorResource = _modelLoader.getEdit()
                                      .getDeploymentDescriptorResource();
                        if (deploymentDescriptorResource != null)
                        {
                            deploymentDescriptorResource.save(
                                   Collections.EMPTY_MAP);
						}
						IFile file = ((IFileEditorInput) getEditorInput())
								.getFile();
						pageflowPage.doSave(file, monitor_);
					}
					sourcePage.doSave(monitor_);
					getMultiPageCommandStackListener().markSaveLocations();
				} catch (Exception e) {
					EditorPlugin.getDefault().getLog().log(
							new Status(IStatus.ERROR, EditorPlugin
									.getPluginId(), IStatus.OK,
									e.getMessage() == null ? "" : e //$NON-NLS-1$
											.getMessage(), e));
				}
			}
		};
		try {
			// commit all pending changes in form pages
			for (Iterator iter = pages.iterator(); iter.hasNext();) {
				Object obj = iter.next();
				if (obj instanceof FormPage) {
					((FormPage) obj).doSave(monitor);
				}
				// else if (obj instanceof PageflowEditor) {
				// ((PageflowEditor) obj).doSave(monitor);
				// }

			}
			operation.run(null);// .run(true, false,
			// operation;
			// runs the operation, and shows progress
			// new ProgressMonitorDialog();

			// refresh the necessary state
			((BasicCommandStack) editingDomain.getCommandStack()).saveIsDone();

			editorDirtyStateChanged();
		} catch (Exception e) {
			EditorPlugin.getDefault().getLog().log(
					new Status(IStatus.ERROR, EditorPlugin.getPluginId(),
							IStatus.OK, e.getMessage(), e));
		}
	}

	public void doSaveAs() {
		SaveAsDialog saveAsDialog = new SaveAsDialog(getSite().getShell());
		saveAsDialog.open();
		IPath path = saveAsDialog.getResult();
		if (path != null) {
			IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
			if (file != null) {
				doSaveAs(URI.createPlatformResourceURI(file.getFullPath()
						.toString(), false), new FileEditorInput(file));
			}
		}
	}

	/**
	 * @param uri
	 * @param editorInput
	 */
	protected void doSaveAs(URI uri, IEditorInput editorInput) {
		editingDomain.getResourceSet().getResources().get(0)
				.setURI(uri);
		setInputWithNotify(editorInput);
		setPartName(editorInput.getName());
		IProgressMonitor progressMonitor = getActionBars()
				.getStatusLineManager() != null ? getActionBars()
				.getStatusLineManager().getProgressMonitor()
				: new NullProgressMonitor();
		doSave(progressMonitor);
	}

	public boolean isSaveAsAllowed() {
		return true;
	}

	/**
	 * Returns the <code>TabbedPropertySheetPage</code> for this editor.
	 * 
	 * @return - the <code>TabbedPropertySheetPage</code>
	 */
	protected IPropertySheetPage getPropertySheetPage() {
		return new TabbedPropertySheetPage(
				new ITabbedPropertySheetPageContributor() {

					public String getContributorId() {
						return EDITOR_ID;
					}
				});
	}

	/** the delegating ZoomManager */
	private DelegatingZoomManager delegatingZoomManager = null;

	/**
	 * check whether the input is related with IFile.
	 * 
	 * @param input
	 * @return
	 */
	private boolean isValidInput(IEditorInput input) {
		if (input != null) {
			IFile file = (IFile) input.getAdapter(IResource.class);
			if (file != null) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Returns the <code>DelegatingZoomManager</code> for this editor.
	 * 
	 * @return - the <code>DelegatingZoomManager</code>
	 */
	protected DelegatingZoomManager getDelegatingZoomManager() {
		if (
				!isValidInput(getEditorInput()) ||
				!isWebProject ||
				_addPagesTask == null ||
				!_addPagesTask.getArePagesLoaded() ||
				pageflowPage == null) {
			return null;
		}
		if (null == delegatingZoomManager) {
			delegatingZoomManager = new DelegatingZoomManager();
			delegatingZoomManager
					.setCurrentZoomManager((ZoomManager) pageflowPage
							.getAdapter(ZoomManager.class));
		}
		return delegatingZoomManager;
	}

	/** the delegating CommandStack */
	private DelegatingCommandStack delegatingCommandStack = null;

	/**
	 * Returns the <code>CommandStack</code> for this editor.
	 * 
	 * @return - the <code>CommandStack</code>
	 */
	public DelegatingCommandStack getDelegatingCommandStack() {
		if (null == delegatingCommandStack) {
			delegatingCommandStack = new DelegatingCommandStack();
		}
		return delegatingCommandStack;
	}

	/*
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	public Object getAdapter(Class adapter) {
		if (adapter == IEditingDomainProvider.class) {
			return new IEditingDomainProvider() {
				public EditingDomain getEditingDomain() {
					return editingDomain;
				}
			};
		}
		if (adapter == EditingDomain.class) {
			return editingDomain;
		}
		if (adapter == AdapterFactory.class) {
			return adapterFactory;
		}
		if (adapter == IEditorPart.class) {
			return getActiveEditor();
		}

		if (adapter == CommandStack.class) {
			return getDelegatingCommandStack();
		}
		if (adapter == ZoomManager.class) {
			return getDelegatingZoomManager();
		}

		if (adapter == ActionRegistry.class) {
			return getActionRegistry();
		}
		if (adapter == IGotoMarker.class) {
			return new IGotoMarker() {
				public void gotoMarker(final IMarker marker) {
				    // this may be called on an editor open (i.e. double-click the Problems view)
				    // so ensure it runs safely with respect to the page load
				    _addPagesTask.pageSafeExecute(new Runnable()
				    {
				        public void run()
				        {
		                    FacesConfigEditor.this.gotoMarker(marker);
				        }
				    });
				}
			};
		}
		if (adapter == StructuredTextEditor.class) {
			return sourcePage;
		}

		if (adapter == IContentOutlinePage.class) {
			return getOutlinePage();
		}

		if (adapter == IPropertySheetPage.class) {
			return getPropertySheetPage();
		}

		if (adapter == IProject.class) {
			return getProject();
		}

		if (adapter == CTabFolder.class) {
			return getContainer();
		}

		if (adapter == IOpenPage.class) {
			return new IOpenPage() {

				public void setActiveEditorPage(String pageID) {
					FacesConfigEditor.this.setActiveEditorPage(pageID);

				}
			};
		}

		return super.getAdapter(adapter);
	}

	private EMFCommandStackGEFAdapter sourceCommandStack;

	/**
	 * get or create the source page's GEF command stack based on its EMF
	 * command stack.
	 * 
	 * @return
	 */
	private CommandStack getSourcePageCommandStack() {
		if (sourceCommandStack == null) {
            IDocument doc = sourcePage.getDocumentProvider().getDocument(getEditorInput());
            if (doc instanceof IStructuredDocument) {
            	sourceCommandStack = new EMFCommandStackGEFAdapter(doc);
            }
            else
            {
                EditorPlugin.getDefault().getLog().log(
                   new Status(IStatus.ERROR, EditorPlugin.getPluginId(), 0, 
                           "Error getting undo stack for Faces Config editor.  Undo may be disabled", //$NON-NLS-1$
                           new Throwable()));
            }
		}
		return sourceCommandStack;
	}

	/** the list of action ids that are to CommandStack actions */
	// private List stackActionIDs = new ArrayList();
	/** the list of action ids that are editor actions */
	private List editorActionIDs = new ArrayList();

	/**
	 * Adds an editor action to this editor.
	 * <p>
	 * Editor actions are actions that depend and work on the editor.
	 * 
	 * @param action -
	 *            the editor action
	 */
	protected void addEditorAction(EditorPartAction action) {
		getActionRegistry().registerAction(action);
		editorActionIDs.add(action.getId());
	}

	/**
	 * Creates different kinds of actions and registers them to the
	 * ActionRegistry.
	 */
	protected void createActions() {
		// register save action
		addEditorAction(new SaveAction(this));
	}

	/**
	 * Indicates that the current page has changed.
	 * <p>
	 * We update the DelegatingCommandStack, OutlineViewer and other things
	 * here. //
	 */
	protected void currentPageChanged() {
		IEditorPart activeEditor = getActiveEditor();
		if (activeEditor == null) {
			return;
		}

		// update command stack
		CommandStack cmdStack = null;

		if (activeEditor == pageflowPage) {
			cmdStack = (CommandStack) activeEditor
					.getAdapter(CommandStack.class);
		} else if (activeEditor == sourcePage)// other page will delegate the
		// GEF command stack to source
		// page's.
		{
			cmdStack = this.getSourcePageCommandStack();
		}

		// Add command stacks
		getMultiPageCommandStackListener().addCommandStack(cmdStack,
				activeEditor);
		getDelegatingCommandStack().setCurrentCommandStack(cmdStack);

		// enable or disable the actions
		// updateActions(stackActionIDs);

		// update zoom actions
		ZoomManager zoomManager = null;
		zoomManager = (ZoomManager) activeEditor.getAdapter(ZoomManager.class);

		if (zoomManager != null) {
			getDelegatingZoomManager().setCurrentZoomManager(zoomManager);
		}

		IEditorActionBarContributor contributor = getEditorSite()
				.getActionBarContributor();
		if (contributor != null
				&& contributor instanceof FacesConfigActionBarContributor) {
			((FacesConfigActionBarContributor) contributor)
					.setActivePage(activeEditor);
			PaletteView paletteView = (PaletteView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().findView(PaletteView.ID);
			if(paletteView != null) {
				paletteView.partActivated(activeEditor);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see MultiPageEditorPart#pageChange(int)
	 */
	protected void pageChange(int newPageIndex) {
		super.pageChange(newPageIndex);
		// getActionBarContributor().setActivePage(getActiveEditor());
		// refresh content depending on current page
		currentPageChanged();
		//Bug 367899 - Navigation Information doesn't get synchronized with "From Outcome" updates
		if (newPageIndex == overviewPageID) {
			if (overviewPage != null) {
				overviewPage.refreshAll();
			}
		}
	}

	public void dispose() 
	{
        // signal that we have been disposed
        // do this before anything else
	    _isDisposed = true;
	    _modelLoader.dispose();
	    
	    ResourcesPlugin.getWorkspace().removeResourceChangeListener(
				resourceChangeListener);

		adapterFactory.dispose();

		if (this.outlinePage != null) 
			outlinePage.dispose();		
		
		if (sourcePage != null) 
			sourcePage.dispose();
		
		if (sourceCommandStack != null)
			sourceCommandStack.dispose();
		
		if (pageflowPage != null) 
			pageflowPage.dispose();					
		
	    if (multiPageCommandStackListener != null)
	    	multiPageCommandStackListener.dispose();	    
	    
		//do not call dispose on delegatingCommandStack.   source and multiPage are already disposed
		
		super.dispose();
	}

	/**
	 * get the project of the faces config file that the editor is working on.
	 * 
	 * @return IProject
	 */
	public IProject getProject() {
		if (currentProject == null) {
			if (_modelLoader.getEdit() != null) {
				IFile file = _modelLoader.getEdit().getFile();
				if (file != null)
					currentProject = file.getProject();
			}
		}
		return currentProject;
	}

	public EditingDomain getEditingDomain() {
		return editingDomain;
	}

	/**
	 * Returns the <code>IContentOutlinePage</code> for this editor.
	 * 
	 * @return - the <code>IContentOutlinePage</code>
	 */
	protected IContentOutlinePage getOutlinePage() {
		if (null == outlinePage) {
			outlinePage = new MultiPageEditorOutlinePage();
		}
		return outlinePage;
	}

	public void addSelectionChangedListener(ISelectionChangedListener listener) {
		selectionChangedListeners.add(listener);
	}

	public ISelection getSelection() {
		return editorSelection;
	}

	public void removeSelectionChangedListener(
			ISelectionChangedListener listener) {
		selectionChangedListeners.remove(listener);
	}

	public void setSelection(ISelection selection) {
		editorSelection = selection;
		for (Iterator listeners = selectionChangedListeners.iterator(); listeners
				.hasNext();) {
			ISelectionChangedListener listener = (ISelectionChangedListener) listeners
					.next();
			listener
					.selectionChanged(new SelectionChangedEvent(this, selection));
		}
	}

	private void gotoMarker(IMarker marker) {
		setActivePage(sourcePageId);
		IDE.gotoMarker(this.sourcePage, marker);
	}

	/**
	 * FIXME: this is used only for testing. Should isolate better
	 * @return the action bar
	 */
	public FacesConfigActionBarContributor getActionBarContributor() {
		return (FacesConfigActionBarContributor) getEditorSite()
				.getActionBarContributor();
	}

	private IActionBars getActionBars() {
		return getActionBarContributor().getActionBars();
	}

	public Object getSelectedPage() {
		IFormPage page = getActivePageInstance();
		if (page != null) 
			return page;
			
		if (getActiveEditor() instanceof PageflowEditor)
			return getActiveEditor();
		
		return null;
	}

	/**
	 * Shows a dialog that asks if conflicting changes should be discarded.
	 * @return the user's response.
	 */
	protected boolean handleDirtyConflict() {
		return MessageDialog
				.openQuestion(
						getSite().getShell(),
						EditorMessages.FacesConfigEditor_ErrorHandlingUndoConflicts_DialogTitle,
						EditorMessages.FacesConfigEditor_ErrorHandlingUndoConflicts_DialogMessage);
	}

	/**
	 * Handles what to do with changed resources on activation.
	 * 
	 * @generated
	 */
	protected void handleChangedResources() {
		if (!changedResources.isEmpty()
				&& (!isDirty() || handleDirtyConflict())) {
			editingDomain.getCommandStack().flush();

			for (Iterator i = changedResources.iterator(); i.hasNext();) {
				Resource resource = (Resource) i.next();
				if (resource.isLoaded()) {
					resource.unload();
					try {
						resource.load(Collections.EMPTY_MAP);
					} catch (IOException exception) {
						EditorPlugin.getDefault().getLog().log(
								new Status(IStatus.ERROR, EditorPlugin
										.getPluginId(), IStatus.OK, exception
										.getMessage() == null ? "" : exception //$NON-NLS-1$
										.getMessage(), exception));
					}
				}
			}
		}
	}

	/**
	 * TODO this is used only for testing.  Should be able to remove if we
	 * go to true automated UI testing
	 * @param pageID
	 */
	public void setActiveEditorPage(String pageID) {
		if (pageID.equals(PageflowEditor.PAGE_ID)) {
			setActivePage(pageflowPageID);
		} else if (pageID.equals(ManagedBeanPage.PAGE_ID)) {
			setActivePage(managedBeanPageID);
		} else if (pageID.equals(ComponentsPage.PAGE_ID)) {
			setActivePage(componentsPageID);
		} else if (pageID.equals(OthersPage.PAGE_ID)) {
			setActivePage(othersPageID);
		} else if (pageID.equals(SOURCE_PAGE_ID)) {
			setActivePage(sourcePageId);			
		}
	}

	private boolean matches(IEditorInput input) {
		final IResource file = (IResource) input.getAdapter(IResource.class);
		boolean hasWebFacet = false;
		boolean hasJSFFacet = false;

		if (file != null) {
			final IProject project = file.getProject();

			if (project != null) {
				try {
					final IFacetedProject facetedProject = ProjectFacetsManager
							.create(project);

					if (facetedProject != null) {
						final Set facets = facetedProject.getProjectFacets();

						for (final Iterator it = facets.iterator(); it
								.hasNext();) {
							final IProjectFacetVersion version = (IProjectFacetVersion) it
									.next();

							IProjectFacet facet = version.getProjectFacet();
							if (IJSFCoreConstants.JSF_CORE_FACET_ID.equals(facet.getId())) {
								hasJSFFacet = true;
							} else if ("jst.web".equals(facet.getId())) { //$NON-NLS-1$
								hasWebFacet = true;
							}
						}
					}
				} catch (CoreException ex) {
					EditorPlugin.getDefault().getLog().log(
							new Status(IStatus.ERROR, EditorPlugin
									.getPluginId(), IStatus.OK,
									ex.getMessage() == null ? "" : ex //$NON-NLS-1$
											.getMessage(), ex));
				}
			}
		}

		return hasWebFacet && hasJSFFacet;
	}
	
    /**
     * DANGER!  This call is for testing only!  Should not be used,
     * even internally, by production code.
     * @param timeoutMs the time to wait in milliseconds
     * @throws InterruptedException 
     */	
	public void doPageLoad(long timeoutMs) throws InterruptedException
	{
	    _modelLoader.waitForLoad(timeoutMs);
	    _addPagesTask.doRun(_modelLoader.getEdit());
	}
}
