@SuppressWarnings("unchecked")
    public synchronized void launch(NMCommunicatorLaunchRequestEvent event) {
      LOG.info("Launching Container with Id: " + event.getContainerId());
      if (this.state == ContainerState.KILLED_BEFORE_LAUNCH) {
        state = ContainerState.DONE;
        sendContainerLaunchFailedMsg(
            event.getContainerId(), "Container was killed before it was launched");
        return;
      }

      ContainerManagementProtocolProxyData proxy = null;
      try {

        proxy = getCMProxy(containerID, containerMgrAddress, containerToken);

        // Construct the actual Container
        ContainerLaunchContext containerLaunchContext = event.getContainerLaunchContext();

        // Now launch the actual container
        StartContainerRequest startRequest = Records.newRecord(StartContainerRequest.class);
        startRequest.setContainerToken(event.getContainerToken());
        startRequest.setContainerLaunchContext(containerLaunchContext);

        StartContainersResponse response =
            proxy
                .getContainerManagementProtocol()
                .startContainers(
                    StartContainersRequest.newInstance(Collections.singletonList(startRequest)));
        if (response.getFailedRequests() != null && !response.getFailedRequests().isEmpty()) {
          throw response.getFailedRequests().get(containerID).deSerialize();
        }

        // after launching, send launched event to task attempt to move
        // it from ASSIGNED to RUNNING state
        context.getEventHandler().handle(new AMContainerEventLaunched(containerID));
        ContainerLaunchedEvent lEvt =
            new ContainerLaunchedEvent(
                containerID, clock.getTime(), context.getApplicationAttemptId());
        context.getHistoryHandler().handle(new DAGHistoryEvent(null, lEvt));

        this.state = ContainerState.RUNNING;
      } catch (Throwable t) {
        String message =
            "Container launch failed for " + containerID + " : " + ExceptionUtils.getStackTrace(t);
        this.state = ContainerState.FAILED;
        sendContainerLaunchFailedMsg(containerID, message);
      } finally {
        if (proxy != null) {
          cmProxy.mayBeCloseProxy(proxy);
        }
      }
    }