public void configure(
        final DeploymentPhaseContext context,
        final ComponentConfiguration componentConfiguration,
        final ViewDescription description,
        final ViewConfiguration configuration)
        throws DeploymentUnitProcessingException {
      // Create method indexes
      final DeploymentReflectionIndex reflectionIndex =
          context.getDeploymentUnit().getAttachment(REFLECTION_INDEX);
      final List<Method> methods = configuration.getProxyFactory().getCachedMethods();
      for (final Method method : methods) {
        MethodIdentifier methodIdentifier = MethodIdentifier.getIdentifierForMethod(method);
        Method componentMethod =
            ClassReflectionIndexUtil.findMethod(
                reflectionIndex, componentConfiguration.getComponentClass(), methodIdentifier);

        if (componentMethod != null) {

          if ((BRIDGE & componentMethod.getModifiers()) != 0) {
            Collection<Method> otherMethods =
                ClassReflectionIndexUtil.findMethods(
                    reflectionIndex,
                    reflectionIndex.getClassIndex(componentConfiguration.getComponentClass()),
                    methodIdentifier.getName(),
                    methodIdentifier.getParameterTypes());
            // try and find the non-bridge method to delegate to
            for (final Method other : otherMethods) {
              if ((BRIDGE & other.getModifiers()) == 0) {
                componentMethod = other;
                break;
              }
            }
          }

          configuration.addViewInterceptor(
              method,
              new ImmediateInterceptorFactory(new ComponentDispatcherInterceptor(componentMethod)),
              InterceptorOrder.View.COMPONENT_DISPATCHER);
          configuration.addClientInterceptor(
              method,
              CLIENT_DISPATCHER_INTERCEPTOR_FACTORY,
              InterceptorOrder.Client.CLIENT_DISPATCHER);
        }
      }

      configuration.addClientPostConstructInterceptor(
          Interceptors.getTerminalInterceptorFactory(),
          InterceptorOrder.ClientPostConstruct.TERMINAL_INTERCEPTOR);
      configuration.addClientPreDestroyInterceptor(
          Interceptors.getTerminalInterceptorFactory(),
          InterceptorOrder.ClientPreDestroy.TERMINAL_INTERCEPTOR);
    }
  /**
   * Construct a new instance.
   *
   * @param componentConfiguration the component configuration
   */
  public EJBComponentCreateService(
      final ComponentConfiguration componentConfiguration,
      final EjbJarConfiguration ejbJarConfiguration) {
    super(componentConfiguration);

    this.componentConfiguration = componentConfiguration;

    this.ejbJarConfiguration = ejbJarConfiguration;

    EJBComponentDescription ejbComponentDescription =
        (EJBComponentDescription) componentConfiguration.getComponentDescription();
    this.transactionManagementType = ejbComponentDescription.getTransactionManagementType();

    // CMTTx
    if (transactionManagementType.equals(TransactionManagementType.CONTAINER)) {
      // slurp some memory
      this.txAttrs =
          new ConcurrentHashMap<
              MethodIntf,
              ConcurrentMap<String, ConcurrentMap<ArrayKey, TransactionAttributeType>>>();
    } else {
      this.txAttrs = null;
    }
    List<ViewConfiguration> views = componentConfiguration.getViews();
    if (views != null) {
      for (ViewConfiguration view : views) {
        final MethodIntf viewType =
            ejbComponentDescription.getMethodIntf(view.getViewClass().getName());
        for (Method method : view.getProxyFactory().getCachedMethods()) {
          this.processTxAttr(ejbComponentDescription, viewType, method);
        }
      }
    }
    // FIXME: TODO: a temporary measure until EJBTHREE-2120 is fully resolved, let's create tx
    // attribute map
    // for the component methods. Once the issue is resolved, we should get rid of this block and
    // just rely on setting
    // up the tx attributes only for the views exposed by this component
    Set<Method> componentMethods = componentConfiguration.getDefinedComponentMethods();
    if (componentMethods != null) {
      for (Method method : componentMethods) {
        this.processTxAttr(ejbComponentDescription, MethodIntf.BEAN, method);
      }
    }
    final HashMap<String, ServiceName> viewServices = new HashMap<String, ServiceName>();
    for (ViewDescription view : componentConfiguration.getComponentDescription().getViews()) {
      viewServices.put(view.getViewClassName(), view.getServiceName());
    }
    this.viewServices = viewServices;
  }
  @Override
  public void configure(
      DeploymentPhaseContext context,
      ComponentConfiguration componentConfiguration,
      ViewDescription viewDescription,
      ViewConfiguration viewConfiguration)
      throws DeploymentUnitProcessingException {
    if (componentConfiguration.getComponentDescription() instanceof EJBComponentDescription
        == false) {
      throw MESSAGES.invalidEjbComponent(
          componentConfiguration.getComponentName(), componentConfiguration.getComponentClass());
    }
    final EJBComponentDescription ejbComponentDescription =
        (EJBComponentDescription) componentConfiguration.getComponentDescription();
    // if security is not enabled on the EJB, then do *not* add the security related interceptors
    if (!ejbComponentDescription.isSecurityEnabled()) {
      ROOT_LOGGER.debug(
          "Security is *not* enabled on EJB: "
              + ejbComponentDescription.getEJBName()
              + ", no security interceptors will apply");
      return;
    }
    final String viewClassName = viewDescription.getViewClassName();
    // setup the security context interceptor
    viewConfiguration.addViewInterceptor(
        new SecurityContextInterceptorFactory(), InterceptorOrder.View.SECURITY_CONTEXT);

    // now setup the rest of the method specific security interceptor(s)
    final List<Method> viewMethods = viewConfiguration.getProxyFactory().getCachedMethods();
    for (final Method viewMethod : viewMethods) {
      // TODO: proxy factory exposes non-public methods, is this a bug in the no-interface view?
      if (!Modifier.isPublic(viewMethod.getModifiers())) {
        continue;
      }
      if (viewMethod.getDeclaringClass() == WriteReplaceInterface.class) {
        continue;
      }
      final EJBMethodSecurityMetaData ejbMethodSecurityMetaData =
          new EJBMethodSecurityMetaData(componentConfiguration, viewClassName, viewMethod);
      // setup the authorization interceptor
      final Interceptor authorizationInterceptor =
          new AuthorizationInterceptor(ejbMethodSecurityMetaData, viewClassName, viewMethod);
      viewConfiguration.addViewInterceptor(
          viewMethod,
          new ImmediateInterceptorFactory(authorizationInterceptor),
          InterceptorOrder.View.EJB_SECURITY_AUTHORIZATION_INTERCEPTOR);
    }
  }
 private static Method getComponentMethod(
     final ComponentConfiguration componentConfiguration,
     final String name,
     final Class<?>[] parameterTypes) {
   try {
     return componentConfiguration.getComponentClass().getMethod(name, parameterTypes);
   } catch (NoSuchMethodException e) {
     return null;
   }
 }
    public void configure(
        final DeploymentPhaseContext context,
        final ComponentConfiguration componentConfiguration,
        final ViewDescription description,
        final ViewConfiguration configuration)
        throws DeploymentUnitProcessingException {
      // Create method indexes
      final DeploymentReflectionIndex reflectionIndex =
          context.getDeploymentUnit().getAttachment(REFLECTION_INDEX);
      final List<Method> methods = configuration.getProxyFactory().getCachedMethods();
      for (final Method method : methods) {
        MethodIdentifier methodIdentifier = MethodIdentifier.getIdentifierForMethod(method);
        Method componentMethod =
            ClassReflectionIndexUtil.findMethod(
                reflectionIndex, componentConfiguration.getComponentClass(), methodIdentifier);

        if (componentMethod == null
            && method.getDeclaringClass().isInterface()
            && (method.getModifiers() & (ABSTRACT | PUBLIC | STATIC)) == PUBLIC) {
          // no component method and the interface method is defaulted, so we really do want to
          // invoke on the interface method
          componentMethod = method;
        }
        if (componentMethod != null) {

          if ((BRIDGE & componentMethod.getModifiers()) != 0) {
            Method other =
                findRealMethodForBridgeMethod(
                    componentMethod, componentConfiguration, reflectionIndex, methodIdentifier);
            // try and find the non-bridge method to delegate to
            if (other != null) {
              componentMethod = other;
            }
          }

          configuration.addViewInterceptor(
              method,
              new ImmediateInterceptorFactory(new ComponentDispatcherInterceptor(componentMethod)),
              InterceptorOrder.View.COMPONENT_DISPATCHER);
          configuration.addClientInterceptor(
              method,
              CLIENT_DISPATCHER_INTERCEPTOR_FACTORY,
              InterceptorOrder.Client.CLIENT_DISPATCHER);
        }
      }

      configuration.addClientPostConstructInterceptor(
          Interceptors.getTerminalInterceptorFactory(),
          InterceptorOrder.ClientPostConstruct.TERMINAL_INTERCEPTOR);
      configuration.addClientPreDestroyInterceptor(
          Interceptors.getTerminalInterceptorFactory(),
          InterceptorOrder.ClientPreDestroy.TERMINAL_INTERCEPTOR);
    }
  @Override
  public ComponentConfiguration createConfiguration(
      final ClassIndex classIndex,
      final ClassLoader moduleClassLoader,
      final ModuleLoader moduleLoader) {
    final ComponentConfiguration configuration =
        super.createConfiguration(classIndex, moduleClassLoader, moduleLoader);
    configuration.setInstanceFactory(
        new ManagedReferenceFactory() {
          @Override
          public ManagedReference getReference() {
            return new ManagedReference() {
              @Override
              public void release() {}

              @Override
              public Object getInstance() {
                return null;
              }
            };
          }
        });
    return configuration;
  };
 @Override
 protected boolean requiresInterceptors(
     final Method method, final ComponentConfiguration componentConfiguration) {
   if (super.requiresInterceptors(method, componentConfiguration)) {
     return true;
   }
   final EJBComponentDescription ejbComponentDescription =
       (EJBComponentDescription) componentConfiguration.getComponentDescription();
   if ((ejbComponentDescription.getTimeoutMethod() != null
           && ejbComponentDescription.getTimeoutMethod().equals(method))
       || ejbComponentDescription.getScheduleMethods().containsKey(method)) {
     return true;
   }
   return false;
 }
 @Override
 public void configure(
     final DeploymentPhaseContext context,
     final ComponentConfiguration componentConfiguration,
     final ViewDescription description,
     final ViewConfiguration configuration)
     throws DeploymentUnitProcessingException {
   final EJBComponentDescription ejbComponentDescription =
       (EJBComponentDescription) componentConfiguration.getComponentDescription();
   if (ejbComponentDescription.getTransactionManagementType()
       == TransactionManagementType.CONTAINER) {
     configuration.addViewInterceptor(
         EjbIIOPTransactionInterceptor.FACTORY, InterceptorOrder.View.EJB_IIOP_TRANSACTION);
   }
 }
    @Override
    public void configure(
        final DeploymentPhaseContext context,
        final ComponentConfiguration componentConfiguration,
        final ViewDescription description,
        final ViewConfiguration configuration)
        throws DeploymentUnitProcessingException {

      // Create view bindings
      final List<BindingConfiguration> bindingConfigurations =
          configuration.getBindingConfigurations();
      for (String bindingName : description.getBindingNames()) {
        bindingConfigurations.add(
            new BindingConfiguration(
                bindingName,
                description.createInjectionSource(
                    description.getServiceName(),
                    Values.immediateValue(componentConfiguration.getModuleClassLoader()))));
      }
    }
  /**
   * Construct a new instance.
   *
   * @param componentConfiguration the component configuration
   */
  public EJBComponentCreateService(
      final ComponentConfiguration componentConfiguration,
      final ApplicationExceptions applicationExceptions) {
    super(componentConfiguration);

    this.applicationExceptions = applicationExceptions;
    final EJBComponentDescription ejbComponentDescription =
        (EJBComponentDescription) componentConfiguration.getComponentDescription();
    this.transactionManagementType = ejbComponentDescription.getTransactionManagementType();

    this.timerService = ejbComponentDescription.getTimerService();
    this.policyContextID = ejbComponentDescription.getPolicyContextID();

    // CMTTx
    if (transactionManagementType.equals(TransactionManagementType.CONTAINER)) {
      this.txAttrs = new HashMap<MethodTransactionAttributeKey, TransactionAttributeType>();
      this.txTimeouts = new HashMap<MethodTransactionAttributeKey, Integer>();
    } else {
      this.txAttrs = null;
      this.txTimeouts = null;
    }
    // Setup the security metadata for the bean
    this.securityMetaData = new EJBSecurityMetaData(componentConfiguration);

    if (ejbComponentDescription.isTimerServiceRequired()) {
      Map<Method, InterceptorFactory> timeoutInterceptors =
          new IdentityHashMap<Method, InterceptorFactory>();
      for (Method method : componentConfiguration.getDefinedComponentMethods()) {
        if ((ejbComponentDescription.getTimeoutMethod() != null
                && ejbComponentDescription.getTimeoutMethod().equals(method))
            || ejbComponentDescription.getScheduleMethods().containsKey(method)) {
          final InterceptorFactory interceptorFactory =
              Interceptors.getChainedInterceptorFactory(
                  componentConfiguration.getAroundTimeoutInterceptors(method));
          timeoutInterceptors.put(method, interceptorFactory);
        }
      }
      this.timeoutInterceptors = timeoutInterceptors;
    } else {
      timeoutInterceptors = Collections.emptyMap();
    }

    List<ViewConfiguration> views = componentConfiguration.getViews();
    if (views != null) {
      for (ViewConfiguration view : views) {
        // TODO: Move this into a configurator
        final EJBViewConfiguration ejbView = (EJBViewConfiguration) view;
        final MethodIntf viewType = ejbView.getMethodIntf();
        for (Method method : view.getProxyFactory().getCachedMethods()) {
          // TODO: proxy factory exposes non-public methods, is this a bug in the no-interface view?
          if (!Modifier.isPublic(method.getModifiers())) continue;
          final Method componentMethod =
              getComponentMethod(
                  componentConfiguration, method.getName(), method.getParameterTypes());
          if (componentMethod != null) {
            this.processTxAttr(ejbComponentDescription, viewType, componentMethod);
          } else {
            this.processTxAttr(ejbComponentDescription, viewType, method);
          }
        }
      }
    }

    this.timeoutMethod = ejbComponentDescription.getTimeoutMethod();

    // FIXME: TODO: a temporary measure until EJBTHREE-2120 is fully resolved, let's create tx
    // attribute map
    // for the component methods. Once the issue is resolved, we should get rid of this block and
    // just rely on setting
    // up the tx attributes only for the views exposed by this component
    // AS7-899: We only want to process public methods of the proper sub-class.
    // (getDefinedComponentMethods returns all in random order)
    // TODO: use ClassReflectionIndex (low prio, because we store the result without class name)
    // (which is a bug: AS7-905)
    Set<Method> lifeCycle = new HashSet<>(componentConfiguration.getLifecycleMethods());
    for (Method method : componentConfiguration.getComponentClass().getMethods()) {
      this.processTxAttr(ejbComponentDescription, MethodIntf.BEAN, method);
      lifeCycle.remove(method);
    }
    // now handle non-public lifecycle methods declared on the bean class itself
    // see WFLY-4127
    for (Method method : lifeCycle) {
      if (method.getDeclaringClass().equals(componentConfiguration.getComponentClass())) {
        this.processTxAttr(ejbComponentDescription, MethodIntf.BEAN, method);
      }
    }

    final HashMap<String, ServiceName> viewServices = new HashMap<String, ServiceName>();
    for (ViewDescription view : componentConfiguration.getComponentDescription().getViews()) {
      viewServices.put(view.getViewClassName(), view.getServiceName());
    }
    this.viewServices = viewServices;
    final EjbHomeViewDescription localHome = ejbComponentDescription.getEjbLocalHomeView();
    this.ejbLocalHome =
        localHome == null ? null : ejbComponentDescription.getEjbLocalHomeView().getServiceName();
    final EjbHomeViewDescription home = ejbComponentDescription.getEjbHomeView();
    this.ejbHome = home == null ? null : home.getServiceName();
    final EJBViewDescription ejbObject = ejbComponentDescription.getEjbRemoteView();
    this.ejbObject = ejbObject == null ? null : ejbObject.getServiceName();
    final EJBViewDescription ejbLocalObject = ejbComponentDescription.getEjbLocalView();
    this.ejbLocalObject = ejbLocalObject == null ? null : ejbLocalObject.getServiceName();
    this.applicationName = componentConfiguration.getApplicationName();
    this.earApplicationName =
        componentConfiguration
            .getComponentDescription()
            .getModuleDescription()
            .getEarApplicationName();
    this.moduleName = componentConfiguration.getModuleName();
    this.distinctName =
        componentConfiguration.getComponentDescription().getModuleDescription().getDistinctName();
    this.shutDownInterceptorFactory = ejbComponentDescription.getShutDownInterceptorFactory();
  }
  @Override
  public ComponentConfiguration createConfiguration(
      final ClassIndex classIndex, final ClassLoader moduleClassLoder) {
    final ComponentConfiguration statelessComponentConfiguration =
        new ComponentConfiguration(this, classIndex, moduleClassLoder);
    // setup the component create service
    statelessComponentConfiguration.setComponentCreateServiceFactory(
        new StatelessComponentCreateServiceFactory());

    // setup the configurator to inject the PoolConfig in the StatelessSessionComponentCreateService
    final StatelessComponentDescription statelessComponentDescription =
        (StatelessComponentDescription) statelessComponentConfiguration.getComponentDescription();
    statelessComponentConfiguration
        .getCreateDependencies()
        .add(new PoolInjectingConfigurator(statelessComponentDescription));

    // add the bmt interceptor
    if (TransactionManagementType.BEAN.equals(this.getTransactionManagementType())) {
      getConfigurators()
          .add(
              new ComponentConfigurator() {
                @Override
                public void configure(
                    final DeploymentPhaseContext context,
                    final ComponentDescription description,
                    final ComponentConfiguration configuration)
                    throws DeploymentUnitProcessingException {
                  final ComponentInstanceInterceptorFactory slsbBmtInterceptorFactory =
                      new ComponentInstanceInterceptorFactory() {
                        @Override
                        protected Interceptor create(
                            Component component, InterceptorFactoryContext context) {
                          if (!(component instanceof StatelessSessionComponent)) {
                            throw MESSAGES.componentNotInstanceOfSessionComponent(
                                component, component.getComponentClass(), "stateless");
                          }
                          return new StatelessBMTInterceptor((StatelessSessionComponent) component);
                        }
                      };
                  // add the bmt interceptor factory
                  configuration.addComponentInterceptor(
                      slsbBmtInterceptorFactory,
                      InterceptorOrder.Component.BMT_TRANSACTION_INTERCEPTOR,
                      false);
                  configuration.addTimeoutInterceptor(
                      slsbBmtInterceptorFactory,
                      InterceptorOrder.Component.BMT_TRANSACTION_INTERCEPTOR);
                }
              });
    } else {
      getConfigurators()
          .add(
              new ComponentConfigurator() {
                @Override
                public void configure(
                    final DeploymentPhaseContext context,
                    final ComponentDescription description,
                    final ComponentConfiguration configuration)
                    throws DeploymentUnitProcessingException {
                  configuration.addTimeoutInterceptor(
                      TimerCMTTxInterceptor.FACTORY,
                      InterceptorOrder.Component.TIMEOUT_CMT_INTERCEPTOR);
                }
              });
    }

    return statelessComponentConfiguration;
  }
  @Override
  public ComponentConfiguration createConfiguration(
      final ClassIndex classIndex,
      final ClassLoader moduleClassLoader,
      final ModuleLoader moduleLoader) {
    final ComponentConfiguration statelessComponentConfiguration =
        new ComponentConfiguration(this, classIndex, moduleClassLoader, moduleLoader);
    // setup the component create service
    statelessComponentConfiguration.setComponentCreateServiceFactory(
        new StatelessComponentCreateServiceFactory());

    // setup the configurator to inject the PoolConfig in the StatelessSessionComponentCreateService
    final StatelessComponentDescription statelessComponentDescription =
        (StatelessComponentDescription) statelessComponentConfiguration.getComponentDescription();
    statelessComponentConfiguration
        .getCreateDependencies()
        .add(new PoolInjectingConfigurator(statelessComponentDescription));

    // add the bmt interceptor
    if (TransactionManagementType.BEAN.equals(this.getTransactionManagementType())) {
      getConfigurators()
          .add(
              new ComponentConfigurator() {
                @Override
                public void configure(
                    final DeploymentPhaseContext context,
                    final ComponentDescription description,
                    final ComponentConfiguration configuration)
                    throws DeploymentUnitProcessingException {

                  // add the bmt interceptor factory
                  configuration.addComponentInterceptor(
                      EjbBMTInterceptor.FACTORY,
                      InterceptorOrder.Component.BMT_TRANSACTION_INTERCEPTOR,
                      false);
                }
              });
    }
    getConfigurators()
        .add(
            new ComponentConfigurator() {
              @Override
              public void configure(
                  final DeploymentPhaseContext context,
                  final ComponentDescription description,
                  final ComponentConfiguration configuration)
                  throws DeploymentUnitProcessingException {
                if (TransactionManagementType.CONTAINER.equals(getTransactionManagementType())) {

                  final EEApplicationClasses applicationClasses =
                      context
                          .getDeploymentUnit()
                          .getAttachment(Attachments.EE_APPLICATION_CLASSES_DESCRIPTION);
                  InterceptorClassDescription interceptorConfig =
                      ComponentDescription.mergeInterceptorConfig(
                          configuration.getComponentClass(),
                          applicationClasses.getClassByName(description.getComponentClassName()),
                          description,
                          MetadataCompleteMarker.isMetadataComplete(context.getDeploymentUnit()));

                  configuration.addPostConstructInterceptor(
                      new LifecycleCMTTxInterceptor.Factory(
                          interceptorConfig.getPostConstruct(), true),
                      InterceptorOrder.ComponentPostConstruct.TRANSACTION_INTERCEPTOR);
                  configuration.addPreDestroyInterceptor(
                      new LifecycleCMTTxInterceptor.Factory(
                          interceptorConfig.getPreDestroy(), true),
                      InterceptorOrder.ComponentPreDestroy.TRANSACTION_INTERCEPTOR);

                  configuration.addTimeoutViewInterceptor(
                      TimerCMTTxInterceptor.FACTORY,
                      InterceptorOrder.View.CMT_TRANSACTION_INTERCEPTOR);
                }
                configuration.addTimeoutViewInterceptor(
                    StatelessComponentInstanceAssociatingFactory.instance(),
                    InterceptorOrder.View.ASSOCIATING_INTERCEPTOR);
              }
            });

    return statelessComponentConfiguration;
  }
  /**
   * Construct a new instance.
   *
   * @param componentConfiguration the component configuration
   */
  public StatefulSessionComponentCreateService(
      final ComponentConfiguration componentConfiguration,
      final ApplicationExceptions ejbJarConfiguration) {
    super(componentConfiguration, ejbJarConfiguration);

    final StatefulComponentDescription componentDescription =
        (StatefulComponentDescription) componentConfiguration.getComponentDescription();
    final ClassLoader classLoader = componentConfiguration.getModuleClassLoader();
    final InterceptorFactory tcclInterceptorFactory =
        new ImmediateInterceptorFactory(new ContextClassLoaderInterceptor(classLoader));
    final InterceptorFactory namespaceContextInterceptorFactory =
        componentConfiguration.getNamespaceContextInterceptorFactory();

    this.afterBeginMethod = componentDescription.getAfterBegin();
    this.afterBegin =
        (this.afterBeginMethod != null)
            ? Interceptors.getChainedInterceptorFactory(
                tcclInterceptorFactory,
                namespaceContextInterceptorFactory,
                CurrentInvocationContextInterceptor.FACTORY,
                invokeMethodOnTarget(this.afterBeginMethod))
            : null;
    this.afterCompletionMethod = componentDescription.getAfterCompletion();
    this.afterCompletion =
        (this.afterCompletionMethod != null)
            ? Interceptors.getChainedInterceptorFactory(
                tcclInterceptorFactory,
                namespaceContextInterceptorFactory,
                CurrentInvocationContextInterceptor.FACTORY,
                invokeMethodOnTarget(this.afterCompletionMethod))
            : null;
    this.beforeCompletionMethod = componentDescription.getBeforeCompletion();
    this.beforeCompletion =
        (this.beforeCompletionMethod != null)
            ? Interceptors.getChainedInterceptorFactory(
                tcclInterceptorFactory,
                namespaceContextInterceptorFactory,
                CurrentInvocationContextInterceptor.FACTORY,
                invokeMethodOnTarget(this.beforeCompletionMethod))
            : null;
    this.prePassivate =
        Interceptors.getChainedInterceptorFactory(
            componentConfiguration.getPrePassivateInterceptors());
    this.postActivate =
        Interceptors.getChainedInterceptorFactory(
            componentConfiguration.getPostActivateInterceptors());
    this.statefulTimeout = componentDescription.getStatefulTimeout();
    // the interceptor chain for EJB e.x remove methods
    this.ejb2XRemoveMethod =
        Interceptors.getChainedInterceptorFactory(
            StatefulSessionSynchronizationInterceptor.factory(
                componentDescription.getTransactionManagementType()),
            new ImmediateInterceptorFactory(new StatefulRemoveInterceptor(false)),
            Interceptors.getTerminalInterceptorFactory());
    this.cache = componentDescription.getCache();
    this.loader = componentConfiguration.getModuleClassLoader();
    MarshallingConfiguration marshallingConfiguration = new MarshallingConfiguration();
    marshallingConfiguration.setClassResolver(
        ModularClassResolver.getInstance(componentConfiguration.getModuleLoader()));
    marshallingConfiguration.setSerializabilityChecker(
        new StatefulSessionBeanSerializabilityChecker(componentConfiguration.getComponentClass()));
    marshallingConfiguration.setClassTable(new StatefulSessionBeanClassTable());
    // ObjectTable which handles serialization of EJB proxies
    marshallingConfiguration.setObjectTable(new EJBClientContextIdentifierObjectTable());
    this.marshallingConfigurations =
        Collections.singletonMap(CURRENT_MARSHALLING_VERSION, marshallingConfiguration);
    this.serializableInterceptorContextKeys = componentConfiguration.getInterceptorContextKeys();
    this.passivationCapable = componentDescription.isPassivationApplicable();
  }
  @Override
  public void configure(
      final DeploymentPhaseContext context,
      final ComponentConfiguration componentConfiguration,
      final ViewDescription description,
      final ViewConfiguration configuration)
      throws DeploymentUnitProcessingException {
    // note that we don't have to handle all methods on the EJBObject, as some are handled client
    // side
    final DeploymentReflectionIndex index =
        context.getDeploymentUnit().getAttachment(Attachments.REFLECTION_INDEX);
    for (final Method method : configuration.getProxyFactory().getCachedMethods()) {

      if (method.getName().equals("getPrimaryKey") && method.getParameterTypes().length == 0) {
        configuration.addClientInterceptor(
            method,
            ViewDescription.CLIENT_DISPATCHER_INTERCEPTOR_FACTORY,
            InterceptorOrder.Client.CLIENT_DISPATCHER);
        configuration.addViewInterceptor(
            method, PRIMARY_KEY_INTERCEPTOR, InterceptorOrder.View.COMPONENT_DISPATCHER);
      } else if (method.getName().equals("remove") && method.getParameterTypes().length == 0) {
        handleRemoveMethod(componentConfiguration, configuration, index, method);

      } else if (method.getName().equals("getEJBLocalHome")
          && method.getParameterTypes().length == 0) {
        configuration.addClientInterceptor(
            method,
            ViewDescription.CLIENT_DISPATCHER_INTERCEPTOR_FACTORY,
            InterceptorOrder.Client.CLIENT_DISPATCHER);
        final GetHomeInterceptorFactory factory = new GetHomeInterceptorFactory();
        configuration.addViewInterceptor(
            method, factory, InterceptorOrder.View.COMPONENT_DISPATCHER);
        final SessionBeanComponentDescription componentDescription =
            (SessionBeanComponentDescription) componentConfiguration.getComponentDescription();
        componentConfiguration
            .getStartDependencies()
            .add(
                new DependencyConfigurator<ComponentStartService>() {
                  @Override
                  public void configureDependency(
                      final ServiceBuilder<?> serviceBuilder, final ComponentStartService service)
                      throws DeploymentUnitProcessingException {
                    EjbHomeViewDescription ejbLocalHomeView =
                        componentDescription.getEjbLocalHomeView();
                    if (ejbLocalHomeView == null) {
                      throw EjbLogger.ROOT_LOGGER.beanLocalHomeInterfaceIsNull(
                          componentDescription.getComponentName());
                    }
                    serviceBuilder.addDependency(
                        ejbLocalHomeView.getServiceName(),
                        ComponentView.class,
                        factory.getViewToCreate());
                  }
                });
      } else if (method.getName().equals("getEJBHome") && method.getParameterTypes().length == 0) {
        configuration.addClientInterceptor(
            method,
            ViewDescription.CLIENT_DISPATCHER_INTERCEPTOR_FACTORY,
            InterceptorOrder.Client.CLIENT_DISPATCHER);
        final GetHomeInterceptorFactory factory = new GetHomeInterceptorFactory();
        configuration.addViewInterceptor(
            method, factory, InterceptorOrder.View.COMPONENT_DISPATCHER);
        final SessionBeanComponentDescription componentDescription =
            (SessionBeanComponentDescription) componentConfiguration.getComponentDescription();
        componentConfiguration
            .getStartDependencies()
            .add(
                new DependencyConfigurator<ComponentStartService>() {
                  @Override
                  public void configureDependency(
                      final ServiceBuilder<?> serviceBuilder, final ComponentStartService service)
                      throws DeploymentUnitProcessingException {
                    EjbHomeViewDescription ejbHomeView = componentDescription.getEjbHomeView();
                    if (ejbHomeView == null) {
                      throw EjbLogger.ROOT_LOGGER.beanHomeInterfaceIsNull(
                          componentDescription.getComponentName());
                    }
                    serviceBuilder.addDependency(
                        ejbHomeView.getServiceName(),
                        ComponentView.class,
                        factory.getViewToCreate());
                  }
                });
      } else if (method.getName().equals("getHandle") && method.getParameterTypes().length == 0) {
        // ignore, handled client side
      } else if (method.getName().equals("isIdentical")
          && method.getParameterTypes().length == 1
          && (method.getParameterTypes()[0].equals(EJBObject.class)
              || method.getParameterTypes()[0].equals(EJBLocalObject.class))) {

        handleIsIdenticalMethod(componentConfiguration, configuration, index, method);
      } else {
        final Method componentMethod =
            ClassReflectionIndexUtil.findMethod(
                index,
                componentConfiguration.getComponentClass(),
                MethodIdentifier.getIdentifierForMethod(method));

        if (componentMethod != null) {
          if (!Modifier.isPublic(componentMethod.getModifiers())) {
            throw EjbLogger.ROOT_LOGGER.ejbBusinessMethodMustBePublic(componentMethod);
          }
          configuration.addViewInterceptor(
              method,
              new ImmediateInterceptorFactory(new ComponentDispatcherInterceptor(componentMethod)),
              InterceptorOrder.View.COMPONENT_DISPATCHER);
          configuration.addClientInterceptor(
              method,
              ViewDescription.CLIENT_DISPATCHER_INTERCEPTOR_FACTORY,
              InterceptorOrder.Client.CLIENT_DISPATCHER);
        } else if (method.getDeclaringClass() != Object.class
            && method.getDeclaringClass() != WriteReplaceInterface.class) {
          throw EjbLogger.ROOT_LOGGER.couldNotFindViewMethodOnEjb(
              method, description.getViewClassName(), componentConfiguration.getComponentName());
        }
      }
    }

    configuration.addClientPostConstructInterceptor(
        Interceptors.getTerminalInterceptorFactory(),
        InterceptorOrder.ClientPostConstruct.TERMINAL_INTERCEPTOR);
    configuration.addClientPreDestroyInterceptor(
        Interceptors.getTerminalInterceptorFactory(),
        InterceptorOrder.ClientPreDestroy.TERMINAL_INTERCEPTOR);
  }
  @Override
  public ComponentConfiguration createConfiguration(
      final ClassIndex classIndex,
      final ClassLoader moduleClassLoader,
      final ModuleLoader moduleLoader) {

    ComponentConfiguration singletonComponentConfiguration =
        new ComponentConfiguration(this, classIndex, moduleClassLoader, moduleLoader);
    // setup the component create service
    singletonComponentConfiguration.setComponentCreateServiceFactory(
        new SingletonComponentCreateServiceFactory(this.isInitOnStartup(), dependsOn));
    if (isExplicitSecurityDomainConfigured()) {
      getConfigurators()
          .add(
              new ComponentConfigurator() {
                @Override
                public void configure(
                    final DeploymentPhaseContext context,
                    final ComponentDescription description,
                    final ComponentConfiguration configuration)
                    throws DeploymentUnitProcessingException {
                  configuration.addPostConstructInterceptor(
                      new SecurityContextInterceptorFactory(
                          isExplicitSecurityDomainConfigured(), false),
                      InterceptorOrder.View.SECURITY_CONTEXT);
                }
              });
    }
    if (getTransactionManagementType().equals(TransactionManagementType.CONTAINER)) {
      // we need to add the transaction interceptor to the lifecycle methods
      getConfigurators()
          .add(
              new ComponentConfigurator() {
                @Override
                public void configure(
                    final DeploymentPhaseContext context,
                    final ComponentDescription description,
                    final ComponentConfiguration configuration)
                    throws DeploymentUnitProcessingException {

                  final EEApplicationClasses applicationClasses =
                      context
                          .getDeploymentUnit()
                          .getAttachment(Attachments.EE_APPLICATION_CLASSES_DESCRIPTION);
                  InterceptorClassDescription interceptorConfig =
                      ComponentDescription.mergeInterceptorConfig(
                          configuration.getComponentClass(),
                          applicationClasses.getClassByName(description.getComponentClassName()),
                          description,
                          MetadataCompleteMarker.isMetadataComplete(context.getDeploymentUnit()));

                  configuration.addPostConstructInterceptor(
                      new LifecycleCMTTxInterceptor.Factory(
                          interceptorConfig.getPostConstruct(), true),
                      InterceptorOrder.ComponentPostConstruct.TRANSACTION_INTERCEPTOR);
                  configuration.addPreDestroyInterceptor(
                      new LifecycleCMTTxInterceptor.Factory(
                          interceptorConfig.getPreDestroy(), true),
                      InterceptorOrder.ComponentPreDestroy.TRANSACTION_INTERCEPTOR);

                  configuration.addTimeoutViewInterceptor(
                      TimerCMTTxInterceptor.FACTORY,
                      InterceptorOrder.View.CMT_TRANSACTION_INTERCEPTOR);
                }
              });
    } else {
      // add the bmt interceptor
      getConfigurators()
          .add(
              new ComponentConfigurator() {
                @Override
                public void configure(
                    final DeploymentPhaseContext context,
                    final ComponentDescription description,
                    final ComponentConfiguration configuration)
                    throws DeploymentUnitProcessingException {

                  configuration.addPostConstructInterceptor(
                      EjbBMTInterceptor.FACTORY,
                      InterceptorOrder.ComponentPostConstruct.TRANSACTION_INTERCEPTOR);
                  configuration.addPreDestroyInterceptor(
                      EjbBMTInterceptor.FACTORY,
                      InterceptorOrder.ComponentPreDestroy.TRANSACTION_INTERCEPTOR);
                  // add the bmt interceptor factory
                  configuration.addComponentInterceptor(
                      EjbBMTInterceptor.FACTORY,
                      InterceptorOrder.Component.BMT_TRANSACTION_INTERCEPTOR,
                      false);
                }
              });
    }

    return singletonComponentConfiguration;
  }