/*******************************************************************************
 * Copyright (c) 2004, 2012 Sybase, Inc. and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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());
	}
}
