Index: src/main/META-INF/components.xml
===================================================================
--- src/main/META-INF/components.xml	(revision 9520)
+++ src/main/META-INF/components.xml	(working copy)
@@ -23,8 +23,4 @@
 
   <factory name="org.jboss.seam.web.webSession" auto-create="true" scope="stateless" value="#{org.jboss.seam.web.session}" />
   
-  <factory name="facesMessages" auto-create="true" scope="stateless" value="#{org.jboss.seam.international.statusMessages}" />
-  
-  <factory name="org.jboss.seam.faces.facesMessages" auto-create="true" scope="stateless" value="#{org.jboss.seam.international.statusMessages}" />
-
 </components>
Index: src/main/org/jboss/seam/international/StatusMessages.java
===================================================================
--- src/main/org/jboss/seam/international/StatusMessages.java	(revision 9520)
+++ src/main/org/jboss/seam/international/StatusMessages.java	(working copy)
@@ -1,5 +1,6 @@
 package org.jboss.seam.international;
 
+import static org.jboss.seam.annotations.Install.BUILT_IN;
 import static org.jboss.seam.international.StatusMessage.Severity.INFO;
 import static org.jboss.seam.international.StatusMessage.Severity.WARN;
 
@@ -12,17 +13,30 @@
 import org.hibernate.validator.InvalidValue;
 import org.jboss.seam.Component;
 import org.jboss.seam.ScopeType;
+import org.jboss.seam.Seam;
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Observer;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
 import org.jboss.seam.contexts.Contexts;
+import org.jboss.seam.core.Instantiator;
 import org.jboss.seam.international.StatusMessage.Severity;
 
 /**
- * Abstract base class for providing status messages. View layers should provide
+ * Base class for providing status messages. View layers should provide
  * a concrete implementation.
  * 
  * @author Pete Muir
  *
  */
-public abstract class StatusMessages implements Serializable
+@Scope(ScopeType.CONVERSATION)
+@Name(StatusMessages.COMPONENT_NAME)
+@Install(precedence=BUILT_IN)
+@BypassInterceptors
+@AutoCreate
+public class StatusMessages extends Instantiator.RegisteredImplementation implements Serializable
 {
    private static final long serialVersionUID = -5395975397632138270L;
    
@@ -398,5 +412,16 @@
       }
       return (StatusMessages) Component.getInstance(COMPONENT_NAME, ScopeType.CONVERSATION);
    }
-
+   
+   @Override
+   protected Class getInstantiatorClass()
+   {
+      return StatusMessagesInstantiator.class;
+   }
+   
+   @Observer(StatusMessagesInstantiator.EVENT_REGISTER_IMPLEMENTATION)
+   public void registerImplementation(Instantiator<StatusMessages> instantiator) 
+   {
+      instantiator.registerImplementation(Seam.getComponentName(getClass()));
+   }
 }
Index: src/main/org/jboss/seam/international/StatusMessagesInstantiator.java
===================================================================
--- src/main/org/jboss/seam/international/StatusMessagesInstantiator.java	(revision 0)
+++ src/main/org/jboss/seam/international/StatusMessagesInstantiator.java	(revision 0)
@@ -0,0 +1,32 @@
+package org.jboss.seam.international;
+
+import static org.jboss.seam.ScopeType.APPLICATION;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.core.Instantiator;
+
+@Name("statusMessagesInstantiator")
+@Scope(APPLICATION)
+@BypassInterceptors
+@Install(precedence=BUILT_IN)
+public class StatusMessagesInstantiator extends Instantiator<StatusMessages>
+{
+   public static final String EVENT_REGISTER_IMPLEMENTATION = EVENT_REGISTER_IMPLEMENTATION_PREFIX + "StatusMessages";
+   
+	@Create
+	public void create() 
+	{
+	   findImplementations(StatusMessages.class);
+	}
+
+   @Override
+   protected String getDefaultComponent()
+   {
+      return StatusMessages.COMPONENT_NAME;
+   }
+}
Index: src/main/org/jboss/seam/faces/FacesMessages.java
===================================================================
--- src/main/org/jboss/seam/faces/FacesMessages.java	(revision 9520)
+++ src/main/org/jboss/seam/faces/FacesMessages.java	(working copy)
@@ -13,6 +13,7 @@
 
 import org.jboss.seam.Component;
 import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.AutoCreate;
 import org.jboss.seam.annotations.Install;
 import org.jboss.seam.annotations.Name;
 import org.jboss.seam.annotations.Scope;
