This commit was manufactured by cvs2svn to create tag 'v20051102'.
diff --git a/plugins/org.eclipse.wst.common.project.facet.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.wst.common.project.facet.core/META-INF/MANIFEST.MF
index 8e0cd48..3c475c1 100644
--- a/plugins/org.eclipse.wst.common.project.facet.core/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.wst.common.project.facet.core/META-INF/MANIFEST.MF
@@ -9,10 +9,7 @@
 Export-Package: org.eclipse.wst.common.project.facet.core,
  org.eclipse.wst.common.project.facet.core.internal;x-internal:=true,
  org.eclipse.wst.common.project.facet.core.runtime,
- org.eclipse.wst.common.project.facet.core.runtime.classpath,
- org.eclipse.wst.common.project.facet.core.runtime.classpath.internal;x-internal:=true,
  org.eclipse.wst.common.project.facet.core.runtime.internal;x-internal:=true
 Require-Bundle: org.eclipse.core.runtime,
- org.eclipse.core.resources,
- org.eclipse.jdt.core
+ org.eclipse.core.resources
 Eclipse-AutoStart: true
diff --git a/plugins/org.eclipse.wst.common.project.facet.core/schemas/facets.exsd b/plugins/org.eclipse.wst.common.project.facet.core/schemas/facets.exsd
index bd664cf..a3ad0c2 100644
--- a/plugins/org.eclipse.wst.common.project.facet.core/schemas/facets.exsd
+++ b/plugins/org.eclipse.wst.common.project.facet.core/schemas/facets.exsd
@@ -170,7 +170,7 @@
          <sequence>
             <element ref="constraint" minOccurs="0" maxOccurs="1"/>
             <element ref="group-member" minOccurs="0" maxOccurs="unbounded"/>
-            <element ref="delegate" minOccurs="0" maxOccurs="unbounded"/>
+            <element ref="action" minOccurs="0" maxOccurs="unbounded"/>
          </sequence>
          <attribute name="facet" type="string" use="required">
             <annotation>
@@ -201,44 +201,6 @@
       </complexType>
    </element>
 
-   <element name="delegate">
-      <complexType>
-         <attribute name="type" use="required">
-            <annotation>
-               <documentation>
-                  
-               </documentation>
-            </annotation>
-            <simpleType>
-               <restriction base="string">
-                  <enumeration value="install">
-                  </enumeration>
-                  <enumeration value="uninstall">
-                  </enumeration>
-                  <enumeration value="version-change">
-                  </enumeration>
-                  <enumeration value="runtime-changed">
-                  </enumeration>
-               </restriction>
-            </simpleType>
-         </attribute>
-         <attribute name="class" type="string">
-            <annotation>
-               <documentation>
-                  
-               </documentation>
-            </annotation>
-         </attribute>
-         <attribute name="noop" type="boolean">
-            <annotation>
-               <documentation>
-                  
-               </documentation>
-            </annotation>
-         </attribute>
-      </complexType>
-   </element>
-
    <element name="category">
       <complexType>
          <sequence>
@@ -293,7 +255,7 @@
       <complexType>
          <sequence>
             <element ref="label"/>
-            <element name="fixed" minOccurs="0" maxOccurs="unbounded">
+            <element name="fixed">
                <complexType>
                   <attribute name="facet" type="string" use="required">
                      <annotation>
@@ -304,7 +266,7 @@
                   </attribute>
                </complexType>
             </element>
-            <element name="preset" minOccurs="0" maxOccurs="1">
+            <element name="preset">
                <complexType>
                   <attribute name="id" type="string" use="required">
                      <annotation>
@@ -326,6 +288,58 @@
       </complexType>
    </element>
 
+   <element name="action">
+      <complexType>
+         <all>
+            <element ref="config-factory" minOccurs="0" maxOccurs="1"/>
+            <element ref="delegate"/>
+         </all>
+         <attribute name="type" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+            <simpleType>
+               <restriction base="string">
+                  <enumeration value="install">
+                  </enumeration>
+                  <enumeration value="uninstall">
+                  </enumeration>
+                  <enumeration value="version-change">
+                  </enumeration>
+                  <enumeration value="runtime-changed">
+                  </enumeration>
+               </restriction>
+            </simpleType>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="config-factory">
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="delegate">
+      <complexType>
+         <attribute name="class" type="string" use="required">
+            <annotation>
+               <documentation>
+                  
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
    <annotation>
       <appInfo>
          <meta.section type="since"/>
diff --git a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/IActionConfigFactory.java b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/IActionConfigFactory.java
new file mode 100644
index 0000000..70887af
--- /dev/null
+++ b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/IActionConfigFactory.java
@@ -0,0 +1,11 @@
+package org.eclipse.wst.common.project.facet.core;
+
+import org.eclipse.core.runtime.CoreException;
+
+public interface IActionConfigFactory
+{
+    Object create()
+    
+        throws CoreException;
+    
+}
diff --git a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/IProjectFacetVersion.java b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/IProjectFacetVersion.java
index 3dd5341..71b7323 100644
--- a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/IProjectFacetVersion.java
+++ b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/IProjectFacetVersion.java
@@ -11,6 +11,7 @@
 
 package org.eclipse.wst.common.project.facet.core;
 
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;
 
 /**
@@ -58,6 +59,22 @@
      *   action type, <code>false</code> otherwise
      */
     
-    boolean supports( Action.Type action );
+    boolean supports( Action.Type type );
+    
+    /**
+     * Creates a new instance of the config object associated with the specified
+     * action on this facet. Will return <code>null</code> if the action 
+     * requires no config.
+     * 
+     * @param type the type of the action.
+     * @return the action config object, or <code>null</code>
+     * @throws CoreException if this project facet version does not support the
+     *   specified action type or if failed while creating the action config
+     *   object
+     */
+    
+    Object createActionConfig( Action.Type type )
+    
+        throws CoreException;
     
 }
diff --git a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/FacetCorePlugin.java b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/FacetCorePlugin.java
index f1cf5ee..79074d7 100644
--- a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/FacetCorePlugin.java
+++ b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/FacetCorePlugin.java
@@ -43,9 +43,15 @@
     public static void log( final Exception e )
     {
         final ILog log = getInstance().getLog();
-        final String msg = e.getMessage();
+        final String msg = e.getMessage() + "";
         
         log.log( new Status( IStatus.ERROR, PLUGIN_ID, IStatus.OK, msg, e ) );
     }
     
+    public static IStatus createErrorStatus( final String msg )
+    {
+        return new Status( IStatus.ERROR, FacetCorePlugin.PLUGIN_ID, 0, msg, 
+                           null );
+    }
+    
 }
