[webbeans-commits] Webbeans SVN: r2279 - in ri/trunk: impl/src/main/java/org/jboss/webbeans/bean and 2 other directories.

webbeans-commits at lists.jboss.org webbeans-commits at lists.jboss.org
Tue Mar 31 03:38:19 EDT 2009


Author: danielc.roth
Date: 2009-03-31 03:38:18 -0400 (Tue, 31 Mar 2009)
New Revision: 2279

Added:
   ri/trunk/impl/src/main/java/org/jboss/webbeans/bean/DisposalMethodBean.java
Modified:
   ri/trunk/impl/src/main/java/org/jboss/webbeans/RootManager.java
   ri/trunk/impl/src/main/java/org/jboss/webbeans/bean/ProducerMethodBean.java
   ri/trunk/impl/src/main/java/org/jboss/webbeans/bootstrap/BeanDeployer.java
   ri/trunk/impl/src/main/java/org/jboss/webbeans/bootstrap/BeanDeployerEnvironment.java
   ri/trunk/tests/src/test/java/org/jboss/webbeans/test/unit/implementation/NewEnterpriseBeanTest.java
Log:
Initial Disposal Method commit


Modified: ri/trunk/impl/src/main/java/org/jboss/webbeans/RootManager.java
===================================================================
--- ri/trunk/impl/src/main/java/org/jboss/webbeans/RootManager.java	2009-03-31 03:54:17 UTC (rev 2278)
+++ ri/trunk/impl/src/main/java/org/jboss/webbeans/RootManager.java	2009-03-31 07:38:18 UTC (rev 2279)
@@ -1,1043 +1,1044 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,  
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jboss.webbeans;
-
-import java.io.InputStream;
-import java.io.Serializable;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.util.ArrayList;
-import java.util.Arrays;
-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.Stack;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
-import javax.context.Context;
-import javax.context.ContextNotActiveException;
-import javax.context.CreationalContext;
-import javax.event.Observer;
-import javax.inject.AmbiguousDependencyException;
-import javax.inject.BindingType;
-import javax.inject.DeploymentException;
-import javax.inject.DuplicateBindingTypeException;
-import javax.inject.Production;
-import javax.inject.Standard;
-import javax.inject.TypeLiteral;
-import javax.inject.UnproxyableDependencyException;
-import javax.inject.UnsatisfiedDependencyException;
-import javax.inject.manager.Bean;
-import javax.inject.manager.Decorator;
-import javax.inject.manager.InjectionPoint;
-import javax.inject.manager.InterceptionType;
-import javax.inject.manager.Interceptor;
-import javax.inject.manager.Manager;
-
-import org.jboss.webbeans.bean.EnterpriseBean;
-import org.jboss.webbeans.bean.NewEnterpriseBean;
-import org.jboss.webbeans.bean.RIBean;
-import org.jboss.webbeans.bean.proxy.ClientProxyProvider;
-import org.jboss.webbeans.bootstrap.api.ServiceRegistry;
-import org.jboss.webbeans.context.ApplicationContext;
-import org.jboss.webbeans.context.ContextMap;
-import org.jboss.webbeans.context.CreationalContextImpl;
-import org.jboss.webbeans.ejb.EjbDescriptorCache;
-import org.jboss.webbeans.event.EventManager;
-import org.jboss.webbeans.event.ObserverImpl;
-import org.jboss.webbeans.injection.NonContextualInjector;
-import org.jboss.webbeans.injection.resolution.ResolvableAnnotatedClass;
-import org.jboss.webbeans.injection.resolution.Resolver;
-import org.jboss.webbeans.introspector.AnnotatedItem;
-import org.jboss.webbeans.introspector.AnnotatedMethod;
-import org.jboss.webbeans.log.Log;
-import org.jboss.webbeans.log.Logging;
-import org.jboss.webbeans.manager.api.WebBeansManager;
-import org.jboss.webbeans.metadata.MetaDataCache;
-import org.jboss.webbeans.resources.spi.NamingContext;
-import org.jboss.webbeans.util.Beans;
-import org.jboss.webbeans.util.Reflections;
-
-/**
- * Implementation of the Web Beans Manager.
- * 
- * Essentially a singleton for registering Beans, Contexts, Observers,
- * Interceptors etc. as well as providing resolution
- * 
- * @author Pete Muir
- * 
- */
-public class RootManager implements WebBeansManager, Serializable
-{
-   
-   private static final Log log = Logging.getLog(RootManager.class);
-   
-   private static final long serialVersionUID = 3021562879133838561L;
-   
-   // The JNDI key to place the manager under
-   public static final String JNDI_KEY = "java:app/Manager";
-   
-   // The enabled deployment types from web-beans.xml
-   private transient List<Class<? extends Annotation>> enabledDeploymentTypes;
-   // The Web Beans event manager
-   private transient final EventManager eventManager;
-   
-   // An executor service for asynchronous tasks
-   private transient final ExecutorService taskExecutor = Executors.newSingleThreadExecutor();
-   
-   // An injection point metadata beans factory
-   private transient final ThreadLocal<Stack<InjectionPoint>> currentInjectionPoint;
-   
-   // The bean resolver
-   private transient final Resolver resolver;
-   
-   // The registered contexts
-   private transient final ContextMap contextMap;
-   // The client proxy pool
-   private transient final ClientProxyProvider clientProxyProvider;
-   // The registered beans
-   private transient List<Bean<?>> beans;
-   // The registered beans, mapped by implementation class
-   private transient final Map<Class<?>, EnterpriseBean<?>> newEnterpriseBeanMap;
-   
-   private transient final Map<String, RIBean<?>> riBeans;
-   
-   // The registered decorators
-   private transient final Set<Decorator> decorators;
-   // The registered interceptors
-   private transient final Set<Interceptor> interceptors;
-   
-   // The EJB resolver provided by the container
-   private transient final ServiceRegistry simpleServiceRegistry;
-   
-   private transient final EjbDescriptorCache ejbDescriptorCache;
-   
-   private final transient Map<Bean<?>, Bean<?>> specializedBeans;
-   
-   private final transient NonContextualInjector nonContextualInjector;
-   
-   /**
-    * Create a new manager
-    * 
-    * @param ejbServices
-    *           the ejbResolver to use
-    */
-   public RootManager(ServiceRegistry simpleServiceRegistry)
-   {
-      this.simpleServiceRegistry = simpleServiceRegistry;
-      this.beans = new CopyOnWriteArrayList<Bean<?>>();
-      this.newEnterpriseBeanMap = new ConcurrentHashMap<Class<?>, EnterpriseBean<?>>();
-      this.riBeans = new ConcurrentHashMap<String, RIBean<?>>();
-      this.resolver = new Resolver(this);
-      this.clientProxyProvider = new ClientProxyProvider();
-      this.decorators = new HashSet<Decorator>();
-      this.interceptors = new HashSet<Interceptor>();
-      this.contextMap = new ContextMap();
-      this.eventManager = new EventManager();
-      this.ejbDescriptorCache = new EjbDescriptorCache();
-      this.currentInjectionPoint = new ThreadLocal<Stack<InjectionPoint>>()
-      {
-         @Override
-         protected Stack<InjectionPoint> initialValue()
-         {
-            return new Stack<InjectionPoint>();
-         }
-      };
-      this.specializedBeans = new HashMap<Bean<?>, Bean<?>>();
-      this.nonContextualInjector = new NonContextualInjector(this);
-      List<Class<? extends Annotation>> defaultEnabledDeploymentTypes = new ArrayList<Class<? extends Annotation>>();
-      defaultEnabledDeploymentTypes.add(0, Standard.class);
-      defaultEnabledDeploymentTypes.add(1, Production.class);
-      setEnabledDeploymentTypes(defaultEnabledDeploymentTypes);
-   }
-   
-   /**
-    * Set up the enabled deployment types, if none are specified by the user,
-    * the default @Production and @Standard are used. For internal use.
-    * 
-    * @param enabledDeploymentTypes
-    *           The enabled deployment types from web-beans.xml
-    */
-   protected void checkEnabledDeploymentTypes()
-   {
-      if (!this.enabledDeploymentTypes.get(0).equals(Standard.class))
-      {
-         throw new DeploymentException("@Standard must be the lowest precedence deployment type");
-      }
-   }
-   
-   protected void addWebBeansDeploymentTypes()
-   {
-      if (!this.enabledDeploymentTypes.contains(WebBean.class))
-      {
-         this.enabledDeploymentTypes.add(1, WebBean.class);
-      }
-   }
-   
-   /**
-    * Registers a bean with the manager
-    * 
-    * @param bean
-    *           The bean to register
-    * @return A reference to manager
-    * 
-    * @see javax.inject.manager.Manager#addBean(javax.inject.manager.Bean)
-    */
-   public Manager addBean(Bean<?> bean)
-   {
-      if (beans.contains(bean))
-      {
-         return this;
-      }
-      resolver.clear();
-      beans.add(bean);
-      return this;
-   }
-   
-   /**
-    * Resolve the disposal method for the given producer method. For internal
-    * use.
-    * 
-    * @param apiType
-    *           The API type to match
-    * @param bindings
-    *           The binding types to match
-    * @return The set of matching disposal methods
-    */
-   public <T> Set<AnnotatedMethod<?>> resolveDisposalMethods(Class<T> apiType, Annotation... bindings)
-   {
-      return Collections.emptySet();
-   }
-   
-   /**
-    * Resolves observers for given event and bindings
-    * 
-    * @param event
-    *           The event to match
-    * @param bindings
-    *           The binding types to match
-    * @return The set of matching observers
-    * 
-    * @see javax.inject.manager.Manager#resolveObservers(java.lang.Object,
-    *      java.lang.annotation.Annotation[])
-    */
-   @SuppressWarnings("unchecked")
-   public <T> Set<Observer<T>> resolveObservers(T event, Annotation... bindings)
-   {
-      Class<?> clazz = event.getClass();
-      for (Annotation annotation : bindings)
-      {
-         if (!MetaDataCache.instance().getBindingTypeModel(annotation.annotationType()).isValid())
-         {
-            throw new IllegalArgumentException("Not a binding type " + annotation);
-         }
-      }
-      HashSet<Annotation> bindingAnnotations = new HashSet<Annotation>(Arrays.asList(bindings));
-      if (bindingAnnotations.size() < bindings.length)
-      {
-         throw new DuplicateBindingTypeException("Duplicate binding types: " + bindings);
-      }
-      Type t = new Reflections.HierarchyDiscovery(clazz).getResolvedType();
-      for (Type type : Reflections.getActualTypeArguments(clazz))
-      {
-         if (type instanceof WildcardType)
-         {
-            throw new IllegalArgumentException("Cannot resolve an event type parameterized with a wildcard " + clazz);
-         }
-         if (type instanceof TypeVariable)
-         {
-            throw new IllegalArgumentException("Cannot resolve an event type parameterized with a type parameter " + clazz);
-         }
-      }
-      return eventManager.getObservers(event, bindings);
-   }
-   
-   /**
-    * A strongly ordered, unmodifiable list of enabled deployment types
-    * 
-    * @return The ordered enabled deployment types known to the manager
-    */
-   public List<Class<? extends Annotation>> getEnabledDeploymentTypes()
-   {
-      return Collections.unmodifiableList(enabledDeploymentTypes);
-   }
-   
-   /**
-    * Set the enabled deployment types
-    * 
-    * @param enabledDeploymentTypes
-    */
-   public void setEnabledDeploymentTypes(List<Class<? extends Annotation>> enabledDeploymentTypes)
-   {
-      this.enabledDeploymentTypes = new ArrayList<Class<? extends Annotation>>(enabledDeploymentTypes);
-      checkEnabledDeploymentTypes();
-      addWebBeansDeploymentTypes();
-   }
-   
-   /**
-    * Resolves beans by API type and binding types
-    * 
-    * @param type
-    *           The API type to match
-    * @param bindings
-    *           The binding types to match
-    * @return The set of matching beans
-    * 
-    * @see javax.inject.manager.Manager#resolveByType(java.lang.Class,
-    *      java.lang.annotation.Annotation[])
-    */
-   public <T> Set<Bean<T>> resolveByType(Class<T> type, Annotation... bindings)
-   {
-      return resolveByType(ResolvableAnnotatedClass.of(type, bindings), bindings);
-   }
-   
-   /**
-    * Resolves beans by API type literal and binding types
-    * 
-    * @param type
-    *           The API type literal to match
-    * @param bindings
-    *           The binding types to match
-    * @return The set of matching beans
-    * 
-    * @see javax.inject.manager.Manager#resolveByType(javax.inject.TypeLiteral,
-    *      java.lang.annotation.Annotation[])
-    */
-   public <T> Set<Bean<T>> resolveByType(TypeLiteral<T> type, Annotation... bindings)
-   {
-      return resolveByType(ResolvableAnnotatedClass.of(type, bindings), bindings);
-   }
-   
-   public <T> Set<Bean<T>> resolveByType(AnnotatedItem<T, ?> element, InjectionPoint injectionPoint, Annotation... bindings)
-   {
-      boolean registerInjectionPoint = !injectionPoint.getType().equals(InjectionPoint.class);
-      try
-      {
-         if (registerInjectionPoint)
-         {
-            currentInjectionPoint.get().push(injectionPoint);
-         }
-         return resolveByType(element, bindings);
-      }
-      finally
-      {
-         if (registerInjectionPoint)
-         {
-            currentInjectionPoint.get().pop();
-         }
-      }
-   }
-   
-   /**
-    * Check the resolution request is valid, and then ask the resolver to
-    * perform the resolution. For internal use.
-    * 
-    * @param element
-    *           The item to resolve
-    * @param bindings
-    *           The binding types to match
-    * @return The set of matching beans
-    */
-   public <T> Set<Bean<T>> resolveByType(AnnotatedItem<T, ?> element, Annotation... bindings)
-   {
-      for (Annotation annotation : element.getAnnotationsAsSet())
-      {
-         if (!MetaDataCache.instance().getBindingTypeModel(annotation.annotationType()).isValid())
-         {
-            throw new IllegalArgumentException("Not a binding type " + annotation);
-         }
-      }
-      for (Type type : element.getActualTypeArguments())
-      {
-         if (type instanceof WildcardType)
-         {
-            throw new IllegalArgumentException("Cannot resolve a type parameterized with a wildcard " + element);
-         }
-         if (type instanceof TypeVariable)
-         {
-            throw new IllegalArgumentException("Cannot resolve a type parameterized with a type parameter " + element);
-         }
-      }
-      if (bindings.length > element.getMetaAnnotations(BindingType.class).size())
-      {
-         throw new DuplicateBindingTypeException("Duplicate bindings (" + Arrays.asList(bindings) + ") type passed " + element.toString());
-      }
-      return resolver.get(element);
-   }
-   
-   /**
-    * Wraps a collection of beans into a thread safe list. Since this overwrites
-    * any existing list of beans in the manager, this should only be done on
-    * startup and other controlled situations. Also maps the beans by
-    * implementation class. For internal use.
-    * 
-    * @param beans
-    *           The set of beans to add
-    * @return A reference to the manager
-    */
-   // TODO Build maps in the deployer :-)
-   public void setBeans(Set<RIBean<?>> beans)
-   {
-      synchronized (beans)
-      {
-         this.beans = new CopyOnWriteArrayList<Bean<?>>(beans);
-         for (RIBean<?> bean : beans)
-         {
-            if (bean instanceof NewEnterpriseBean)
-            {
-               newEnterpriseBeanMap.put(bean.getType(), (EnterpriseBean<?>) bean);
-            }
-            riBeans.put(bean.getId(), bean);
-         }
-         resolver.clear();
-      }
-   }
-   
-   /**
-    * Gets the class-mapped beans. For internal use.
-    * 
-    * @return The bean map
-    */
-   public Map<Class<?>, EnterpriseBean<?>> getNewEnterpriseBeanMap()
-   {
-      return newEnterpriseBeanMap;
-   }
-   
-   /**
-    * The beans registered with the Web Bean manager. For internal use
-    * 
-    * @return The list of known beans
-    */
-   public List<Bean<?>> getBeans()
-   {
-      return Collections.unmodifiableList(beans);
-   }
-   
-   public Map<String, RIBean<?>> getRiBeans()
-   {
-      return Collections.unmodifiableMap(riBeans);
-   }
-   
-   /**
-    * Registers a context with the manager
-    * 
-    * @param context
-    *           The context to add
-    * @return A reference to the manager
-    * 
-    * @see javax.inject.manager.Manager#addContext(javax.context.Context)
-    */
-   public Manager addContext(Context context)
-   {
-      contextMap.add(context);
-      return this;
-   }
-   
-   /**
-    * Registers a decorator with the manager
-    * 
-    * @param decorator
-    *           The decorator to register
-    * @return A reference to the manager
-    * 
-    * @see javax.inject.manager.Manager#addDecorator(javax.inject.manager.Decorator)
-    */
-   public Manager addDecorator(Decorator decorator)
-   {
-      decorators.add(decorator);
-      return this;
-   }
-   
-   /**
-    * Registers an interceptor with the manager
-    * 
-    * @param interceptor
-    *           The interceptor to register
-    * @return A reference to the manager
-    * 
-    * @see javax.inject.manager.Manager#addInterceptor(javax.inject.manager.Interceptor)
-    */
-   public Manager addInterceptor(Interceptor interceptor)
-   {
-      interceptors.add(interceptor);
-      return this;
-   }
-   
-   /**
-    * Registers an observer for a given event type and binding types
-    * 
-    * @param observer
-    *           The observer to register
-    * @param eventType
-    *           The event type to match
-    * @param bindings
-    *           The bindings to match
-    * @return A reference to the manager
-    * 
-    * @see javax.inject.manager.Manager#addObserver(javax.event.Observer,
-    *      java.lang.Class, java.lang.annotation.Annotation[])
-    */
-   public <T> Manager addObserver(Observer<T> observer, Class<T> eventType, Annotation... bindings)
-   {
-      this.eventManager.addObserver(observer, eventType, bindings);
-      return this;
-   }
-   
-   public <T> Manager addObserver(ObserverImpl<T> observer)
-   {
-      this.eventManager.addObserver(observer, observer.getEventType(), observer.getBindingsAsArray());
-      return this;
-   }
-   
-   /**
-    * Registers an observer for a given event type literal and binding types
-    * 
-    * @param observer
-    *           The observer to register
-    * @param eventType
-    *           The event type literal to match
-    * @param bindings
-    *           The bindings to match
-    * @return A reference to the manager
-    * 
-    * @see javax.inject.manager.Manager#addObserver(javax.event.Observer,
-    *      javax.inject.TypeLiteral, java.lang.annotation.Annotation[])
-    */
-   public <T> Manager addObserver(Observer<T> observer, TypeLiteral<T> eventType, Annotation... bindings)
-   {
-      eventManager.addObserver(observer, eventType.getType(), bindings);
-      return this;
-   }
-   
-   /**
-    * Fires an event object with given event object for given bindings
-    * 
-    * @param event
-    *           The event object to pass along
-    * @param bindings
-    *           The binding types to match
-    * 
-    * @see javax.inject.manager.Manager#fireEvent(java.lang.Object,
-    *      java.lang.annotation.Annotation[])
-    */
-   public void fireEvent(Object event, Annotation... bindings)
-   {
-      // Check the event object for template parameters which are not allowed by
-      // the spec.
-      if (Reflections.isParameterizedType(event.getClass()))
-      {
-         throw new IllegalArgumentException("Event type " + event.getClass().getName() + " is not allowed because it is a generic");
-      }
-      // Also check that the binding types are truly binding types
-      for (Annotation binding : bindings)
-      {
-         if (!Reflections.isBindings(binding))
-         {
-            throw new IllegalArgumentException("Event type " + event.getClass().getName() + " cannot be fired with non-binding type " + binding.getClass().getName() + " specified");
-         }
-      }
-      
-      // Get the observers for this event. Although resolveObservers is
-      // parameterized, this method is not, so we have to use
-      // Observer<Object> for observers.
-      Set<Observer<Object>> observers = resolveObservers(event, bindings);
-      eventManager.notifyObservers(observers, event);
-   }
-   
-   /**
-    * Gets an active context of the given scope. Throws an exception if there
-    * are no active contexts found or if there are too many matches
-    * 
-    * @param scopeType
-    *           The scope to match
-    * @return A single active context of the given scope
-    * 
-    * @see javax.inject.manager.Manager#getContext(java.lang.Class)
-    */
-   public Context getContext(Class<? extends Annotation> scopeType)
-   {
-      List<Context> activeContexts = new ArrayList<Context>();
-      for (Context context : contextMap.getContext(scopeType))
-      {
-         if (context.isActive())
-         {
-            activeContexts.add(context);
-         }
-      }
-      if (activeContexts.isEmpty())
-      {
-         throw new ContextNotActiveException("No active contexts for scope type " + scopeType.getName());
-      }
-      if (activeContexts.size() > 1)
-      {
-         throw new IllegalStateException("More than one context active for scope type " + scopeType.getName());
-      }
-      return activeContexts.iterator().next();
-   }
-   
-   /**
-    * Direct access to built in contexts. For internal use.
-    * 
-    * @param scopeType
-    *           The scope type of the context
-    * @return The context
-    */
-   public Context getBuiltInContext(Class<? extends Annotation> scopeType)
-   {
-      return contextMap.getBuiltInContext(scopeType);
-   }
-   
-   /**
-    * Returns an instance of a bean
-    * 
-    * @param bean
-    *           The bean to instantiate
-    * @return An instance of the bean
-    * 
-    * @see javax.inject.manager.Manager#getInstance(javax.inject.manager.Bean)
-    */
-   public <T> T getInstance(Bean<T> bean)
-   {
-      return getInstance(bean, true);
-   }
-   
-   public <T> T getInstance(Bean<T> bean, boolean create)
-   {
-      if (create)
-      {
-         return getInstance(bean, new CreationalContextImpl<T>(bean));
-      }
-      else
-      {
-         return getInstance(bean, null);
-      }
-   }
-   
-   /**
-    * Returns an instance of a bean
-    * 
-    * @param bean
-    *           The bean to instantiate
-    * @return An instance of the bean
-    * 
-    * @see javax.inject.manager.Manager#getInstance(javax.inject.manager.Bean)
-    */
-   @SuppressWarnings("unchecked")
-   private <T> T getInstance(Bean<T> bean, CreationalContextImpl<T> creationalContext)
-   {
-      if (specializedBeans.containsKey(bean))
-      {
-         return getInstance((Bean<T>) specializedBeans.get(bean), creationalContext);
-      }
-      else if (MetaDataCache.instance().getScopeModel(bean.getScopeType()).isNormal())
-      {
-         if (creationalContext != null || (creationalContext == null && getContext(bean.getScopeType()).get(bean) != null))
-         {
-            return (T) clientProxyProvider.getClientProxy(bean);
-         }
-         else
-         {
-            return null;
-         }
-      }
-      else
-      {
-         return getContext(bean.getScopeType()).get(bean, creationalContext);
-      }
-   }
-   
-   public <T> T getInstanceToInject(InjectionPoint injectionPoint)
-   {
-      return this.<T> getInstanceToInject(injectionPoint, null);
-   }
-   
-   public void injectNonContextualInstance(Object instance)
-   {
-      nonContextualInjector.inject(instance);
-   }
-   
-   @SuppressWarnings("unchecked")
-   public <T> T getInstanceToInject(InjectionPoint injectionPoint, CreationalContext<?> creationalContext)
-   {
-      boolean registerInjectionPoint = !injectionPoint.getType().equals(InjectionPoint.class);
-      try
-      {
-         if (registerInjectionPoint)
-         {
-            currentInjectionPoint.get().push(injectionPoint);
-         }
-         AnnotatedItem<T, ?> element = ResolvableAnnotatedClass.of(injectionPoint.getType(), injectionPoint.getBindings().toArray(new Annotation[0]));
-         Bean<T> bean = getBeanByType(element, element.getBindingsAsArray());
-         if (creationalContext instanceof CreationalContextImpl)
-         {
-            CreationalContextImpl<?> ctx = (CreationalContextImpl<?>) creationalContext;
-            if (ctx.containsIncompleteInstance(bean))
-            {
-               return ctx.getIncompleteInstance(bean);
-            }
-            else
-            {
-               return getInstance(bean, ctx.getCreationalContext(bean));
-            }
-         }
-         else
-         {
-            return getInstance(bean);
-         }
-      }
-      finally
-      {
-         if (registerInjectionPoint)
-         {
-            currentInjectionPoint.get().pop();
-         }
-      }
-   }
-   
-   /**
-    * Gets an instance by name, returning null if none is found and throwing an
-    * exception if too many beans match
-    * 
-    * @param name
-    *           The name to match
-    * @return An instance of the bean
-    * 
-    * @see javax.inject.manager.Manager#getInstanceByName(java.lang.String)
-    */
-   public Object getInstanceByName(String name)
-   {
-      Set<Bean<?>> beans = resolveByName(name);
-      if (beans.size() == 0)
-      {
-         return null;
-      }
-      else if (beans.size() > 1)
-      {
-         throw new AmbiguousDependencyException("Resolved multiple Web Beans with " + name);
-      }
-      else
-      {
-         return getInstance(beans.iterator().next());
-      }
-   }
-   
-   /**
-    * Returns an instance by API type and binding types
-    * 
-    * @param type
-    *           The API type to match
-    * @param bindings
-    *           The binding types to match
-    * @return An instance of the bean
-    * 
-    * @see javax.inject.manager.Manager#getInstanceByType(java.lang.Class,
-    *      java.lang.annotation.Annotation[])
-    */
-   public <T> T getInstanceByType(Class<T> type, Annotation... bindings)
-   {
-      return getInstanceByType(ResolvableAnnotatedClass.of(type, bindings), bindings);
-   }
-   
-   /**
-    * Returns an instance by type literal and binding types
-    * 
-    * @param type
-    *           The type to match
-    * @param bindings
-    *           The binding types to match
-    * @return An instance of the bean
-    * 
-    * @see javax.inject.manager.Manager#getInstanceByType(javax.inject.TypeLiteral,
-    *      java.lang.annotation.Annotation[])
-    */
-   public <T> T getInstanceByType(TypeLiteral<T> type, Annotation... bindings)
-   {
-      return getInstanceByType(ResolvableAnnotatedClass.of(type, bindings), bindings);
-   }
-   
-   /**
-    * Resolve an instance, verify that the resolved bean can be instantiated,
-    * and return
-    * 
-    * @param element
-    *           The annotated item to match
-    * @param bindings
-    *           The binding types to match
-    * @return An instance of the bean
-    */
-   private <T> T getInstanceByType(AnnotatedItem<T, ?> element, Annotation... bindings)
-   {
-      return getInstance(getBeanByType(element, bindings));
-   }
-   
-   public <T> Bean<T> getBeanByType(AnnotatedItem<T, ?> element, Annotation... bindings)
-   {
-      Set<Bean<T>> beans = resolveByType(element, bindings);
-      if (beans.size() == 0)
-      {
-         throw new UnsatisfiedDependencyException(element + "Unable to resolve any Web Beans");
-      }
-      else if (beans.size() > 1)
-      {
-         throw new AmbiguousDependencyException(element + "Resolved multiple Web Beans");
-      }
-      Bean<T> bean = beans.iterator().next();
-      boolean normalScoped = MetaDataCache.instance().getScopeModel(bean.getScopeType()).isNormal();
-      if (normalScoped && !Beans.isBeanProxyable(bean))
-      {
-         throw new UnproxyableDependencyException("Normal scoped bean " + bean + " is not proxyable");
-      }
-      return bean;
-   }
-   
-   /**
-    * Removes an observer
-    * 
-    * @param observer
-    *           The observer to remove
-    * @param eventType
-    *           The event type to match
-    * @param bindings
-    *           the binding types to match
-    * @return A reference to the manager
-    * 
-    * @see javax.inject.manager.Manager#removeObserver(javax.event.Observer,
-    *      java.lang.Class, java.lang.annotation.Annotation[])
-    */
-   public <T> Manager removeObserver(Observer<T> observer, Class<T> eventType, Annotation... bindings)
-   {
-      this.eventManager.removeObserver(observer, eventType, bindings);
-      return this;
-   }
-   
-   /**
-    * Removes an observer
-    * 
-    * @param observer
-    *           The observer to remove
-    * @param eventType
-    *           The event type to match
-    * @param bindings
-    *           the binding types to match
-    * @return A reference to the manager
-    * 
-    * @see javax.inject.manager.Manager#removeObserver(javax.event.Observer,
-    *      javax.inject.TypeLiteral, java.lang.annotation.Annotation[])
-    */
-   public <T> Manager removeObserver(Observer<T> observer, TypeLiteral<T> eventType, Annotation... bindings)
-   {
-      this.eventManager.removeObserver(observer, eventType.getRawType(), bindings);
-      return this;
-   }
-   
-   /**
-    * Resolves a set of beans based on their name
-    * 
-    * @param The
-    *           name to match
-    * @return The set of matching beans
-    * 
-    * @see javax.inject.manager.Manager#resolveByName(java.lang.String)
-    */
-   public Set<Bean<?>> resolveByName(String name)
-   {
-      return resolver.get(name);
-   }
-   
-   /**
-    * Resolves a list of decorators based on API types and binding types Os
-    * 
-    * @param types
-    *           The set of API types to match
-    * @param bindings
-    *           The binding types to match
-    * @return A list of matching decorators
-    * 
-    * @see javax.inject.manager.Manager#resolveDecorators(java.util.Set,
-    *      java.lang.annotation.Annotation[])
-    */
-   public List<Decorator> resolveDecorators(Set<Type> types, Annotation... bindings)
-   {
-      throw new UnsupportedOperationException();
-   }
-   
-   /**
-    * Resolves a list of interceptors based on interception type and interceptor
-    * bindings
-    * 
-    * @param type
-    *           The interception type to resolve
-    * @param interceptorBindings
-    *           The binding types to match
-    * @return A list of matching interceptors
-    * 
-    * @see javax.inject.manager.Manager#resolveInterceptors(javax.inject.manager.InterceptionType,
-    *      java.lang.annotation.Annotation[])
-    */
-   public List<Interceptor> resolveInterceptors(InterceptionType type, Annotation... interceptorBindings)
-   {
-      throw new UnsupportedOperationException();
-   }
-   
-   /**
-    * Get the web bean resolver. For internal use
-    * 
-    * @return The resolver
-    */
-   public Resolver getResolver()
-   {
-      return resolver;
-   }
-   
-   public EjbDescriptorCache getEjbDescriptorCache()
-   {
-      return ejbDescriptorCache;
-   }
-   
-   /**
-    * Gets a string representation
-    * 
-    * @return A string representation
-    */
-   @Override
-   public String toString()
-   {
-      StringBuilder buffer = new StringBuilder();
-      buffer.append("Manager\n");
-      buffer.append("Enabled deployment types: " + getEnabledDeploymentTypes() + "\n");
-      buffer.append("Registered contexts: " + contextMap.keySet() + "\n");
-      buffer.append("Registered beans: " + getBeans().size() + "\n");
-      buffer.append("Registered decorators: " + decorators.size() + "\n");
-      buffer.append("Registered interceptors: " + interceptors.size() + "\n");
-      buffer.append("Specialized beans: " + specializedBeans.size() + "\n");
-      return buffer.toString();
-   }
-   
-   public Manager parse(InputStream xmlStream)
-   {
-      throw new UnsupportedOperationException();
-   }
-   
-   public Manager createActivity()
-   {
-      return new ChildManager(this);
-   }
-   
-   public Manager setCurrent(Class<? extends Annotation> scopeType)
-   {
-      throw new UnsupportedOperationException();
-   }
-   
-   public ServiceRegistry getServices()
-   {
-      return simpleServiceRegistry;
-   }
-   
-   /**
-    * Accesses the factory used to create each instance of InjectionPoint that
-    * is injected into web beans.
-    * 
-    * @return the factory
-    */
-   public InjectionPoint getInjectionPoint()
-   {
-      if (!currentInjectionPoint.get().empty())
-      {
-         return currentInjectionPoint.get().peek();
-      }
-      else
-      {
-         return null;
-      }
-   }
-   
-   /**
-    * 
-    * @return
-    */
-   public Map<Bean<?>, Bean<?>> getSpecializedBeans()
-   {
-      // TODO make this unmodifiable after deploy!
-      return specializedBeans;
-   }
-   
-   // Serialization
-   
-   protected Object readResolve()
-   {
-      return CurrentManager.rootManager();
-   }
-   
-   /**
-    * Provides access to the executor service used for asynchronous tasks.
-    * 
-    * @return the ExecutorService for this manager
-    */
-   public ExecutorService getTaskExecutor()
-   {
-      return taskExecutor;
-   }
-   
-   public void shutdown()
-   {
-      log.trace("Ending application");
-      shutdownExecutors();
-      ApplicationContext.INSTANCE.destroy();
-      ApplicationContext.INSTANCE.setActive(false);
-      ApplicationContext.INSTANCE.setBeanStore(null);
-      getServices().get(NamingContext.class).unbind(RootManager.JNDI_KEY);
-   }
-   
-   /**
-    * Shuts down any executor services in the manager.
-    */
-   protected void shutdownExecutors()
-   {
-      taskExecutor.shutdown();
-      try
-      {
-         // Wait a while for existing tasks to terminate
-         if (!taskExecutor.awaitTermination(60, TimeUnit.SECONDS))
-         {
-            taskExecutor.shutdownNow(); // Cancel currently executing tasks
-            // Wait a while for tasks to respond to being cancelled
-            if (!taskExecutor.awaitTermination(60, TimeUnit.SECONDS))
-            {
-               // Log the error here
-            }
-         }
-      }
-      catch (InterruptedException ie)
-      {
-         // (Re-)Cancel if current thread also interrupted
-         taskExecutor.shutdownNow();
-         // Preserve interrupt status
-         Thread.currentThread().interrupt();
-      }
-   }
-   
-}
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,  
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jboss.webbeans;
+
+import java.io.InputStream;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.ArrayList;
+import java.util.Arrays;
+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.Stack;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import javax.context.Context;
+import javax.context.ContextNotActiveException;
+import javax.context.CreationalContext;
+import javax.event.Observer;
+import javax.inject.AmbiguousDependencyException;
+import javax.inject.BindingType;
+import javax.inject.DeploymentException;
+import javax.inject.DuplicateBindingTypeException;
+import javax.inject.Production;
+import javax.inject.Standard;
+import javax.inject.TypeLiteral;
+import javax.inject.UnproxyableDependencyException;
+import javax.inject.UnsatisfiedDependencyException;
+import javax.inject.manager.Bean;
+import javax.inject.manager.Decorator;
+import javax.inject.manager.InjectionPoint;
+import javax.inject.manager.InterceptionType;
+import javax.inject.manager.Interceptor;
+import javax.inject.manager.Manager;
+
+import org.jboss.webbeans.bean.DisposalMethodBean;
+import org.jboss.webbeans.bean.EnterpriseBean;
+import org.jboss.webbeans.bean.NewEnterpriseBean;
+import org.jboss.webbeans.bean.RIBean;
+import org.jboss.webbeans.bean.proxy.ClientProxyProvider;
+import org.jboss.webbeans.bootstrap.api.ServiceRegistry;
+import org.jboss.webbeans.context.ApplicationContext;
+import org.jboss.webbeans.context.ContextMap;
+import org.jboss.webbeans.context.CreationalContextImpl;
+import org.jboss.webbeans.ejb.EjbDescriptorCache;
+import org.jboss.webbeans.event.EventManager;
+import org.jboss.webbeans.event.ObserverImpl;
+import org.jboss.webbeans.injection.NonContextualInjector;
+import org.jboss.webbeans.injection.resolution.ResolvableAnnotatedClass;
+import org.jboss.webbeans.injection.resolution.Resolver;
+import org.jboss.webbeans.introspector.AnnotatedItem;
+import org.jboss.webbeans.introspector.AnnotatedMethod;
+import org.jboss.webbeans.log.Log;
+import org.jboss.webbeans.log.Logging;
+import org.jboss.webbeans.manager.api.WebBeansManager;
+import org.jboss.webbeans.metadata.MetaDataCache;
+import org.jboss.webbeans.resources.spi.NamingContext;
+import org.jboss.webbeans.util.Beans;
+import org.jboss.webbeans.util.Reflections;
+
+/**
+ * Implementation of the Web Beans Manager.
+ * 
+ * Essentially a singleton for registering Beans, Contexts, Observers,
+ * Interceptors etc. as well as providing resolution
+ * 
+ * @author Pete Muir
+ * 
+ */
+public class RootManager implements WebBeansManager, Serializable
+{
+   
+   private static final Log log = Logging.getLog(RootManager.class);
+   
+   private static final long serialVersionUID = 3021562879133838561L;
+   
+   // The JNDI key to place the manager under
+   public static final String JNDI_KEY = "java:app/Manager";
+   
+   // The enabled deployment types from web-beans.xml
+   private transient List<Class<? extends Annotation>> enabledDeploymentTypes;
+   // The Web Beans event manager
+   private transient final EventManager eventManager;
+   
+   // An executor service for asynchronous tasks
+   private transient final ExecutorService taskExecutor = Executors.newSingleThreadExecutor();
+   
+   // An injection point metadata beans factory
+   private transient final ThreadLocal<Stack<InjectionPoint>> currentInjectionPoint;
+   
+   // The bean resolver
+   private transient final Resolver resolver;
+   
+   // The registered contexts
+   private transient final ContextMap contextMap;
+   // The client proxy pool
+   private transient final ClientProxyProvider clientProxyProvider;
+   // The registered beans
+   private transient List<Bean<?>> beans;
+   // The registered beans, mapped by implementation class
+   private transient final Map<Class<?>, EnterpriseBean<?>> newEnterpriseBeanMap;
+   
+   private transient final Map<String, RIBean<?>> riBeans;
+   
+   // The registered decorators
+   private transient final Set<Decorator> decorators;
+   // The registered interceptors
+   private transient final Set<Interceptor> interceptors;
+   
+   // The EJB resolver provided by the container
+   private transient final ServiceRegistry simpleServiceRegistry;
+   
+   private transient final EjbDescriptorCache ejbDescriptorCache;
+   
+   private final transient Map<Bean<?>, Bean<?>> specializedBeans;
+   
+   private final transient NonContextualInjector nonContextualInjector;
+   
+   /**
+    * Create a new manager
+    * 
+    * @param ejbServices
+    *           the ejbResolver to use
+    */
+   public RootManager(ServiceRegistry simpleServiceRegistry)
+   {
+      this.simpleServiceRegistry = simpleServiceRegistry;
+      this.beans = new CopyOnWriteArrayList<Bean<?>>();
+      this.newEnterpriseBeanMap = new ConcurrentHashMap<Class<?>, EnterpriseBean<?>>();
+      this.riBeans = new ConcurrentHashMap<String, RIBean<?>>();
+      this.resolver = new Resolver(this);
+      this.clientProxyProvider = new ClientProxyProvider();
+      this.decorators = new HashSet<Decorator>();
+      this.interceptors = new HashSet<Interceptor>();
+      this.contextMap = new ContextMap();
+      this.eventManager = new EventManager();
+      this.ejbDescriptorCache = new EjbDescriptorCache();
+      this.currentInjectionPoint = new ThreadLocal<Stack<InjectionPoint>>()
+      {
+         @Override
+         protected Stack<InjectionPoint> initialValue()
+         {
+            return new Stack<InjectionPoint>();
+         }
+      };
+      this.specializedBeans = new HashMap<Bean<?>, Bean<?>>();
+      this.nonContextualInjector = new NonContextualInjector(this);
+      List<Class<? extends Annotation>> defaultEnabledDeploymentTypes = new ArrayList<Class<? extends Annotation>>();
+      defaultEnabledDeploymentTypes.add(0, Standard.class);
+      defaultEnabledDeploymentTypes.add(1, Production.class);
+      setEnabledDeploymentTypes(defaultEnabledDeploymentTypes);
+   }
+   
+   /**
+    * Set up the enabled deployment types, if none are specified by the user,
+    * the default @Production and @Standard are used. For internal use.
+    * 
+    * @param enabledDeploymentTypes
+    *           The enabled deployment types from web-beans.xml
+    */
+   protected void checkEnabledDeploymentTypes()
+   {
+      if (!this.enabledDeploymentTypes.get(0).equals(Standard.class))
+      {
+         throw new DeploymentException("@Standard must be the lowest precedence deployment type");
+      }
+   }
+   
+   protected void addWebBeansDeploymentTypes()
+   {
+      if (!this.enabledDeploymentTypes.contains(WebBean.class))
+      {
+         this.enabledDeploymentTypes.add(1, WebBean.class);
+      }
+   }
+   
+   /**
+    * Registers a bean with the manager
+    * 
+    * @param bean
+    *           The bean to register
+    * @return A reference to manager
+    * 
+    * @see javax.inject.manager.Manager#addBean(javax.inject.manager.Bean)
+    */
+   public Manager addBean(Bean<?> bean)
+   {
+      if (beans.contains(bean))
+      {
+         return this;
+      }
+      resolver.clear();
+      beans.add(bean);
+      return this;
+   }
+   
+   /**
+    * Resolve the disposal method for the given producer method. For internal
+    * use.
+    * 
+    * @param apiType
+    *           The API type to match
+    * @param bindings
+    *           The binding types to match
+    * @return The set of matching disposal methods
+    */
+   public <T> Set<Bean<T>> resolveDisposalBeans(Class<T> apiType, Annotation... bindings)
+   {
+      return resolveByType(apiType, bindings);
+   }
+   
+   /**
+    * Resolves observers for given event and bindings
+    * 
+    * @param event
+    *           The event to match
+    * @param bindings
+    *           The binding types to match
+    * @return The set of matching observers
+    * 
+    * @see javax.inject.manager.Manager#resolveObservers(java.lang.Object,
+    *      java.lang.annotation.Annotation[])
+    */
+   @SuppressWarnings("unchecked")
+   public <T> Set<Observer<T>> resolveObservers(T event, Annotation... bindings)
+   {
+      Class<?> clazz = event.getClass();
+      for (Annotation annotation : bindings)
+      {
+         if (!MetaDataCache.instance().getBindingTypeModel(annotation.annotationType()).isValid())
+         {
+            throw new IllegalArgumentException("Not a binding type " + annotation);
+         }
+      }
+      HashSet<Annotation> bindingAnnotations = new HashSet<Annotation>(Arrays.asList(bindings));
+      if (bindingAnnotations.size() < bindings.length)
+      {
+         throw new DuplicateBindingTypeException("Duplicate binding types: " + bindings);
+      }
+      Type t = new Reflections.HierarchyDiscovery(clazz).getResolvedType();
+      for (Type type : Reflections.getActualTypeArguments(clazz))
+      {
+         if (type instanceof WildcardType)
+         {
+            throw new IllegalArgumentException("Cannot resolve an event type parameterized with a wildcard " + clazz);
+         }
+         if (type instanceof TypeVariable)
+         {
+            throw new IllegalArgumentException("Cannot resolve an event type parameterized with a type parameter " + clazz);
+         }
+      }
+      return eventManager.getObservers(event, bindings);
+   }
+   
+   /**
+    * A strongly ordered, unmodifiable list of enabled deployment types
+    * 
+    * @return The ordered enabled deployment types known to the manager
+    */
+   public List<Class<? extends Annotation>> getEnabledDeploymentTypes()
+   {
+      return Collections.unmodifiableList(enabledDeploymentTypes);
+   }
+   
+   /**
+    * Set the enabled deployment types
+    * 
+    * @param enabledDeploymentTypes
+    */
+   public void setEnabledDeploymentTypes(List<Class<? extends Annotation>> enabledDeploymentTypes)
+   {
+      this.enabledDeploymentTypes = new ArrayList<Class<? extends Annotation>>(enabledDeploymentTypes);
+      checkEnabledDeploymentTypes();
+      addWebBeansDeploymentTypes();
+   }
+   
+   /**
+    * Resolves beans by API type and binding types
+    * 
+    * @param type
+    *           The API type to match
+    * @param bindings
+    *           The binding types to match
+    * @return The set of matching beans
+    * 
+    * @see javax.inject.manager.Manager#resolveByType(java.lang.Class,
+    *      java.lang.annotation.Annotation[])
+    */
+   public <T> Set<Bean<T>> resolveByType(Class<T> type, Annotation... bindings)
+   {
+      return resolveByType(ResolvableAnnotatedClass.of(type, bindings), bindings);
+   }
+   
+   /**
+    * Resolves beans by API type literal and binding types
+    * 
+    * @param type
+    *           The API type literal to match
+    * @param bindings
+    *           The binding types to match
+    * @return The set of matching beans
+    * 
+    * @see javax.inject.manager.Manager#resolveByType(javax.inject.TypeLiteral,
+    *      java.lang.annotation.Annotation[])
+    */
+   public <T> Set<Bean<T>> resolveByType(TypeLiteral<T> type, Annotation... bindings)
+   {
+      return resolveByType(ResolvableAnnotatedClass.of(type, bindings), bindings);
+   }
+   
+   public <T> Set<Bean<T>> resolveByType(AnnotatedItem<T, ?> element, InjectionPoint injectionPoint, Annotation... bindings)
+   {
+      boolean registerInjectionPoint = !injectionPoint.getType().equals(InjectionPoint.class);
+      try
+      {
+         if (registerInjectionPoint)
+         {
+            currentInjectionPoint.get().push(injectionPoint);
+         }
+         return resolveByType(element, bindings);
+      }
+      finally
+      {
+         if (registerInjectionPoint)
+         {
+            currentInjectionPoint.get().pop();
+         }
+      }
+   }
+   
+   /**
+    * Check the resolution request is valid, and then ask the resolver to
+    * perform the resolution. For internal use.
+    * 
+    * @param element
+    *           The item to resolve
+    * @param bindings
+    *           The binding types to match
+    * @return The set of matching beans
+    */
+   public <T> Set<Bean<T>> resolveByType(AnnotatedItem<T, ?> element, Annotation... bindings)
+   {
+      for (Annotation annotation : element.getAnnotationsAsSet())
+      {
+         if (!MetaDataCache.instance().getBindingTypeModel(annotation.annotationType()).isValid())
+         {
+            throw new IllegalArgumentException("Not a binding type " + annotation);
+         }
+      }
+      for (Type type : element.getActualTypeArguments())
+      {
+         if (type instanceof WildcardType)
+         {
+            throw new IllegalArgumentException("Cannot resolve a type parameterized with a wildcard " + element);
+         }
+         if (type instanceof TypeVariable)
+         {
+            throw new IllegalArgumentException("Cannot resolve a type parameterized with a type parameter " + element);
+         }
+      }
+      if (bindings.length > element.getMetaAnnotations(BindingType.class).size())
+      {
+         throw new DuplicateBindingTypeException("Duplicate bindings (" + Arrays.asList(bindings) + ") type passed " + element.toString());
+      }
+      return resolver.get(element);
+   }
+   
+   /**
+    * Wraps a collection of beans into a thread safe list. Since this overwrites
+    * any existing list of beans in the manager, this should only be done on
+    * startup and other controlled situations. Also maps the beans by
+    * implementation class. For internal use.
+    * 
+    * @param beans
+    *           The set of beans to add
+    * @return A reference to the manager
+    */
+   // TODO Build maps in the deployer :-)
+   public void setBeans(Set<RIBean<?>> beans)
+   {
+      synchronized (beans)
+      {
+         this.beans = new CopyOnWriteArrayList<Bean<?>>(beans);
+         for (RIBean<?> bean : beans)
+         {
+            if (bean instanceof NewEnterpriseBean)
+            {
+               newEnterpriseBeanMap.put(bean.getType(), (EnterpriseBean<?>) bean);
+            }
+            riBeans.put(bean.getId(), bean);
+         }
+         resolver.clear();
+      }
+   }
+   
+   /**
+    * Gets the class-mapped beans. For internal use.
+    * 
+    * @return The bean map
+    */
+   public Map<Class<?>, EnterpriseBean<?>> getNewEnterpriseBeanMap()
+   {
+      return newEnterpriseBeanMap;
+   }
+   
+   /**
+    * The beans registered with the Web Bean manager. For internal use
+    * 
+    * @return The list of known beans
+    */
+   public List<Bean<?>> getBeans()
+   {
+      return Collections.unmodifiableList(beans);
+   }
+   
+   public Map<String, RIBean<?>> getRiBeans()
+   {
+      return Collections.unmodifiableMap(riBeans);
+   }
+   
+   /**
+    * Registers a context with the manager
+    * 
+    * @param context
+    *           The context to add
+    * @return A reference to the manager
+    * 
+    * @see javax.inject.manager.Manager#addContext(javax.context.Context)
+    */
+   public Manager addContext(Context context)
+   {
+      contextMap.add(context);
+      return this;
+   }
+   
+   /**
+    * Registers a decorator with the manager
+    * 
+    * @param decorator
+    *           The decorator to register
+    * @return A reference to the manager
+    * 
+    * @see javax.inject.manager.Manager#addDecorator(javax.inject.manager.Decorator)
+    */
+   public Manager addDecorator(Decorator decorator)
+   {
+      decorators.add(decorator);
+      return this;
+   }
+   
+   /**
+    * Registers an interceptor with the manager
+    * 
+    * @param interceptor
+    *           The interceptor to register
+    * @return A reference to the manager
+    * 
+    * @see javax.inject.manager.Manager#addInterceptor(javax.inject.manager.Interceptor)
+    */
+   public Manager addInterceptor(Interceptor interceptor)
+   {
+      interceptors.add(interceptor);
+      return this;
+   }
+   
+   /**
+    * Registers an observer for a given event type and binding types
+    * 
+    * @param observer
+    *           The observer to register
+    * @param eventType
+    *           The event type to match
+    * @param bindings
+    *           The bindings to match
+    * @return A reference to the manager
+    * 
+    * @see javax.inject.manager.Manager#addObserver(javax.event.Observer,
+    *      java.lang.Class, java.lang.annotation.Annotation[])
+    */
+   public <T> Manager addObserver(Observer<T> observer, Class<T> eventType, Annotation... bindings)
+   {
+      this.eventManager.addObserver(observer, eventType, bindings);
+      return this;
+   }
+   
+   public <T> Manager addObserver(ObserverImpl<T> observer)
+   {
+      this.eventManager.addObserver(observer, observer.getEventType(), observer.getBindingsAsArray());
+      return this;
+   }
+   
+   /**
+    * Registers an observer for a given event type literal and binding types
+    * 
+    * @param observer
+    *           The observer to register
+    * @param eventType
+    *           The event type literal to match
+    * @param bindings
+    *           The bindings to match
+    * @return A reference to the manager
+    * 
+    * @see javax.inject.manager.Manager#addObserver(javax.event.Observer,
+    *      javax.inject.TypeLiteral, java.lang.annotation.Annotation[])
+    */
+   public <T> Manager addObserver(Observer<T> observer, TypeLiteral<T> eventType, Annotation... bindings)
+   {
+      eventManager.addObserver(observer, eventType.getType(), bindings);
+      return this;
+   }
+   
+   /**
+    * Fires an event object with given event object for given bindings
+    * 
+    * @param event
+    *           The event object to pass along
+    * @param bindings
+    *           The binding types to match
+    * 
+    * @see javax.inject.manager.Manager#fireEvent(java.lang.Object,
+    *      java.lang.annotation.Annotation[])
+    */
+   public void fireEvent(Object event, Annotation... bindings)
+   {
+      // Check the event object for template parameters which are not allowed by
+      // the spec.
+      if (Reflections.isParameterizedType(event.getClass()))
+      {
+         throw new IllegalArgumentException("Event type " + event.getClass().getName() + " is not allowed because it is a generic");
+      }
+      // Also check that the binding types are truly binding types
+      for (Annotation binding : bindings)
+      {
+         if (!Reflections.isBindings(binding))
+         {
+            throw new IllegalArgumentException("Event type " + event.getClass().getName() + " cannot be fired with non-binding type " + binding.getClass().getName() + " specified");
+         }
+      }
+      
+      // Get the observers for this event. Although resolveObservers is
+      // parameterized, this method is not, so we have to use
+      // Observer<Object> for observers.
+      Set<Observer<Object>> observers = resolveObservers(event, bindings);
+      eventManager.notifyObservers(observers, event);
+   }
+   
+   /**
+    * Gets an active context of the given scope. Throws an exception if there
+    * are no active contexts found or if there are too many matches
+    * 
+    * @param scopeType
+    *           The scope to match
+    * @return A single active context of the given scope
+    * 
+    * @see javax.inject.manager.Manager#getContext(java.lang.Class)
+    */
+   public Context getContext(Class<? extends Annotation> scopeType)
+   {
+      List<Context> activeContexts = new ArrayList<Context>();
+      for (Context context : contextMap.getContext(scopeType))
+      {
+         if (context.isActive())
+         {
+            activeContexts.add(context);
+         }
+      }
+      if (activeContexts.isEmpty())
+      {
+         throw new ContextNotActiveException("No active contexts for scope type " + scopeType.getName());
+      }
+      if (activeContexts.size() > 1)
+      {
+         throw new IllegalStateException("More than one context active for scope type " + scopeType.getName());
+      }
+      return activeContexts.iterator().next();
+   }
+   
+   /**
+    * Direct access to built in contexts. For internal use.
+    * 
+    * @param scopeType
+    *           The scope type of the context
+    * @return The context
+    */
+   public Context getBuiltInContext(Class<? extends Annotation> scopeType)
+   {
+      return contextMap.getBuiltInContext(scopeType);
+   }
+   
+   /**
+    * Returns an instance of a bean
+    * 
+    * @param bean
+    *           The bean to instantiate
+    * @return An instance of the bean
+    * 
+    * @see javax.inject.manager.Manager#getInstance(javax.inject.manager.Bean)
+    */
+   public <T> T getInstance(Bean<T> bean)
+   {
+      return getInstance(bean, true);
+   }
+   
+   public <T> T getInstance(Bean<T> bean, boolean create)
+   {
+      if (create)
+      {
+         return getInstance(bean, new CreationalContextImpl<T>(bean));
+      }
+      else
+      {
+         return getInstance(bean, null);
+      }
+   }
+   
+   /**
+    * Returns an instance of a bean
+    * 
+    * @param bean
+    *           The bean to instantiate
+    * @return An instance of the bean
+    * 
+    * @see javax.inject.manager.Manager#getInstance(javax.inject.manager.Bean)
+    */
+   @SuppressWarnings("unchecked")
+   private <T> T getInstance(Bean<T> bean, CreationalContextImpl<T> creationalContext)
+   {
+      if (specializedBeans.containsKey(bean))
+      {
+         return getInstance((Bean<T>) specializedBeans.get(bean), creationalContext);
+      }
+      else if (MetaDataCache.instance().getScopeModel(bean.getScopeType()).isNormal())
+      {
+         if (creationalContext != null || (creationalContext == null && getContext(bean.getScopeType()).get(bean) != null))
+         {
+            return (T) clientProxyProvider.getClientProxy(bean);
+         }
+         else
+         {
+            return null;
+         }
+      }
+      else
+      {
+         return getContext(bean.getScopeType()).get(bean, creationalContext);
+      }
+   }
+   
+   public <T> T getInstanceToInject(InjectionPoint injectionPoint)
+   {
+      return this.<T> getInstanceToInject(injectionPoint, null);
+   }
+   
+   public void injectNonContextualInstance(Object instance)
+   {
+      nonContextualInjector.inject(instance);
+   }
+   
+   @SuppressWarnings("unchecked")
+   public <T> T getInstanceToInject(InjectionPoint injectionPoint, CreationalContext<?> creationalContext)
+   {
+      boolean registerInjectionPoint = !injectionPoint.getType().equals(InjectionPoint.class);
+      try
+      {
+         if (registerInjectionPoint)
+         {
+            currentInjectionPoint.get().push(injectionPoint);
+         }
+         AnnotatedItem<T, ?> element = ResolvableAnnotatedClass.of(injectionPoint.getType(), injectionPoint.getBindings().toArray(new Annotation[0]));
+         Bean<T> bean = getBeanByType(element, element.getBindingsAsArray());
+         if (creationalContext instanceof CreationalContextImpl)
+         {
+            CreationalContextImpl<?> ctx = (CreationalContextImpl<?>) creationalContext;
+            if (ctx.containsIncompleteInstance(bean))
+            {
+               return ctx.getIncompleteInstance(bean);
+            }
+            else
+            {
+               return getInstance(bean, ctx.getCreationalContext(bean));
+            }
+         }
+         else
+         {
+            return getInstance(bean);
+         }
+      }
+      finally
+      {
+         if (registerInjectionPoint)
+         {
+            currentInjectionPoint.get().pop();
+         }
+      }
+   }
+   
+   /**
+    * Gets an instance by name, returning null if none is found and throwing an
+    * exception if too many beans match
+    * 
+    * @param name
+    *           The name to match
+    * @return An instance of the bean
+    * 
+    * @see javax.inject.manager.Manager#getInstanceByName(java.lang.String)
+    */
+   public Object getInstanceByName(String name)
+   {
+      Set<Bean<?>> beans = resolveByName(name);
+      if (beans.size() == 0)
+      {
+         return null;
+      }
+      else if (beans.size() > 1)
+      {
+         throw new AmbiguousDependencyException("Resolved multiple Web Beans with " + name);
+      }
+      else
+      {
+         return getInstance(beans.iterator().next());
+      }
+   }
+   
+   /**
+    * Returns an instance by API type and binding types
+    * 
+    * @param type
+    *           The API type to match
+    * @param bindings
+    *           The binding types to match
+    * @return An instance of the bean
+    * 
+    * @see javax.inject.manager.Manager#getInstanceByType(java.lang.Class,
+    *      java.lang.annotation.Annotation[])
+    */
+   public <T> T getInstanceByType(Class<T> type, Annotation... bindings)
+   {
+      return getInstanceByType(ResolvableAnnotatedClass.of(type, bindings), bindings);
+   }
+   
+   /**
+    * Returns an instance by type literal and binding types
+    * 
+    * @param type
+    *           The type to match
+    * @param bindings
+    *           The binding types to match
+    * @return An instance of the bean
+    * 
+    * @see javax.inject.manager.Manager#getInstanceByType(javax.inject.TypeLiteral,
+    *      java.lang.annotation.Annotation[])
+    */
+   public <T> T getInstanceByType(TypeLiteral<T> type, Annotation... bindings)
+   {
+      return getInstanceByType(ResolvableAnnotatedClass.of(type, bindings), bindings);
+   }
+   
+   /**
+    * Resolve an instance, verify that the resolved bean can be instantiated,
+    * and return
+    * 
+    * @param element
+    *           The annotated item to match
+    * @param bindings
+    *           The binding types to match
+    * @return An instance of the bean
+    */
+   private <T> T getInstanceByType(AnnotatedItem<T, ?> element, Annotation... bindings)
+   {
+      return getInstance(getBeanByType(element, bindings));
+   }
+   
+   public <T> Bean<T> getBeanByType(AnnotatedItem<T, ?> element, Annotation... bindings)
+   {
+      Set<Bean<T>> beans = resolveByType(element, bindings);
+      if (beans.size() == 0)
+      {
+         throw new UnsatisfiedDependencyException(element + "Unable to resolve any Web Beans");
+      }
+      else if (beans.size() > 1)
+      {
+         throw new AmbiguousDependencyException(element + "Resolved multiple Web Beans");
+      }
+      Bean<T> bean = beans.iterator().next();
+      boolean normalScoped = MetaDataCache.instance().getScopeModel(bean.getScopeType()).isNormal();
+      if (normalScoped && !Beans.isBeanProxyable(bean))
+      {
+         throw new UnproxyableDependencyException("Normal scoped bean " + bean + " is not proxyable");
+      }
+      return bean;
+   }
+   
+   /**
+    * Removes an observer
+    * 
+    * @param observer
+    *           The observer to remove
+    * @param eventType
+    *           The event type to match
+    * @param bindings
+    *           the binding types to match
+    * @return A reference to the manager
+    * 
+    * @see javax.inject.manager.Manager#removeObserver(javax.event.Observer,
+    *      java.lang.Class, java.lang.annotation.Annotation[])
+    */
+   public <T> Manager removeObserver(Observer<T> observer, Class<T> eventType, Annotation... bindings)
+   {
+      this.eventManager.removeObserver(observer, eventType, bindings);
+      return this;
+   }
+   
+   /**
+    * Removes an observer
+    * 
+    * @param observer
+    *           The observer to remove
+    * @param eventType
+    *           The event type to match
+    * @param bindings
+    *           the binding types to match
+    * @return A reference to the manager
+    * 
+    * @see javax.inject.manager.Manager#removeObserver(javax.event.Observer,
+    *      javax.inject.TypeLiteral, java.lang.annotation.Annotation[])
+    */
+   public <T> Manager removeObserver(Observer<T> observer, TypeLiteral<T> eventType, Annotation... bindings)
+   {
+      this.eventManager.removeObserver(observer, eventType.getRawType(), bindings);
+      return this;
+   }
+   
+   /**
+    * Resolves a set of beans based on their name
+    * 
+    * @param The
+    *           name to match
+    * @return The set of matching beans
+    * 
+    * @see javax.inject.manager.Manager#resolveByName(java.lang.String)
+    */
+   public Set<Bean<?>> resolveByName(String name)
+   {
+      return resolver.get(name);
+   }
+   
+   /**
+    * Resolves a list of decorators based on API types and binding types Os
+    * 
+    * @param types
+    *           The set of API types to match
+    * @param bindings
+    *           The binding types to match
+    * @return A list of matching decorators
+    * 
+    * @see javax.inject.manager.Manager#resolveDecorators(java.util.Set,
+    *      java.lang.annotation.Annotation[])
+    */
+   public List<Decorator> resolveDecorators(Set<Type> types, Annotation... bindings)
+   {
+      throw new UnsupportedOperationException();
+   }
+   
+   /**
+    * Resolves a list of interceptors based on interception type and interceptor
+    * bindings
+    * 
+    * @param type
+    *           The interception type to resolve
+    * @param interceptorBindings
+    *           The binding types to match
+    * @return A list of matching interceptors
+    * 
+    * @see javax.inject.manager.Manager#resolveInterceptors(javax.inject.manager.InterceptionType,
+    *      java.lang.annotation.Annotation[])
+    */
+   public List<Interceptor> resolveInterceptors(InterceptionType type, Annotation... interceptorBindings)
+   {
+      throw new UnsupportedOperationException();
+   }
+   
+   /**
+    * Get the web bean resolver. For internal use
+    * 
+    * @return The resolver
+    */
+   public Resolver getResolver()
+   {
+      return resolver;
+   }
+   
+   public EjbDescriptorCache getEjbDescriptorCache()
+   {
+      return ejbDescriptorCache;
+   }
+   
+   /**
+    * Gets a string representation
+    * 
+    * @return A string representation
+    */
+   @Override
+   public String toString()
+   {
+      StringBuilder buffer = new StringBuilder();
+      buffer.append("Manager\n");
+      buffer.append("Enabled deployment types: " + getEnabledDeploymentTypes() + "\n");
+      buffer.append("Registered contexts: " + contextMap.keySet() + "\n");
+      buffer.append("Registered beans: " + getBeans().size() + "\n");
+      buffer.append("Registered decorators: " + decorators.size() + "\n");
+      buffer.append("Registered interceptors: " + interceptors.size() + "\n");
+      buffer.append("Specialized beans: " + specializedBeans.size() + "\n");
+      return buffer.toString();
+   }
+   
+   public Manager parse(InputStream xmlStream)
+   {
+      throw new UnsupportedOperationException();
+   }
+   
+   public Manager createActivity()
+   {
+      return new ChildManager(this);
+   }
+   
+   public Manager setCurrent(Class<? extends Annotation> scopeType)
+   {
+      throw new UnsupportedOperationException();
+   }
+   
+   public ServiceRegistry getServices()
+   {
+      return simpleServiceRegistry;
+   }
+   
+   /**
+    * Accesses the factory used to create each instance of InjectionPoint that
+    * is injected into web beans.
+    * 
+    * @return the factory
+    */
+   public InjectionPoint getInjectionPoint()
+   {
+      if (!currentInjectionPoint.get().empty())
+      {
+         return currentInjectionPoint.get().peek();
+      }
+      else
+      {
+         return null;
+      }
+   }
+   
+   /**
+    * 
+    * @return
+    */
+   public Map<Bean<?>, Bean<?>> getSpecializedBeans()
+   {
+      // TODO make this unmodifiable after deploy!
+      return specializedBeans;
+   }
+   
+   // Serialization
+   
+   protected Object readResolve()
+   {
+      return CurrentManager.rootManager();
+   }
+   
+   /**
+    * Provides access to the executor service used for asynchronous tasks.
+    * 
+    * @return the ExecutorService for this manager
+    */
+   public ExecutorService getTaskExecutor()
+   {
+      return taskExecutor;
+   }
+   
+   public void shutdown()
+   {
+      log.trace("Ending application");
+      shutdownExecutors();
+      ApplicationContext.INSTANCE.destroy();
+      ApplicationContext.INSTANCE.setActive(false);
+      ApplicationContext.INSTANCE.setBeanStore(null);
+      getServices().get(NamingContext.class).unbind(RootManager.JNDI_KEY);
+   }
+   
+   /**
+    * Shuts down any executor services in the manager.
+    */
+   protected void shutdownExecutors()
+   {
+      taskExecutor.shutdown();
+      try
+      {
+         // Wait a while for existing tasks to terminate
+         if (!taskExecutor.awaitTermination(60, TimeUnit.SECONDS))
+         {
+            taskExecutor.shutdownNow(); // Cancel currently executing tasks
+            // Wait a while for tasks to respond to being cancelled
+            if (!taskExecutor.awaitTermination(60, TimeUnit.SECONDS))
+            {
+               // Log the error here
+            }
+         }
+      }
+      catch (InterruptedException ie)
+      {
+         // (Re-)Cancel if current thread also interrupted
+         taskExecutor.shutdownNow();
+         // Preserve interrupt status
+         Thread.currentThread().interrupt();
+      }
+   }
+   
+}

