/*******************************************************************************
 * 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.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.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$

	/**
	 * 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") //$NON-NLS-1$
                        protected Collection changedResources = new ArrayList();

						@SuppressWarnings("hiding") //$NON-NLS-1$
                        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;
		}

		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)
            {
                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, null);
                            }
                            
                            IFormPage overviewPage = new OverviewPage(FacesConfigEditor.this);
                            addPage(overviewPage, null);
        
                            // Page flow
                            createAndAddPageflowPage();
        
                            // pages
                            IFormPage managedBeanPage = new ManagedBeanPage(FacesConfigEditor.this);
                            managedBeanPageID = addPage(managedBeanPage, null);
                            IFormPage componentsPage = new ComponentsPage(FacesConfigEditor.this);
                            componentsPageID = addPage(componentsPage, null);
                            IFormPage othersPage = new OthersPage(FacesConfigEditor.this);
                            othersPageID = addPage(othersPage, null);
                        }
        
                        sourcePage = new StructuredTextEditor();
        
                        sourcePage.setEditorPart(FacesConfigEditor.this);
        
                        sourcePageId = addPage(sourcePage, FacesConfigEditor.this.getEditorInput());
                        setPageText(sourcePageId,
                                EditorMessages.FacesConfigEditor_Source_TabName);
                        sourcePage.update();
                        
                        // 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);
						_modelLoader.getEdit()
								.getDeploymentDescriptorResource().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.getArePagesLoaded()) {
			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);
		}
	}

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

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

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