/*
 * 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.openejb.config;

import org.apache.openejb.BeanContext;
import org.apache.openejb.OpenEJBException;
import org.apache.openejb.api.LocalClient;
import org.apache.openejb.api.Proxy;
import org.apache.openejb.api.RemoteClient;
import org.apache.openejb.cdi.CdiBeanInfo;
import org.apache.openejb.config.rules.CheckClasses;
import org.apache.openejb.core.EmptyResourcesClassLoader;
import org.apache.openejb.core.ParentClassLoaderFinder;
import org.apache.openejb.core.TempClassLoader;
import org.apache.openejb.core.webservices.JaxWsUtils;
import org.apache.openejb.dyni.DynamicSubclass;
import org.apache.openejb.jee.ActivationConfig;
import org.apache.openejb.jee.ActivationSpec;
import org.apache.openejb.jee.AdminObject;
import org.apache.openejb.jee.ApplicationClient;
import org.apache.openejb.jee.AroundInvoke;
import org.apache.openejb.jee.AroundTimeout;
import org.apache.openejb.jee.AssemblyDescriptor;
import org.apache.openejb.jee.AsyncMethod;
import org.apache.openejb.jee.AuthenticationMechanism;
import org.apache.openejb.jee.Beans;
import org.apache.openejb.jee.ConcurrencyManagementType;
import org.apache.openejb.jee.ConcurrentLockType;
import org.apache.openejb.jee.ConcurrentMethod;
import org.apache.openejb.jee.ConfigProperty;
import org.apache.openejb.jee.ContainerConcurrency;
import org.apache.openejb.jee.ContainerTransaction;
import org.apache.openejb.jee.DataSource;
import org.apache.openejb.jee.EjbJar;
import org.apache.openejb.jee.EjbLocalRef;
import org.apache.openejb.jee.EjbRef;
import org.apache.openejb.jee.EjbReference;
import org.apache.openejb.jee.Empty;
import org.apache.openejb.jee.EnterpriseBean;
import org.apache.openejb.jee.EnvEntry;
import org.apache.openejb.jee.ExcludeList;
import org.apache.openejb.jee.FacesConfig;
import org.apache.openejb.jee.FacesManagedBean;
import org.apache.openejb.jee.Filter;
import org.apache.openejb.jee.Handler;
import org.apache.openejb.jee.HandlerChains;
import org.apache.openejb.jee.Icon;
import org.apache.openejb.jee.InboundResourceadapter;
import org.apache.openejb.jee.InitMethod;
import org.apache.openejb.jee.Injectable;
import org.apache.openejb.jee.InjectionTarget;
import org.apache.openejb.jee.Interceptor;
import org.apache.openejb.jee.InterceptorBinding;
import org.apache.openejb.jee.Invokable;
import org.apache.openejb.jee.IsolationLevel;
import org.apache.openejb.jee.JMSConnectionFactory;
import org.apache.openejb.jee.JMSDestination;
import org.apache.openejb.jee.JndiConsumer;
import org.apache.openejb.jee.JndiReference;
import org.apache.openejb.jee.License;
import org.apache.openejb.jee.Lifecycle;
import org.apache.openejb.jee.LifecycleCallback;
import org.apache.openejb.jee.Listener;
import org.apache.openejb.jee.MessageAdapter;
import org.apache.openejb.jee.MessageDrivenBean;
import org.apache.openejb.jee.MessageListener;
import org.apache.openejb.jee.MethodAttribute;
import org.apache.openejb.jee.MethodParams;
import org.apache.openejb.jee.MethodPermission;
import org.apache.openejb.jee.NamedMethod;
import org.apache.openejb.jee.OutboundResourceAdapter;
import org.apache.openejb.jee.ParamValue;
import org.apache.openejb.jee.PersistenceContextRef;
import org.apache.openejb.jee.PersistenceContextSynchronization;
import org.apache.openejb.jee.PersistenceContextType;
import org.apache.openejb.jee.PersistenceUnitRef;
import org.apache.openejb.jee.PortComponent;
import org.apache.openejb.jee.Property;
import org.apache.openejb.jee.RemoteBean;
import org.apache.openejb.jee.RemoveMethod;
import org.apache.openejb.jee.ResAuth;
import org.apache.openejb.jee.ResSharingScope;
import org.apache.openejb.jee.ResourceAdapter;
import org.apache.openejb.jee.ResourceEnvRef;
import org.apache.openejb.jee.ResourceRef;
import org.apache.openejb.jee.SecurityIdentity;
import org.apache.openejb.jee.SecurityRoleRef;
import org.apache.openejb.jee.ServiceRef;
import org.apache.openejb.jee.Servlet;
import org.apache.openejb.jee.ServletMapping;
import org.apache.openejb.jee.Session;
import org.apache.openejb.jee.SessionBean;
import org.apache.openejb.jee.SessionType;
import org.apache.openejb.jee.SingletonBean;
import org.apache.openejb.jee.StatefulBean;
import org.apache.openejb.jee.StatelessBean;
import org.apache.openejb.jee.Tag;
import org.apache.openejb.jee.Text;
import org.apache.openejb.jee.Timeout;
import org.apache.openejb.jee.Timer;
import org.apache.openejb.jee.TimerConsumer;
import org.apache.openejb.jee.TimerSchedule;
import org.apache.openejb.jee.TldTaglib;
import org.apache.openejb.jee.TransAttribute;
import org.apache.openejb.jee.TransactionSupportType;
import org.apache.openejb.jee.TransactionType;
import org.apache.openejb.jee.WebApp;
import org.apache.openejb.jee.WebserviceDescription;
import org.apache.openejb.jee.oejb3.OpenejbJar;
import org.apache.openejb.loader.JarLocation;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.util.Classes;
import org.apache.openejb.util.Join;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
import org.apache.openejb.util.SuperProperties;
import org.apache.openejb.util.URLs;
import org.apache.openejb.util.proxy.DynamicProxyImplFactory;
import org.apache.xbean.finder.Annotated;
import org.apache.xbean.finder.AnnotationFinder;
import org.apache.xbean.finder.IAnnotationFinder;
import org.apache.xbean.finder.MetaAnnotatedClass;
import org.apache.xbean.finder.archive.Archive;
import org.apache.xbean.finder.archive.ClassesArchive;

import javax.annotation.ManagedBean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.annotation.Resources;
import javax.annotation.security.DeclareRoles;
import javax.annotation.security.DenyAll;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.annotation.security.RunAs;
import javax.annotation.sql.DataSourceDefinition;
import javax.annotation.sql.DataSourceDefinitions;
import javax.decorator.Decorator;
import javax.decorator.Delegate;
import javax.ejb.AccessTimeout;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.AfterBegin;
import javax.ejb.AfterCompletion;
import javax.ejb.ApplicationException;
import javax.ejb.Asynchronous;
import javax.ejb.BeforeCompletion;
import javax.ejb.ConcurrencyManagement;
import javax.ejb.DependsOn;
import javax.ejb.EJB;
import javax.ejb.EJBHome;
import javax.ejb.EJBLocalHome;
import javax.ejb.EJBLocalObject;
import javax.ejb.EJBObject;
import javax.ejb.EJBs;
import javax.ejb.Init;
import javax.ejb.Local;
import javax.ejb.LocalBean;
import javax.ejb.LocalHome;
import javax.ejb.Lock;
import javax.ejb.LockType;
import javax.ejb.MessageDriven;
import javax.ejb.PostActivate;
import javax.ejb.PrePassivate;
import javax.ejb.Remote;
import javax.ejb.RemoteHome;
import javax.ejb.Remove;
import javax.ejb.Schedule;
import javax.ejb.Schedules;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.Stateful;
import javax.ejb.StatefulTimeout;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.ConversationScoped;
import javax.enterprise.context.Dependent;
import javax.enterprise.context.NormalScope;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.inject.Model;
import javax.enterprise.inject.Produces;
import javax.enterprise.inject.Stereotype;
import javax.enterprise.inject.spi.DefinitionException;
import javax.enterprise.inject.spi.Extension;
import javax.inject.Inject;
import javax.interceptor.ExcludeClassInterceptors;
import javax.interceptor.ExcludeDefaultInterceptors;
import javax.interceptor.Interceptors;
import javax.jms.JMSConnectionFactoryDefinition;
import javax.jms.JMSConnectionFactoryDefinitions;
import javax.jms.JMSDestinationDefinition;
import javax.jms.JMSDestinationDefinitions;
import javax.jms.Queue;
import javax.jws.HandlerChain;
import javax.jws.WebService;
import javax.persistence.Converter;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.MappedSuperclass;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContexts;
import javax.persistence.PersistenceUnit;
import javax.persistence.PersistenceUnits;
import javax.resource.spi.Activation;
import javax.resource.spi.AdministeredObject;
import javax.resource.spi.ConnectionDefinition;
import javax.resource.spi.ConnectionDefinitions;
import javax.resource.spi.Connector;
import javax.resource.spi.SecurityPermission;
import javax.resource.spi.work.WorkContext;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;
import javax.ws.rs.ext.Provider;
import javax.xml.ws.Service;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.WebServiceRef;
import javax.xml.ws.WebServiceRefs;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;

import static java.util.Arrays.asList;

/**
 * @version $Rev$ $Date$
 */
public class AnnotationDeployer implements DynamicDeployer {
    public static final Logger logger = Logger.getInstance(LogCategory.OPENEJB_STARTUP, AnnotationDeployer.class.getPackage().getName());
    public static final Logger startupLogger = Logger.getInstance(LogCategory.OPENEJB_STARTUP_CONFIG, "org.apache.openejb.util.resources");

    public static final String OPENEJB_JPA_AUTO_SCAN = "openejb.jpa.auto-scan";
    public static final String OPENEJB_JPA_AUTO_SCAN_PACKAGE = "openejb.jpa.auto-scan.package";

    private static final ThreadLocal<DeploymentModule> currentModule = new ThreadLocal<DeploymentModule>();
    private static final Set<String> lookupMissing = new HashSet<String>(2);
    private static final String[] JSF_CLASSES = new String[]{
        "javax.faces.application.ResourceDependencies",
        "javax.faces.application.ResourceDependency",
        "javax.faces.bean.ApplicationScoped",
        "javax.faces.bean.CustomScoped",
        "javax.faces.bean.ManagedBean",
        "javax.faces.bean.ManagedProperty",
        "javax.faces.bean.NoneScoped",
        "javax.faces.bean.ReferencedBean",
        "javax.faces.bean.RequestScoped",
        "javax.faces.bean.SessionScoped",
        "javax.faces.bean.ViewScoped",
        "javax.faces.component.FacesComponent",
        "javax.faces.component.UIComponent",
        "javax.faces.convert.Converter",
        "javax.faces.convert.FacesConverter",
        "javax.faces.event.ListenerFor",
        "javax.faces.event.ListenersFor",
        "javax.faces.event.NamedEvent",
        "javax.faces.render.FacesBehaviorRenderer",
        "javax.faces.render.FacesRenderer",
        "javax.faces.render.Renderer",
        "javax.faces.validator.FacesValidator",
        "javax.faces.validator.Validator"
    };

    private static final String[] WEB_CLASSES = new String[]{
        // Servlet 3.0
        "javax.servlet.annotation.WebServlet",
        "javax.servlet.annotation.WebFilter",
        "javax.servlet.annotation.WebListener",

        // WebSocket 1.0 (since Tomcat 7.0.47)
        "javax.websocket.server.ServerEndpoint",
        "javax.websocket.server.ServerApplicationConfig",
        "javax.websocket.Endpoint"
    };

    private static final Collection<String> API_CLASSES = new ArrayList<String>(WEB_CLASSES.length + JSF_CLASSES.length);

    static {
        API_CLASSES.addAll(Arrays.asList(JSF_CLASSES));
        API_CLASSES.addAll(Arrays.asList(WEB_CLASSES));
    }

    public static final Set<String> knownResourceEnvTypes = new TreeSet<String>(Arrays.asList(
        "javax.ejb.EJBContext",
        "javax.ejb.SessionContext",
        "javax.ejb.EntityContext",
        "javax.ejb.MessageDrivenContext",
        "javax.transaction.UserTransaction",
        "javax.jms.Queue",
        "javax.jms.Topic",
        "javax.xml.ws.WebServiceContext",
        "javax.ejb.TimerService",
        "javax.enterprise.inject.spi.BeanManager",
        "javax.validation.Validator",
        "javax.validation.ValidatorFactory"
    ));

    public static final Set<String> knownEnvironmentEntries = new TreeSet<String>(Arrays.asList(
        "boolean", "java.lang.Boolean",
        "char", "java.lang.Character",
        "byte", "java.lang.Byte",
        "short", "java.lang.Short",
        "int", "java.lang.Integer",
        "long", "java.lang.Long",
        "float", "java.lang.Float",
        "double", "java.lang.Double",
        "java.lang.String",
        "java.lang.Class"
    ));

    private final DiscoverAnnotatedBeans discoverAnnotatedBeans;
    private final ProcessAnnotatedBeans processAnnotatedBeans;
    private final EnvEntriesPropertiesDeployer envEntriesPropertiesDeployer;
    private final MBeanDeployer mBeanDeployer;
    private final BuiltInEnvironmentEntries builtInEnvironmentEntries;
    private final MergeWebappJndiContext mergeWebappJndiContext;

    public AnnotationDeployer() {
        discoverAnnotatedBeans = new DiscoverAnnotatedBeans();
        processAnnotatedBeans = new ProcessAnnotatedBeans(SystemInstance.get().getOptions().get("openejb.jaxws.add-remote", false));
        builtInEnvironmentEntries = new BuiltInEnvironmentEntries(SystemInstance.get().getOptions().get("openejb.environment.default", false));
        envEntriesPropertiesDeployer = new EnvEntriesPropertiesDeployer();
        mBeanDeployer = new MBeanDeployer();
        mergeWebappJndiContext = new MergeWebappJndiContext();
    }

    public AppModule deploy(AppModule appModule) throws OpenEJBException {
        final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(appModule.getClassLoader());
        setModule(appModule);
        try {
            appModule = discoverAnnotatedBeans.deploy(appModule);
            appModule = envEntriesPropertiesDeployer.deploy(appModule);
            appModule = mergeWebappJndiContext.deploy(appModule);
            appModule = builtInEnvironmentEntries.deploy(appModule);
            appModule = processAnnotatedBeans.deploy(appModule);
            appModule = mergeWebappJndiContext.deploy(appModule);
            appModule = mBeanDeployer.deploy(appModule);
            return appModule;
        } finally {
            envEntriesPropertiesDeployer.resetAdditionalEnvEntries();
            Thread.currentThread().setContextClassLoader(classLoader);
            removeModule();
        }
    }

    // TODO Remove this section.  It's called by some code in the assembler.
    // The scanning portion should be completed prior to this point
    public void deploy(final CdiBeanInfo beanInfo) throws OpenEJBException {
        this.processAnnotatedBeans.deploy(beanInfo);
    }

    public WebModule deploy(WebModule webModule) throws OpenEJBException {
        setModule(webModule);
        final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(webModule.getClassLoader());
        try {
            webModule = discoverAnnotatedBeans.deploy(webModule);
            webModule = envEntriesPropertiesDeployer.deploy(webModule);
            webModule = processAnnotatedBeans.deploy(webModule);
            return webModule;
        } finally {
            envEntriesPropertiesDeployer.resetAdditionalEnvEntries();
            Thread.currentThread().setContextClassLoader(classLoader);
            removeModule();
        }
    }

    public static DeploymentModule getModule() {
        return currentModule.get();
    }

    private static void setModule(final DeploymentModule module) {
        currentModule.set(module);
    }

    private static void removeModule() {
        currentModule.remove();
    }

    private static ValidationContext getValidationContext() {
        return getModule().getValidation();
    }

    private static void mergeApplicationExceptionAnnotation(final AssemblyDescriptor assemblyDescriptor, final Class<?> exceptionClass, final ApplicationException annotation) {
        final org.apache.openejb.jee.ApplicationException applicationException = assemblyDescriptor.getApplicationException(exceptionClass);
        if (applicationException.getRollback() == null) {
            applicationException.setRollback(annotation.rollback());
        }
        if (applicationException.getInherited() == null) {
            applicationException.setInherited(annotation.inherited());
        }
    }

    public static boolean isKnownEnvironmentEntryType(final Class type) {
        return knownEnvironmentEntries.contains(type.getName()) || type.isEnum();
    }

    public static boolean isShareableJNDINamespace(final String jndiName) {
        return jndiName.startsWith("java:global/") || jndiName.startsWith("java:app/") || jndiName.startsWith("java:module/");
    }

    public static class DiscoverAnnotatedBeans implements DynamicDeployer {
        public AppModule deploy(AppModule appModule) throws OpenEJBException {
            if (!appModule.isWebapp() && !appModule.getWebModules().isEmpty()) { // need to scan for jsf stuff at least
                try {
                    appModule.setEarLibFinder(FinderFactory.createFinder(appModule));
                } catch (final Exception e) {
                    logger.error("Can't create a finder for ear libs", e);
                }
            }

            for (final EjbModule ejbModule : appModule.getEjbModules()) {
                ejbModule.initAppModule(appModule);
                setModule(ejbModule);
                try {
                    deploy(ejbModule);
                } finally {
                    removeModule();
                }
            }
            for (final ClientModule clientModule : appModule.getClientModules()) {
                clientModule.initAppModule(appModule);
                setModule(clientModule);
                try {
                    deploy(clientModule);
                } finally {
                    removeModule();
                }
            }
            for (final ConnectorModule connectorModule : appModule.getConnectorModules()) {
                connectorModule.initAppModule(appModule);
                setModule(connectorModule);
                try {
                    deploy(connectorModule);
                } finally {
                    removeModule();
                }
            }
            for (final WebModule webModule : appModule.getWebModules()) { // here we scan by inheritance so great to keep it last
                webModule.initAppModule(appModule);
                setModule(webModule);
                try {
                    deploy(webModule);
                } finally {
                    removeModule();
                }
            }
            final AdditionalBeanDiscoverer discoverer = SystemInstance.get().getComponent(AdditionalBeanDiscoverer.class);
            if (discoverer != null) {
                appModule = discoverer.discover(appModule);
            }
            return appModule;
        }

        public ClientModule deploy(final ClientModule clientModule) throws OpenEJBException {

            if (clientModule.getApplicationClient() == null) {
                clientModule.setApplicationClient(new ApplicationClient());
            }

            // Lots of jars have main classes so this might not even be an app client.
            // We're not going to scrape it for @LocalClient or @RemoteClient annotations
            // unless they flag us specifically by adding a META-INF/application-client.xml
            //
            // ClientModules that already have a AnnotationFinder have been generated automatically
            // from an EjbModule, so we don't skip those ever.
            if (clientModule.getFinder() == null && clientModule.getAltDDs().containsKey("application-client.xml")) {
                if (clientModule.getApplicationClient() != null && clientModule.getApplicationClient().isMetadataComplete()) {
                    return clientModule;
                }
            }


            IAnnotationFinder finder = clientModule.getFinder();

            if (finder == null) {
                try {
                    finder = FinderFactory.createFinder(clientModule);
                } catch (final MalformedURLException e) {
                    startupLogger.warning("startup.scrapeFailedForClientModule.url", clientModule.getJarLocation());
                    return clientModule;
                } catch (final Exception e) {
                    startupLogger.warning("startup.scrapeFailedForClientModule", e, clientModule.getJarLocation());
                    return clientModule;
                }
            }

            // This method is also called by the deploy(EjbModule) method to see if those
            // modules have any @LocalClient or @RemoteClient classes
            for (final Annotated<Class<?>> clazz : finder.findMetaAnnotatedClasses(LocalClient.class)) {
                clientModule.getLocalClients().add(clazz.get().getName());
            }

            for (final Annotated<Class<?>> clazz : finder.findMetaAnnotatedClasses(RemoteClient.class)) {
                clientModule.getRemoteClients().add(clazz.get().getName());
            }

            if (clientModule.getApplicationClient() == null) {
                if (clientModule.getRemoteClients().size() > 0 || clientModule.getLocalClients().size() > 0) {
                    clientModule.setApplicationClient(new ApplicationClient());
                }
            }

            return clientModule;
        }

        public ConnectorModule deploy(final ConnectorModule connectorModule) throws OpenEJBException {

            org.apache.openejb.jee.Connector connector = connectorModule.getConnector();
            if (connector == null) {
                connector = new org.apache.openejb.jee.Connector();
            }

            // JCA 1.6 - 18.3.1 do not look at annotations if the provided connector
            // deployment descriptor is "meta-data complete".

            float specVersion = 0;
            try {
                specVersion = Float.parseFloat(connector.getVersion());
            } catch (final Exception e) {
                // no-op
            }

            if (specVersion < 1.6 || Boolean.TRUE.equals(connector.isMetadataComplete())) {
                return connectorModule;
            }


            IAnnotationFinder finder = connectorModule.getFinder();
            if (finder == null) {
                try {
                    finder = FinderFactory.createFinder(connectorModule);
                    connectorModule.setFinder(finder);
                } catch (final Exception e) {
                    // TODO: some sort of error
                    return connectorModule;
                }
            }

            final List<Class<?>> connectorClasses = finder.findAnnotatedClasses(Connector.class);

            // are we allowed to have more than one connector class? Not without a deployment descriptor
            if (connector.getResourceAdapter() == null || connector.getResourceAdapter().getResourceAdapterClass() == null || connector.getResourceAdapter().getResourceAdapterClass().length() == 0) {
                if (connectorClasses.size() == 0) { //NOPMD
                    // TODO: fail some validation here too
                }

                if (connectorClasses.size() > 1) { //NOPMD
                    // too many connector classes, this is against the spec
                    // TODO: something like connectorModule.getValidation().fail(ejbName, "abstractAnnotatedAsBean", annotationClass.getSimpleName(), beanClass.get().getName());
                }
            }

            Class<?> connectorClass = null;
            if (connectorClasses.size() == 1) {
                connectorClass = connectorClasses.get(0);
            }

            if (connectorClasses.size() > 1) {
                for (final Class<?> cls : connectorClasses) {
                    if (cls.getName().equals(connector.getResourceAdapter().getResourceAdapterClass())) {
                        connectorClass = cls;
                        break;
                    }
                }
            }

            if (connectorClass != null) {
                if (connector.getResourceAdapter() == null) {
                    connector.setResourceAdapter(new ResourceAdapter());
                }

                if (connector.getResourceAdapter().getResourceAdapterClass() == null || connector.getResourceAdapter().getResourceAdapterClass().length() == 0) {
                    connector.getResourceAdapter().setResourceAdapterClass(connectorClass.getName());
                }

                final Connector connectorAnnotation = connectorClass.getAnnotation(Connector.class);

                connector.setDisplayNames(getTexts(connector.getDisplayNames(), connectorAnnotation.displayName()));
                connector.setDescriptions(getTexts(connector.getDescriptions(), connectorAnnotation.description()));

                connector.setEisType(getString(connector.getEisType(), connectorAnnotation.eisType()));
                connector.setVendorName(getString(connector.getVendorName(), connectorAnnotation.vendorName()));
                connector.setResourceAdapterVersion(getString(connector.getResourceAdapterVersion(), connectorAnnotation.version()));

                if (connector.getIcons().isEmpty()) {
                    final int smallIcons = connectorAnnotation.smallIcon().length;
                    final int largeIcons = connectorAnnotation.largeIcon().length;

                    for (int i = 0; i < smallIcons && i < largeIcons; i++) {
                        final Icon icon = new Icon();
                        // locale can't be specified in the annotation and it is en by default
                        // so on other systems it doesn't work because Icon return the default locale
                        icon.setLang(Locale.getDefault().getLanguage());
                        if (i < smallIcons) {
                            icon.setSmallIcon(connectorAnnotation.smallIcon()[i]);
                        }

                        if (i < largeIcons) {
                            icon.setLargeIcon(connectorAnnotation.largeIcon()[i]);
                        }

                        connector.getIcons().add(icon);
                    }
                }

                if (connector.getLicense() == null) {
                    final License license = new License();
                    connector.setLicense(license);
                    license.setLicenseRequired(connectorAnnotation.licenseRequired());
                }

                connector.getLicense().setDescriptions(getTexts(connector.getLicense().getDescriptions(), connectorAnnotation.licenseDescription()));


                final SecurityPermission[] annotationSecurityPermissions = connectorAnnotation.securityPermissions();
                final List<org.apache.openejb.jee.SecurityPermission> securityPermission = connector.getResourceAdapter().getSecurityPermission();
                if (securityPermission == null || securityPermission.size() == 0) {
                    for (final SecurityPermission sp : annotationSecurityPermissions) {
                        final org.apache.openejb.jee.SecurityPermission permission = new org.apache.openejb.jee.SecurityPermission();
                        permission.setSecurityPermissionSpec(sp.permissionSpec());
                        permission.setDescriptions(stringsToTexts(sp.description()));
                        securityPermission.add(permission);
                    }
                }

                final Class<? extends WorkContext>[] annotationRequiredWorkContexts = connectorAnnotation.requiredWorkContexts();
                final List<String> requiredWorkContext = connector.getRequiredWorkContext();
                if (requiredWorkContext.size() == 0) {
                    for (final Class<? extends WorkContext> cls : annotationRequiredWorkContexts) {
                        requiredWorkContext.add(cls.getName());
                    }
                }

                OutboundResourceAdapter outboundResourceAdapter = connector.getResourceAdapter().getOutboundResourceAdapter();
                if (outboundResourceAdapter == null) {
                    outboundResourceAdapter = new OutboundResourceAdapter();
                    connector.getResourceAdapter().setOutboundResourceAdapter(outboundResourceAdapter);
                }

                final List<AuthenticationMechanism> authenticationMechanisms = outboundResourceAdapter.getAuthenticationMechanism();
                final javax.resource.spi.AuthenticationMechanism[] authMechanisms = connectorAnnotation.authMechanisms();
                if (authenticationMechanisms.size() == 0) {
                    for (final javax.resource.spi.AuthenticationMechanism am : authMechanisms) {
                        final AuthenticationMechanism authMechanism = new AuthenticationMechanism();
                        authMechanism.setAuthenticationMechanismType(am.authMechanism());
                        authMechanism.setCredentialInterface(am.credentialInterface().toString());
                        authMechanism.setDescriptions(stringsToTexts(am.description()));

                        authenticationMechanisms.add(authMechanism);
                    }
                }

                if (outboundResourceAdapter.getTransactionSupport() == null) {
                    outboundResourceAdapter.setTransactionSupport(TransactionSupportType.fromValue(connectorAnnotation.transactionSupport().toString()));
                }

                if (outboundResourceAdapter.isReauthenticationSupport() == null) {
                    outboundResourceAdapter.setReauthenticationSupport(connectorAnnotation.reauthenticationSupport());
                }
            }

            // process @ConnectionDescription(s)
            List<Class<?>> classes = finder.findAnnotatedClasses(ConnectionDefinitions.class);
            for (final Class<?> cls : classes) {
                final ConnectionDefinitions connectionDefinitionsAnnotation = cls.getAnnotation(ConnectionDefinitions.class);
                final ConnectionDefinition[] definitions = connectionDefinitionsAnnotation.value();

                for (final ConnectionDefinition definition : definitions) {
                    processConnectionDescription(connector.getResourceAdapter(), definition, cls);
                }
            }

            classes = finder.findAnnotatedClasses(ConnectionDefinition.class);
            for (final Class<?> cls : classes) {
                final ConnectionDefinition connectionDefinitionAnnotation = cls.getAnnotation(ConnectionDefinition.class);
                processConnectionDescription(connector.getResourceAdapter(), connectionDefinitionAnnotation, cls);
            }


            InboundResourceadapter inboundResourceAdapter = connector.getResourceAdapter().getInboundResourceAdapter();
            if (inboundResourceAdapter == null) {
                inboundResourceAdapter = new InboundResourceadapter();
                connector.getResourceAdapter().setInboundResourceAdapter(inboundResourceAdapter);
            }

            MessageAdapter messageAdapter = inboundResourceAdapter.getMessageAdapter();
            if (messageAdapter == null) {
                messageAdapter = new MessageAdapter();
                inboundResourceAdapter.setMessageAdapter(messageAdapter);
            }

            classes = finder.findAnnotatedClasses(Activation.class);
            for (final Class<?> cls : classes) {
                MessageListener messageListener = null;
                final Activation activationAnnotation = cls.getAnnotation(Activation.class);

                final List<MessageListener> messageListeners = messageAdapter.getMessageListener();
                for (final MessageListener ml : messageListeners) {
                    if (cls.getName().equals(ml.getActivationSpec().getActivationSpecClass())) {
                        messageListener = ml;
                        break;
                    }
                }

                if (messageListener == null) {
                    final Class<?>[] listeners = activationAnnotation.messageListeners();
                    for (final Class<?> listener : listeners) {
                        messageAdapter.addMessageListener(new MessageListener(listener.getName(), cls.getName()));
                    }
                }
            }

            classes = finder.findAnnotatedClasses(AdministeredObject.class);
            final List<AdminObject> adminObjects = connector.getResourceAdapter().getAdminObject();
            for (final Class<?> cls : classes) {
                final AdministeredObject administeredObjectAnnotation = cls.getAnnotation(AdministeredObject.class);
                final Class[] adminObjectInterfaces = administeredObjectAnnotation.adminObjectInterfaces();

                AdminObject adminObject = null;
                for (final AdminObject admObj : adminObjects) {
                    if (admObj.getAdminObjectClass().equals(cls.getName())) {
                        adminObject = admObj;
                    }
                }

                if (adminObject == null) {
                    for (final Class iface : adminObjectInterfaces) {
                        final AdminObject newAdminObject = new AdminObject();
                        newAdminObject.setAdminObjectClass(cls.getName());
                        newAdminObject.setAdminObjectInterface(iface.getName());
                        adminObjects.add(newAdminObject);
                    }
                }
            }

            // need to make a list of classes to process for config properties

            // resource adapter
            final String raCls = connector.getResourceAdapter().getResourceAdapterClass();
            process(connectorModule.getClassLoader(), raCls, connector.getResourceAdapter());

            // managedconnectionfactory
            if (connector.getResourceAdapter() != null && connector.getResourceAdapter().getOutboundResourceAdapter() != null) {
                final List<org.apache.openejb.jee.ConnectionDefinition> connectionDefinitions = connector.getResourceAdapter().getOutboundResourceAdapter().getConnectionDefinition();
                for (final org.apache.openejb.jee.ConnectionDefinition connectionDefinition : connectionDefinitions) {
                    process(connectorModule.getClassLoader(), connectionDefinition.getManagedConnectionFactoryClass(), connectionDefinition);
                }
            }

            // administeredobject
            if (connector.getResourceAdapter() != null) {
                final List<AdminObject> raAdminObjects = connector.getResourceAdapter().getAdminObject();
                for (final AdminObject raAdminObject : raAdminObjects) {
                    process(connectorModule.getClassLoader(), raAdminObject.getAdminObjectClass(), raAdminObject);
                }
            }

            // activationspec
            if (connector.getResourceAdapter() != null && connector.getResourceAdapter().getInboundResourceAdapter() != null && connector.getResourceAdapter().getInboundResourceAdapter().getMessageAdapter() != null) {
                final List<MessageListener> messageListeners = connector.getResourceAdapter().getInboundResourceAdapter().getMessageAdapter().getMessageListener();
                for (final MessageListener messageListener : messageListeners) {
                    final ActivationSpec activationSpec = messageListener.getActivationSpec();
                    process(connectorModule.getClassLoader(), activationSpec.getActivationSpecClass(), activationSpec);
                }
            }

            return connectorModule;
        }