Added: ri/trunk/impl/src/main/java/org/jboss/webbeans/bean/DisposalMethodBean.java
===================================================================
--- ri/trunk/impl/src/main/java/org/jboss/webbeans/bean/DisposalMethodBean.java	                        (rev 0)
+++ ri/trunk/impl/src/main/java/org/jboss/webbeans/bean/DisposalMethodBean.java	2009-03-31 07:38:18 UTC (rev 2279)
@@ -0,0 +1,298 @@
+package org.jboss.webbeans.bean;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import javax.context.CreationalContext;
+import javax.event.Observes;
+import javax.inject.DefinitionException;
+import javax.inject.Disposes;
+import javax.inject.Initializer;
+import javax.inject.Produces;
+import javax.inject.manager.Bean;
+import javax.inject.manager.InjectionPoint;
+
+import org.jboss.webbeans.RootManager;
+import org.jboss.webbeans.bootstrap.BeanDeployerEnvironment;
+import org.jboss.webbeans.injection.AnnotatedInjectionPoint;
+import org.jboss.webbeans.injection.MethodInjectionPoint;
+import org.jboss.webbeans.injection.ParameterInjectionPoint;
+import org.jboss.webbeans.introspector.AnnotatedItem;
+import org.jboss.webbeans.introspector.AnnotatedMethod;
+import org.jboss.webbeans.introspector.AnnotatedParameter;
+
+public class DisposalMethodBean<T> extends AbstractBean<T, Method>
+{
+
+   protected DisposalMethodBean(RootManager manager, AnnotatedMethod<T> disposalMethod, Bean<?> declaringBean)
+   {
+      super(manager);
+      this.disposalMethod = disposalMethod;
+      this.declaringBean = declaringBean;
+      checkDisposalMethod();
+      initInjectionPoints();
+      initType();
+      initTypes();
+      this.id = createId("DisposalMethod-" + declaringBean.getName() + "-"+ disposalMethod.getSignature().toString());
+      
+   }
+
+   protected Bean<?> declaringBean;
+   protected AnnotatedMethod<T> disposalMethod;
+   protected Set<AnnotatedInjectionPoint<?, ?>> disposalInjectionPoints;
+   private String id;
+
+   @Override
+   protected void initTypes()
+   {
+      Set<Type> types = new HashSet<Type>();
+      types = new HashSet<Type>();
+      types.add(getType());
+      types.add(Object.class); // FODO: Maybe not?
+      super.types = types;
+   }
+
+   protected void initType()
+   {
+      this.type = (Class<T>) disposalMethod.getAnnotatedParameters(Disposes.class).get(0).getRawType();
+   }
+
+   public static <T> DisposalMethodBean<T> of(RootManager manager, AnnotatedMethod<T> disposalMethod, Bean<?> declaringBean)
+   {
+      return new DisposalMethodBean<T>(manager, disposalMethod, declaringBean);
+   }
+
+   private void initInjectionPoints()
+   {
+      disposalInjectionPoints = new HashSet<AnnotatedInjectionPoint<?, ?>>();
+
+      List<? extends AnnotatedParameter<?>> disposalMethodParameters = disposalMethod.getParameters();
+
+      // First one must be @Disposes, if more, register injectionpoints
+      if (disposalMethodParameters.size() > 1)
+      {
+         for (int i = 1; i < disposalMethodParameters.size(); i++)
+         {
+            AnnotatedParameter<?> parameter = disposalMethodParameters.get(i);
+            disposalInjectionPoints.add(ParameterInjectionPoint.of(declaringBean, parameter));
+         }
+      }
+
+      injectionPoints.add(MethodInjectionPoint.of(declaringBean, disposalMethod));
+
+   }
+
+   @Override
+   public Set<Annotation> getBindings()
+   {
+      // At least 1 parameter exists, already checked in constructor
+      return disposalMethod.getParameters().get(0).getBindings();
+   }
+
+   @Override
+   public Class<? extends Annotation> getDeploymentType()
+   {
+      return declaringBean.getDeploymentType();
+   }
+
+   public Set<AnnotatedInjectionPoint<?, ?>> getInjectionPoints()
+   {
+      return injectionPoints;
+   }
+
+   @Override
+   public String getName()
+   {
+      return disposalMethod.getPropertyName();
+   }
+
+   @Override
+   public Class<? extends Annotation> getScopeType()
+   {
+      return declaringBean.getScopeType();
+   }
+
+   @Override
+   public Set<? extends Type> getTypes()
+   {
+      return types;
+   }
+
+   @Override
+   public String toString()
+   {
+      return disposalMethod.toString();
+   }
+
+   @Override
+   public boolean isNullable()
+   {
+      return false;
+   }
+
+   @Override
+   public boolean isSerializable()
+   {
+      return declaringBean.isSerializable();
+   }
+
+   public T create(CreationalContext<T> creationalContext)
+   {
+      return null;
+   }
+
+   public void invokeDisposeMethod(Object instance)
+   {
+      List<Object> parameters = new LinkedList<Object>();
+
+      parameters.add(instance);
+
+      for (InjectionPoint injectionPoint : disposalInjectionPoints)
+      {
+         Object injectionObject = getManager().getInstanceToInject(injectionPoint);
+         parameters.add(injectionObject);
+      }
+
+      Object beanInstance = disposalMethod.isStatic() ? declaringBean : getManager().getInstance(declaringBean);
+
+      try
+      {
+         disposalMethod.invoke(beanInstance, parameters.toArray());
+      }
+      catch (Exception e)
+      {
+         // TODO: 
+      }
+
+   }
+
+   private void checkDisposalMethod()
+   {
+      if (!disposalMethod.getParameters().get(0).isAnnotationPresent(Disposes.class))
+      {
+         throw new DefinitionException(disposalMethod.toString() + " doesn't have @Dispose as first parameter");
+      }
+      if (disposalMethod.getAnnotatedParameters(Disposes.class).size() > 1)
+      {
+         throw new DefinitionException(disposalMethod.toString() + " has more than one @Dispose parameters");
+      }
+      if (disposalMethod.getAnnotatedParameters(Observes.class).size() > 0)
+      {
+         throw new DefinitionException("@Observes is not allowed on disposal method, see " + disposalMethod.toString());
+      }
+      if (disposalMethod.getAnnotation(Initializer.class) != null)
+      {
+         throw new DefinitionException("@Intitializer is not allowed on a disposal method, see " + disposalMethod.toString());
+      }
+      if (disposalMethod.getAnnotation(Produces.class) != null)
+      {
+         throw new DefinitionException("@Produces is not allowed on a disposal method, see " + disposalMethod.toString());
+      }
+      if (declaringBean instanceof EnterpriseBean)
+      {
+         boolean methodDeclaredOnTypes = false;
+         // TODO use annotated item?
+         for (Type type : declaringBean.getTypes())
+         {
+            if (type instanceof Class)
+            {
+               Class<?> clazz = (Class<?>) type;
+               try
+               {
+                  clazz.getDeclaredMethod(disposalMethod.getName(), disposalMethod.getParameterTypesAsArray());
+                  methodDeclaredOnTypes = true;
+               }
+               catch (NoSuchMethodException nsme)
+               {
+                  // No - op
+               }
+            }
+         }
+         if (!methodDeclaredOnTypes)
+         {
+            throw new DefinitionException("Producer method " + toString() + " must be declared on a business interface of " + declaringBean);
+         }
+      }
+   }
+
+   @Override
+   public Class<T> getType()
+   {
+      return type;
+   }
+
+   @Override
+   public void initialize(BeanDeployerEnvironment environment)
+   {
+
+   }
+
+   @Override
+   public boolean isPrimitive()
+   {
+      return false;
+   }
+
+   @Override
+   public boolean isProxyable()
+   {
+      return false;
+   }
+
+   @Override
+   public boolean isSpecializing()
+   {
+      return false;
+   }
+
+   @Override
+   protected AnnotatedItem<T, Method> getAnnotatedItem()
+   {
+      return disposalMethod;
+   }
+
+   @Override
+   protected Class<? extends Annotation> getDefaultDeploymentType()
+   {
+      return declaringBean.getDeploymentType();
+   }
+
+   @Override
+   protected String getDefaultName()
+   {
+      return disposalMethod.getPropertyName();
+   }
+
+   @Override
+   protected void initDeploymentType()
+   {
+   }
+
+   @Override
+   protected void initScopeType()
+   {
+   }
+
+   @Override
+   public AbstractBean<?, ?> getSpecializedBean()
+   {
+      return null;
+   }
+
+   public void destroy(T instance)
+   {
+
+   }
+
+   @Override
+   public String getId()
+   {
+      return id;
+   }
+
+}

