/******************************************************************************
 * Copyright (c) 2010 Oracle
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * Contributors:
 *    Konstantin Komissarchik - initial implementation and ongoing maintenance
 ******************************************************************************/

package org.eclipse.wst.common.project.facet.core.internal;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdapterManager;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.project.facet.core.ActionConfig;
import org.eclipse.wst.common.project.facet.core.DefaultConfigurationPresetFactory;
import org.eclipse.wst.common.project.facet.core.FacetedProjectFramework;
import org.eclipse.wst.common.project.facet.core.IActionConfig;
import org.eclipse.wst.common.project.facet.core.IActionDefinition;
import org.eclipse.wst.common.project.facet.core.IDynamicPreset;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;
import org.eclipse.wst.common.project.facet.core.IFacetedProjectWorkingCopy;
import org.eclipse.wst.common.project.facet.core.IListener;
import org.eclipse.wst.common.project.facet.core.IPreset;
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.MinimalConfigurationPresetFactory;
import org.eclipse.wst.common.project.facet.core.ProjectFacetDetector;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectEvent;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectFrameworkEvent;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectFrameworkListener;
import org.eclipse.wst.common.project.facet.core.events.IFacetedProjectListener;
import org.eclipse.wst.common.project.facet.core.events.IProjectFacetsChangedEvent;
import org.eclipse.wst.common.project.facet.core.events.internal.FacetedProjectEvent;
import org.eclipse.wst.common.project.facet.core.events.internal.ProjectFacetsChangedEvent;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;
import org.eclipse.wst.common.project.facet.core.runtime.RuntimeManager;
import org.eclipse.wst.common.project.facet.core.util.internal.IndexedSet;
import org.eclipse.wst.common.project.facet.core.util.internal.MiscUtil;
import org.eclipse.wst.common.project.facet.core.util.internal.StatusWrapper;

/**
 * @since 3.0
 * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
 */

public final class FacetedProjectWorkingCopy

    implements IFacetedProjectWorkingCopy
    
