@Override
  protected void performBoottime(OperationContext context, ModelNode operation, ModelNode model)
      throws OperationFailedException {

    checkIfNodeIdentifierIsDefault(context, model);

    boolean jts = model.hasDefined(JTS) && model.get(JTS).asBoolean();

    final Resource subsystemResource =
        context.readResourceFromRoot(PathAddress.pathAddress(TransactionExtension.SUBSYSTEM_PATH));
    final List<ServiceName> deps = new LinkedList<>();

    for (Resource.ResourceEntry re : subsystemResource.getChildren(CM_RESOURCE)) {
      deps.add(TxnServices.JBOSS_TXN_CMR.append(re.getName()));
    }

    // recovery environment
    performRecoveryEnvBoottime(context, model, jts, deps);

    // core environment
    performCoreEnvironmentBootTime(context, model);

    // coordinator environment
    performCoordinatorEnvBoottime(context, model, jts);

    // object store
    performObjectStoreBoottime(context, model);

    // always propagate the transaction context
    // TODO: need a better way to do this, but this value gets cached in a static
    // so we need to make sure we set it before anything tries to read it
    jtsPropertyManager.getJTSEnvironmentBean().setAlwaysPropagateContext(true);

    context.addStep(
        new AbstractDeploymentChainStep() {
          protected void execute(final DeploymentProcessorTarget processorTarget) {
            processorTarget.addDeploymentProcessor(
                TransactionExtension.SUBSYSTEM_NAME,
                Phase.PARSE,
                Phase.PARSE_TRANSACTION_ROLLBACK_ACTION,
                new TransactionLeakRollbackProcessor());
            processorTarget.addDeploymentProcessor(
                TransactionExtension.SUBSYSTEM_NAME,
                Phase.POST_MODULE,
                Phase.POST_MODULE_TRANSACTIONS_EE_CONCURRENCY,
                new EEConcurrencyContextHandleFactoryProcessor());
            processorTarget.addDeploymentProcessor(
                TransactionExtension.SUBSYSTEM_NAME,
                Phase.INSTALL,
                Phase.INSTALL_TRANSACTION_BINDINGS,
                new TransactionJndiBindingProcessor());
            processorTarget.addDeploymentProcessor(
                TransactionExtension.SUBSYSTEM_NAME,
                Phase.DEPENDENCIES,
                Phase.DEPENDENCIES_TRANSACTIONS,
                new TransactionDependenciesProcessor());
            processorTarget.addDeploymentProcessor(
                TransactionExtension.SUBSYSTEM_NAME,
                Phase.DEPENDENCIES,
                Phase.DEPENDENCIES_TRANSACTIONS,
                new CompensationsDependenciesDeploymentProcessor());
          }
        },
        OperationContext.Stage.RUNTIME);

    // bind the TransactionManger and the TSR into JNDI
    final BinderService tmBinderService = new BinderService("TransactionManager");
    final ServiceBuilder<ManagedReferenceFactory> tmBuilder =
        context
            .getServiceTarget()
            .addService(
                ContextNames.JBOSS_CONTEXT_SERVICE_NAME.append("TransactionManager"),
                tmBinderService);
    tmBuilder.addDependency(
        ContextNames.JBOSS_CONTEXT_SERVICE_NAME,
        ServiceBasedNamingStore.class,
        tmBinderService.getNamingStoreInjector());
    tmBuilder.addDependency(
        TransactionManagerService.SERVICE_NAME,
        javax.transaction.TransactionManager.class,
        new Injector<javax.transaction.TransactionManager>() {
          @Override
          public void inject(final javax.transaction.TransactionManager value)
              throws InjectionException {
            tmBinderService
                .getManagedObjectInjector()
                .inject(new ValueManagedReferenceFactory(new ImmediateValue<Object>(value)));
          }

          @Override
          public void uninject() {
            tmBinderService.getManagedObjectInjector().uninject();
          }
        });
    tmBuilder.install();

    final BinderService tmLegacyBinderService = new BinderService("TransactionManager");
    final ServiceBuilder<ManagedReferenceFactory> tmLegacyBuilder =
        context
            .getServiceTarget()
            .addService(
                ContextNames.JAVA_CONTEXT_SERVICE_NAME.append("TransactionManager"),
                tmLegacyBinderService);
    tmLegacyBuilder.addDependency(
        ContextNames.JAVA_CONTEXT_SERVICE_NAME,
        ServiceBasedNamingStore.class,
        tmLegacyBinderService.getNamingStoreInjector());
    tmLegacyBuilder.addDependency(
        TransactionManagerService.SERVICE_NAME,
        javax.transaction.TransactionManager.class,
        new Injector<javax.transaction.TransactionManager>() {
          @Override
          public void inject(final javax.transaction.TransactionManager value)
              throws InjectionException {
            tmLegacyBinderService
                .getManagedObjectInjector()
                .inject(new ValueManagedReferenceFactory(new ImmediateValue<Object>(value)));
          }

          @Override
          public void uninject() {
            tmLegacyBinderService.getManagedObjectInjector().uninject();
          }
        });
    tmLegacyBuilder.install();

    final BinderService tsrBinderService = new BinderService("TransactionSynchronizationRegistry");
    final ServiceBuilder<ManagedReferenceFactory> tsrBuilder =
        context
            .getServiceTarget()
            .addService(
                ContextNames.JBOSS_CONTEXT_SERVICE_NAME.append(
                    "TransactionSynchronizationRegistry"),
                tsrBinderService);
    tsrBuilder.addDependency(
        ContextNames.JBOSS_CONTEXT_SERVICE_NAME,
        ServiceBasedNamingStore.class,
        tsrBinderService.getNamingStoreInjector());
    tsrBuilder.addDependency(
        TransactionSynchronizationRegistryService.SERVICE_NAME,
        TransactionSynchronizationRegistry.class,
        new Injector<TransactionSynchronizationRegistry>() {
          @Override
          public void inject(final TransactionSynchronizationRegistry value)
              throws InjectionException {
            tsrBinderService
                .getManagedObjectInjector()
                .inject(new ValueManagedReferenceFactory(new ImmediateValue<Object>(value)));
          }

          @Override
          public void uninject() {
            tsrBinderService.getManagedObjectInjector().uninject();
          }
        });
    tsrBuilder.install();

    // Install the UserTransactionAccessControlService
    final UserTransactionAccessControlService lookupControlService =
        new UserTransactionAccessControlService();
    context
        .getServiceTarget()
        .addService(UserTransactionAccessControlService.SERVICE_NAME, lookupControlService)
        .install();

    // Bind the UserTransaction into JNDI
    final UserTransactionBindingService userTransactionBindingService =
        new UserTransactionBindingService("UserTransaction");
    final ServiceBuilder<ManagedReferenceFactory> utBuilder =
        context
            .getServiceTarget()
            .addService(
                ContextNames.JBOSS_CONTEXT_SERVICE_NAME.append("UserTransaction"),
                userTransactionBindingService);
    utBuilder
        .addDependency(
            ContextNames.JBOSS_CONTEXT_SERVICE_NAME,
            ServiceBasedNamingStore.class,
            userTransactionBindingService.getNamingStoreInjector())
        .addDependency(
            UserTransactionAccessControlService.SERVICE_NAME,
            UserTransactionAccessControlService.class,
            userTransactionBindingService.getUserTransactionAccessControlServiceInjector())
        .addDependency(
            UserTransactionService.SERVICE_NAME,
            UserTransaction.class,
            new ManagedReferenceInjector<UserTransaction>(
                userTransactionBindingService.getManagedObjectInjector()));
    utBuilder.install();

    // install the EE Concurrency transaction setup provider's service
    final TransactionSetupProviderService transactionSetupProviderService =
        new TransactionSetupProviderService();
    context
        .getServiceTarget()
        .addService(
            ConcurrentServiceNames.TRANSACTION_SETUP_PROVIDER_SERVICE_NAME,
            transactionSetupProviderService)
        .addDependency(
            TransactionManagerService.SERVICE_NAME,
            TransactionManager.class,
            transactionSetupProviderService.getTransactionManagerInjectedValue())
        .install();
  }
    @Override
    protected void performBoottime(
        OperationContext context,
        ModelNode operation,
        ModelNode model,
        ServiceVerificationHandler verificationHandler,
        List<ServiceController<?>> newControllers)
        throws OperationFailedException {
      SecurityLogger.ROOT_LOGGER.activatingSecuritySubsystem();

      if (context.getProcessType() != ProcessType.APPLICATION_CLIENT) {
        // remove once AS7-4687 is resolved
        SecurityActions.setSystemProperty(
            SecurityContextAssociation.SECURITYCONTEXT_THREADLOCAL, "true");
      }
      final ServiceTarget target = context.getServiceTarget();

      final SecurityBootstrapService bootstrapService = new SecurityBootstrapService();
      newControllers.add(
          target
              .addService(SecurityBootstrapService.SERVICE_NAME, bootstrapService)
              .addDependency(
                  Services.JBOSS_SERVICE_MODULE_LOADER,
                  ServiceModuleLoader.class,
                  bootstrapService.getServiceModuleLoaderInjectedValue())
              .addListener(verificationHandler)
              .setInitialMode(ServiceController.Mode.ACTIVE)
              .install());

      context.addStep(
          new AbstractDeploymentChainStep() {
            protected void execute(DeploymentProcessorTarget processorTarget) {}
          },
          OperationContext.Stage.RUNTIME);

      // add service to bind SecurityDomainJndiInjectable to JNDI
      final SecurityDomainJndiInjectable securityDomainJndiInjectable =
          new SecurityDomainJndiInjectable();
      final BinderService binderService = new BinderService("jaas");
      newControllers.add(
          target
              .addService(ContextNames.JBOSS_CONTEXT_SERVICE_NAME.append("jaas"), binderService)
              .addInjection(binderService.getManagedObjectInjector(), securityDomainJndiInjectable)
              .addDependency(
                  ContextNames.JBOSS_CONTEXT_SERVICE_NAME,
                  ServiceBasedNamingStore.class,
                  binderService.getNamingStoreInjector())
              .addDependency(
                  SecurityManagementService.SERVICE_NAME,
                  ISecurityManagement.class,
                  securityDomainJndiInjectable.getSecurityManagementInjector())
              .addListener(verificationHandler)
              .setInitialMode(ServiceController.Mode.ACTIVE)
              .install());

      // add security management service
      ModelNode modelNode =
          SecuritySubsystemRootResourceDefinition.DEEP_COPY_SUBJECT_MODE.resolveModelAttribute(
              context, model);
      final SecurityManagementService securityManagementService =
          new SecurityManagementService(
              AUTHENTICATION_MANAGER,
              modelNode.isDefined() && modelNode.asBoolean(),
              CALLBACK_HANDLER,
              AUTHORIZATION_MANAGER,
              AUDIT_MANAGER,
              IDENTITY_TRUST_MANAGER,
              MAPPING_MANAGER);
      newControllers.add(
          target
              .addService(SecurityManagementService.SERVICE_NAME, securityManagementService)
              .addDependency(
                  Services.JBOSS_SERVICE_MODULE_LOADER,
                  ServiceModuleLoader.class,
                  securityManagementService.getServiceModuleLoaderInjectedValue())
              .addListener(verificationHandler)
              .setInitialMode(ServiceController.Mode.ACTIVE)
              .install());

      // add subject factory service
      final SubjectFactoryService subjectFactoryService =
          new SubjectFactoryService(SUBJECT_FACTORY);
      newControllers.add(
          target
              .addService(SubjectFactoryService.SERVICE_NAME, subjectFactoryService)
              .addDependency(
                  SecurityManagementService.SERVICE_NAME,
                  ISecurityManagement.class,
                  subjectFactoryService.getSecurityManagementInjector())
              .addListener(verificationHandler)
              .setInitialMode(ServiceController.Mode.ACTIVE)
              .install());

      // add jaas configuration service
      Configuration loginConfig = XMLLoginConfigImpl.getInstance();
      final JaasConfigurationService jaasConfigurationService =
          new JaasConfigurationService(loginConfig);
      newControllers.add(
          target
              .addService(JaasConfigurationService.SERVICE_NAME, jaasConfigurationService)
              .addListener(verificationHandler)
              .setInitialMode(ServiceController.Mode.ACTIVE)
              .install());

      // add Simple Security Manager Service
      final SimpleSecurityManagerService simpleSecurityManagerService =
          new SimpleSecurityManagerService();

      newControllers.add(
          target
              .addService(SimpleSecurityManagerService.SERVICE_NAME, simpleSecurityManagerService)
              .addDependency(
                  SecurityManagementService.SERVICE_NAME,
                  ISecurityManagement.class,
                  simpleSecurityManagerService.getSecurityManagementInjector())
              .addListener(verificationHandler)
              .install());

      context.addStep(
          new AbstractDeploymentChainStep() {
            protected void execute(DeploymentProcessorTarget processorTarget) {
              processorTarget.addDeploymentProcessor(
                  SecurityExtension.SUBSYSTEM_NAME,
                  Phase.INSTALL,
                  Phase.INSTALL_JACC_POLICY,
                  new JaccEarDeploymentProcessor());
              processorTarget.addDeploymentProcessor(
                  SecurityExtension.SUBSYSTEM_NAME,
                  Phase.DEPENDENCIES,
                  Phase.DEPENDENCIES_SECURITY,
                  new SecurityDependencyProcessor());
            }
          },
          OperationContext.Stage.RUNTIME);
    }