@Override
 public Set<String> getSSHFingerprints(Stack stack, String gateway) {
   Set<String> result = new HashSet<>();
   LOGGER.debug("Get SSH fingerprints of gateway instance for stack: {}", stack);
   CloudContext cloudContext = new CloudContext(stack);
   CloudCredential cloudCredential = credentialConverter.convert(stack.getCredential());
   InstanceMetaData gatewayMetaData =
       stack.getGatewayInstanceGroup().getInstanceMetaData().iterator().next();
   CloudInstance gatewayInstance = metadataConverter.convert(gatewayMetaData);
   GetSSHFingerprintsRequest<GetSSHFingerprintsResult> sSHFingerprintReq =
       new GetSSHFingerprintsRequest<>(cloudContext, cloudCredential, gatewayInstance);
   LOGGER.info("Triggering GetSSHFingerprintsRequest stack event: {}", sSHFingerprintReq);
   eventBus.notify(sSHFingerprintReq.selector(), Event.wrap(sSHFingerprintReq));
   try {
     GetSSHFingerprintsResult res = sSHFingerprintReq.await();
     LOGGER.info("Get SSH fingerprints of gateway instance for stack result: {}", res);
     if (res.getStatus().equals(EventStatus.FAILED)) {
       LOGGER.error("Failed to get SSH fingerprint", res.getErrorDetails());
       throw new OperationException(res.getErrorDetails());
     }
     result.addAll(res.getSshFingerprints());
   } catch (InterruptedException e) {
     LOGGER.error(
         format("Failed to get SSH fingerprints of gateway instance stack: %s", cloudContext), e);
     throw new OperationException(e);
   }
   return result;
 }
 @Override
 public void stopAll(Stack stack) {
   LOGGER.info("Assembling stop request for stack: {}", stack);
   CloudContext cloudContext = new CloudContext(stack);
   CloudCredential cloudCredential = credentialConverter.convert(stack.getCredential());
   List<CloudInstance> instances = metadataConverter.convert(stack.getInstanceMetaDataAsList());
   List<CloudResource> resources = cloudResourceConverter.convert(stack.getResources());
   StopInstancesRequest<StopInstancesResult> stopRequest =
       new StopInstancesRequest<>(cloudContext, cloudCredential, resources, instances);
   LOGGER.info("Triggering event: {}", stopRequest);
   eventBus.notify(stopRequest.selector(), Event.wrap(stopRequest));
   try {
     StopInstancesResult res = stopRequest.await();
     LOGGER.info("Result: {}", res);
     if (res.isFailed()) {
       Exception exception = res.getException();
       LOGGER.error("Failed to stop the stack", exception);
       throw new OperationException(exception);
     } else {
       for (CloudVmInstanceStatus instanceStatus : res.getResults().getResults()) {
         if (instanceStatus.getStatus().equals(InstanceStatus.FAILED)) {
           throw new OperationException(
               "Failed to stop the following instance: " + instanceStatus.getCloudInstance());
         }
       }
     }
   } catch (InterruptedException e) {
     LOGGER.error("Error while stopping the stack", e);
     throw new OperationException(e);
   }
 }
 @Override
 public Set<String> removeInstances(
     Stack stack,
     String gateWayUserData,
     String coreUserData,
     Set<String> instanceIds,
     String instanceGroup) {
   LOGGER.debug("Assembling downscale stack event for stack: {}", stack);
   CloudContext cloudContext = new CloudContext(stack);
   CloudCredential cloudCredential = credentialConverter.convert(stack.getCredential());
   List<CloudResource> resources = cloudResourceConverter.convert(stack.getResources());
   List<CloudInstance> instances = new ArrayList<>();
   InstanceGroup group = stack.getInstanceGroupByInstanceGroupName(instanceGroup);
   for (InstanceMetaData metaData : group.getAllInstanceMetaData()) {
     if (instanceIds.contains(metaData.getInstanceId())) {
       CloudInstance cloudInstance = metadataConverter.convert(metaData);
       instances.add(cloudInstance);
     }
   }
   CloudStack cloudStack =
       cloudStackConverter.convert(stack, coreUserData, gateWayUserData, instanceIds);
   DownscaleStackRequest<DownscaleStackResult> downscaleRequest =
       new DownscaleStackRequest<>(
           cloudContext, cloudCredential, cloudStack, resources, instances);
   LOGGER.info("Triggering downscale stack event: {}", downscaleRequest);
   eventBus.notify(downscaleRequest.selector(), Event.wrap(downscaleRequest));
   try {
     DownscaleStackResult res = downscaleRequest.await();
     LOGGER.info("Downscale stack result: {}", res);
     if (res.getStatus().equals(EventStatus.FAILED)) {
       LOGGER.error("Failed to downscale the stack", res.getErrorDetails());
       throw new OperationException(res.getErrorDetails());
     }
     return instanceIds;
   } catch (InterruptedException e) {
     LOGGER.error("Error while downscaling the stack", e);
     throw new OperationException(e);
   }
 }