@Override
  public Boolean call() {
    LOGGER.info(
        "Checking if AWS CloudFormation stack '{}' reached status '{}'",
        cloudFormationStackName,
        successStatus);

    try {
      com.amazonaws.services.cloudformation.model.Stack cfStack =
          cfClient.describeStacks(describeStacksRequest).getStacks().get(0);
      List<StackEvent> stackEvents =
          cfClient.describeStackEvents(stackEventsRequest).getStackEvents();
      return doCheck(cfStack, stackEvents);
    } catch (AmazonServiceException e) {
      return handleError(e);
    }
  }
  @Override
  public void execute() throws BuildException {
    checkParams();
    AmazonCloudFormationClient client = getOrCreateClient(AmazonCloudFormationClient.class);
    DescribeStacksRequest describeStacksRequest =
        new DescribeStacksRequest().withStackName(stackName);

    try {
      DescribeStacksResult result = client.describeStacks(describeStacksRequest);
      Stack stack = result.getStacks().get(0);

      // put the desired stack parameters into properties
      if (stack.getParameters() != null) {
        for (Parameter parameter : stack.getParameters()) {
          StackItem item = parameters.remove(parameter.getParameterKey());
          if (item != null) {
            getProject().setNewProperty(item.getProperty(), parameter.getParameterValue());
          }
        }
      }

      for (StackItem item : parameters.values()) {
        getProject().setNewProperty(item.getName(), item.getDefault());
      }

      if (stack.getTags() != null) {
        for (Tag tag : stack.getTags()) {
          StackItem item = tags.remove(tag.getKey());
          if (item != null) {
            getProject().setNewProperty(item.getName(), tag.getValue());
          }
        }
      }

      for (StackItem item : tags.values()) {
        getProject().setNewProperty(item.getProperty(), item.getDefault());
      }
    } catch (Exception e) {
      throw new BuildException("Could not describe stack " + e.getMessage(), e);
    }
  }