diff --git a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/FacetedProject.java b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/FacetedProject.java
index 95f6782..296f9dd 100644
--- a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/FacetedProject.java
+++ b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/FacetedProject.java
@@ -11,14 +11,15 @@
 
 package org.eclipse.wst.common.project.facet.core.internal;
 
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
 import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.PrintWriter;
-import java.io.Writer;
+import java.io.StringReader;
+import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
@@ -26,6 +27,12 @@
 import java.util.List;
 import java.util.Set;
 
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
@@ -41,6 +48,11 @@
 import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
 import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;
 import org.eclipse.wst.common.project.facet.core.runtime.RuntimeManager;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
 
 /**
  * @author <a href="mailto:kosta@bea.com">Konstantin Komissarchik</a>
@@ -57,7 +69,7 @@
     private final HashSet fixed;
     private final Set fixedReadOnly;
     private IRuntime runtime;
-    private final File f;
+    private final IFile f;
     
     FacetedProject( final IProject project )
     {
@@ -67,7 +79,9 @@
         this.fixed = new HashSet();
         this.fixedReadOnly = Collections.unmodifiableSet( this.fixed );
         this.runtime = null;
-        this.f = new File( project.getLocation().toFile(), ".facets" );
+        
+        this.f = project.getFile( ".settings/" + FacetCorePlugin.PLUGIN_ID 
+                                  + ".xml" );
         
         open();
     }
@@ -199,9 +213,16 @@
                         = monitor == null 
                           ? null : new SubProgressMonitor( monitor, 1 );
                     
-                    callDelegate( this.project, fv, action.getConfig(),
-                                  IDelegate.Type.get( action.getType() ),
-                                  delegate, submonitor );
+                    Object config = action.getConfig();
+                    
+                    if( config == null )
+                    {
+                        config = fv.createActionConfig( type );
+                    }
+                    
+                    callDelegate( this.project, fv, config,
+                                  IDelegate.Type.get( type ), delegate,
+                                  submonitor );
                 }
 
                 apply( this.facets, action );
@@ -323,7 +344,7 @@
             else
             {
                 cause = new Status( IStatus.ERROR, FacetCorePlugin.PLUGIN_ID,
-                                    0, e.getMessage(), e );
+                                    0, e.getMessage() + "", e );
             }
             
             final String msg;
@@ -392,6 +413,73 @@
         }
     }
     
+    private void save()
+    
+        throws CoreException
+        
+    {
+        final StringWriter w = new StringWriter();
+        final PrintWriter out = new PrintWriter( w );
+        
+        final String nl = System.getProperty( "line.separator" );
+        
+        out.print( "<faceted-project>" );
+        out.print( nl );
+        
+        if( this.runtime != null )
+        {
+            out.print( "  <runtime name=\"" );
+            out.print( this.runtime.getName() );
+            out.print( "\"/>" );
+            out.print( nl );
+        }
+        
+        for( Iterator itr = this.fixed.iterator(); itr.hasNext(); )
+        {
+            final IProjectFacet f = (IProjectFacet) itr.next();
+            
+            out.print( "  <fixed facet=\"" );
+            out.print( f.getId() );
+            out.print( "\"/>" );
+            out.print( nl );
+        }
+        
+        for( Iterator itr = this.facets.iterator(); itr.hasNext(); )
+        {
+            final IProjectFacetVersion fv
+                = (IProjectFacetVersion) itr.next();
+            
+            out.print( "  <installed facet=\"" );
+            out.print( fv.getProjectFacet().getId() );
+            out.print( "\" version=\"" );
+            out.print( fv.getVersionString() );
+            out.print( "\"/>" );
+            out.print( nl );
+        }
+        
+        out.print( "</faceted-project>" );
+        out.print( nl );
+        
+        final InputStream in 
+            = new ByteArrayInputStream( w.getBuffer().toString().getBytes() );
+        
+        if( this.f.exists() )
+        {
+            this.f.setContents( in, true, false, null );
+        }
+        else
+        {
+            final IFolder parent = (IFolder) this.f.getParent();
+            
+            if( ! parent.exists() )
+            {
+                parent.create( true, true, null );
+            }
+            
+            this.f.create( in, true, null );
+        }
+    }
+
     private void open()
     {
         if( ! this.f.exists() )
@@ -399,52 +487,86 @@
             return;
         }
         
-        BufferedReader in = null;
+        final Element root = parse( this.f.getLocation().toFile() );
+        final Element[] elements = children( root );
+        
+        for( int i = 0; i < elements.length; i++ )
+        {
+            final Element e = elements[ i ];
+            final String name = e.getNodeName();
+            
+            if( name.equals( "runtime" ) )
+            {
+                final String rn = e.getAttribute( "name" );
+                this.runtime = RuntimeManager.getRuntime( rn );
+            }
+            else if( name.equals( "fixed" ) )
+            {
+                // TODO: Handle the case where facet is not defined.
+                
+                final String fid = e.getAttribute( "facet" );
+                
+                final IProjectFacet f
+                    = ProjectFacetsManager.getProjectFacet( fid );
+                
+                this.fixed.add( f );
+            }
+            else if( name.equals( "installed" ) )
+            {
+                // TODO: Handle the case where facet or version is not defined.
+                
+                final String id = e.getAttribute( "facet" );
+                final String version = e.getAttribute( "version" );
+                
+                final IProjectFacet f
+                    = ProjectFacetsManager.getProjectFacet( id );
+                
+                final IProjectFacetVersion fv = f.getVersion( version );
+                
+                this.facets.add( fv );
+            }
+        }
+    }
+    
+    private static Element parse( final File f )
+    {
+        final DocumentBuilder docbuilder;
         
         try
         {
-            in = new BufferedReader( new FileReader( this.f ) );
+            final DocumentBuilderFactory factory 
+                = DocumentBuilderFactory.newInstance();
             
-            for( String line = in.readLine(); line != null; 
-                 line = in.readLine() )
-            {
-                if( line.startsWith( "r:" ) )
+            factory.setValidating( false );
+            
+            docbuilder = factory.newDocumentBuilder();
+            
+            docbuilder.setEntityResolver
+            (
+                new EntityResolver()
                 {
-                    final String name = line.substring( 2 );
-                    this.runtime = RuntimeManager.getRuntime( name );
-                }
-                else if( line.startsWith( "f:" ) )
-                {
-                    final IProjectFacet f
-                        = ProjectFacetsManager.getProjectFacet( line.substring( 2 ) );
-                    
-                    this.fixed.add( f );
-                }
-                else
-                {
-                    final int colon = line.indexOf( ':' );
-                    
-                    if( colon == -1 )
+                    public InputSource resolveEntity( final String publicID, 
+                                                      final String systemID )
                     {
-                        // TODO: Handle this.
-                        continue;
+                        return new InputSource( new StringReader( "" ) );
                     }
-                    
-                    final String name = line.substring( 0, colon );
-                    final String version = line.substring( colon + 1 );
-                    
-                    // TODO: Handle the case where the facet is not available.
-                    
-                    final IProjectFacetVersion fv
-                        = ProjectFacetsManager.getProjectFacet( name ).getVersion( version );
-    
-                    this.facets.add( fv );
                 }
-            }
+            );
         }
-        catch( IOException e )
+        catch( ParserConfigurationException e )
         {
-            // TODO: Handle this better.
+            throw new RuntimeException( e );
+        }
+
+        InputStream in = null;
+
+        try
+        {
+            in = new BufferedInputStream( new FileInputStream( f ) );
+            return docbuilder.parse( in ).getDocumentElement();
+        }
+        catch( Exception e )
+        {
             throw new RuntimeException( e );
         }
         finally
@@ -460,60 +582,22 @@
         }
     }
     
-    private void save()
+    private Element[] children( final Element element )
     {
-        PrintWriter out = null;
+        final List list = new ArrayList();
+        final NodeList nl = element.getChildNodes();
         
-        try
+        for( int i = 0, n = nl.getLength(); i < n; i++ )
         {
-            final Writer w = new BufferedWriter( new FileWriter( this.f ) );
-            out = new PrintWriter( w );
+            final Node node = nl.item( i );
             
-            if( this.runtime != null )
+            if( node.getNodeType() == Node.ELEMENT_NODE )
             {
-                out.print( "r:" );
-                out.println( this.runtime.getName() );
-            }
-            
-            for( Iterator itr = this.fixed.iterator(); itr.hasNext(); )
-            {
-                final IProjectFacet f = (IProjectFacet) itr.next();
-                
-                out.print( "f:" );
-                out.println( f.getId() );
-            }
-            
-            for( Iterator itr = this.facets.iterator(); itr.hasNext(); )
-            {
-                final IProjectFacetVersion fv
-                    = (IProjectFacetVersion) itr.next();
-                
-                out.print( fv.getProjectFacet().getId() );
-                out.print( ':' );
-                out.println( fv.getVersionString() );
-            }
-        }
-        catch( IOException e )
-        {
-            // TODO: Handle this better.
-            throw new RuntimeException( e );
-        }
-        finally
-        {
-            if( out != null )
-            {
-                out.close();
+                list.add( node );
             }
         }
         
-        try
-        {
-            this.project.refreshLocal( 1, null );
-        }
-        catch( CoreException e )
-        {
-            // TODO: Report this.
-        }
+        return (Element[]) list.toArray( new Element[ list.size() ] );
     }
     
     private static final class Resources
@@ -528,7 +612,7 @@
         
         static
         {
-            initializeMessages( Constraint.class.getName(), 
+            initializeMessages( FacetedProject.class.getName(), 
                                 Resources.class );
         }
     }
diff --git a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/ProjectFacetVersion.java b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/ProjectFacetVersion.java
index 2c104c9..afffd00 100644
--- a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/ProjectFacetVersion.java
+++ b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/ProjectFacetVersion.java
@@ -13,7 +13,10 @@
 
 import java.util.HashMap;
 
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.Platform;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.common.project.facet.core.IActionConfigFactory;
 import org.eclipse.wst.common.project.facet.core.IConstraint;
 import org.eclipse.wst.common.project.facet.core.IDelegate;
 import org.eclipse.wst.common.project.facet.core.IProjectFacet;
@@ -37,6 +40,7 @@
     private IConstraint constraint;
     private String plugin;
     private final HashMap delegates = new HashMap();
+    private final HashMap configFactories = new HashMap();    
     
     ProjectFacetVersion() {}
     
@@ -80,11 +84,60 @@
         this.plugin = plugin;
     }
     
+    public boolean supports( final Action.Type type )
+    {
+        return this.delegates.containsKey( IDelegate.Type.get( type ) );
+    }
+    
+    public Object createActionConfig( final Action.Type type )
+    
+        throws CoreException
+        
+    {
+        if( ! supports( type ) )
+        {
+            final String msg 
+                = NLS.bind( Resources.actionNotSupported, toString(), 
+                            type.toString() );
+            
+            throw new CoreException( FacetCorePlugin.createErrorStatus( msg ) );
+        }
+        
+        final String clname 
+            = (String) this.configFactories.get( IDelegate.Type.get( type ) );
+        
+        if( clname == null )
+        {
+            return null;
+        }
+        else
+        {
+            final Object temp = create( clname );
+            
+            if( ! ( temp instanceof IActionConfigFactory ) )
+            {
+                final String msg
+                    = NLS.bind( Resources.notInstanceOf, clname,
+                                IActionConfigFactory.class.getName() );
+                
+                throw new CoreException( FacetCorePlugin.createErrorStatus( msg ) );
+            }
+            
+            return ( (IActionConfigFactory) temp ).create();
+        }
+    }
+    
+    void setActionConfigFactory( final IDelegate.Type type,
+                                 final String configFactoryClassName )
+    {
+        this.configFactories.put( type, configFactoryClassName );
+    }
+    
     IDelegate getDelegate( final IDelegate.Type type )
     {
         Object delegate = this.delegates.get( type );
         
-        if( delegate == null || delegate == ProjectFacetsManagerImpl.NOOP )
+        if( delegate == null )
         {
             return null;
         }
@@ -111,11 +164,6 @@
         this.delegates.put( type, delegateClassName );
     }
     
-    public boolean supports( final Action.Type type )
-    {
-        return this.delegates.containsKey( IDelegate.Type.get( type ) );
-    }
-    
     private Object create( final String clname )
     {
         final Bundle bundle = Platform.getBundle( this.plugin );
@@ -136,5 +184,20 @@
     {
         return this.facet.getLabel() + " " + this.version;
     }
+    
+    private static final class Resources
+    
+        extends NLS
+        
+    {
+        public static String actionNotSupported;
+        public static String notInstanceOf;
+        
+        static
+        {
+            initializeMessages( ProjectFacetVersion.class.getName(), 
+                                Resources.class );
+        }
+    }
 
 }
diff --git a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/ProjectFacetVersion.properties b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/ProjectFacetVersion.properties
new file mode 100644
index 0000000..6cdd97c
--- /dev/null
+++ b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/ProjectFacetVersion.properties
@@ -0,0 +1,2 @@
+actionNotSupported = Project facet {0} does not support action type {1}.
+notInstanceOf = Class {0} is not an instance of {1}.
diff --git a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/ProjectFacetsManagerImpl.java b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/ProjectFacetsManagerImpl.java
index f7bdc61..78c159c 100644
--- a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/ProjectFacetsManagerImpl.java
+++ b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/internal/ProjectFacetsManagerImpl.java
@@ -58,7 +58,6 @@
 
 public final class ProjectFacetsManagerImpl
 {
-    static final String NOOP = "#noop#";
     private static final String EXTENSION_ID = "facets";
     
     private final IndexedSet facets;
@@ -977,61 +976,84 @@
                 
                 group.addMember( fv );
             }
-            else if( childName.equals( "delegate" ) )
+            else if( childName.equals( "action" ) )
             {
-                final String type = child.getAttribute( "type" );
-                IDelegate.Type t = null;
-                
-                if( type == null )
-                {
-                    // TODO: error
-                }
-                else if( type.equals( "install" ) )
-                {
-                    t = IDelegate.Type.INSTALL;
-                }
-                else if( type.equals( "uninstall" ) )
-                {
-                    t = IDelegate.Type.UNINSTALL;
-                }
-                else if( type.equals( "version-change" ) )
-                {
-                    t = IDelegate.Type.VERSION_CHANGE; 
-                }
-                else if( type.equals( "runtime-changed" ) )
-                {
-                    t = IDelegate.Type.RUNTIME_CHANGED;
-                }
-                else
-                {
-                    // TODO: error
-                }
-
-                final String noop = child.getAttribute( "noop" );
-                
-                if( noop != null && noop.equalsIgnoreCase( "true" ) )
-                {
-                    fv.setDelegate( t, NOOP );
-                }
-                else
-                {
-                    final String clname = child.getAttribute( "class" );
-
-                    if( clname == null )
-                    {
-                        // TODO: error
-                    }
-                    
-                    fv.setDelegate( t, clname );
-                }
+                readAction( child, fv );
             }
         }
         
         f.addVersion( fv );
     }
+
+    private void readAction( final IConfigurationElement config,
+                             final ProjectFacetVersion fv )
+    {
+        final String type = config.getAttribute( "type" );
+        IDelegate.Type t = null;
+        
+        if( type == null )
+        {
+            // TODO: error
+        }
+        else if( type.equals( "install" ) )
+        {
+            t = IDelegate.Type.INSTALL;
+        }
+        else if( type.equals( "uninstall" ) )
+        {
+            t = IDelegate.Type.UNINSTALL;
+        }
+        else if( type.equals( "version-change" ) )
+        {
+            t = IDelegate.Type.VERSION_CHANGE; 
+        }
+        else if( type.equals( "runtime-changed" ) )
+        {
+            t = IDelegate.Type.RUNTIME_CHANGED;
+        }
+        else
+        {
+            // TODO: error
+        }
+
+        final IConfigurationElement[] children = config.getChildren();
+        
+        for( int i = 0; i < children.length; i++ )
+        {
+            final IConfigurationElement child = children[ i ];
+            final String childName = child.getName();
+            
+            if( childName.equals( "config-factory" ) )
+            {
+                final String clname = child.getAttribute( "class" );
+                
+                if( clname == null )
+                {
+                    // TODO: error
+                }
+                
+                fv.setActionConfigFactory( t, clname );
+            }
+            else if( childName.equals( "delegate" ) )
+            {
+                final String clname = child.getAttribute( "class" );
+                
+                if( clname == null )
+                {
+                    // TODO: error
+                }
+                
+                fv.setDelegate( t, clname );
+            }
+            else
+            {
+                // TODO: error
+            }
+        }
+    }
     
     private IConstraint readConstraint( final IConfigurationElement root,
-                                                      final ProjectFacetVersion desc )
+                                        final ProjectFacetVersion fv )
     {
         final IConstraint.Type type
             = IConstraint.Type.get( root.getName() );
@@ -1046,7 +1068,7 @@
             
             for( int i = 0; i < children.length; i++ )
             {
-                operands[ i ] = readConstraint( children[ i ], desc );
+                operands[ i ] = readConstraint( children[ i ], fv );
             }
         }
         else if( type == IConstraint.Type.REQUIRES )
@@ -1099,7 +1121,7 @@
             throw new IllegalStateException();
         }
         
-        return new Constraint( desc, type, operands );
+        return new Constraint( fv, type, operands );
     }
     
     private void readTemplate( final IConfigurationElement config )
diff --git a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/RuntimeManager.java b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/RuntimeManager.java
index 3f8cd3b..6bcb428 100644
--- a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/RuntimeManager.java
+++ b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/RuntimeManager.java
@@ -163,13 +163,4 @@
         return RuntimeManagerImpl.createRuntimeComponent( rcv, properties );
     }
     
-    /**
-     * Caution: experimental.
-     */
-    
-    public static void bridge()
-    {
-        RuntimeManagerImpl.bridge();
-    }
-    
 }
