private void processMessageBeans(
      final DeploymentUnit deploymentUnit,
      final Collection<AnnotationInstance> messageBeanAnnotations,
      final CompositeIndex compositeIndex)
      throws DeploymentUnitProcessingException {
    if (messageBeanAnnotations.isEmpty()) return;

    final EjbJarDescription ejbJarDescription = getEjbJarDescription(deploymentUnit);
    final ServiceName deploymentUnitServiceName = deploymentUnit.getServiceName();
    DeploymentDescriptorEnvironment deploymentDescriptorEnvironment = null;

    for (final AnnotationInstance messageBeanAnnotation : messageBeanAnnotations) {
      final AnnotationTarget target = messageBeanAnnotation.target();
      final ClassInfo beanClassInfo = (ClassInfo) target;
      if (!assertMDBClassValidity(beanClassInfo)) {
        continue;
      }
      final String ejbName = beanClassInfo.name().local();
      final AnnotationValue nameValue = messageBeanAnnotation.value("name");
      final String beanName =
          nameValue == null || nameValue.asString().isEmpty() ? ejbName : nameValue.asString();
      final MessageDrivenBeanMetaData beanMetaData =
          getEnterpriseBeanMetaData(deploymentUnit, beanName, MessageDrivenBeanMetaData.class);
      final String beanClassName;
      final String messageListenerInterfaceName;
      boolean replacement =
          deploymentUnit.getAttachment(Attachments.EJB_ANNOTATION_PROPERTY_REPLACEMENT);
      final Properties activationConfigProperties =
          getActivationConfigProperties(messageBeanAnnotation, replacement);
      final String messagingType;
      if (beanMetaData != null) {
        beanClassName = override(beanClassInfo.name().toString(), beanMetaData.getEjbClass());
        deploymentDescriptorEnvironment =
            new DeploymentDescriptorEnvironment("java:comp/env/", beanMetaData);

        if (beanMetaData instanceof MessageDrivenBeanMetaData) {
          // It may actually be GenericBeanMetadata instance
          final MessageDrivenBeanMetaData mdb = (MessageDrivenBeanMetaData) beanMetaData;
          messagingType = mdb.getMessagingType();
          final ActivationConfigMetaData activationConfigMetaData = mdb.getActivationConfig();
          if (activationConfigMetaData != null) {
            final ActivationConfigPropertiesMetaData propertiesMetaData =
                activationConfigMetaData.getActivationConfigProperties();
            if (propertiesMetaData != null) {
              for (final ActivationConfigPropertyMetaData propertyMetaData : propertiesMetaData) {
                activationConfigProperties.put(
                    propertyMetaData.getKey(), propertyMetaData.getValue());
              }
            }
          }
        } else if (beanMetaData instanceof JBossGenericBeanMetaData) {
          // TODO: fix the hierarchy so this is not needed
          final JBossGenericBeanMetaData mdb = (JBossGenericBeanMetaData) beanMetaData;
          messagingType = mdb.getMessagingType();
          final ActivationConfigMetaData activationConfigMetaData = mdb.getActivationConfig();
          if (activationConfigMetaData != null) {
            final ActivationConfigPropertiesMetaData propertiesMetaData =
                activationConfigMetaData.getActivationConfigProperties();
            if (propertiesMetaData != null) {
              for (final ActivationConfigPropertyMetaData propertyMetaData : propertiesMetaData) {
                activationConfigProperties.put(
                    propertyMetaData.getKey(), propertyMetaData.getValue());
              }
            }
          }
        } else {
          messagingType = null;
        }
        messageListenerInterfaceName =
            messagingType != null
                ? messagingType
                : getMessageListenerInterface(compositeIndex, messageBeanAnnotation);

      } else {
        beanClassName = beanClassInfo.name().toString();
        messageListenerInterfaceName =
            getMessageListenerInterface(compositeIndex, messageBeanAnnotation);
      }
      final String defaultResourceAdapterName =
          this.getDefaultResourceAdapterName(deploymentUnit.getServiceRegistry());
      final MessageDrivenComponentDescription beanDescription =
          new MessageDrivenComponentDescription(
              beanName,
              beanClassName,
              ejbJarDescription,
              deploymentUnitServiceName,
              messageListenerInterfaceName,
              activationConfigProperties,
              defaultResourceAdapterName,
              beanMetaData);
      beanDescription.setDeploymentDescriptorEnvironment(deploymentDescriptorEnvironment);

      addComponent(deploymentUnit, beanDescription);
    }

    EjbDeploymentMarker.mark(deploymentUnit);
  }
  @Override
  public void deploy(final DeploymentPhaseContext phaseContext)
      throws DeploymentUnitProcessingException {

    final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
    if (!IIOPDeploymentMarker.isIIOPDeployment(deploymentUnit)) {
      return;
    }

    final EEModuleDescription moduleDescription =
        deploymentUnit.getAttachment(Attachments.EE_MODULE_DESCRIPTION);
    if (!EjbDeploymentMarker.isEjbDeployment(deploymentUnit)) {
      return;
    }

    // a bean-name -> IIOPMetaData map, reflecting the assembly descriptor IIOP configuration.
    Map<String, IIOPMetaData> iiopMetaDataMap = new HashMap<String, IIOPMetaData>();
    final EjbJarMetaData ejbMetaData =
        deploymentUnit.getAttachment(EjbDeploymentAttachmentKeys.EJB_JAR_METADATA);
    if (ejbMetaData != null && ejbMetaData.getAssemblyDescriptor() != null) {
      List<IIOPMetaData> iiopMetaDatas =
          ejbMetaData.getAssemblyDescriptor().getAny(IIOPMetaData.class);
      if (iiopMetaDatas != null && iiopMetaDatas.size() > 0) {
        for (IIOPMetaData metaData : iiopMetaDatas) {
          iiopMetaDataMap.put(metaData.getEjbName(), metaData);
        }
      }
    }

    final DeploymentClassIndex classIndex =
        deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.CLASS_INDEX);
    final DeploymentReflectionIndex deploymentReflectionIndex =
        deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.REFLECTION_INDEX);
    final Module module =
        deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.MODULE);
    if (moduleDescription != null) {
      for (final ComponentDescription componentDescription :
          moduleDescription.getComponentDescriptions()) {
        if (componentDescription instanceof EJBComponentDescription) {
          final EJBComponentDescription ejbComponentDescription =
              (EJBComponentDescription) componentDescription;
          if (ejbComponentDescription.getEjbRemoteView() != null
              && ejbComponentDescription.getEjbHomeView() != null) {
            // check if there is IIOP metadata for the bean - first using the bean name, then the
            // wildcard "*" if needed.
            IIOPMetaData iiopMetaData = iiopMetaDataMap.get(ejbComponentDescription.getEJBName());
            if (iiopMetaData == null) {
              iiopMetaData = iiopMetaDataMap.get(IIOPMetaData.WILDCARD_BEAN_NAME);
            }
            // the bean will be exposed via IIOP if it has IIOP metadata that applies to it or if
            // IIOP access
            // has been enabled by default in the EJB3 subsystem.
            if (iiopMetaData != null || settingsService.isEnabledByDefault()) {
              processEjb(
                  ejbComponentDescription,
                  classIndex,
                  deploymentReflectionIndex,
                  module,
                  phaseContext.getServiceTarget(),
                  iiopMetaData);
            }
          }
        }
      }
    }
  }
  private void processSessionBeans(
      final DeploymentUnit deploymentUnit,
      final List<AnnotationInstance> sessionBeanAnnotations,
      final SessionBeanComponentDescription.SessionBeanType annotatedSessionBeanType) {

    final EjbJarDescription ejbJarDescription = getEjbJarDescription(deploymentUnit);
    final ServiceName deploymentUnitServiceName = deploymentUnit.getServiceName();

    // process these session bean annotations and create component descriptions out of it
    for (final AnnotationInstance sessionBeanAnnotation : sessionBeanAnnotations) {
      final AnnotationTarget target = sessionBeanAnnotation.target();
      if (!(target instanceof ClassInfo)) {
        // Let's just WARN and move on. No need to throw an error
        EjbMessages.MESSAGES.annotationOnlyAllowedOnClass(
            sessionBeanAnnotation.name().toString(), target);
        continue;
      }
      final ClassInfo sessionBeanClassInfo = (ClassInfo) target;
      // skip if it's not a valid class for session bean
      if (!assertSessionBeanClassValidity(sessionBeanClassInfo)) {
        continue;
      }
      final String ejbName = sessionBeanClassInfo.name().local();
      final AnnotationValue nameValue = sessionBeanAnnotation.value("name");
      final String beanName =
          nameValue == null || nameValue.asString().isEmpty() ? ejbName : nameValue.asString();
      final SessionBeanMetaData beanMetaData =
          getEnterpriseBeanMetaData(deploymentUnit, beanName, SessionBeanMetaData.class);
      final SessionBeanComponentDescription.SessionBeanType sessionBeanType;
      final String beanClassName;
      if (beanMetaData != null) {
        beanClassName =
            override(sessionBeanClassInfo.name().toString(), beanMetaData.getEjbClass());
        sessionBeanType =
            override(
                annotatedSessionBeanType,
                descriptionOf(((SessionBeanMetaData) beanMetaData).getSessionType()));
      } else {
        beanClassName = sessionBeanClassInfo.name().toString();
        sessionBeanType = annotatedSessionBeanType;
      }

      final SessionBeanComponentDescription sessionBeanDescription;
      switch (sessionBeanType) {
        case STATELESS:
          sessionBeanDescription =
              new StatelessComponentDescription(
                  beanName,
                  beanClassName,
                  ejbJarDescription,
                  deploymentUnitServiceName,
                  beanMetaData);
          break;
        case STATEFUL:
          sessionBeanDescription =
              new StatefulComponentDescription(
                  beanName,
                  beanClassName,
                  ejbJarDescription,
                  deploymentUnitServiceName,
                  beanMetaData);
          // If passivation is disabled for the SFSB, either via annotation or via DD, then setup
          // the component
          // description appropriately
          final boolean passivationCapableAnnotationValue =
              sessionBeanAnnotation.value("passivationCapable") == null
                  ? true
                  : sessionBeanAnnotation.value("passivationCapable").asBoolean();
          // TODO: Pass the DD value as first param for override
          final boolean passivationApplicable = override(null, passivationCapableAnnotationValue);
          ((StatefulComponentDescription) sessionBeanDescription)
              .setPassivationApplicable(passivationApplicable);
          break;
        case SINGLETON:
          sessionBeanDescription =
              new SingletonComponentDescription(
                  beanName,
                  beanClassName,
                  ejbJarDescription,
                  deploymentUnitServiceName,
                  beanMetaData);
          break;
        default:
          throw EjbMessages.MESSAGES.unknownSessionBeanType(sessionBeanType.name());
      }

      addComponent(deploymentUnit, sessionBeanDescription);
    }

    EjbDeploymentMarker.mark(deploymentUnit);
  }
  @Override
  public void deploy(final DeploymentPhaseContext phaseContext)
      throws DeploymentUnitProcessingException {

    final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
    final EEModuleDescription moduleDescription =
        deploymentUnit.getAttachment(Attachments.EE_MODULE_DESCRIPTION);
    final Module module =
        deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.MODULE);

    final EjbJarMetaData ejbJarMetaData =
        deploymentUnit.getAttachment(EjbDeploymentAttachmentKeys.EJB_JAR_METADATA);

    ServiceName defaultTimerPersistenceService =
        TimerPersistence.SERVICE_NAME.append(defaultTimerDataStore);
    final Map<String, ServiceName> timerPersistenceServices = new HashMap<String, ServiceName>();
    // if this is an EJB deployment then create an EJB module level TimerServiceRegistry which can
    // be used by the timer services
    // of all EJB components that belong to this EJB module.
    final TimerServiceRegistry timerServiceRegistry =
        EjbDeploymentMarker.isEjbDeployment(deploymentUnit) ? new TimerServiceRegistry() : null;

    if (ejbJarMetaData != null && ejbJarMetaData.getAssemblyDescriptor() != null) {
      List<TimerServiceMetaData> timerService =
          ejbJarMetaData.getAssemblyDescriptor().getAny(TimerServiceMetaData.class);
      if (timerService != null) {
        for (TimerServiceMetaData data : timerService) {
          if (data.getEjbName().equals("*")) {
            defaultTimerPersistenceService =
                TimerPersistence.SERVICE_NAME.append(data.getDataStoreName());
          } else {
            timerPersistenceServices.put(
                data.getEjbName(), TimerPersistence.SERVICE_NAME.append(data.getDataStoreName()));
          }
        }
      }
    }
    final ServiceName finalDefaultTimerPersistenceService = defaultTimerPersistenceService;

    for (final ComponentDescription componentDescription :
        moduleDescription.getComponentDescriptions()) {

      if (componentDescription.isTimerServiceApplicable()) {
        if (componentDescription.isTimerServiceRequired()) {
          // the component has timeout methods, it needs a 'real' timer service
          final String deploymentName;
          if (moduleDescription.getDistinctName() == null
              || moduleDescription.getDistinctName().length() == 0) {
            deploymentName =
                moduleDescription.getApplicationName() + "." + moduleDescription.getModuleName();
          } else {
            deploymentName =
                moduleDescription.getApplicationName()
                    + "."
                    + moduleDescription.getModuleName()
                    + "."
                    + moduleDescription.getDistinctName();
          }

          ROOT_LOGGER.debug(
              "Installing timer service for component " + componentDescription.getComponentName());
          componentDescription
              .getConfigurators()
              .add(
                  new ComponentConfigurator() {
                    @Override
                    public void configure(
                        final DeploymentPhaseContext context,
                        final ComponentDescription description,
                        final ComponentConfiguration configuration)
                        throws DeploymentUnitProcessingException {
                      final EJBComponentDescription ejbComponentDescription =
                          (EJBComponentDescription) description;

                      final ServiceName invokerServiceName =
                          ejbComponentDescription
                              .getServiceName()
                              .append(TimedObjectInvokerImpl.SERVICE_NAME);
                      final TimedObjectInvokerImpl invoker =
                          new TimedObjectInvokerImpl(deploymentName, module);
                      context
                          .getServiceTarget()
                          .addService(invokerServiceName, invoker)
                          .addDependency(
                              componentDescription.getCreateServiceName(),
                              EJBComponent.class,
                              invoker.getEjbComponent())
                          .install();

                      // install the timer create service
                      final ServiceName serviceName =
                          componentDescription
                              .getServiceName()
                              .append(TimerServiceImpl.SERVICE_NAME);
                      final TimerServiceImpl service =
                          new TimerServiceImpl(
                              ejbComponentDescription.getScheduleMethods(),
                              serviceName,
                              timerServiceRegistry);
                      final ServiceBuilder<javax.ejb.TimerService> createBuilder =
                          context.getServiceTarget().addService(serviceName, service);
                      createBuilder.addDependency(
                          TIMER_SERVICE_NAME, Timer.class, service.getTimerInjectedValue());
                      createBuilder.addDependency(
                          componentDescription.getCreateServiceName(),
                          EJBComponent.class,
                          service.getEjbComponentInjectedValue());
                      createBuilder.addDependency(
                          timerServiceThreadPool,
                          ExecutorService.class,
                          service.getExecutorServiceInjectedValue());
                      if (timerPersistenceServices.containsKey(
                          ejbComponentDescription.getEJBName())) {
                        createBuilder.addDependency(
                            timerPersistenceServices.get(ejbComponentDescription.getEJBName()),
                            TimerPersistence.class,
                            service.getTimerPersistence());
                      } else {
                        createBuilder.addDependency(
                            finalDefaultTimerPersistenceService,
                            TimerPersistence.class,
                            service.getTimerPersistence());
                      }
                      createBuilder.addDependency(
                          invokerServiceName,
                          TimedObjectInvoker.class,
                          service.getTimedObjectInvoker());
                      createBuilder.install();
                      ejbComponentDescription.setTimerService(service);
                      // inject the timer service directly into the start service
                      configuration
                          .getStartDependencies()
                          .add(
                              new DependencyConfigurator<ComponentStartService>() {
                                @Override
                                public void configureDependency(
                                    final ServiceBuilder<?> serviceBuilder,
                                    final ComponentStartService service)
                                    throws DeploymentUnitProcessingException {
                                  serviceBuilder.addDependency(serviceName);
                                }
                              });
                    }
                  });
        } else {
          // the EJB is of a type that could have a timer service, but has no timer methods.
          // just bind the non-functional timer service
          componentDescription
              .getConfigurators()
              .add(
                  new ComponentConfigurator() {
                    @Override
                    public void configure(
                        final DeploymentPhaseContext context,
                        final ComponentDescription description,
                        final ComponentConfiguration configuration)
                        throws DeploymentUnitProcessingException {
                      final EJBComponentDescription ejbComponentDescription =
                          (EJBComponentDescription) description;
                      final ServiceName nonFunctionalTimerServiceName =
                          NonFunctionalTimerService.serviceNameFor(ejbComponentDescription);
                      final NonFunctionalTimerService nonFunctionalTimerService;
                      if (ejbComponentDescription instanceof StatefulComponentDescription) {
                        // for stateful beans, use a different error message that gets thrown from
                        // the NonFunctionalTimerService
                        nonFunctionalTimerService =
                            new NonFunctionalTimerService(
                                EjbMessages.MESSAGES.timerServiceMethodNotAllowedForSFSB(
                                    ejbComponentDescription.getComponentName()),
                                timerServiceRegistry);
                      } else {
                        nonFunctionalTimerService =
                            new NonFunctionalTimerService(
                                EjbMessages.MESSAGES.ejbHasNoTimerMethods(), timerServiceRegistry);
                      }
                      // add the non-functional timer service as a MSC service
                      context
                          .getServiceTarget()
                          .addService(nonFunctionalTimerServiceName, nonFunctionalTimerService)
                          .install();
                      // set the timer service in the EJB component
                      ejbComponentDescription.setTimerService(nonFunctionalTimerService);
                      // now we want the EJB component to depend on this non-functional timer
                      // service to start
                      configuration
                          .getStartDependencies()
                          .add(
                              new DependencyConfigurator<ComponentStartService>() {
                                @Override
                                public void configureDependency(
                                    ServiceBuilder<?> serviceBuilder, ComponentStartService service)
                                    throws DeploymentUnitProcessingException {
                                  serviceBuilder.addDependency(nonFunctionalTimerServiceName);
                                }
                              });
                    }
                  });
        }
      }
    }
  }