@@ -30,12 +31,13 @@
  * @author Pete Muir
  */
 @Scope(ScopeType.CONVERSATION)
-@Name(StatusMessages.COMPONENT_NAME)
+@Name(FacesMessages.COMPONENT_NAME)
 @Install(precedence=BUILT_IN, classDependencies="javax.faces.context.FacesContext")
 @BypassInterceptors
+@AutoCreate
 public class FacesMessages extends StatusMessages
 {
-   
+   public static final String COMPONENT_NAME = "org.jboss.seam.faces.facesMessages";
    /**
     * Called by Seam to transfer messages from FacesMessages to JSF
     */
@@ -351,6 +353,12 @@
       {
          throw new IllegalStateException("No active conversation context");
       }
-      return (FacesMessages) Component.getInstance(StatusMessages.COMPONENT_NAME, ScopeType.CONVERSATION);
+      return (FacesMessages) Component.getInstance(FacesMessages.COMPONENT_NAME, ScopeType.CONVERSATION);
    }
+   
+   @Override
+   public boolean isActiveImplementation()
+   {
+      return FacesContext.getCurrentInstance() != null;
+   }
 }
Index: src/main/org/jboss/seam/faces/FacesManager.java
===================================================================
--- src/main/org/jboss/seam/faces/FacesManager.java	(revision 9520)
+++ src/main/org/jboss/seam/faces/FacesManager.java	(working copy)
@@ -42,11 +42,12 @@
  * @author <a href="mailto:theute@jboss.org">Thomas Heute</a>
  */
 @Scope(ScopeType.EVENT)
-@Name("org.jboss.seam.core.manager")
+@Name("org.jboss.seam.faces.facesManager")
 @Install(precedence=FRAMEWORK, classDependencies="javax.faces.context.FacesContext")
 @BypassInterceptors
 public class FacesManager extends Manager
 {
+   
    private static final LogProvider log = Logging.getLogProvider(FacesManager.class);
    
    
@@ -309,5 +310,11 @@
    {
       return (FacesManager) Manager.instance();
    }
-
+   
+   @Override
+   public boolean isActiveImplementation()
+   {
+      return FacesContext.getCurrentInstance() != null;
+   }
+   
 }
Index: src/main/org/jboss/seam/core/Manager.java
===================================================================
--- src/main/org/jboss/seam/core/Manager.java	(revision 9520)
+++ src/main/org/jboss/seam/core/Manager.java	(working copy)
@@ -19,9 +19,11 @@
 import org.jboss.seam.Component;
 import org.jboss.seam.ConcurrentRequestTimeoutException;
 import org.jboss.seam.ScopeType;
+import org.jboss.seam.Seam;
 import org.jboss.seam.annotations.FlushModeType;
 import org.jboss.seam.annotations.Install;
 import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Observer;
 import org.jboss.seam.annotations.Scope;
 import org.jboss.seam.annotations.intercept.BypassInterceptors;
 import org.jboss.seam.contexts.Contexts;
@@ -44,8 +46,10 @@
 @Name("org.jboss.seam.core.manager")
 @Install(precedence=BUILT_IN)
 @BypassInterceptors