        void process(final ClassLoader cl, final String cls, final Object object) {

            List<ConfigProperty> configProperties = null;
            try {
                // grab a list of ConfigProperty objects
                configProperties = (List<ConfigProperty>) object.getClass().getDeclaredMethod("getConfigProperty").invoke(object);
            } catch (final Exception e) {
                // no-op
            }

            if (configProperties == null) {
                // can't get config properties
                return;
            }

            ClassLoader classLoader = cl;
            if (classLoader == null) {
                classLoader = Thread.currentThread().getContextClassLoader();
            }

            final List<String> allowedTypes = Arrays.asList(new String[]{Boolean.class.getName(), String.class.getName(), Integer.class.getName(), Double.class.getName(), Byte.class.getName(), Short.class.getName(), Long.class.getName(), Float.class.getName(), Character.class.getName()});

            try {
                final Class<?> clazz = classLoader.loadClass(realClassName(cls));
                final Object o = clazz.newInstance();

                // add any introspected properties
                final BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
                final PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

                for (final PropertyDescriptor propertyDescriptor : propertyDescriptors) {
                    final String name = propertyDescriptor.getName();
                    Class<?> type = propertyDescriptor.getPropertyType();
                    if (type == null) {
                        continue;
                    }
                    if (type.isPrimitive()) {
                        type = getWrapper(type.getName());
                    }

                    if (!allowedTypes.contains(type.getName())) {
                        continue;
                    }

                    if (!containsConfigProperty(configProperties, name)) {
                        final ConfigProperty configProperty = new ConfigProperty();
                        configProperties.add(configProperty);

                        Object value = null;
                        if (propertyDescriptor.getReadMethod() != null) {
                            try {
                                value = propertyDescriptor.getReadMethod().invoke(o);
                            } catch (final Exception e) {
                                // no-op
                            }
                        }

                        final Method write = propertyDescriptor.getWriteMethod();
                        javax.resource.spi.ConfigProperty annotation = null;
                        if (write != null) {
                            annotation = write.getAnnotation(javax.resource.spi.ConfigProperty.class);
                            if (annotation == null) {
                                try {
                                    // if there's no annotation on the setter, we'll try and scrape one off the field itself (assuming the same name)
                                    annotation = clazz.getDeclaredField(name).getAnnotation(javax.resource.spi.ConfigProperty.class);
                                } catch (final Exception ignored) {
                                    // no-op : getDeclaredField() throws exceptions and does not return null
                                }
                            }
                        }

                        configProperty.setConfigPropertyName(name);
                        configProperty.setConfigPropertyType(getConfigPropertyType(annotation, type));
                        if (value != null) {
                            configProperty.setConfigPropertyValue(value.toString());
                        }

                        if (annotation != null) {
                            if (annotation.defaultValue() != null && annotation.defaultValue().length() > 0) {
                                configProperty.setConfigPropertyValue(annotation.defaultValue());
                            }
                            configProperty.setConfigPropertyConfidential(annotation.confidential());
                            configProperty.setConfigPropertyIgnore(annotation.ignore());
                            configProperty.setConfigPropertySupportsDynamicUpdates(annotation.supportsDynamicUpdates());
                            configProperty.setDescriptions(stringsToTexts(annotation.description()));
                        }
                    }
                }

                // add any annotated fields we haven't already picked up
                final Field[] declaredFields = clazz.getDeclaredFields();
                for (final Field field : declaredFields) {
                    final javax.resource.spi.ConfigProperty annotation = field.getAnnotation(javax.resource.spi.ConfigProperty.class);

                    final String name = field.getName();
                    Object value = null;
                    try {
                        value = field.get(o);
                    } catch (final Exception e) {
                        // no-op
                    }

                    if (!containsConfigProperty(configProperties, name)) {
                        final String type = getConfigPropertyType(annotation, field.getType());

                        if (type != null) {
                            final ConfigProperty configProperty = new ConfigProperty();
                            configProperties.add(configProperty);

                            configProperty.setConfigPropertyName(name);
                            configProperty.setConfigPropertyType(type);
                            if (value != null) {
                                configProperty.setConfigPropertyValue(value.toString());
                            }

                            if (annotation != null) {
                                if (annotation.defaultValue() != null) {
                                    configProperty.setConfigPropertyValue(annotation.defaultValue());
                                }
                                configProperty.setConfigPropertyConfidential(annotation.confidential());
                                configProperty.setConfigPropertyIgnore(annotation.ignore());
                                configProperty.setConfigPropertySupportsDynamicUpdates(annotation.supportsDynamicUpdates());
                            }
                        }
                    }
                }
            } catch (final Exception e) {
                e.printStackTrace();
            }
        }

        private String getConfigPropertyType(final javax.resource.spi.ConfigProperty annotation, final Class<?> type) {
            Class<?> t = annotation == null ? null : annotation.type();
            if (t == null && type != null) {
                return type.getName();
            } else if (t == null) {
                return null;
            }

            if (t.equals(Object.class)) {
                t = type;
            }
            if (t == null) { // t == null && type == null
                return null;
            }

            if (t.isPrimitive()) {
                t = getWrapper(t.getName());
            }

            return t.getName();
        }

        private boolean containsConfigProperty(final List<ConfigProperty> configProperties, final String name) {
            for (final ConfigProperty configProperty : configProperties) {
                if (configProperty.getConfigPropertyName().equals(name)) {
                    return true;
                }
            }

            return false;
        }

        private Class<?> getWrapper(final String primitiveType) {
            final Map<String, Class<?>> builtInMap = new HashMap<>();
            {
                builtInMap.put("int", Integer.class);
                builtInMap.put("long", Long.class);
                builtInMap.put("double", Double.class);
                builtInMap.put("float", Float.class);
                builtInMap.put("boolean", Boolean.class);
                builtInMap.put("char", Character.class);
                builtInMap.put("byte", Byte.class);
                builtInMap.put("void", Void.class);
                builtInMap.put("short", Short.class);
            }

            return builtInMap.get(primitiveType);
        }

        private void processConnectionDescription(final ResourceAdapter resourceAdapter, final ConnectionDefinition connectionDefinitionAnnotation, final Class<?> cls) {
            // try and find the managed connection factory

            OutboundResourceAdapter outboundResourceAdapter = resourceAdapter.getOutboundResourceAdapter();
            if (outboundResourceAdapter == null) {
                outboundResourceAdapter = new OutboundResourceAdapter();
                resourceAdapter.setOutboundResourceAdapter(outboundResourceAdapter);
            }

            final List<org.apache.openejb.jee.ConnectionDefinition> connectionDefinition = outboundResourceAdapter.getConnectionDefinition();

            org.apache.openejb.jee.ConnectionDefinition definition = null;
            for (final org.apache.openejb.jee.ConnectionDefinition cd : connectionDefinition) {
                if (cd.getManagedConnectionFactoryClass().equals(cls.getName())) {
                    definition = cd;
                    break;
                }
            }

            if (definition == null) {
                definition = new org.apache.openejb.jee.ConnectionDefinition();
                outboundResourceAdapter.getConnectionDefinition().add(definition);
            }

            if (definition.getManagedConnectionFactoryClass() == null) {
                definition.setManagedConnectionFactoryClass(cls.getName());
            }

            if (definition.getConnectionInterface() == null) {
                definition.setConnectionInterface(connectionDefinitionAnnotation.connection().getName());
            }

            if (definition.getConnectionImplClass() == null) {
                definition.setConnectionImplClass(connectionDefinitionAnnotation.connectionImpl().getName());
            }

            if (definition.getConnectionFactoryInterface() == null) {
                definition.setConnectionFactoryInterface(connectionDefinitionAnnotation.connectionFactory().getName());
            }

            if (definition.getConnectionFactoryImplClass() == null) {
                definition.setConnectionFactoryImplClass(connectionDefinitionAnnotation.connectionFactoryImpl().getName());
            }
        }

        private Text[] stringsToTexts(final String[] strings) {
            if (strings == null) {
                return null;
            }

            final Text[] result = new Text[strings.length];
            for (int i = 0; i < result.length; i++) {
                result[i] = new Text();
                result[i].setValue(strings[i]);
            }

            return result;
        }

        private String getString(final String descriptorString, final String annotationString) {
            if (descriptorString != null && descriptorString.length() > 0) {
                return descriptorString;
            }

            if (annotationString != null && annotationString.length() > 0) {
                return annotationString;
            }

            return null;
        }

        private Text[] getTexts(final Text[] originalTexts, final String[] newStrings) {
            if (newStrings != null && newStrings.length > 0 && (originalTexts == null || originalTexts.length == 0)) {
                final Text[] texts = new Text[newStrings.length];
                for (int i = 0; i < newStrings.length; i++) {
                    texts[i] = new Text(null, newStrings[i]);
                }

                return texts;
            } else {
                return originalTexts;
            }
        }

        public WebModule deploy(final WebModule webModule) throws OpenEJBException {
            WebApp webApp = webModule.getWebApp();
            if (webApp != null && webApp.isMetadataComplete()) {
                return webModule;
            }

            try {
                if (webModule.getFinder() == null) {
                    webModule.setFinder(FinderFactory.createFinder(webModule));
                }
            } catch (final Exception e) {
                startupLogger.warning("Unable to scrape for @WebService or @WebServiceProvider annotations. AnnotationFinder failed.", e);
                return webModule;
            }

            if (webApp == null) {
                webApp = new WebApp();
                webModule.setWebApp(webApp);
            }

            final List<String> existingServlets = new ArrayList<>();
            for (final Servlet servlet : webApp.getServlet()) {
                if (servlet.getServletClass() != null) {
                    existingServlets.add(servlet.getServletClass());
                }
            }

            final IAnnotationFinder finder = webModule.getFinder();
            final List<Class> classes = new ArrayList<>();
            classes.addAll(finder.findAnnotatedClasses(WebService.class));
            classes.addAll(finder.findAnnotatedClasses(WebServiceProvider.class));

            for (final Class<?> webServiceClass : classes) {
                // If this class is also annotated @Stateless or @Singleton, we should skip it
                if (webServiceClass.isAnnotationPresent(Singleton.class) || webServiceClass.isAnnotationPresent(Stateless.class)) {
                    webModule.getEjbWebServices().add(webServiceClass.getName());
                    continue;
                }

                final int modifiers = webServiceClass.getModifiers();
                if (!Modifier.isPublic(modifiers) || Modifier.isFinal(modifiers) || Modifier.isAbstract(modifiers)) {
                    continue;
                }

                if (existingServlets.contains(webServiceClass.getName())) {
                    continue;
                }

                // create webApp and webservices objects if they don't exist already

                // add new <servlet/> element
                final Servlet servlet = new Servlet();
                servlet.setServletName(webServiceClass.getName());
                servlet.setServletClass(webServiceClass.getName());
                final ParamValue param = new ParamValue();
                param.setParamName("openejb-internal");
                param.setParamValue("true");
                servlet.getInitParam().add(param);
                webApp.getServlet().add(servlet);
            }

           /*
            * REST
            */
            boolean restHandledByTheWebApp;
            try {
                restHandledByTheWebApp = webModule.getClassLoader().loadClass(Application.class.getName()) != Application.class;
            } catch (final Throwable e) { // ClassNotFoundException or NoClassDefFoundError
                restHandledByTheWebApp = false;
            }

            if (!restHandledByTheWebApp) {
                // get by annotations
                webModule.getRestClasses().addAll(findRestClasses(webModule, finder));
                addJaxRsProviders(finder, webModule.getJaxrsProviders(), Provider.class);

                // Applications with a default constructor
                // findSubclasses will not work by default to gain a lot of time
                // look FinderFactory for the flag to activate it or
                // use @ApplicationPath("/")
                final List<Class<? extends Application>> applications = finder.findSubclasses(Application.class);
                for (final Class<? extends Application> app : applications) {
                    addRestApplicationIfPossible(webModule, app);
                }

                // look for ApplicationPath, it will often return the same than the previous one
                // but without finder.link() invocation it still works
                // so it can save a lot of startup time
                final List<Annotated<Class<?>>> applicationsByAnnotation = finder.findMetaAnnotatedClasses(ApplicationPath.class);
                for (final Annotated<Class<?>> annotatedApp : applicationsByAnnotation) {
                    final Class<?> app = annotatedApp.get();
                    if (!Application.class.isAssignableFrom(app)) {
                        logger.error("class '" + app.getName() + "' is annotated with @ApplicationPath but doesn't implement " + Application.class.getName());
                        continue;
                    }

                    addRestApplicationIfPossible(webModule, (Class<? extends Application>) app);
                }
            }

            /*
             * JSF
             */

            // we need to look for JSF stuff in ear libs (converters...) so get back the finder for this part
            IAnnotationFinder parentFinder = null;
            final AppModule appModule = webModule.getAppModule();
            if (appModule != null) {
                parentFinder = appModule.getEarLibFinder();
            }

            final ClassLoader classLoader = webModule.getClassLoader();
            for (final String jsfClass : JSF_CLASSES) {
                final Class<? extends Annotation> clazz;
                try {
                    clazz = (Class<? extends Annotation>) classLoader.loadClass(jsfClass);
                } catch (final ClassNotFoundException e) {
                    continue;
                }

                final Set<String> convertedClasses = new HashSet<>();

                if (parentFinder != null) {
                    final List<Annotated<Class<?>>> foundParent = parentFinder.findMetaAnnotatedClasses(clazz);
                    for (final Annotated<Class<?>> annotated : foundParent) {
                        convertedClasses.add(annotated.get().getName());
                    }

                    for (final EjbModule module : appModule.getEjbModules()) {
                        // if we are deplying a webapp we don't need to (re)do it
                        // or if this module is another webapp we don't need to look it
                        // otherwise that's a common part of ear we want to scan
                        if (appModule.isWebapp() || module.isWebapp() && !module.getModuleId().equals(webModule.getModuleId())) {
                            continue;
                        }

                        final List<Annotated<Class<?>>> ejbFound = module.getFinder().findMetaAnnotatedClasses(clazz);
                        for (final Annotated<Class<?>> annotated : ejbFound) {
                            convertedClasses.add(annotated.get().getName());
                        }
                    }
                }

                final List<Annotated<Class<?>>> found = finder.findMetaAnnotatedClasses(clazz);
                for (final Annotated<Class<?>> annotated : found) {
                    convertedClasses.add(annotated.get().getName());
                }

                webModule.getJsfAnnotatedClasses().put(jsfClass, convertedClasses);
            }

            /*
             * Servlet, Filter, Listener...
             * here we can scan by inheritance so do it last
             */

            Map<String, String> urlByClasses = null;
            for (final String apiClassName : WEB_CLASSES) {
                final Class<? extends Annotation> clazz;
                try {
                    clazz = (Class<? extends Annotation>) classLoader.loadClass(apiClassName);
                } catch (final ClassNotFoundException e) {
                    continue;
                }

                if (urlByClasses == null) { // try to reuse scanning info, maybe some better indexing can be a nice idea
                    urlByClasses = FinderFactory.urlByClass(finder);
                }

                final List<Annotated<Class<?>>> found = finder.findMetaAnnotatedClasses(clazz);
                addWebAnnotatedClassInfo(urlByClasses, webModule.getWebAnnotatedClasses(), found);
            }

            if (urlByClasses != null) {
                urlByClasses.clear();
            }

            return webModule;
        }

        private void addJaxRsProviders(final IAnnotationFinder finder, final Collection<String> set, final Class<? extends Annotation> annotation) {
            for (final Annotated<Class<?>> provider : finder.findMetaAnnotatedClasses(annotation)) {
                set.add(provider.get().getName());
            }
        }

        private static void addRestApplicationIfPossible(final WebModule webModule, final Class<? extends Application> app) {
            if (!isInstantiable(app)) {
                return;
            }

            if (app.getConstructors().length == 0) {
                webModule.getRestApplications().add(app.getName());
            } else {
                for (final Constructor<?> ctr : app.getConstructors()) {
                    if (ctr.getParameterTypes().length == 0) {
                        webModule.getRestApplications().add(app.getName());
                        break;
                    }
                }
            }
        }

