public MachineLocation call() throws Exception {
      // Blocks if a latch was configured.
      entity().getConfig(BrooklynConfigKeys.PROVISION_LATCH);
      final Map<String, Object> flags = obtainProvisioningFlags(location);
      if (!(location instanceof LocalhostMachineProvisioningLocation))
        log.info(
            "Starting {}, obtaining a new location instance in {} with ports {}",
            new Object[] {entity(), location, flags.get("inboundPorts")});
      entity().sensors().set(SoftwareProcess.PROVISIONING_LOCATION, location);
      Transition expectedState = entity().sensors().get(Attributes.SERVICE_STATE_EXPECTED);

      // BROOKLYN-263: see corresponding code in doStop()
      if (expectedState != null
          && (expectedState.getState() == Lifecycle.STOPPING
              || expectedState.getState() == Lifecycle.STOPPED)) {
        throw new IllegalStateException(
            "Provisioning aborted before even begun for "
                + entity()
                + " in "
                + location
                + " (presumably by a concurrent call to stop");
      }
      entity()
          .sensors()
          .set(AttributesInternal.INTERNAL_PROVISIONING_TASK_STATE, ProvisioningTaskState.RUNNING);

      MachineLocation machine;
      try {
        machine =
            Tasks.withBlockingDetails(
                "Provisioning machine in " + location, new ObtainLocationTask(location, flags));
        entity().sensors().set(INTERNAL_PROVISIONED_MACHINE, machine);
      } finally {
        entity().sensors().remove(AttributesInternal.INTERNAL_PROVISIONING_TASK_STATE);
      }

      if (machine == null) {
        throw new NoMachinesAvailableException(
            "Failed to obtain machine in " + location.toString());
      }
      if (log.isDebugEnabled()) {
        log.debug(
            "While starting {}, obtained new location instance {}",
            entity(),
            (machine instanceof SshMachineLocation
                ? machine
                    + ", details "
                    + ((SshMachineLocation) machine).getUser()
                    + ":"
                    + Sanitizer.sanitize(((SshMachineLocation) machine).config().getLocalBag())
                : machine));
      }
      return machine;
    }
 protected String getDeprecatedProperty(ConfigBag conf, String key) {
   if (conf.containsKey(key)) {
     LOG.warn(
         "Jclouds using deprecated brooklyn-jclouds property "
             + key
             + ": "
             + Sanitizer.sanitize(conf.getAllConfig()));
     return (String) conf.getStringKey(key);
   } else {
     return null;
   }
 }
  @Override
  public ComputeService findComputeService(ConfigBag conf, boolean allowReuse) {
    String provider = checkNotNull(conf.get(CLOUD_PROVIDER), "provider must not be null");
    String identity =
        checkNotNull(conf.get(CloudLocationConfig.ACCESS_IDENTITY), "identity must not be null");
    String credential =
        checkNotNull(
            conf.get(CloudLocationConfig.ACCESS_CREDENTIAL), "credential must not be null");

    Properties properties = new Properties();
    properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, Boolean.toString(true));
    properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, Boolean.toString(true));
    properties.setProperty(
        "jclouds.ssh.max-retries",
        conf.getStringKey("jclouds.ssh.max-retries") != null
            ? conf.getStringKey("jclouds.ssh.max-retries").toString()
            : "50");
    // Enable aws-ec2 lazy image fetching, if given a specific imageId; otherwise customize for
    // specific owners; or all as a last resort
    // See https://issues.apache.org/jira/browse/WHIRR-416
    if ("aws-ec2".equals(provider)) {
      // TODO convert AWS-only flags to config keys
      if (groovyTruth(conf.get(IMAGE_ID))) {
        properties.setProperty(PROPERTY_EC2_AMI_QUERY, "");
        properties.setProperty(PROPERTY_EC2_CC_AMI_QUERY, "");
      } else if (groovyTruth(conf.getStringKey("imageOwner"))) {
        properties.setProperty(
            PROPERTY_EC2_AMI_QUERY,
            "owner-id=" + conf.getStringKey("imageOwner") + ";state=available;image-type=machine");
      } else if (groovyTruth(conf.getStringKey("anyOwner"))) {
        // set `anyOwner: true` to override the default query (which is restricted to certain owners
        // as per below),
        // allowing the AMI query to bind to any machine
        // (note however, we sometimes pick defaults in JcloudsLocationFactory);
        // (and be careful, this can give a LOT of data back, taking several minutes,
        // and requiring extra memory allocated on the command-line)
        properties.setProperty(PROPERTY_EC2_AMI_QUERY, "state=available;image-type=machine");
        /*
         * by default the following filters are applied:
         * Filter.1.Name=owner-id&Filter.1.Value.1=137112412989&
         * Filter.1.Value.2=063491364108&
         * Filter.1.Value.3=099720109477&
         * Filter.1.Value.4=411009282317&
         * Filter.2.Name=state&Filter.2.Value.1=available&
         * Filter.3.Name=image-type&Filter.3.Value.1=machine&
         */
      }

      // occasionally can get com.google.common.util.concurrent.UncheckedExecutionException:
      // java.lang.RuntimeException:
      //     security group eu-central-1/jclouds#brooklyn-bxza-alex-eu-central-shoul-u2jy-nginx-ielm
      // is not available after creating
      // the default timeout was 500ms so let's raise it in case that helps
      properties.setProperty(
          EC2Constants.PROPERTY_EC2_TIMEOUT_SECURITYGROUP_PRESENT,
          "" + Duration.seconds(30).toMilliseconds());
    }

    // FIXME Deprecated mechanism, should have a ConfigKey for overrides
    Map<String, Object> extra =
        Maps.filterKeys(conf.getAllConfig(), Predicates.containsPattern("^jclouds\\."));
    if (extra.size() > 0) {
      LOG.warn("Jclouds using deprecated property overrides: " + Sanitizer.sanitize(extra));
    }
    properties.putAll(extra);

    String endpoint = conf.get(CloudLocationConfig.CLOUD_ENDPOINT);
    if (!groovyTruth(endpoint)) endpoint = getDeprecatedProperty(conf, Constants.PROPERTY_ENDPOINT);
    if (groovyTruth(endpoint)) properties.setProperty(Constants.PROPERTY_ENDPOINT, endpoint);

    Map<?, ?> cacheKey =
        MutableMap.builder()
            .putAll(properties)
            .put("provider", provider)
            .put("identity", identity)
            .put("credential", credential)
            .putIfNotNull("endpoint", endpoint)
            .build()
            .asUnmodifiable();

    if (allowReuse) {
      ComputeService result = cachedComputeServices.get(cacheKey);
      if (result != null) {
        LOG.trace(
            "jclouds ComputeService cache hit for compute service, for "
                + Sanitizer.sanitize(properties));
        return result;
      }
      LOG.debug(
          "jclouds ComputeService cache miss for compute service, creating, for "
              + Sanitizer.sanitize(properties));
    }

    Iterable<Module> modules = getCommonModules();

    // Synchronizing to avoid deadlock from sun.reflect.annotation.AnnotationType.
    // See https://github.com/brooklyncentral/brooklyn/issues/974
    ComputeServiceContext computeServiceContext;
    synchronized (createComputeServicesMutex) {
      computeServiceContext =
          ContextBuilder.newBuilder(provider)
              .modules(modules)
              .credentials(identity, credential)
              .overrides(properties)
              .build(ComputeServiceContext.class);
    }
    final ComputeService computeService = computeServiceContext.getComputeService();
    if (allowReuse) {
      synchronized (cachedComputeServices) {
        ComputeService result = cachedComputeServices.get(cacheKey);
        if (result != null) {
          LOG.debug(
              "jclouds ComputeService cache recovery for compute service, for "
                  + Sanitizer.sanitize(cacheKey));
          // keep the old one, discard the new one
          computeService.getContext().close();
          return result;
        }
        LOG.debug(
            "jclouds ComputeService created "
                + computeService
                + ", adding to cache, for "
                + Sanitizer.sanitize(properties));
        cachedComputeServices.put(cacheKey, computeService);
      }
    }
    return computeService;
  }
 @Override
 protected ToStringHelper newVerboseStringHelper() {
   return super.newVerboseStringHelper().add("config", Sanitizer.sanitize(getConfig()));
 }