{
    private static final SortedSet<IProjectFacetVersion> EMPTY_SORTED_FV_SET
        = Collections.unmodifiableSortedSet( new TreeSet<IProjectFacetVersion>() );
    
    /**
     * The object that's used internally for synchronizing access to the data structure.
     */
    
    private Object lock;
    
    /**
     * The name of the project in the scenario where the working copy is for a
     * project that doesn't exist yet, <code>null</code> otherwise.
     */
    
    private String projectName;
    
    /**
     * The validation status of the project name. If the project name is acceptable, the status
     * severity is going to be IStatus.OK.
     */
    
    private IStatus projectNameValidation;
    
    /**
     * The location of the project in the scenario where the working copy is for a
     * project that doesn't exist yet, <code>null</code> otherwise.
     */
    
    private IPath projectLocation;
    private IFacetedProject project;
    private Set<IProjectFacet> fixedFacets;
    private IndexedSet<IProjectFacet,IProjectFacetVersion> facets;
    private Map<IProjectFacet,SortedSet<IProjectFacetVersion>> availableFacets;
    private IndexedSet<String,IPreset> availablePresets;
    private String selectedPresetId;
    private final Set<IRuntime> targetableRuntimes;
    private final Set<IRuntime> targetedRuntimes;
    private IRuntime primaryRuntime;
    private Set<Action> actions;
    private List<IStatus> problems;
    private final List<Runnable> disposeTasks;
    
    /**
     * Maps event types to the list of listeners registered for those events. The map is
     * populated with empty listeners lists for all event types at initialization and is 
     * not modified after that. The contained lists use copy-on-write behavior to guarantee 
     * for safe iteration when notifying listeners.
     */
    
    private final Map<IFacetedProjectEvent.Type,List<IFacetedProjectListener>> listeners;

    /**
     * Tracks whether or not event notification is currently suspended. This counter is
     * incremented by the suspendEventNotification() method and decremented by the
     * resumeEventNotification() method. Once the counter reaches zero, any queued events
     * can be delivered.
     */
    
    private int suspendEventNoticationCounter;
    
    /**
     * Tracks the events that are queued while event notification is suspended.
     */
    
    private final List<IFacetedProjectEvent> queuedEvents;
    
    public FacetedProjectWorkingCopy( final IFacetedProject project )
    {
        this.lock = new Object();
        this.projectName = null;
        this.projectNameValidation = Status.OK_STATUS;
        this.projectLocation = null;
        this.project = project;
        this.actions = Collections.emptySet();
        this.problems = Collections.emptyList();
        this.fixedFacets = Collections.emptySet();
        this.facets = new IndexedSet<IProjectFacet,IProjectFacetVersion>();
        this.availableFacets = Collections.emptyMap();
        this.availablePresets = new IndexedSet<String,IPreset>();
        this.selectedPresetId = null;
        this.targetableRuntimes = new CopyOnWriteArraySet<IRuntime>();
        this.targetedRuntimes = new CopyOnWriteArraySet<IRuntime>();
        this.primaryRuntime = null;
        this.disposeTasks = new ArrayList<Runnable>();
        
        this.listeners = new HashMap<IFacetedProjectEvent.Type,List<IFacetedProjectListener>>();
        
        for( IFacetedProjectEvent.Type eventType : IFacetedProjectEvent.Type.values() )
        {
            this.listeners.put( eventType, new CopyOnWriteArrayList<IFacetedProjectListener>() );
        }
        
        this.suspendEventNoticationCounter = 0;
        this.queuedEvents = new ArrayList<IFacetedProjectEvent>();
        
        refreshAvailableFacets();
        
        if( this.project != null )
        {
            setFixedProjectFacets( this.project.getFixedProjectFacets() );
        }

        refreshAvailablePresets();
        
        if( this.project != null )
        {
            setProjectFacets( this.project.getProjectFacets() );
        }
        
        refreshTargetableRuntimes();
        
        if( this.project != null )
        {
            setTargetedRuntimes( this.project.getTargetedRuntimes() );
            setPrimaryRuntime( this.project.getPrimaryRuntime() );
        }
        
        // Listen for changes to registered runtimes.
        
        final Job runtimesRefreshJob = new Job( Resources.refreshingAvailableRuntimesJobName )
        {
            protected IStatus run( final IProgressMonitor monitor )
            {
                // Suspending event notification to make sure that the internal list of
                // targetable runtimes is updated before the AVAILABLE_RUNTIMES_CHANGED
                // event is received by listeners.
                
                suspendEventNotification();
                
                try
                {
                    final IFacetedProjectEvent event
                        = new FacetedProjectEvent( FacetedProjectWorkingCopy.this, 
                                                   IFacetedProjectEvent.Type.AVAILABLE_RUNTIMES_CHANGED );
                    
                    notifyListeners( event );
                    
                    refreshTargetableRuntimes();
                }
                finally
                {
                    resumeEventNotification();
                }
                
                return Status.OK_STATUS;
            }
        };

        final IListener runtimeManagerListener = new IListener()
        {
            public void handle()
            {
                runtimesRefreshJob.schedule();
            }
        };
        
        RuntimeManager.addRuntimeListener( runtimeManagerListener );
        
        addDisposeTask
        (
            new Runnable()
            {
                public void run()
                {
                    RuntimeManager.removeRuntimeListener( runtimeManagerListener );
                }
            }
        );
        
        // Listen for changes to registered presets.
        
        final IFacetedProjectFrameworkListener presetsListener = new IFacetedProjectFrameworkListener()
        {
            public void handleEvent( final IFacetedProjectFrameworkEvent event )
            {
                refreshAvailablePresets();
            }
        };
        
        FacetedProjectFramework.addListener( presetsListener, 
                                             IFacetedProjectFrameworkEvent.Type.PRESET_ADDED, 
                                             IFacetedProjectFrameworkEvent.Type.PRESET_REMOVED );
        
        addDisposeTask
        (
            new Runnable()
            {
                public void run()
                {
                    FacetedProjectFramework.removeListener( presetsListener );
                }
            }
        );
        
        // Listen for changes to the project.
        
        final IFacetedProjectListener targetedRuntimesChangedListener = new IFacetedProjectListener()
        {
            public void handleEvent( final IFacetedProjectEvent event )
            {
                performValidation();
            }
        };
        
        addListener( targetedRuntimesChangedListener,
                     IFacetedProjectEvent.Type.TARGETED_RUNTIMES_CHANGED );
    }
    
    public String getProjectName()
    {
        synchronized( this.lock )
        {
            if( this.project != null )
            {
                return this.project.getProject().getName();
            }
            else
            {
                return this.projectName;
            }
        }
    }
    
    public void setProjectName( final String name )
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                if( this.project == null )
                {
                    if( ! equals( this.projectName, name ) )
                    {
                        this.projectName = name;
                        
                        for( Action action : getProjectFacetActions() )
                        {
                            final Object config = action.getConfig();
                            
                            if( config != null )
                            {
                                IActionConfig c = null;
                                
                                if( config instanceof IActionConfig )
                                {
                                    c = (IActionConfig) config;
                                }
                                else
                                {
                                    final IAdapterManager m = Platform.getAdapterManager();
                                    final String t = IActionConfig.class.getName();
                                    c = (IActionConfig) m.loadAdapter( config, t );
                                }
                                
                                if( c != null )
                                {
                                    c.setProjectName( this.projectName );
                                }
                            }
                        }
                        
                        notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.PROJECT_NAME_CHANGED ) );
                        
                        final IWorkspace ws = ResourcesPlugin.getWorkspace();
                        
                        final IStatus validateNameResult    
                            = ws.validateName( this.projectName, IResource.PROJECT );
                        
                        if( ! this.projectNameValidation.equals( validateNameResult ) )
                        {
                            this.projectNameValidation = validateNameResult;
                            notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.VALIDATION_PROBLEMS_CHANGED ) );
                        }
                    }
                }
                else
                {
                    throw new IllegalArgumentException(); // TODO: needs message
                }
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    public IPath getProjectLocation()
    {
        synchronized( this.lock )
        {
            if( this.project != null )
            {
                return this.project.getProject().getLocation();
            }
            else
            {
                return this.projectLocation;
            }
        }
    }
    
    public void setProjectLocation( final IPath location )
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                if( this.project == null )
                {
                    this.projectLocation = location;
                }
                else
                {
                    throw new IllegalArgumentException(); // TODO: needs message
                }
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    public IProject getProject()
    {
        final IFacetedProject fproj = getFacetedProject();
        
        if( fproj == null )
        {
            return null;
        }
        else
        {
            return fproj.getProject();
        }
    }
    
    public IFacetedProject getFacetedProject()
    {
        synchronized( this.lock )
        {
            if( this.project == null && this.projectName != null )
            {
                final IWorkspace ws = ResourcesPlugin.getWorkspace();
                
                if( ws.validateName( this.projectName, IResource.PROJECT ).getSeverity() != IStatus.ERROR )
                {
                    final IProject pj = ws.getRoot().getProject( this.projectName );
                    
                    if( pj != null && pj.exists() )
                    {
                        try
                        {
                            this.project = ProjectFacetsManager.create( pj );
                        }
                        catch( CoreException e )
                        {
                            FacetCorePlugin.log( e );
                        }
                    }
                }
            }
            
            return this.project;
        }
    }
    
    public Set<IProjectFacet> getFixedProjectFacets()
    {
        synchronized( this.lock )
        {
            return this.fixedFacets;
        }
    }
    
    public boolean isFixedProjectFacet( final IProjectFacet facet )
    {
        synchronized( this.lock )
        {
            return this.fixedFacets.contains( facet );
        }
    }
    
    public void setFixedProjectFacets( final Set<IProjectFacet> fixed )
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                if( this.fixedFacets.equals( fixed ) )
                {
                    return;
                }
                
                final Set<IProjectFacetVersion> newFacets 
                    = new HashSet<IProjectFacetVersion>( getProjectFacets() );
                
                for( IProjectFacet f : fixed )
                {
                    final IProjectFacetVersion currentVersion = getProjectFacetVersion( f );
                    
                    if( currentVersion == null && f.getVersions().size() > 0 )
                    {
                        IProjectFacetVersion fv = f.getDefaultVersion();
                        
                        if( ! isFacetAvailable( fv ) )
                        {
                            fv = getHighestAvailableVersion( f );
                        }
                        
                        if( fv != null )
                        {
                            newFacets.add( fv );
                        }
                    }
                }
                
                setProjectFacets( newFacets );
                
                this.fixedFacets 
                    = Collections.unmodifiableSet( new HashSet<IProjectFacet>( fixed ) );
                
                notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.FIXED_FACETS_CHANGED ) );
                
                refreshAvailableFacets();
                refreshAvailablePresets();
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    public Map<IProjectFacet,SortedSet<IProjectFacetVersion>> getAvailableFacets()
    {
        synchronized( this.lock )
        {
            return this.availableFacets;
        }
    }
    
    public boolean isFacetAvailable( final IProjectFacet f )
    {
        synchronized( this.lock )
        {
            return this.availableFacets.containsKey( f );
        }
    }
    
    public boolean isFacetAvailable( final IProjectFacetVersion fv )
    {
        synchronized( this.lock )
        {
            final Set<IProjectFacetVersion> versions 
                = this.availableFacets.get( fv.getProjectFacet() );
            
            return ( versions != null && versions.contains( fv ) );
        }
    }
    
    public SortedSet<IProjectFacetVersion> getAvailableVersions( final IProjectFacet f )
    {
        synchronized( this.lock )
        {
            SortedSet<IProjectFacetVersion> availableVersions = this.availableFacets.get( f );
            
            if( availableVersions == null )
            {
                availableVersions = EMPTY_SORTED_FV_SET;
            }
            
            return availableVersions;
        }
    }
    
    @SuppressWarnings( "unchecked" )
    
    public IProjectFacetVersion getHighestAvailableVersion( final IProjectFacet f )
    {
        synchronized( this.lock )
        {
            IProjectFacetVersion version = null;
            final SortedSet<IProjectFacetVersion> availableVersions = this.availableFacets.get( f );
            
            if( availableVersions != null )
            {
                for( IProjectFacetVersion fv : availableVersions )
                {
                    if( version == null )
                    {
                        version = fv;
                    }
                    else
                    {
                        if( fv.compareTo( version ) > 0 )
                        {
                            version = fv;
                        }
                    }
                }
            }
            
            return version;
        }
    }
    
    private void refreshAvailableFacets()
    {
        final Map<IProjectFacet,SortedSet<IProjectFacetVersion>> newAvailableFacets
            = new HashMap<IProjectFacet,SortedSet<IProjectFacetVersion>>();
        
        final Set<IRuntime> targetedRuntimes = getTargetedRuntimes();
        
        for( IProjectFacet f : ProjectFacetsManager.getProjectFacets() )
        {
            SortedSet<IProjectFacetVersion> versions = null;
            
            for( IProjectFacetVersion fv : f.getVersions() )
            {
                boolean available = true;
                
                if( this.project == null || ! this.project.hasProjectFacet( fv ) )
                {
                    for( IRuntime r : targetedRuntimes )
                    {
                        if( ! r.supports( fv ) )
                        {
                            available = false;
                            break;
                        }
                    }
                    
                    if( available && ! fv.isValidFor( this.fixedFacets ) )
                    {
                        available = false;
                    }
                }
                
                if( available )
                {
                    if( versions == null )
                    {
                        versions = new TreeSet<IProjectFacetVersion>();
                        newAvailableFacets.put( f, versions );
                    }
                    
                    versions.add( fv );
                }
            }
        }
        
        // Add any unknown facets that are referenced by the project.
        
        if( this.project != null )
        {
            for( IProjectFacetVersion fv : this.project.getProjectFacets() )
            {
                if( fv.getPluginId() == null )
                {
                    final IProjectFacet f = fv.getProjectFacet();
                    SortedSet<IProjectFacetVersion> versions = newAvailableFacets.get( f );
                    
                    if( versions == null )
                    {
                        versions = new TreeSet<IProjectFacetVersion>();
                        newAvailableFacets.put( f, versions );
                    }
                    
                    versions.add( fv );
                }
            }
        }
        
        // If there is a change to the available facets, apply the change and notify the listeners.
        
        if( ! this.availableFacets.equals( newAvailableFacets ) )
        {
            for( Map.Entry<IProjectFacet,SortedSet<IProjectFacetVersion>> entry 
                 : newAvailableFacets.entrySet() )
            {
                entry.setValue( Collections.unmodifiableSortedSet( entry.getValue() ) );
            }
            
            this.availableFacets = Collections.unmodifiableMap( newAvailableFacets );
            
            notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.AVAILABLE_FACETS_CHANGED ) );

            refreshAvailablePresets();
        }
    }
    
    public Set<IProjectFacetVersion> getProjectFacets()
    {
        synchronized( this.lock )
        {
            return this.facets.getItemSet();
        }
    }
    
    public IProjectFacetVersion getProjectFacetVersion( final IProjectFacet f )
    {
        synchronized( this.lock )
        {
            return this.facets.getItemByKey( f );
        }
    }
    
    public boolean hasProjectFacet( final IProjectFacet f )
    {
        synchronized( this.lock )
        {
            return this.facets.containsKey( f );
        }
    }

    public boolean hasProjectFacet( final IProjectFacetVersion fv )
    {
        synchronized( this.lock )
        {
            return this.facets.containsItem( fv );
        }
    }
    
    public void setProjectFacets( final Set<IProjectFacetVersion> facets )
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                final IndexedSet<IProjectFacet,IProjectFacetVersion> newProjectFacets
                    = new IndexedSet<IProjectFacet,IProjectFacetVersion>();
                
                for( IProjectFacetVersion fv : facets )
                {
                    newProjectFacets.addItemWithKey( fv.getProjectFacet(), fv );
                }
                
                final Set<IProjectFacetVersion> addedFacets = new HashSet<IProjectFacetVersion>();
                final Set<IProjectFacetVersion> removedFacets = new HashSet<IProjectFacetVersion>();
                final Set<IProjectFacetVersion> changedVersions = new HashSet<IProjectFacetVersion>();
                
                for( IProjectFacetVersion fv : newProjectFacets.getItemSet() )
                {
                    final IProjectFacetVersion currentFacetVersion 
                        = this.facets.getItemByKey( fv.getProjectFacet() );
                    
                    if( currentFacetVersion == null )
                    {
                        addedFacets.add( fv );
                    }
                    else
                    {
                        if( ! fv.equals( currentFacetVersion ) )
                        {
                            changedVersions.add( fv );
                        }
                    }
                }
                
                for( IProjectFacetVersion fv : this.facets.getItemSet() )
                {
                    if( ! newProjectFacets.containsKey( fv.getProjectFacet() ) )
                    {
                        removedFacets.add( fv );
                    }
                }
                
                if( addedFacets.isEmpty() && removedFacets.isEmpty() && changedVersions.isEmpty() )
                {
                    return;
                }
                
                setSelectedPreset( null );
                
                this.facets = newProjectFacets;
                
                final IProjectFacetsChangedEvent event
                    = new ProjectFacetsChangedEvent( this, addedFacets, removedFacets,
                                                     changedVersions );
                
                notifyListeners( event );
                
                notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.PROJECT_MODIFIED ) );
                
                refreshTargetableRuntimes();
                refreshProjectFacetActions();
                refreshAvailablePresets();
                performValidation();
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    public void addProjectFacet( final IProjectFacetVersion fv )
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                final IProjectFacetVersion existingVersion 
                    = this.facets.getItemByKey( fv.getProjectFacet() );
                
                if( existingVersion == null )
                {
                    final Set<IProjectFacetVersion> newProjectFacets 
                        = new HashSet<IProjectFacetVersion>();
        
                    newProjectFacets.addAll( this.facets.getItemSet() );
                    newProjectFacets.add( fv );
                    
                    setProjectFacets( newProjectFacets );
                }
                else if( existingVersion == fv )
                {
                    return;
                }
                else
                {
                    // TODO: needs exception msg
                    throw new IllegalArgumentException();
                }
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    public void removeProjectFacet( final IProjectFacet f )
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                final IProjectFacetVersion fv = getProjectFacetVersion( f );
                
                if( fv != null )
                {
                    removeProjectFacet( getProjectFacetVersion( f ) );
                }
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    public void removeProjectFacet( final IProjectFacetVersion fv )
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                final IProjectFacetVersion existingVersion 
                    = this.facets.getItemByKey( fv.getProjectFacet() );
                
                if( existingVersion == null )
                {
                    return;
                }
                else if( existingVersion == fv )
                {
                    final Set<IProjectFacetVersion> newProjectFacets 
                        = new HashSet<IProjectFacetVersion>();
        
                    newProjectFacets.addAll( this.facets.getItemSet() );
                    newProjectFacets.remove( fv );
                    
                    setProjectFacets( newProjectFacets );
                }
                else
                {
                    // TODO: needs exception msg
                    throw new IllegalArgumentException();
                }
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }

    public void changeProjectFacetVersion( final IProjectFacetVersion fv )
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                final IProjectFacetVersion existingVersion 
                    = this.facets.getItemByKey( fv.getProjectFacet() );
                
                if( existingVersion == null )
                {
                    // TODO: needs exception msg
                    throw new IllegalArgumentException();
                }
                else if( existingVersion == fv )
                {
                    return;
                }
                else
                {
                    final Set<IProjectFacetVersion> newProjectFacets 
                        = new HashSet<IProjectFacetVersion>();
        
                    newProjectFacets.addAll( this.facets.getItemSet() );
                    newProjectFacets.remove( existingVersion );
                    newProjectFacets.add( fv );
                    
                    setProjectFacets( newProjectFacets );
                }
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    private Set<IProjectFacetVersion> getBaseProjectFacets()
    {
        if( this.project == null )
        {
            return Collections.emptySet();
        }
        else
        {
            return this.project.getProjectFacets();
        }
    }
    
    public Set<IPreset> getAvailablePresets()
    {
        synchronized( this.lock )
        {
            return this.availablePresets.getItemSet();
        }
    }
    
    private void refreshAvailablePresets()
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                final IndexedSet<String,IPreset> newAvailablePresets = new IndexedSet<String,IPreset>();
                Map<String,Object> context = null;
                
                for( IPreset preset : ProjectFacetsManager.getPresets() )
                {
                    if( preset.getType() == IPreset.Type.DYNAMIC )
                    {
                        if( context == null )
                        {
                            context = new HashMap<String,Object>();
                            
                            context.put( IDynamicPreset.CONTEXT_KEY_FACETED_PROJECT, this );
                            
                            context.put( IDynamicPreset.CONTEXT_KEY_PRIMARY_RUNTIME, 
                                         this.primaryRuntime );
                            
                            context.put( IDynamicPreset.CONTEXT_KEY_FIXED_FACETS, 
                                         this.fixedFacets );
                        }
                        
                        preset = ( (IDynamicPreset) preset ).resolve( context );
                        
                        if( preset == null )
                        {
                            continue;
                        }
                    }
                    
                    final Set<IProjectFacetVersion> facets = preset.getProjectFacets();
                    boolean applicable = true;
                    
                    // All of the facets listed in the preset and their versions must be available.
                    
                    for( IProjectFacetVersion fv : facets )
                    {
                        if( ! isFacetAvailable( fv ) )
                        {
                            applicable = false;
                            break;
                        }
                    }
                    
                    // The preset must span across all of the fixed facets.
                    
                    for( IProjectFacet f : this.fixedFacets )
                    {
                        boolean found = false;
        
                        for( IProjectFacetVersion fv : f.getVersions() )
                        {
                            if( facets.contains( fv ) )
                            {
                                found = true;
                                break;
                            }
                        }
                        
                        if( ! found )
                        {
                            applicable = false;
                            break;
                        }
                    }
                    
                    if( applicable )
                    {
                        newAvailablePresets.addItemWithKey( preset.getId(), preset );
                    }
                }
                
                if( ! this.availablePresets.equals( newAvailablePresets ) )
                {
                    this.availablePresets = newAvailablePresets;
                    notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.AVAILABLE_PRESETS_CHANGED ) );
                    
                    if( this.selectedPresetId != null && 
                        ! this.availablePresets.containsKey( this.selectedPresetId ) )
                    {
                        setSelectedPreset( null );
                    }
                }
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    public IPreset getSelectedPreset()
    {
        synchronized( this.lock )
        {
            if( this.selectedPresetId != null )
            {
                return this.availablePresets.getItemByKey( this.selectedPresetId );
            }
            else
            {
                return null;
            }
        }
    }
    
    public void setSelectedPreset( final String presetId )
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                if( presetId != null && ! this.availablePresets.containsKey( presetId ) )
                {
                    final String msg = Resources.bind( Resources.couldNotSelectPreset, presetId ); 
                    throw new IllegalArgumentException( msg );
                }
                
                final IPreset preset = this.availablePresets.getItemByKey( presetId );
                
                if( ! equals( this.selectedPresetId, presetId ) || 
                    ( preset != null && ! equals( preset.getProjectFacets(), getProjectFacets() ) ) )
                {
                    if( preset != null )
                    {
                        // The following line keeps the setProjectFacets() call that comes next from 
                        // causing a preset change event from being generated. We want to avoid 
                        // firing two preset change events while presenting a consistent data 
                        // structure (the old preset isn't selected) to event handlers listening on 
                        // the facet change event.
                        
                        this.selectedPresetId = null;
                        
                        setProjectFacets( preset.getProjectFacets() );
                    }
                    
                    this.selectedPresetId = presetId;
                    
                    notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.SELECTED_PRESET_CHANGED ) );
                }
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    public IPreset getDefaultConfiguration()
    {
        synchronized( this.lock )
        {
            return this.availablePresets.getItemByKey( DefaultConfigurationPresetFactory.PRESET_ID );
        }
    }

    public IPreset getMinimalConfiguration()
    {
        synchronized( this.lock )
        {
            return this.availablePresets.getItemByKey( MinimalConfigurationPresetFactory.PRESET_ID );
        }
    }

    public Set<IRuntime> getTargetableRuntimes()
    {
        synchronized( this.lock )
        {
            return this.targetableRuntimes;
        }
    }
    
    public boolean isTargetable( final IRuntime runtime )
    {
        synchronized( this.lock )
        {
            return this.targetableRuntimes.contains( runtime );
        }
    }
    
    public void refreshTargetableRuntimes()
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                final Set<IRuntime> result = new HashSet<IRuntime>();
                
                for( IRuntime r : RuntimeManager.getRuntimes() )
                {
                    boolean ok = true;
                    
                    for( IProjectFacetVersion fv : this.facets.getItemSet() )
                    {
                        if( ! r.supports( fv ) )
                        {
                            ok = false;
                            break;
                        }
                    }
        
                    if( ok )
                    {
                        result.add( r );
                    }
                }
                
                if( ! this.targetableRuntimes.equals( result ) )
                {
                    this.targetableRuntimes.clear();
                    this.targetableRuntimes.addAll( result );
                    notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.TARGETABLE_RUNTIMES_CHANGED ) );
                    
                    final List<IRuntime> toRemove = new ArrayList<IRuntime>();
                    
                    for( IRuntime r : this.targetedRuntimes )
                    {
                        if( ! this.targetableRuntimes.contains( r ) )
                        {
                            toRemove.add( r );
                        }
                    }
                    
                    this.targetedRuntimes.removeAll( toRemove );
                    
                    if( ! toRemove.isEmpty() )
                    {
                        notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.TARGETED_RUNTIMES_CHANGED ) );
                        refreshAvailableFacets();
                        
                        if( this.primaryRuntime != null && 
                            ! this.targetableRuntimes.contains( this.primaryRuntime ) )
                        {
                            autoAssignPrimaryRuntime();
                        }
                    }
                }
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    public Set<IRuntime> getTargetedRuntimes()
    {
        synchronized( this.lock )
        {
            return this.targetedRuntimes;
        }
    }
    
    public boolean isTargeted( final IRuntime runtime )
    {
        synchronized( this.lock )
        {
            return this.targetedRuntimes.contains( runtime );
        }
    }
    
    public void setTargetedRuntimes( final Set<IRuntime> runtimes )
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                if( ! this.targetedRuntimes.equals( runtimes ) )
                {
                    this.targetedRuntimes.clear();
                    this.targetedRuntimes.addAll( runtimes );
                    
                    notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.TARGETED_RUNTIMES_CHANGED ) );
                    notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.PROJECT_MODIFIED ) );
                    refreshAvailableFacets();
                    
                    if( this.primaryRuntime == null ||
                        ! this.targetedRuntimes.contains( this.primaryRuntime ) )
                    {
                        autoAssignPrimaryRuntime();
                    }
                }
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    public void addTargetedRuntime( final IRuntime runtime )
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                if( runtime == null )
                {
                    throw new NullPointerException();
                }
                else
                {
                    this.targetedRuntimes.add( runtime );
                    
                    notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.TARGETED_RUNTIMES_CHANGED ) );
                    refreshAvailableFacets();
                    
                    if( this.primaryRuntime == null )
                    {
                        this.primaryRuntime = runtime;

                        notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.PRIMARY_RUNTIME_CHANGED ) );
                        refreshAvailablePresets();
                    }
                    
                    notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.PROJECT_MODIFIED ) );
                }
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    public void removeTargetedRuntime( final IRuntime runtime )
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                if( runtime == null )
                {
                    throw new NullPointerException();
                }
                else
                {
                    if( this.targetedRuntimes.remove( runtime ) )
                    {
                        notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.TARGETED_RUNTIMES_CHANGED ) );
                        refreshAvailableFacets();
                        
                        if( runtime.equals( this.primaryRuntime ) )
                        {
                            autoAssignPrimaryRuntime();
                        }
                        
                        notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.PROJECT_MODIFIED ) );
                    }
                }
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    public IRuntime getPrimaryRuntime()
    {
        synchronized( this.lock )
        {
            return this.primaryRuntime;
        }
    }
    
    public void setPrimaryRuntime( final IRuntime runtime )
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                if( ! equals( this.primaryRuntime, runtime ) )
                {
                    if( runtime == null && this.targetedRuntimes.size() > 0 )
                    {
                        throw new IllegalArgumentException();
                    }
                    
                    if( this.targetedRuntimes.contains( runtime ) )
                    {
                        this.primaryRuntime = runtime;
                    }
                    
                    notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.PRIMARY_RUNTIME_CHANGED ) );
                    refreshAvailablePresets();
                }
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    private void autoAssignPrimaryRuntime()
    {
        if( this.targetedRuntimes.isEmpty() )
        {
            this.primaryRuntime = null;
        }
        else
        {
            // Pick one to be the primary. No special semantics as to which 
            // one.
            
            this.primaryRuntime = this.targetedRuntimes.iterator().next();
        }

        notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.PRIMARY_RUNTIME_CHANGED ) );
        refreshAvailablePresets();
    }
    
    public Set<Action> getProjectFacetActions()
    {
        synchronized( this.lock )
        {
            return this.actions;
        }
    }
    
    public Action getProjectFacetAction( final IProjectFacet facet )
    {
        synchronized( this.lock )
        {
            return getProjectFacetAction( this.actions, null, facet );
        }
    }
    
    private static Action getProjectFacetAction( final Set<Action> actions,
                                                 final Action.Type type,
                                                 final IProjectFacetVersion fv )
    {
        for( Action action : actions )
        {
            if( ( type == null || action.getType() == type ) && 
                action.getProjectFacetVersion() == fv )
            {
                return action;
            }
        }
        
        return null;
    }
    
    private static Action getProjectFacetAction( final Set<Action> actions,
                                                 final Action.Type type,
                                                 final IProjectFacet f )
    {
        for( Action action : actions )
        {
            if( ( type == null || action.getType() == type ) && 
                action.getProjectFacetVersion().getProjectFacet() == f )
            {
                return action;
            }
        }
        
        return null;
    }
    
    private Action createProjectFacetAction( final Set<Action> actions,
                                             final Action.Type type,
                                             final IProjectFacetVersion fv )
    {
        Action action = getProjectFacetAction( actions, type, fv );
        
        if( action == null )
        {
            final Set<IProjectFacetVersion> base = getBaseProjectFacets();
            
            Object config = null;
            
            if( fv.supports( base, type ) )
            {
                try
                {
                    final IProjectFacet f = fv.getProjectFacet();
                    
                    action = getProjectFacetAction( actions, type, f );
                    
                    if( action != null )
                    {
                        final IProjectFacetVersion current
                            = action.getProjectFacetVersion();
                        
                        if( fv.supports( base, type ) &&
                            current.supports( base, type ) &&
                            fv.getActionDefinition( base, type )
                              == current.getActionDefinition( base, type ) )
                        {
                            config = action.getConfig();
                        }
                    }
                    
                    if( config == null )
                    {
                        final IActionDefinition def = fv.getActionDefinition( base, type );
                        config = def.createConfigObject();
                    }
                    
                    bindProjectFacetActionConfig( config, fv );
                }
                catch( CoreException e )
                {
                    FacetCorePlugin.log( e );
                }
            }

            action = new Action( type, fv, config );
        }
        
        return action;
    }
    
    private void bindProjectFacetActionConfig( final Object actionConfig,
                                               final IProjectFacetVersion fv )
    {
        if( actionConfig != null )
        {
            IActionConfig c1 = null;
            
            if( actionConfig instanceof IActionConfig )
            {
                c1 = (IActionConfig) actionConfig;
            }
            else if( actionConfig != null )
            {
                final IAdapterManager m 
                    = Platform.getAdapterManager();
                
                final String t
                    = IActionConfig.class.getName();
                
                c1 = (IActionConfig) m.loadAdapter( actionConfig, t );
            }
            
            if( c1 != null )
            {
                c1.setProjectName( getProjectName() );
                
                if( fv != null )
                {
                    c1.setVersion( fv );
                }
            }
            
            ActionConfig c2 = null;
            
            if( actionConfig instanceof ActionConfig )
            {
                c2 = (ActionConfig) actionConfig;
            }
            else if( actionConfig != null )
            {
                final IAdapterManager m = Platform.getAdapterManager();
                final String t = ActionConfig.class.getName();
                c2 = (ActionConfig) m.loadAdapter( actionConfig, t );
            }
            
            if( c2 != null )
            {
                c2.setFacetedProjectWorkingCopy( this );
                
                if( fv != null )
                {
                    c2.setProjectFacetVersion( fv );
                }
            }
        }
    }
    
    private void refreshProjectFacetActions()
    {
        final Set<IProjectFacetVersion> base = getBaseProjectFacets();
        final Set<IProjectFacetVersion> sel = getProjectFacets();
        final Set<Action> old = new HashSet<Action>( this.actions );
        final Set<Action> newActions = new HashSet<Action>();
        
        // What has been removed?
        
        for( IProjectFacetVersion fv : base )
        {
            if( ! sel.contains( fv ) )
            {
                newActions.add( createProjectFacetAction( old, Action.Type.UNINSTALL, fv ) );
            }
        }

        // What has been added?

        for( IProjectFacetVersion fv : sel )
        {
            if( ! base.contains( fv ) )
            {
                newActions.add( createProjectFacetAction( old, Action.Type.INSTALL, fv ) );
            }
        }
        
        // Coalesce uninstall/install pairs into version change actions, if
        // possible.
        
        final Set<Action> toadd = new HashSet<Action>();
        final Set<Action> toremove = new HashSet<Action>();
        
        for( Action action1 : newActions )
        {
            for( Action action2 : newActions )
            {
                if( action1.getType() == Action.Type.UNINSTALL &&
                    action2.getType() == Action.Type.INSTALL )
                {
                    final IProjectFacetVersion f1 = action1.getProjectFacetVersion();
                    final IProjectFacetVersion f2 = action2.getProjectFacetVersion();
                    
                    if( f1.getProjectFacet() == f2.getProjectFacet() )
                    {
                        toremove.add( action1 );
                        toremove.add( action2 );
                        toadd.add( createProjectFacetAction( old, Action.Type.VERSION_CHANGE, f2 ) );
                    }
                }
            }
        }
        
        newActions.removeAll( toremove );
        newActions.addAll( toadd );
        
        this.actions = newActions;
        
        for( Action action : toremove )
        {
            final Object actionConfig = action.getConfig();
            ActionConfig c = null;
            
            if( actionConfig instanceof ActionConfig )
            {
                c = (ActionConfig) actionConfig;
            }
            else if( actionConfig != null )
            {
                final IAdapterManager m = Platform.getAdapterManager();
                final String t = ActionConfig.class.getName();
                c = (ActionConfig) m.loadAdapter( actionConfig, t );
            }
            
            if( c != null )
            {
                c.dispose();
            }
        }
    }
    
    public void setProjectFacetActionConfig( final IProjectFacet facet,
                                             final Object newActionConfig )
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                final Action oldAction = getProjectFacetAction( facet );
                
                if( oldAction == null )
                {
                    throw new IllegalArgumentException();
                }
                
                final IProjectFacetVersion fv = oldAction.getProjectFacetVersion();
                final Action newAction = new Action( oldAction.getType(), fv, newActionConfig );
                bindProjectFacetActionConfig( newActionConfig, fv );
                
                this.actions.remove( oldAction );
                this.actions.add( newAction );
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    public void detect( IProgressMonitor monitor )
    {
        if( monitor == null )
        {
            monitor = new NullProgressMonitor();
        }
        
        monitor.beginTask( "", 1000 ); //$NON-NLS-1$
        
        try
        {
            final List<ProjectFacetDetector> detectors = ProjectFacetDetectorsExtensionPoint.getDetectors();
            monitor.worked( 100 );
            
            if( ! detectors.isEmpty() )
            {
                final IProgressMonitor submon = new SubProgressMonitor( monitor, 900 );
                submon.beginTask( "", detectors.size() ); //$NON-NLS-1$
                
                try
                {
                    for( ProjectFacetDetector detector : detectors )
                    {
                        if( monitor.isCanceled() )
                        {
                            return;
                        }
                        
                        final IProgressMonitor detectorProgressMonitor = new SubProgressMonitor( submon, 1 );

                        try
                        {
                            detector.detect( this, detectorProgressMonitor );
                        }
                        catch( Exception e )
                        {
                            FacetCorePlugin.log( e );
                        }
                        finally
                        {
                            detectorProgressMonitor.done();
                        }
                    }
                }
                finally
                {
                    submon.done();
                }
            }
        }
        finally
        {
            monitor.done();
        }
    }
    
    public void addListener( final IFacetedProjectListener listener,
                             final IFacetedProjectEvent.Type... types )
    {
        synchronized( this.lock )
        {
            if( types.length == 0 )
            {
                throw new IllegalArgumentException();
            }
            
            for( IFacetedProjectEvent.Type type : types )
            {
                this.listeners.get( type ).add( listener );
            }
        }
    }

    public void removeListener( final IFacetedProjectListener listener )
    {
        synchronized( this.lock )
        {
            for( List<IFacetedProjectListener> listeners : this.listeners.values() )
            {
                listeners.remove( listener );
            }
        }
    }

    private void notifyListeners( final IFacetedProjectEvent event )
    {
        List<IFacetedProjectListener> listenersToNotify = null;
        
        synchronized( this.lock )
        {
            if( this.suspendEventNoticationCounter == 0 )
            {
                listenersToNotify = this.listeners.get( event.getType() );
            }
            else
            {
                this.queuedEvents.add( event );
            }
        }
        
        if( listenersToNotify != null )
        {
            for( IFacetedProjectListener listener : listenersToNotify )
            {
                try
                {
                    listener.handleEvent( event );
                }
                catch( Exception e )
                {
                    FacetCorePlugin.log( e );
                }
            }
        }
    }
    
    private void suspendEventNotification()
    {
        synchronized( this.lock )
        {
            this.suspendEventNoticationCounter++;
        }
    }
    
    private void resumeEventNotification()
    {
        List<IFacetedProjectEvent> eventsToFire = null;
        
        synchronized( this.lock )
        {
            this.suspendEventNoticationCounter--;
            
            if( this.suspendEventNoticationCounter == 0 )
            {
                if( ! this.queuedEvents.isEmpty() )
                {
                    eventsToFire = new ArrayList<IFacetedProjectEvent>();
                    eventsToFire.addAll( this.queuedEvents );
                    this.queuedEvents.clear();
                }
            }
            else if( this.suspendEventNoticationCounter < 0 )
            {
                throw new IllegalStateException();
            }
        }
        
        if( eventsToFire != null )
        {
            for( IFacetedProjectEvent event : eventsToFire )
            {
                notifyListeners( event );
            }
        }
    }
    
    public IStatus validate( final IProgressMonitor monitor )
    {
        return validate();
    }
    
    public IStatus validate()
    {
        synchronized( this.lock )
        {
            final MultiStatus ms = Constraint.createMultiStatus();
            
            if( ! this.projectNameValidation.isOK() )
            {
                final StatusWrapper wrapper = new StatusWrapper( this.projectNameValidation );
                wrapper.setCode( PROBLEM_PROJECT_NAME );
                
                ms.add( wrapper );
            }
            
            for( IStatus st : this.problems )
            {
                final StatusWrapper wrapper = new StatusWrapper( st );
                wrapper.setCode( PROBLEM_OTHER );
                
                ms.add( wrapper );
            }
            
            for( IRuntime runtime : this.targetedRuntimes )
            {
                final IStatus st = runtime.validate( new NullProgressMonitor() );
                
                if( ! st.isOK() )
                {
                    final String msg 
                        = Resources.bind( Resources.invalidRuntimeMsg, runtime.getName(), 
                                          st.getMessage() );
                    
                    final StatusWrapper wrapper = new StatusWrapper( st );
                    wrapper.setMessage( msg );
                    
                    ms.add( wrapper );
                }
            }

            return ms;
        }
    }
    
    private void performValidation()
    {
        final Set<IProjectFacetVersion> base = getBaseProjectFacets();

        final List<IStatus> probs = new ArrayList<IStatus>();
        final MultiStatus ms = (MultiStatus) ProjectFacetsManager.check( base, this.actions );
        
        for( IStatus st : ms.getChildren() )
        {
            probs.add( st );
        }
        
        for( IProjectFacetVersion fv : base )
        {
            final IProjectFacet f = fv.getProjectFacet();
            
            String msg = null; 
            
            if( f.getPluginId() == null )
            {
                msg = NLS.bind( Resources.facetNotFound, f.getId() );
            }
            else if( fv.getPluginId() == null )
            {
                msg = NLS.bind( Resources.facetVersionNotFound, f.getId(), 
                                fv.getVersionString() );
            }
            
            if( msg != null )
            {
                final IStatus sub
                    = new Status( IStatus.WARNING, FacetCorePlugin.PLUGIN_ID, 0, msg, null );
                
                probs.add( sub );
            }
        }
        
        for( IRuntime r : getTargetedRuntimes() )
        {
            for( IProjectFacetVersion fv : getProjectFacets() )
            {
                if( ! r.supports( fv ) )
                {
                    final String msg
                        = NLS.bind( Resources.facetNotSupportedByTarget, fv.toString(), 
                                    r.getLocalizedName() );
                    
                    final IStatus sub
                        = new Status( IStatus.ERROR, FacetCorePlugin.PLUGIN_ID, 0, msg, null );
                    
                    probs.add( sub );
                }
            }
        }
        
        if( ! probs.equals( this.problems ) )
        {
            this.problems = probs;
            notifyListeners( new FacetedProjectEvent( this, IFacetedProjectEvent.Type.VALIDATION_PROBLEMS_CHANGED ) );
        }
    }
    
    public boolean isDirty()
    {
        if( this.project == null )
        {
            return true;
        }
        else
        {
            return ! equal( this.project.getFixedProjectFacets(), getFixedProjectFacets() ) ||
                   ! equal( this.project.getProjectFacets(), getProjectFacets() ) ||
                   ! equal( this.project.getTargetedRuntimes(), getTargetedRuntimes() ) ||
                   ! equal( this.project.getPrimaryRuntime(), getPrimaryRuntime() );
        }
    }
    
    private boolean equal( final Object obj1,
                           final Object obj2 )
    {
        return MiscUtil.equal( obj1, obj2 );
    }
    
    private boolean equal( final IRuntime r1,
                           final IRuntime r2 )
    {
        if( r1 == null && r2 == null )
        {
            return true;
        }
        else if( r1 == null || r2 == null )
        {
            return false;
        }
        else
        {
            return r1.getName().equals( r2.getName() );
        }
    }
    
    private boolean equal( final Set<IRuntime> set1,
                           final Set<IRuntime> set2 )
    {
        if( set1.size() != set2.size() )
        {
            return false;
        }
        else
        {
            for( IRuntime r1 : set1 )
            {
                boolean found = false;
                
                for( IRuntime r2 : set2 )
                {
                    if( r1.getName().equals( r2.getName() ) )
                    {
                        found = true;
                        break;
                    }
                }
                
                if( ! found )
                {
                    return false;
                }
            }
            
            return true;
        }
    }
    
    public void commitChanges( final IProgressMonitor monitor )
    
        throws CoreException
        
    {
        final SubMonitor pm = SubMonitor.convert( monitor, 100 );
        
        try
        {
            // In order to avoid deadlocks, we clone the working copy. This allows us to release
            // the lock on this working copy while running mergeChanges(). This is important since
            // mergeChanges() can call out to third-party code.
            
            final FacetedProjectWorkingCopy clone;
            
            synchronized( this.lock )
            {
                clone = (FacetedProjectWorkingCopy) clone();
            }
            
            try
            {
                final IFacetedProject fpj;
                    
                if( this.project == null )
                {
                    fpj = ProjectFacetsManager.create( this.projectName,
                                                       this.projectLocation, 
                                                       pm.newChild( 10, SubMonitor.SUPPRESS_ALL_LABELS ) );
                    
                    this.project = fpj;
                }
                else
                {
                    fpj = clone.getFacetedProject();
                    pm.worked( 10 );
                }
                
                ( (FacetedProject) fpj ).mergeChanges( clone, pm.newChild( 90 ) );
            }
            finally
            {
                clone.dispose();
            }
                
            // Reset the working copy so that it can be used again.
            
            synchronized( this.lock )
            {
                this.projectName = null;
                this.projectNameValidation = Status.OK_STATUS;
                this.projectLocation = null;
                
                revertChanges();
            }
        }
        finally
        {
            pm.done();
        }
    }
    
    public void mergeChanges( final IFacetedProjectWorkingCopy fpjwc )
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                setProjectName( fpjwc.getProjectName() );
                setProjectLocation( fpjwc.getProjectLocation() );
                setFixedProjectFacets( fpjwc.getFixedProjectFacets() );
                setProjectFacets( fpjwc.getProjectFacets() );
                setTargetedRuntimes( fpjwc.getTargetedRuntimes() );
                setPrimaryRuntime( fpjwc.getPrimaryRuntime() );
                
                final IPreset selectedPreset = fpjwc.getSelectedPreset();
                
                if( selectedPreset != null )
                {
                    setSelectedPreset( selectedPreset.getId() );
                }
                
                this.actions.clear();
                this.actions.addAll( ( (FacetedProjectWorkingCopy) fpjwc  ).actions );
                
                for( IFacetedProject.Action action : this.actions )
                {
                    bindProjectFacetActionConfig( action.getConfig(), null );
                }
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    public void revertChanges()
    {
        suspendEventNotification();
        
        try
        {
            synchronized( this.lock )
            {
                if( this.project != null )
                {
                    setFixedProjectFacets( this.project.getFixedProjectFacets() );
                    setTargetedRuntimes( Collections.<IRuntime>emptySet() );
                    setProjectFacets( this.project.getProjectFacets() );
                    setTargetedRuntimes( this.project.getTargetedRuntimes() );
                    setPrimaryRuntime( this.project.getPrimaryRuntime() );
                    this.actions.clear();
                }
                else
                {
                    throw new UnsupportedOperationException();
                }
            }
        }
        finally
        {
            resumeEventNotification();
        }
    }
    
    public IFacetedProjectWorkingCopy clone()
    {
        synchronized( this.lock )
        {
            final FacetedProjectWorkingCopy clone = new FacetedProjectWorkingCopy( this.project );
            
            if( this.project == null )
            {
                clone.setProjectName( getProjectName() );
                clone.setProjectLocation( getProjectLocation() );
            }
            
            clone.setFixedProjectFacets( getFixedProjectFacets() );
            clone.setProjectFacets( getProjectFacets() );
            clone.setTargetedRuntimes( getTargetedRuntimes() );
            clone.setPrimaryRuntime( getPrimaryRuntime() );
            
            final IPreset selectedPreset = getSelectedPreset();
            
            if( selectedPreset != null )
            {
                clone.setSelectedPreset( selectedPreset.getId() );
            }
            
            clone.actions.clear();
            clone.actions.addAll( this.actions );

            return clone;
        }
    }
    
    public void dispose()
    {
        synchronized( this.disposeTasks )
        {
            for( Runnable task : this.disposeTasks )
            {
                try
                {
                    task.run();
                }
                catch( Exception e )
                {
                    FacetCorePlugin.log( e );
                }
            }
        }
    }
    
    public void addDisposeTask( final Runnable task )
    {
        synchronized( this.disposeTasks )
        {
            this.disposeTasks.add( task );
        }
    }
    
    private static boolean equals( final Object obj1,
                                   final Object obj2 )
    {
        if( obj1 == obj2 )
        {
            return true;
        }
        else if( obj1 == null || obj2 == null )
        {
            return false;
        }
        else
        {
            return obj1.equals( obj2 );
        }
    }
    
    private static final class Resources
    
        extends NLS
        
    {
        public static String couldNotSelectPreset;
        public static String facetNotFound;
        public static String facetVersionNotFound;
        public static String facetNotSupportedByTarget;
        public static String invalidRuntimeMsg;
        public static String refreshingAvailableRuntimesJobName;
        
        static
        {
            initializeMessages( FacetedProjectWorkingCopy.class.getName(), 
                                Resources.class );
        }
    }

}
