/** Lookups a Stack */
  protected void ensureStackLookup() {
    if (isNotEmpty(stackId)) return;

    getLog().info("Looking up stackId (stack name: " + stackName + ")");

    final Pattern namePattern;

    if (GlobUtil.hasWildcards(stackName)) {
      namePattern = GlobUtil.globify(stackName);
    } else {
      namePattern = Pattern.compile(Pattern.quote(stackName));
    }

    String nextToken = null;
    final ListStacksRequest req =
        new ListStacksRequest()
            .withStackStatusFilters(
                StackStatus.CREATE_COMPLETE,
                StackStatus.CREATE_FAILED,
                StackStatus.UPDATE_COMPLETE);

    do {
      req.setNextToken(nextToken);

      final ListStacksResult result = getService().listStacks(req);

      final Optional<StackSummary> matchedStackSummary =
          result
              .getStackSummaries()
              .stream()
              .filter(x -> namePattern.matcher(x.getStackName()).matches())
              .findFirst();

      if (matchedStackSummary.isPresent()) {
        getLog().info("Found stack (stackSummary: " + matchedStackSummary.get());

        this.stackId = matchedStackSummary.get().getStackId();
        this.stackSummary = matchedStackSummary.get();

        return;
      }

      nextToken = result.getNextToken();
    } while (null != nextToken);

    throw new IllegalStateException("Stack '" + stackName + "' not found!");
  }