void removeRuntimeServices(OperationContext context, ModelNode operation, ModelNode model)
      throws OperationFailedException {

    final PathAddress address = getCacheContainerAddressFromOperation(operation);
    final String containerName = address.getLastElement().getValue();

    // need to remove all container-related services started, in reverse order
    context.removeService(KeyAffinityServiceFactoryService.getServiceName(containerName));

    // remove the BinderService entry
    ModelNode resolvedValue = null;
    final String jndiName =
        (resolvedValue =
                    CacheContainerResourceDefinition.JNDI_NAME.resolveModelAttribute(
                        context, model))
                .isDefined()
            ? resolvedValue.asString()
            : null;
    context.removeService(
        createCacheContainerBinding(jndiName, containerName).getBinderServiceName());

    // remove the cache container
    context.removeService(EmbeddedCacheManagerService.getServiceName(containerName));
    context.removeService(EmbeddedCacheManagerConfigurationService.getServiceName(containerName));
    context.removeService(GlobalComponentRegistryService.getServiceName(containerName));

    // check if a channel was installed
    final ServiceName channelServiceName = ChannelService.getServiceName(containerName);
    final ServiceController<?> channelServiceController =
        context.getServiceRegistry(false).getService(channelServiceName);
    if (channelServiceController != null) {
      for (ChannelServiceProvider provider :
          ServiceLoader.load(
              ChannelServiceProvider.class, ChannelServiceProvider.class.getClassLoader())) {
        for (ServiceName name : provider.getServiceNames(containerName)) {
          context.removeService(name);
        }
      }
      // unregister the protocol metrics by adding a step
      ChannelInstanceResourceDefinition.addChannelProtocolMetricsDeregistrationStep(
          context, containerName);

      context.removeService(createChannelBinding(containerName).getBinderServiceName());
      context.removeService(channelServiceName);
    }
  }
  Collection<ServiceController<?>> installRuntimeServices(
      OperationContext context,
      ModelNode operation,
      ModelNode containerModel,
      ServiceVerificationHandler verificationHandler)
      throws OperationFailedException {

    final PathAddress address = getCacheContainerAddressFromOperation(operation);
    final String name = address.getLastElement().getValue();
    final ServiceTarget target = context.getServiceTarget();

    // pick up the attribute values from the model
    ModelNode resolvedValue = null;
    // make default cache non required (AS7-3488)
    final String defaultCache =
        (resolvedValue =
                    CacheContainerResourceDefinition.DEFAULT_CACHE.resolveModelAttribute(
                        context, containerModel))
                .isDefined()
            ? resolvedValue.asString()
            : null;
    final String jndiName =
        (resolvedValue =
                    CacheContainerResourceDefinition.JNDI_NAME.resolveModelAttribute(
                        context, containerModel))
                .isDefined()
            ? resolvedValue.asString()
            : null;
    final String listenerExecutor =
        (resolvedValue =
                    CacheContainerResourceDefinition.LISTENER_EXECUTOR.resolveModelAttribute(
                        context, containerModel))
                .isDefined()
            ? resolvedValue.asString()
            : null;
    final String evictionExecutor =
        (resolvedValue =
                    CacheContainerResourceDefinition.EVICTION_EXECUTOR.resolveModelAttribute(
                        context, containerModel))
                .isDefined()
            ? resolvedValue.asString()
            : null;
    final String replicationQueueExecutor =
        (resolvedValue =
                    CacheContainerResourceDefinition.REPLICATION_QUEUE_EXECUTOR
                        .resolveModelAttribute(context, containerModel))
                .isDefined()
            ? resolvedValue.asString()
            : null;
    final ServiceController.Mode initialMode =
        StartMode.valueOf(
                CacheContainerResourceDefinition.START
                    .resolveModelAttribute(context, containerModel)
                    .asString())
            .getMode();
    final boolean statistics =
        CacheContainerResourceDefinition.STATISTICS_ENABLED
            .resolveModelAttribute(context, containerModel)
            .asBoolean();

    ServiceName[] aliases = null;
    if (containerModel.hasDefined(ModelKeys.ALIASES)) {
      List<ModelNode> list = operation.get(ModelKeys.ALIASES).asList();
      aliases = new ServiceName[list.size()];
      for (int i = 0; i < list.size(); i++) {
        aliases[i] = EmbeddedCacheManagerService.getServiceName(list.get(i).asString());
      }
    }

    final ModuleIdentifier moduleId =
        (resolvedValue =
                    CacheContainerResourceDefinition.MODULE.resolveModelAttribute(
                        context, containerModel))
                .isDefined()
            ? ModuleIdentifier.fromString(resolvedValue.asString())
            : null;

    // if we have a transport defined, pick up the transport-related attributes and install a
    // channel
    final Transport transportConfig =
        containerModel.hasDefined(ModelKeys.TRANSPORT)
                && containerModel.get(ModelKeys.TRANSPORT).hasDefined(ModelKeys.TRANSPORT_NAME)
            ? new Transport()
            : null;

    String stack = null;
    String transportExecutor = null;

    Collection<ServiceController<?>> controllers = new LinkedList<>();

    if (transportConfig != null) {
      ModelNode transport = containerModel.get(ModelKeys.TRANSPORT, ModelKeys.TRANSPORT_NAME);

      stack =
          (resolvedValue =
                      TransportResourceDefinition.STACK.resolveModelAttribute(context, transport))
                  .isDefined()
              ? resolvedValue.asString()
              : null;
      // if cluster is not defined, use the cache container name as the default
      final String cluster =
          (resolvedValue =
                      TransportResourceDefinition.CLUSTER.resolveModelAttribute(context, transport))
                  .isDefined()
              ? resolvedValue.asString()
              : name;
      long lockTimeout =
          TransportResourceDefinition.LOCK_TIMEOUT
              .resolveModelAttribute(context, transport)
              .asLong();
      transportExecutor =
          (resolvedValue =
                      TransportResourceDefinition.EXECUTOR.resolveModelAttribute(
                          context, transport))
                  .isDefined()
              ? resolvedValue.asString()
              : null;

      // initialise the Transport
      transportConfig.setClusterName(cluster);
      transportConfig.setLockTimeout(lockTimeout);

      controllers.addAll(
          this.installChannelServices(target, name, cluster, stack, verificationHandler));

      // register the protocol metrics by adding a step
      ChannelInstanceResourceDefinition.addChannelProtocolMetricsRegistrationStep(
          context, cluster, stack);

      for (ChannelServiceProvider provider :
          ServiceLoader.load(
              ChannelServiceProvider.class, ChannelServiceProvider.class.getClassLoader())) {
        log.debugf("Installing %s for channel %s", provider.getClass().getSimpleName(), cluster);
        controllers.addAll(provider.install(target, name, moduleId));
      }
    }

    // install the cache container configuration service
    controllers.add(
        this.installContainerConfigurationService(
            target,
            name,
            defaultCache,
            statistics,
            moduleId,
            stack,
            transportConfig,
            transportExecutor,
            listenerExecutor,
            evictionExecutor,
            replicationQueueExecutor,
            verificationHandler));

    // install a cache container service
    controllers.add(
        this.installContainerService(
            target, name, aliases, transportConfig, initialMode, verificationHandler));

    // install a name service entry for the cache container
    controllers.add(this.installJndiService(target, name, jndiName, verificationHandler));

    controllers.add(
        this.installKeyAffinityServiceFactoryService(target, name, verificationHandler));

    controllers.add(
        this.installGlobalComponentRegistryService(
            target, name, transportConfig, verificationHandler));

    log.debugf("%s cache container installed", name);
    return controllers;
  }