protected void beforeSubmit(Map<?, ?> flags, Task<?> task) {
    incompleteTaskCount.incrementAndGet();

    Task<?> currentTask = Tasks.current();
    if (currentTask != null) ((TaskInternal<?>) task).setSubmittedByTask(currentTask);
    ((TaskInternal<?>) task).setSubmitTimeUtc(System.currentTimeMillis());

    if (flags.get("tag") != null)
      ((TaskInternal<?>) task).getMutableTags().add(flags.remove("tag"));
    if (flags.get("tags") != null)
      ((TaskInternal<?>) task).getMutableTags().addAll((Collection<?>) flags.remove("tags"));

    for (Object tag : ((TaskInternal<?>) task).getTags()) {
      getMutableTasksWithTag(tag).add(task);
    }
  }
 /** @deprecated in 0.4.0, use Tasks.current() */
 public static Task getCurrentTask() {
   return Tasks.current();
 }
  @Override
  public void install() {
    // will fail later if can't sudo (if sudo is required)
    DynamicTasks.queueIfPossible(SshTasks.dontRequireTtyForSudo(getMachine(), false))
        .orSubmitAndBlock();

    DownloadResolver nginxResolver = mgmt().getEntityDownloadsManager().newDownloader(this);
    List<String> nginxUrls = nginxResolver.getTargets();
    String nginxSaveAs = nginxResolver.getFilename();
    setExpandedInstallDir(
        getInstallDir()
            + "/"
            + nginxResolver.getUnpackedDirectoryName(format("nginx-%s", getVersion())));

    boolean sticky = ((NginxController) entity).isSticky();
    boolean isMac = getMachine().getOsDetails().isMac();

    MutableMap<String, String> installGccPackageFlags =
        MutableMap.of(
            "onlyifmissing", "gcc",
            "yum", "gcc",
            "apt", "gcc",
            "zypper", "gcc",
            "port", null);
    MutableMap<String, String> installMakePackageFlags =
        MutableMap.of(
            "onlyifmissing", "make",
            "yum", "make",
            "apt", "make",
            "zypper", "make",
            "port", null);
    MutableMap<String, String> installPackageFlags =
        MutableMap.of(
            "yum", "openssl-devel pcre-devel",
            "apt", "libssl-dev zlib1g-dev libpcre3-dev",
            "zypper", "libopenssl-devel pcre-devel",
            "port", null);

    String stickyModuleVersion = entity.getConfig(NginxController.STICKY_VERSION);
    DownloadResolver stickyModuleResolver =
        mgmt()
            .getEntityDownloadsManager()
            .newDownloader(
                this, "stickymodule", ImmutableMap.of("addonversion", stickyModuleVersion));
    List<String> stickyModuleUrls = stickyModuleResolver.getTargets();
    String stickyModuleSaveAs = stickyModuleResolver.getFilename();
    String stickyModuleExpandedInstallDir =
        String.format(
            "%s/src/%s",
            getExpandedInstallDir(),
            stickyModuleResolver.getUnpackedDirectoryName(
                "nginx-sticky-module-" + stickyModuleVersion));

    List<String> cmds = Lists.newArrayList();

    cmds.add(BashCommands.INSTALL_TAR);
    cmds.add(
        BashCommands.alternatives(
            BashCommands.ifExecutableElse0(
                "apt-get", BashCommands.installPackage("build-essential")),
            BashCommands.ifExecutableElse0(
                "yum",
                BashCommands.sudo("yum -y --nogpgcheck groupinstall \"Development Tools\""))));
    cmds.add(BashCommands.installPackage(installGccPackageFlags, "nginx-prerequisites-gcc"));
    cmds.add(BashCommands.installPackage(installMakePackageFlags, "nginx-prerequisites-make"));
    cmds.add(BashCommands.installPackage(installPackageFlags, "nginx-prerequisites"));
    cmds.addAll(BashCommands.commandsToDownloadUrlsAs(nginxUrls, nginxSaveAs));

    String pcreExpandedInstallDirname = "";
    if (isMac) {
      String pcreVersion = entity.getConfig(NginxController.PCRE_VERSION);
      DownloadResolver pcreResolver =
          mgmt()
              .getEntityDownloadsManager()
              .newDownloader(this, "pcre", ImmutableMap.of("addonversion", pcreVersion));
      List<String> pcreUrls = pcreResolver.getTargets();
      String pcreSaveAs = pcreResolver.getFilename();
      pcreExpandedInstallDirname = pcreResolver.getUnpackedDirectoryName("pcre-" + pcreVersion);

      // Install PCRE
      cmds.addAll(BashCommands.commandsToDownloadUrlsAs(pcreUrls, pcreSaveAs));
      cmds.add(format("mkdir -p %s/pcre-dist", getInstallDir()));
      cmds.add(format("tar xvzf %s", pcreSaveAs));
      cmds.add(format("cd %s", pcreExpandedInstallDirname));
      cmds.add(format("./configure --prefix=%s/pcre-dist", getInstallDir()));
      cmds.add("make");
      cmds.add("make install");
      cmds.add("cd ..");
    }

    cmds.add(format("tar xvzf %s", nginxSaveAs));
    cmds.add(format("cd %s", getExpandedInstallDir()));

    if (sticky) {
      cmds.add("cd src");
      cmds.addAll(BashCommands.commandsToDownloadUrlsAs(stickyModuleUrls, stickyModuleSaveAs));
      cmds.add(format("tar xvzf %s", stickyModuleSaveAs));
      cmds.add("cd ..");
    }

    // Note that for OS X, not including space after "-L" because broken in 10.6.8 (but fixed in
    // 10.7.x)
    //      see http://trac.nginx.org/nginx/ticket/227
    String withLdOpt = entity.getConfig(NginxController.WITH_LD_OPT);
    if (isMac)
      withLdOpt =
          format("-L%s/pcre-dist/lib", getInstallDir())
              + (Strings.isBlank(withLdOpt) ? "" : " " + withLdOpt);
    String withCcOpt = entity.getConfig(NginxController.WITH_CC_OPT);

    StringBuilder configureCommand =
        new StringBuilder("./configure")
            .append(format(" --prefix=%s/dist", getExpandedInstallDir()))
            .append(" --with-http_ssl_module")
            .append(sticky ? format(" --add-module=%s ", stickyModuleExpandedInstallDir) : "")
            .append(!Strings.isBlank(withLdOpt) ? format(" --with-ld-opt=\"%s\"", withLdOpt) : "")
            .append(!Strings.isBlank(withCcOpt) ? format(" --with-cc-opt=\"%s\"", withCcOpt) : "");
    if (isMac) {
      configureCommand
          .append(" --with-pcre=")
          .append(getInstallDir())
          .append("/")
          .append(pcreExpandedInstallDirname);
    }

    cmds.addAll(ImmutableList.of("mkdir -p dist", configureCommand.toString(), "make install"));

    ScriptHelper script =
        newScript(INSTALLING)
            .body
            .append(cmds)
            .header
            .prepend("set -x")
            .gatherOutput()
            .failOnNonZeroResultCode(false);

    int result = script.execute();

    if (result != 0) {
      String notes =
          "likely an error building nginx. consult the brooklyn log ssh output for further details.\n"
              + "note that this Brooklyn nginx driver compiles nginx from source. "
              + "it attempts to install common prerequisites but this does not always succeed.\n";
      OsDetails os = getMachine().getOsDetails();
      if (os.isMac()) {
        notes +=
            "deploying to Mac OS X, you will require Xcode and Xcode command-line tools, and on "
                + "some versions the pcre library (e.g. using macports, sudo port install pcre).\n";
      }
      if (os.isWindows()) {
        notes +=
            "this nginx driver is not designed for windows, unless cygwin is installed, and you are patient.\n";
      }
      if (getEntity().getApplication().getClass().getCanonicalName().startsWith("brooklyn.demo.")) {
        // this is maybe naughty ... but since we use nginx in the first demo example,
        // and since it's actually pretty complicated, let's give a little extra hand-holding
        notes +=
            "if debugging this is all a bit much and you just want to run a demo, "
                + "you have two fairly friendly options.\n"
                + "1. you can use a well known cloud, like AWS or Rackspace, where this should run "
                + "in a tried-and-tested Ubuntu or CentOS environment, without any problems "
                + "(and if it does let us know and we'll fix it!).\n"
                + "2. or you can just use the demo without nginx, instead access the appserver instances directly.\n";
      }

      if (!script.getResultStderr().isEmpty()) {
        notes += "\n" + "STDERR\n" + script.getResultStderr() + "\n";
        Streams.logStreamTail(
            log,
            "STDERR of problem in " + Tasks.current(),
            Streams.byteArrayOfString(script.getResultStderr()),
            1024);
      }
      if (!script.getResultStdout().isEmpty()) {
        notes += "\n" + "STDOUT\n" + script.getResultStdout() + "\n";
        Streams.logStreamTail(
            log,
            "STDOUT of problem in " + Tasks.current(),
            Streams.byteArrayOfString(script.getResultStdout()),
            1024);
      }

      Tasks.setExtraStatusDetails(notes.trim());

      throw new IllegalStateException(
          "Installation of nginx failed (shell returned non-zero result " + result + ")");
    }
  }