Modified: ri/trunk/impl/src/main/java/org/jboss/webbeans/bean/ProducerMethodBean.java
===================================================================
--- ri/trunk/impl/src/main/java/org/jboss/webbeans/bean/ProducerMethodBean.java	2009-03-31 03:54:17 UTC (rev 2278)
+++ ri/trunk/impl/src/main/java/org/jboss/webbeans/bean/ProducerMethodBean.java	2009-03-31 07:38:18 UTC (rev 2279)
@@ -1,266 +1,276 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,  
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.jboss.webbeans.bean;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.util.Set;
-
-import javax.context.CreationalContext;
-import javax.event.Observes;
-import javax.inject.CreationException;
-import javax.inject.DefinitionException;
-import javax.inject.Disposes;
-
-import org.jboss.webbeans.RootManager;
-import org.jboss.webbeans.bootstrap.BeanDeployerEnvironment;
-import org.jboss.webbeans.injection.MethodInjectionPoint;
-import org.jboss.webbeans.injection.ParameterInjectionPoint;
-import org.jboss.webbeans.introspector.AnnotatedMethod;
-import org.jboss.webbeans.introspector.AnnotatedParameter;
-import org.jboss.webbeans.util.Names;
-
-/**
- * Represents a producer method bean
- * 
- * @author Pete Muir
- * 
- * @param <T>
- */
-public class ProducerMethodBean<T> extends AbstractProducerBean<T, Method>
-{
-   // The underlying method
-   private MethodInjectionPoint<T> method;
-   
-   private AnnotatedMethod<?> disposalMethod;
-   
-   private ProducerMethodBean<?> specializedBean;
-
-   private final String id;
-   
-   /**
-    * Creates a producer method Web Bean
-    * 
-    * @param method
-    *           The underlying method abstraction
-    * @param declaringBean
-    *           The declaring bean abstraction
-    * @param manager
-    *           the current manager
-    * @return A producer Web Bean
-    */
-   public static <T> ProducerMethodBean<T> of(AnnotatedMethod<T> method, AbstractClassBean<?> declaringBean, RootManager manager)
-   {
-      return new ProducerMethodBean<T>(method, declaringBean, manager);
-   }
-   
-   protected ProducerMethodBean(AnnotatedMethod<T> method, AbstractClassBean<?> declaringBean, RootManager manager)
-   {
-      super(declaringBean, manager);
-      this.method = MethodInjectionPoint.of(this, method);
-      initType();
-      initTypes();
-      initBindings();
-      this.id = createId("ProducerField-" + declaringBean.getType().getName() + "-"+ method.getSignature().toString());
-   }
-   
-   protected T produceInstance(CreationalContext<T> creationalContext)
-   {
-      Object receiver = getReceiver(creationalContext);
-      if (receiver != null)
-      {
-         return method.invokeOnInstance(receiver, manager, creationalContext, CreationException.class);
-      }
-      else
-      {
-         return method.invoke(receiver, manager, creationalContext, CreationException.class);
-      }
-   }
-   
-   /**
-    * Initializes the bean and its metadata
-    */
-   @Override
-   public void initialize(BeanDeployerEnvironment environment)
-   {
-      if (!isInitialized())
-      {
-         super.initialize(environment);
-         checkProducerMethod();
-         // initDisposalMethod();
-         initInjectionPoints();
-      }
-   }
-   
-   /**
-    * Initializes the injection points
-    */
-   protected void initInjectionPoints()
-   {
-      for (AnnotatedParameter<?> parameter : method.getParameters())
-      {
-         injectionPoints.add(ParameterInjectionPoint.of(this, parameter));
-      }
-   }
-   
-   /**
-    * Validates the producer method
-    */
-   protected void checkProducerMethod()
-   {
-      if (getAnnotatedItem().getAnnotatedParameters(Observes.class).size() > 0)
-      {
-         throw new DefinitionException("Producer method cannot have parameter annotated @Observes");
-      }
-      else if (getAnnotatedItem().getAnnotatedParameters(Disposes.class).size() > 0)
-      {
-         throw new DefinitionException("Producer method cannot have parameter annotated @Disposes");
-      }
-      else if (declaringBean instanceof EnterpriseBean)
-      {
-         boolean methodDeclaredOnTypes = false;
-         // TODO use annotated item?
-         for (Type type : declaringBean.getTypes())
-         {
-            if (type instanceof Class)
-            {
-               Class<?> clazz = (Class<?>) type;
-               try
-               {
-                  clazz.getDeclaredMethod(getAnnotatedItem().getName(), getAnnotatedItem().getParameterTypesAsArray());
-                  methodDeclaredOnTypes = true;
-               }
-               catch (NoSuchMethodException nsme) 
-               {
-                  // No - op
-               }
-            }
-         }
-         if (!methodDeclaredOnTypes)
-         {
-            throw new DefinitionException("Producer method " + toString() + " must be declared on a business interface of " + declaringBean);
-         }
-      }
-   }
-   
-   /**
-    * Initializes the remove method
-    */
-   protected void initDisposalMethod(BeanDeployerEnvironment environment)
-   {
-      Set<AnnotatedMethod<?>> disposalMethods = manager.resolveDisposalMethods(getType(), getBindings().toArray(new Annotation[0]));
-      if (disposalMethods.size() == 1)
-      {
-         this.disposalMethod = disposalMethods.iterator().next();
-      }
-      else if (disposalMethods.size() > 1)
-      {
-         // TODO List out found disposal methods
-         throw new DefinitionException("Cannot declare multiple disposal methods for this producer method");
-      }
-   }
-   
-   /**
-    * Gets the annotated item representing the method
-    * 
-    * @return The annotated item
-    */
-   @Override
-   public AnnotatedMethod<T> getAnnotatedItem()
-   {
-      return method;
-   }
-   
-   /**
-    * Returns the default name
-    * 
-    * @return The default name
-    */
-   @Override
-   protected String getDefaultName()
-   {
-      return method.getPropertyName();
-   }
-   
-   /**
-    * Returns the disposal method
-    * 
-    * @return The method representation
-    */
-   public AnnotatedMethod<?> getDisposalMethod()
-   {
-      return disposalMethod;
-   }
-   
-   /**
-    * Gets a string representation
-    * 
-    * @return The string representation
-    */
-   @Override
-   public String toString()
-   {
-      StringBuilder buffer = new StringBuilder();
-      buffer.append(Names.scopeTypeToString(getScopeType()));
-      if (getName() == null)
-      {
-         buffer.append("unnamed producer method bean");
-      }
-      else
-      {
-         buffer.append("simple producer method bean '" + getName() + "'");
-      }
-      buffer.append(" [" + getType().getName() + "] ");
-      buffer.append("API types " + getTypes() + ", binding types " + getBindings());
-      return buffer.toString();
-   }
-
-   @Override
-   public AbstractBean<?, ?> getSpecializedBean()
-   {
-      return specializedBean;
-   }
-   
-   @Override
-   protected void preSpecialize()
-   {
-      if (declaringBean.getAnnotatedItem().getSuperclass().getDeclaredMethod(getAnnotatedItem().getAnnotatedMethod()) == null)
-      {
-         throw new DefinitionException("Specialized producer method does not override a method on the direct superclass");
-      }
-   }
-   
-   @Override
-   protected void specialize(BeanDeployerEnvironment environment)
-   {
-      AnnotatedMethod<?> superClassMethod = declaringBean.getAnnotatedItem().getSuperclass().getMethod(getAnnotatedItem().getAnnotatedMethod());
-      if (environment.getProducerMethod(superClassMethod) == null)
-      {
-         throw new IllegalStateException(toString() + " does not specialize a bean");
-      }
-      this.specializedBean = environment.getProducerMethod(superClassMethod);
-   }
-   
-   @Override
-   public String getId()
-   {
-      return id;
-   }
-   
-}
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,  
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jboss.webbeans.bean;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Set;
+
+import javax.context.CreationalContext;
+import javax.event.Observes;
+import javax.inject.CreationException;
+import javax.inject.DefinitionException;
+import javax.inject.Disposes;
+import javax.inject.manager.Bean;
+
+import org.jboss.webbeans.RootManager;
+import org.jboss.webbeans.bootstrap.BeanDeployerEnvironment;
+import org.jboss.webbeans.injection.MethodInjectionPoint;
+import org.jboss.webbeans.injection.ParameterInjectionPoint;
+import org.jboss.webbeans.introspector.AnnotatedMethod;
+import org.jboss.webbeans.introspector.AnnotatedParameter;
+import org.jboss.webbeans.util.Names;
+
+/**
+ * Represents a producer method bean
+ * 
+ * @author Pete Muir
+ * 
+ * @param <T>
+ */
+public class ProducerMethodBean<T> extends AbstractProducerBean<T, Method>
+{
+   // The underlying method
+   private MethodInjectionPoint<T> method;
+
+   private DisposalMethodBean<?> disposalMethodBean;
+
+   private ProducerMethodBean<?> specializedBean;
+
+   private final String id;
+
+   /**
+    * Creates a producer method Web Bean
+    * 
+    * @param method The underlying method abstraction
+    * @param declaringBean The declaring bean abstraction
+    * @param manager the current manager
+    * @return A producer Web Bean
+    */
+   public static <T> ProducerMethodBean<T> of(AnnotatedMethod<T> method, AbstractClassBean<?> declaringBean, RootManager manager)
+   {
+      return new ProducerMethodBean<T>(method, declaringBean, manager);
+   }
+
+   protected ProducerMethodBean(AnnotatedMethod<T> method, AbstractClassBean<?> declaringBean, RootManager manager)
+   {
+      super(declaringBean, manager);
+      this.method = MethodInjectionPoint.of(this, method);
+      initType();
+      initTypes();
+      initBindings();
+      this.id = createId("ProducerField-" + declaringBean.getType().getName() + "-" + method.getSignature().toString());
+   }
+
+   protected T produceInstance(CreationalContext<T> creationalContext)
+   {
+      Object receiver = getReceiver(creationalContext);
+      if (receiver != null)
+      {
+         return method.invokeOnInstance(receiver, manager, creationalContext, CreationException.class);
+      }
+      else
+      {
+         return method.invoke(receiver, manager, creationalContext, CreationException.class);
+      }
+   }
+
+   /**
+    * Initializes the bean and its metadata
+    */
+   @Override
+   public void initialize(BeanDeployerEnvironment environment)
+   {
+      if (!isInitialized())
+      {
+         super.initialize(environment);
+         checkProducerMethod();
+         // initDisposalMethod();
+         initInjectionPoints();
+      }
+   }
+
+   /**
+    * Initializes the injection points
+    */
+   protected void initInjectionPoints()
+   {
+      for (AnnotatedParameter<?> parameter : method.getParameters())
+      {
+         injectionPoints.add(ParameterInjectionPoint.of(this, parameter));
+      }
+   }
+
+   /**
+    * Validates the producer method
+    */
+   protected void checkProducerMethod()
+   {
+      if (getAnnotatedItem().getAnnotatedParameters(Observes.class).size() > 0)
+      {
+         throw new DefinitionException("Producer method cannot have parameter annotated @Observes");
+      }
+      else if (getAnnotatedItem().getAnnotatedParameters(Disposes.class).size() > 0)
+      {
+         throw new DefinitionException("Producer method cannot have parameter annotated @Disposes");
+      }
+      else if (declaringBean instanceof EnterpriseBean)
+      {
+         boolean methodDeclaredOnTypes = false;
+         // TODO use annotated item?
+         for (Type type : declaringBean.getTypes())
+         {
+            if (type instanceof Class)
+            {
+               Class<?> clazz = (Class<?>) type;
+               try
+               {
+                  clazz.getDeclaredMethod(getAnnotatedItem().getName(), getAnnotatedItem().getParameterTypesAsArray());
+                  methodDeclaredOnTypes = true;
+               }
+               catch (NoSuchMethodException nsme)
+               {
+                  // No - op
+               }
+            }
+         }
+         if (!methodDeclaredOnTypes)
+         {
+            throw new DefinitionException("Producer method " + toString() + " must be declared on a business interface of " + declaringBean);
+         }
+      }
+   }
+
+   /**
+    * Initializes the remove method
+    */
+   protected void initDisposalMethod(BeanDeployerEnvironment environment)
+   {
+      Set<Bean<T>> disposalBeans = manager.resolveDisposalBeans(getType(), bindings.toArray(new Annotation[0]));
+
+      if (disposalBeans.size() == 1)
+      {
+         this.disposalMethodBean = (DisposalMethodBean<?>) disposalBeans.iterator().next();
+         environment.addResolvedDisposalBean(disposalMethodBean);
+      }
+      else if (disposalBeans.size() > 1)
+      {
+         // TODO List out found disposal methods
+         throw new DefinitionException("Cannot declare multiple disposal methods for this producer method");
+      }
+   }
+
+   @Override
+   public void destroy(T instance)
+   {
+      // Delegate destruction to disposal method
+      if (disposalMethodBean != null)
+         disposalMethodBean.invokeDisposeMethod(instance);
+
+      super.destroy(instance);
+   }
+
+   /**
+    * Gets the annotated item representing the method
+    * 
+    * @return The annotated item
+    */
+   @Override
+   public AnnotatedMethod<T> getAnnotatedItem()
+   {
+      return method;
+   }
+
+   /**
+    * Returns the default name
+    * 
+    * @return The default name
+    */
+   @Override
+   protected String getDefaultName()
+   {
+      return method.getPropertyName();
+   }
+
+   /**
+    * Returns the disposal method
+    * 
+    * @return The method representation
+    */
+   public DisposalMethodBean<?> getDisposalMethod()
+   {
+      return disposalMethodBean;
+   }
+
+   /**
+    * Gets a string representation
+    * 
+    * @return The string representation
+    */
+   @Override
+   public String toString()
+   {
+      StringBuilder buffer = new StringBuilder();
+      buffer.append(Names.scopeTypeToString(getScopeType()));
+      if (getName() == null)
+      {
+         buffer.append("unnamed producer method bean");
+      }
+      else
+      {
+         buffer.append("simple producer method bean '" + getName() + "'");
+      }
+      buffer.append(" [" + getType().getName() + "] ");
+      buffer.append("API types " + getTypes() + ", binding types " + getBindings());
+      return buffer.toString();
+   }
+
+   @Override
+   public AbstractBean<?, ?> getSpecializedBean()
+   {
+      return specializedBean;
+   }
+
+   @Override
+   protected void preSpecialize()
+   {
+      if (declaringBean.getAnnotatedItem().getSuperclass().getDeclaredMethod(getAnnotatedItem().getAnnotatedMethod()) == null)
+      {
+         throw new DefinitionException("Specialized producer method does not override a method on the direct superclass");
+      }
+   }
+
+   @Override
+   protected void specialize(BeanDeployerEnvironment environment)
+   {
+      AnnotatedMethod<?> superClassMethod = declaringBean.getAnnotatedItem().getSuperclass().getMethod(getAnnotatedItem().getAnnotatedMethod());
+      if (environment.getProducerMethod(superClassMethod) == null)
+      {
+         throw new IllegalStateException(toString() + " does not specialize a bean");
+      }
+      this.specializedBean = environment.getProducerMethod(superClassMethod);
+   }
+
+   @Override
+   public String getId()
+   {
+      return id;
+   }
+
+}

