/*******************************************************************************
 * 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;

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

	private int managedBeanPageID;

	private int componentsPageID;

	private int othersPageID;

	private int sourcePageId;

	private PageflowEditor pageflowPage;

	/** 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());
                            }
                            
                            IFormPage overviewPage = new OverviewPage(FacesConfigEditor.this);
                            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();
	}

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