@Override
  public Server apply(@Nullable String baseResource) {
    if (!jetty.getState().equals(Server.STARTED)
        // TODO code smell = hard coding addresses or ports!!
        && !new InetSocketAddressConnect().apply(new IPSocket("localhost", port))) {
      ResourceHandler resource_handler = new ResourceHandler();
      resource_handler.setDirectoriesListed(true);
      resource_handler.setWelcomeFiles(new String[] {"index.html"});

      resource_handler.setResourceBase(baseResource);
      logger.info("serving " + resource_handler.getBaseResource());

      HandlerList handlers = new HandlerList();
      handlers.setHandlers(new Handler[] {resource_handler, new DefaultHandler()});
      jetty.setHandler(handlers);

      try {
        jetty.start();
      } catch (Exception e) {
        logger.error(e, "Server jetty could not be started at this %s", baseResource);
      }
      return jetty;
    } else {
      logger.debug("Server jetty serving %s already running. Skipping start", baseResource);
      return jetty;
    }
  }
  public Iterable<RunningNode> apply(Iterable<NodePlan> nodePlans) {
    final ImmutableList.Builder<RunningNode> cloudTemplateNodeBuilder =
        ImmutableList.<RunningNode>builder();

    final ImmutableList.Builder<ListenableFuture<NodeMetadata>> plannedInstancesBuilder =
        ImmutableList.<ListenableFuture<NodeMetadata>>builder();

    final AtomicInteger failedLaunches = new AtomicInteger();

    for (final NodePlan nodePlan : nodePlans) {
      for (int i = 0; i < nodePlan.getCount(); i++) {
        final int index = i;
        logger.info(
            "Queuing cloud instance: #%d %d, %s %s",
            index, nodePlan.getCount(), nodePlan.getCloudName(), nodePlan.getTemplateName());

        ListenableFuture<NodeMetadata> provisionTemplate =
            executor.submit(new RetrySupplierOnException(nodePlan.getNodeSupplier(), logger));

        Futures.addCallback(
            provisionTemplate,
            new FutureCallback<NodeMetadata>() {
              public void onSuccess(NodeMetadata result) {
                if (result != null) {
                  cloudTemplateNodeBuilder.add(
                      new RunningNode(
                          nodePlan.getCloudName(),
                          nodePlan.getTemplateName(),
                          nodePlan.getActionOnBuildFinish(),
                          result));
                } else {
                  failedLaunches.incrementAndGet();
                }
              }

              public void onFailure(Throwable t) {
                failedLaunches.incrementAndGet();
                logger.warn(
                    t,
                    "Error while launching instance: #%d %d, %s %s",
                    index,
                    nodePlan.getCount(),
                    nodePlan.getCloudName(),
                    nodePlan.getTemplateName());
              }
            });

        plannedInstancesBuilder.add(provisionTemplate);
      }
    }

    // block until all complete
    List<NodeMetadata> nodesActuallyLaunched =
        Futures.getUnchecked(Futures.successfulAsList(plannedInstancesBuilder.build()));

    final ImmutableList<RunningNode> cloudTemplateNodes = cloudTemplateNodeBuilder.build();

    assert cloudTemplateNodes.size() == nodesActuallyLaunched.size()
        : String.format(
            "expected nodes from callbacks to be the same count as those from the list of futures!%n"
                + "fromCallbacks:%s%nfromFutures%s%n",
            cloudTemplateNodes, nodesActuallyLaunched);

    if (failedLaunches.get() > 0) {
      terminateNodes.apply(cloudTemplateNodes);
      throw new IllegalStateException("One or more instances failed to launch.");
    }
    return cloudTemplateNodes;
  }