You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2012/12/04 22:07:51 UTC

svn commit: r1417182 [21/22] - in /openejb/trunk/openejb: container/openejb-core/ deps/ deps/webbeans-impl/ deps/webbeans-impl/src/ deps/webbeans-impl/src/main/ deps/webbeans-impl/src/main/java/ deps/webbeans-impl/src/main/java/org/ deps/webbeans-impl/...

Added: openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java?rev=1417182&view=auto
==============================================================================
--- openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java (added)
+++ openejb/trunk/openejb/deps/webbeans-impl/src/main/java/org/apache/webbeans/util/WebBeansUtil.java Tue Dec  4 21:07:25 2012
@@ -0,0 +1,3180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.webbeans.util;
+
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.decorator.Decorator;
+import javax.enterprise.context.Conversation;
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.NormalScope;
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.event.Event;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.Alternative;
+import javax.enterprise.inject.Disposes;
+import javax.enterprise.inject.IllegalProductException;
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.Produces;
+import javax.enterprise.inject.Specializes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedParameter;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.BeforeShutdown;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.InjectionTarget;
+import javax.enterprise.inject.spi.Interceptor;
+import javax.enterprise.inject.spi.ObserverMethod;
+import javax.enterprise.inject.spi.PassivationCapable;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+import javax.enterprise.inject.spi.ProcessBean;
+import javax.enterprise.inject.spi.ProcessInjectionTarget;
+import javax.enterprise.inject.spi.ProcessManagedBean;
+import javax.enterprise.inject.spi.ProcessObserverMethod;
+import javax.enterprise.inject.spi.ProcessProducer;
+import javax.enterprise.inject.spi.ProcessProducerField;
+import javax.enterprise.inject.spi.ProcessProducerMethod;
+import javax.enterprise.inject.spi.ProcessSessionBean;
+import javax.enterprise.util.TypeLiteral;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Provider;
+import javax.inject.Scope;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.AroundTimeout;
+import javax.interceptor.InvocationContext;
+
+import org.apache.webbeans.annotation.AnnotationManager;
+import org.apache.webbeans.annotation.AnyLiteral;
+import org.apache.webbeans.annotation.ApplicationScopeLiteral;
+import org.apache.webbeans.annotation.DefaultLiteral;
+import org.apache.webbeans.annotation.DependentScopeLiteral;
+import org.apache.webbeans.annotation.NewLiteral;
+import org.apache.webbeans.annotation.RequestedScopeLiteral;
+import org.apache.webbeans.component.AbstractInjectionTargetBean;
+import org.apache.webbeans.component.AbstractOwbBean;
+import org.apache.webbeans.component.AbstractProducerBean;
+import org.apache.webbeans.component.BeanManagerBean;
+import org.apache.webbeans.component.ConversationBean;
+import org.apache.webbeans.component.EnterpriseBeanMarker;
+import org.apache.webbeans.component.EventBean;
+import org.apache.webbeans.component.ExtensionBean;
+import org.apache.webbeans.component.InjectionPointBean;
+import org.apache.webbeans.component.InjectionTargetBean;
+import org.apache.webbeans.component.InjectionTargetWrapper;
+import org.apache.webbeans.component.InstanceBean;
+import org.apache.webbeans.component.ManagedBean;
+import org.apache.webbeans.component.NewBean;
+import org.apache.webbeans.component.NewManagedBean;
+import org.apache.webbeans.component.OwbBean;
+import org.apache.webbeans.component.ProducerFieldBean;
+import org.apache.webbeans.component.ProducerMethodBean;
+import org.apache.webbeans.component.ResourceBean;
+import org.apache.webbeans.component.WebBeansType;
+import org.apache.webbeans.component.creation.AnnotatedTypeBeanCreatorImpl;
+import org.apache.webbeans.component.creation.ManagedBeanCreatorImpl;
+import org.apache.webbeans.config.DefinitionUtil;
+import org.apache.webbeans.config.EJBWebBeansConfigurator;
+import org.apache.webbeans.config.OWBLogConst;
+import org.apache.webbeans.config.OpenWebBeansConfiguration;
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.container.BeanManagerImpl;
+import org.apache.webbeans.container.ExternalScope;
+import org.apache.webbeans.container.InjectionResolver;
+import org.apache.webbeans.conversation.ConversationImpl;
+import org.apache.webbeans.decorator.DecoratorUtil;
+import org.apache.webbeans.decorator.WebBeansDecoratorConfig;
+import org.apache.webbeans.event.ObserverMethodImpl;
+import org.apache.webbeans.exception.WebBeansConfigurationException;
+import org.apache.webbeans.exception.helper.ViolationMessageBuilder;
+import org.apache.webbeans.exception.inject.DefinitionException;
+import org.apache.webbeans.exception.inject.DeploymentException;
+import org.apache.webbeans.exception.inject.InconsistentSpecializationException;
+import org.apache.webbeans.inject.AlternativesManager;
+import org.apache.webbeans.intercept.InterceptorData;
+import org.apache.webbeans.intercept.InterceptorDataImpl;
+import javax.enterprise.inject.spi.InterceptionType;
+import org.apache.webbeans.logger.WebBeansLoggerFacade;
+import org.apache.webbeans.plugins.OpenWebBeansEjbLCAPlugin;
+import org.apache.webbeans.plugins.PluginLoader;
+import org.apache.webbeans.portable.creation.InjectionTargetProducer;
+import org.apache.webbeans.portable.creation.ProducerBeansProducer;
+import org.apache.webbeans.portable.events.ProcessBeanImpl;
+import org.apache.webbeans.portable.events.ProcessProducerImpl;
+import org.apache.webbeans.portable.events.discovery.ErrorStack;
+import org.apache.webbeans.portable.events.generics.GProcessAnnotatedType;
+import org.apache.webbeans.portable.events.generics.GProcessBean;
+import org.apache.webbeans.portable.events.generics.GProcessInjectionTarget;
+import org.apache.webbeans.portable.events.generics.GProcessManagedBean;
+import org.apache.webbeans.portable.events.generics.GProcessObservableMethod;
+import org.apache.webbeans.portable.events.generics.GProcessProducer;
+import org.apache.webbeans.portable.events.generics.GProcessProducerField;
+import org.apache.webbeans.portable.events.generics.GProcessProducerMethod;
+import org.apache.webbeans.portable.events.generics.GProcessSessionBean;
+import org.apache.webbeans.spi.plugins.OpenWebBeansEjbPlugin;
+import org.apache.webbeans.spi.plugins.OpenWebBeansPlugin;
+
+
+import static org.apache.webbeans.util.InjectionExceptionUtils.throwUnproxyableResolutionException;
+
+/**
+ * Contains some utility methods used in the all project.
+ *
+ * @version $Rev: 1410305 $ $Date: 2012-11-16 12:10:00 +0100 (ven., 16 nov. 2012) $
+ */
+@SuppressWarnings("unchecked")
+public final class WebBeansUtil
+{
+    /**
+     * Enforcing that interceptor callbacks should not be
+     * able to throw checked exceptions is configurable
+     */
+    private static volatile Boolean enforceCheckedException;
+
+    private final static Class<Instance<?>> INSTANCE_TYPE
+            = new TypeLiteral<Instance<?>>()
+    {
+        private static final long serialVersionUID = 3555319035805031154L;
+    }.getRawType();
+
+    private final static Class<Provider<?>> PROVIDER_TYPE
+            = new TypeLiteral<Provider<?>>()
+    {
+        private static final long serialVersionUID = -2611190564495920054L;
+    }.getRawType();
+
+    private final static Class<Event<?>>    EVENT_TYPE
+            = new TypeLiteral<Event<?>>()
+    {
+        private static final long serialVersionUID = -1395145871249763477L;
+    }.getRawType();
+
+    private final WebBeansContext webBeansContext;
+
+    public WebBeansUtil(WebBeansContext webBeansContext)
+    {
+        this.webBeansContext = webBeansContext;
+    }
+
+    /**
+     * Lifycycle methods like {@link javax.annotation.PostConstruct} and
+     * {@link javax.annotation.PreDestroy} must not define a checked Exception
+     * regarding to the spec. But this is often unnecessary restrictive so we
+     * allow to disable this check application wide.
+     *
+     * @return <code>true</code> if the spec rule of having no checked exception should be enforced
+     */
+    private boolean isNoCheckedExceptionEnforced()
+    {
+        if (enforceCheckedException == null)
+        {
+            enforceCheckedException = Boolean.parseBoolean(webBeansContext.getOpenWebBeansConfiguration().
+                    getProperty(OpenWebBeansConfiguration.INTERCEPTOR_FORCE_NO_CHECKED_EXCEPTIONS, "true"));
+        }
+
+        return enforceCheckedException.booleanValue();
+    }
+
+    /**
+     * Gets current classloader with current thread.
+     *
+     * @return Current class loader instance
+     */
+    public static ClassLoader getCurrentClassLoader()
+    {
+        ClassLoader loader =  Thread.currentThread().getContextClassLoader();
+
+        if (loader == null)
+        {
+            loader = WebBeansUtil.class.getClassLoader();
+        }
+
+        return loader;
+    }
+
+    /**
+     * Checks the generic type requirements.
+     *
+     * @param bean managed bean instance
+     */
+    public static void checkGenericType(Bean<?> bean)
+    {
+        Asserts.assertNotNull(bean);
+
+        Class<?> clazz = bean.getBeanClass();
+
+        if (ClassUtil.isDefinitionContainsTypeVariables(clazz))
+        {
+            if(!bean.getScope().equals(Dependent.class))
+            {
+                throw new WebBeansConfigurationException("Generic type may only defined with scope @Dependent " +
+                        "for ManagedBean class : " + clazz.getName());
+            }
+        }
+    }
+
+
+    /**
+     * Check producer method/field bean return type.
+     * @param bean producer bean instance
+     * @param member related member instance
+     */
+    public static void checkProducerGenericType(Bean<?> bean,Member member)
+    {
+        Asserts.assertNotNull(bean,"Bean is null");
+
+        Type type = null;
+
+        if(bean instanceof ProducerMethodBean)
+        {
+            type = ((ProducerMethodBean<?>)bean).getCreatorMethod().getGenericReturnType();
+        }
+        else if(bean instanceof ProducerFieldBean)
+        {
+            type = ((ProducerFieldBean<?>)bean).getCreatorField().getGenericType();
+        }
+        else
+        {
+            throw new IllegalArgumentException("Bean must be Producer Field or Method Bean instance : " + bean);
+        }
+
+        String messageTemplate = "Producer Field/Method Bean with name : %s" + 
+                         " in bean class : %s"; 
+
+        String memberName = member.getName();
+        String declaringClassName = member.getDeclaringClass().getName();
+        if(checkGenericForProducers(type, messageTemplate, memberName, declaringClassName))
+        {
+            if(!bean.getScope().equals(Dependent.class))
+            {
+                String message = format(messageTemplate, memberName, declaringClassName);
+                throw new WebBeansConfigurationException(message + " scope must bee @Dependent");
+            }
+        }
+    }
+
+    /**
+     * Check generic types for producer method and fields.
+     * @param type generic return type
+     * @param messageTemplate error message
+     * @return true if parametrized type argument is TypeVariable
+     */
+    //Helper method
+    private static boolean checkGenericForProducers(Type type, String messageTemplate, Object... errorMessageArgs)
+    {
+        boolean result = false;
+
+        if(type instanceof TypeVariable)
+        {
+            String message = format(messageTemplate, errorMessageArgs);
+            throw new WebBeansConfigurationException(message + " return type can not be type variable");
+        }
+
+        if(ClassUtil.isParametrizedType(type))
+        {
+            Type[] actualTypes = ClassUtil.getActualTypeArguments(type);
+
+            if(actualTypes.length == 0)
+            {
+                String message = format(messageTemplate, errorMessageArgs);
+                throw new WebBeansConfigurationException(message +
+                        " return type must define actual type arguments or type variable");
+            }
+
+            for(Type actualType : actualTypes)
+            {
+                if(ClassUtil.isWildCardType(actualType))
+                {
+                    String message = format(messageTemplate, errorMessageArgs);
+                    throw new WebBeansConfigurationException(message +
+                            " return type can not define wildcard actual type argument");
+                }
+
+                if(ClassUtil.isTypeVariable(actualType))
+                {
+                    result = true;
+                }
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Return <code>true</code> if the given class is ok for manage bean conditions,
+     * <code>false</code> otherwise.
+     *
+     * @param clazz class in hand
+     * @return <code>true</code> if the given class is ok for simple web bean conditions.
+     */
+    public void isManagedBeanClass(Class<?> clazz)
+    {
+        Asserts.nullCheckForClass(clazz, "Class is null");
+
+        int modifier = clazz.getModifiers();
+
+        if (!Modifier.isStatic(modifier) && ClassUtil.isInnerClazz(clazz))
+        {
+            throw new WebBeansConfigurationException("Bean implementation class : "
+                                                     + clazz.getName() + " can not be non-static inner class");
+        }
+
+        if (!ClassUtil.isConcrete(clazz) && !AnnotationUtil.hasClassAnnotation(clazz, Decorator.class))
+        {
+            throw new WebBeansConfigurationException("Bean implementation class : " + clazz.getName()
+                                                     + " have to be concrete if not defines as @Decorator");
+        }
+
+        if (!isConstructureOk(clazz))
+        {
+            throw new WebBeansConfigurationException("Bean implementation class : " + clazz.getName()
+                                                     + " must define at least one Constructor");
+        }
+
+        if(Extension.class.isAssignableFrom(clazz))
+        {
+            throw new WebBeansConfigurationException("Bean implementation class can not implement "
+                                                     + "javax.enterprise.inject.spi.Extension.!");
+        }
+
+        Class<?>[] interfaces = clazz.getInterfaces();
+        if(interfaces != null && interfaces.length > 0)
+        {
+            for(Class<?> intr : interfaces)
+            {
+                if(intr.getName().equals("javax.ejb.EnterpriseBean"))
+                {
+                    throw new WebBeansConfigurationException("Bean implementation class can not implement "
+                                                             + "javax.ejb.EnterpriseBean");
+                }
+            }
+        }
+
+        // and finally call all checks which are defined in plugins like JSF, JPA, etc
+        List<OpenWebBeansPlugin> plugins = webBeansContext.getPluginLoader().getPlugins();
+        for (OpenWebBeansPlugin plugin : plugins)
+        {
+            try
+            {
+                plugin.isManagedBean(clazz);
+            }
+            catch (Exception e)
+            {
+                PluginLoader.throwsException(e);
+            }
+        }
+    }
+
+    /**
+     * Returns true if given class supports injections,
+     * false otherwise.
+     * <p>
+     * Each plugin is asked with given class that supports
+     * injections or not.
+     * </p>
+     * @param clazz scanned class
+     * @return  true if given class supports injections
+     */
+    public boolean supportsJavaEeComponentInjections(Class<?> clazz)
+    {
+        if (clazz.isInterface() || clazz.isAnnotation() || clazz.isEnum())
+        {
+            // interfaces, annotations and enums are no subject of injection
+            return false;
+        }
+
+        // and finally call all checks which are defined in plugins like JSF, JPA, etc
+        List<OpenWebBeansPlugin> plugins = webBeansContext.getPluginLoader().getPlugins();
+        for (OpenWebBeansPlugin plugin : plugins)
+        {
+            //Ejb plugin handles its own events
+            //Also EJb beans supports injections
+            if(!(plugin instanceof OpenWebBeansEjbPlugin))
+            {
+                if(plugin.supportsJavaEeComponentInjections(clazz))
+                {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Defines applicable constructor.
+     * @param <T> type info
+     * @param clazz class type
+     * @return constructor
+     * @throws WebBeansConfigurationException any configuration exception
+     */
+    public <T> Constructor<T> defineConstructor(Class<T> clazz) throws WebBeansConfigurationException
+    {
+        Asserts.nullCheckForClass(clazz);
+        Constructor<?>[] constructors = webBeansContext.getSecurityService().doPrivilegedGetDeclaredConstructors(clazz);
+
+        return defineConstructor(constructors, clazz);
+
+    }
+
+
+    public <T> Constructor<T> defineConstructor(Constructor<?>[] constructors, Class<T> clazz)
+    {
+        Constructor<T> result = null;
+
+        boolean inAnnotation = false;
+
+        /* Check for @Initializer */
+        for (Constructor<?> constructor : constructors)
+        {
+            if (constructor.getAnnotation(Inject.class) != null)
+            {
+                if (inAnnotation)// duplicate @In
+                {
+                    throw new WebBeansConfigurationException("There are more than one Constructor with "
+                                                             + "Initializer annotation in class " + clazz.getName());
+                }
+                inAnnotation = true;
+                result = (Constructor<T>) constructor;
+            }
+        }
+
+        if (result == null)
+        {
+            result = getNoArgConstructor(clazz);
+
+            if(result == null)
+            {
+                throw new WebBeansConfigurationException("No constructor is found for the class : " + clazz.getName());
+            }
+        }
+
+
+        Annotation[][] parameterAnns = result.getParameterAnnotations();
+        for (Annotation[] parameters : parameterAnns)
+        {
+            for (Annotation param : parameters)
+            {
+                if (param.annotationType().equals(Disposes.class))
+                {
+                    throw new WebBeansConfigurationException("Constructor parameter annotations can not contain " +
+                            "@Disposes annotation in class : " + clazz.getName());
+                }
+
+                if(param.annotationType().equals(Observes.class))
+                {
+                    throw new WebBeansConfigurationException("Constructor parameter annotations can not contain " +
+                            "@Observes annotation in class : " + clazz.getName());
+                }
+            }
+
+        }
+
+        return result;
+
+    }
+
+    /**
+     * Check that simple web beans class has compatible constructor.
+     * @param clazz web beans simple class
+     * @throws WebBeansConfigurationException if the web beans has incompatible
+     *             constructor
+     */
+    public boolean isConstructureOk(Class<?> clazz) throws WebBeansConfigurationException
+    {
+        Asserts.nullCheckForClass(clazz);
+
+        if (getNoArgConstructor(clazz) != null)
+        {
+            return true;
+        }
+
+        Constructor<?>[] constructors = webBeansContext.getSecurityService().doPrivilegedGetDeclaredConstructors(clazz);
+
+        for (Constructor<?> constructor : constructors)
+        {
+            if (constructor.getAnnotation(Inject.class) != null)
+            {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Check producer method is ok for deployment.
+     *
+     * @param method producer method
+     * @param parentImplClazzName parent class name
+     */
+    public static void checkProducerMethodForDeployment(Method method, String parentImplClazzName)
+    {
+        Asserts.assertNotNull(method, "Method argument can not be null");
+
+        if (AnnotationUtil.hasMethodAnnotation(method, Inject.class) ||
+            AnnotationUtil.hasMethodParameterAnnotation(method, Disposes.class) ||
+            AnnotationUtil.hasMethodParameterAnnotation(method, Observes.class))
+        {
+            throw new WebBeansConfigurationException("Producer Method Bean with name : " + method.getName()
+                                                     + " in bean class : " + parentImplClazzName
+                                                     + " can not be annotated with @Initializer/@Destructor annotation "
+                                                     + "or has a parameter annotated with @Disposes/@Observes");
+        }
+    }
+
+    /**
+     * CheckProducerMethodDisposal.
+     * @param disposalMethod disposal method
+     * @param definedBeanClassName bean class name
+     */
+    public static void checkProducerMethodDisposal(Method disposalMethod, String definedBeanClassName)
+    {
+        if (AnnotationUtil.hasMethodMultipleParameterAnnotation(disposalMethod, Disposes.class))
+        {
+            throw new WebBeansConfigurationException("Disposal method : " + disposalMethod.getName() + " in class "
+                                                     + definedBeanClassName
+                                                     + " has multiple @Disposes annotation parameter");
+        }
+
+        if (AnnotationUtil.hasMethodAnnotation(disposalMethod, Inject.class) ||
+            AnnotationUtil.hasMethodParameterAnnotation(disposalMethod, Observes.class) ||
+            AnnotationUtil.hasMethodAnnotation(disposalMethod, Produces.class))
+        {
+            throw new WebBeansConfigurationException("Disposal method : " + disposalMethod.getName()
+                                                     + " in the class : " + definedBeanClassName
+                                                     + " can not be annotated with @Initializer/@Destructor/@Produces "
+                                                     + "annotation or has a parameter annotated with @Observes");
+        }
+
+    }
+
+    /**
+     * New WebBeans component class.
+     *
+     * @param <T>
+     * @param clazz impl. class
+     * @return the new component
+     */
+    public <T> NewManagedBean<T> createNewComponent(Class<T> clazz, Type apiType)
+    {
+        Asserts.nullCheckForClass(clazz);
+
+        NewManagedBean<T> comp;
+        DefinitionUtil definitionUtil = webBeansContext.getDefinitionUtil();
+
+
+        if (webBeansContext.getManagedBeanConfigurator().isManagedBean(clazz))
+        {
+            comp = new NewManagedBean<T>(clazz, WebBeansType.MANAGED, webBeansContext);
+            comp.setImplScopeType(new DependentScopeLiteral());
+            comp.setConstructor(defineConstructor(clazz));
+            definitionUtil.addConstructorInjectionPointMetaData(comp, comp.getConstructor());
+
+            definitionUtil.defineInjectedFields(comp);
+            definitionUtil.defineInjectedMethods(comp);
+        }
+        else if (EJBWebBeansConfigurator.isSessionBean(clazz, webBeansContext))
+        {
+            comp = new NewManagedBean<T>(clazz, WebBeansType.ENTERPRISE, webBeansContext);
+            comp.setImplScopeType(new DependentScopeLiteral());
+        }
+        else
+        {
+            throw new WebBeansConfigurationException("@New annotation on type : " + clazz.getName()
+                                                     + " must defined as a simple or an enterprise web bean");
+        }
+
+        comp.addQualifier(new NewLiteral(clazz));
+        comp.setName(null);
+        if(apiType == null)
+        {
+            comp.addApiType(clazz);
+        }
+        else
+        {
+            comp.getTypes().add(apiType);
+        }
+
+        comp.addApiType(Object.class);
+
+        return comp;
+    }
+
+    /**
+     * Creates a new extension bean.
+     *
+     * @param <T> extension service class
+     * @param clazz impl. class
+     * @return a new extension service bean
+     */
+    public <T> ExtensionBean<T> createExtensionComponent(Class<T> clazz)
+    {
+        Asserts.nullCheckForClass(clazz);
+
+        ExtensionBean<T> comp = null;
+        comp = new ExtensionBean<T>(clazz, webBeansContext);
+        comp.setEnabled(true);
+
+        DefinitionUtil definitionUtil = webBeansContext.getDefinitionUtil();
+        definitionUtil.defineApiTypes(comp, clazz);
+
+        comp.setImplScopeType(new ApplicationScopeLiteral());
+        comp.addQualifier(new DefaultLiteral());
+
+        definitionUtil.defineObserverMethods(comp, clazz);
+
+        return comp;
+    }
+
+
+    /**
+     * Creates a new manager bean instance.
+     * @return new manager bean instance
+     */
+    public BeanManagerBean getManagerBean()
+    {
+        BeanManagerBean managerComponent = new BeanManagerBean(webBeansContext);
+
+        managerComponent.setImplScopeType(new DependentScopeLiteral());
+        managerComponent.addQualifier(new DefaultLiteral());
+        managerComponent.addQualifier(new AnyLiteral());
+        managerComponent.addApiType(BeanManager.class);
+        managerComponent.addApiType(Object.class);
+
+        return managerComponent;
+    }
+
+    /**
+     * Creates a new instance bean.
+     * @return new instance bean
+     */
+    @SuppressWarnings("serial")
+    public <T> InstanceBean<T> getInstanceBean()
+    {
+        InstanceBean<T> instanceBean = new InstanceBean<T>(webBeansContext);
+
+        instanceBean.getTypes().add(INSTANCE_TYPE);
+        instanceBean.getTypes().add(PROVIDER_TYPE);
+        instanceBean.addApiType(Object.class);
+
+        instanceBean.addQualifier(new AnyLiteral());
+        instanceBean.setImplScopeType(new DependentScopeLiteral());
+        instanceBean.setName(null);
+
+        return instanceBean;
+    }
+
+    /**
+     * Creates a new event bean.
+     * @return new event bean
+     */
+    @SuppressWarnings("serial")
+    public <T> EventBean<T> getEventBean()
+    {
+        EventBean<T> eventBean = new EventBean<T>(webBeansContext);
+
+        eventBean.getTypes().add(EVENT_TYPE);
+        eventBean.addApiType(Object.class);
+
+        eventBean.addQualifier(new AnyLiteral());
+        eventBean.setImplScopeType(new DependentScopeLiteral());
+        eventBean.setName(null);
+
+        return eventBean;
+    }
+
+
+    /**
+     * Returns new conversation bean instance.
+     * The name is explicitly specified in 6.7.2 and is not the normal default name.
+     * @return new conversation bean
+     */
+    public ConversationBean getConversationBean()
+    {
+        ConversationBean conversationComp = new ConversationBean(webBeansContext);
+
+        conversationComp.addApiType(Conversation.class);
+        conversationComp.addApiType(ConversationImpl.class);
+        conversationComp.addApiType(Object.class);
+        conversationComp.setImplScopeType(new RequestedScopeLiteral());
+        conversationComp.addQualifier(new DefaultLiteral());
+        conversationComp.addQualifier(new AnyLiteral());
+        conversationComp.setName("javax.enterprise.context.conversation");
+
+        WebBeansDecoratorConfig.configureDecorators(conversationComp);
+
+        return conversationComp;
+    }
+
+    /**
+     * Returns a new injected point bean instance.
+     * @return new injected point bean
+     */
+    public InjectionPointBean getInjectionPointBean()
+    {
+        return new InjectionPointBean(webBeansContext);
+    }
+
+    /**
+     * Check the {@link PostConstruct} or {@link PreDestroy} annotated method
+     * criterias, and return post construct or pre destroyDependents method.
+     * <p>
+     * Web Beans container is responsible for setting the post construct or pre
+     * destroyDependents annotation if the web beans component is not an EJB components,
+     * in this case EJB container is responsible for this.
+     * </p>
+     *
+     * @param clazz checked class
+     * @param commonAnnotation post construct or predestroy annotation
+     * @param invocationContext whether the takes an invocationContext, as in
+     *            interceptors defiend outside of the bean class.
+     * @return post construct or predestroy method
+     */
+    public Method checkCommonAnnotationCriterias(Class<?> clazz, Class<? extends Annotation> commonAnnotation, boolean invocationContext)
+    {
+        Asserts.nullCheckForClass(clazz);
+
+        Method[] methods = ClassUtil.getDeclaredMethods(clazz);
+        Method result = null;
+        boolean found = false;
+        for (Method method : methods)
+        {
+            if (AnnotationUtil.hasMethodAnnotation(method, commonAnnotation))
+            {
+                if (ClassUtil.isMoreThanOneMethodWithName(method.getName(), clazz))
+                {
+                    continue;
+                }
+
+                if (found)
+                {
+                    throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName()
+                            + " annotation is declared more than one method in the class : " + clazz.getName());
+                }
+
+                found = true;
+                result = method;
+
+                // Check method criterias
+                if (ClassUtil.isMethodHasParameter(method))
+                {
+                    // Check method criterias
+                    Class<?>[] params = ClassUtil.getMethodParameterTypes(method);
+                    if (params.length != 1 || !params[0].equals(InvocationContext.class))
+                    {
+                        throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName()
+                                + " annotated method : " + method.getName() + " in class : " + clazz.getName()
+                                + " can not take any formal arguments other than InvocationContext");
+                    }
+                }
+                else if(invocationContext)
+                {
+                    // Maybe it just intercepts itself, but we were looking at it like an @Interceptor
+                    return null;
+                }
+
+                if (!ClassUtil.getReturnType(method).equals(Void.TYPE))
+                {
+                    throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName()
+                            + " annotated method : " + method.getName() + " in class : " + clazz.getName()
+                            + " must return void type");
+                }
+
+                if (isNoCheckedExceptionEnforced() && ClassUtil.isMethodHasCheckedException(method))
+                {
+                    throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName()
+                            + " annotated method : " + method.getName() + " in class : " + clazz.getName()
+                            + " can not throw any checked exception");
+                }
+
+                if (Modifier.isStatic(method.getModifiers()))
+                {
+                    throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName()
+                            + " annotated method : " + method.getName() + " in class : "
+                            + clazz.getName() + " can not be static");
+                }
+            }
+        }
+
+        return result;
+    }
+
+    public <T> Method checkCommonAnnotationCriterias(AnnotatedType<T> annotatedType, Class<? extends Annotation> commonAnnotation, boolean invocationContext)
+    {
+        Class<?> clazz = annotatedType.getJavaClass();
+
+        Method result = null;
+        boolean found = false;
+        Set<AnnotatedMethod<? super T>> methods = annotatedType.getMethods();
+        for(AnnotatedMethod<? super T> methodA : methods)
+        {
+            AnnotatedMethod<T> methodB = (AnnotatedMethod<T>)methodA;
+            Method method = methodB.getJavaMember();
+            if (method.isAnnotationPresent(commonAnnotation))
+            {
+                if (ClassUtil.isMoreThanOneMethodWithName(method.getName(), clazz))
+                {
+                    continue;
+                }
+
+                if (found)
+                {
+                    throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName()
+                            + " annotation is declared more than one method in the class : " + clazz.getName());
+                }
+                found = true;
+                result = method;
+
+                // Check method criterias
+                if (methodB.getParameters().isEmpty())
+                {
+                    if (!invocationContext)
+                    {
+                        throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName()
+                                + " annotated method : " + method.getName() + " in class : " + clazz.getName()
+                                + " can not take any formal arguments");
+                    }
+
+                    List<AnnotatedParameter<T>> parameters = methodB.getParameters();
+                    List<Class<?>> clazzParameters = new ArrayList<Class<?>>();
+                    for(AnnotatedParameter<T> parameter : parameters)
+                    {
+                        clazzParameters.add(ClassUtil.getClazz(parameter.getBaseType()));
+                    }
+
+                    Class<?>[] params = clazzParameters.toArray(new Class<?>[clazzParameters.size()]);
+                    if (params.length != 1 || !params[0].equals(InvocationContext.class))
+                    {
+                        throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName()
+                                + " annotated method : " + method.getName() + " in class : " + clazz.getName()
+                                + " can not take any formal arguments other than InvocationContext");
+                    }
+                }
+                else if(invocationContext)
+                {
+                    throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName()
+                            + " annotated method : " + method.getName() + " in class : " + clazz.getName()
+                            + " must take a parameter with class type javax.interceptor.InvocationContext.");
+                }
+
+                if (!ClassUtil.getReturnType(method).equals(Void.TYPE))
+                {
+                    throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName()
+                            + " annotated method : " + method.getName() + " in class : " + clazz.getName()
+                            + " must return void type");
+                }
+
+                if (isNoCheckedExceptionEnforced() && ClassUtil.isMethodHasCheckedException(method))
+                {
+                    throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName()
+                            + " annotated method : " + method.getName() + " in class : " + clazz.getName()
+                            + " can not throw any checked exception");
+                }
+
+                if (Modifier.isStatic(method.getModifiers()))
+                {
+                    throw new WebBeansConfigurationException("@" + commonAnnotation.getSimpleName()
+                            + " annotated method : " + method.getName() + " in class : " + clazz.getName()
+                            + " can not be static");
+                }
+            }
+
+        }
+
+
+        return result;
+    }
+
+    /**
+     * Check the {@link AroundInvoke} annotated method criterias, and return
+     * around invoke method.
+     * <p>
+     * Web Beans container is responsible for setting around invoke annotation
+     * if the web beans component is not an EJB components, in this case EJB
+     * container is responsible for this.
+     * </p>
+     *
+     * @param clazz checked class
+     * @return around invoke method
+     */
+    public static Method checkAroundInvokeAnnotationCriterias(Class<?> clazz, Class<? extends Annotation> annot)
+    {
+        Asserts.nullCheckForClass(clazz);
+
+        Method[] methods = ClassUtil.getDeclaredMethods(clazz);
+        Method result = null;
+        boolean found = false;
+        for (Method method : methods)
+        {
+            if (AnnotationUtil.hasMethodAnnotation(method, annot))
+            {
+                // Overriden methods
+                if (ClassUtil.isMoreThanOneMethodWithName(method.getName(), clazz))
+                {
+                    continue;
+                }
+
+                if (found)
+                {
+                    throw new WebBeansConfigurationException("@" + annot.getSimpleName()
+                            + " annotation is declared more than one method in the class : " + clazz.getName());
+                }
+
+                found = true;
+                result = method;
+
+                // Check method criterias
+                Class<?>[] params = ClassUtil.getMethodParameterTypes(method);
+                if (params.length != 1 || !params[0].equals(InvocationContext.class))
+                {
+                    throw new WebBeansConfigurationException("@" + annot.getSimpleName() + " annotated method : "
+                            + method.getName() + " in class : " + clazz.getName()
+                            + " can not take any formal arguments other than InvocationContext");
+                }
+
+                if (!ClassUtil.getReturnType(method).equals(Object.class))
+                {
+                    throw new WebBeansConfigurationException("@" + annot.getSimpleName() + " annotated method : "
+                            + method.getName() + " in class : " + clazz.getName() + " must return Object type");
+                }
+
+                if (Modifier.isStatic(method.getModifiers()) || ClassUtil.isFinal(method.getModifiers()))
+                {
+                    throw new WebBeansConfigurationException("@" + annot.getSimpleName() + " annotated method : "
+                            + method.getName() + " in class : " + clazz.getName() + " can not be static or final");
+                }
+            }
+        }
+
+        return result;
+    }
+
+    public static <T> Method checkAroundInvokeAnnotationCriterias(AnnotatedType<T> annotatedType, Class<? extends Annotation> annot)
+    {
+        Method result = null;
+        boolean found = false;
+        Set<AnnotatedMethod<? super T>> methods = annotatedType.getMethods();
+        for(AnnotatedMethod<? super T> methodA : methods)
+        {
+            AnnotatedMethod<T> method = (AnnotatedMethod<T>)methodA;
+
+            if (method.isAnnotationPresent(annot))
+            {
+                // Overriden methods
+                if (ClassUtil.isMoreThanOneMethodWithName(method.getJavaMember().getName(),
+                                                          annotatedType.getJavaClass()))
+                {
+                    continue;
+                }
+
+                if (found)
+                {
+                    throw new WebBeansConfigurationException("@" + annot.getSimpleName()
+                            + " annotation is declared more than one method in the class : "
+                            + annotatedType.getJavaClass().getName());
+                }
+
+                found = true;
+                result = method.getJavaMember();
+
+                List<AnnotatedParameter<T>> parameters = method.getParameters();
+                List<Class<?>> clazzParameters = new ArrayList<Class<?>>();
+                for(AnnotatedParameter<T> parameter : parameters)
+                {
+                    clazzParameters.add(ClassUtil.getClazz(parameter.getBaseType()));
+                }
+
+                Class<?>[] params = clazzParameters.toArray(new Class<?>[clazzParameters.size()]);
+
+                if (params.length != 1 || !params[0].equals(InvocationContext.class))
+                {
+                    throw new WebBeansConfigurationException("@" + annot.getSimpleName() + " annotated method : "
+                            + method.getJavaMember().getName() + " in class : " + annotatedType.getJavaClass().getName()
+                            + " can not take any formal arguments other than InvocationContext");
+                }
+
+                if (!ClassUtil.getReturnType(method.getJavaMember()).equals(Object.class))
+                {
+                    throw new WebBeansConfigurationException("@" + annot.getSimpleName() + " annotated method : "
+                            + method.getJavaMember().getName()+ " in class : " + annotatedType.getJavaClass().getName()
+                            + " must return Object type");
+                }
+
+                if (Modifier.isStatic(method.getJavaMember().getModifiers()) ||
+                    ClassUtil.isFinal(method.getJavaMember().getModifiers()))
+                {
+                    throw new WebBeansConfigurationException("@" + annot.getSimpleName() + " annotated method : "
+                            + method.getJavaMember().getName( )+ " in class : " + annotatedType.getJavaClass().getName()
+                            + " can not be static or final");
+                }
+            }
+        }
+
+        return result;
+    }
+
+
+    /**
+     * Configures the interceptor stack of the web beans component.
+     *
+     * @param interceptorClass interceptor class
+     * @param interceptionType annotation type
+     * @param definedInInterceptorClass check if annotation is defined in
+     *            interceptor class (as opposed to bean class)
+     * @param definedInMethod check if the interceptor is defined in the comp.
+     *            method
+     * @param stack interceptor stack
+     * @param annotatedInterceptorClassMethod if definedInMethod, this specify
+     *            method
+     * @param defineWithInterceptorBinding if interceptor is defined with WebBeans
+     *            spec, not EJB spec
+     */
+    public void configureInterceptorMethods(Interceptor<?> webBeansInterceptor,
+                                             Class<?> interceptorClass,
+                                             Class<? extends Annotation> interceptionType,
+                                             boolean definedInInterceptorClass,
+                                             boolean definedInMethod,
+                                             List<InterceptorData> stack,
+                                             Method annotatedInterceptorClassMethod,
+                                             boolean defineWithInterceptorBinding)
+    {
+        InterceptorData intData = null;
+        Method method = null;
+        OpenWebBeansEjbLCAPlugin ejbPlugin = null;
+        Class<? extends Annotation> prePassivateClass  = null;
+        Class<? extends Annotation> postActivateClass  = null;
+
+        ejbPlugin = webBeansContext.getPluginLoader().getEjbLCAPlugin();
+        if(ejbPlugin != null)
+        {
+            prePassivateClass  = ejbPlugin.getPrePassivateClass();
+            postActivateClass  = ejbPlugin.getPostActivateClass();
+        }
+
+        //Check for default constructor of EJB based interceptor
+        if(webBeansInterceptor == null)
+        {
+            if(definedInInterceptorClass)
+            {
+                Constructor<?> ct = getNoArgConstructor(interceptorClass);
+                if (ct == null)
+                {
+                    throw new WebBeansConfigurationException("class : " + interceptorClass.getName()
+                            + " must have no-arg constructor");
+                }
+            }
+        }
+
+        if (interceptionType.equals(AroundInvoke.class) || interceptionType.equals(AroundTimeout.class))
+        {
+            method = WebBeansUtil.checkAroundInvokeAnnotationCriterias(interceptorClass, interceptionType);
+        }
+        else if (interceptionType.equals(PostConstruct.class) || ((postActivateClass != null) && (interceptionType.equals(postActivateClass)))
+                 || interceptionType.equals(PreDestroy.class) || ((prePassivateClass != null) && (interceptionType.equals(prePassivateClass))))
+        {
+            method = checkCommonAnnotationCriterias(interceptorClass, interceptionType, definedInInterceptorClass);
+        }
+
+        if (method != null)
+        {
+            intData = new InterceptorDataImpl(defineWithInterceptorBinding, webBeansContext);
+            intData.setDefinedInInterceptorClass(definedInInterceptorClass);
+            intData.setDefinedInMethod(definedInMethod);
+            intData.setInterceptorBindingMethod(annotatedInterceptorClassMethod);
+            intData.setWebBeansInterceptor(webBeansInterceptor);
+
+            if (definedInInterceptorClass)
+            {
+                intData.setInterceptorClass(interceptorClass);
+            }
+
+            intData.setInterceptorMethod(method, interceptionType);
+
+            stack.add(intData);
+        }
+    }
+
+
+    public <T> void configureInterceptorMethods(Interceptor<?> webBeansInterceptor,
+                                                 AnnotatedType<T> annotatedType,
+                                                 Class<? extends Annotation> annotation,
+                                                 boolean definedInInterceptorClass,
+                                                 boolean definedInMethod,
+                                                 List<InterceptorData> stack,
+                                                 Method annotatedInterceptorClassMethod)
+    {
+        InterceptorData intData = null;
+        Method method = null;
+        OpenWebBeansEjbLCAPlugin ejbPlugin = null;
+        Class<? extends Annotation> prePassivateClass  = null;
+        Class<? extends Annotation> postActivateClass  = null;
+
+        ejbPlugin = webBeansContext.getPluginLoader().getEjbLCAPlugin();
+        if(ejbPlugin != null)
+        {
+            prePassivateClass  = ejbPlugin.getPrePassivateClass();
+            postActivateClass  = ejbPlugin.getPostActivateClass();
+        }
+
+        if (annotation.equals(AroundInvoke.class) ||
+                annotation.equals(AroundTimeout.class))
+        {
+            method = WebBeansUtil.checkAroundInvokeAnnotationCriterias(annotatedType, annotation);
+        }
+        else if (annotation.equals(PostConstruct.class) || ((postActivateClass != null) && (annotation.equals(postActivateClass)))
+                 || annotation.equals(PreDestroy.class) || ((prePassivateClass != null) && (annotation.equals(prePassivateClass))))
+        {
+            method = checkCommonAnnotationCriterias(annotatedType, annotation, definedInInterceptorClass);
+        }
+
+        if (method != null)
+        {
+            intData = new InterceptorDataImpl(true, webBeansContext);
+            intData.setDefinedInInterceptorClass(definedInInterceptorClass);
+            intData.setDefinedInMethod(definedInMethod);
+            intData.setInterceptorBindingMethod(annotatedInterceptorClassMethod);
+            intData.setWebBeansInterceptor(webBeansInterceptor);
+            intData.setInterceptorMethod(method, annotation);
+            intData.setInterceptorClass(webBeansInterceptor.getBeanClass());
+
+            stack.add(intData);
+        }
+    }
+
+
+    /**
+     * Create a new instance of the given class using it's default constructor
+     * regardless if the constructor is visible or not.
+     * This is needed to construct some package scope classes in the TCK.
+     *
+     * @param <T>
+     * @param clazz
+     * @return
+     * @throws WebBeansConfigurationException
+     */
+    public <T> T newInstanceForced(Class<T> clazz) throws WebBeansConfigurationException
+    {
+        // FIXME: This new instance should have JCDI injection performed
+        Constructor<T> ct = getNoArgConstructor(clazz);
+        if (ct == null)
+        {
+            throw new WebBeansConfigurationException("class : " + clazz.getName() + " must have no-arg constructor");
+        }
+
+        if (!ct.isAccessible())
+        {
+            webBeansContext.getSecurityService().doPrivilegedSetAccessible(ct, true);
+        }
+
+        try
+        {
+            return ct.newInstance();
+        }
+        catch( IllegalArgumentException e )
+        {
+            throw new WebBeansConfigurationException("class : " + clazz.getName() + " is not constructable", e);
+        }
+        catch( IllegalAccessException e )
+        {
+            throw new WebBeansConfigurationException("class : " + clazz.getName() + " is not constructable", e);
+        }
+        catch( InvocationTargetException e )
+        {
+            throw new WebBeansConfigurationException("class : " + clazz.getName() + " is not constructable", e);
+        }
+        catch( InstantiationException e )
+        {
+            throw new WebBeansConfigurationException("class : " + clazz.getName() + " is not constructable", e);
+        }
+    }
+
+    /**
+     * Returns true if interceptor stack contains interceptor with given type.
+     *
+     * @param stack interceptor stack
+     * @param type interceptor type
+     * @return true if stack contains the interceptor with given type
+     */
+    public static boolean isContainsInterceptorMethod(List<InterceptorData> stack, InterceptionType type)
+    {
+        if (stack.size() > 0)
+        {
+            Iterator<InterceptorData> it = stack.iterator();
+            while (it.hasNext())
+            {
+                Method m = null;
+                InterceptorData data = it.next();
+
+                if (type.equals(InterceptionType.AROUND_INVOKE))
+                {
+                    m = data.getAroundInvoke();
+                }
+                else if (type.equals(InterceptionType.AROUND_TIMEOUT))
+                {
+                    m = data.getAroundTimeout();
+                }
+                else if (type.equals(InterceptionType.POST_CONSTRUCT))
+                {
+                    m = data.getPostConstruct();
+                }
+                else if (type.equals(InterceptionType.POST_ACTIVATE))
+                {
+                    m = data.getPostActivate();
+                }
+                else if (type.equals(InterceptionType.PRE_DESTROY))
+                {
+                    m = data.getPreDestroy();
+                }
+                else if (type.equals(InterceptionType.PRE_PASSIVATE))
+                {
+                    m = data.getPrePassivate();
+                }
+
+                if (m != null)
+                {
+                    return true;
+                }
+
+            }
+        }
+
+        return false;
+    }
+
+    public static String getManagedBeanDefaultName(String clazzName)
+    {
+        Asserts.assertNotNull(clazzName);
+
+        if(clazzName.length() > 0)
+        {
+            StringBuilder name = new StringBuilder(clazzName);
+            name.setCharAt(0, Character.toLowerCase(name.charAt(0)));
+
+            return name.toString();
+        }
+
+        return clazzName;
+    }
+
+    public static String getProducerDefaultName(String methodName)
+    {
+        StringBuilder buffer = new StringBuilder(methodName);
+
+        if (buffer.length() > 3 &&  (buffer.substring(0, 3).equals("get") || buffer.substring(0, 3).equals("set")))
+        {
+
+            if(Character.isUpperCase(buffer.charAt(3)))
+            {
+                buffer.setCharAt(3, Character.toLowerCase(buffer.charAt(3)));
+            }
+
+            return buffer.substring(3);
+        }
+        else if ((buffer.length() > 2 &&  buffer.substring(0, 2).equals("is")))
+        {
+            if(Character.isUpperCase(buffer.charAt(2)))
+            {
+                buffer.setCharAt(2, Character.toLowerCase(buffer.charAt(2)));
+            }
+
+            return buffer.substring(2);
+        }
+
+        else
+        {
+            buffer.setCharAt(0, Character.toLowerCase(buffer.charAt(0)));
+            return buffer.toString();
+        }
+    }
+
+    /**
+     * Return true if a list of beans are directly specialized/extended each other.
+     *
+     * @param beans, a set of specialized beans.
+     *
+     * @return
+     */
+    protected static boolean isDirectlySpecializedBeanSet(Set<Bean<?>> beans)
+    {
+
+        ArrayList<AbstractOwbBean<?>> beanList = new ArrayList<AbstractOwbBean<?>>();
+
+        for(Bean<?> bb : beans)
+        {
+            AbstractOwbBean<?>bean = (AbstractOwbBean<?>)bb;
+            beanList.add(bean);
+        }
+
+        java.util.Collections.sort(beanList, new java.util.Comparator()
+        {
+            public int compare(Object o1, Object o2)
+            {
+                AbstractOwbBean<?> b1 = (AbstractOwbBean<?>)o1;
+                AbstractOwbBean<?> b2 = (AbstractOwbBean<?>)o2;
+                Class c1 = b1.getReturnType();
+                Class c2 = b2.getReturnType();
+                if (c2.isAssignableFrom(c1))
+                {
+                    return 1;
+                }
+
+                if (c1.isAssignableFrom(c2))
+                {
+                    return -1;
+                }
+
+                throw new InconsistentSpecializationException(c1 + " and " + c2 + "are not assignable to each other." );
+            }
+        });
+
+        for(int i=0; i<beanList.size() - 1; i++)
+        {
+            if (!beanList.get(i).getReturnType().equals(beanList.get(i+1).getReturnType().getSuperclass()))
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public void configureSpecializations(List<Class<?>> beanClasses)
+    {
+        for(Class<?> clazz : beanClasses)
+        {
+            configureSpecializations(clazz, beanClasses);
+        }
+    }
+
+    /**
+     * Configures the bean specializations.
+     * <p>
+     * Specialized beans inherit the <code>name</code> property
+     * from their parents. Specialized bean deployment priority
+     * must be higher than its super class related bean.
+     * </p>
+     *
+     * @param specializedClass specialized class
+     * @throws DefinitionException if name is defined
+     * @throws InconsistentSpecializationException related with priority
+     * @throws WebBeansConfigurationException any other exception
+     */
+    protected void configureSpecializations(Class<?> specializedClass, List<Class<?>> beanClasses)
+    {
+        Asserts.nullCheckForClass(specializedClass);
+
+        Bean<?> superBean = null;
+        Bean<?> specialized = null;
+        Set<Bean<?>> resolvers = isConfiguredWebBeans(specializedClass, true);
+        AlternativesManager altManager = webBeansContext.getAlternativesManager();
+
+        if (resolvers != null)
+        {
+            if(resolvers.isEmpty())
+            {
+                throw new InconsistentSpecializationException("Specialized bean for class : " + specializedClass
+                        + " is not enabled in the deployment.");
+            }
+
+            specialized = resolvers.iterator().next();
+
+            if(resolvers.size() > 1)
+            {
+                if (!isDirectlySpecializedBeanSet(resolvers))
+                {
+                    throw new InconsistentSpecializationException("More than one specialized bean for class : "
+                            + specializedClass + " is enabled in the deployment.");
+                }
+                // find the widest bean which satisfies the specializedClass
+                for( Bean<?> sp : resolvers)
+                {
+                    if (sp == specialized)
+                    {
+                        continue;
+                    }
+
+                    if (((AbstractOwbBean<?>)sp).getReturnType().
+                            isAssignableFrom(((AbstractOwbBean<?>)specialized).getReturnType()))
+                    {
+                        specialized = sp;
+                    }
+                }
+            }
+
+            Class<?> superClass = specializedClass.getSuperclass();
+
+            resolvers = isConfiguredWebBeans(superClass,false);
+
+            for(Bean<?> candidates : resolvers)
+            {
+                AbstractOwbBean<?> candidate = (AbstractOwbBean<?>)candidates;
+
+                if(!(candidate instanceof NewBean))
+                {
+                    if(candidate.getReturnType().equals(superClass))
+                    {
+                        superBean = candidates;
+                        break;
+                    }
+                }
+            }
+
+            if (superBean != null)
+            {
+                // Recursively configure super class first if super class is also a special bean.
+                // So the name and bean meta data could be populated to this beanclass.
+                if (beanClasses.contains(superClass) && ((AbstractOwbBean<?>)superBean).isEnabled())
+                {
+                    configureSpecializations(superClass, beanClasses);
+                }
+
+                if (!AnnotationUtil.hasClassAnnotation(specializedClass, Alternative.class))
+                {
+                    //disable superbean if the current bean is not an alternative
+                    ((AbstractOwbBean<?>)superBean).setEnabled(false);
+                }
+                else if(altManager.isClassAlternative(specializedClass))
+                {
+                    //disable superbean if the current bean is an enabled alternative
+                    ((AbstractOwbBean<?>)superBean).setEnabled(false);
+                }
+
+                AbstractOwbBean<?> comp = (AbstractOwbBean<?>)specialized;
+                if (comp.isSpecializedBean())
+                {
+                    // This comp is already configured in previous invocation
+                    // return directly, else Exception might be fired when set
+                    // bean name again.
+                    return;
+                }
+
+                //Check types of the beans
+                if(comp.getClass() != superBean.getClass())
+                {
+                    throw new DefinitionException("@Specialized Class : " + specializedClass.getName()
+                            + " and its super class may be the same type of bean,i.e, ManagedBean, SessionBean etc.");
+                }
+
+                if(superBean.getName() != null)
+                {
+                    if(comp.getName() != null)
+                    {
+                        throw new DefinitionException("@Specialized Class : " + specializedClass.getName()
+                                + " may not explicitly declare a bean name");
+                    }
+
+                    comp.setName(superBean.getName());
+                    comp.setSpecializedBean(true);
+                }
+
+                specialized.getQualifiers().addAll(superBean.getQualifiers());
+            }
+
+            else
+            {
+                throw new InconsistentSpecializationException("WebBean component class : " + specializedClass.getName()
+                        + " is not enabled for specialized by the " + specializedClass + " class");
+            }
+        }
+
+    }
+
+    /**
+     * Configure a list of producer method beans, which override the same method
+     * and the bean classes are directly extended each other.
+     *
+     * @param sortedProducerBeans
+     */
+    protected void configSpecializedProducerMethodBeans(List<ProducerMethodBean> sortedProducerBeans)
+    {
+        if (sortedProducerBeans.isEmpty())
+        {
+            return;
+        }
+
+        AlternativesManager altManager = webBeansContext.getAlternativesManager();
+        Method superMethod = sortedProducerBeans.get(0).getCreatorMethod();
+
+        for(int i=1; i<sortedProducerBeans.size(); i++)
+        {
+            ProducerMethodBean bean = sortedProducerBeans.get(i);
+            ProducerMethodBean superBean = sortedProducerBeans.get(i - 1);
+
+            // inherit superbean qualifiers
+            Set<Annotation> qualifiers = superBean.getQualifiers();
+            for(Annotation an : qualifiers)
+            {
+                bean.addQualifier(an);
+            }
+            // inherit name is super class has name
+            boolean isSuperHasName = configuredProducerSpecializedName(bean, bean.getCreatorMethod(), superMethod);
+
+            // disable super bean if needed
+            if (bean.getCreatorMethod().getAnnotation(Alternative.class) == null)
+            {
+                //disable superbean if the current bean is not an alternative
+                superBean.setEnabled(false);
+            }
+            else if(altManager.isClassAlternative(bean.getBeanClass()))
+            {
+                //disable superbean if the current bean is an enabled alternative
+                superBean.setEnabled(false);
+            }
+
+            //if no name defined, set superMethod to this bean since this
+            //bean's method might have name defined.
+            if (!isSuperHasName)
+            {
+                superMethod = bean.getCreatorMethod();
+            }
+        }
+    }
+
+    /**
+     * Configure direct/indirect specialized producer method beans.
+     */
+    public void configureProducerMethodSpecializations()
+    {
+        Method method;
+        ProducerMethodBean pbean;
+        ProducerMethodBean pLeft;
+        ProducerMethodBean pRight;
+
+        // collect all producer method beans
+        Set<Bean<?>> beans = webBeansContext.getBeanManagerImpl().getBeans();
+        List<ProducerMethodBean> producerBeans = new ArrayList<ProducerMethodBean>();
+        for(Bean b : beans)
+        {
+            if (b instanceof ProducerMethodBean)
+            {
+                producerBeans.add((ProducerMethodBean)b);
+            }
+        }
+
+        // create sorted bean helper.
+        SortedListHelper<ProducerMethodBean> producerBeanListHelper = new
+                SortedListHelper<ProducerMethodBean>(new ArrayList<ProducerMethodBean>(),
+                new Comparator<ProducerMethodBean> ()
+                {
+                    public int compare(ProducerMethodBean e1, ProducerMethodBean e2)
+                    {
+                        if (e1.getBeanClass().isAssignableFrom(e2.getBeanClass()))
+                        {
+                            return -1;
+                        }
+                        else if (e1.equals(e2))
+                        {
+                            return 0;
+                        }
+                        return 1;
+                    }
+                });
+
+        while(true)
+        {
+            pbean = null;
+            method = null;
+            producerBeanListHelper.clear();
+
+            //locate a specialized bean
+            for(ProducerMethodBean pb : producerBeans)
+            {
+                if (pb.isSpecializedBean())
+                {
+                    pbean = pb;
+                    method = pb.getCreatorMethod();
+                    producerBeanListHelper.add(pb);
+                    break;
+                }
+            }
+            if (pbean == null)
+            {
+                break;
+            }
+
+            pRight = pbean;
+            pLeft = pRight;
+            boolean pLeftContinue = true;
+            boolean pRightContinue = true;
+
+            // find all pbean's super beans and sub sub beans
+            while(pLeftContinue || pRightContinue)
+            {
+                pRightContinue = false;
+                pLeftContinue = false;
+                for(ProducerMethodBean pb : producerBeans)
+                {
+                    //left
+                    if (pLeft!= null &&
+                        pLeft.getBeanClass().getSuperclass().equals(pb.getBeanClass()))
+                    {
+                        Method superMethod = ClassUtil.getClassMethodWithTypes(pb.getBeanClass(), method.getName(),
+                                Arrays.asList(method.getParameterTypes()));
+
+                        //Added by GE, method check is necessary otherwise getting wrong method qualifier annotations
+                        if (superMethod != null && superMethod.equals(pb.getCreatorMethod()))
+                        {
+                            producerBeanListHelper.add(pb);
+                            pLeft = (pb.isSpecializedBean()) ? pb : null;
+                        }
+                        else
+                        {
+                            pLeft = null;
+                        }
+                        if (pLeft != null)
+                        {
+                            pLeftContinue = true;
+                        }
+                    }
+                    //right
+                    if (pRight != null &&
+                        pb.getBeanClass().getSuperclass().equals(pRight.getBeanClass()))
+                    {
+                        if (!pb.isSpecializedBean())
+                        {
+                            pRight = null;
+                        }
+                        else
+                        {
+                            Method superMethod = ClassUtil.getClassMethodWithTypes(pb.getBeanClass(), method.getName(),
+                                    Arrays.asList(method.getParameterTypes()));
+                            //Added by GE, method check is necessary otherwise getting wrong method qualifier annotations
+                            if (superMethod != null && superMethod.equals(pb.getCreatorMethod()))
+                            {
+                                producerBeanListHelper.add(pb);
+                                pRight = pb;
+                            }
+                            else
+                            {
+                                pRight = null;
+                            }
+                        }
+                        if (pRight != null)
+                        {
+                            pRightContinue = true;
+                        }
+                    }
+                } // for
+            } // while
+
+            //remove the group from producer bean list
+            for(ProducerMethodBean pb : producerBeanListHelper.getList())
+            {
+                producerBeans.remove(pb);
+            }
+            //configure the directly extended producer beans
+            configSpecializedProducerMethodBeans(producerBeanListHelper.getList());
+        }
+    }
+
+
+    public Set<Bean<?>> isConfiguredWebBeans(Class<?> clazz,boolean annotate)
+    {
+        Asserts.nullCheckForClass(clazz);
+
+        Set<Bean<?>> beans = new HashSet<Bean<?>>();
+
+        Set<Bean<?>> components = webBeansContext.getBeanManagerImpl().getComponents();
+        Iterator<Bean<?>> it = components.iterator();
+
+        while (it.hasNext())
+        {
+            AbstractOwbBean<?> bean = (AbstractOwbBean<?>)it.next();
+
+            boolean enterprise = false;
+            if(bean instanceof EnterpriseBeanMarker)
+            {
+                enterprise = true;
+            }
+
+            if (bean.getTypes().contains(clazz) ||
+                    (enterprise && bean.getBeanClass().equals(clazz)))
+            {
+                if(annotate)
+                {
+                    if(bean.getReturnType().isAnnotationPresent(Specializes.class))
+                    {
+                        if(!(bean instanceof NewBean))
+                        {
+                            beans.add(bean);
+                        }
+                    }
+                }
+                else
+                {
+                    beans.add(bean);
+                }
+            }
+        }
+
+        return beans;
+    }
+
+    /**
+     * Checks the unproxiable condition.
+     * @param bean managed bean
+     * @param scopeType scope type
+     * @throws WebBeansConfigurationException if
+     *  bean is not proxied by the container
+     */
+    public void checkUnproxiableApiType(Bean<?> bean, Class<? extends Annotation> scopeType)
+    {
+        Asserts.assertNotNull("bean", "bean parameter can not be null");
+        Asserts.assertNotNull(scopeType, "scopeType parameter can not be null");
+
+        //Unproxiable test for NormalScoped beans
+        if (isScopeTypeNormal(scopeType))
+        {
+            ViolationMessageBuilder violationMessage = ViolationMessageBuilder.newViolation();
+
+            Class<?> beanClass;
+            if (bean instanceof OwbBean) 
+            {
+                beanClass = ((OwbBean)bean).getReturnType();
+            }
+            else 
+            {
+                beanClass = bean.getBeanClass();
+            }
+            
+            if(!beanClass.isInterface() && beanClass != Object.class)
+            {
+                if(beanClass.isPrimitive())
+                {
+                    violationMessage.addLine("It isn't possible to proxy a primitive type (" + beanClass.getName(), ")");
+                }
+
+                if(ClassUtil.isArray(beanClass))
+                {
+                    violationMessage.addLine("It isn't possible to proxy an array type (", beanClass.getName(), ")");
+                }
+
+                if(!violationMessage.containsViolation())
+                {
+                    if (ClassUtil.isFinal(beanClass.getModifiers()))
+                    {
+                        violationMessage.addLine(beanClass.getName(), " is a final class! CDI doesn't allow to proxy that.");
+                    }
+
+                    Method[] methods = SecurityUtil.doPrivilegedGetDeclaredMethods(beanClass);
+                    for (Method m : methods)
+                    {
+                        int modifiers = m.getModifiers();
+                        if (ClassUtil.isFinal(modifiers) && !Modifier.isPrivate(modifiers) &&
+                            !m.isSynthetic() && !m.isBridge())
+                        {
+                            violationMessage.addLine(beanClass.getName(), " has final method "+ m + " CDI doesn't allow to proxy that.");
+                        }
+                    }
+
+                    Constructor<?> cons = getNoArgConstructor(beanClass);
+                    if (cons == null)
+                    {
+                        violationMessage.addLine(beanClass.getName(), " has no explicit no-arg constructor!",
+                                "A public or protected constructor without args is required!");
+                    }
+                    else if (Modifier.isPrivate(cons.getModifiers()))
+                    {
+                        violationMessage.addLine(beanClass.getName(), " has a >private< no-arg constructor! CDI doesn't allow to proxy that.");
+                    }
+                }
+
+                //Throw Exception
+                if(violationMessage.containsViolation())
+                {
+                    throwUnproxyableResolutionException(violationMessage);
+                }
+            }
+        }
+    }
+
+    private <T> Constructor<T> getNoArgConstructor(Class<T> clazz)
+    {
+        return webBeansContext.getSecurityService().doPrivilegedGetDeclaredConstructor(clazz);
+    }
+
+    /**
+     * Configures the producer method specialization.
+     *
+     * @param component producer method component
+     * @param method specialized producer method
+     * @param superClass bean super class that has overriden method
+     * @throws DefinitionException if the name is exist on the producer method when
+     *         parent also has name
+     * @throws WebBeansConfigurationException any other exceptions
+     */
+    public static void configureProducerSpecialization(AbstractOwbBean<?> component, Method method, Class<?> superClass)
+    {
+        Method superMethod = ClassUtil.getClassMethodWithTypes(superClass, method.getName(), Arrays.asList(method.getParameterTypes()));
+        if (superMethod == null)
+        {
+            throw new WebBeansConfigurationException("Producer method specialization is failed. Method "
+                    + method.getName() + " not found in super class : " + superClass.getName());
+        }
+
+        if (!AnnotationUtil.hasAnnotation(superMethod.getAnnotations(), Produces.class))
+        {
+            throw new WebBeansConfigurationException("Producer method specialization is failed. Method "
+                    + method.getName() + " found in super class : " + superClass.getName()
+                    + " is not annotated with @Produces");
+        }
+
+        component.setSpecializedBean(true);
+
+    }
+
+    /**
+     * Configures the name of the producer method for specializing the parent.
+     *
+     * @param component producer method component
+     * @param method specialized producer method
+     * @param superMethod overriden super producer method
+     */
+    public boolean configuredProducerSpecializedName(AbstractOwbBean<?> component, Method method, Method superMethod)
+    {
+        return webBeansContext.getAnnotationManager().configuredProducerSpecializedName(component, method, superMethod);
+    }
+
+    public static void checkInjectedMethodParameterConditions(Method method, Class<?> clazz)
+    {
+        Asserts.assertNotNull(method, "method parameter can not be null");
+        Asserts.nullCheckForClass(clazz);
+
+        if (AnnotationUtil.hasMethodParameterAnnotation(method, Disposes.class) ||
+            AnnotationUtil.hasMethodParameterAnnotation(method, Observes.class))
+        {
+            throw new WebBeansConfigurationException("Initializer method parameters in method : " + method.getName()
+                    + " in class : " + clazz.getName() + " can not be annotated with @Disposes or @Observers");
+
+        }
+
+    }
+
+    /**
+     * Returns true if instance injection point false otherwise.
+     *
+     * @param injectionPoint injection point definition
+     * @return true if instance injection point
+     */
+    public static boolean checkObtainsInjectionPointConditions(InjectionPoint injectionPoint)
+    {
+        Type type = injectionPoint.getType();
+
+        Class<?> candidateClazz = null;
+        if(type instanceof Class)
+        {
+            candidateClazz = (Class<?>)type;
+        }
+        else if(type instanceof ParameterizedType)
+        {
+            ParameterizedType pt = (ParameterizedType)type;
+            candidateClazz = (Class<?>)pt.getRawType();
+        }
+
+        if(!candidateClazz.isAssignableFrom(Instance.class))
+        {
+            return false;
+        }
+
+        Class<?> rawType;
+
+        if(ClassUtil.isParametrizedType(injectionPoint.getType()))
+        {
+            ParameterizedType pt = (ParameterizedType)injectionPoint.getType();
+
+            rawType = (Class<?>) pt.getRawType();
+
+            Type[] typeArgs = pt.getActualTypeArguments();
+
+            if(!(rawType.isAssignableFrom(Instance.class)))
+            {
+                throw new WebBeansConfigurationException("<Instance> field injection " + injectionPoint.toString()
+                        + " must have type javax.inject.Instance");
+            }
+            else
+            {
+                if(typeArgs.length != 1)
+                {
+                    throw new WebBeansConfigurationException("<Instance> field injection " + injectionPoint.toString()
+                            + " must not have more than one actual type argument");
+                }
+            }
+        }
+        else
+        {
+            throw new WebBeansConfigurationException("<Instance> field injection " + injectionPoint.toString()
+                    + " must be defined as ParameterizedType with one actual type argument");
+        }
+
+        return true;
+    }
+
+    public <T> void defineInterceptor(ManagedBeanCreatorImpl<T> managedBeanCreator, ProcessInjectionTarget<T> injectionTargetEvent)
+    {
+        Class<?> clazz = injectionTargetEvent.getAnnotatedType().getJavaClass();
+        AnnotatedType annotatedType = injectionTargetEvent.getAnnotatedType();
+
+        if (webBeansContext.getInterceptorsManager().isInterceptorEnabled(clazz))
+        {
+            ManagedBean<T> component;
+
+            webBeansContext.getInterceptorUtil().checkInterceptorConditions(annotatedType);
+            component = defineManagedBean(managedBeanCreator, injectionTargetEvent, false);
+
+            if (component != null)
+            {
+                Annotation[] anns = annotatedType.getAnnotations().toArray(new Annotation[annotatedType.getAnnotations().size()]);
+                webBeansContext.getWebBeansInterceptorConfig().configureInterceptorClass(component,
+                        webBeansContext.getAnnotationManager().getInterceptorBindingMetaAnnotations(anns));
+            }
+            else
+            {
+                // TODO could probably be a bit more descriptive
+                throw new DeploymentException("Cannot create Interceptor for class" + injectionTargetEvent.getAnnotatedType());
+            }
+        }
+
+    }
+
+
+    /**
+     * Define decorator bean.
+     * @param <T> type info
+     * @param creator bean creator
+     * @param processInjectionTargetEvent
+     */
+    public <T> void defineDecorator(ManagedBeanCreatorImpl<T> creator, ProcessInjectionTarget<T> processInjectionTargetEvent)
+    {
+        Class<T> clazz = processInjectionTargetEvent.getAnnotatedType().getJavaClass();
+        if (webBeansContext.getDecoratorsManager().isDecoratorEnabled(clazz))
+        {
+            ManagedBean<T> delegate = null;
+
+            DecoratorUtil.checkDecoratorConditions(clazz);
+
+            if(Modifier.isAbstract(clazz.getModifiers()))
+            {
+                delegate = defineAbstractDecorator(creator, processInjectionTargetEvent);
+            }
+            else
+            {
+                delegate = defineManagedBean(creator, processInjectionTargetEvent, false);
+            }
+
+            if (delegate != null)
+            {
+                WebBeansDecoratorConfig.configureDecoratorClass(delegate);
+            }
+            else
+            {
+                // TODO could probably be a bit more descriptive
+                throw new DeploymentException("Cannot create Decorator for class" + processInjectionTargetEvent.getAnnotatedType());
+            }
+        }
+    }
+
+    /**
+     * The result of this invocation get's cached
+     * @see #isScopeTypeNormalCache
+     * @param scopeType
+     * @return <code>true</code> if the given scopeType represents a
+     *         {@link javax.enterprise.context.NormalScope}d bean
+     */
+    public boolean isScopeTypeNormal(Class<? extends Annotation> scopeType)
+    {
+        Asserts.assertNotNull(scopeType, "scopeType argument can not be null");
+
+        Boolean isNormal = isScopeTypeNormalCache.get(scopeType);
+
+        if (isNormal != null)
+        {
+            return isNormal.booleanValue();
+        }
+
+
+        if (scopeType.isAnnotationPresent(NormalScope.class))
+        {
+            isScopeTypeNormalCache.put(scopeType, Boolean.TRUE);
+            return true;
+        }
+
+        if(scopeType.isAnnotationPresent(Scope.class))
+        {
+            isScopeTypeNormalCache.put(scopeType, Boolean.FALSE);
+            return false;
+        }
+
+        List<ExternalScope> additionalScopes = webBeansContext.getBeanManagerImpl().getAdditionalScopes();
+        for (ExternalScope additionalScope : additionalScopes)
+        {
+            if (additionalScope.getScope().equals(scopeType))
+            {
+                isNormal = additionalScope.isNormal() ? Boolean.TRUE : Boolean.FALSE;
+                isScopeTypeNormalCache.put(scopeType, isNormal);
+                return isNormal.booleanValue();
+            }
+        }
+
+        // no scopetype found so far -> kawumms
+        throw new IllegalArgumentException("scopeType argument must be annotated with @Scope or @NormalScope");
+    }
+
+    /**
+     * we cache results of calls to {@link #isScopeTypeNormalCache} because
+     * this doesn't change at runtime.
+     * We don't need to take special care about classloader
+     * hierarchies, because each cl has other classes.
+     */
+    private static Map<Class<? extends Annotation>, Boolean> isScopeTypeNormalCache =
+            new ConcurrentHashMap<Class<? extends Annotation>, Boolean>();
+    
+    public static void checkNullInstance(Object instance, Class<? > scopeType, String errorMessage, 
+            Object... errorMessageArgs)
+    {
+        if (instance == null)
+        {
+            if (!scopeType.equals(Dependent.class))
+            {
+                String message = format(errorMessage, errorMessageArgs);
+                throw new IllegalProductException(message);
+            }
+        }
+    }
+
+    public void checkSerializableScopeType(Class<? extends Annotation> scopeType, boolean isSerializable, String errorMessage,
+            Object... errorMessageArgs)
+    {
+        if (webBeansContext.getBeanManagerImpl().isPassivatingScope(scopeType))
+        {
+            if (!isSerializable)
+            {
+                String message = format(errorMessage, errorMessageArgs);
+                throw new IllegalProductException(message);
+            }
+        }
+    }
+
+    public static Bean<?> getMostSpecializedBean(BeanManager manager, Bean<?> component)
+    {
+         Set<Bean<?>> beans;
+
+         if (component instanceof EnterpriseBeanMarker)
+         {
+             beans = new HashSet<Bean<?>>();
+             Set<Bean<?>> allBeans = ((BeanManagerImpl)(manager)).getBeans(Object.class, AnnotationUtil.getAnnotationsFromSet(component.getQualifiers()));
+
+             for(Bean<?> candidateBean : allBeans)
+             {
+                 if (candidateBean instanceof EnterpriseBeanMarker)
+                 {
+                     /*
+                      * If a bean class of a session bean X is annotated @Specializes, then the bean class of X must directly extend
+                      * the bean class of another session bean Y. Then X directly specializes Y, as defined in Section 4.3, ‚"Specialization".
+                      */
+                     Class<?> candidateSuperClass = candidateBean.getBeanClass().getSuperclass();
+                     if (candidateSuperClass.equals(component.getBeanClass()))
+                     {
+                         beans.add(candidateBean);
+                     }
+                 }
+             }
+         }
+         else
+         {
+             beans = manager.getBeans(component.getBeanClass(),
+                     AnnotationUtil.getAnnotationsFromSet(component.getQualifiers()));
+         }
+
+        for(Bean<?> bean : beans)
+        {
+            Bean<?> find = bean;
+
+            if(!find.equals(component))
+            {
+                if(AnnotationUtil.hasClassAnnotation(find.getBeanClass(), Specializes.class))
+                {
+                    return getMostSpecializedBean(manager, find);
+                }
+            }
+        }
+
+        return component;
+    }
+
+    /**
+     * Returns <code>ProcessAnnotatedType</code> event.
+     * @param <T> bean type
+     * @param annotatedType bean class
+     * @return event
+     */
+    public <T> GProcessAnnotatedType fireProcessAnnotatedTypeEvent(AnnotatedType<T> annotatedType)
+    {
+        GProcessAnnotatedType processAnnotatedEvent = new GProcessAnnotatedType(annotatedType);
+
+        //Fires ProcessAnnotatedType
+        webBeansContext.getBeanManagerImpl().fireEvent(processAnnotatedEvent,AnnotationUtil.EMPTY_ANNOTATION_ARRAY);
+
+        if (processAnnotatedEvent.isModifiedAnnotatedType())
+        {
+            webBeansContext.getAnnotatedElementFactory().setAnnotatedType(processAnnotatedEvent.getAnnotatedType());
+        }
+
+        return processAnnotatedEvent;
+    }
+
+    /**
+     * Returns <code>ProcessInjectionTarget</code> event.
+     * @param <T> bean type
+     * @param bean bean instance
+     * @return event
+     */
+    public <T> GProcessInjectionTarget fireProcessInjectionTargetEvent(AbstractInjectionTargetBean<T> bean)
+    {
+        GProcessInjectionTarget processInjectionTargetEvent = createProcessInjectionTargetEvent(bean);
+        return fireProcessInjectionTargetEvent(processInjectionTargetEvent);
+
+
+    }
+
+    public GProcessInjectionTarget fireProcessInjectionTargetEvent(GProcessInjectionTarget processInjectionTargetEvent)
+    {
+        //Fires ProcessInjectionTarget
+        webBeansContext.getBeanManagerImpl().fireEvent(processInjectionTargetEvent, AnnotationUtil.EMPTY_ANNOTATION_ARRAY);
+
+        return processInjectionTargetEvent;
+    }
+
+    public <T> GProcessInjectionTarget createProcessInjectionTargetEvent(AbstractInjectionTargetBean<T> bean)
+    {
+        AnnotatedType<T> annotatedType = webBeansContext.getAnnotatedElementFactory().newAnnotatedType(bean.getReturnType());
+        InjectionTargetProducer<T> injectionTarget = new InjectionTargetProducer<T>(bean);
+        return new GProcessInjectionTarget(injectionTarget, annotatedType);
+    }
+
+
+    /**
+     * Returns <code>ProcessInjectionTarget</code> event.
+     * @param <T> bean type
+     * @return event
+     */
+    public <T> GProcessInjectionTarget fireProcessInjectionTargetEventForJavaEeComponents(Class<T> componentClass)
+    {
+        AnnotatedType<T> annotatedType = webBeansContext.getAnnotatedElementFactory().newAnnotatedType(componentClass);
+        InjectionTarget<T> injectionTarget = webBeansContext.getBeanManagerImpl().createInjectionTarget(annotatedType);
+        GProcessInjectionTarget processInjectionTargetEvent = new GProcessInjectionTarget(injectionTarget,annotatedType);
+
+        //Fires ProcessInjectionTarget
+        return fireProcessInjectionTargetEvent(processInjectionTargetEvent);
+
+    }
+
+
+    public GProcessProducer fireProcessProducerEventForMethod(ProducerMethodBean<?> producerMethod, AnnotatedMethod<?> method)
+    {
+        GProcessProducer producerEvent = new GProcessProducer(new ProducerBeansProducer(producerMethod),method);
+
+        //Fires ProcessProducer for methods
+        webBeansContext.getBeanManagerImpl().fireEvent(producerEvent, AnnotationUtil.EMPTY_ANNOTATION_ARRAY);
+
+        return producerEvent;
+    }
+
+    public GProcessProducer fireProcessProducerEventForField(ProducerFieldBean<?> producerField, AnnotatedField<?> field)
+    {
+        GProcessProducer producerEvent = new GProcessProducer(new ProducerBeansProducer(producerField),field);
+
+        //Fires ProcessProducer for fields
+        webBeansContext.getBeanManagerImpl().fireEvent(producerEvent, AnnotationUtil.EMPTY_ANNOTATION_ARRAY);
+
+        return producerEvent;
+    }
+
+    public void fireProcessProducerMethodBeanEvent(Map<ProducerMethodBean<?>, AnnotatedMethod<?>> annotatedMethods, AnnotatedType<?> annotatedType)
+    {
+        WebBeansContext webBeansContext = this.webBeansContext;

[... 941 lines stripped ...]