Modified: ri/trunk/impl/src/main/java/org/jboss/webbeans/bootstrap/BeanDeployer.java
===================================================================
--- ri/trunk/impl/src/main/java/org/jboss/webbeans/bootstrap/BeanDeployer.java	2009-03-31 03:54:17 UTC (rev 2278)
+++ ri/trunk/impl/src/main/java/org/jboss/webbeans/bootstrap/BeanDeployer.java	2009-03-31 07:38:18 UTC (rev 2279)
@@ -1,340 +1,361 @@
-package org.jboss.webbeans.bootstrap;
-
-import java.lang.annotation.Annotation;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.event.Observes;
-import javax.inject.BindingType;
-import javax.inject.DeploymentType;
-import javax.inject.Initializer;
-import javax.inject.Produces;
-import javax.inject.Realizes;
-
-import org.jboss.webbeans.RootManager;
-import org.jboss.webbeans.bean.AbstractClassBean;
-import org.jboss.webbeans.bean.EnterpriseBean;
-import org.jboss.webbeans.bean.NewEnterpriseBean;
-import org.jboss.webbeans.bean.NewSimpleBean;
-import org.jboss.webbeans.bean.ProducerFieldBean;
-import org.jboss.webbeans.bean.ProducerMethodBean;
-import org.jboss.webbeans.bean.RIBean;
-import org.jboss.webbeans.bean.SimpleBean;
-import org.jboss.webbeans.ejb.EJBApiAbstraction;
-import org.jboss.webbeans.event.ObserverFactory;
-import org.jboss.webbeans.event.ObserverImpl;
-import org.jboss.webbeans.introspector.AnnotatedClass;
-import org.jboss.webbeans.introspector.AnnotatedField;
-import org.jboss.webbeans.introspector.AnnotatedMethod;
-import org.jboss.webbeans.introspector.WrappedAnnotatedField;
-import org.jboss.webbeans.introspector.WrappedAnnotatedMethod;
-import org.jboss.webbeans.introspector.jlr.AnnotatedClassImpl;
-import org.jboss.webbeans.jpa.spi.JpaServices;
-import org.jboss.webbeans.jsf.JSFApiAbstraction;
-import org.jboss.webbeans.log.LogProvider;
-import org.jboss.webbeans.log.Logging;
-import org.jboss.webbeans.servlet.ServletApiAbstraction;
-import org.jboss.webbeans.util.Reflections;
-
-public class BeanDeployer
-{
-   
-   private static final LogProvider log = Logging.getLogProvider(BeanDeployer.class);
-   
-   private final BeanDeployerEnvironment beanDeployerEnvironment;
-   private final Set<AnnotatedClass<?>> classes;
-   private final RootManager manager;
-   
-   public BeanDeployer(RootManager manager)
-   {
-      this.manager = manager;
-      this.beanDeployerEnvironment = new BeanDeployerEnvironment();
-      this.classes = new HashSet<AnnotatedClass<?>>();
-   }
-   
-   public <T> BeanDeployer addBean(RIBean<T> bean)
-   {
-      this.beanDeployerEnvironment.addBean(bean);
-      return this;
-   }
-   
-   public BeanDeployer addClass(Class<?> clazz)
-   {
-      if (!clazz.isAnnotation() && !clazz.isEnum())
-      {
-         classes.add(AnnotatedClassImpl.of(clazz));
-      }
-      return this;
-   }
-   
-   public BeanDeployer addClasses(Iterable<Class<?>> classes)
-   {
-      for (Class<?> clazz : classes)
-      {
-         addClass(clazz);
-      }
-      return this;
-   }
-   
-   public BeanDeployer addClasses(Collection<AnnotatedClass<?>> classes)
-   {
-      classes.addAll(classes);
-      return this;
-   }
-   
-   public BeanDeployer createBeans()
-   {
-      for (AnnotatedClass<?> clazz : classes)
-      {
-         if (manager.getEjbDescriptorCache().containsKey(clazz.getRawType()))
-         {
-            createEnterpriseBean(clazz);
-         }
-         else if (isTypeSimpleWebBean(clazz))
-         {
-            createSimpleBean(clazz);
-         }
-      }
-      return this;
-   }
-   
-   public BeanDeployer deploy()
-   {
-      Set<RIBean<?>> beans = beanDeployerEnvironment.getBeans();
-      for (RIBean<?> bean : beans)
-      {
-         bean.initialize(beanDeployerEnvironment);
-         log.info("Bean: " + bean);
-      }
-      manager.setBeans(beans);
-      for (ObserverImpl<?> observer : beanDeployerEnvironment.getObservers())
-      {
-         observer.initialize();
-         log.info("Observer : " + observer);
-         manager.addObserver(observer);
-      }
-      return this;
-   }
-
-   public BeanDeployerEnvironment getBeanDeployerEnvironment()
-   {
-      return beanDeployerEnvironment;
-   }
-   
-   /**
-    * Creates a Web Bean from a bean abstraction and adds it to the set of
-    * created beans
-    * 
-    * Also creates the implicit field- and method-level beans, if present
-    * 
-    * @param bean
-    *           The bean representation
-    */
-   protected <T> void createBean(AbstractClassBean<T> bean, final AnnotatedClass<T> annotatedClass)
-   {
-      
-      addBean(bean);
-      
-      manager.getResolver().addInjectionPoints(bean.getInjectionPoints());
-      
-      createProducerMethods(bean, annotatedClass);
-      createProducerFields(bean, annotatedClass);
-      createObserverMethods(bean, annotatedClass);
-      createDisposalMethods(bean, annotatedClass);
-      
-      if (annotatedClass.isAnnotationPresent(Realizes.class))
-      {
-         createRealizedProducerMethods(bean, annotatedClass);
-         createRealizedProducerFields(bean, annotatedClass);
-         createRealizedObserverMethods(bean, annotatedClass);
-      }
-   }
-   
-   private void createProducerMethods(AbstractClassBean<?> declaringBean, AnnotatedClass<?> annotatedClass)
-   {
-      for (AnnotatedMethod<?> method : annotatedClass.getDeclaredAnnotatedMethods(Produces.class))
-      {
-         createProducerMethod(declaringBean, method);         
-      }
-   }
-   
-   private void createDisposalMethods(AbstractClassBean<?> declaringBean, AnnotatedClass<?> annotatedClass)
-   {
-      
-   }
-   
-   private <T> void createProducerMethod(AbstractClassBean<?> declaringBean, AnnotatedMethod<T> annotatedMethod)
-   {
-      ProducerMethodBean<T> bean = ProducerMethodBean.of(annotatedMethod, declaringBean, manager);
-      addBean(bean);
-      manager.getResolver().addInjectionPoints(bean.getInjectionPoints());
-   }
-   
-   private void createRealizedProducerMethods(AbstractClassBean<?> declaringBean, AnnotatedClass<?> realizingClass)
-   {
-      AnnotatedClass<?> realizedClass = realizingClass.getSuperclass();
-      for (AnnotatedMethod<?> realizedMethod : realizedClass.getDeclaredAnnotatedMethods(Produces.class))
-      {
-         createProducerMethod(declaringBean, realizeProducerMethod(realizedMethod, realizingClass));
-      }
-   }
-   
-   private void createRealizedProducerFields(AbstractClassBean<?> declaringBean, AnnotatedClass<?> realizingClass)
-   {
-      AnnotatedClass<?> realizedClass = realizingClass.getSuperclass();
-      for (final AnnotatedField<?> realizedField : realizedClass.getDeclaredAnnotatedFields(Produces.class))
-      {
-         createProducerField(declaringBean, realizeProducerField(realizedField, realizingClass));
-      }
-   }
-   
-   private <T> void createProducerField(AbstractClassBean<?> declaringBean, AnnotatedField<T> field)
-   {
-      ProducerFieldBean<T> bean = ProducerFieldBean.of(field, declaringBean, manager);
-      addBean(bean);
-   }
-   
-   private void createProducerFields(AbstractClassBean<?> declaringBean, AnnotatedClass<?> annotatedClass)
-   {
-      for (AnnotatedField<?> field : annotatedClass.getDeclaredAnnotatedFields(Produces.class))
-      {
-         createProducerField(declaringBean, field);
-      }
-   }
-   
-   private void createObserverMethods(AbstractClassBean<?> declaringBean, AnnotatedClass<?> annotatedClass)
-   {
-      for (AnnotatedMethod<?> method : annotatedClass.getDeclaredMethodsWithAnnotatedParameters(Observes.class))
-      {
-         createObserverMethod(declaringBean, method);
-      }
-   }
-   
-   private void createRealizedObserverMethods(AbstractClassBean<?> declaringBean, AnnotatedClass<?> realizingClass)
-   {
-      createObserverMethods(declaringBean, realizingClass.getSuperclass());
-   }
-   
-   private void createObserverMethod(AbstractClassBean<?> declaringBean, AnnotatedMethod<?> method)
-   {
-      ObserverImpl<?> observer = ObserverFactory.create(method, declaringBean, manager);
-      beanDeployerEnvironment.getObservers().add(observer);
-   }
-   
-   private <T> void createSimpleBean(AnnotatedClass<T> annotatedClass)
-   {
-      SimpleBean<T> bean = SimpleBean.of(annotatedClass, manager);
-      createBean(bean, annotatedClass);
-      addBean(NewSimpleBean.of(annotatedClass, manager));
-   }
-   
-   private <T> void createEnterpriseBean(AnnotatedClass<T> annotatedClass)
-   {
-      // TODO Don't create enterprise bean if it has no local interfaces!
-      EnterpriseBean<T> bean = EnterpriseBean.of(annotatedClass, manager);
-      createBean(bean, annotatedClass);
-      addBean(NewEnterpriseBean.of(annotatedClass, manager));
-   }
-   
-   /**
-    * Indicates if the type is a simple Web Bean
-    * 
-    * @param type
-    *           The type to inspect
-    * @return True if simple Web Bean, false otherwise
-    */
-   private boolean isTypeSimpleWebBean(AnnotatedClass<?> clazz)
-   {
-      Class<?> rawType = clazz.getRawType();
-      EJBApiAbstraction ejbApiAbstraction = manager.getServices().get(EJBApiAbstraction.class);
-      JSFApiAbstraction jsfApiAbstraction = manager.getServices().get(JSFApiAbstraction.class);
-      ServletApiAbstraction servletApiAbstraction = manager.getServices().get(ServletApiAbstraction.class);
-      // TODO: check 3.2.1 for more rules!!!!!!
-      return !Reflections.isAbstract(rawType) && 
-             !Reflections.isParameterizedType(rawType) && 
-             !servletApiAbstraction.SERVLET_CLASS.isAssignableFrom(rawType) && 
-             !servletApiAbstraction.FILTER_CLASS.isAssignableFrom(rawType) && 
-             !servletApiAbstraction.SERVLET_CONTEXT_LISTENER_CLASS.isAssignableFrom(rawType) && 
-             !servletApiAbstraction.HTTP_SESSION_LISTENER_CLASS.isAssignableFrom(rawType) && 
-             !servletApiAbstraction.SERVLET_REQUEST_LISTENER_CLASS.isAssignableFrom(rawType) && 
-             !ejbApiAbstraction.ENTERPRISE_BEAN_CLASS.isAssignableFrom(rawType) && 
-             !jsfApiAbstraction.UICOMPONENT_CLASS.isAssignableFrom(rawType) && 
-             hasSimpleWebBeanConstructor(clazz)
-             && (manager.getServices().contains(JpaServices.class) ? !manager.getServices().get(JpaServices.class).discoverEntities().contains(clazz.getRawType()) : true);
-   }
-   
-   private static boolean hasSimpleWebBeanConstructor(AnnotatedClass<?> type)
-   {
-      return type.getNoArgsConstructor() != null || type.getAnnotatedConstructors(Initializer.class).size() > 0;
-   }
-   
-   private static <T> AnnotatedMethod<T> realizeProducerMethod(final AnnotatedMethod<T> method, final AnnotatedClass<?> realizingClass)
-   {
-      return new WrappedAnnotatedMethod<T>(method, realizingClass.getMetaAnnotations(BindingType.class))
-      {
-         
-         @Override
-         public Set<Annotation> getMetaAnnotations(Class<? extends Annotation> metaAnnotationType)
-         {
-            if (metaAnnotationType.equals(DeploymentType.class))
-            {
-               return realizingClass.getMetaAnnotations(DeploymentType.class);
-            }
-            else
-            {
-               return super.getMetaAnnotations(metaAnnotationType);
-            }
-         }
-         
-         @Override
-         public Set<Annotation> getDeclaredMetaAnnotations(Class<? extends Annotation> metaAnnotationType)
-         {
-            if (metaAnnotationType.equals(DeploymentType.class))
-            {
-               return realizingClass.getDeclaredMetaAnnotations(DeploymentType.class);
-            }
-            else
-            {
-               return super.getDeclaredMetaAnnotations(metaAnnotationType);
-            }
-         }
-         
-      };
-   }
-   
-   private static <T> AnnotatedField<T> realizeProducerField(final AnnotatedField<T> field, final AnnotatedClass<?> realizingClass)
-   {
-      return new WrappedAnnotatedField<T>(field, realizingClass.getMetaAnnotations(BindingType.class))
-      {
-         
-         @Override
-         public Set<Annotation> getMetaAnnotations(Class<? extends Annotation> metaAnnotationType)
-         {
-            if (metaAnnotationType.equals(DeploymentType.class))
-            {
-               return realizingClass.getMetaAnnotations(DeploymentType.class);
-            }
-            else
-            {
-               return super.getMetaAnnotations(metaAnnotationType);
-            }
-         }
-         
-         @Override
-         public Set<Annotation> getDeclaredMetaAnnotations(Class<? extends Annotation> metaAnnotationType)
-         {
-            if (metaAnnotationType.equals(DeploymentType.class))
-            {
-               return realizingClass.getDeclaredMetaAnnotations(DeploymentType.class);
-            }
-            else
-            {
-               return super.getDeclaredMetaAnnotations(metaAnnotationType);
-            }
-         }
-         
-      };
-   }
-   
-}
+package org.jboss.webbeans.bootstrap;
+
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.event.Observes;
+import javax.inject.BindingType;
+import javax.inject.DeploymentType;
+import javax.inject.Initializer;
+import javax.inject.Produces;
+import javax.inject.Realizes;
+import javax.inject.UnsatisfiedDependencyException;
+
+import org.jboss.webbeans.RootManager;
+import org.jboss.webbeans.bean.AbstractClassBean;
+import org.jboss.webbeans.bean.DisposalMethodBean;
+import org.jboss.webbeans.bean.EnterpriseBean;
+import org.jboss.webbeans.bean.NewEnterpriseBean;
+import org.jboss.webbeans.bean.NewSimpleBean;
+import org.jboss.webbeans.bean.ProducerFieldBean;
+import org.jboss.webbeans.bean.ProducerMethodBean;
+import org.jboss.webbeans.bean.RIBean;
+import org.jboss.webbeans.bean.SimpleBean;
+import org.jboss.webbeans.ejb.EJBApiAbstraction;
+import org.jboss.webbeans.event.ObserverFactory;
+import org.jboss.webbeans.event.ObserverImpl;
+import org.jboss.webbeans.introspector.AnnotatedClass;
+import org.jboss.webbeans.introspector.AnnotatedField;
+import org.jboss.webbeans.introspector.AnnotatedMethod;
+import org.jboss.webbeans.introspector.WrappedAnnotatedField;
+import org.jboss.webbeans.introspector.WrappedAnnotatedMethod;
+import org.jboss.webbeans.introspector.jlr.AnnotatedClassImpl;
+import org.jboss.webbeans.jpa.spi.JpaServices;
+import org.jboss.webbeans.jsf.JSFApiAbstraction;
+import org.jboss.webbeans.log.LogProvider;
+import org.jboss.webbeans.log.Logging;
+import org.jboss.webbeans.servlet.ServletApiAbstraction;
+import org.jboss.webbeans.util.Reflections;
+
+public class BeanDeployer
+{
+   
+   private static final LogProvider log = Logging.getLogProvider(BeanDeployer.class);
+   
+   private final BeanDeployerEnvironment beanDeployerEnvironment;
+   private final Set<AnnotatedClass<?>> classes;
+   private final RootManager manager;
+   
+   public BeanDeployer(RootManager manager)
+   {
+      this.manager = manager;
+      this.beanDeployerEnvironment = new BeanDeployerEnvironment();
+      this.classes = new HashSet<AnnotatedClass<?>>();
+   }
+   
+   public <T> BeanDeployer addBean(RIBean<T> bean)
+   {
+      this.beanDeployerEnvironment.addBean(bean);
+      return this;
+   }
+   
+   public BeanDeployer addClass(Class<?> clazz)
+   {
+      if (!clazz.isAnnotation() && !clazz.isEnum())
+      {
+         classes.add(AnnotatedClassImpl.of(clazz));
+      }
+      return this;
+   }
+   
+   public BeanDeployer addClasses(Iterable<Class<?>> classes)
+   {
+      for (Class<?> clazz : classes)
+      {
+         addClass(clazz);
+      }
+      return this;
+   }
+   
+   public BeanDeployer addClasses(Collection<AnnotatedClass<?>> classes)
+   {
+      classes.addAll(classes);
+      return this;
+   }
+   
+   public BeanDeployer createBeans()
+   {
+      for (AnnotatedClass<?> clazz : classes)
+      {
+         if (manager.getEjbDescriptorCache().containsKey(clazz.getRawType()))
+         {
+            createEnterpriseBean(clazz);
+         }
+         else if (isTypeSimpleWebBean(clazz))
+         {
+            createSimpleBean(clazz);
+         }
+      }
+      return this;
+   }
+   
+   public BeanDeployer deploy()
+   {
+      Set<RIBean<?>> beans = beanDeployerEnvironment.getBeans();
+      for (RIBean<?> bean : beans)
+      {
+         bean.initialize(beanDeployerEnvironment);
+         log.info("Bean: " + bean);
+      }
+      manager.setBeans(beans);
+      for (ObserverImpl<?> observer : beanDeployerEnvironment.getObservers())
+      {
+         observer.initialize();
+         log.info("Observer : " + observer);
+         manager.addObserver(observer);
+      }
+      
+      // TODO: move to boot
+      checkDisposalMethods();
+      
+      return this;
+   }
+
+   
+   private void checkDisposalMethods() {
+	      Set<DisposalMethodBean<?>> all = new HashSet<DisposalMethodBean<?>>(beanDeployerEnvironment.getAllDisposalBeans()); 
+	      Set<DisposalMethodBean<?>> resolved = new HashSet<DisposalMethodBean<?>>(beanDeployerEnvironment.getResolvedDisposalBeans()); 
+	      if(resolved.contains(all)) {
+	         StringBuffer buff = new StringBuffer();
+	         buff.append("The following Disposal methods where not resolved\n");
+	         all.removeAll(resolved);
+	         for(DisposalMethodBean<?> bean: all) {
+	            buff.append(bean.toString());
+	         }
+	         throw new UnsatisfiedDependencyException(buff.toString());
+	      }
+	   }   
+   
+   public BeanDeployerEnvironment getBeanDeployerEnvironment()
+   {
+      return beanDeployerEnvironment;
+   }
+   
+   /**
+    * Creates a Web Bean from a bean abstraction and adds it to the set of
+    * created beans
+    * 
+    * Also creates the implicit field- and method-level beans, if present
+    * 
+    * @param bean
+    *           The bean representation
+    */
+   protected <T> void createBean(AbstractClassBean<T> bean, final AnnotatedClass<T> annotatedClass)
+   {
+      
+      addBean(bean);
+      
+      manager.getResolver().addInjectionPoints(bean.getInjectionPoints());
+      
+      createProducerMethods(bean, annotatedClass);
+      createProducerFields(bean, annotatedClass);
+      createObserverMethods(bean, annotatedClass);
+      createDisposalMethods(bean, annotatedClass);
+      
+      if (annotatedClass.isAnnotationPresent(Realizes.class))
+      {
+         createRealizedProducerMethods(bean, annotatedClass);
+         createRealizedProducerFields(bean, annotatedClass);
+         createRealizedObserverMethods(bean, annotatedClass);
+      }
+   }
+   
+   private void createProducerMethods(AbstractClassBean<?> declaringBean, AnnotatedClass<?> annotatedClass)
+   {
+      for (AnnotatedMethod<?> method : annotatedClass.getDeclaredAnnotatedMethods(Produces.class))
+      {
+         createProducerMethod(declaringBean, method);         
+      }
+   }
+   
+   private void createDisposalMethods(AbstractClassBean<?> declaringBean, AnnotatedClass<?> annotatedClass)
+   {
+      
+   }
+   
+   private <T> void createProducerMethod(AbstractClassBean<?> declaringBean, AnnotatedMethod<T> annotatedMethod)
+   {
+      ProducerMethodBean<T> bean = ProducerMethodBean.of(annotatedMethod, declaringBean, manager);
+      addBean(bean);
+      manager.getResolver().addInjectionPoints(bean.getInjectionPoints());
+   }
+   
+   private void createRealizedProducerMethods(AbstractClassBean<?> declaringBean, AnnotatedClass<?> realizingClass)
+   {
+      AnnotatedClass<?> realizedClass = realizingClass.getSuperclass();
+      for (AnnotatedMethod<?> realizedMethod : realizedClass.getDeclaredAnnotatedMethods(Produces.class))
+      {
+         createProducerMethod(declaringBean, realizeProducerMethod(realizedMethod, realizingClass));
+      }
+   }
+   
+   private void createRealizedProducerFields(AbstractClassBean<?> declaringBean, AnnotatedClass<?> realizingClass)
+   {
+      AnnotatedClass<?> realizedClass = realizingClass.getSuperclass();
+      for (final AnnotatedField<?> realizedField : realizedClass.getDeclaredAnnotatedFields(Produces.class))
+      {
+         createProducerField(declaringBean, realizeProducerField(realizedField, realizingClass));
+      }
+   }
+   
+   private <T> void createProducerField(AbstractClassBean<?> declaringBean, AnnotatedField<T> field)
+   {
+      ProducerFieldBean<T> bean = ProducerFieldBean.of(field, declaringBean, manager);
+      addBean(bean);
+   }
+   
+   private void createProducerFields(AbstractClassBean<?> declaringBean, AnnotatedClass<?> annotatedClass)
+   {
+      for (AnnotatedField<?> field : annotatedClass.getDeclaredAnnotatedFields(Produces.class))
+      {
+         createProducerField(declaringBean, field);
+      }
+   }
+   
+   private void createObserverMethods(AbstractClassBean<?> declaringBean, AnnotatedClass<?> annotatedClass)
+   {
+      for (AnnotatedMethod<?> method : annotatedClass.getDeclaredMethodsWithAnnotatedParameters(Observes.class))
+      {
+         createObserverMethod(declaringBean, method);
+      }
+   }
+   
+   private void createRealizedObserverMethods(AbstractClassBean<?> declaringBean, AnnotatedClass<?> realizingClass)
+   {
+      createObserverMethods(declaringBean, realizingClass.getSuperclass());
+   }
+   
+   private void createObserverMethod(AbstractClassBean<?> declaringBean, AnnotatedMethod<?> method)
+   {
+      ObserverImpl<?> observer = ObserverFactory.create(method, declaringBean, manager);
+      beanDeployerEnvironment.getObservers().add(observer);
+   }
+   
+   private <T> void createSimpleBean(AnnotatedClass<T> annotatedClass)
+   {
+      SimpleBean<T> bean = SimpleBean.of(annotatedClass, manager);
+      createBean(bean, annotatedClass);
+      addBean(NewSimpleBean.of(annotatedClass, manager));
+   }
+   
+   private <T> void createEnterpriseBean(AnnotatedClass<T> annotatedClass)
+   {
+      // TODO Don't create enterprise bean if it has no local interfaces!
+      EnterpriseBean<T> bean = EnterpriseBean.of(annotatedClass, manager);
+      createBean(bean, annotatedClass);
+      addBean(NewEnterpriseBean.of(annotatedClass, manager));
+   }
+   
+   /**
+    * Indicates if the type is a simple Web Bean
+    * 
+    * @param type
+    *           The type to inspect
+    * @return True if simple Web Bean, false otherwise
+    */
+   private boolean isTypeSimpleWebBean(AnnotatedClass<?> clazz)
+   {
+      Class<?> rawType = clazz.getRawType();
+      EJBApiAbstraction ejbApiAbstraction = manager.getServices().get(EJBApiAbstraction.class);
+      JSFApiAbstraction jsfApiAbstraction = manager.getServices().get(JSFApiAbstraction.class);
+      ServletApiAbstraction servletApiAbstraction = manager.getServices().get(ServletApiAbstraction.class);
+      // TODO: check 3.2.1 for more rules!!!!!!
+      return !Reflections.isAbstract(rawType) && 
+             !Reflections.isParameterizedType(rawType) && 
+             !servletApiAbstraction.SERVLET_CLASS.isAssignableFrom(rawType) && 
+             !servletApiAbstraction.FILTER_CLASS.isAssignableFrom(rawType) && 
+             !servletApiAbstraction.SERVLET_CONTEXT_LISTENER_CLASS.isAssignableFrom(rawType) && 
+             !servletApiAbstraction.HTTP_SESSION_LISTENER_CLASS.isAssignableFrom(rawType) && 
+             !servletApiAbstraction.SERVLET_REQUEST_LISTENER_CLASS.isAssignableFrom(rawType) && 
+             !ejbApiAbstraction.ENTERPRISE_BEAN_CLASS.isAssignableFrom(rawType) && 
+             !jsfApiAbstraction.UICOMPONENT_CLASS.isAssignableFrom(rawType) && 
+             hasSimpleWebBeanConstructor(clazz)
+             && (manager.getServices().contains(JpaServices.class) ? !manager.getServices().get(JpaServices.class).discoverEntities().contains(clazz.getRawType()) : true);
+   }
+   
+   private static boolean hasSimpleWebBeanConstructor(AnnotatedClass<?> type)
+   {
+      return type.getNoArgsConstructor() != null || type.getAnnotatedConstructors(Initializer.class).size() > 0;
+   }
+   
+   private static <T> AnnotatedMethod<T> realizeProducerMethod(final AnnotatedMethod<T> method, final AnnotatedClass<?> realizingClass)
+   {
+      return new WrappedAnnotatedMethod<T>(method, realizingClass.getMetaAnnotations(BindingType.class))
+      {
+         
+         @Override
+         public Set<Annotation> getMetaAnnotations(Class<? extends Annotation> metaAnnotationType)
+         {
+            if (metaAnnotationType.equals(DeploymentType.class))
+            {
+               return realizingClass.getMetaAnnotations(DeploymentType.class);
+            }
+            else
+            {
+               return super.getMetaAnnotations(metaAnnotationType);
+            }
+         }
+         
+         @Override
+         public Set<Annotation> getDeclaredMetaAnnotations(Class<? extends Annotation> metaAnnotationType)
+         {
+            if (metaAnnotationType.equals(DeploymentType.class))
+            {
+               return realizingClass.getDeclaredMetaAnnotations(DeploymentType.class);
+            }
+            else
+            {
+               return super.getDeclaredMetaAnnotations(metaAnnotationType);
+            }
+         }
+         
+      };
+   }
+   
+   private static <T> AnnotatedField<T> realizeProducerField(final AnnotatedField<T> field, final AnnotatedClass<?> realizingClass)
+   {
+      return new WrappedAnnotatedField<T>(field, realizingClass.getMetaAnnotations(BindingType.class))
+      {
+         
+         @Override
+         public Set<Annotation> getMetaAnnotations(Class<? extends Annotation> metaAnnotationType)
+         {
+            if (metaAnnotationType.equals(DeploymentType.class))
+            {
+               return realizingClass.getMetaAnnotations(DeploymentType.class);
+            }
+            else
+            {
+               return super.getMetaAnnotations(metaAnnotationType);
+            }
+         }
+         
+         @Override
+         public Set<Annotation> getDeclaredMetaAnnotations(Class<? extends Annotation> metaAnnotationType)
+         {
+            if (metaAnnotationType.equals(DeploymentType.class))
+            {
+               return realizingClass.getDeclaredMetaAnnotations(DeploymentType.class);
+            }
+            else
+            {
+               return super.getDeclaredMetaAnnotations(metaAnnotationType);
+            }
+         }
+         
+      };
+   }
+   
+}