-public class Manager
+public class Manager extends Instantiator.RegisteredImplementation
 {
+   
+   public static final String COMPONENT_NAME = "org.jboss.seam.core.manager";
    public static final String EVENT_CONVERSATION_TIMEOUT = "org.jboss.seam.conversationTimeout";
    public static final String EVENT_CONVERSATION_DESTROYED = "org.jboss.seam.conversationDestroyed";
    public static final String EVENT_CONVERSATION_BEGIN = "org.jboss.seam.beginConversation";
@@ -367,7 +371,7 @@
       {
          throw new IllegalStateException("No active event context");
       }
-      Manager instance = (Manager) Component.getInstance(Manager.class, ScopeType.EVENT);
+      Manager instance = (Manager) Component.getInstance(COMPONENT_NAME, ScopeType.EVENT);
       if (instance==null)
       {
          throw new IllegalStateException("No Manager could be created, make sure the Component exists in application scope");
@@ -1043,5 +1047,18 @@
    public void setUriEncoding(String encoding) {
        URIEncoding = encoding;
    }
+   
+   @Override
+   protected Class getInstantiatorClass()
+   {
+      return ManagerInstantiator.class;
+   }
 
+   @Observer(ManagerInstantiator.EVENT_REGISTER_IMPLEMENTATION)
+   public void registerImplementation(Instantiator<Manager> instantiator) 
+   {
+      instantiator.registerImplementation(Seam.getComponentName(getClass()));
+   }
+   
+   
 }
Index: src/main/org/jboss/seam/core/ManagerInstantiator.java
===================================================================
--- src/main/org/jboss/seam/core/ManagerInstantiator.java	(revision 0)
+++ src/main/org/jboss/seam/core/ManagerInstantiator.java	(revision 0)
@@ -0,0 +1,32 @@
+package org.jboss.seam.core;
+
+import static org.jboss.seam.ScopeType.APPLICATION;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+
+@Name("org.jboss.seam.core.managerInstantiator")
+@Scope(APPLICATION)
+@BypassInterceptors
+@Install(precedence=BUILT_IN)
+public class ManagerInstantiator extends Instantiator<Manager>
+{
+   
+   public static final String EVENT_REGISTER_IMPLEMENTATION = EVENT_REGISTER_IMPLEMENTATION_PREFIX + "Manager";
+   
+   @Create
+   public void create() 
+   {
+      findImplementations(Manager.class);
+   }
+   
+   @Override
+   public String getDefaultComponent() 
+   {
+      return Manager.COMPONENT_NAME;
+   }
+}
Index: src/main/org/jboss/seam/core/Instantiator.java
===================================================================
--- src/main/org/jboss/seam/core/Instantiator.java	(revision 0)
+++ src/main/org/jboss/seam/core/Instantiator.java	(revision 0)
@@ -0,0 +1,144 @@
+package org.jboss.seam.core;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.seam.Component;
+import org.jboss.seam.Seam;
+import org.jboss.seam.annotations.Unwrap;
+
+public abstract class Instantiator<T extends Instantiator.RegisteredImplementation>
+{
+   private List<String> registeredImplementations = new ArrayList<String>();
+
+   protected static final String EVENT_REGISTER_IMPLEMENTATION_PREFIX = "org.jboss.seam.core.registerImplementation.";
+   
+   protected boolean instantiating = false;
+   
+   
+   protected abstract String getDefaultComponent();
+   
+   public boolean isInstantiating()
+   {
+      return instantiating;
+   }
+
+   protected void findImplementations(Class clazz)
+   {
+      try 
+      { 
+         instantiating = true;
+         Events.instance().raiseEvent(EVENT_REGISTER_IMPLEMENTATION_PREFIX + clazz.getSimpleName(), this);
+      }
+      finally 
+      { 
+         instantiating = false;
+      }
+   }
+   
+   public void registerImplementation(String component) 
+   { 
+      registeredImplementations.add(component);
+   }
+
+   protected T selectImplementation() 
+   {
+      instantiating = true;
+      
+      try 
+      {
+	      List<T> active = new ArrayList<T>();
+	
+	      for (String possibleImplementation : registeredImplementations)
+	      {
+	         T instance = (T) Component.getInstance(possibleImplementation);
+	         if (instance.isActiveImplementation()) 
+	         { 
+	            active.add(instance);
+	         }
+	      }
+	
+	      T chosen = null;
+	      if (active.size() == 1)
+	      {
+	         chosen = active.get(0);
+	      }
+	      else if (active.size() == 0) 
+	      {
+	         chosen = (T) Component.getInstance(getDefaultComponent());
+	      }
+	      else
+	      {
+	         throw new IllegalStateException("Too many active components for " + getClass());
+	      }
+         chosen.setChosen(true);
+         Seam.getComponentScope(chosen.getClass()).getContext().set(getDefaultComponent(), chosen);
+         return chosen;
+
+      }
+      finally 
+      {
+         instantiating = false;
+      }
+   }
+   
+   public static abstract class RegisteredImplementation 
+   { 
+      
+      /**
+       * This is set on an implementation once it has been selected for a context, so that the unwrap method below
+       * knows that it doesn't need to choose a new implementation.
+       */
+      boolean chosen = false;
+      
+      /**
+       * Subclasses override this method to signal that they should be chosen as the implementation
+       */
+      public boolean isActiveImplementation() { return false; }
+
+      /**
+       * Subclasses return the class of the instantiator component that should be used to choose implementations for this
+       * component
+       */
+      protected abstract Class getInstantiatorClass();
+ 
+      private boolean instantiating = false;
+      
+      @Unwrap
+      public Object unwrap() 
+      {
+         if (chosen || instantiating)
+            return this;
+         try 
+         { 
+            instantiating = true;
+         
+	         Instantiator instantiator = (Instantiator) Component.getInstance(getInstantiatorClass());
+	         if (instantiator == null)
+	         {
+	            throw new IllegalStateException("No instantiator component exists of class " + getInstantiatorClass().getName()
+	                  + " in order to create component class " + getClass().getName());
+	         }
+	         
+            return instantiator.isInstantiating() ? this : instantiator.selectImplementation();
+         }
+         finally 
+         { 
+            instantiating = false;
+         }
+      }
+
+      public boolean isChosen()
+      {
+         return chosen;
+      }
+
+      public void setChosen(boolean chosen)
+      {
+         this.chosen = chosen;
+      }
+      
+      
+   }
+
+}
Index: src/wicket/org/jboss/seam/wicket/WicketManager.java
===================================================================
--- src/wicket/org/jboss/seam/wicket/WicketManager.java	(revision 9520)
+++ src/wicket/org/jboss/seam/wicket/WicketManager.java	(working copy)
@@ -1,21 +1,28 @@
 package org.jboss.seam.wicket;
 
 
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import org.apache.wicket.Application;
+import org.jboss.seam.Component;
 import org.jboss.seam.ScopeType;
 import org.jboss.seam.annotations.Install;
 import org.jboss.seam.annotations.Name;
 import org.jboss.seam.annotations.Scope;
 import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.contexts.Contexts;
 import org.jboss.seam.core.ConversationPropagation;
 import org.jboss.seam.core.Manager;
 
 @Scope(ScopeType.EVENT)
-@Name("org.jboss.seam.core.manager")
-@Install(precedence=100, classDependencies="org.apache.wicket.Application")
+@Name(WicketManager.COMPONENT_NAME)
+@Install(precedence=BUILT_IN, classDependencies="org.apache.wicket.Application")
 @BypassInterceptors
 public class WicketManager extends Manager
 {
    
+   public static final String COMPONENT_NAME = "org.jboss.seam.wicket.wicketManager";
+   
    public String appendConversationIdFromRedirectFilter(String url)
    {
       super.beforeRedirect();
@@ -28,6 +35,21 @@
    
    public static WicketManager instance()
    {
-      return (WicketManager) Manager.instance();
+      if ( !Contexts.isEventContextActive() )
+      {
+         throw new IllegalStateException("No active event context");
+      }
+      WicketManager instance = (WicketManager) Component.getInstance(COMPONENT_NAME, ScopeType.EVENT);
+      if (instance==null)
+      {
+         throw new IllegalStateException("No WicketManager could be created, make sure the Component exists in application scope");
+      }
+      return instance;
    }
+   
+   @Override
+   public boolean isActiveImplementation()
+   {
+      return Application.exists();
+   }
 }
Index: src/wicket/org/jboss/seam/wicket/international/WicketStatusMessages.java
===================================================================
--- src/wicket/org/jboss/seam/wicket/international/WicketStatusMessages.java	(revision 9520)
+++ src/wicket/org/jboss/seam/wicket/international/WicketStatusMessages.java	(working copy)
@@ -4,23 +4,23 @@
 
 import java.util.List;
 
-import org.jboss.seam.Component;
+import org.apache.wicket.Application;
 import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.AutoCreate;
 import org.jboss.seam.annotations.Install;
 import org.jboss.seam.annotations.Name;
 import org.jboss.seam.annotations.Scope;
 import org.jboss.seam.annotations.intercept.BypassInterceptors;
-import org.jboss.seam.contexts.Contexts;
 import org.jboss.seam.international.StatusMessage;
 import org.jboss.seam.international.StatusMessages;
 
 @Scope(ScopeType.CONVERSATION)
-@Name(StatusMessages.COMPONENT_NAME)
+@Name("org.jboss.seam.wicket.international.wicketStatusMessages")
 @Install(precedence=FRAMEWORK, classDependencies="org.apache.wicket.Application")
 @BypassInterceptors
+@AutoCreate
 public class WicketStatusMessages extends StatusMessages
 {
-   
    public void onBeforeRender()
    {
       doRunTasks();
@@ -38,11 +38,12 @@
    
    public static WicketStatusMessages instance()
    {
-      if ( !Contexts.isConversationContextActive() )
-      {
-         throw new IllegalStateException("No active conversation context");
-      }
-      return (WicketStatusMessages) Component.getInstance(StatusMessages.COMPONENT_NAME, ScopeType.CONVERSATION);
+      return (WicketStatusMessages) StatusMessages.instance();
    }
 
+   @Override
+   public boolean isActiveImplementation()
+   {
+      return Application.exists();
+   }
 }

