@Override
  public ProxyController serverCommunicationRegistered(
      final String serverProcessName, final ManagementChannelHandler channelAssociation) {
    if (shutdown || connectionFinished) {
      throw HostControllerMessages.MESSAGES.hostAlreadyShutdown();
    }
    final String serverName = ManagedServer.getServerName(serverProcessName);
    final ManagedServer server = servers.get(serverName);
    if (server == null) {
      ROOT_LOGGER.noServerAvailable(serverName);
      return null;
    }
    try {
      final TransactionalProtocolClient client = server.channelRegistered(channelAssociation);
      final Channel channel = channelAssociation.getChannel();
      channel.addCloseHandler(
          new CloseHandler<Channel>() {

            public void handleClose(final Channel closed, final IOException exception) {
              final boolean shuttingDown = shutdown || connectionFinished;
              // Unregister right away
              if (server.callbackUnregistered(client, shuttingDown)) {
                domainController.unregisterRunningServer(server.getServerName());
              }
            }
          });
      return server.getProxyController();
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
 @Override
 public void reconnectServer(
     final String serverName,
     final ModelNode domainModel,
     final byte[] authKey,
     final boolean running,
     final boolean stopping) {
   if (shutdown || connectionFinished) {
     throw HostControllerMessages.MESSAGES.hostAlreadyShutdown();
   }
   ManagedServer existing = servers.get(serverName);
   if (existing != null) {
     ROOT_LOGGER.existingServerWithState(serverName, existing.getState());
     return;
   }
   final ManagedServer server = createManagedServer(serverName, authKey);
   if ((existing = servers.putIfAbsent(serverName, server)) != null) {
     ROOT_LOGGER.existingServerWithState(serverName, existing.getState());
     return;
   }
   if (running) {
     if (!stopping) {
       server.reconnectServerProcess(createBootFactory(serverName, domainModel));
       // Register the server proxy at the domain controller
       domainController.registerRunningServer(server.getProxyController());
     } else {
       server.setServerProcessStopping();
     }
   } else {
     server.removeServerProcess();
   }
   synchronized (shutdownCondition) {
     shutdownCondition.notifyAll();
   }
 }
 @Override
 public ServerStatus restartServer(
     final String serverName,
     final int gracefulTimeout,
     final ModelNode domainModel,
     final boolean blocking) {
   stopServer(serverName, gracefulTimeout);
   synchronized (shutdownCondition) {
     for (; ; ) {
       if (shutdown || connectionFinished) {
         throw HostControllerMessages.MESSAGES.hostAlreadyShutdown();
       }
       if (!servers.containsKey(serverName)) {
         break;
       }
       try {
         shutdownCondition.wait();
       } catch (InterruptedException e) {
         Thread.currentThread().interrupt();
         break;
       }
     }
   }
   startServer(serverName, domainModel, blocking);
   return determineServerStatus(serverName);
 }
 @Override
 public ServerStatus startServer(
     final String serverName, final ModelNode domainModel, final boolean blocking) {
   if (shutdown || connectionFinished) {
     throw HostControllerMessages.MESSAGES.hostAlreadyShutdown();
   }
   ManagedServer server = servers.get(serverName);
   if (server == null) {
     // Create a new authKey
     final byte[] authKey = new byte[16];
     new Random(new SecureRandom().nextLong()).nextBytes(authKey);
     removeNullChar(authKey);
     // Create the managed server
     final ManagedServer newServer = createManagedServer(serverName, authKey);
     server = servers.putIfAbsent(serverName, newServer);
     if (server == null) {
       server = newServer;
     }
   }
   // Start the server
   server.start(createBootFactory(serverName, domainModel));
   synchronized (shutdownCondition) {
     shutdownCondition.notifyAll();
   }
   if (blocking) {
     // Block until the server started message
     server.awaitState(ManagedServer.InternalState.SERVER_STARTED);
   } else {
     // Wait until the server opens the mgmt connection
     server.awaitState(ManagedServer.InternalState.SERVER_STARTING);
   }
   return server.getState();
 }
 @Override
 protected void validateReferencedNewValueExisits(OperationContext context, ModelNode value)
     throws OperationFailedException {
   final Resource root = context.readResourceFromRoot(PathAddress.EMPTY_ADDRESS, false);
   // Don't do this on boot since the domain model is not populated yet
   if (!context.isBooting()
       && root.getChild(PathElement.pathElement(SERVER_GROUP, value.asString())) == null) {
     throw HostControllerMessages.MESSAGES.noServerGroupCalled(value.asString());
   }
 }
 @Override
 public ServerStatus reloadServer(final String serverName, final boolean blocking) {
   if (shutdown || connectionFinished) {
     throw HostControllerMessages.MESSAGES.hostAlreadyShutdown();
   }
   final ManagedServer server = servers.get(serverName);
   if (server == null) {
     return ServerStatus.STOPPED;
   }
   if (server.reload(CurrentOperationIdHolder.getCurrentOperationID())) {
     // Reload with current permit
     if (blocking) {
       server.awaitState(ManagedServer.InternalState.SERVER_STARTED);
     } else {
       server.awaitState(ManagedServer.InternalState.SERVER_STARTING);
     }
   }
   return determineServerStatus(serverName);
 }