        public EjbModule deploy(final EjbModule ejbModule) throws OpenEJBException {
            if (ejbModule.getEjbJar() != null && ejbModule.getEjbJar().isMetadataComplete()) {
                return ejbModule;
            }

            try {
                if (ejbModule.getFinder() == null) {
                    ejbModule.setFinder(FinderFactory.createFinder(ejbModule));
                }
            } catch (final MalformedURLException e) {
                startupLogger.warning("startup.scrapeFailedForModule", ejbModule.getJarLocation());
                return ejbModule;
            } catch (final Exception e) {
                startupLogger.warning("Unable to scrape for @Stateful, @Stateless, @Singleton or @MessageDriven annotations. AnnotationFinder failed.", e);
                return ejbModule;
            }

            final IAnnotationFinder finder = ejbModule.getFinder();

            // Fill in default sessionType for xml declared EJBs
            for (final EnterpriseBean bean : ejbModule.getEjbJar().getEnterpriseBeans()) {
                if (!(bean instanceof SessionBean)) {
                    continue;
                }

                final SessionBean sessionBean = (SessionBean) bean;

                if (sessionBean.getSessionType() != null) {
                    continue;
                }

                try {
                    final Class<?> clazz = ejbModule.getClassLoader().loadClass(bean.getEjbClass());
                    sessionBean.setSessionType(getSessionType(clazz));
                } catch (final Throwable handledInValidation) {
                    // no-op
                }
            }

            // Fill in default ejbName for xml declared EJBs
            for (final EnterpriseBean bean : ejbModule.getEjbJar().getEnterpriseBeans()) {
                if (bean.getEjbClass() == null) {
                    continue;
                }
                if (bean.getEjbName() == null || bean.getEjbName().startsWith("@NULL@")) {
                    ejbModule.getEjbJar().removeEnterpriseBean(bean.getEjbName());
                    try {
                        final Class<?> clazz = ejbModule.getClassLoader().loadClass(bean.getEjbClass());
                        final String ejbName = getEjbName(bean, clazz);
                        bean.setEjbName(ejbName);
                    } catch (final Throwable handledInValidation) {
                        // no-op
                    }
                    ejbModule.getEjbJar().addEnterpriseBean(bean);
                }
            }
            /* 19.2:  ejb-name: Default is the unqualified name of the bean class */

            final EjbJar ejbJar = ejbModule.getEjbJar();
            for (final Annotated<Class<?>> beanClass : finder.findMetaAnnotatedClasses(Singleton.class)) {
                final Singleton singleton = beanClass.getAnnotation(Singleton.class);
                final String ejbName = getEjbName(singleton, beanClass.get());

                if (!isValidEjbAnnotationUsage(Singleton.class, beanClass, ejbName, ejbModule)) {
                    continue;
                }

                EnterpriseBean enterpriseBean = ejbJar.getEnterpriseBean(ejbName);
                if (enterpriseBean == null) {
                    enterpriseBean = new SingletonBean(ejbName, beanClass.get());
                    ejbJar.addEnterpriseBean(enterpriseBean);
                }
                if (enterpriseBean.getEjbClass() == null) {
                    enterpriseBean.setEjbClass(beanClass.get());
                }
                if (enterpriseBean instanceof SessionBean) {
                    final SessionBean sessionBean = (SessionBean) enterpriseBean;
                    sessionBean.setSessionType(SessionType.SINGLETON);

                    if (singleton.mappedName() != null) {
                        sessionBean.setMappedName(singleton.mappedName());
                    }
                }
                LegacyProcessor.process(beanClass.get(), enterpriseBean);
            }

            for (final Annotated<Class<?>> beanClass : finder.findMetaAnnotatedClasses(Stateless.class)) {
                final Stateless stateless = beanClass.getAnnotation(Stateless.class);
                final String ejbName = getEjbName(stateless, beanClass.get());

                if (!isValidEjbAnnotationUsage(Stateless.class, beanClass, ejbName, ejbModule)) {
                    continue;
                }

                EnterpriseBean enterpriseBean = ejbJar.getEnterpriseBean(ejbName);
                if (enterpriseBean == null) {
                    enterpriseBean = new StatelessBean(ejbName, beanClass.get());
                    ejbJar.addEnterpriseBean(enterpriseBean);
                }
                if (enterpriseBean.getEjbClass() == null) {
                    enterpriseBean.setEjbClass(beanClass.get());
                }
                if (enterpriseBean instanceof SessionBean) {
                    final SessionBean sessionBean = (SessionBean) enterpriseBean;
                    sessionBean.setSessionType(SessionType.STATELESS);

                    if (stateless.mappedName() != null) {
                        sessionBean.setMappedName(stateless.mappedName());
                    }
                }
                LegacyProcessor.process(beanClass.get(), enterpriseBean);
            }

            // The Specialization code is good, but it possibly needs to be moved to after the full processing of the bean
            // the plus is that it would get the required interfaces.  The minus is that it would get all the other items

            // Possibly study alternatives.  Alternatives might have different meta data completely while it seems Specializing beans inherit all meta-data

            // Anyway.. the qualifiers aren't getting inherited, so we need to fix that

            for (final Annotated<Class<?>> beanClass : finder.findMetaAnnotatedClasses(Stateful.class)) {
                final Stateful stateful = beanClass.getAnnotation(Stateful.class);
                final String ejbName = getEjbName(stateful, beanClass.get());

                if (!isValidEjbAnnotationUsage(Stateful.class, beanClass, ejbName, ejbModule)) {
                    continue;
                }

                EnterpriseBean enterpriseBean = ejbJar.getEnterpriseBean(ejbName);
                if (enterpriseBean == null) {
                    enterpriseBean = new StatefulBean(ejbName, beanClass.get());
                    ejbJar.addEnterpriseBean(enterpriseBean);
                }
                if (enterpriseBean.getEjbClass() == null) {
                    enterpriseBean.setEjbClass(beanClass.get());
                }
                if (enterpriseBean instanceof SessionBean) {
                    final SessionBean sessionBean = (SessionBean) enterpriseBean;
                    // TODO: We might be stepping on an xml override here
                    sessionBean.setSessionType(SessionType.STATEFUL);
                    if (stateful.mappedName() != null) {
                        sessionBean.setMappedName(stateful.mappedName());
                    }
                    if (sessionBean.getPassivationCapable() == null) {
                        sessionBean.setPassivationCapable(stateful.passivationCapable());
                    }
                }
                LegacyProcessor.process(beanClass.get(), enterpriseBean);
            }

            for (final Annotated<Class<?>> beanClass : finder.findMetaAnnotatedClasses(ManagedBean.class)) {
                final ManagedBean managed = beanClass.getAnnotation(ManagedBean.class);
                final String ejbName = getEjbName(managed, beanClass.get());

                // TODO: this is actually against the spec, but the requirement is rather silly
                // (allowing @Stateful and @ManagedBean on the same class)
                // If the TCK doesn't complain we should discourage it
                if (!isValidEjbAnnotationUsage(ManagedBean.class, beanClass, ejbName, ejbModule)) {
                    continue;
                }

                EnterpriseBean enterpriseBean = ejbJar.getEnterpriseBean(ejbName);
                if (enterpriseBean == null) {
                    enterpriseBean = new org.apache.openejb.jee.ManagedBean(ejbName, beanClass.get());
                    ejbJar.addEnterpriseBean(enterpriseBean);
                }
                if (enterpriseBean.getEjbClass() == null) {
                    enterpriseBean.setEjbClass(beanClass.get());
                }
                if (enterpriseBean instanceof SessionBean) {
                    final SessionBean sessionBean = (SessionBean) enterpriseBean;
                    sessionBean.setSessionType(SessionType.MANAGED);

                    final TransactionType transactionType = sessionBean.getTransactionType();
                    if (transactionType == null) {
                        sessionBean.setTransactionType(TransactionType.BEAN);
                    }
                }
            }

            for (final Annotated<Class<?>> beanClass : finder.findMetaAnnotatedClasses(MessageDriven.class)) {
                final MessageDriven mdb = beanClass.getAnnotation(MessageDriven.class);
                final String ejbName = getEjbName(mdb, beanClass.get());

                if (!isValidEjbAnnotationUsage(MessageDriven.class, beanClass, ejbName, ejbModule)) {
                    continue;
                }

                MessageDrivenBean messageBean = (MessageDrivenBean) ejbJar.getEnterpriseBean(ejbName);
                if (messageBean == null) {
                    messageBean = new MessageDrivenBean(ejbName);
                    ejbJar.addEnterpriseBean(messageBean);
                }
                if (messageBean.getEjbClass() == null) {
                    messageBean.setEjbClass(beanClass.get());
                }
                LegacyProcessor.process(beanClass.get(), messageBean);
            }

            AssemblyDescriptor assemblyDescriptor = ejbModule.getEjbJar().getAssemblyDescriptor();
            if (assemblyDescriptor == null) {
                assemblyDescriptor = new AssemblyDescriptor();
                ejbModule.getEjbJar().setAssemblyDescriptor(assemblyDescriptor);
            }

            startupLogger.debug("Searching for annotated application exceptions (see OPENEJB-980)");
            final List<Class<?>> appExceptions = finder.findAnnotatedClasses(ApplicationException.class);
            for (final Class<?> exceptionClass : appExceptions) {
                startupLogger.debug("...handling " + exceptionClass);
                final ApplicationException annotation = exceptionClass.getAnnotation(ApplicationException.class);
                if (assemblyDescriptor.getApplicationException(exceptionClass) == null) {
                    startupLogger.debug("...adding " + exceptionClass + " with rollback=" + annotation.rollback());
                    assemblyDescriptor.addApplicationException(exceptionClass, annotation.rollback(), annotation.inherited());
                } else {
                    mergeApplicationExceptionAnnotation(assemblyDescriptor, exceptionClass, annotation);
                }
            }

            { // after having found EJB for auto CDI activation
                final Map<URL, List<String>> managedClasses;
                Beans beans = ejbModule.getBeans();

                final boolean deployComp;
                if (beans == null && !ejbJar.getEnterpriseBeansByEjbName().isEmpty()
                        && isActivateCdiForEjbOnlyModules(ejbModule)) {
                    logger.info("Activating CDI in ACTIVATED mode in module '" + ejbModule.getModuleUri() + "' cause EJB were found\n" +
                            "  add openejb.cdi.activated=false in application.properties to switch it off or\n" +
                            "  openejb.cdi.activated-on-ejb=false in conf/system.properties" +
                            "  to switch it off");
                    beans = new Beans();
                    beans.setBeanDiscoveryMode("ANNOTATED");
                    beans.setVersion("1.1");
                    try {
                        ejbModule.getModuleUri().toURL();
                        beans.setUri(ejbModule.getModuleUri().toASCIIString());
                    } catch (final MalformedURLException | IllegalArgumentException iae) { // test? fake a URI
                        beans.setUri(URI.create("jar:file://!/" + ejbModule.getModuleUri().toASCIIString() + "/META-INF/beans.xml").toASCIIString());
                    }
                    ejbModule.setBeans(beans);
                    deployComp = false; // no need normally since mainly only EJB will be injectable
                } else {
                    deployComp = true;
                }

                if (beans != null) {
                    managedClasses = beans.getManagedClasses();
                    getBeanClasses(beans.getUri(), finder, managedClasses, beans.getNotManagedClasses(), ejbModule.getAltDDs());

                    if (deployComp) {
                        // passing jar location to be able to manage maven classes/test-classes which have the same moduleId
                        String id = ejbModule.getModuleId();
                        if (ejbModule.getJarLocation() != null &&
                                (ejbModule.getJarLocation().contains(ejbModule.getModuleId() + "/target/test-classes".replace("/", File.separator)) ||
                                        ejbModule.getJarLocation().contains(ejbModule.getModuleId() + "/build/classes/test".replace("/", File.separator)))) {
                            // with maven/gradle if both src/main/java and src/test/java are deployed
                            // moduleId.Comp exists twice so it fails
                            // here we simply modify the test comp bean name to avoid it
                            id += "_test";
                        }
                        final String name = BeanContext.Comp.openejbCompName(id);
                        final org.apache.openejb.jee.ManagedBean managedBean = new CompManagedBean(name, BeanContext.Comp.class);
                        managedBean.setTransactionType(TransactionType.BEAN);
                        ejbModule.getEjbJar().addEnterpriseBean(managedBean);

                        if ("true".equals(SystemInstance.get().getProperty("openejb.cdi.support.@Startup", "true"))) {
                            final List<Annotated<Class<?>>> forceStart = finder.findMetaAnnotatedClasses(Startup.class);
                            final List<String> startupBeans = beans.getStartupBeans();
                            for (final Annotated<Class<?>> clazz : forceStart) {
                                startupBeans.add(clazz.get().getName());
                            }
                        }
                    }
                }
            }

            // ejb can be rest bean and only then in standalone so scan providers here too
            // adding them to app since they should be in the app classloader
            if (ejbModule.getAppModule() != null) {
                addJaxRsProviders(finder, ejbModule.getAppModule().getJaxRsProviders(), Provider.class);
            }

            autoJpa(ejbModule);

            return ejbModule;
        }

        private boolean isActivateCdiForEjbOnlyModules(final EjbModule ejbModule) {
            final String activated = ejbModule.getProperties().getProperty("openejb.cdi.activated");
            final String globalConfig = SystemInstance.get().getProperty("openejb.cdi.activated-on-ejb"); // spec should be true but mem + bck compat
            return (globalConfig == null || Boolean.parseBoolean(globalConfig)) &&
                    ((activated == null && hasAtInject(ejbModule)) || (activated != null && Boolean.parseBoolean(activated)));
        }

        // quick heuristic to guess if cdi is needed, avoid to need more mem when useless
        private boolean hasAtInject(final EjbModule ejbModule) {
            final IAnnotationFinder finder = ejbModule.getFinder();
            return finder != null &&
                    (!finder.findAnnotatedFields(Inject.class).isEmpty()
                    || !finder.findAnnotatedConstructors(Inject.class).isEmpty()
                    || !finder.findAnnotatedMethods(Inject.class).isEmpty());
        }

        private SessionType getSessionType(final Class<?> clazz) {
            if (clazz.isAnnotationPresent(Stateful.class)) {
                return SessionType.STATEFUL;
            }
            if (clazz.isAnnotationPresent(Stateless.class)) {
                return SessionType.STATELESS;
            }
            if (clazz.isAnnotationPresent(Singleton.class)) {
                return SessionType.SINGLETON;
            }
            if (clazz.isAnnotationPresent(ManagedBean.class)) {
                return SessionType.MANAGED;
            }
            return null;
        }

        private String getEjbName(final EnterpriseBean bean, final Class<?> clazz) {

            if (bean instanceof SessionBean) {
                final SessionBean sessionBean = (SessionBean) bean;
                switch (sessionBean.getSessionType()) {
                    case STATEFUL: {
                        final Stateful annotation = clazz.getAnnotation(Stateful.class);
                        if (annotation != null && specified(annotation.name())) {
                            return annotation.name();
                        }
                    }
                    case STATELESS: {
                        final Stateless annotation = clazz.getAnnotation(Stateless.class);
                        if (annotation != null && specified(annotation.name())) {
                            return annotation.name();
                        }
                    }
                    case SINGLETON: {
                        final Singleton annotation = clazz.getAnnotation(Singleton.class);
                        if (annotation != null && specified(annotation.name())) {
                            return annotation.name();
                        }
                    }
                }
            }

            if (bean instanceof MessageDrivenBean) {
                final MessageDriven annotation = clazz.getAnnotation(MessageDriven.class);
                if (annotation != null && specified(annotation.name())) {
                    return annotation.name();
                }
            }

            return clazz.getSimpleName();
        }

        private static boolean specified(final String name) {
            return name != null && name.length() != 0;
        }

        private void getBeanClasses(final String uri, final IAnnotationFinder finder,
                                    final Map<URL, List<String>> classes,
                                    final Map<URL, List<String>> notManaged,
                                    final Map<String, Object> altDD) {

            //  What we're hoping in this method is to get lucky and find
            //  that our 'finder' instances is an AnnotationFinder that is
            //  holding an AggregatedArchive so we can get the classes that
            //  that pertain to each URL for CDI purposes.
            //
            //  If not we call finder.getAnnotatedClassNames() which may return
            //  more classes than actually apply to CDI.  This can "pollute"
            //  the CDI class space and break injection points

            // force cast otherwise we would be broken
            final IAnnotationFinder delegate = FinderFactory.ModuleLimitedFinder.class.isInstance(finder) ?
                    FinderFactory.ModuleLimitedFinder.class.cast(finder).getDelegate() : finder;
            if (!AnnotationFinder.class.isInstance(delegate)) {
                return; // only few tests
            }

            final AnnotationFinder annotationFinder = AnnotationFinder.class.cast(delegate);
            final Archive archive = annotationFinder.getArchive();

            if (!WebappAggregatedArchive.class.isInstance(archive)) {
                try {
                    final List<String> annotatedClassNames = annotationFinder.getAnnotatedClassNames();
                    if (!annotatedClassNames.isEmpty()) {
                        classes.put(uri == null ? null : new URL(uri), annotatedClassNames);
                    }
                } catch (final MalformedURLException e) {
                    throw new IllegalStateException(e);
                }
                return;
            }

            final WebappAggregatedArchive aggregatedArchive = (WebappAggregatedArchive) archive;
            final Map<URL, List<String>> map = aggregatedArchive.getClassesMap();

            Collection<Class<?>> discoveredBeans = null;
            List<Class<? extends Extension>> extensions = null;

            final FolderDDMapper ddMapper = SystemInstance.get().getComponent(FolderDDMapper.class);
            for (final Map.Entry<URL, List<String>> entry : map.entrySet()) {
                final URL key = entry.getKey();
                final URL beansXml = hasBeansXml(key, ddMapper);
                final List<String> value = entry.getValue();
                if (beansXml != null) {
                    classes.put(beansXml, value);
                } else if (!value.isEmpty()) {
                    final Set<String> fastValue = new HashSet<>(value);
                    if (discoveredBeans == null) { // lazy init for apps not using it, it slows down the app boot and that should be useless
                        discoveredBeans = new HashSet<>();

                        final Set<Class<? extends Annotation>> containerAnnot = new HashSet<>();
                        containerAnnot.add(Stereotype.class);
                        containerAnnot.add(NormalScope.class);
                        containerAnnot.add(Dependent.class);
                        containerAnnot.add(ApplicationScoped.class);
                        containerAnnot.add(ConversationScoped.class);
                        containerAnnot.add(RequestScoped.class);
                        containerAnnot.add(SessionScoped.class);
                        containerAnnot.add(Model.class);
                        containerAnnot.add(Singleton.class);
                        containerAnnot.add(Stateless.class);
                        containerAnnot.add(Stateful.class);
                        containerAnnot.add(MessageDriven.class);
                        containerAnnot.add(javax.interceptor.Interceptor.class);
                        containerAnnot.add(Decorator.class);
                        final ClassLoader classLoader = ParentClassLoaderFinder.Helper.get();
                        try {
                            for (final String name : asList("javax.faces.flow.FlowScoped", "javax.faces.view.ViewScoped")) {
                                containerAnnot.add((Class<? extends Annotation>) classLoader.loadClass(name));
                            }
                        } catch (final Throwable e) {
                            // no-op
                        }

                        final Set<Class<?>> newMarkers = new HashSet<>();
                        for (final Class<? extends Annotation> a : containerAnnot) {
                            newMarkers.addAll(finder.findAnnotatedClasses(a));
                        }

                        do {
                            final Set<Class<?>> loopMarkers = new HashSet<>(newMarkers);
                            newMarkers.clear();
                            for (final Class<?> marker : loopMarkers) {
                                discoveredBeans.add(marker);

                                final List<Class<?>> found = finder.findAnnotatedClasses(Class.class.cast(marker));
                                for (final Class<?> c : found) {
                                    if (c.isAnnotation()) {
                                        newMarkers.add(c);
                                    }
                                    discoveredBeans.add(c);
                                }
                            }
                        } while (!newMarkers.isEmpty());

                        for (final Field field : finder.findAnnotatedFields(Delegate.class)) { // should be done for constructors but too slow?
                            discoveredBeans.add(field.getDeclaringClass());
                        }

                        extensions = finder.findImplementations(Extension.class);
                    }

                    boolean skip = false;
                    for (final Class<?> c : extensions) {
                        if (fastValue.contains(c.getName())) {
                            // legacy mode, we should check META-INF/services/... but this mode + having an Extension should be enough
                            skip = true;
                            continue;
                        }
                    }
                    if (skip) {
                        continue;
                    }

                    final Set<String> beans = new HashSet<>();
                    for (final Class<?> c : discoveredBeans) {
                        final String name = c.getName();
                        if (fastValue.contains(name)) {
                            beans.add(name);
                        }
                    }

                    if (beans.isEmpty()) {
                        continue;
                    }

                    // just keep the potential ones to not load all classes during boot
                    notManaged.put(entry.getKey(), new ArrayList<>(beans));
                }
            }
        }

        public URL hasBeansXml(final URL url, final FolderDDMapper ddMapper) {
            final String urlPath = url.getPath();
            if (urlPath.endsWith("/WEB-INF/beans.xml")) {
                return url;
            }
            if (urlPath.endsWith("WEB-INF/classes/") || urlPath.endsWith("WEB-INF/classes")) {
                final File toFile = URLs.toFile(url);
                {
                    final File file = new File(toFile.getParent(), "beans.xml");
                    if (file.exists()) {
                        try {
                            return file.toURI().toURL();
                        } catch (final MalformedURLException e) {
                            return url;
                        }
                    }
                }
                {
                    final File file = new File(toFile, "META-INF/beans.xml");
                    if (file.exists()) {
                        try {
                            return file.toURI().toURL();
                        } catch (final MalformedURLException e) {
                            return url;
                        }
                    }
                }
                return null;
            }
            if (url.getPath().endsWith("!/META-INF/beans.xml")) {
                return url;
            }

            try (URLClassLoader loader = new URLClassLoader(new URL[]{url}, new EmptyResourcesClassLoader())) {
                final String[] paths = {
                        "META-INF/beans.xml",
                        "WEB-INF/beans.xml",
                        "/WEB-INF/beans.xml",
                        "/META-INF/beans.xml",
                };

                for (final String path : paths) {
                    final URL resource = loader.findResource(path);
                    if (resource != null) {
                        return resource;
                    }
                }
            } catch (final Exception e) {
                // no-op
            }
            // no-op
            if (ddMapper != null) {
                final File asFile = URLs.toFile(url);
                if (asFile.isDirectory()) {
                    final File ddFolder = ddMapper.getDDFolder(asFile);
                    final File file = new File(ddFolder, "beans.xml");
                    if (file.isFile()) {
                        try {
                            return file.toURI().toURL();
                        } catch (final MalformedURLException e) {
                            // no-op
                        }
                    }
                }
            }
            return null;
        }

        private String getEjbName(final MessageDriven mdb, final Class<?> beanClass) {
            return mdb.name().isEmpty() ? beanClass.getSimpleName() : mdb.name();
        }

        private String getEjbName(final Stateful stateful, final Class<?> beanClass) {
            return stateful.name().isEmpty() ? beanClass.getSimpleName() : stateful.name();
        }

        private String getEjbName(final Stateless stateless, final Class<?> beanClass) {
            return stateless.name().isEmpty() ? beanClass.getSimpleName() : stateless.name();
        }

        private String getEjbName(final Singleton singleton, final Class<?> beanClass) {
            return singleton.name().isEmpty() ? beanClass.getSimpleName() : singleton.name();
        }

        private String getEjbName(final ManagedBean managed, final Class<?> beanClass) {
            return managed.value().isEmpty() ? beanClass.getSimpleName() : managed.value();
        }

        private boolean isValidEjbAnnotationUsage(final Class annotationClass, final Annotated<Class<?>> beanClass, final String ejbName, final EjbModule ejbModule) {
            final List<Class<? extends Annotation>> annotations = new ArrayList(Arrays.asList(Singleton.class, Stateless.class, Stateful.class, MessageDriven.class));
            annotations.remove(annotationClass);

            final boolean b = true;
            for (final Class<? extends Annotation> secondAnnotation : annotations) {
                final Annotation annotation = beanClass.getAnnotation(secondAnnotation);

                if (annotation == null) {
                    continue;
                }

                String secondEjbName = null;
                if (annotation instanceof Stateful) {
                    secondEjbName = getEjbName((Stateful) annotation, beanClass.get());
                } else if (annotation instanceof Stateless) {
                    secondEjbName = getEjbName((Stateless) annotation, beanClass.get());
                } else if (annotation instanceof Singleton) {
                    secondEjbName = getEjbName((Singleton) annotation, beanClass.get());
                } else if (annotation instanceof MessageDriven) {
                    secondEjbName = getEjbName((MessageDriven) annotation, beanClass.get());
                }

                if (ejbName.equals(secondEjbName)) {
                    ejbModule.getValidation().fail(ejbName, "multiplyAnnotatedAsBean", annotationClass.getSimpleName(), secondAnnotation.getSimpleName(), ejbName, beanClass.get().getName());
                }
            }

            if (beanClass.get().isInterface()) {
                if (!CheckClasses.isAbstractAllowed(beanClass.get())) {
                    ejbModule.getValidation().fail(ejbName, "interfaceAnnotatedAsBean", annotationClass.getSimpleName(), beanClass.get().getName());
                    return false;
                }
            } else if (Modifier.isAbstract(beanClass.get().getModifiers())) {
                if (!CheckClasses.isAbstractAllowed(beanClass.get())) {
                    ejbModule.getValidation().fail(ejbName, "abstractAnnotatedAsBean", annotationClass.getSimpleName(), beanClass.get().getName());
                    return false;
                }
            }

            return b;
        }

    }

    public static void autoJpa(final EjbModule ejbModule) {
        final IAnnotationFinder finder = ejbModule.getFinder();
        if (ejbModule.getAppModule() != null) {
            for (final PersistenceModule pm : ejbModule.getAppModule().getPersistenceModules()) {
                for (final org.apache.openejb.jee.jpa.unit.PersistenceUnit pu : pm.getPersistence().getPersistenceUnit()) {
                    if ((pu.isExcludeUnlistedClasses() == null || !pu.isExcludeUnlistedClasses())
                        && "true".equalsIgnoreCase(pu.getProperties().getProperty(OPENEJB_JPA_AUTO_SCAN))) {
                        doAutoJpa(finder, pu);
                    }
                }
            }
        }
    }

    public static void doAutoJpa(final IAnnotationFinder finder, final org.apache.openejb.jee.jpa.unit.PersistenceUnit pu) {
        final String packageName = pu.getProperties().getProperty(OPENEJB_JPA_AUTO_SCAN_PACKAGE);
        String[] packageNames = null;
        if (packageName != null) {
            packageNames = packageName.split(",");
        }

        // no need of meta currently since JPA providers doesn't support it
        final List<Class<?>> classes = new ArrayList<>();
        classes.addAll(finder.findAnnotatedClasses(Entity.class));
        classes.addAll(finder.findAnnotatedClasses(Embeddable.class));
        classes.addAll(finder.findAnnotatedClasses(MappedSuperclass.class));
        classes.addAll(finder.findAnnotatedClasses(Converter.class));
        final List<String> existingClasses = pu.getClazz();
        for (final Class<?> clazz : classes) {
            final String name = clazz.getName();
            if (existingClasses.contains(name)) {
                continue;
            }

            if (packageNames == null) {
                pu.getClazz().add(name);
            } else {
                for (final String pack : packageNames) {
                    if (name.startsWith(pack)) {
                        pu.getClazz().add(name);
                    }
                }
            }
        }
        pu.setScanned(true);
    }

    public static class ProcessAnnotatedBeans implements DynamicDeployer {

        public static final String STRICT_INTERFACE_DECLARATION = "openejb.strict.interface.declaration";

        private final boolean webserviceAsRemote;

        public ProcessAnnotatedBeans(final boolean wsAsRemote) {
            webserviceAsRemote = wsAsRemote;
        }

        public void deploy(final CdiBeanInfo beanInfo) throws OpenEJBException {

            final AnnotationFinder annotationFinder = createFinder(beanInfo.getBeanClass());
            /*
             * @EJB
             * @Resource
             * @WebServiceRef
             * @PersistenceUnit
             * @PersistenceContext
             */
            buildAnnotatedRefs(beanInfo, annotationFinder, beanInfo.getClassLoader());

            processWebServiceClientHandlers(beanInfo, annotationFinder, beanInfo.getClassLoader());

        }

        public AppModule deploy(final AppModule appModule) throws OpenEJBException {
            for (final EjbModule ejbModule : appModule.getEjbModules()) {
                setModule(ejbModule);
                try {
                    deploy(ejbModule);
                } finally {
                    removeModule();
                }
            }
            for (final ClientModule clientModule : appModule.getClientModules()) {
                setModule(clientModule);
                try {
                    deploy(clientModule);
                } finally {
                    removeModule();
                }
            }
            for (final ConnectorModule connectorModule : appModule.getConnectorModules()) {
                setModule(connectorModule);
                try {
                    deploy(connectorModule);
                } finally {
                    removeModule();
                }
            }
            for (final WebModule webModule : appModule.getWebModules()) {
                setModule(webModule);
                try {
                    deploy(webModule);
                } finally {
                    removeModule();
                }
            }
            return appModule;
        }

        public ClientModule deploy(final ClientModule clientModule) throws OpenEJBException {
            if (clientModule.getApplicationClient() != null && clientModule.getApplicationClient().isMetadataComplete()) {
                return clientModule;
            }

            final ClassLoader classLoader = clientModule.getClassLoader();

            ApplicationClient client = clientModule.getApplicationClient();

            if (client == null) {
                client = new ApplicationClient();
            }

            final Set<Class> remoteClients = new HashSet<>();

            if (clientModule.getMainClass() != null) {
                final String className = realClassName(clientModule.getMainClass());

                // OPENEJB-1063: a Main-Class should use "." instead of "/"
                // it wasn't check before jdk 1.5 so we can get old module with
                // bad format http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4986512
                // replace all "/" by "."
                if (clientModule.getMainClass().contains("/")) { // className can't be null here
                    clientModule.setMainClass(className);
                }

                final Class clazz;
                try {
                    clazz = classLoader.loadClass(className);
                    remoteClients.add(clazz);

                    final AnnotationFinder annotationFinder = createFinder(clazz);

                    buildAnnotatedRefs(client, annotationFinder, classLoader);
                } catch (final ClassNotFoundException e) {
                    /**
                     * Some ClientModule are discovered only because the jar uses a Main-Class
                     * entry in the MANIFEST.MF file.  Lots of jars do this that are not used as
                     * java ee application clients, so lets not make this a failure unless it
                     * has a META-INF/application-client.xml which tells us it is in fact
                     * expected to be a ClientModule and not just some random jar.
                     */
                    if (clientModule.getAltDDs().containsKey("application-client.xml")) {
                        getValidationContext().fail("client", "client.missingMainClass", className);
                    } else {
                        getValidationContext().warn("client", "client.missingMainClass", className);
                    }
                }
            }

            for (final String rawClassName : clientModule.getRemoteClients()) {
                final String className = realClassName(rawClassName);
                final Class clazz;
                try {
                    clazz = classLoader.loadClass(className);
                    remoteClients.add(clazz);
                } catch (final ClassNotFoundException e) {
                    throw new OpenEJBException("Unable to load RemoteClient class: " + className, e);
                }

                final AnnotationFinder annotationFinder = createFinder(clazz);

                buildAnnotatedRefs(client, annotationFinder, classLoader);
            }

            for (final String rawClassName : clientModule.getLocalClients()) {
                final String className = realClassName(rawClassName);
                final Class clazz;
                try {
                    clazz = classLoader.loadClass(className);
                } catch (final ClassNotFoundException e) {
                    throw new OpenEJBException("Unable to load LocalClient class: " + className, e);
                }

                final AnnotationFinder annotationFinder = createFinder(clazz);

                buildAnnotatedRefs(client, annotationFinder, classLoader);
            }

            validateRemoteClientRefs(classLoader, client, remoteClients);

            final IAnnotationFinder finder = clientModule.getFinder();
            if (!AnnotationFinder.class.isInstance(finder) && finder != null) {
                final Class<?>[] loadedClasses = new Class<?>[finder.getAnnotatedClassNames().size()];
                int i = 0;
                for (final String s : finder.getAnnotatedClassNames()) {
                    try {
                        loadedClasses[i++] = classLoader.loadClass(s);
                    } catch (final ClassNotFoundException e) {
                        // no-op
                    }
                }
                clientModule.getFinderReference().set(new FinderFactory.OpenEJBAnnotationFinder(new ClassesArchive(loadedClasses)));
            }
            processWebServiceClientHandlers(client, AnnotationFinder.class.cast(clientModule.getFinder()), classLoader);

            return clientModule;
        }

