@Override
  public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
    final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
    final EEModuleDescription moduleDescription =
        deploymentUnit.getAttachment(Attachments.EE_MODULE_DESCRIPTION);

    if (moduleDescription == null) {
      return;
    }

    final ServiceTarget serviceTarget = phaseContext.getServiceTarget();
    // if this is a war we need to bind to the modules comp namespace
    if (DeploymentTypeMarker.isType(DeploymentType.WAR, deploymentUnit)
        || DeploymentTypeMarker.isType(DeploymentType.APPLICATION_CLIENT, deploymentUnit)) {
      final ServiceName moduleContextServiceName =
          ContextNames.contextServiceNameOfModule(
              moduleDescription.getApplicationName(), moduleDescription.getModuleName());
      bindServices(deploymentUnit, serviceTarget, moduleContextServiceName);
    }

    for (ComponentDescription component : moduleDescription.getComponentDescriptions()) {
      if (component.getNamingMode() == ComponentNamingMode.CREATE) {
        final ServiceName compContextServiceName =
            ContextNames.contextServiceNameOfComponent(
                moduleDescription.getApplicationName(),
                moduleDescription.getModuleName(),
                component.getComponentName());
        bindServices(deploymentUnit, serviceTarget, compContextServiceName);
      }
    }
  }
  @Override
  public void deploy(final DeploymentPhaseContext phaseContext)
      throws DeploymentUnitProcessingException {
    final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
    final EEModuleDescription eeModuleDescription =
        deploymentUnit.getAttachment(Attachments.EE_MODULE_DESCRIPTION);
    final Module module =
        deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.MODULE);

    if (eeModuleDescription == null) {
      return;
    }

    final Collection<ComponentDescription> componentConfigurations =
        eeModuleDescription.getComponentDescriptions();

    final DeploymentReflectionIndex deploymentReflectionIndex =
        deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.REFLECTION_INDEX);
    final EEApplicationClasses applicationClasses =
        deploymentUnit.getAttachment(Attachments.EE_APPLICATION_CLASSES_DESCRIPTION);

    for (ComponentDescription componentConfiguration : componentConfigurations) {
      if (componentConfiguration instanceof SessionBeanComponentDescription) {
        try {
          processComponentConfig(
              deploymentUnit,
              applicationClasses,
              module,
              deploymentReflectionIndex,
              (SessionBeanComponentDescription) componentConfiguration);
        } catch (Exception e) {
          throw MESSAGES.failToMergeData(componentConfiguration.getComponentName(), e);
        }
      }
    }
    if (appclient) {
      for (ComponentDescription componentDescription :
          deploymentUnit.getAttachmentList(Attachments.ADDITIONAL_RESOLVABLE_COMPONENTS)) {
        if (componentDescription instanceof SessionBeanComponentDescription) {
          try {
            processComponentConfig(
                deploymentUnit,
                applicationClasses,
                module,
                deploymentReflectionIndex,
                (SessionBeanComponentDescription) componentDescription);
          } catch (Exception e) {
            throw MESSAGES.failToMergeData(componentDescription.getComponentName(), e);
          }
        }
      }
    }
  }
  @Override
  public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {

    final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();
    final DeploymentUnit topLevelDeployment =
        deploymentUnit.getParent() == null ? deploymentUnit : deploymentUnit.getParent();
    final ServiceTarget serviceTarget = phaseContext.getServiceTarget();
    if (!WeldDeploymentMarker.isPartOfWeldDeployment(topLevelDeployment)) {
      return;
    }

    final Collection<ServiceName> dependencies =
        deploymentUnit.getAttachment(Attachments.JNDI_DEPENDENCIES);

    BeanDeploymentArchiveImpl rootBda =
        deploymentUnit.getAttachment(WeldAttachments.DEPLOYMENT_ROOT_BEAN_DEPLOYMENT_ARCHIVE);
    if (rootBda == null) {
      // this archive is not actually a bean archive.
      // then use the top level root bda
      rootBda =
          topLevelDeployment.getAttachment(WeldAttachments.DEPLOYMENT_ROOT_BEAN_DEPLOYMENT_ARCHIVE);
    }
    if (rootBda == null) {
      WeldLogger.ROOT_LOGGER.couldNotFindBeanManagerForDeployment(deploymentUnit.getName());
      return;
    }

    final ServiceName weldServiceName =
        topLevelDeployment.getServiceName().append(WeldBootstrapService.SERVICE_NAME);

    // add the BeanManager service
    final ServiceName beanManagerServiceName = BeanManagerService.serviceName(deploymentUnit);
    BeanManagerService beanManagerService = new BeanManagerService(rootBda.getId());
    serviceTarget
        .addService(beanManagerServiceName, beanManagerService)
        .addDependency(
            weldServiceName, WeldBootstrapService.class, beanManagerService.getWeldContainer())
        .install();
    ;

    final EEModuleDescription moduleDescription =
        deploymentUnit.getAttachment(org.jboss.as.ee.component.Attachments.EE_MODULE_DESCRIPTION);

    if (moduleDescription == null) {
      return;
    }

    // hack to set up a java:comp binding for jar deployments as well as wars
    if (DeploymentTypeMarker.isType(DeploymentType.WAR, deploymentUnit)
        || deploymentUnit.getName().endsWith(".jar")) {
      // bind the bean manager to JNDI
      final ServiceName moduleContextServiceName =
          ContextNames.contextServiceNameOfModule(
              moduleDescription.getApplicationName(), moduleDescription.getModuleName());
      bindBeanManager(
          serviceTarget,
          beanManagerServiceName,
          moduleContextServiceName,
          dependencies,
          phaseContext.getServiceRegistry());
    }

    // bind the bm into java:comp for all components that require it
    for (ComponentDescription component : moduleDescription.getComponentDescriptions()) {
      if (component.getNamingMode() == ComponentNamingMode.CREATE) {
        final ServiceName compContextServiceName =
            ContextNames.contextServiceNameOfComponent(
                moduleDescription.getApplicationName(),
                moduleDescription.getModuleName(),
                component.getComponentName());
        bindBeanManager(
            serviceTarget,
            beanManagerServiceName,
            compContextServiceName,
            dependencies,
            phaseContext.getServiceRegistry());
      }
    }
    deploymentUnit.addToAttachmentList(Attachments.SETUP_ACTIONS, new WeldContextSetup());
  }
  @Override
  public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitProcessingException {
    final DeploymentUnit deploymentUnit = phaseContext.getDeploymentUnit();

    final Module module =
        deploymentUnit.getAttachment(org.jboss.as.server.deployment.Attachments.MODULE);
    if (module == null) {
      return;
    }

    final ResteasyDeploymentData resteasy =
        deploymentUnit.getAttachment(JaxrsAttachments.RESTEASY_DEPLOYMENT_DATA);
    if (resteasy == null) {
      return;
    }
    // right now I only support resources
    if (!resteasy.isScanResources()) return;

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

    final ClassLoader loader = module.getClassLoader();

    for (final ComponentDescription component : moduleDescription.getComponentDescriptions()) {
      Class<?> componentClass = null;
      try {
        componentClass = loader.loadClass(component.getComponentClassName());
      } catch (ClassNotFoundException e) {
        throw new DeploymentUnitProcessingException(e);
      }
      if (!GetRestful.isRootResource(componentClass)) continue;

      if (component instanceof SessionBeanComponentDescription) {
        Class[] jaxrsType = GetRestful.getSubResourceClass(componentClass);
        final String jndiName;
        if (component.getViews().size() == 1) {
          // only 1 view, just use the simple JNDI name
          jndiName =
              "java:app/" + moduleDescription.getModuleName() + "/" + component.getComponentName();
        } else {
          boolean found = false;
          String foundType = null;
          for (final ViewDescription view : component.getViews()) {
            for (Class subResource : jaxrsType) {
              if (view.getViewClassName().equals(subResource.getName())) {
                foundType = subResource.getName();
                found = true;
                break;
              }
            }
            if (found) {
              break;
            }
          }
          if (!found) {
            throw JaxrsMessages.MESSAGES.typeNameNotAnEjbView(
                Arrays.asList(jaxrsType), component.getComponentName());
          }
          jndiName =
              "java:app/"
                  + moduleDescription.getModuleName()
                  + "/"
                  + component.getComponentName()
                  + "!"
                  + foundType;
        }

        JAXRS_LOGGER.debugf(
            "Found JAX-RS Managed Bean: %s local jndi jaxRsTypeName: %s",
            component.getComponentClassName(), jndiName);
        StringBuilder buf = new StringBuilder();
        buf.append(jndiName)
            .append(";")
            .append(component.getComponentClassName())
            .append(";")
            .append("true");

        resteasy.getScannedJndiComponentResources().add(buf.toString());
        // make sure its removed from list
        resteasy.getScannedResourceClasses().remove(component.getComponentClassName());
      } else if (component instanceof ManagedBeanComponentDescription) {
        String jndiName =
            "java:app/" + moduleDescription.getModuleName() + "/" + component.getComponentName();

        JAXRS_LOGGER.debugf(
            "Found JAX-RS Managed Bean: %s local jndi name: %s",
            component.getComponentClassName(), jndiName);
        StringBuilder buf = new StringBuilder();
        buf.append(jndiName)
            .append(";")
            .append(component.getComponentClassName())
            .append(";")
            .append("true");

        resteasy.getScannedJndiComponentResources().add(buf.toString());
        // make sure its removed from list
        resteasy.getScannedResourceClasses().remove(component.getComponentClassName());
      }
    }
  }
  private void processSessionBeanMetaData(
      final DeploymentUnit deploymentUnit, final SessionBeanMetaData sessionBean)
      throws DeploymentUnitProcessingException {
    final EjbJarDescription ejbJarDescription = getEjbJarDescription(deploymentUnit);
    final EEModuleDescription eeModuleDescription =
        deploymentUnit.getAttachment(Attachments.EE_MODULE_DESCRIPTION);
    final List<ComponentDescription> additionalComponents =
        deploymentUnit.getAttachmentList(Attachments.ADDITIONAL_RESOLVABLE_COMPONENTS);

    final String beanName = sessionBean.getName();
    // the important bit is to skip already processed EJBs via annotations
    if (ejbJarDescription.hasComponent(beanName)) {
      final ComponentDescription description = eeModuleDescription.getComponentByName(beanName);
      if (description instanceof SessionBeanComponentDescription) {
        ((SessionBeanComponentDescription) description).setDescriptorData(sessionBean);
      } else {
        throw new DeploymentUnitProcessingException(
            "Session bean with name "
                + beanName
                + " referenced in ejb-jar.xml could not be created, as existing non session bean component with same name already exists: "
                + description);
      }
      return;
    }

    if (appclient) {
      for (final ComponentDescription component : additionalComponents) {
        if (component.getComponentName().equals(beanName)) {
          if (component instanceof SessionBeanComponentDescription) {
            ((SessionBeanComponentDescription) component).setDescriptorData(sessionBean);
          } else {
            throw new DeploymentUnitProcessingException(
                "Session bean with name "
                    + beanName
                    + " referenced in ejb-jar.xml could not be created, as existing non session bean component with same name already exists: "
                    + component);
          }
          return;
        }
      }
    }
    final SessionType sessionType = sessionBean.getSessionType();

    if (sessionType == null) {}

    if (sessionType == null && sessionBean instanceof GenericBeanMetaData) {
      // TODO: this is a hack
      return;
    }
    final String beanClassName = sessionBean.getEjbClass();
    final SessionBeanComponentDescription sessionBeanDescription;
    switch (sessionType) {
      case Stateless:
        sessionBeanDescription =
            new StatelessComponentDescription(
                beanName, beanClassName, ejbJarDescription, deploymentUnit.getServiceName());
        break;
      case Stateful:
        sessionBeanDescription =
            new StatefulComponentDescription(
                beanName, beanClassName, ejbJarDescription, deploymentUnit.getServiceName());
        break;
      case Singleton:
        sessionBeanDescription =
            new SingletonComponentDescription(
                beanName, beanClassName, ejbJarDescription, deploymentUnit.getServiceName());
        break;
      default:
        throw new IllegalArgumentException("Unknown session bean type: " + sessionType);
    }
    if (appclient) {
      deploymentUnit.addToAttachmentList(
          Attachments.ADDITIONAL_RESOLVABLE_COMPONENTS, sessionBeanDescription);

    } else {
      // Add this component description to module description
      ejbJarDescription.getEEModuleDescription().addComponent(sessionBeanDescription);
    }
    sessionBeanDescription.setDescriptorData(sessionBean);
  }
  @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);
                                }
                              });
                    }
                  });
        }
      }
    }
  }