Modified: ri/trunk/impl/src/main/java/org/jboss/webbeans/bootstrap/BeanDeployerEnvironment.java
===================================================================
--- ri/trunk/impl/src/main/java/org/jboss/webbeans/bootstrap/BeanDeployerEnvironment.java	2009-03-31 03:54:17 UTC (rev 2278)
+++ ri/trunk/impl/src/main/java/org/jboss/webbeans/bootstrap/BeanDeployerEnvironment.java	2009-03-31 07:38:18 UTC (rev 2279)
@@ -1,99 +1,117 @@
-package org.jboss.webbeans.bootstrap;
-
-import java.lang.annotation.Annotation;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.jboss.webbeans.bean.AbstractClassBean;
-import org.jboss.webbeans.bean.NewBean;
-import org.jboss.webbeans.bean.ProducerMethodBean;
-import org.jboss.webbeans.bean.RIBean;
-import org.jboss.webbeans.event.ObserverImpl;
-import org.jboss.webbeans.injection.resolution.ResolvableAnnotatedClass;
-import org.jboss.webbeans.introspector.AnnotatedClass;
-import org.jboss.webbeans.introspector.AnnotatedItem;
-import org.jboss.webbeans.introspector.AnnotatedMethod;
-
-public class BeanDeployerEnvironment
-{
-   
-   private static final AnnotatedItem<?, ?> OTHER_BEANS_ANNOTATED_ITEM = ResolvableAnnotatedClass.of(BeanDeployerEnvironment.class, new Annotation[0]);
-   
-   private final Map<AnnotatedClass<?>, AbstractClassBean<?>> classBeanMap;
-   private final Map<AnnotatedMethod<?>, ProducerMethodBean<?>> methodBeanMap; 
-   private final Set<RIBean<?>> beans;
-   private final Set<ObserverImpl<?>> observers;
-   private final Set<AnnotatedMethod<?>> disposalMethods; 
-    
-   public BeanDeployerEnvironment()
-   {
-      this.classBeanMap = new HashMap<AnnotatedClass<?>, AbstractClassBean<?>>();
-      this.methodBeanMap = new HashMap<AnnotatedMethod<?>, ProducerMethodBean<?>>();
-      this.disposalMethods = new HashSet<AnnotatedMethod<?>>();
-      this.beans = new HashSet<RIBean<?>>();
-      this.observers = new HashSet<ObserverImpl<?>>();
-   }
-   
-   public ProducerMethodBean<?> getProducerMethod(AnnotatedMethod<?> method)
-   {
-      if (!methodBeanMap.containsKey(method))
-      {
-         return null;
-      }
-      else
-      {
-         ProducerMethodBean<?> bean = methodBeanMap.get(method);
-         bean.initialize(this);
-         return bean;
-      }
-   }
-   
-   public AbstractClassBean<?> getClassBean(AnnotatedClass<?> clazz)
-   {
-      if (!classBeanMap.containsKey(clazz))
-      {
-         return null;
-      }
-      else
-      {
-         AbstractClassBean<?> bean = classBeanMap.get(clazz);
-         bean.initialize(this);
-         return bean;
-      }
-   }
-   
-   public void addBean(RIBean<?> value)
-   {
-      
-      if (value instanceof AbstractClassBean && !(value instanceof NewBean))
-      {
-         AbstractClassBean<?> bean = (AbstractClassBean<?>) value;
-         classBeanMap.put(bean.getAnnotatedItem(), bean);
-      }
-      else if (value instanceof ProducerMethodBean)
-      {
-         ProducerMethodBean<?> bean = (ProducerMethodBean<?>) value;
-         methodBeanMap.put(bean.getAnnotatedItem(), bean);
-      }
-      beans.add(value);
-   }
-   
-   public Set<RIBean<?>> getBeans()
-   {
-      return Collections.unmodifiableSet(beans);
-   }
-   
-   public Set<ObserverImpl<?>> getObservers()
-   {
-      return observers;
-   }
-   
-   public Set<AnnotatedMethod<?>> getDisposalMethods()
-   {
-      return disposalMethods;
-   }
-   
-}
+package org.jboss.webbeans.bootstrap;
+
+import java.lang.annotation.Annotation;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.jboss.webbeans.bean.AbstractClassBean;
+import org.jboss.webbeans.bean.DisposalMethodBean;
+import org.jboss.webbeans.bean.NewBean;
+import org.jboss.webbeans.bean.ProducerMethodBean;
+import org.jboss.webbeans.bean.RIBean;
+import org.jboss.webbeans.event.ObserverImpl;
+import org.jboss.webbeans.injection.resolution.ResolvableAnnotatedClass;
+import org.jboss.webbeans.introspector.AnnotatedClass;
+import org.jboss.webbeans.introspector.AnnotatedItem;
+import org.jboss.webbeans.introspector.AnnotatedMethod;
+
+public class BeanDeployerEnvironment
+{
+
+   private static final AnnotatedItem<?, ?> OTHER_BEANS_ANNOTATED_ITEM = ResolvableAnnotatedClass.of(BeanDeployerEnvironment.class, new Annotation[0]);
+
+   private final Map<AnnotatedClass<?>, AbstractClassBean<?>> classBeanMap;
+   private final Map<AnnotatedMethod<?>, ProducerMethodBean<?>> methodBeanMap;
+   private final Set<RIBean<?>> beans;
+   private final Set<ObserverImpl<?>> observers;
+   private final Set<DisposalMethodBean<?>> allDisposalBeans;
+   private final Set<DisposalMethodBean<?>> resolvedDisposalBeans;
+
+   public BeanDeployerEnvironment()
+   {
+      this.classBeanMap = new HashMap<AnnotatedClass<?>, AbstractClassBean<?>>();
+      this.methodBeanMap = new HashMap<AnnotatedMethod<?>, ProducerMethodBean<?>>();
+      this.allDisposalBeans = new HashSet<DisposalMethodBean<?>>();
+      this.resolvedDisposalBeans = new HashSet<DisposalMethodBean<?>>();
+      this.beans = new HashSet<RIBean<?>>();
+      this.observers = new HashSet<ObserverImpl<?>>();
+   }
+
+   public ProducerMethodBean<?> getProducerMethod(AnnotatedMethod<?> method)
+   {
+      if (!methodBeanMap.containsKey(method))
+      {
+         return null;
+      }
+      else
+      {
+         ProducerMethodBean<?> bean = methodBeanMap.get(method);
+         bean.initialize(this);
+         return bean;
+      }
+   }
+
+   public AbstractClassBean<?> getClassBean(AnnotatedClass<?> clazz)
+   {
+      if (!classBeanMap.containsKey(clazz))
+      {
+         return null;
+      }
+      else
+      {
+         AbstractClassBean<?> bean = classBeanMap.get(clazz);
+         bean.initialize(this);
+         return bean;
+      }
+   }
+
+   public void addBean(RIBean<?> value)
+   {
+
+      if (value instanceof AbstractClassBean && !(value instanceof NewBean))
+      {
+         AbstractClassBean<?> bean = (AbstractClassBean<?>) value;
+         classBeanMap.put(bean.getAnnotatedItem(), bean);
+      }
+      else if (value instanceof ProducerMethodBean)
+      {
+         ProducerMethodBean<?> bean = (ProducerMethodBean<?>) value;
+         methodBeanMap.put(bean.getAnnotatedItem(), bean);
+      }
+      beans.add(value);
+   }
+
+   public Set<RIBean<?>> getBeans()
+   {
+      return Collections.unmodifiableSet(beans);
+   }
+
+   public Set<ObserverImpl<?>> getObservers()
+   {
+      return observers;
+   }
+
+   public Set<DisposalMethodBean<?>> getAllDisposalBeans()
+   {
+      return allDisposalBeans;
+   }
+
+   public void addAllDisposalBean(DisposalMethodBean<?> disposalBean)
+   {
+      allDisposalBeans.add(disposalBean);
+   }
+
+   public void addResolvedDisposalBean(DisposalMethodBean<?> disposalBean)
+   {
+      resolvedDisposalBeans.add(disposalBean);
+   }
+
+   public Set<DisposalMethodBean<?>> getResolvedDisposalBeans()
+   {
+      return resolvedDisposalBeans;
+   }
+
+}

Modified: ri/trunk/tests/src/test/java/org/jboss/webbeans/test/unit/implementation/NewEnterpriseBeanTest.java
===================================================================
--- ri/trunk/tests/src/test/java/org/jboss/webbeans/test/unit/implementation/NewEnterpriseBeanTest.java	2009-03-31 03:54:17 UTC (rev 2278)
+++ ri/trunk/tests/src/test/java/org/jboss/webbeans/test/unit/implementation/NewEnterpriseBeanTest.java	2009-03-31 07:38:18 UTC (rev 2279)
@@ -74,7 +74,7 @@
    {
       initNewBean();
       Class<?> type = TypeInfo.ofTypes(newEnterpriseBean.getTypes()).getSuperClass();
-      assert manager.resolveDisposalMethods(type, newEnterpriseBean.getBindings().toArray(new Annotation[0])).isEmpty();
+      assert manager.resolveDisposalBeans(type, newEnterpriseBean.getBindings().toArray(new Annotation[0])).isEmpty();
    }   
    
 }




More information about the weld-commits mailing list