diff --git a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/classpath/ClasspathHelper.java b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/classpath/ClasspathHelper.java
deleted file mode 100644
index 81e8917..0000000
--- a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/classpath/ClasspathHelper.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/******************************************************************************
- * Copyright (c) 2005 BEA Systems, Inc.
- * 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:
- *    Konstantin Komissarchik - initial API and implementation
- ******************************************************************************/
-
-package org.eclipse.wst.common.project.facet.core.runtime.classpath;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.ProjectScope;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.preferences.IEclipsePreferences;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.eclipse.wst.common.project.facet.core.IFacetedProject;
-import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
-import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
-import org.eclipse.wst.common.project.facet.core.internal.FacetCorePlugin;
-import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;
-import org.osgi.service.prefs.BackingStoreException;
-import org.osgi.service.prefs.Preferences;
-
-/**
- * <p>A utility used in conjunction with IClasspathProvider in order to manage
- * the bookkeeping when project facets are installed and uninstalled, and when
- * the bound runtime changes. This utility tracks which classpath entries were
- * added to the project by which facet and stores this information in a project
- * metadata file. This enables the classpath entries to be removed without
- * knowing what they are. It is only necessary to know which facet added them.
- * This utility supports the case where the same classpath entry is added by
- * multiple project facets. In this situation, a classpath entry is only
- * removed when the removal has been requested for all of the facets that added
- * it.</p>
- * 
- * <p>Typically the project facet author will write something like this in the
- * install delegate:</p>
- * 
- * <pre>
- * if( ! ClasspathHelper.addClasspathEntries( project, fv )
- * {
- *     // Handle the case when there is no bound runtime or when the bound
- *     // runtime cannot provide classpath entries for this facet.
- *     
- *     final List alternate = ...;
- *     ClasspathHelper.addClasspathEntries( project, fv, alternate );
- * }
- * </pre>
- * 
- * <p>And something like this in the uninstall delegate:</p>
- * 
- * <pre>
- * ClasspathHelper.removeClasspathEntries( project, fv );
- * </pre>
- * 
- * <p>And something like this in the runtime changed delegate:</p>
- * 
- * <pre>
- * ClasspathHelper.removeClasspathEntries( project, fv );
- * 
- * if( ! ClasspathHelper.addClasspathEntries( project, fv )
- * {
- *     // Handle the case when there is no bound runtime or when the bound
- *     // runtime cannot provide classpath entries for this facet.
- *     
- *     final List alternate = ...;
- *     ClasspathHelper.addClasspathEntries( project, fv, alternate );
- * }
- * </pre>
- * 
- * <p>And something like this in the version change delegate:</p>
- * 
- * <pre>
- * final IProjectFacetVersion oldver
- *   = fproj.getInstalledVersion( fv.getProjectFacet() );
- * 
- * ClasspathHelper.removeClasspathEntries( project, oldver );
- * 
- * if( ! ClasspathHelper.addClasspathEntries( project, fv )
- * {
- *     // Handle the case when there is no bound runtime or when the bound
- *     // runtime cannot provide classpath entries for this facet.
- *     
- *     final List alternate = ...;
- *     ClasspathHelper.addClasspathEntries( project, fv, alternate );
- * }
- * </pre>
- * 
- * @author <a href="mailto:kosta@bea.com">Konstantin Komissarchik</a>
- */
-
-public final class ClasspathHelper
-{
-    private static final Object SYSTEM_OWNER = new Object();
-    
-    private ClasspathHelper() {}
-    
-    /**
-     * Convenience method for adding to the project the classpath entries
-     * provided for the specified project facet by the runtime bound to the
-     * project. The entries are marked as belonging to the specified project
-     * facet.
-     *   
-     * @param project the project
-     * @param fv the project facet version that will own these entries
-     * @return <code>true</code> if classpath entries were added, or
-     *   <code>false</code> if there is no runtime bound to the project or if
-     *   it cannot provide classpath entries for the specified facet
-     * @throws CoreException if failed while adding the classpath entries
-     */
-    
-    public static boolean addClasspathEntries( final IProject project,
-                                               final IProjectFacetVersion fv )
-    
-        throws CoreException
-        
-    {
-        final IFacetedProject fproj 
-            = ProjectFacetsManager.create( project );
-    
-        final IRuntime runtime = fproj.getRuntime();
-        
-        if( runtime != null )
-        {
-            final IClasspathProvider cpprov 
-                = (IClasspathProvider) runtime.getAdapter( IClasspathProvider.class );
-            
-            final List cpentries = cpprov.getClasspathEntries( fv );
-            
-            if( cpentries != null )
-            {
-                addClasspathEntries( project, fv, cpentries );
-                return true;
-            }
-        }
-        
-        return false;
-    }
-    
-    /**
-     * Add the provided classpath entries to project and marks them as belonging
-     * to the specified project facet.
-     * 
-     * @param project the project
-     * @param fv the project facet version that will own these entries
-     * @param cpentries the classpath entries (element type: 
-     *   {@see IClasspathEntry})
-     * @throws CoreException if failed while adding the classpath entries
-     */
-    
-    public static void addClasspathEntries( final IProject project,
-                                            final IProjectFacetVersion fv,
-                                            final List cpentries )
-    
-        throws CoreException
-        
-    {
-        try
-        {
-            final IJavaProject jproj = JavaCore.create( project );
-            final List cp = getClasspath( jproj );
-            boolean cpchanged = false;
-
-            final Map prefs = readPreferences( project );
-            
-            for( Iterator itr = cpentries.iterator(); itr.hasNext(); )
-            {
-                final IClasspathEntry cpentry = (IClasspathEntry) itr.next();
-                final IPath path = cpentry.getPath();
-                
-                final boolean contains = cp.contains( cpentry );
-                
-                Set owners = (Set) prefs.get( path );
-                
-                if( owners == null )
-                {
-                    owners = new HashSet();
-
-                    if( contains )
-                    {
-                        owners.add( SYSTEM_OWNER );
-                    }
-                    
-                    prefs.put( path, owners );
-                }
-                
-                owners.add( fv );
-                
-                if( ! contains )
-                {
-                    cp.add( cpentry );
-                    cpchanged = true;
-                }
-            }
-            
-            if( cpchanged )
-            {
-                setClasspath( jproj, cp );
-            }
-            
-            writePreferences( project, prefs );
-        }
-        catch( BackingStoreException e )
-        {
-            // TODO: throw CoreException here
-            throw new RuntimeException( e );
-        }
-    }
-    
-    /**
-     * Removes the classpath entries belonging to the specified project facet.
-     * Any entries that also belong to another facet are left in place.
-     * 
-     * @param project the project
-     * @param fv the project facet that owns the entries that should be removed
-     * @throws CoreException if failed while removing classpath entries
-     */
-    
-    public static void removeClasspathEntries( final IProject project,
-                                               final IProjectFacetVersion fv )
-    
-        throws CoreException
-        
-    {
-        try
-        {
-            final IJavaProject jproj = JavaCore.create( project );
-            final List cp = getClasspath( jproj );
-            boolean cpchanged = false;
-
-            final Map prefs = readPreferences( project );
-            
-            for( Iterator itr1 = prefs.entrySet().iterator(); itr1.hasNext(); )
-            {
-                final Map.Entry entry = (Map.Entry) itr1.next();
-                final IPath path = (IPath) entry.getKey();
-                final Set owners = (Set) entry.getValue();
-                
-                if( owners.contains( fv ) )
-                {
-                    owners.remove( fv );
-                    
-                    if( owners.size() == 0 )
-                    {
-                        itr1.remove();
-                        
-                        for( Iterator itr2 = cp.iterator(); itr2.hasNext(); )
-                        {
-                            final IClasspathEntry cpentry
-                                = (IClasspathEntry) itr2.next();
-                            
-                            if( cpentry.getPath().equals( path ) )
-                            {
-                                itr2.remove();
-                                cpchanged = true;
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-
-            if( cpchanged )
-            {
-                setClasspath( jproj, cp );
-            }
-            
-            writePreferences( project, prefs );
-        }
-        catch( BackingStoreException e )
-        {
-            // TODO: throw CoreException here
-            throw new RuntimeException( e );
-        }
-    }
-    
-    private static List getClasspath( final IJavaProject jproj )
-    
-        throws CoreException
-        
-    {
-        final ArrayList list = new ArrayList();
-        final IClasspathEntry[] cp = jproj.getRawClasspath();
-        
-        for( int i = 0; i < cp.length; i++ )
-        {
-            list.add( cp[ i ] );
-        }
-        
-        return list;
-    }
-    
-    private static void setClasspath( final IJavaProject jproj,
-                                      final List cp )
-    
-        throws CoreException
-        
-    {
-        final IClasspathEntry[] newcp
-            = (IClasspathEntry[]) cp.toArray( new IClasspathEntry[ cp.size() ] );
-        
-        jproj.setRawClasspath( newcp, null );
-    }
-    
-    private static Map readPreferences( final IProject project )
-    
-        throws BackingStoreException
-        
-    {
-        final Preferences root = getPreferencesNode( project );
-        final Map result = new HashMap();
-        
-        final String[] keys = root.childrenNames();
-        
-        for( int i = 0; i < keys.length; i++ )
-        {
-            final String key = keys[ i ];
-            final Preferences node = root.node( key );
-            
-            final String owners = node.get( "owners", null );
-            final String[] split = owners.split( ";" );
-            final Set set = new HashSet();
-            
-            for( int j = 0; j < split.length; j++ )
-            {
-                final String segment = split[ j ];
-                
-                if( segment.equals( "#system#" ) )
-                {
-                    set.add( SYSTEM_OWNER );
-                }
-                else
-                {
-                    final IProjectFacetVersion fv 
-                        = parseFeatureVersion( segment );
-                    
-                    set.add( fv );
-                }
-            }
-            
-            result.put( decode( key ), set );
-        }
-        
-        return result;
-    }
-    
-    private static void writePreferences( final IProject project,
-                                          final Map prefs )
-    
-        throws BackingStoreException
-        
-    {
-        final Preferences root = getPreferencesNode( project );
-        final String[] children = root.childrenNames();
-        
-        for( int i = 0; i < children.length; i++ )
-        {
-            root.node( children[ i ] ).removeNode();
-        }
-        
-        for( Iterator itr1 = prefs.entrySet().iterator(); itr1.hasNext(); )
-        {
-            final Map.Entry entry = (Map.Entry) itr1.next();
-            final IPath path = (IPath) entry.getKey();
-            final Set owners = (Set) entry.getValue();
-            
-            final StringBuffer buf = new StringBuffer();
-            
-            for( Iterator itr2 = owners.iterator(); itr2.hasNext(); )
-            {
-                final Object owner = itr2.next();
-
-                if( buf.length() > 0 ) 
-                {
-                    buf.append( ';' );
-                }
-                
-                if( owner == SYSTEM_OWNER )
-                {
-                    buf.append( "#system#" );
-                }
-                else
-                {
-                    final IProjectFacetVersion fv 
-                        = (IProjectFacetVersion) owner;
-                    
-                    buf.append( fv.getProjectFacet().getId() );
-                    buf.append( ':' );
-                    buf.append( fv.getVersionString() );
-                }
-            }
-
-            final Preferences node = root.node( encode( path ) );
-            node.put( "owners", buf.toString() );
-        }
-        
-        root.flush();
-    }
-    
-    
-    private static Preferences getPreferencesNode( final IProject project )
-    {
-        final ProjectScope scope = new ProjectScope( project );
-        
-        final IEclipsePreferences pluginRoot 
-            = scope.getNode( FacetCorePlugin.PLUGIN_ID );
-        
-        return pluginRoot.node( "classpath.helper" );
-    }
-    
-    private static IProjectFacetVersion parseFeatureVersion( final String str )
-    {
-        final int colon = str.indexOf( ':' );
-        final String id = str.substring( 0, colon );
-        final String ver = str.substring( colon + 1 );
-        
-        return ProjectFacetsManager.getProjectFacet( id ).getVersion( ver );
-    }
-    
-    private static String encode( final IPath path )
-    {
-        return path.toString().replaceAll( "/", "::" );
-    }
-    
-    private static IPath decode( final String path )
-    {
-        return new Path( path.replaceAll( "::", "/" ) );
-    }
-    
-
-}
diff --git a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/classpath/IClasspathProvider.java b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/classpath/IClasspathProvider.java
deleted file mode 100644
index 2ce2206..0000000
--- a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/classpath/IClasspathProvider.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/******************************************************************************
- * Copyright (c) 2005 BEA Systems, Inc.
- * 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:
- *    Konstantin Komissarchik - initial API and implementation
- ******************************************************************************/
-
-package org.eclipse.wst.common.project.facet.core.runtime.classpath;
-
-import java.util.List;
-
-import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
-
-/**
- * The iterface implemented by a runtime component adapter in order to provide
- * classpath entries for project facets. For convenience, the runtime can also
- * be adapted to this interface. That adapter will delegate to the runtime 
- * components in the order that they are listed in the runtime. The first one 
- * that can provide classpath entries for the specified project facet wins. 
- * 
- * @author <a href="mailto:kosta@bea.com">Konstantin Komissarchik</a>
- */
-
-public interface IClasspathProvider
-{
-    /**
-     * Returns the classpath entries for the specified project facet.
-     * 
-     * @param fv the project facet version
-     * @return returns the classpath entries for the specified project facet
-     *   (element type: {@see org.eclipse.jdt.core.IClasspathEntry}), or
-     *   <code>null</code> if this provider does not provide classpath entries
-     *   for the given project facet
-     */
-    
-    List getClasspathEntries( IProjectFacetVersion fv );
-    
-}
diff --git a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/classpath/internal/RuntimeClasspathProvider.java b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/classpath/internal/RuntimeClasspathProvider.java
deleted file mode 100644
index 50d5e82..0000000
--- a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/classpath/internal/RuntimeClasspathProvider.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/******************************************************************************
- * Copyright (c) 2005 BEA Systems, Inc.
- * 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:
- *    Konstantin Komissarchik - initial API and implementation
- ******************************************************************************/
-
-package org.eclipse.wst.common.project.facet.core.runtime.classpath.internal;
-
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.core.runtime.IAdapterFactory;
-import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
-import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;
-import org.eclipse.wst.common.project.facet.core.runtime.IRuntimeComponent;
-import org.eclipse.wst.common.project.facet.core.runtime.classpath.IClasspathProvider;
-
-/**
- * @author <a href="mailto:kosta@bea.com">Konstantin Komissarchik</a>
- */
-
-public final class RuntimeClasspathProvider
-
-    implements IClasspathProvider
-    
-{
-    private final IRuntime r;
-    
-    public RuntimeClasspathProvider( final IRuntime r )
-    {
-        this.r = r;
-    }
-
-    public List getClasspathEntries( final IProjectFacetVersion fv )
-    {
-        for( Iterator itr = this.r.getRuntimeComponents().iterator(); 
-             itr.hasNext(); )
-        {
-            final IRuntimeComponent rc = (IRuntimeComponent) itr.next();
-            
-            final IClasspathProvider cpprov 
-                = (IClasspathProvider) rc.getAdapter( IClasspathProvider.class );
-            
-            if( cpprov != null )
-            {
-                final List cp = cpprov.getClasspathEntries( fv );
-                
-                if( cp != null )
-                {
-                    return cp;
-                }
-            }
-        }
-        
-        return null;
-    }
-    
-    public static final class Factory
-    
-        implements IAdapterFactory
-        
-    {
-        private static final Class[] ADAPTER_TYPES
-            = { IClasspathProvider.class };
-        
-        public Object getAdapter( final Object adaptable, 
-                                  final Class adapterType )
-        {
-            if( adapterType == IClasspathProvider.class )
-            {
-                return new RuntimeClasspathProvider( (IRuntime) adaptable );
-            }
-            else
-            {
-                return null;
-            }
-        }
-
-        public Class[] getAdapterList()
-        {
-            return ADAPTER_TYPES;
-        }
-    }
-
-}
diff --git a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/internal/RuntimeManagerImpl.java b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/internal/RuntimeManagerImpl.java
index 04d980d..2440886 100644
--- a/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/internal/RuntimeManagerImpl.java
+++ b/plugins/org.eclipse.wst.common.project.facet.core/src/org/eclipse/wst/common/project/facet/core/runtime/internal/RuntimeManagerImpl.java
@@ -108,11 +108,14 @@
     
     public static Set getRuntimes()
     {
-        return runtimes.getUnmodifiable();
+        bridge();
+        return (Set) runtimes.clone();
     }
     
     public static Set getRuntimes( final Set facets )
     {
+        bridge();
+        
         final HashSet result = new HashSet();
         
         for( Iterator itr1 = runtimes.iterator(); itr1.hasNext(); )
@@ -140,11 +143,13 @@
     
     public static boolean isRuntimeDefined( final String name )
     {
+        bridge();
         return runtimes.containsKey( name );
     }
     
     public static IRuntime getRuntime( final String name )
     {
+        bridge();
         final IRuntime runtime = (IRuntime) runtimes.get( name );
         
         if( runtime == null )
@@ -248,20 +253,31 @@
         return result;
     }
     
-    public static void bridge()
+    private static boolean bridging = false;
+    
+    private static void bridge()
     {
-        try
+        if( ! bridging )
         {
-            // This is just a hack that needs to be replaced as soon as possible.
+            bridging = true;
             
-            final Bundle bundle = Platform.getBundle( "org.eclipse.jst.server.core" );
-            
-            final Class cl = bundle.loadClass( "org.eclipse.jst.server.core.internal.RuntimeBridge" );
-            ( (IRuntimeBridge) cl.newInstance() ).port();
-        }
-        catch( Exception e )
-        {
-            FacetCorePlugin.log( e );
+            try
+            {
+                // This is just a hack that needs to be replaced as soon as possible.
+                
+                final Bundle bundle = Platform.getBundle( "org.eclipse.jst.server.core" );
+                
+                final Class cl = bundle.loadClass( "org.eclipse.jst.server.core.internal.RuntimeBridge" );
+                ( (IRuntimeBridge) cl.newInstance() ).port();
+            }
+            catch( Exception e )
+            {
+                FacetCorePlugin.log( e );
+            }
+            finally
+            {
+                bridging = false;
+            }
         }
     }
     
diff --git a/plugins/org.eclipse.wst.common.project.facet.ui/plugin.xml b/plugins/org.eclipse.wst.common.project.facet.ui/plugin.xml
index 2a29953..e22d8da 100644
--- a/plugins/org.eclipse.wst.common.project.facet.ui/plugin.xml
+++ b/plugins/org.eclipse.wst.common.project.facet.ui/plugin.xml
@@ -23,5 +23,5 @@
         id="org.eclipse.wst.common.project.facet.ui.AddRemoveProjectFacetsMenuAction"/>
     </objectContribution>
   </extension>
-   
+  
 </plugin>
diff --git a/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/AbstractFacetWizardPage.java b/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/AbstractFacetWizardPage.java
index fc614cb..130ded1 100644
--- a/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/AbstractFacetWizardPage.java
+++ b/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/AbstractFacetWizardPage.java
@@ -35,4 +35,9 @@
         this.context = context;
     }
     
+    public void transferStateToConfig()
+    {
+        
+    }
+    
 }
diff --git a/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/ProjectFacetsUiManager.java b/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/ProjectFacetsUiManager.java
index 68c801b..3af155a 100644
--- a/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/ProjectFacetsUiManager.java
+++ b/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/ProjectFacetsUiManager.java
@@ -28,12 +28,6 @@
     
     private ProjectFacetsUiManager() {}
     
-    public static Object getConfig( final Action.Type actionType,
-                                    final IProjectFacetVersion f )
-    {
-        return impl.getConfig( actionType, f );
-    }
-    
     /**
      * @return (element type: {@see IFacetWizardPage})
      */
diff --git a/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/internal/FacetsSelectionPanel.java b/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/internal/FacetsSelectionPanel.java
index f8fd299..51b9357 100644
--- a/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/internal/FacetsSelectionPanel.java
+++ b/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/internal/FacetsSelectionPanel.java
@@ -20,6 +20,7 @@
 import java.util.List;
 import java.util.Set;
 
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.Status;
@@ -48,6 +49,7 @@
 import org.eclipse.jface.viewers.TableViewer;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.SashForm;
 import org.eclipse.swt.events.SelectionAdapter;
@@ -78,7 +80,6 @@
 import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
 import org.eclipse.wst.common.project.facet.core.IFacetedProject.Action;
 import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;
-import org.eclipse.wst.common.project.facet.ui.ProjectFacetsUiManager;
 import org.osgi.framework.Bundle;
 
 /**
@@ -468,14 +469,27 @@
     
     private Action createAction( final Set actions,
                                  final Action.Type type,
-                                 final IProjectFacetVersion f )
+                                 final IProjectFacetVersion fv )
     {
-        Action action = getAction( actions, type, f );
+        Action action = getAction( actions, type, fv );
         
         if( action == null )
         {
-            final Object config = ProjectFacetsUiManager.getConfig( type, f );
-            action = new Action( type, f, config );
+            Object config = null;
+            
+            if( fv.supports( type ) )
+            {
+                try
+                {
+                    config = fv.createActionConfig( type );
+                }
+                catch( CoreException e )
+                {
+                    FacetUiPlugin.log( e );
+                }
+            }
+
+            action = new Action( type, fv, config );
         }
         
         return action;
@@ -1434,22 +1448,70 @@
 
             if( iconPath == null )
             {
-                plugin = FacetUiPlugin.PLUGIN_ID;
-                iconPath = "images/unknown.gif";
+                return getDefaultImage();
             }
-
+            else
+            {
+                return getImage( plugin, iconPath );
+            }
+        }
+        
+        private Image getImage( final String plugin,
+                                final String iconPath )
+        {
             final String key = plugin + ":" + iconPath;
             Image image = this.imageRegistry.get( key );
 
             if( image == null )
             {
-                final Bundle bundle = Platform.getBundle( plugin );
-                final URL url = bundle.getEntry( iconPath );
-
-                this.imageRegistry.put( key, ImageDescriptor.createFromURL( url ) );
-                image = this.imageRegistry.get( key );
+                Bundle bundle = Platform.getBundle( plugin );
+                URL url = bundle.getEntry( iconPath );
+                
+                if( url == null )
+                {
+                    final String msg 
+                        = Resources.bind( Resources.iconNotFound, plugin,
+                                          iconPath );
+                    
+                    final IStatus status
+                        = new Status( IStatus.ERROR, FacetUiPlugin.PLUGIN_ID,
+                                      0, msg, null );
+                    
+                    FacetUiPlugin.getInstance().getLog().log( status );
+                    
+                    image = getDefaultImage();
+                    this.imageRegistry.put( key, image );
+                }
+                else
+                {
+                    this.imageRegistry.put( key, ImageDescriptor.createFromURL( url ) );
+                    image = this.imageRegistry.get( key );
+                }
             }
+            
+            return image;
+        }
+        
+        private static final String DEFAULT_IMG_KEY = "#DEFAULT#";
+        private static final String DEFAULT_IMG_LOCATION = "images/unknown.gif";
+        
+        private Image getDefaultImage()
+        {
+            Image image = this.imageRegistry.get( DEFAULT_IMG_KEY );
 
+            if( image == null )
+            {
+                final Bundle bundle 
+                    = Platform.getBundle( FacetUiPlugin.PLUGIN_ID );
+                
+                final URL url = bundle.getEntry( DEFAULT_IMG_LOCATION );
+                
+                this.imageRegistry.put( DEFAULT_IMG_KEY, 
+                                        ImageDescriptor.createFromURL( url ) );
+                
+                image = this.imageRegistry.get( DEFAULT_IMG_KEY );
+            }
+            
             return image;
         }
 
@@ -1669,6 +1731,20 @@
         public void removeListener( ILabelProviderListener listener ) {}
     }
     
+    private static final class Resources
+    
+        extends NLS
+        
+    {
+        public static String iconNotFound;
+        
+        static
+        {
+            initializeMessages( FacetsSelectionPanel.class.getName(), 
+                                Resources.class );
+        }
+    }
+    
     private static final GridData gdfill()
     {
         return new GridData( SWT.FILL, SWT.FILL, true, true );
diff --git a/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/internal/FacetsSelectionPanel.properties b/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/internal/FacetsSelectionPanel.properties
new file mode 100644
index 0000000..72cedb3
--- /dev/null
+++ b/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/internal/FacetsSelectionPanel.properties
@@ -0,0 +1 @@
+iconNotFound = Could not load icon "{1}" from plugin {0}.
\ No newline at end of file
diff --git a/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/internal/ProjectFacetsUiManagerImpl.java b/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/internal/ProjectFacetsUiManagerImpl.java
index 22ee9f8..2c516b5 100644
--- a/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/internal/ProjectFacetsUiManagerImpl.java
+++ b/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/internal/ProjectFacetsUiManagerImpl.java
@@ -44,24 +44,6 @@
         readExtensions();
     }
     
-    public Object getConfig( final Action.Type actionType,
-                             final IProjectFacetVersion f )
-    {
-        final WizardPagesInfo info = (WizardPagesInfo) this.metadata.get( f );
-        
-        if( info != null )
-        {
-            final String clname = (String) info.configs.get( actionType );
-            
-            if( clname != null )
-            {
-                return create( info.plugin, clname );
-            }
-        }
-        
-        return null;
-    }
-    
     /**
      * @return (element type: {@see IFacetWizardPage})
      */
@@ -201,40 +183,12 @@
                 throw new IllegalStateException();
             }
             
-            info.configs.put( actionType, readConfigClass( child ) );
             info.pagesets.put( actionType, readPageList( child ) );
         }
         
         this.metadata.put( fv, info );
     }
 
-    private String readConfigClass( final IConfigurationElement config )
-    {
-        final IConfigurationElement[] children = config.getChildren();
-        
-        for( int i = 0; i < children.length; i++ )
-        {
-            final IConfigurationElement child = children[ i ];
-            final String childName = child.getName();
-            
-            if( childName.equals( "config" ) )
-            {
-                final String clname = child.getAttribute( "class" );
-                
-                if( clname == null )
-                {
-                    // TODO: handle this better.
-                    throw new IllegalStateException();
-                }
-                
-                return clname;
-            }
-        }
-
-        // TODO: handle this better.
-        throw new IllegalStateException();
-    }
-    
     private List readPageList( final IConfigurationElement config )
     {
         final ArrayList list = new ArrayList();
@@ -265,7 +219,6 @@
     private static class WizardPagesInfo
     {
         public String plugin;
-        public HashMap configs = new HashMap();
         public HashMap pagesets = new HashMap();
     }
     
diff --git a/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/internal/RuntimesPanel.java b/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/internal/RuntimesPanel.java
index e85a98d..bc68570 100644
--- a/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/internal/RuntimesPanel.java
+++ b/plugins/org.eclipse.wst.common.project.facet.ui/src/org/eclipse/wst/common/project/facet/ui/internal/RuntimesPanel.java
@@ -304,8 +304,6 @@
         {
             final Set res = new HashSet();
             
-            RuntimeManager.bridge();
-            
             for( Iterator itr1 = RuntimeManager.getRuntimes().iterator();
                  itr1.hasNext(); )
             {