static ExecutorService createDefaultExecutor() {
   final ThreadGroup group = new ThreadGroup("domain-mgmt-client-thread");
   final ThreadFactory threadFactory =
       new JBossThreadFactory(
           group,
           Boolean.FALSE,
           null,
           "%G " + executorCount.incrementAndGet() + "-%t",
           null,
           null,
           doPrivileged(GetAccessControlContextAction.getInstance()));
   return new ThreadPoolExecutor(
       4, 4, 30L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(256), threadFactory);
 }
  static final class HostControllerExecutorService implements Service<ExecutorService> {
    final ThreadFactory threadFactory =
        new JBossThreadFactory(
            new ThreadGroup("Host Controller Service Threads"),
            Boolean.FALSE,
            null,
            "%G - %t",
            null,
            null,
            doPrivileged(GetAccessControlContextAction.getInstance()));
    private ExecutorService executorService;

    @Override
    public synchronized void start(final StartContext context) throws StartException {
      executorService =
          new ThreadPoolExecutor(
              0,
              Integer.MAX_VALUE,
              5L,
              TimeUnit.SECONDS,
              new SynchronousQueue<Runnable>(),
              threadFactory);
    }

    @Override
    public synchronized void stop(final StopContext context) {
      Thread executorShutdown =
          new Thread(
              new Runnable() {
                @Override
                public void run() {
                  try {
                    executorService.shutdown();
                  } finally {
                    executorService = null;
                    context.complete();
                  }
                }
              },
              "HostController ExecutorService Shutdown Thread");
      executorShutdown.start();
      context.asynchronous();
    }

    @Override
    public synchronized ExecutorService getValue() throws IllegalStateException {
      return executorService;
    }
  }
/**
 * Installs {@link MasterDomainControllerOperationHandlerImpl} which handles requests from slave DC
 * to master DC.
 *
 * @author <a href="*****@*****.**">Kabir Khan</a>
 */