        private void validateRemoteClientRefs(final ClassLoader classLoader, final ApplicationClient client, final Set<Class> remoteClients) {
            for (final EjbLocalRef ref : client.getEjbLocalRef()) {
                for (final InjectionTarget target : ref.getInjectionTarget()) {
                    try {
                        final Class<?> targetClass = classLoader.loadClass(realClassName(target.getInjectionTargetClass()));
                        for (final Class remoteClient : remoteClients) {
                            if (targetClass.isAssignableFrom(remoteClient)) {
                                fail(remoteClient.getName(), "remoteClient.ejbLocalRef", target.getInjectionTargetClass(), target.getInjectionTargetName());
                            }
                        }
                    } catch (final ClassNotFoundException ignore) {
                        // no-op
                    }
                }
            }

            for (final PersistenceContextRef ref : client.getPersistenceContextRef()) {
                for (final InjectionTarget target : ref.getInjectionTarget()) {
                    try {
                        final Class<?> targetClass = classLoader.loadClass(realClassName(target.getInjectionTargetClass()));
                        for (final Class remoteClient : remoteClients) {
                            if (targetClass.isAssignableFrom(remoteClient)) {
                                fail(remoteClient.getName(), "remoteClient.persistenceContextRef", target.getInjectionTargetClass(), target.getInjectionTargetName());
                            }
                        }
                    } catch (final ClassNotFoundException ignore) {
                        // no-op
                    }
                }
            }

            /* TODO: still useful?
            List<String> unusableTypes = new ArrayList<String>(knownResourceEnvTypes);
            unusableTypes.remove("javax.jms.Topic");
            unusableTypes.remove("javax.jms.Queue");

            for (ResourceEnvRef ref : client.getResourceEnvRef()) {

                if (!unusableTypes.contains(ref.getType())) continue;

                for (InjectionTarget target : ref.getInjectionTarget()) {
                    try {
                        Class<?> targetClass = classLoader.loadClass(target.getInjectionTargetClass());
                        for (Class remoteClient : remoteClients) {
                            if (targetClass.isAssignableFrom(remoteClient)) {
                                fail(remoteClient.getName(), "remoteClient.resourceEnvRef", target.getInjectionTargetClass(), target.getInjectionTargetName(), ref.getType());
                            }
                        }
                    } catch (ClassNotFoundException ignore) {
                    }
                }
            }
            */
        }

        public ConnectorModule deploy(final ConnectorModule connectorModule) throws OpenEJBException {
            // resource modules currently don't have any annotations
            return connectorModule;
        }