public class MasterDomainControllerOperationHandlerService
    extends AbstractModelControllerOperationHandlerFactoryService {

  public static final ServiceName SERVICE_NAME =
      DomainController.SERVICE_NAME.append(
          ModelControllerClientOperationHandlerFactoryService.OPERATION_HANDLER_NAME_SUFFIX);

  private final DomainController domainController;
  private final HostControllerRegistrationHandler.OperationExecutor operationExecutor;
  private final TransactionalOperationExecutor txOperationExecutor;
  private final ManagementPongRequestHandler pongRequestHandler =
      new ManagementPongRequestHandler();
  private final ThreadFactory threadFactory =
      new JBossThreadFactory(
          new ThreadGroup("slave-request-threads"),
          Boolean.FALSE,
          null,
          "%G - %t",
          null,
          null,
          doPrivileged(GetAccessControlContextAction.getInstance()));
  private final DomainControllerRuntimeIgnoreTransformationRegistry
      runtimeIgnoreTransformationRegistry;

  public MasterDomainControllerOperationHandlerService(
      final DomainController domainController,
      final HostControllerRegistrationHandler.OperationExecutor operationExecutor,
      TransactionalOperationExecutor txOperationExecutor,
      DomainControllerRuntimeIgnoreTransformationRegistry runtimeIgnoreTransformationRegistry) {
    this.domainController = domainController;
    this.operationExecutor = operationExecutor;
    this.txOperationExecutor = txOperationExecutor;
    this.runtimeIgnoreTransformationRegistry = runtimeIgnoreTransformationRegistry;
  }

  @Override
  public synchronized void start(StartContext context) throws StartException {
    pongRequestHandler.resetConnectionId();
    super.start(context);
  }

  @Override
  public ManagementChannelHandler startReceiving(final Channel channel) {
    final ManagementChannelHandler handler =
        new ManagementChannelHandler(
            ManagementClientChannelStrategy.create(channel), getExecutor());
    // Assemble the request handlers for the domain channel
    handler.addHandlerFactory(
        new HostControllerRegistrationHandler(
            handler,
            domainController,
            operationExecutor,
            getExecutor(),
            runtimeIgnoreTransformationRegistry));
    handler.addHandlerFactory(new ModelControllerClientOperationHandler(getController(), handler));
    handler.addHandlerFactory(
        new MasterDomainControllerOperationHandlerImpl(domainController, getExecutor()));
    handler.addHandlerFactory(pongRequestHandler);
    handler.addHandlerFactory(
        new DomainTransactionalProtocolOperationHandler(txOperationExecutor, handler));
    channel.receiveMessage(handler.getReceiver());
    return handler;
  }

  private class DomainTransactionalProtocolOperationHandler
      extends TransactionalProtocolOperationHandler {
    private final TransactionalOperationExecutor executor;

    private volatile SlaveRequest activeSlaveRequest;

    public DomainTransactionalProtocolOperationHandler(
        TransactionalOperationExecutor executor, ManagementChannelAssociation channelAssociation) {
      super(null, channelAssociation);
      this.executor = executor;
    }

    @Override
    protected ModelNode internalExecute(
        final ModelNode operation,
        final ManagementRequestContext<?> context,
        final OperationMessageHandler messageHandler,
        final ProxyOperationControl control,
        OperationAttachments attachments) {

      final OperationStepHandler handler;
      final String operationName = operation.require(OP).asString();
      if (operationName.equals(PullDownDataForServerConfigOnSlaveHandler.OPERATION_NAME)) {
        handler =
            new PullDownDataForServerConfigOnSlaveHandler(
                SlaveChannelAttachments.getHostName(context.getChannel()),
                SlaveChannelAttachments.getTransformers(context.getChannel()),
                runtimeIgnoreTransformationRegistry);
      } else {
        throw HostControllerLogger.ROOT_LOGGER.cannotExecuteTransactionalOperationFromSlave(
            operationName);
      }

      Integer domainControllerLockId;
      if (operation
          .get(OPERATION_HEADERS)
          .hasDefined(DomainControllerLockIdUtils.DOMAIN_CONTROLLER_LOCK_ID)) {
        domainControllerLockId =
            operation
                .get(OPERATION_HEADERS, DomainControllerLockIdUtils.DOMAIN_CONTROLLER_LOCK_ID)
                .asInt();
      } else {
        domainControllerLockId = null;
      }

      final Integer slaveLockId =
          operation
              .get(OPERATION_HEADERS, DomainControllerLockIdUtils.SLAVE_CONTROLLER_LOCK_ID)
              .asInt();
      if (domainControllerLockId == null) {
        synchronized (this) {
          SlaveRequest slaveRequest = this.activeSlaveRequest;
          if (slaveRequest != null) {
            domainControllerLockId = slaveRequest.domainId;
            slaveRequest.refCount.incrementAndGet();
          }
        }
        // TODO https://issues.jboss.org/browse/AS7-6809 If there are many slaves calling back many
        // of these threads will be blocked, and I
        // believe they are a finite resource
      }

      try {
        if (domainControllerLockId != null) {
          return executor.joinActiveOperation(
              operation, messageHandler, control, attachments, handler, domainControllerLockId);
        } else {
          ModelNode result =
              executor.executeAndAttemptLock(
                  operation,
                  messageHandler,
                  control,
                  attachments,
                  new OperationStepHandler() {
                    @Override
                    public void execute(OperationContext context, ModelNode operation)
                        throws OperationFailedException {
                      // Grab the lock id and store it
                      Integer domainControllerLockId =
                          CurrentOperationIdHolder.getCurrentOperationID();
                      synchronized (this) {
                        activeSlaveRequest = new SlaveRequest(domainControllerLockId);
                      }
                      context.addStep(operation, handler, OperationContext.Stage.MODEL);
                      context.stepCompleted();
                    }
                  });
          return result;
        }
      } finally {
        synchronized (this) {
          SlaveRequest slaveRequest = this.activeSlaveRequest;
          if (slaveRequest != null) {
            int refcount = slaveRequest.refCount.decrementAndGet();
            if (refcount == 0) {
              activeSlaveRequest = null;
            }
          }
        }
      }
    }
  }

  public interface TransactionalOperationExecutor {
    ModelNode executeAndAttemptLock(
        ModelNode operation,
        OperationMessageHandler handler,
        ModelController.OperationTransactionControl control,
        OperationAttachments attachments,
        OperationStepHandler step);

    ModelNode joinActiveOperation(
        ModelNode operation,
        OperationMessageHandler handler,
        ModelController.OperationTransactionControl control,
        OperationAttachments attachments,
        OperationStepHandler step,
        int permit);
  }

  private final class SlaveRequest {
    private final int domainId;
    private final AtomicInteger refCount = new AtomicInteger(1);

    SlaveRequest(int domainId) {
      this.domainId = domainId;
    }
  }
}