        /**
         * Collects a list of all webapp related classes that are eligible for
         * annotation processing then scans them and fills out the web.xml with
         * the xml version of the annotations.
         *
         * @param webModule
         * @return
         * @throws OpenEJBException
         */
        public WebModule deploy(final WebModule webModule) throws OpenEJBException {
            final WebApp webApp = webModule.getWebApp();
            if (webApp != null && webApp.isMetadataComplete()) {
                return webModule;
            }

            /*
             * Classes added to this set will be scanned for annotations
             */
            final Set<Class> classes = new HashSet<>();


            final ClassLoader classLoader = webModule.getClassLoader();

            final String webXmlApplication = webApp.contextParamsAsMap().get("javax.ws.rs.Application");
            if (webXmlApplication != null) {
                webModule.getRestApplications().clear();
                webModule.getRestApplications().add(webXmlApplication);
            }

            final Collection<String> restApp = webModule.getRestApplications();
            if (restApp.isEmpty()) {
                addRestClassesToScannedClasses(webModule, classes, classLoader);
            } else {
                for (final String rawClassName : restApp) {
                    final String application = realClassName(rawClassName);
                    if (application != null) {
                        final Class<?> clazz;
                        try {
                            clazz = classLoader.loadClass(application);
                            classes.add(clazz);
                        } catch (final ClassNotFoundException e) {
                            throw new OpenEJBException("Unable to load Application class: " + application, e);
                        }
                        if (Modifier.isAbstract(clazz.getModifiers())) {
                            continue;
                        }

                        try {
                            final Application app = Application.class.cast(clazz.newInstance());
                            try {
                                final Set<Class<?>> appClasses = app.getClasses();
                                if (!appClasses.isEmpty()) {
                                    classes.addAll(appClasses);
                                } else {
                                    addRestClassesToScannedClasses(webModule, classes, classLoader);
                                }
                            } catch (final RuntimeException npe) {
                                if (app == null) {
                                    throw npe;
                                }
                                // if app depends on cdi no need to do it
                            }
                        } catch (final InstantiationException e) {
                            throw new OpenEJBException("Unable to instantiate Application class: " + application, e);
                        } catch (final IllegalAccessException e) {
                            throw new OpenEJBException("Unable to access Application class: " + application, e);
                        }
                    }
                }
            }


            /*
             * Servlet classes are scanned
             */
            for (final Servlet servlet : webApp.getServlet()) {
                final String servletName = servlet.getServletName();
                if ("javax.ws.rs.core.Application".equals(servletName) || "javax.ws.rs.Application".equals(servletName)) {
                    // check first if there is a real application as init param
                    boolean done = false;
                    for (final ParamValue pv : servlet.getInitParam()) {
                        if ("javax.ws.rs.core.Application".equals(pv.getParamName()) || "javax.ws.rs.Application".equals(pv.getParamName())) {
                            webModule.getRestApplications().add(pv.getParamValue());
                            done = true;
                            break;
                        }
                    }
                    if (!done) {
                        servlet.setServletName(ProvidedJAXRSApplication.class.getName());
                        webModule.getRestApplications().add(ProvidedJAXRSApplication.class.getName());
                        for (final ServletMapping mapping : webApp.getServletMapping()) {
                            if (servletName.equals(mapping.getServletName())) {
                                mapping.setServletName(ProvidedJAXRSApplication.class.getName());
                            }
                        }
                    }
                    continue;
                }

                String servletClass = realClassName(servlet.getServletClass());
                if (servletClass == null) { // try with servlet name, @see org.apache.openejb.arquillian.tests.jaxrs.basicapp.BasicApplication
                    servletClass = realClassName(servletName);
                }

                if (servletClass != null && servlet.getJspFile() == null) { // jaxrs application doesn't have a jsp file
                    if (!"org.apache.openejb.server.rest.OpenEJBRestServlet".equals(servletClass)) {
                        try {
                            final Class clazz = classLoader.loadClass(servletClass);
                            classes.add(clazz);
                            if (servlet.getServletClass() == null) {
                                servlet.setServletClass(servletClass);
                            }
                        } catch (final ClassNotFoundException e) {
                            if (servlet.getServletClass() != null) {
                                throw new OpenEJBException("Unable to load servlet class: " + servletClass, e);
                            } else {
                                logger.error("servlet " + servletName + " has no servlet-class defined and is not a subclass of Application");
                            }
                        }
                    }

                    // if the servlet is a rest init servlet don't deploy rest classes automatically
                    for (final ParamValue param : servlet.getInitParam()) {
                        if (param.getParamName().equals(Application.class.getName()) || param.getParamName().equals("javax.ws.rs.Application")) {
                            webModule.getRestApplications().clear();
                            webModule.getRestApplications().add(param.getParamValue());
                            break;
                        }
                    }
                }
            }

            /*
             * Filter classes are scanned
             */
            for (final Filter filter : webApp.getFilter()) {
                final String filterClass = realClassName(filter.getFilterClass());
                if (filterClass != null) {
                    try {
                        final Class clazz = classLoader.loadClass(filterClass);
                        classes.add(clazz);
                    } catch (final ClassNotFoundException e) {
                        throw new OpenEJBException("Unable to load servlet filter class: " + filterClass, e);
                    }
                }
            }

            /*
             * Listener classes are scanned
             */
            for (final Listener listener : webApp.getListener()) {
                final String listenerClass = realClassName(listener.getListenerClass());
                if (listenerClass != null) {
                    try {
                        final Class clazz = classLoader.loadClass(listenerClass);
                        classes.add(clazz);
                    } catch (final ClassNotFoundException e) {
                        throw new OpenEJBException("Unable to load servlet listener class: " + listenerClass, e);
                    }
                }
            }

            for (final TldTaglib taglib : webModule.getTaglibs()) {
                /*
                 * TagLib Listener classes are scanned
                 */
                for (final Listener listener : taglib.getListener()) {
                    final String listenerClass = realClassName(listener.getListenerClass());
                    if (listenerClass != null) {
                        try {
                            final Class clazz = classLoader.loadClass(listenerClass);
                            classes.add(clazz);
                        } catch (final ClassNotFoundException e) {
                            logger.error("Unable to load tag library servlet listener class: " + listenerClass);
                        }
                    }
                }

                /*
                 * TagLib Tag classes are scanned
                 */
                for (final Tag tag : taglib.getTag()) {
                    final String tagClass = realClassName(tag.getTagClass());
                    if (tagClass != null) {
                        try {
                            final Class clazz = classLoader.loadClass(tagClass);
                            classes.add(clazz);
                        } catch (final ClassNotFoundException e) {
                            logger.error("Unable to load tag library tag class: " + tagClass);
                        }
                    }
                }
            }

            /*
             * WebService HandlerChain classes are scanned
             */
            if (webModule.getWebservices() != null) {
                for (final WebserviceDescription webservice : webModule.getWebservices().getWebserviceDescription()) {
                    for (final PortComponent port : webservice.getPortComponent()) {
                        // skip ejb port defs
                        if (port.getServiceImplBean().getEjbLink() != null) {
                            continue;
                        }

                        if (port.getHandlerChains() == null) {
                            continue;
                        }
                        for (final org.apache.openejb.jee.HandlerChain handlerChain : port.getHandlerChains().getHandlerChain()) {
                            for (final Handler handler : handlerChain.getHandler()) {
                                final String handlerClass = realClassName(handler.getHandlerClass());
                                if (handlerClass != null) {
                                    try {
                                        final Class clazz = classLoader.loadClass(handlerClass);
                                        classes.add(clazz);
                                    } catch (final ClassNotFoundException e) {
                                        throw new OpenEJBException("Unable to load webservice handler class: " + handlerClass, e);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            /*
             * JSF ManagedBean classes are scanned
             */
            for (final FacesConfig facesConfig : webModule.getFacesConfigs()) {
                for (final FacesManagedBean bean : facesConfig.getManagedBean()) {
                    final String managedBeanClass = realClassName(bean.getManagedBeanClass().trim());
                    if (managedBeanClass != null) {
                        try {
                            final Class clazz = classLoader.loadClass(managedBeanClass);
                            classes.add(clazz);
                        } catch (final ClassNotFoundException e) {
                            logger.error("Unable to load JSF managed bean class: " + managedBeanClass);
                        }
                    }
                }
            }

            final IAnnotationFinder finder = webModule.getFinder();

            if (finder != null) {
                for (final String apiClassName : API_CLASSES) {
                    final Class<? extends Annotation> clazz;
                    try {
                        clazz = (Class<? extends Annotation>) classLoader.loadClass(apiClassName);
                    } catch (final ClassNotFoundException e) {
                        continue;
                    }
                    if (clazz.isAnnotation()) {
                        classes.addAll(metaToClass(finder.findMetaAnnotatedClasses(clazz)));
                    } else if (Modifier.isAbstract(clazz.getModifiers())) {
                        classes.addAll(finder.findSubclasses(clazz));
                    } else {
                        classes.addAll(finder.findImplementations(clazz));
                    }
                }
            }

            final AnnotationFinder annotationFinder = createFinder(classes.toArray(new Class<?>[classes.size()]));

            /*
             * @EJB
             * @Resource
             * @WebServiceRef
             * @PersistenceUnit
             * @PersistenceContext
             */
            buildAnnotatedRefs(webApp, annotationFinder, classLoader);

            processWebServiceClientHandlers(webApp, annotationFinder, classLoader);

            return webModule;
        }

        public EjbModule deploy(final EjbModule ejbModule) throws OpenEJBException {
            if (ejbModule.getEjbJar() != null && ejbModule.getEjbJar().isMetadataComplete()) {
                return ejbModule;
            }

//            Map<String, EjbDeployment> deployments = ejbModule.getOpenejbJar().getDeploymentsByEjbName();
            final ClassLoader classLoader = ejbModule.getClassLoader();
            final EnterpriseBean[] enterpriseBeans = ejbModule.getEjbJar().getEnterpriseBeans();
            for (final EnterpriseBean bean : enterpriseBeans) {
                final String ejbName = bean.getEjbName();
                final String ejbClassName = realClassName(bean.getEjbClass());

                if (ejbClassName == null) {
                    final List<String> others = new ArrayList<>();
                    for (final EnterpriseBean otherBean : enterpriseBeans) {
                        others.add(otherBean.getEjbName());
                    }
                    fail(ejbName, "xml.noEjbClass", ejbName, Join.join(", ", others));
                }

                final Class<?> clazz;
                try {
                    clazz = classLoader.loadClass(ejbClassName);
                } catch (final ClassNotFoundException e) {
                    // Handled in CheckClasses.java along with other missing classes
                    continue;
                }

                final MetaAnnotatedClass<?> metaClass = new MetaAnnotatedClass(clazz);
                final boolean dynamicBean = DynamicProxyImplFactory.isKnownDynamicallyImplemented(metaClass, clazz);

                AnnotationFinder finder = null; // created lazily since not always needed
                final AnnotationFinder annotationFinder;
                if (ejbModule.getFinder() instanceof AnnotationFinder) {
                    AnnotationFinder af = (AnnotationFinder) ejbModule.getFinder();

                    final List<Class<?>> ancestors = Classes.ancestors(clazz);
                    ancestors.addAll(asList(clazz.getInterfaces()));
                    if (dynamicBean) {
                        final Proxy p = metaClass.getAnnotation(Proxy.class);
                        if (p != null) {
                            ancestors.add(p.value());
                        }
                    }

                    final String[] names = new String[ancestors.size()];
                    int i = 0;
                    for (final Class<?> ancestor : ancestors) {
                        names[i++] = ancestor.getName();
                    }
                    annotationFinder = af.select(names);
                } else { // shouldn't occur
                    if (!dynamicBean) {
                        annotationFinder = createFinder(clazz);
                    } else {
                        final Class<?>[] classes;
                        final Proxy proxy = metaClass.getAnnotation(Proxy.class);
                        if (proxy == null) {
                            classes = new Class<?>[]{clazz};
                        } else {
                            classes = new Class<?>[]{clazz, proxy.value()};
                        }
                        annotationFinder = createFinder(classes);
                    }
                }

                /*
                 * @PostConstruct
                 * @PreDestroy
                 * @AroundInvoke
                 * @Timeout
                 * @PostActivate
                 * @PrePassivate
                 * @Init
                 * @Remove
                 * @AroundTimeout
                 * @AfterBegin
                 * @BeforeCompletion
                 * @AfterCompletion
                 */
                processCallbacks(bean, annotationFinder);

                /*
                 * @TransactionManagement
                 */
                if (bean.getTransactionType() == null) {
                    final TransactionManagement tx = getInheritableAnnotation(clazz, TransactionManagement.class);
                    TransactionManagementType transactionType = TransactionManagementType.CONTAINER;
                    if (tx != null) {
                        transactionType = tx.value();
                    }
                    switch (transactionType) {
                        case BEAN:
                            bean.setTransactionType(TransactionType.BEAN);
                            break;
                        case CONTAINER:
                            bean.setTransactionType(TransactionType.CONTAINER);
                            break;
                    }
                }

                final AssemblyDescriptor assemblyDescriptor = ejbModule.getEjbJar().getAssemblyDescriptor();

                /*
                 * @ApplicationException
                 */
                processApplicationExceptions(clazz, assemblyDescriptor);

                /*
                 * TransactionAttribute
                 */
                if (bean.getTransactionType() == TransactionType.CONTAINER) {
                    processAttributes(new TransactionAttributeHandler(assemblyDescriptor, ejbName), clazz, annotationFinder);
                } else {
                    if (finder == null) {
                        finder = annotationFinder.select(clazz.getName());
                    }
                    checkAttributes(new TransactionAttributeHandler(assemblyDescriptor, ejbName), ejbName, ejbModule, finder, "invalidTransactionAttribute");
                }

                /*
                 * @RolesAllowed
                 * @PermitAll
                 * @DenyAll
                 * @RunAs
                 * @DeclareRoles
                 */
                processSecurityAnnotations(clazz, ejbName, ejbModule, annotationFinder, bean);

                /*
                 * @Schedule
                 * @Schedules
                 */
                processSchedules(bean, annotationFinder);

                /*
                 * Add any interceptors they may have referenced in xml but did not declare
                 */
                for (final InterceptorBinding binding : assemblyDescriptor.getInterceptorBinding()) {
                    final EjbJar ejbJar = ejbModule.getEjbJar();

                    final List<String> list = new ArrayList<>(binding.getInterceptorClass());

                    if (binding.getInterceptorOrder() != null) {
                        list.clear();
                        list.addAll(binding.getInterceptorOrder().getInterceptorClass());
                    }

                    for (final String interceptor : list) {
                        if (ejbJar.getInterceptor(interceptor) == null) {
                            logger.debug("Adding '<ejb-jar><interceptors><interceptor>' entry for undeclared interceptor " + interceptor);
                            ejbJar.addInterceptor(new Interceptor(interceptor));
                        }
                    }
                }

                /*
                 * @Interceptors
                 */
                final List<Annotated<Class<?>>> annotatedClasses = sortClasses(annotationFinder.findMetaAnnotatedClasses(Interceptors.class));
                for (final Annotated<Class<?>> interceptorsAnnotatedClass : annotatedClasses) {
                    final Interceptors interceptors = interceptorsAnnotatedClass.getAnnotation(Interceptors.class);
                    final EjbJar ejbJar = ejbModule.getEjbJar();
                    for (final Class interceptor : interceptors.value()) {
                        if (ejbJar.getInterceptor(interceptor.getName()) == null) {
                            ejbJar.addInterceptor(new Interceptor(interceptor.getName()));
                        }
                    }

                    final InterceptorBinding binding = new InterceptorBinding(bean);
                    assemblyDescriptor.getInterceptorBinding().add(0, binding);

                    for (final Class interceptor : interceptors.value()) {
                        binding.getInterceptorClass().add(interceptor.getName());
                    }
                }

                final List<Annotated<Method>> annotatedMethods = sortMethods(annotationFinder.findMetaAnnotatedMethods(Interceptors.class));
                for (final Annotated<Method> method : annotatedMethods) {
                    final Interceptors interceptors = method.getAnnotation(Interceptors.class);
                    if (interceptors != null) {
                        final EjbJar ejbJar = ejbModule.getEjbJar();
                        for (final Class interceptor : interceptors.value()) {
                            if (ejbJar.getInterceptor(interceptor.getName()) == null) {
                                ejbJar.addInterceptor(new Interceptor(interceptor.getName()));
                            }
                        }

                        final InterceptorBinding binding = new InterceptorBinding(bean);
                        assemblyDescriptor.getInterceptorBinding().add(0, binding);

                        for (final Class interceptor : interceptors.value()) {
                            binding.getInterceptorClass().add(interceptor.getName());
                        }

                        binding.setMethod(new NamedMethod(method.get()));
                    }
                }

                /*
                 * @ExcludeDefaultInterceptors
                 */
                final ExcludeDefaultInterceptors excludeDefaultInterceptors = clazz.getAnnotation(ExcludeDefaultInterceptors.class);
                if (excludeDefaultInterceptors != null) {
                    final InterceptorBinding binding = assemblyDescriptor.addInterceptorBinding(new InterceptorBinding(bean));
                    binding.setExcludeDefaultInterceptors(true);
                }

                for (final Annotated<Method> method : annotationFinder.findMetaAnnotatedMethods(ExcludeDefaultInterceptors.class)) {
                    final InterceptorBinding binding = assemblyDescriptor.addInterceptorBinding(new InterceptorBinding(bean));
                    binding.setExcludeDefaultInterceptors(true);
                    binding.setMethod(new NamedMethod(method.get()));
                }

                for (final Annotated<Method> method : sortMethods(annotationFinder.findMetaAnnotatedMethods(ExcludeClassInterceptors.class))) {
                    final InterceptorBinding binding = assemblyDescriptor.addInterceptorBinding(new InterceptorBinding(bean));
                    binding.setExcludeClassInterceptors(true);
                    binding.setMethod(new NamedMethod(method.get()));
                }

                /**
                 * All beans except MDBs have remoting capabilities (busines or legacy interfaces)
                 */
                if (bean instanceof RemoteBean) {
                    final RemoteBean remoteBean = (RemoteBean) bean;

                    /*
                     * @RemoteHome
                     */
                    if (remoteBean.getHome() == null) {
                        final RemoteHome remoteHome = getInheritableAnnotation(clazz, RemoteHome.class);
                        if (remoteHome != null) {
                            final Class<?> homeClass = remoteHome.value();
                            try {
                                Method create = null;
                                for (final Method method : homeClass.getMethods()) {
                                    if (method.getName().startsWith("create")) {
                                        create = method;
                                        break;
                                    }
                                }
                                if (create == null) {
                                    throw new NoSuchMethodException("create");
                                }

                                final Class<?> remoteClass = create.getReturnType();
                                remoteBean.setHome(homeClass.getName());
                                remoteBean.setRemote(remoteClass.getName());
                            } catch (final NoSuchMethodException e) {
                                logger.error("Class annotated as a RemoteHome has no 'create()' method.  Unable to determine remote interface type.  Bean class: " + clazz.getName() + ",  Home class: " + homeClass.getName());
                            }
                        }
                    }

                    /*
                     * @LocalHome
                     */
                    if (remoteBean.getLocalHome() == null) {
                        final LocalHome localHome = getInheritableAnnotation(clazz, LocalHome.class);
                        if (localHome != null) {
                            final Class<?> homeClass = localHome.value();
                            try {
                                Method create = null;
                                for (final Method method : homeClass.getMethods()) {
                                    if (method.getName().startsWith("create")) {
                                        create = method;
                                        break;
                                    }
                                }
                                if (create == null) {
                                    throw new NoSuchMethodException("create");
                                }

                                final Class<?> remoteClass = create.getReturnType();
                                remoteBean.setLocalHome(homeClass.getName());
                                remoteBean.setLocal(remoteClass.getName());
                            } catch (final NoSuchMethodException e) {
                                logger.error("Class annotated as a LocalHome has no 'create()' method.  Unable to determine remote interface type.  Bean class: " + clazz.getName() + ",  Home class: " + homeClass.getName());
                            }
                        }
                    }

                    /*
                     * Annotations specific to @Stateless, @Stateful and @Singleton beans
                     */
                    if (remoteBean instanceof SessionBean) {
                        final SessionBean sessionBean = (SessionBean) remoteBean;

                        // add parents
                        sessionBean.getParents().add(clazz.getName());
                        if (!clazz.isInterface()) {
                            for (Class<?> current = clazz.getSuperclass(); !current.equals(Object.class); current = current.getSuperclass()) {
                                sessionBean.getParents().add(current.getName());
                            }
                        }

                        /*
                        * @Remote
                        * @Local
                        * @WebService
                        * @WebServiceProvider
                        */
                        processSessionInterfaces(sessionBean, clazz, ejbModule);

                        /*
                         * @Asynchronous
                         */
                        processAsynchronous(bean, annotationFinder);

                        /*
                         * Allow for all session bean types
                         * @DependsOn
                         */
                        if (sessionBean.getDependsOn() == null) {
                            final DependsOn dependsOn = getInheritableAnnotation(clazz, DependsOn.class);
                            if (dependsOn != null) {
                                sessionBean.setDependsOn(dependsOn.value());
                            } else {
                                sessionBean.setDependsOn(Collections.EMPTY_LIST);
                            }
                        }

                        /**
                         * Annotations for singletons and stateless
                         */
                        if (sessionBean.getSessionType() != SessionType.STATEFUL) {
                            // REST can be fun
                            if (annotationFinder.isAnnotationPresent(Path.class)) {
                                sessionBean.setRestService(true);
                            }
                        }

                        /*
                         * Annotations specific to @Singleton beans
                         */
                        if (sessionBean.getSessionType() == SessionType.SINGLETON) {

                            /*
                             * @ConcurrencyManagement
                             */
                            if (sessionBean.getConcurrencyManagementType() == null) {
                                final ConcurrencyManagement tx = getInheritableAnnotation(clazz, ConcurrencyManagement.class);
                                javax.ejb.ConcurrencyManagementType concurrencyType = javax.ejb.ConcurrencyManagementType.CONTAINER;
                                if (tx != null) {
                                    concurrencyType = tx.value();
                                }
                                switch (concurrencyType) {
                                    case BEAN:
                                        sessionBean.setConcurrencyManagementType(ConcurrencyManagementType.BEAN);
                                        break;
                                    case CONTAINER:
                                        sessionBean.setConcurrencyManagementType(ConcurrencyManagementType.CONTAINER);
                                        break;
                                }
                            }

                            /*
                             * @Lock
                             */
                            final LockHandler lockHandler = new LockHandler(assemblyDescriptor, sessionBean);
                            if (sessionBean.getConcurrencyManagementType() == ConcurrencyManagementType.CONTAINER) {
                                processAttributes(lockHandler, clazz, annotationFinder);
                            } else {
                                checkAttributes(lockHandler, ejbName, ejbModule, annotationFinder, "invalidConcurrencyAttribute");
                            }

                            /*
                             * @AccessTimeout
                             */
                            final AccessTimeoutHandler accessTimeoutHandler =
                                new AccessTimeoutHandler(assemblyDescriptor, sessionBean, lockHandler.getContainerConcurrency());
                            processAttributes(accessTimeoutHandler, clazz, annotationFinder);

                            /*
                             * @Startup
                             */
                            if (!sessionBean.hasInitOnStartup()) {
                                final Startup startup = getInheritableAnnotation(clazz, Startup.class);
                                sessionBean.setInitOnStartup(startup != null);
                            }

                        } else if (sessionBean.getSessionType() == SessionType.STATEFUL) {
                            /*
                             * Annotations specific to @Stateful beans
                             */

                            /*
                             * @StatefulTimeout
                             */
                            if (sessionBean.getStatefulTimeout() == null) {
                                final StatefulTimeout annotation = getInheritableAnnotation(clazz, StatefulTimeout.class);
                                if (annotation != null) {
                                    final Timeout timeout = new Timeout();
                                    timeout.setTimeout(annotation.value());
                                    timeout.setUnit(annotation.unit());
                                    sessionBean.setStatefulTimeout(timeout);
                                }
                            }

                            /*
                             * @AccessTimeout
                             */
                            final AccessTimeoutHandler accessTimeoutHandler = new AccessTimeoutHandler(assemblyDescriptor, sessionBean);
                            processAttributes(accessTimeoutHandler, clazz, annotationFinder);

                        }
                    }
                }

                if (bean instanceof MessageDrivenBean) {
                    /*
                     * @ActivationConfigProperty
                     */
                    final MessageDrivenBean mdb = (MessageDrivenBean) bean;
                    final MessageDriven messageDriven = clazz.getAnnotation(MessageDriven.class);
                    if (messageDriven != null) {
                        ActivationConfig activationConfig = mdb.getActivationConfig();
                        if (activationConfig == null) {
                            activationConfig = new ActivationConfig();
                        }

                        if (!messageDriven.mappedName().isEmpty()) {
                            if (mdb.getActivationConfig() == null) {
                                mdb.setActivationConfig(activationConfig);
                            }
                            if (!activationConfig.toProperties().containsKey("destinationType")) {
                                activationConfig.addProperty("destinationType", Queue.class.getName());
                            }
                            activationConfig.addProperty("destination", messageDriven.mappedName());
                        }

                        final ActivationConfigProperty[] configProperties = messageDriven.activationConfig();
                        if (configProperties != null) {
                            if (mdb.getActivationConfig() == null) {
                                mdb.setActivationConfig(activationConfig);
                            }

                            final Properties properties = activationConfig.toProperties();
                            for (final ActivationConfigProperty property : configProperties) {
                                if (!properties.containsKey(property.propertyName())) {
                                    activationConfig.addProperty(property.propertyName(), property.propertyValue());
                                }
                            }
                        }

                        if (mdb.getMessagingType() == null) {
                            final Class<?> interfce = messageDriven.messageListenerInterface();
                            if (interfce != null && !interfce.equals(Object.class)) {
                                if (!interfce.isInterface()) {
                                    // TODO: Move this check to o.a.o.c.rules.CheckClasses and do it for all MDBs, annotated or not
                                    throw new OpenEJBException("MessageListenerInterface property of @MessageDriven is not an interface");
                                }
                                mdb.setMessagingType(interfce.getName());
                            }
                        }
                    }

                    /*
                     * Determine the MessageListener interface
                     */
                    if (mdb.getMessagingType() == null) {
                        final List<Class<?>> interfaces = new ArrayList<>();
                        for (final Class<?> intf : clazz.getInterfaces()) {
                            final String name = intf.getName();
                            if (!name.equals("java.io.Serializable") &&
                                !name.equals("java.io.Externalizable") &&
                                !name.startsWith("javax.ejb.") &&
                                !intf.isSynthetic()) {
                                interfaces.add(intf);
                            }
                        }

                        if (interfaces.size() != 1) {
                            StringBuilder msg = new StringBuilder("When annotating a bean class as @MessageDriven without" +
                                    " declaring messageListenerInterface, the bean must implement exactly one interface, no more and" +
                                    " no less. beanClass=" + clazz.getName() + " interfaces=");
                            for (final Class<?> intf : interfaces) {
                                msg.append(intf.getName()).append(", ");
                            }
                            // TODO: Make this a validation failure, not an exception
                            throw new IllegalStateException(msg.toString());
                        }
                        mdb.setMessagingType(interfaces.get(0).getName());
                    }
                }

                buildAnnotatedRefs(bean, annotationFinder, classLoader);

                processWebServiceHandlers(ejbModule, bean, annotationFinder);

                processWebServiceClientHandlers(bean, annotationFinder, classLoader);

                try {
                    if (BeanContext.Comp.class.getName().equals(bean.getEjbClass())) {
                        buildAnnotatedRefs(bean, ejbModule.getFinder(), classLoader);
                    }
                } catch (final OpenEJBException e) {
                    logger.error("Processing of @Resource, @EJB, and other references failed for CDI managed beans", e);
                }
            }

            for (final Interceptor interceptor : ejbModule.getEjbJar().getInterceptors()) {
                final Class<?> clazz;
                try {
                    clazz = classLoader.loadClass(realClassName(interceptor.getInterceptorClass()));
                } catch (final ClassNotFoundException e) {
                    throw new OpenEJBException("Unable to load interceptor class: " + interceptor.getInterceptorClass(), e);
                }

                final AnnotationFinder annotationFinder = createFinder(clazz);

                /*
                 * @PostConstruct
                 * @PreDestroy
                 * @AroundInvoke
                 * @Timeout
                 * @PostActivate
                 * @PrePassivate
                 * @Init
                 * @Remove
                 */
                processCallbacks(interceptor, annotationFinder);

                /*
                 * @ApplicationException
                 */
                processApplicationExceptions(clazz, ejbModule.getEjbJar().getAssemblyDescriptor());

                /*
                 * @EJB
                 * @Resource
                 * @WebServiceRef
                 * @PersistenceUnit
                 * @PersistenceContext
                 */
                buildAnnotatedRefs(interceptor, annotationFinder, classLoader);

                processWebServiceClientHandlers(interceptor, annotationFinder, classLoader);

                /**
                 * Interceptors do not have their own section in ejb-jar.xml for resource references
                 * so we add them to the references of each ejb.  A bit backwards but more or less
                 * mandated by the design of the spec.
                 */
                for (final EnterpriseBean bean : enterpriseBeans) {
                    // Just simply merge the injection targets of the interceptors to enterprise beans
                    mergeJndiReferences(interceptor.getEnvEntryMap(), bean.getEnvEntryMap());
                    mergeJndiReferences(interceptor.getEjbRefMap(), bean.getEjbRefMap());
                    mergeJndiReferences(interceptor.getEjbLocalRefMap(), bean.getEjbLocalRefMap());
                    mergeJndiReferences(interceptor.getResourceRefMap(), bean.getResourceRefMap());
                    mergeJndiReferences(interceptor.getResourceEnvRefMap(), bean.getResourceEnvRefMap());
                    mergeJndiReferences(interceptor.getPersistenceContextRefMap(), bean.getPersistenceContextRefMap());
                    mergeJndiReferences(interceptor.getPersistenceUnitRefMap(), bean.getPersistenceUnitRefMap());
                    mergeJndiReferences(interceptor.getMessageDestinationRefMap(), bean.getMessageDestinationRefMap());
                    mergeJndiReferences(interceptor.getServiceRefMap(), bean.getServiceRefMap());
                }
            }

            return ejbModule;
        }

        private void processAsynchronous(final EnterpriseBean bean, final AnnotationFinder annotationFinder) {
            if (!(bean instanceof SessionBean)) {
                return;
            }

            final SessionBean sessionBean = (SessionBean) bean;

            for (final Annotated<Method> method : annotationFinder.findMetaAnnotatedMethods(Asynchronous.class)) {
                sessionBean.getAsyncMethod().add(new AsyncMethod(method.get()));
            }

            //Spec 4.5.1 @Asynchronous could be used at the class level of a bean-class ( or superclass ).
            //Seems that it should not be used on the any interface view

            for (final Annotated<Class<?>> clazz : annotationFinder.findMetaAnnotatedClasses(Asynchronous.class)) {
                if (!clazz.get().isInterface()) {
                    sessionBean.getAsynchronousClasses().add(clazz.get().getName());
                }
            }
        }

        private <T extends Injectable> void mergeJndiReferences(final Map<String, T> from, final Map<String, T> to) {
            for (final Map.Entry<String, T> entry : from.entrySet()) {
                final Injectable injectable = to.get(entry.getKey());
                if (injectable == null) {
                    to.put(entry.getKey(), entry.getValue());
                } else {
                    injectable.getInjectionTarget().addAll(entry.getValue().getInjectionTarget());
                }
            }
        }

        //TODO why is this necessary, we scan for exceptions with this annotation elsewhere.
        private void processApplicationExceptions(final Class<?> clazz, final AssemblyDescriptor assemblyDescriptor) {
            /*
             * @ApplicationException
             */
            for (final Method method : clazz.getMethods()) {
                for (final Class<?> exception : method.getExceptionTypes()) {
                    final ApplicationException annotation = exception.getAnnotation(ApplicationException.class);
                    if (annotation == null) {
                        continue;
                    }
                    if (assemblyDescriptor.getApplicationException(exception) != null) {
                        mergeApplicationExceptionAnnotation(assemblyDescriptor, exception, annotation);
                    } else {
                        logger.debug("Found previously undetected application exception {0} listed on a method {1} with annotation {2}", method, exception, annotation);
                        assemblyDescriptor.addApplicationException(exception, annotation.rollback(), annotation.inherited());
                    }
                }
            }
        }

        private void processSessionInterfaces(final SessionBean sessionBean, final Class<?> beanClass, final EjbModule ejbModule) {

            final ValidationContext validation = ejbModule.getValidation();
            final String ejbName = sessionBean.getEjbName();

            final boolean strict = getProperty(STRICT_INTERFACE_DECLARATION, "false").equalsIgnoreCase("true");

            /*
             * Collect all interfaces explicitly declared via xml.
             * We will subtract these from the interfaces implemented
             * by the bean and do annotation scanning on the remainder.
             */
            final List<String> descriptor = new ArrayList<>();
            descriptor.add(sessionBean.getHome());
            descriptor.add(sessionBean.getRemote());
            descriptor.add(sessionBean.getLocalHome());
            descriptor.add(sessionBean.getLocal());
            descriptor.addAll(sessionBean.getBusinessLocal());
            descriptor.addAll(sessionBean.getBusinessRemote());
            descriptor.add(sessionBean.getServiceEndpoint());

            final BusinessInterfaces xml = new BusinessInterfaces();
            xml.addLocals(sessionBean.getBusinessLocal(), ejbModule.getClassLoader());
            xml.addRemotes(sessionBean.getBusinessRemote(), ejbModule.getClassLoader());

            if (beanClass.getAnnotation(LocalBean.class) != null) {
                sessionBean.setLocalBean(new Empty());
            }

            /**
             * Anything declared as both <business-local> and <business-remote> is invalid in strict mode
             */
            if (strict) {
                for (final Class interfce : xml.local) {
                    if (xml.remote.contains(interfce)) {
                        validation.fail(ejbName, "xml.localRemote.conflict", interfce.getName());
                    }
                }
            }

            /**
             * Merge the xml declared business interfaces into the complete set
             */
            final BusinessInterfaces all = new BusinessInterfaces();
            all.local.addAll(xml.local);
            all.remote.addAll(xml.remote);

            final List<Class<?>> classes = strict ? new ArrayList(Collections.singletonList(beanClass)) : Classes.ancestors(beanClass);

            for (final Class<?> clazz : classes) {

                /*
                 * @WebService
                 * @WebServiceProvider
                 */
                Class<?> webServiceItf = null;
                if (sessionBean.getServiceEndpoint() == null) {
                    Class defaultEndpoint = BeanContext.ServiceEndpoint.class;

                    for (final Class interfce : clazz.getInterfaces()) {
                        if (interfce.isAnnotationPresent(WebService.class)) {
                            defaultEndpoint = interfce;
                            webServiceItf = interfce;
                        }
                    }

                    final WebService webService = clazz.getAnnotation(WebService.class);
                    if (webService != null) {

                        final String className = webService.endpointInterface();

                        if (!className.isEmpty()) {
                            sessionBean.setServiceEndpoint(className);
                        } else {
                            sessionBean.setServiceEndpoint(defaultEndpoint.getName());
                        }
                    } else if (clazz.isAnnotationPresent(WebServiceProvider.class)) {
                        sessionBean.setServiceEndpoint(defaultEndpoint.getName());
                    } else if (!defaultEndpoint.equals(BeanContext.ServiceEndpoint.class)) {
                        sessionBean.setServiceEndpoint(defaultEndpoint.getName());
                    }
                }

                /*
                 * These interface types are not eligable to be business interfaces.
                 * java.io.Serializable
                 * java.io.Externalizable
                 * javax.ejb.*
                 */
                final List<Class<?>> interfaces = new ArrayList<>();
                if (!clazz.isInterface()) { // dynamic proxy implementation
                    for (final Class<?> interfce : clazz.getInterfaces()) {
                        final String name = interfce.getName();
                        if (!name.equals("scala.ScalaObject") &&
                            !name.equals("groovy.lang.GroovyObject") &&
                            !name.equals("java.io.Serializable") &&
                            !name.equals("java.io.Externalizable") &&
                            !(name.equals(InvocationHandler.class.getName()) && DynamicSubclass.isDynamic(beanClass)) &&
                            !name.startsWith("javax.ejb.") &&
                            !descriptor.contains(interfce.getName()) &&
                            !interfce.isSynthetic() &&
                            !"net.sourceforge.cobertura.coveragedata.HasBeenInstrumented".equals(name) &&
                            !name.startsWith("org.scalatest.")) {
                            interfaces.add(interfce);
                        }
                    }
                }

                /**
                 * Anything discovered and delcared in a previous loop
                 * or at the beginning in the deployment descriptor is
                 * not eligable to be redefined.
                 */
                interfaces.removeAll(all.local);
                interfaces.removeAll(all.remote);

                /**
                 * OK, now start checking the class metadata
                 */
                final Local local = clazz.getAnnotation(Local.class);
                final Remote remote = clazz.getAnnotation(Remote.class);

                final boolean impliedLocal = local != null && local.value().length == 0;
                final boolean impliedRemote = remote != null && remote.value().length == 0;

                /**
                 * This set holds the values of @Local and @Remote
                 * when applied to the bean class itself
                 *
                 * These declarations override any similar declaration
                 * on the interface.
                 */
                final BusinessInterfaces bean = new BusinessInterfaces();
                if (local != null) {
                    bean.local.addAll(Arrays.asList(local.value()));
                }
                if (remote != null) {
                    bean.remote.addAll(Arrays.asList(remote.value()));
                }

                if (strict) {
                    for (final Class interfce : bean.local) {
                        if (bean.remote.contains(interfce)) {
                            validation.fail(ejbName, "ann.localRemote.conflict", interfce.getName());
                        }
                    }
                }

                /**
                 * Anything listed explicitly via @Local or @Remote
                 * on the bean class does not need to be investigated.
                 * We do not need to check these interfaces for @Local or @Remote
                 */
                interfaces.removeAll(bean.local);
                interfaces.removeAll(bean.remote);

                if (impliedLocal || impliedRemote) {
                    if (interfaces.size() != 1) {
                        /**
                         * Cannot imply either @Local or @Remote and list multiple interfaces
                         */
                        // Need to extract the class names and append .class to them to show proper validation level 3 message
                        final List<String> interfaceNames = new ArrayList<>();
                        for (final Class<?> intrfce : interfaces) {
                            interfaceNames.add(intrfce.getName() + ".class");
                        }

                        // just warn for @Local since Glassfish supports it even if it is weird
                        // still fail for @Remote!
                        if (impliedLocal && local.value().length == 0 && interfaces.size() == 0 && !strict) {
                            validation.warn(ejbName, "ann.local.forLocalBean", Join.join(", ", interfaceNames));
                            // we don't go out to let be deployed
                        } else if (impliedLocal) {
                            validation.fail(ejbName, "ann.local.noAttributes", Join.join(", ", interfaceNames));
                            /**
                             * This bean is invalid, so do not bother looking at the other interfaces or the superclass
                             */
                            return;
                        }
                        if (impliedRemote) {
                            validation.fail(ejbName, "ann.remote.noAttributes", Join.join(", ", interfaceNames));
                            /**
                             * This bean is invalid, so do not bother looking at the other interfaces or the superclass
                             */
                            return;
                        }
                    } else if (strict && impliedLocal && impliedRemote) {
                        final Class<?> interfce = interfaces.remove(0);
                        /**
                         * Cannot imply @Local and @Remote at the same time with strict mode on
                         */
                        validation.fail(ejbName, "ann.localRemote.ambiguous", interfce.getName());
                    } else {
                        if (impliedLocal) {
                            bean.local.addAll(interfaces);
                        }
                        if (impliedRemote) {
                            bean.remote.addAll(interfaces);
                        }

                        interfaces.clear();
                    }
                }

                /**
                 * OK, now start checking the metadata of the interfaces implemented by this class
                 */

                /**
                 * This set holds the list of interfaces that the bean implements
                 * that are annotated either as @Local or @Remote
                 *
                 * If the interface is annotated to the contrary in the bean class
                 * the bean class meta data wins, therefore we track these separately
                 *
                 * Ultimately, the deployment descriptor wins over all, so we have tracked
                 * those declarations separately as well.
                 */
                final BusinessInterfaces implemented = new BusinessInterfaces();

                for (final Class interfce : interfaces) {
                    final boolean isLocal = interfce.isAnnotationPresent(Local.class);
                    final boolean isRemote = interfce.isAnnotationPresent(Remote.class);

                    if (strict && isLocal && isRemote) {
                        validation.fail(ejbName, "ann.localRemote.conflict", interfce.getName());
                    } else {
                        final Class[] superInterface = interfce.getInterfaces();
                        if (isLocal) {
                            if (strict) {
                                for (final Class si : superInterface) {
                                    final boolean present = si.isAnnotationPresent(Remote.class);
                                    if (present) {
                                        validation.fail(ejbName, "ann.remoteOrLocal.converse.parent", interfce.getName(), "Local", si.getName(), "Remote");
                                    }
                                }
                            }
                            implemented.local.add(interfce);
                        }
                        if (isRemote) {
                            if (strict) {
                                for (final Class si : superInterface) {
                                    final boolean present = si.isAnnotationPresent(Local.class);
                                    if (present) {
                                        validation.fail(ejbName, "ann.remoteOrLocal.converse.parent", interfce.getName(), "Remote", si.getName(), "Local");
                                    }
                                }
                            }
                            implemented.remote.add(interfce);
                        }
                    }

                }

                interfaces.removeAll(implemented.local);
                interfaces.removeAll(implemented.remote);


                /**
                 * Merge in class-level metadata.
                 *
                 * We've already merged in the xml metadata, so that
                 * metadata will win over this metadata.
                 */

                // remove anything we've already seen
                bean.local.removeAll(all.local);
                bean.local.removeAll(all.remote);
                bean.remote.removeAll(all.remote);
                bean.remote.removeAll(all.local);

                // validate the things we are going to add
                for (final Class interfce : bean.local) {
                    validateLocalInterface(interfce, validation, ejbName);
                }
                for (final Class interfce : bean.remote) {
                    validateRemoteInterface(interfce, validation, ejbName);
                }

                // add finally, add them
                all.local.addAll(bean.local);
                all.remote.addAll(bean.remote);


                /**
                 * Merge in interface-level metadata
                 *
                 * We've already merged in the xml metadata *and* class metadata,
                 * so both of those will win over this metadata.
                 */

                // remove anything we've already seen
                implemented.local.removeAll(all.local);
                implemented.local.removeAll(all.remote);
                implemented.remote.removeAll(all.remote);
                implemented.remote.removeAll(all.local);

                // validate the things we are going to add
                for (final Class interfce : implemented.local) {
                    validateLocalInterface(interfce, validation, ejbName);
                }
                for (final Class interfce : implemented.remote) {
                    validateRemoteInterface(interfce, validation, ejbName);
                }

                // add the rest
                all.local.addAll(implemented.local);
                all.remote.addAll(implemented.remote);


                // We only consider the top-most class (the bean class itself) when evaluating
                // the case of absolutely no metadata at all and attempting to figure out the
                // default view which will be implied as either @LocalBean or @Local
                if (clazz == beanClass
                    && sessionBean.getLocalBean() == null
                    && sessionBean.getBusinessLocal().isEmpty()
                    && sessionBean.getBusinessRemote().isEmpty()
                    && sessionBean.getHome() == null
                    && sessionBean.getRemote() == null
                    && sessionBean.getLocalHome() == null
                    && sessionBean.getLocal() == null
                    && all.local.isEmpty()
                    && all.remote.isEmpty()
                    ) {

                    if (interfaces.size() == 0 || DynamicProxyImplFactory.isKnownDynamicallyImplemented(clazz)) {
                        // No interfaces?  Then @LocalBean

                        sessionBean.setLocalBean(new Empty());

                    } else if (interfaces.size() == 1) {
                        // One interface?  Then @Local

                        all.local.add(interfaces.remove(0));

                    } else {
                        // Multiple interfaces?  Illegal
                        validation.fail(ejbName, "too.many.interfaces", ejbName, interfaces.toString().replace("interface ", ""));
                        return;
                    }
                }

                // do it here to not loose the @Local handling (if (interfaces.size() == 1))
                if (webserviceAsRemote
                    && webServiceItf != null
                    && all.remote.isEmpty()) {
                    all.remote.add(webServiceItf);
                }

                //alway set Local View for ManagedBean
                if (beanClass.isAnnotationPresent(ManagedBean.class)) {
                    sessionBean.setLocalBean(new Empty());
                }
            }

            // Finally, add all the business interfaces we found
            for (final Class interfce : all.local) {
                sessionBean.addBusinessLocal(interfce);
            }
            for (final Class interfce : all.remote) {
                sessionBean.addBusinessRemote(interfce);
            }
        }

        private static class BusinessInterfaces {
            private final Set<Class> local = new LinkedHashSet<>();
            private final Set<Class> remote = new LinkedHashSet<>();

            public void addLocals(final Collection<String> names, final ClassLoader loader) {
                add(loader, names, local);
            }

            public void addRemotes(final Collection<String> names, final ClassLoader loader) {
                add(loader, names, remote);
            }

            private void add(final ClassLoader loader, final Collection<String> names, final Set<Class> classes) {
                for (final String className : names) {
                    try {
                        classes.add(loader.loadClass(realClassName(className)));
                    } catch (final Throwable t) {
                        // handled in validation
                    }
                }
            }
        }

        private String getProperty(final String key, final String defaultValue) {
            String value = SystemInstance.get().getOptions().get(key, defaultValue);
            final DeploymentModule module = getModule();

            if (module instanceof EjbModule) {
                final EjbModule ejbModule = (EjbModule) module;

                final OpenejbJar openejbJar = ejbModule.getOpenejbJar();
                if (openejbJar != null && openejbJar.getProperties() != null) {
                    value = openejbJar.getProperties().getProperty(key, value);
                }
            }
            return value;
        }

        private void processSecurityAnnotations(final Class<?> beanClass, final String ejbName, final EjbModule ejbModule, final AnnotationFinder annotationFinder, final EnterpriseBean bean) {
            final AssemblyDescriptor assemblyDescriptor = ejbModule.getEjbJar().getAssemblyDescriptor();

            final List<String> classPermissions = getDeclaredClassPermissions(assemblyDescriptor, ejbName);

            for (final Class<?> clazzz : Classes.ancestors(beanClass)) {
                final MetaAnnotatedClass<?> clazz = new MetaAnnotatedClass(clazzz);
                /*
                 * Process annotations at the class level
                 */
                if (!classPermissions.contains("*") || !classPermissions.contains(clazz.getName())) {

                    final RolesAllowed rolesAllowed = clazz.getAnnotation(RolesAllowed.class);
                    final PermitAll permitAll = clazz.getAnnotation(PermitAll.class);
                    final DenyAll denyAll = clazz.getAnnotation(DenyAll.class);

                    /*
                     * @RolesAllowed
                     */
                    if ((rolesAllowed != null && permitAll != null)
                        || (rolesAllowed != null && denyAll != null)
                        || (permitAll != null && denyAll != null)) {
                        ejbModule.getValidation().fail(ejbName, "permitAllAndRolesAllowedOnClass", clazz.getName());
                    }

                    if (rolesAllowed != null) {
                        final MethodPermission methodPermission = new MethodPermission();
                        methodPermission.getRoleName().addAll(Arrays.asList(rolesAllowed.value()));
                        methodPermission.getMethod().add(new org.apache.openejb.jee.Method(ejbName, clazz.getName(), "*"));
                        assemblyDescriptor.getMethodPermission().add(methodPermission);

                        // Automatically add a role ref for any role listed in RolesAllowed
                        final RemoteBean remoteBean = (RemoteBean) bean;
                        final List<SecurityRoleRef> securityRoleRefs = remoteBean.getSecurityRoleRef();
                        for (final String role : rolesAllowed.value()) {
                            securityRoleRefs.add(new SecurityRoleRef(role));
                        }
                    }

                    /*
                     * @PermitAll
                     */
                    if (permitAll != null) {
                        final MethodPermission methodPermission = new MethodPermission();
                        methodPermission.setUnchecked(true);
                        methodPermission.getMethod().add(new org.apache.openejb.jee.Method(ejbName, clazz.getName(), "*"));
                        assemblyDescriptor.getMethodPermission().add(methodPermission);
                    }

                    /**
                     * @DenyAll
                     */
                    if (denyAll != null) {
                        assemblyDescriptor.getExcludeList()
                            .addMethod(new org.apache.openejb.jee.Method(ejbName, clazz.getName(), "*"));
                    }
                }

                /*
                 * @RunAs
                 */
                final RunAs runAs = clazz.getAnnotation(RunAs.class);
                if (runAs != null && bean.getSecurityIdentity() == null) {
                    final SecurityIdentity securityIdentity = new SecurityIdentity();
                    securityIdentity.setRunAs(runAs.value());
                    bean.setSecurityIdentity(securityIdentity);
                }

                /*
                 * @DeclareRoles
                 */
                final DeclareRoles declareRoles = clazz.getAnnotation(DeclareRoles.class);
                if (declareRoles != null && bean instanceof RemoteBean) {
                    final RemoteBean remoteBean = (RemoteBean) bean;
                    final List<SecurityRoleRef> securityRoleRefs = remoteBean.getSecurityRoleRef();
                    for (final String role : declareRoles.value()) {
                        securityRoleRefs.add(new SecurityRoleRef(role));
                    }
                }
            }

            /*
             * Process annotations at the method level
             */
            final List<Method> seen = new ArrayList<>();

            /*
             * @RolesAllowed
             */
            for (final Annotated<Method> method : annotationFinder.findMetaAnnotatedMethods(RolesAllowed.class)) {
                checkConflictingSecurityAnnotations(method, ejbName, ejbModule, seen);
                final RolesAllowed rolesAllowed = method.getAnnotation(RolesAllowed.class);
                final MethodPermission methodPermission = new MethodPermission();
                methodPermission.getRoleName().addAll(Arrays.asList(rolesAllowed.value()));
                methodPermission.getMethod().add(new org.apache.openejb.jee.Method(ejbName, method.get()));
                assemblyDescriptor.getMethodPermission().add(methodPermission);

                // Automatically add a role ref for any role listed in RolesAllowed
                final RemoteBean remoteBean = (RemoteBean) bean;
                final List<SecurityRoleRef> securityRoleRefs = remoteBean.getSecurityRoleRef();
                for (final String role : rolesAllowed.value()) {
                    securityRoleRefs.add(new SecurityRoleRef(role));
                }
            }

            /*
             * @PermitAll
             */
            for (final Annotated<Method> method : annotationFinder.findMetaAnnotatedMethods(PermitAll.class)) {
                checkConflictingSecurityAnnotations(method, ejbName, ejbModule, seen);
                final MethodPermission methodPermission = new MethodPermission();
                methodPermission.setUnchecked(true);
                methodPermission.getMethod().add(new org.apache.openejb.jee.Method(ejbName, method.get()));
                assemblyDescriptor.getMethodPermission().add(methodPermission);
            }

            /*
             * @DenyAll
             */
            for (final Annotated<Method> method : annotationFinder.findMetaAnnotatedMethods(DenyAll.class)) {
                checkConflictingSecurityAnnotations(method, ejbName, ejbModule, seen);
                final ExcludeList excludeList = assemblyDescriptor.getExcludeList();
                excludeList.addMethod(new org.apache.openejb.jee.Method(ejbName, method.get()));
            }

        }

        /**
         * Validation
         *
         * Conflicting use of @RolesAllowed, @PermitAll, and @DenyAll
         *
         * @param method
         * @param ejbName
         * @param ejbModule
         * @param seen
         */
        private void checkConflictingSecurityAnnotations(final Annotated<Method> method, final String ejbName, final EjbModule ejbModule, final List<Method> seen) {
            if (seen.contains(method.get())) {
                return;
            } else {
                seen.add(method.get());
            }

            final List<String> annotations = new ArrayList<>();
            for (final Class<? extends Annotation> annotation : Arrays.asList(RolesAllowed.class, PermitAll.class, DenyAll.class)) {
                if (method.getAnnotation(annotation) != null) {
                    annotations.add("@" + annotation.getSimpleName());
                }
            }

            if (annotations.size() > 1) {
                ejbModule.getValidation().fail(ejbName, "conflictingSecurityAnnotations", method.get().getName(), Join.join(" and ", annotations), method.get().getDeclaringClass());
            }
        }

        private void processSchedules(final EnterpriseBean bean, final AnnotationFinder annotationFinder) {
            if (!(bean instanceof TimerConsumer)) {
                return;
            }
            final TimerConsumer timerConsumer = (TimerConsumer) bean;
            final Set<Annotated<Method>> scheduleMethods = new HashSet<>();
            scheduleMethods.addAll(annotationFinder.findMetaAnnotatedMethods(Schedules.class));
            scheduleMethods.addAll(annotationFinder.findMetaAnnotatedMethods(Schedule.class));

            final List<Timer> timers = timerConsumer.getTimer();

            // TODO : The NamedMethod object implements equals and hashCode, so we could rely on that rather than collecting strings
            final Set<String> methodsConfiguredInDeploymentXml = new HashSet<>();
            for (final Timer timer : timers) {
                final NamedMethod namedMethod = timer.getTimeoutMethod();
                methodsConfiguredInDeploymentXml.add(namedMethod.getMethodName() + (namedMethod.getMethodParams() == null ? "" : Join.join("", namedMethod.getMethodParams().getMethodParam())));
            }

            for (final Annotated<Method> method : scheduleMethods) {

                // Don't add the schedules from annotations if the schedules have been
                // supplied for this method via xml.  The xml is considered an override.
                if (methodsConfiguredInDeploymentXml.contains(method.get().getName() + Join.join("", (Object[]) asStrings(method.get().getParameterTypes())))) {
                    continue;
                }

                final List<Schedule> scheduleAnnotationList = new ArrayList<>();

                final Schedules schedulesAnnotation = method.getAnnotation(Schedules.class);
                if (schedulesAnnotation != null) {
                    scheduleAnnotationList.addAll(Arrays.asList(schedulesAnnotation.value()));
                }

                final Schedule scheduleAnnotation = method.getAnnotation(Schedule.class);
                if (scheduleAnnotation != null) {
                    scheduleAnnotationList.add(scheduleAnnotation);
                }

                for (final Schedule schedule : scheduleAnnotationList) {
                    final Timer timer = new Timer();
                    timer.setPersistent(schedule.persistent());
                    timer.setInfo(schedule.info() == null || schedule.info().isEmpty() ? null : schedule.info());
                    timer.setTimezone(schedule.timezone() == null || schedule.timezone().isEmpty() ? null : schedule.timezone());
                    //Copy TimerSchedule
                    final TimerSchedule timerSchedule = new TimerSchedule();
                    timerSchedule.setSecond(schedule.second());
                    timerSchedule.setMinute(schedule.minute());
                    timerSchedule.setHour(schedule.hour());
                    timerSchedule.setDayOfWeek(schedule.dayOfWeek());
                    timerSchedule.setDayOfMonth(schedule.dayOfMonth());
                    timerSchedule.setMonth(schedule.month());
                    timerSchedule.setYear(schedule.year());
                    timer.setSchedule(timerSchedule);
                    //Copy Method Signature
                    timer.setTimeoutMethod(new NamedMethod(method.get()));

                    timers.add(timer);
                }
            }
        }

        private void processCallbacks(final Lifecycle bean, final AnnotationFinder annotationFinder) {

            final boolean override = "true".equalsIgnoreCase(getProperty("openejb.callbacks.override", "false"));

            /*
             * @PostConstruct
             */
            if (apply(override, bean.getPostConstruct())) {
                for (final Annotated<Method> method : sortMethods(annotationFinder.findMetaAnnotatedMethods(PostConstruct.class))) {
                    bean.getPostConstruct().add(new LifecycleCallback(method.get()));
                }
            }

            /*
             * @PreDestroy
             */
            if (apply(override, bean.getPreDestroy())) {
                for (final Annotated<Method> method : sortMethods(annotationFinder.findMetaAnnotatedMethods(PreDestroy.class))) {
                    bean.getPreDestroy().add(new LifecycleCallback(method.get()));
                }
            }

            if (bean instanceof Invokable) {
                final Invokable invokable = (Invokable) bean;

                /*
                 * @AroundInvoke
                 */
                if (apply(override, invokable.getAroundInvoke())) {
                    for (final Annotated<Method> method : sortMethods(annotationFinder.findMetaAnnotatedMethods(javax.interceptor.AroundInvoke.class))) {
                        invokable.getAroundInvoke().add(new AroundInvoke(method.get()));
                    }
                }

                /*
                 *  @AroundTimeout
                 */
                if (apply(override, invokable.getAroundTimeout())) {
                    for (final Annotated<Method> method : sortMethods(annotationFinder.findMetaAnnotatedMethods(javax.interceptor.AroundTimeout.class))) {
                        invokable.getAroundTimeout().add(new AroundTimeout(method.get()));
                    }
                }
            }

            /*
             * @Timeout
             */
            if (bean instanceof TimerConsumer) {
                final TimerConsumer timerConsumer = (TimerConsumer) bean;
                if (timerConsumer.getTimeoutMethod() == null) {
                    final List<Annotated<Method>> timeoutMethods = sortMethods(annotationFinder.findMetaAnnotatedMethods(javax.ejb.Timeout.class));
                    //Validation Logic is moved to CheckCallback class.
                    if (timeoutMethods.size() >= 1) {
                        // Use the timeout method most near the child class because
                        // the timeout method in child class will override the timeout method in super classes
                        timerConsumer.setTimeoutMethod(new NamedMethod(timeoutMethods.get(timeoutMethods.size() - 1).get()));
                    }
                }
            }

            if (bean instanceof Session) {
                final Session session = (Session) bean;

                /*
                 * @AfterBegin
                 */
                final LifecycleCallback afterBegin = getFirst(session.getAfterBegin());
                if (afterBegin == null) {
                    for (final Annotated<Method> method : sortMethods(annotationFinder.findMetaAnnotatedMethods(AfterBegin.class))) {
                        session.getAfterBegin().add(new LifecycleCallback(method.get()));
                    }
                }

                /*
                 * @BeforeCompletion
                 */
                final LifecycleCallback beforeCompletion = getFirst(session.getBeforeCompletion());
                if (beforeCompletion == null) {
                    for (final Annotated<Method> method : sortMethods(annotationFinder.findMetaAnnotatedMethods(BeforeCompletion.class))) {
                        session.getBeforeCompletion().add(new LifecycleCallback(method.get()));
                    }
                }

                /*
                 * @AfterCompletion
                 */
                final LifecycleCallback afterCompletion = getFirst(session.getAfterCompletion());
                if (afterCompletion == null) {
                    for (final Annotated<Method> method : sortMethods(annotationFinder.findMetaAnnotatedMethods(AfterCompletion.class))) {
                        session.getAfterCompletion().add(new LifecycleCallback(method.get()));
                    }
                }

                /*
                 * @PostActivate
                 */
                if (apply(override, session.getPostActivate())) {
                    for (final Annotated<Method> method : sortMethods(annotationFinder.findMetaAnnotatedMethods(PostActivate.class))) {
                        session.getPostActivate().add(new LifecycleCallback(method.get()));
                    }
                }

                /*
                 * @PrePassivate
                 */
                if (apply(override, session.getPrePassivate())) {
                    for (final Annotated<Method> method : sortMethods(annotationFinder.findMetaAnnotatedMethods(PrePassivate.class))) {
                        session.getPrePassivate().add(new LifecycleCallback(method.get()));
                    }
                }
                /*
                 * @Init
                 */
                for (final Annotated<Method> method : sortMethods(annotationFinder.findMetaAnnotatedMethods(Init.class))) {
                    final InitMethod initMethod = new InitMethod(method.get());

                    final Init init = method.getAnnotation(Init.class);
                    if (init.value() != null && !init.value().isEmpty()) {
                        initMethod.setCreateMethod(init.value());
                    }

                    session.getInitMethod().add(initMethod);
                }

                /*
                 * @Remove
                 */
                final List<Annotated<Method>> removeMethods = sortMethods(annotationFinder.findMetaAnnotatedMethods(Remove.class));
                final Map<NamedMethod, RemoveMethod> declaredRemoveMethods = new HashMap<>();
                for (final RemoveMethod removeMethod : session.getRemoveMethod()) {
                    declaredRemoveMethods.put(removeMethod.getBeanMethod(), removeMethod);
                }
                for (final Annotated<Method> method : removeMethods) {
                    final Remove remove = method.getAnnotation(Remove.class);
                    final RemoveMethod removeMethod = new RemoveMethod(method.get(), remove.retainIfException());

                    final RemoveMethod declaredRemoveMethod = declaredRemoveMethods.get(removeMethod.getBeanMethod());

                    if (declaredRemoveMethod == null) {
                        session.getRemoveMethod().add(removeMethod);
                    } else if (!declaredRemoveMethod.isExplicitlySet()) {
                        declaredRemoveMethod.setRetainIfException(remove.retainIfException());
                    }
                }
            }
        }

        private boolean apply(final boolean override, final List<?> list) {
            // Compliant behavior is to always add the annotated callbacks
            // into the list of xml configured callbacks

            // Legacy behavior was to not apply the annotations to the list
            // if there were any of the related elements specified in the xml

            // if we are *not* using the legacy logic, always return true
            if (!override) {
                return true;
            }

            // if we are using that logic, then only return true if the list is empty
            // i.e. we will not augment the list if callbacks have been specified in xml
            return list.size() == 0;
        }

        public void buildAnnotatedRefs(final JndiConsumer consumer, final IAnnotationFinder annotationFinder, final ClassLoader classLoader) throws OpenEJBException {
            //
            // @EJB
            //

            final List<EJB> ejbList = new ArrayList<>();
            for (final Annotated<Class<?>> clazz : annotationFinder.findMetaAnnotatedClasses(EJBs.class)) {
                final EJBs ejbs = clazz.getAnnotation(EJBs.class);
                ejbList.addAll(Arrays.asList(ejbs.value()));
            }
            for (final Annotated<Class<?>> clazz : annotationFinder.findMetaAnnotatedClasses(EJB.class)) {
                final EJB e = clazz.getAnnotation(EJB.class);
                ejbList.add(e);
            }

            for (final EJB ejb : ejbList) {
                buildEjbRef(consumer, ejb, null);
            }

            for (final Annotated<Field> field : annotationFinder.findMetaAnnotatedFields(EJB.class)) {
                final EJB ejb = field.getAnnotation(EJB.class);

                final Member member = new FieldMember(field.get());

                buildEjbRef(consumer, ejb, member);
            }

            for (final Annotated<Method> method : annotationFinder.findMetaAnnotatedMethods(EJB.class)) {
                final EJB ejb = method.getAnnotation(EJB.class);

                final Member member = new MethodMember(method.get());

                buildEjbRef(consumer, ejb, member);
            }

            //
            // @Resource
            //

            final List<Resource> resourceList = new ArrayList<>();
            for (final Annotated<Class<?>> clazz : annotationFinder.findMetaAnnotatedClasses(Resources.class)) {
                final Resources resources = clazz.getAnnotation(Resources.class);
                resourceList.addAll(Arrays.asList(resources.value()));
            }
            for (final Annotated<Class<?>> clazz : annotationFinder.findMetaAnnotatedClasses(Resource.class)) {
                final Resource resource = clazz.getAnnotation(Resource.class);
                resourceList.add(resource);
            }

            for (final Resource resource : resourceList) {
                buildResource(consumer, resource, null);
            }

            for (final Annotated<Field> field : annotationFinder.findMetaAnnotatedFields(Resource.class)) {
                final Resource resource = field.getAnnotation(Resource.class);

                final Member member = new FieldMember(field.get());

                buildResource(consumer, resource, member);
            }

            for (final Annotated<Method> method : annotationFinder.findMetaAnnotatedMethods(Resource.class)) {
                final Resource resource = method.getAnnotation(Resource.class);

                final Member member = new MethodMember(method.get());

                buildResource(consumer, resource, member);
            }

            //
            // @Context (REST)
            //
            for (final Annotated<Field> field : annotationFinder.findMetaAnnotatedFields(Context.class)) {
                final Member member = new FieldMember(field.get());
                buildContext(consumer, member);
            }

            //
            // @WebServiceRef
            //

            final List<WebServiceRef> webservicerefList = new ArrayList<>();
            for (final Annotated<Class<?>> clazz : annotationFinder.findMetaAnnotatedClasses(WebServiceRefs.class)) {
                final WebServiceRefs webServiceRefs = clazz.getAnnotation(WebServiceRefs.class);
                webservicerefList.addAll(Arrays.asList(webServiceRefs.value()));
            }
            for (final Annotated<Class<?>> clazz : annotationFinder.findMetaAnnotatedClasses(WebServiceRef.class)) {
                final WebServiceRef webServiceRef = clazz.getAnnotation(WebServiceRef.class);
                webservicerefList.add(webServiceRef);
            }

            for (final WebServiceRef webserviceref : webservicerefList) {

                buildWebServiceRef(consumer, webserviceref, null, null, classLoader);
            }

            for (final Annotated<Field> field : annotationFinder.findMetaAnnotatedFields(WebServiceRef.class)) {
                final WebServiceRef webserviceref = field.getAnnotation(WebServiceRef.class);
                final HandlerChain handlerChain = field.getAnnotation(HandlerChain.class);

                final Member member = new FieldMember(field.get());

                buildWebServiceRef(consumer, webserviceref, handlerChain, member, classLoader);
            }

            for (final Annotated<Method> method : annotationFinder.findMetaAnnotatedMethods(WebServiceRef.class)) {
                final WebServiceRef webserviceref = method.getAnnotation(WebServiceRef.class);
                final HandlerChain handlerChain = method.getAnnotation(HandlerChain.class);

                final Member member = new MethodMember(method.get());

                buildWebServiceRef(consumer, webserviceref, handlerChain, member, classLoader);
            }

            //
            // @PersistenceUnit
            //

            final List<PersistenceUnit> persistenceUnitList = new ArrayList<>();
            for (final Annotated<Class<?>> clazz : annotationFinder.findMetaAnnotatedClasses(PersistenceUnits.class)) {
                final PersistenceUnits persistenceUnits = clazz.getAnnotation(PersistenceUnits.class);
                persistenceUnitList.addAll(Arrays.asList(persistenceUnits.value()));
            }
            for (final Annotated<Class<?>> clazz : annotationFinder.findMetaAnnotatedClasses(PersistenceUnit.class)) {
                final PersistenceUnit persistenceUnit = clazz.getAnnotation(PersistenceUnit.class);
                persistenceUnitList.add(persistenceUnit);
            }
            for (final PersistenceUnit pUnit : persistenceUnitList) {
                buildPersistenceUnit(consumer, pUnit, null);
            }
            for (final Annotated<Field> field : annotationFinder.findMetaAnnotatedFields(PersistenceUnit.class)) {
                final PersistenceUnit pUnit = field.getAnnotation(PersistenceUnit.class);
                final Member member = new FieldMember(field.get());
                buildPersistenceUnit(consumer, pUnit, member);
            }
            for (final Annotated<Method> method : annotationFinder.findMetaAnnotatedMethods(PersistenceUnit.class)) {
                final PersistenceUnit pUnit = method.getAnnotation(PersistenceUnit.class);
                final Member member = new MethodMember(method.get());
                buildPersistenceUnit(consumer, pUnit, member);
            }

            //
            // @PersistenceContext
            //

            final PersistenceContextAnnFactory pcFactory = new PersistenceContextAnnFactory();
            final List<PersistenceContext> persistenceContextList = new ArrayList<>();
            for (final Annotated<Class<?>> clazz : annotationFinder.findMetaAnnotatedClasses(PersistenceContexts.class)) {
                final PersistenceContexts persistenceContexts = clazz.getAnnotation(PersistenceContexts.class);
                persistenceContextList.addAll(Arrays.asList(persistenceContexts.value()));
                pcFactory.addAnnotations(clazz.get());
            }
            for (final Annotated<Class<?>> clazz : annotationFinder.findMetaAnnotatedClasses(PersistenceContext.class)) {
                final PersistenceContext persistenceContext = clazz.getAnnotation(PersistenceContext.class);
                persistenceContextList.add(persistenceContext);
                pcFactory.addAnnotations(clazz.get());

                // dynamic proxy implementation
                if (clazz.get().isInterface()) {
                    final Member member = new FilledMember("em", EntityManager.class, clazz.get());

                    buildPersistenceContext(consumer, pcFactory.create(persistenceContext, member), member);
                }
            }
            for (final PersistenceContext pCtx : persistenceContextList) {
                buildPersistenceContext(consumer, pcFactory.create(pCtx, null), null);
            }
            for (final Annotated<Field> field : annotationFinder.findMetaAnnotatedFields(PersistenceContext.class)) {
                final PersistenceContext pCtx = field.getAnnotation(PersistenceContext.class);
                final Member member = new FieldMember(field.get());
                buildPersistenceContext(consumer, pcFactory.create(pCtx, member), member);
            }
            for (final Annotated<Method> method : annotationFinder.findMetaAnnotatedMethods(PersistenceContext.class)) {
                final PersistenceContext pCtx = method.getAnnotation(PersistenceContext.class);
                final Member member = new MethodMember(method.get());
                buildPersistenceContext(consumer, pcFactory.create(pCtx, member), member);
            }

            //
            // @DataSourceDefinition
            //

            for (final Annotated<Class<?>> annotated : annotationFinder.findMetaAnnotatedClasses(DataSourceDefinitions.class)) {
                final DataSourceDefinitions defs = annotated.getAnnotation(DataSourceDefinitions.class);
                for (final DataSourceDefinition definition : defs.value()) {
                    buildDataSourceDefinition(consumer, definition);
                }
            }

            for (final Annotated<Class<?>> annotated : annotationFinder.findMetaAnnotatedClasses(DataSourceDefinition.class)) {
                final DataSourceDefinition definition = annotated.getAnnotation(DataSourceDefinition.class);
                buildDataSourceDefinition(consumer, definition);
            }

            //
            // @JMSConnectionFactoryDefinition
            //

            for (final Annotated<Class<?>> annotated : annotationFinder.findMetaAnnotatedClasses(JMSConnectionFactoryDefinitions.class)) {
                final JMSConnectionFactoryDefinitions defs = annotated.getAnnotation(JMSConnectionFactoryDefinitions.class);
                for (final JMSConnectionFactoryDefinition definition : defs.value()) {
                    buildConnectionFactoryDefinition(consumer, definition);
                }
            }

            for (final Annotated<Class<?>> annotated : annotationFinder.findMetaAnnotatedClasses(JMSConnectionFactoryDefinition.class)) {
                final JMSConnectionFactoryDefinition definition = annotated.getAnnotation(JMSConnectionFactoryDefinition.class);
                buildConnectionFactoryDefinition(consumer, definition);
            }

            //
            // @JMSDestinationDefinition
            //
            for (final Annotated<Class<?>> annotated : annotationFinder.findMetaAnnotatedClasses(JMSDestinationDefinitions.class)) {
                final JMSDestinationDefinitions defs = annotated.getAnnotation(JMSDestinationDefinitions.class);
                for (final JMSDestinationDefinition definition : defs.value()) {
                    buildDestinationDefinition(consumer, definition);
                }
            }

            for (final Annotated<Class<?>> annotated : annotationFinder.findMetaAnnotatedClasses(JMSDestinationDefinition.class)) {
                buildDestinationDefinition(consumer, annotated.getAnnotation(JMSDestinationDefinition.class));
            }
        }

        private void buildContext(final JndiConsumer consumer, final Member member) {
            final ContextRef ref = new ContextRef();
            ref.setName(member.getDeclaringClass().getName() + "/" + member.getName());
            ref.setResType(member.getType().getName());

            final InjectionTarget target = new InjectionTarget();
            target.setInjectionTargetClass(member.getDeclaringClass().getName());
            target.setInjectionTargetName(member.getName());
            ref.getInjectionTarget().add(target);

            consumer.getResourceRef().add(ref);
        }

        /**
         * Process @EJB into <ejb-ref> or <ejb-local-ref> for the specified member (field or method)
         *
         * @param consumer
         * @param ejb
         * @param member
         */
        private void buildEjbRef(final JndiConsumer consumer, final EJB ejb, final Member member) {

            // TODO: Looks like we aren't looking for an existing ejb-ref or ejb-local-ref
            // we need to do this to support overriding.

            /**
             * Was @EJB used at a class level witout specifying the 'name' or 'beanInterface' attributes?
             */
            final String name = consumer.getJndiConsumerName();
            if (member == null) {
                boolean shouldReturn = false;
                if (ejb.name().isEmpty()) {
                    fail(name, "ejbAnnotation.onClassWithNoName");
                    shouldReturn = true;
                }
                if (ejb.beanInterface().equals(Object.class)) {
                    fail(name, "ejbAnnotation.onClassWithNoBeanInterface");
                    shouldReturn = true;
                }
                if (shouldReturn) {
                    return;
                }
            }

            final EjbRef ejbRef = new EjbRef();

            // This is how we deal with the fact that we don't know
            // whether to use an EjbLocalRef or EjbRef (remote).
            // We flag it uknown and let the linking code take care of
            // figuring out what to do with it.
            ejbRef.setRefType(EjbReference.Type.UNKNOWN);

            // Get the ejb-ref-name
            String refName = ejb.name();
            if (refName.length() == 0) {
                refName = member.getDeclaringClass().getName() + "/" + member.getName();
            }

            //TODO can refName actually be null?
            ejbRef.setEjbRefName(normalize(refName));

            if (member != null) {
                // Set the member name where this will be injected
                final InjectionTarget target = new InjectionTarget();
                target.setInjectionTargetClass(member.getDeclaringClass().getName());
                target.setInjectionTargetName(member.getName());
                ejbRef.getInjectionTarget().add(target);

            }

            Class<?> interfce = ejb.beanInterface();
            if (interfce.equals(Object.class)) {
                interfce = member == null ? null : member.getType();
            }

            final boolean localbean = isKnownLocalBean(interfce);
            final boolean dynamicallyImplemented = DynamicProxyImplFactory.isKnownDynamicallyImplemented(interfce);

            if (!localbean && interfce != null && !isValidEjbInterface(name, interfce, ejbRef.getName())) {
                return;
            }

            if (interfce != null && !interfce.equals(Object.class)) {
                if (EJBHome.class.isAssignableFrom(interfce)) {
                    ejbRef.setHome(interfce.getName());
                    final Method[] methods = interfce.getMethods();
                    for (final Method method : methods) {
                        if (method.getName().startsWith("create")) {
                            ejbRef.setRemote(method.getReturnType().getName());
                            break;
                        }
                    }
                    ejbRef.setRefType(EjbReference.Type.REMOTE);
                } else if (EJBLocalHome.class.isAssignableFrom(interfce)) {
                    ejbRef.setHome(interfce.getName());
                    final Method[] methods = interfce.getMethods();
                    for (final Method method : methods) {
                        if (method.getName().startsWith("create")) {
                            ejbRef.setRemote(method.getReturnType().getName());
                            break;
                        }
                    }
                    ejbRef.setRefType(EjbReference.Type.LOCAL);
                } else if (localbean) {
                    ejbRef.setRefType(EjbReference.Type.LOCAL);
                    ejbRef.setRemote(interfce.getName());
                } else if (dynamicallyImplemented) {
                    ejbRef.setRefType(EjbReference.Type.LOCAL);
                    ejbRef.setRemote(interfce.getName());
                } else {
                    ejbRef.setRemote(interfce.getName());
                    if (interfce.getAnnotation(Local.class) != null) {
                        ejbRef.setRefType(EjbReference.Type.LOCAL);
                    } else if (interfce.getAnnotation(Remote.class) != null) {
                        ejbRef.setRefType(EjbReference.Type.REMOTE);
                    }
                }
            }

            // Set the ejb-link, if any
            String ejbName = ejb.beanName();
            if (ejbName.isEmpty()) {
                ejbName = null;
            }
            ejbRef.setEjbLink(ejbName);

            // Set the mappedName, if any
            String mappedName = ejb.mappedName();
            if (mappedName.isEmpty()) {
                mappedName = null;
            }
            ejbRef.setMappedName(mappedName);

            // Set lookup name, if any
            String lookupName = getLookupName(ejb);
            if (lookupName.isEmpty()) {
                lookupName = null;
            }
            ejbRef.setLookupName(lookupName);

            final Map<String, EjbRef> remoteRefs = consumer.getEjbRefMap();
            if (remoteRefs.containsKey(ejbRef.getName())) {
                final EjbRef ref = remoteRefs.get(ejbRef.getName());
                if (ref.getRemote() == null) {
                    ref.setRemote(ejbRef.getRemote());
                }
                if (ref.getHome() == null) {
                    ref.setHome(ejbRef.getHome());
                }
                if (ref.getMappedName() == null) {
                    ref.setMappedName(ejbRef.getMappedName());
                }
                ref.getInjectionTarget().addAll(ejbRef.getInjectionTarget());
                return;
            }

            final Map<String, EjbLocalRef> localRefs = consumer.getEjbLocalRefMap();
            if (localRefs.containsKey(ejbRef.getName())) {
                final EjbLocalRef ejbLocalRef = new EjbLocalRef(ejbRef);
                final EjbLocalRef ref = localRefs.get(ejbLocalRef.getName());
                if (ref.getLocal() == null) {
                    ref.setLocal(ejbLocalRef.getLocal());
                }
                if (ref.getLocalHome() == null) {
                    ref.setLocalHome(ejbLocalRef.getLocalHome());
                }
                if (ref.getMappedName() == null) {
                    ref.setMappedName(ejbLocalRef.getMappedName());
                }
                if(ref.getEjbLink() == null){
                    ref.setEjbLink(ejbLocalRef.getEjbLink());
                }
                ref.getInjectionTarget().addAll(ejbLocalRef.getInjectionTarget());
                return;
            }

            switch (ejbRef.getRefType()) {
                case UNKNOWN:
                case REMOTE:
                    consumer.getEjbRef().add(ejbRef);
                    break;
                case LOCAL:
                    consumer.getEjbLocalRef().add(new EjbLocalRef(ejbRef));
                    break;
            }
        }


        private String normalize(final String refName) {
            if (refName.startsWith("java:")) {
                return refName.startsWith("/") ? refName.substring(1) : refName;
            }
            return "java:comp/env/" + refName;
        }

        private boolean isKnownLocalBean(final Class clazz) {
            if (clazz.isAnnotation()) {
                return false;
            }
            if (clazz.isArray()) {
                return false;
            }
            if (clazz.isEnum()) {
                return false;
            }
            if (clazz.isInterface()) {
                return false;
            }
            if (clazz.isPrimitive()) {
                return false;
            }
            if (Modifier.isAbstract(clazz.getModifiers())) {
                return false;
            }
            if (Modifier.isFinal(clazz.getModifiers())) {
                return false;
            }

            return true;
        }

        private boolean isValidEjbInterface(final String b, final Class clazz, final String refName) {
            if (!clazz.isInterface()) { //NOPMD
                //It is not an interface. No validation necessary.
            } else if (EJBObject.class.isAssignableFrom(clazz)) {
                fail(b, "ann.ejb.ejbObject", clazz.getName(), refName);
                return false;
            } else if (EJBLocalObject.class.isAssignableFrom(clazz)) {
                fail(b, "ann.ejb.ejbLocalObject", clazz.getName(), refName);
                return false;
            }
            return true;
        }

        private void fail(final String component, final String key, final Object... details) {
            getValidationContext().fail(component, key, details);
        }

        /**
         * Process @Resource into either <resource-ref> or <resource-env-ref> for the given member (field or method) or class
         *
         * @param consumer
         * @param resource
         * @param member
         */
        private void buildResource(final JndiConsumer consumer, final Resource resource, final Member member) {

            /**
             * Was @Resource used at a class level without specifying the 'name' or 'beanInterface' attributes?
             */
            if (member == null) {
                if (resource.name().length() == 0) {
                    fail(consumer.getJndiConsumerName(), "resourceAnnotation.onClassWithNoName");
                    return;
                }
            }

            // Get the ref-name
            String refName = resource.name();
            if (refName.isEmpty()) {
                refName = member.getDeclaringClass().getName() + "/" + member.getName();
            }

            refName = normalize(refName);

            JndiReference reference = consumer.getEnvEntryMap().get(refName);
            if (reference == null) {

                /**
                 * Was @Resource mistakenly used when either @PersistenceContext or @PersistenceUnit should have been used?
                 */
                if (member != null) { // Little quick validation for common mistake
                    final Class type = member.getType();
                    if (EntityManager.class.isAssignableFrom(type)) {
                        fail(consumer.getJndiConsumerName(), "resourceRef.onEntityManager", refName);
                        return;
                    } else if (EntityManagerFactory.class.isAssignableFrom(type)) {
                        fail(consumer.getJndiConsumerName(), "resourceRef.onEntityManagerFactory", refName);
                        return;
                    }
                }

                final Class type;
                if (member == null) {
                    type = resource.type();
                } else {
                    type = member.getType();
                }

                if (knownResourceEnvTypes.contains(type.getName())) {
                    /*
                     * @Resource <resource-env-ref>
                     */
                    ResourceEnvRef resourceEnvRef = consumer.getResourceEnvRefMap().get(refName);
                    if (resourceEnvRef == null) {
                        resourceEnvRef = new ResourceEnvRef();
                        resourceEnvRef.setName(refName);
                        consumer.getResourceEnvRef().add(resourceEnvRef);
                    }

                    if (resourceEnvRef.getResourceEnvRefType() == null || "".equals(resourceEnvRef.getResourceEnvRefType())) {
                        resourceEnvRef.setResourceEnvRefType(type.getName());
                    }
                    reference = resourceEnvRef;
                } else if (isKnownEnvironmentEntryType(type)) {
                    /*
                     * @Resource <env-entry>
                     *
                     * Add an env-entry via @Resource if 'lookup' attribute is set.
                     */
                    final String lookupName = getLookupName(resource);
                    if (!lookupName.isEmpty()) {
                        final EnvEntry envEntry = new EnvEntry();
                        envEntry.setName(refName);
                        consumer.getEnvEntry().add(envEntry);

                        envEntry.setLookupName(lookupName);

                        reference = envEntry;
                    } else if (isShareableJNDINamespace(refName)) {
                        final EnvEntry envEntry = new EnvEntry();
                        envEntry.setName(refName);
                        consumer.getEnvEntry().add(envEntry);
                        reference = envEntry;
                    } else {

                        final String shortName = normalize(member.getName());
                        reference = consumer.getEnvEntryMap().get(shortName);

                        if (reference == null) {
                            final EnvEntry envEntry = new EnvEntry();
                            envEntry.setName(refName);
                            consumer.getEnvEntry().add(envEntry);
                            reference = envEntry;
                        }

//                        /*
//                         * Can't add env-entry since @Resource.lookup is not set and it is NOT in a shareable JNDI name space
//                         */
//                        return;
                    }
                } else {
                    /*
                     * @Resource <resource-ref>
                     */
                    ResourceRef resourceRef = consumer.getResourceRefMap().get(refName);

                    if (resourceRef == null) {
                        resourceRef = new ResourceRef();
                        resourceRef.setName(refName);
                        consumer.getResourceRef().add(resourceRef);
                    }

                    if (member != null) {
                        resourceRef.setOrigin(member.getDeclaringClass() + "#" + member.getName());
                    } // TODO: else @Resource on a class

                    if (resourceRef.getResAuth() == null) {
                        if (resource.authenticationType() == Resource.AuthenticationType.APPLICATION) {
                            resourceRef.setResAuth(ResAuth.APPLICATION);
                        } else {
                            resourceRef.setResAuth(ResAuth.CONTAINER);
                        }
                    }

                    if (resourceRef.getResType() == null || "".equals(resourceRef.getResType())) {
                        resourceRef.setResType(type.getName());
                    }

                    if (resourceRef.getResSharingScope() == null) {
                        if (resource.shareable()) {
                            resourceRef.setResSharingScope(ResSharingScope.SHAREABLE);
                        } else {
                            resourceRef.setResSharingScope(ResSharingScope.UNSHAREABLE);
                        }
                    }
                    reference = resourceRef;
                }
            }

            /*
             * Fill in the injection information <injection-target>
             */
            if (member != null) {
                // Set the member name where this will be injected
                final InjectionTarget target = new InjectionTarget();
                target.setInjectionTargetClass(member.getDeclaringClass().getName());
                target.setInjectionTargetName(member.getName());
                reference.getInjectionTarget().add(target);
            }

            // Override the mapped name if not set
            if (reference.getMappedName() == null && !resource.mappedName().isEmpty()) {
                reference.setMappedName(resource.mappedName());
            }

            // Override the lookup name if not set
            if (reference.getLookupName() == null) {
                final String lookupName = getLookupName(resource);
                if (!lookupName.isEmpty()) {
                    reference.setLookupName(lookupName);
                }
            }
        }

        private static Method getLookupMethod(final Class cls) {
            final String name = cls.getName();
            if (!lookupMissing.contains(name)) {
                try {
                    return cls.getMethod("lookup", null);
                } catch (final NoSuchMethodException e) {
                    lookupMissing.add(name);
                    final String exists = getSourceIfExists(cls);
                    logger.warning("Method 'lookup' is not available for '" + name + "'"
                        + (null != exists ? ". The old API '" + exists + "' was found on the classpath." : ". Probably using an older Runtime."));
                }
            }

            return null;
        }

        private static String getSourceIfExists(final Class<?> cls) {
            if (cls.getProtectionDomain() != null && cls.getProtectionDomain().getCodeSource() != null
                && cls.getProtectionDomain().getCodeSource().getLocation() != null) {
                return cls.getProtectionDomain().getCodeSource().getLocation().toString();
            }
            return null;
        }

        private static String getLookupName(final Resource resource) {
            String value = "";
            final Method lookupMethod = getLookupMethod(Resource.class);
            if (lookupMethod != null) {
                try {
                    value = (String) lookupMethod.invoke(resource, null);
                } catch (final Exception e) {
                    // ignore
                }
            }
            return value;
        }


        private static String getLookupName(final EJB ejb) {
            String value = "";
            final Method lookupMethod = getLookupMethod(EJB.class);
            if (lookupMethod != null) {
                try {
                    value = (String) lookupMethod.invoke(ejb, null);
                } catch (final Exception e) {
                    // ignore
                }
            }
            return value;
        }


        /**
         * Process @PersistenceUnit into <persistence-unit> for the specified member (field or method)
         *
         * @param consumer
         * @param persistenceUnit
         * @param member
         * @throws OpenEJBException
         */
        private void buildPersistenceUnit(final JndiConsumer consumer, final PersistenceUnit persistenceUnit, final Member member) throws OpenEJBException {
            String refName = persistenceUnit.name();
            // Get the ref-name
            if (refName.length() == 0) {
                /**
                 * Was @PersistenceUnit used at a class level without specifying the 'name' attribute?
                 */
                if (member == null) {
                    fail(consumer.getJndiConsumerName(), "persistenceUnitAnnotation.onClassWithNoName", persistenceUnit.unitName());
                    return;
                }
                refName = member.getDeclaringClass().getName() + "/" + member.getName();
            }

            refName = normalize(refName);
            PersistenceUnitRef persistenceUnitRef = consumer.getPersistenceUnitRefMap().get(refName);
            if (persistenceUnitRef == null) {
                persistenceUnitRef = new PersistenceUnitRef();
                persistenceUnitRef.setPersistenceUnitName(persistenceUnit.unitName());
                persistenceUnitRef.setPersistenceUnitRefName(refName);
                consumer.getPersistenceUnitRef().add(persistenceUnitRef);
            }


            if (member != null) {
                final Class type = member.getType();
                if (EntityManager.class.isAssignableFrom(type)) {
                    failIfCdiProducer(member, "EntityManagerFactory");

                    /**
                     * Was @PersistenceUnit mistakenly used when @PersistenceContext should have been used?
                     */
                    final ValidationContext validationContext = getValidationContext();
                    final String jndiConsumerName = consumer.getJndiConsumerName();
                    final String name = persistenceUnitRef.getName();
                    validationContext.fail(jndiConsumerName, "persistenceUnitAnnotation.onEntityManager", name);
                } else if (!EntityManagerFactory.class.isAssignableFrom(type)) {
                    failIfCdiProducer(member, "EntityManagerFactory");


                    /**
                     * Was @PersistenceUnit mistakenly used for something that isn't an EntityManagerFactory?
                     */
                    fail(consumer.getJndiConsumerName(), "persistenceUnitAnnotation.onNonEntityManagerFactory", persistenceUnitRef.getName());
                } else {
                    // Set the member name where this will be injected
                    final InjectionTarget target = new InjectionTarget();
                    target.setInjectionTargetClass(member.getDeclaringClass().getName());
                    target.setInjectionTargetName(member.getName());
                    persistenceUnitRef.getInjectionTarget().add(target);
                }
            }

            if (persistenceUnitRef.getPersistenceUnitName() == null && !persistenceUnit.unitName().isEmpty()) {
                persistenceUnitRef.setPersistenceUnitName(persistenceUnit.unitName());
            }
        }

        /**
         * Process @PersistenceContext into <persistence-context> for the specified member (field or method)
         *
         * Refer 16.11.2.1 Overriding Rules of EJB Core Spec for overriding rules
         *
         * @param consumer
         * @param persistenceContext
         * @param member
         * @throws OpenEJBException
         */
        private void buildPersistenceContext(final JndiConsumer consumer, final PersistenceContextAnn persistenceContext, final Member member) throws OpenEJBException {
            AppModule module = null;
            if (currentModule.get() instanceof AppModule) {
                module = (AppModule) currentModule.get();
            } else if (currentModule.get() instanceof Module) {
                module = ((Module) currentModule.get()).getAppModule();
            }
            if (module != null
                && org.apache.openejb.jee.jpa.unit.TransactionType.RESOURCE_LOCAL.equals(module.getTransactionType(persistenceContext.unitName()))) {
                // should it be in warn level?
                // IMO no since with CDI it is tempting to do so
                String name = persistenceContext.unitName();
                if (name == null || name.isEmpty()) { // search for it
                    try { // get the first one
                        name = module.getPersistenceModules().iterator().next()
                            .getPersistence()
                            .getPersistenceUnit().iterator().next().getName();
                    } catch (final Exception e) {
                        name = "?";
                    }
                }
                logger.info("PersistenceUnit '" + name + "' is a RESOURCE_LOCAL one, " +
                    "you'll have to manage @PersistenceContext yourself.");
                return;
            }

            String refName = persistenceContext.name();

            if (refName.length() == 0) {
                /**
                 * Was @PersistenceContext used at a class level without specifying the 'name' attribute?
                 */
                if (member == null) {
                    fail(consumer.getJndiConsumerName(), "persistenceContextAnnotation.onClassWithNoName", persistenceContext.unitName());
                    return;
                }
                refName = member.getDeclaringClass().getName() + "/" + member.getName();
            }

            refName = normalize(refName);

            PersistenceContextRef persistenceContextRef = consumer.getPersistenceContextRefMap().get(refName);
            if (persistenceContextRef == null) {
                persistenceContextRef = new PersistenceContextRef();
                if (persistenceContext.synchronization() != null) { // should be the case in "normal" deployments
                    persistenceContextRef.setPersistenceContextSynchronization(PersistenceContextSynchronization.valueOf(persistenceContext.synchronization().toUpperCase(Locale.ENGLISH)));
                }
                persistenceContextRef.setPersistenceUnitName(persistenceContext.unitName());
                persistenceContextRef.setPersistenceContextRefName(refName);
                if ("EXTENDED".equalsIgnoreCase(persistenceContext.type())) {
                    persistenceContextRef.setPersistenceContextType(PersistenceContextType.EXTENDED);
                } else {
                    persistenceContextRef.setPersistenceContextType(PersistenceContextType.TRANSACTION);
                }
                consumer.getPersistenceContextRef().add(persistenceContextRef);
            } else {
                if (persistenceContextRef.getPersistenceUnitName() == null || "".equals(persistenceContextRef.getPersistenceUnitName())) {
                    persistenceContextRef.setPersistenceUnitName(persistenceContext.unitName());
                }
                if (persistenceContextRef.getPersistenceContextType() == null) {
                    if ("EXTENDED".equalsIgnoreCase(persistenceContext.type())) {
                        persistenceContextRef.setPersistenceContextType(PersistenceContextType.EXTENDED);
                    } else {
                        persistenceContextRef.setPersistenceContextType(PersistenceContextType.TRANSACTION);
                    }
                }
                if (persistenceContextRef.getPersistenceContextSynchronization() == null && persistenceContext.synchronization() != null) {
                    persistenceContextRef.setPersistenceContextSynchronization(PersistenceContextSynchronization.valueOf(persistenceContext.synchronization().toUpperCase(Locale.ENGLISH)));
                }
            }

            List<Property> persistenceProperties = persistenceContextRef.getPersistenceProperty();
            if (persistenceProperties == null) {
                persistenceProperties = new ArrayList<>();
                persistenceContextRef.setPersistenceProperty(persistenceProperties);
            }

            for (final Map.Entry<String, String> persistenceProperty : persistenceContext.properties().entrySet()) {
                boolean flag = true;
                for (final Property prpty : persistenceProperties) {
                    if (prpty.getName().equals(persistenceProperty.getKey())) {
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    final Property property = new Property();
                    property.setName(persistenceProperty.getKey());
                    property.setValue(persistenceProperty.getValue());
                    persistenceProperties.add(property);
                }
            }

            if (member != null) {
                final Class type = member.getType();
                if (EntityManagerFactory.class.isAssignableFrom(type)) {
                    failIfCdiProducer(member, "EntityManager");

                    /**
                     * Was @PersistenceContext mistakenly used when @PersistenceUnit should have been used?
                     */
                    fail(consumer.getJndiConsumerName(), "persistenceContextAnnotation.onEntityManagerFactory", persistenceContextRef.getName());
                } else if (!EntityManager.class.isAssignableFrom(type)) {
                    failIfCdiProducer(member, "EntityManager");

                    /**
                     * Was @PersistenceContext mistakenly used for something that isn't an EntityManager?
                     */
                    fail(consumer.getJndiConsumerName(), "persistenceContextAnnotation.onNonEntityManager", persistenceContextRef.getName());
                } else {
                    // Set the member name where this will be injected
                    final InjectionTarget target = new InjectionTarget();
                    target.setInjectionTargetClass(member.getDeclaringClass().getName());
                    target.setInjectionTargetName(member.getName());
                    persistenceContextRef.getInjectionTarget().add(target);
                }
            }
        }

        private void buildDestinationDefinition(final JndiConsumer consumer, final JMSDestinationDefinition definition) {
            final JMSDestination destination = new JMSDestination();
            destination.setName(definition.name());
            destination.setClassName(definition.className());
            destination.setInterfaceName(definition.interfaceName());
            destination.setResourceAdapter(definition.resourceAdapter());
            destination.setDestinationName(definition.destinationName());

            for (final String s : definition.properties()) {
                final int equal = s.indexOf('=');
                if (equal < s.length() - 1) {
                    final SuperProperties props = new SuperProperties();
                    try {
                        props.load(new ByteArrayInputStream(s.getBytes()));
                        for (final String key : props.stringPropertyNames()) {
                            if (!key.isEmpty()) {
                                destination.property(key, props.getProperty(key));
                            }
                        }
                    } catch (final IOException e) {
                        final String key = s.substring(0, equal).trim();
                        final String value = s.substring(equal + 1).trim();
                        destination.property(key, value);
                    }
                } else {
                    destination.property(s.trim(), "");
                }
            }

            consumer.getJMSDestination().add(destination);
        }

        private void buildConnectionFactoryDefinition(final JndiConsumer consumer, final JMSConnectionFactoryDefinition definition) {
            final JMSConnectionFactory connectionFactory = new JMSConnectionFactory();
            connectionFactory.setName(definition.name());
            connectionFactory.setMinPoolSize(definition.minPoolSize());
            connectionFactory.setMaxPoolSize(definition.maxPoolSize());
            connectionFactory.setClassName(definition.className());
            connectionFactory.setInterfaceName(definition.interfaceName());
            connectionFactory.setClientId(definition.clientId());
            connectionFactory.setUser(definition.user());
            connectionFactory.setPassword(definition.password());
            connectionFactory.setResourceAdapter(definition.resourceAdapter());
            connectionFactory.setTransactional(definition.transactional());

            for (final String s : definition.properties()) {
                final int equal = s.indexOf('=');
                if (equal < s.length() - 1) {
                    final SuperProperties props = new SuperProperties();
                    try {
                        props.load(new ByteArrayInputStream(s.getBytes()));
                        for (final String key : props.stringPropertyNames()) {
                            if (!key.isEmpty()) {
                                connectionFactory.property(key, props.getProperty(key));
                            }
                        }
                    } catch (final IOException e) {
                        final String key = s.substring(0, equal).trim();
                        final String value = s.substring(equal + 1).trim();
                        connectionFactory.property(key, value);
                    }
                } else {
                    connectionFactory.property(s.trim(), "");
                }
            }

            consumer.getJMSConnectionFactories().add(connectionFactory);
        }

        private void buildDataSourceDefinition(final JndiConsumer consumer, final DataSourceDefinition d) {
            final DataSource dataSource = new DataSource();

            dataSource.setName(d.name());
            dataSource.setClassName(d.className());
            dataSource.setTransactional(d.transactional());

            final DataSource existing = consumer.getDataSourceMap().get(dataSource.getKey());

            if (existing != null) {
                return;
            }

            // Optional properties
            if (!d.databaseName().isEmpty()) {
                dataSource.setDatabaseName(d.databaseName());
            }
            if (d.initialPoolSize() != -1) {
                dataSource.setInitialPoolSize(d.initialPoolSize());
            }
            if (d.isolationLevel() != -1) {
                dataSource.setIsolationLevel(IsolationLevel.fromFlag(d.isolationLevel()));
            }
            if (d.loginTimeout() != 0) {
                dataSource.setLoginTimeout(d.loginTimeout());
            }
            if (d.maxIdleTime() != -1) {
                dataSource.setMaxIdleTime(d.maxIdleTime());
            }
            if (d.maxPoolSize() != -1) {
                dataSource.setMaxPoolSize(d.maxPoolSize());
            }
            if (d.maxStatements() != -1) {
                dataSource.setMaxStatements(d.maxStatements());
            }
            if (d.minPoolSize() != -1) {
                dataSource.setMinPoolSize(d.minPoolSize());
            }
            if (!d.password().isEmpty()) {
                dataSource.setPassword(d.password());
            }
            if (d.portNumber() != -1) {
                dataSource.setPortNumber(d.portNumber());
            }
            if (!"localhost".equals(d.serverName())) {
                dataSource.setServerName(d.serverName());
            }
            if (!d.url().isEmpty()) {
                dataSource.setUrl(d.url());
            }
            if (!d.user().isEmpty()) {
                dataSource.setUser(d.user());
            }

            for (final String s : d.properties()) {
                final int equal = s.indexOf('=');
                if (equal < s.length() - 1) {
                    final SuperProperties props = new SuperProperties();
                    try {
                        props.load(new ByteArrayInputStream(s.getBytes()));
                        for (final String key : props.stringPropertyNames()) {
                            if (!key.isEmpty()) {
                                dataSource.property(key, props.getProperty(key));
                            }
                        }
                    } catch (final IOException e) {
                        final String key = s.substring(0, equal).trim();
                        final String value = s.substring(equal + 1).trim();
                        dataSource.property(key, value);
                    }
                } else {
                    dataSource.property(s.trim(), "");
                }
            }

            consumer.getDataSource().add(dataSource);
        }


        /**
         * Process @WebServiceRef and @HandlerChain for the given member (field or method)
         *
         * @param consumer
         * @param webService
         * @param handlerChain
         * @param member
         * @param classLoader
         * @throws OpenEJBException
         */
        private void buildWebServiceRef(final JndiConsumer consumer, final WebServiceRef webService, final HandlerChain handlerChain, final Member member, final ClassLoader classLoader) throws OpenEJBException {

            ServiceRef serviceRef;

            String refName = webService.name();
            if (refName.isEmpty()) {
                if (member == null) {
                    //TODO fail
                    return;
                }
                refName = member.getDeclaringClass().getName() + "/" + member.getName();
            }

            refName = normalize(refName);

            serviceRef = consumer.getServiceRefMap().get(refName);

            if (serviceRef == null) {
                serviceRef = new ServiceRef();
                serviceRef.setServiceRefName(refName);

                consumer.getServiceRef().add(serviceRef);
            }

            if (member != null) {
                // Set the member name where this will be injected
                final InjectionTarget target = new InjectionTarget();
                target.setInjectionTargetClass(member.getDeclaringClass().getName());
                target.setInjectionTargetName(member.getName());
                serviceRef.getInjectionTarget().add(target);
            }

            // Set service interface
            Class<?> serviceInterface = null;
            if (serviceRef.getServiceInterface() == null) {
                serviceInterface = webService.type();
                if (serviceInterface.equals(Object.class)) {
                    serviceInterface = webService.value();
                    if ((Service.class.equals(serviceInterface) || Object.class.equals(serviceInterface)) && member != null) {
                        serviceInterface = member.getType();
                    }
                }
            }
            if (serviceInterface == null || !Service.class.isAssignableFrom(serviceInterface)) {
                serviceInterface = Service.class;
            }
            serviceRef.setServiceInterface(serviceInterface.getName());

            // reference type
            if (serviceRef.getServiceRefType() == null || "".equals(serviceRef.getServiceRefType())) {
                if (webService.type() != Object.class) {
                    serviceRef.setServiceRefType(webService.type().getName());
                } else {
                    serviceRef.setServiceRefType(member.getType().getName());
                }
            }
            Class<?> refType = null;
            try {
                refType = classLoader.loadClass(realClassName(serviceRef.getType()));
            } catch (final ClassNotFoundException e) {
                // no-op
            }

            // Set the mappedName
            if (serviceRef.getMappedName() == null) {
                String mappedName = webService.mappedName();
                if (mappedName.isEmpty()) {
                    mappedName = null;
                }
                serviceRef.setMappedName(mappedName);
            }

            // wsdl file
            if (serviceRef.getWsdlFile() == null) {
                final String wsdlLocation = webService.wsdlLocation();
                if (!wsdlLocation.isEmpty()) {
                    serviceRef.setWsdlFile(wsdlLocation);
                }
            }

            if (SystemInstance.get().hasProperty("openejb.geronimo")) {
                return;
            }

            if (serviceRef.getWsdlFile() == null && refType != null) {
                serviceRef.setWsdlFile(JaxWsUtils.getServiceWsdlLocation(refType, classLoader));
            }
            if (serviceRef.getWsdlFile() == null) {
                serviceRef.setWsdlFile(JaxWsUtils.getServiceWsdlLocation(serviceInterface, classLoader));
            }

            // service qname
            if (serviceRef.getServiceQname() == null && refType != null) {
                try {
                    serviceRef.setServiceQname(JaxWsUtils.getServiceQName(refType));
                } catch (final IllegalArgumentException iae) {
                    if (FieldMember.class.isInstance(member) && FieldMember.class.cast(member).field.getAnnotation(Produces.class) != null) {
                        throw new DefinitionException(FieldMember.class.cast(member).field + " is not a webservice client");
                    }
                    throw iae;
                }
            }
            if (serviceRef.getServiceQname() == null) {
                serviceRef.setServiceQname(JaxWsUtils.getServiceQName(serviceInterface));
            }

            // handlers
            if (serviceRef.getHandlerChains() == null && handlerChain != null) {
                try {
                    final URL handlerFileURL = member.getDeclaringClass().getResource(handlerChain.file());
                    final HandlerChains handlerChains = ReadDescriptors.readHandlerChains(handlerFileURL);
                    serviceRef.setHandlerChains(handlerChains);
                } catch (final Throwable e) {
                    throw new OpenEJBException("Unable to load handler chain file: " + handlerChain.file(), e);
                }
            }
        }

        /**
         * Scan for @EJB, @Resource, @WebServiceRef, @PersistenceUnit, and @PersistenceContext on WebService HandlerChain classes
         */
        private void processWebServiceHandlers(final EjbModule ejbModule, final EnterpriseBean bean, final AnnotationFinder finder) throws OpenEJBException {
            // add webservice handler classes to the class finder used in annotation processing
            final Set<String> classes = new HashSet<>();
            if (ejbModule.getWebservices() != null) {
                for (final WebserviceDescription webservice : ejbModule.getWebservices().getWebserviceDescription()) {
                    for (final PortComponent port : webservice.getPortComponent()) {
                        // only process port definitions for this ejb
                        if (!bean.getEjbName().equals(port.getServiceImplBean().getEjbLink())) {
                            continue;
                        }

                        if (port.getHandlerChains() == null) {
                            continue;
                        }
                        for (final org.apache.openejb.jee.HandlerChain handlerChain : port.getHandlerChains().getHandlerChain()) {
                            for (final Handler handler : handlerChain.getHandler()) {
                                final String handlerClass = realClassName(handler.getHandlerClass());
                                if (handlerClass != null) {
                                    classes.add(handlerClass);
                                }
                            }
                        }
                    }
                }
            }
            // classes.add(bean.getEjbClass());
            final AnnotationFinder handlersFinder = finder.select(classes);
            buildAnnotatedRefs(bean, handlersFinder, ejbModule.getClassLoader());
        }

        /**
         * Scan for @EJB, @Resource, @WebServiceRef, @PersistenceUnit, and @PersistenceContext on WebService HandlerChain classes
         *
         * @param consumer
         * @param classLoader
         * @throws OpenEJBException
         */
        private void processWebServiceClientHandlers(final JndiConsumer consumer, final AnnotationFinder finder, final ClassLoader classLoader) throws OpenEJBException {
            if (SystemInstance.get().hasProperty("openejb.geronimo")) {
                return;
            }

            final Set<String> processedClasses = new HashSet<>();
            final Set<String> handlerClasses = new HashSet<>();
            do {
                // get unprocessed handler classes
                handlerClasses.clear();
                for (final ServiceRef serviceRef : consumer.getServiceRef()) {
                    final HandlerChains chains = serviceRef.getAllHandlers();
                    if (chains == null) {
                        continue;
                    }
                    for (final org.apache.openejb.jee.HandlerChain handlerChain : chains.getHandlerChain()) {
                        for (final Handler handler : handlerChain.getHandler()) {
                            if (handler.getHandlerClass() != null) {
                                handlerClasses.add(realClassName(handler.getHandlerClass()));
                            }
                        }
                    }
                }
                handlerClasses.removeAll(processedClasses);
                if (handlerClasses.isEmpty()) {
                    continue;
                }

                // process handler classes
                final AnnotationFinder handlerAnnotationFinder = finder != null ? finder.select(handlerClasses) :
                        new FinderFactory.OpenEJBAnnotationFinder(new FinderFactory.DoLoadClassesArchive(classLoader, handlerClasses));

                /*
                 * @EJB
                 * @Resource
                 * @WebServiceRef
                 * @PersistenceUnit
                 * @PersistenceContext
                 */
                buildAnnotatedRefs(consumer, handlerAnnotationFinder, classLoader);

                processedClasses.addAll(handlerClasses);
            } while (!handlerClasses.isEmpty());
        }

        // ----------------------------------------------------------------------
        //
        //  Utility methods and classes
        //
        // ----------------------------------------------------------------------


        private List<String> getDeclaredClassPermissions(final AssemblyDescriptor assemblyDescriptor, final String ejbName) {
            final List<MethodPermission> permissions = assemblyDescriptor.getMethodPermission();
            final List<String> classPermissions = new ArrayList<>();
            for (final MethodPermission permission : permissions) {
                for (final org.apache.openejb.jee.Method method : permission.getMethod()) {
                    if (!method.getEjbName().equals(ejbName)) {
                        continue;
                    }
                    if (!"*".equals(method.getMethodName())) {
                        continue;
                    }

                    String className = method.getClassName();
                    if (className == null) {
                        className = "*";
                    }
                    classPermissions.add(className);
                }
            }
            return classPermissions;
        }

        public interface AnnotationHandler<A extends Annotation> {
            Class<A> getAnnotationClass();

            Map<String, List<MethodAttribute>> getExistingDeclarations();

            void addClassLevelDeclaration(A annotation, Class clazz);

            void addMethodLevelDeclaration(A annotation, Method method);
        }

        public static class TransactionAttributeHandler implements AnnotationHandler<TransactionAttribute> {

            private final AssemblyDescriptor assemblyDescriptor;
            private final String ejbName;

            public TransactionAttributeHandler(final AssemblyDescriptor assemblyDescriptor, final String ejbName) {
                this.assemblyDescriptor = assemblyDescriptor;
                this.ejbName = ejbName;
            }

            public Map<String, List<MethodAttribute>> getExistingDeclarations() {
                return assemblyDescriptor.getMethodTransactionMap(ejbName);
            }

            public void addClassLevelDeclaration(final TransactionAttribute attribute, final Class type) {
                final ContainerTransaction ctx = new ContainerTransaction(cast(attribute.value()), type.getName(), ejbName, "*");
                assemblyDescriptor.getContainerTransaction().add(ctx);
            }

            public void addMethodLevelDeclaration(final TransactionAttribute attribute, final Method method) {
                final ContainerTransaction ctx = new ContainerTransaction(cast(attribute.value()), ejbName, method);
                assemblyDescriptor.getContainerTransaction().add(ctx);
            }

            public Class<TransactionAttribute> getAnnotationClass() {
                return TransactionAttribute.class;
            }

            private TransAttribute cast(final TransactionAttributeType transactionAttributeType) {
                return TransAttribute.valueOf(transactionAttributeType.toString());
            }
        }

        private static class ConcurrentMethodHandler {

            protected final AssemblyDescriptor assemblyDescriptor;
            protected final SessionBean bean;
            protected final Map<Object, ContainerConcurrency> methods;

            public ConcurrentMethodHandler(final AssemblyDescriptor assemblyDescriptor,
                                           final SessionBean bean,
                                           final Map<Object, ContainerConcurrency> methods) {
                this.assemblyDescriptor = assemblyDescriptor;
                this.bean = bean;
                this.methods = methods;
            }

            public Map<String, List<MethodAttribute>> getExistingDeclarations() {
                final Map<String, List<MethodAttribute>> declarations = new HashMap<>();
                final List<ConcurrentMethod> methods = bean.getConcurrentMethod();
                for (final ConcurrentMethod method : methods) {
                    List<MethodAttribute> list = declarations.computeIfAbsent(method.getMethod().getMethodName(), k -> new ArrayList<>());
                    list.add(new MethodAttribute(null, bean.getEjbName(), method.getMethod()));
                }
                return declarations;
            }

            public ContainerConcurrency getContainerConcurrency(final Method method) {
                ContainerConcurrency concurrency = methods.get(method);
                if (concurrency == null) {
                    concurrency = new ContainerConcurrency(null, bean.getEjbName(), method);
                    methods.put(method, concurrency);
                    assemblyDescriptor.getContainerConcurrency().add(concurrency);
                }
                return concurrency;
            }

            public ContainerConcurrency getContainerConcurrency(final Class clazz) {
                ContainerConcurrency concurrency = methods.get(clazz);
                if (concurrency == null) {
                    concurrency = new ContainerConcurrency(null, clazz.getName(), bean.getEjbName(), "*");
                    methods.put(clazz, concurrency);
                    assemblyDescriptor.getContainerConcurrency().add(concurrency);
                }
                return concurrency;
            }

            protected Map<Object, ContainerConcurrency> getContainerConcurrency() {
                return methods;
            }
        }

        public static class LockHandler extends ConcurrentMethodHandler implements AnnotationHandler<Lock> {

            public LockHandler(final AssemblyDescriptor assemblyDescriptor,
                               final SessionBean bean) {
                this(assemblyDescriptor, bean, new HashMap<Object, ContainerConcurrency>());
            }

            public LockHandler(final AssemblyDescriptor assemblyDescriptor,
                               final SessionBean bean,
                               final Map<Object, ContainerConcurrency> methods) {
                super(assemblyDescriptor, bean, methods);
            }

            public void addClassLevelDeclaration(final Lock attribute, final Class type) {
                final ContainerConcurrency concurrency = getContainerConcurrency(type);
                concurrency.setLock(toLock(attribute));
            }

            public void addMethodLevelDeclaration(final Lock attribute, final Method method) {
                final ContainerConcurrency concurrency = getContainerConcurrency(method);
                concurrency.setLock(toLock(attribute));
            }

            private ConcurrentLockType toLock(final Lock annotation) {
                if (LockType.READ.equals(annotation.value())) {
                    return ConcurrentLockType.READ;
                } else if (LockType.WRITE.equals(annotation.value())) {
                    return ConcurrentLockType.WRITE;
                } else {
                    throw new IllegalArgumentException("Unknown lock annotation: " + annotation.value());
                }
            }

            public Class<Lock> getAnnotationClass() {
                return Lock.class;
            }

        }

        public static class AccessTimeoutHandler extends ConcurrentMethodHandler implements AnnotationHandler<AccessTimeout> {

            public AccessTimeoutHandler(final AssemblyDescriptor assemblyDescriptor,
                                        final SessionBean bean) {
                this(assemblyDescriptor, bean, new HashMap<Object, ContainerConcurrency>());
            }

            public AccessTimeoutHandler(final AssemblyDescriptor assemblyDescriptor,
                                        final SessionBean bean,
                                        final Map<Object, ContainerConcurrency> methods) {
                super(assemblyDescriptor, bean, methods);
            }

            public void addClassLevelDeclaration(final AccessTimeout attribute, final Class type) {
                final ContainerConcurrency concurrency = getContainerConcurrency(type);
                concurrency.setAccessTimeout(toTimeout(attribute));
            }

            public void addMethodLevelDeclaration(final AccessTimeout attribute, final Method method) {
                final ContainerConcurrency concurrency = getContainerConcurrency(method);
                concurrency.setAccessTimeout(toTimeout(attribute));
            }

            private Timeout toTimeout(final AccessTimeout annotation) {
                final Timeout timeout = new Timeout();
                timeout.setTimeout(annotation.value());
                timeout.setUnit(annotation.unit());
                return timeout;
            }

            public Class<AccessTimeout> getAnnotationClass() {
                return AccessTimeout.class;
            }

        }

        private <A extends Annotation> void checkAttributes(final AnnotationHandler<A> handler, final String ejbName, final EjbModule ejbModule, final AnnotationFinder annotationFinder, final String messageKey) {
            final Map<String, List<MethodAttribute>> existingDeclarations = handler.getExistingDeclarations();

            int xml = 0;
            for (final List<MethodAttribute> methodAttributes : existingDeclarations.values()) {
                xml += methodAttributes.size();
            }

            if (xml > 0) {
                ejbModule.getValidation().warn(ejbName, "xml." + messageKey, xml);
            }

            int ann = annotationFinder.findAnnotatedClasses(handler.getAnnotationClass()).size();
            ann += annotationFinder.findAnnotatedMethods(handler.getAnnotationClass()).size();

            if (ann > 0) {
                ejbModule.getValidation().warn(ejbName, "ann." + messageKey, ann);
            }


        }

        private <A extends Annotation> void processAttributes(final AnnotationHandler<A> handler, final Class<?> clazz, final AnnotationFinder annotationFinder) {
            final Map<String, List<MethodAttribute>> existingDeclarations = handler.getExistingDeclarations();

            // SET THE DEFAULT
            final Class<A> annotationClass = handler.getAnnotationClass();

            final List<Annotated<Class<?>>> types = sortClasses(annotationFinder.findMetaAnnotatedClasses(annotationClass));
            if (!hasMethodAttribute("*", null, existingDeclarations)) {
                for (final Annotated<Class<?>> type : types) {
                    if (!type.get().isAssignableFrom(clazz)) {
                        continue;
                    }
                    if (!hasMethodAttribute("*", type.get(), existingDeclarations)) {
                        final A attribute = type.getAnnotation(annotationClass);
                        if (attribute != null) {
                            handler.addClassLevelDeclaration(attribute, type.get());
                        }
                    }
                }
            }

            final List<Annotated<Method>> methods = annotationFinder.findMetaAnnotatedMethods(annotationClass);
            for (final Annotated<Method> method : methods) {
                final A attribute = method.getAnnotation(annotationClass);
                if (!existingDeclarations.containsKey(method.get().getName())) {
                    // no method with this name in descriptor
                    handler.addMethodLevelDeclaration(attribute, method.get());
                } else {
                    // method name already declared
                    final List<MethodAttribute> list = existingDeclarations.get(method.get().getName());
                    for (final MethodAttribute mtx : list) {
                        final MethodParams methodParams = mtx.getMethodParams();
                        if (methodParams == null) {
                            // params not specified, so this is more specific
                            handler.addMethodLevelDeclaration(attribute, method.get());
                        } else {
                            final List<String> params1 = methodParams.getMethodParam();
                            final String[] params2 = asStrings(method.get().getParameterTypes());
                            if (params1.size() != params2.length) {
                                // params not the same
                                handler.addMethodLevelDeclaration(attribute, method.get());
                            } else {
                                for (int i = 0; i < params1.size(); i++) {
                                    final String a = params1.get(i);
                                    final String b = params2[i];
                                    if (!a.equals(b)) {
                                        // params not the same
                                        handler.addMethodLevelDeclaration(attribute, method.get());
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        private boolean hasMethodAttribute(final String methodName, final Class clazz, final Map<String, List<MethodAttribute>> map) {
            return getMethodAttribute(methodName, clazz, map) != null;
        }

        private MethodAttribute getMethodAttribute(final String methodName, final Class clazz, final Map<String, List<MethodAttribute>> map) {
            final List<MethodAttribute> methodAttributes = map.get(methodName);
            if (methodAttributes == null) {
                return null;
            }

            for (final MethodAttribute methodAttribute : methodAttributes) {
                final String className = clazz != null ? clazz.getName() : "null";

                if (className.equals(methodAttribute.getClassName())) {
                    return methodAttribute;
                }
            }
            return null;
        }

        /**
         * Searches for an annotation starting at the specified class and working backwards.
         * Searching stops when the annotation is found.
         *
         * @param clazz
         * @param annotationClass
         * @return
         */
        private <A extends Annotation> A getInheritableAnnotation(final Class clazz, final Class<A> annotationClass) {
            if (clazz == null || clazz.equals(Object.class)) {
                return null;
            }

            final MetaAnnotatedClass meta = new MetaAnnotatedClass(clazz);
            final Annotation annotation = meta.getAnnotation(annotationClass);
            if (annotation != null) {
                return (A) annotation;
            }

            return getInheritableAnnotation(clazz.getSuperclass(), annotationClass);
        }

        /**
         * Creates a list of the specified class and all its parent
         * classes then creates a AnnotationFinder from that list which
         * can be used for easy annotation scanning.
         *
         * @param classes
         * @return
         */
        private AnnotationFinder createFinder(final Class<?>... classes) {
            final Set<Class<?>> parents = new HashSet<>();
            for (final Class<?> clazz : classes) {
                parents.addAll(Classes.ancestors(clazz));
            }
            return new AnnotationFinder(new ClassesArchive(parents)).enableMetaAnnotations(); // no need to have subclasses/impl here
        }

        /**
         * Converts an array of classes to an array of class name strings
         *
         * @param types
         * @return
         */
        private String[] asStrings(final Class[] types) {
            final List<String> names = new ArrayList<>();
            for (final Class clazz : types) {
                names.add(clazz.getName());
            }
            return names.toArray(new String[names.size()]);
        }

        /**
         * Grabs the first element of a list if there is one.
         *
         * @param list
         * @return
         */
        private <T> T getFirst(final List<T> list) {
            if (list.size() > 0) {
                return list.get(0);
            }
            return null;
        }

        /**
         * Remote interface validation
         *
         * @param interfce
         * @param validation
         * @param ejbName
         * @return
         */
        private boolean validateRemoteInterface(final Class interfce, final ValidationContext validation, final String ejbName) {
            return isValidInterface(interfce, validation, ejbName, "Remote");
        }

        /**
         * Local interface validation
         *
         * @param interfce
         * @param validation
         * @param ejbName
         * @return
         */
        private boolean validateLocalInterface(final Class interfce, final ValidationContext validation, final String ejbName) {
            return isValidInterface(interfce, validation, ejbName, "Local");
        }

        /**
         * Checks that the values specified via @Local and @Remote are *not*:
         *
         * - classes
         * - derived from javax.ejb.EJBObject
         * - derived from javax.ejb.EJBHome
         * - derived from javax.ejb.EJBLocalObject
         * - derived from javax.ejb.EJBLocalHome
         *
         * @param interfce
         * @param validation
         * @param ejbName
         * @param annotationName
         * @return
         */
        private boolean isValidInterface(final Class interfce, final ValidationContext validation, final String ejbName, final String annotationName) {
            if (!interfce.isInterface()) {
                validation.fail(ejbName, "ann.notAnInterface", annotationName, interfce.getName());
                return false;
            } else if (EJBHome.class.isAssignableFrom(interfce)) {
                validation.fail(ejbName, "ann.remoteOrLocal.ejbHome", annotationName, interfce.getName());
                return false;
            } else if (EJBObject.class.isAssignableFrom(interfce)) {
                validation.fail(ejbName, "ann.remoteOrLocal.ejbObject", annotationName, interfce.getName());
                return false;
            } else if (EJBLocalHome.class.isAssignableFrom(interfce)) {
                validation.fail(ejbName, "ann.remoteOrLocal.ejbLocalHome", annotationName, interfce.getName());
                return false;
            } else if (EJBLocalObject.class.isAssignableFrom(interfce)) {
                validation.fail(ejbName, "ann.remoteOrLocal.ejbLocalObject", annotationName, interfce.getName());
                return false;
            }
            return true;
        }
    }

    private static void failIfCdiProducer(final Member member, final String type) {
        if (FieldMember.class.isInstance(member) && FieldMember.class.cast(member).field.getAnnotation(Produces.class) != null) {
            throw new DefinitionException(FieldMember.class.cast(member).field + " is not a " + type);
        }
    }

    private static void addRestClassesToScannedClasses(final WebModule webModule, final Set<Class> classes, final ClassLoader classLoader) throws OpenEJBException {
        for (final String rawClassName : webModule.getRestClasses()) {
            final String className = realClassName(rawClassName);
            if (className != null) {
                final Class<?> clazz;
                try {
                    clazz = classLoader.loadClass(className);
                    classes.add(clazz);
                } catch (final ClassNotFoundException e) {
                    throw new OpenEJBException("Unable to load REST class: " + className, e);
                }
            }
        }
    }

    /**
     * Small utility interface used to allow polymorphing
     * of java.lang.reflect.Method and java.lang.reflect.Field
     * so that each can be treated as injection targets using
     * the same code.
     */
    public interface Member {
        Class<?> getDeclaringClass();

        String getName();

        Class<?> getType();
    }

    public static class FilledMember implements Member {
        private final String name;
        private final Class<?> type;
        private final Class<?> declaringClass;

        public FilledMember(final String name, final Class<?> type, final Class<?> declaringClass) {
            this.name = name;
            this.type = type;
            this.declaringClass = declaringClass;
        }

        public Class getDeclaringClass() {
            return declaringClass;
        }

        public String getName() {
            return name;
        }

        public Class getType() {
            return type;
        }

        @Override
        public String toString() {
            return "FilledMember{" +
                "name='" + name + '\'' +
                ", type=" + type.getName() +
                ", declaringClass=" + declaringClass.getName() +
                '}';
        }
    }

    /**
     * Implementation of Member for java.lang.reflect.Method
     * Used for injection targets that are annotated methods
     */
    public static class MethodMember implements Member {
        private final Method setter;

        public MethodMember(final Method method) {
            this.setter = method;
        }

        public Class<?> getType() {
            return setter.getParameterTypes()[0];
        }

        public Class<?> getDeclaringClass() {
            return setter.getDeclaringClass();
        }

        /**
         * The method name needs to be changed from "getFoo" to "foo"
         *
         * @return
         */
        public String getName() {
            final StringBuilder name = new StringBuilder(setter.getName());

            // remove 'set'
            name.delete(0, 3);

            // lowercase first char
            name.setCharAt(0, Character.toLowerCase(name.charAt(0)));

            return name.toString();
        }

        public String toString() {
            return setter.toString();
        }
    }

    /**
     * Implementation of Member for java.lang.reflect.Field
     * Used for injection targets that are annotated fields
     */
    public static class FieldMember implements Member {
        private final Field field;

        public FieldMember(final Field field) {
            this.field = field;
        }

        public Class<?> getType() {
            return field.getType();
        }

        public String toString() {
            return field.toString();
        }

        public Class<?> getDeclaringClass() {
            return field.getDeclaringClass();
        }

        public String getName() {
            return field.getName();
        }
    }

    public static List<Annotated<Class<?>>> sortClasses(final List<Annotated<Class<?>>> list) {
        list.sort(new Comparator<Annotated<Class<?>>>() {
            @Override
            public int compare(final Annotated<Class<?>> o1, final Annotated<Class<?>> o2) {
                return compareClasses(o1.get(), o2.get());
            }
        });
        return list;
    }

    public static List<Class<?>> sortClassesParentFirst(final List<Class<?>> list) {
        list.sort(new Comparator<Class<?>>() {
            @Override
            public int compare(final Class<?> o1, final Class<?> o2) {
                return compareClasses(o2, o1);
            }
        });
        return list;
    }

    public static List<Annotated<Method>> sortMethods(final List<Annotated<Method>> list) {
        list.sort(new Comparator<Annotated<Method>>() {
            @Override
            public int compare(final Annotated<Method> o1, final Annotated<Method> o2) {
                return compareClasses(o1.get().getDeclaringClass(), o2.get().getDeclaringClass());
            }
        });
        return list;
    }

    private static int compareClasses(final Class<?> a, final Class<?> b) {
        if (a == b) {
            return 0;
        }
        if (a.isAssignableFrom(b)) {
            return 1;
        }
        if (b.isAssignableFrom(a)) {
            return -1;
        }

        return 0;
    }

    public static Collection<String> findRestClasses(final WebModule webModule, final IAnnotationFinder finder) {
        final Collection<String> classes = new HashSet<>();

        // annotations on classes
        final List<Annotated<Class<?>>> annotatedClasses = finder.findMetaAnnotatedClasses(Path.class);
        for (final Annotated<Class<?>> aClazz : annotatedClasses) {
            final Class<?> clazz = aClazz.get();
            if (isInstantiable(clazz)) {
                if (!isEJB(clazz)) {
                    classes.add(clazz.getName());
                } else {
                    webModule.getEjbRestServices().add(clazz.getName());
                }
            } else if (clazz.isInterface()) {
                final Class api = clazz;
                final List impl = finder.findImplementations((Class<?>)api);
                if (impl != null && impl.size() == 1) { // single impl so that's the service
                    final Class implClass = (Class) impl.iterator().next();
                    final String name = implClass.getName();
                    if (!isEJB(implClass)) {
                        classes.add(name);
                    } else {
                        webModule.getEjbRestServices().add(name);
                    }
                }
            } else if (isEJB(clazz) && DynamicSubclass.isDynamic(clazz)) {
                classes.add(clazz.getName());
            }
        }

        if ("true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.jaxrs.scanning.methods", "false"))) {
            final List<Annotated<Method>> methods = finder.findMetaAnnotatedMethods(Path.class);
            for (final Annotated<Method> aMethod : methods) {
                final Method method = aMethod.get();
                final Class<?> clazz = method.getDeclaringClass();

                if (isInstantiable(clazz)) {
                    if (!isEJB(clazz)) {
                        classes.add(clazz.getName());
                    } else {
                        webModule.getEjbRestServices().add(clazz.getName());
                    }
                } else if (isEJB(clazz) && DynamicSubclass.isDynamic(clazz)) {
                    classes.add(clazz.getName());
                }
            }
        }

        return classes;
    }

    public static boolean isInstantiable(final Class<?> clazz) {
        final int modifiers = clazz.getModifiers();
        return !Modifier.isAbstract(modifiers)
                && !(clazz.getEnclosingClass() != null
                && !Modifier.isStatic(modifiers))
                && Modifier.isPublic(modifiers) && !clazz.isEnum();
    }

    private static boolean isEJB(final Class<?> clazz) {
        return clazz.isAnnotationPresent(Stateless.class)
            || clazz.isAnnotationPresent(Singleton.class)
            || clazz.isAnnotationPresent(ManagedBean.class)  // what a weird idea!
            || clazz.isAnnotationPresent(Stateful.class); // what another weird idea!
    }

    private static String realClassName(final String rawClassName) {
        if (rawClassName == null) {
            return null;
        }
        if (rawClassName.contains("/")) {
            return rawClassName.replace("/", ".");
        }
        return rawClassName;
    }

    private static Collection<Class<?>> metaToClass(final List<Annotated<Class<?>>> found) {
        final Collection<Class<?>> classes = new ArrayList<>(found.size());
        for (final Annotated<Class<?>> clazz : found) {
            classes.add(clazz.get());
        }
        return classes;
    }

    private static Map<String, Set<String>> addWebAnnotatedClassInfo(final Map<String, String> urlByClasses, final Map<String, Set<String>> classes, final List<Annotated<Class<?>>> found) {
        for (final Annotated<Class<?>> clazz : found) {
            final Class<?> loadedClass = clazz.get();
            final String name = loadedClass.getName();

            // url of the jar/folder containing the class
            String url = null;
            if (urlByClasses != null) {
                url = urlByClasses.get(name);
            }

            if (url == null) {
                try {
                    url = JarLocation.jarLocation(loadedClass).toURI().toURL().toExternalForm();
                } catch (final MalformedURLException e) {
                    url = classLocation(loadedClass).toExternalForm();
                }
            }

            Set<String> list = classes.computeIfAbsent(url, k -> new HashSet<>());

            // saving class url
            // first try the file approach (if the same class is in several classloaders it avoids weird errors)
            try {
                final File dir = new File(new URL(url).toURI());
                if (dir.isDirectory()) {
                    final File fileClazz = new File(dir, name.replace('.', '/') + ".class");
                    if (fileClazz.exists()) {
                        list.add(fileClazz.toURI().toURL().toExternalForm());
                    } else {
                        list.add(classLocation(loadedClass).toExternalForm());
                    }
                } else if (url.endsWith(".jar") && url.startsWith("file:")) {
                    list.add("jar:" + url + "!/" + name.replace('.', '/') + ".class");
                } else {
                    list.add(classLocation(loadedClass).toExternalForm());
                }
            } catch (final Exception e) {
                list.add(classLocation(loadedClass).toExternalForm());
            }
        }
        return classes;
    }

    public static URL classLocation(final Class clazz) {
        try {
            final String classFileName = clazz.getName().replace(".", "/") + ".class";

            final ClassLoader loader = clazz.getClassLoader();
            final URL url;
            if (loader != null) {
                if (TempClassLoader.class.isInstance(loader)) {
                    url = TempClassLoader.class.cast(loader).getInternalResource(classFileName);
                } else { // shouldn't occur
                    url = loader.getResource(classFileName);
                }
            } else {
                url = clazz.getResource(classFileName);
            }

            if (url == null) {
                throw new IllegalStateException("classloader.getResource(classFileName) returned a null URL");
            }

            return url;
        } catch (final RuntimeException e) {
            throw e;
        } catch (final Exception e) {
            throw new IllegalStateException(e);
        }
    }

    public EnvEntriesPropertiesDeployer getEnvEntriesPropertiesDeployer() {
        return envEntriesPropertiesDeployer;
    }


    public static class ProvidedJAXRSApplication extends Application {
        // no-method
    }

    public interface FolderDDMapper {
        File getDDFolder(final File dir);
    }
}
