@Override
  @NotNull
  public TaskResult execute(@NotNull CommonTaskContext commonTaskContext) throws TaskException {

    final TaskResultBuilder taskResultBuilder = TaskResultBuilder.newBuilder(commonTaskContext);
    final TaskContext taskContext = Narrow.to(commonTaskContext, TaskContext.class);
    final BuildLogger buildLogger = taskContext.getBuildLogger();

    // move this crazy resolution out of here.
    resolveContext(taskContext, commonTaskContext);

    final String rubyRuntimeLabel =
        RubyBuildConfigurationPlugin.getRubyRuntime(getBuildDefinition());

    try {

      if (rubyRuntimeLabel == null) {
        throw new RuntimeLocatorException(
            "A ruby runtime has not been chosen for this plan.  Please see the miscellaneous tab to choose a plan-wide ruby runtime.");
      }

      final RubyLabel rubyLabel = RubyLabel.fromString(rubyRuntimeLabel);

      final ConfigurationMap config = commonTaskContext.getConfigurationMap();
      Map<String, String> envVars = buildEnvironment(rubyLabel, config);

      List<String> commandsList = buildCommandList(rubyLabel, config);

      ExternalProcess externalProcess =
          getProcessService()
              .createExternalProcess(
                  commonTaskContext,
                  new ExternalProcessBuilder()
                      .env(envVars)
                      .command(commandsList)
                      .workingDirectory(commonTaskContext.getWorkingDirectory()));

      externalProcess.execute();

      taskResultBuilder.checkReturnCode(externalProcess, 0);
    } catch (IllegalArgumentException e) {
      buildLogger.addErrorLogEntry("Could not run ruby task: " + e.getMessage(), e);
      taskResultBuilder.failed();
    } catch (PathNotFoundException e) {
      buildLogger.addErrorLogEntry("Could not run ruby task: " + e.getMessage(), e);
      taskResultBuilder.failed();
    } catch (RuntimeLocatorException e) {
      buildLogger.addErrorLogEntry("Could not run ruby task: " + e.getMessage(), e);
      taskResultBuilder.failed();
    }

    return taskResultBuilder.build();
  }
  private void resolveContext(TaskContext taskContext, CommonTaskContext commonTaskContext) {

    // This is a hack to ultimately resolve the BuildDefinition.  Unfortunately this is not well
    // encapsulated and the lack of
    //      information provided to the deploy task makes it difficult to navigate back to.
    if (taskContext != null) {
      // taskContext is null for deploy tasks
      setBuildContext(taskContext.getBuildContext().getParentBuildContext());
      setBuildDefinition(getBuildContext().getBuildDefinition());
    } else {

      // this is a deploy task
      final DeploymentTaskContext deploymentTaskContext =
          Narrow.to(commonTaskContext, DeploymentTaskContext.class);
      long environmentId = deploymentTaskContext.getDeploymentContext().getEnvironmentId();

      DeploymentProject deploymentProject =
          getDeploymentProjectService().getDeploymentProjectForEnvironment(environmentId);
      Plan plan = getPlanManager().getPlanByKey(deploymentProject.getPlanKey());
      setBuildDefinition(plan.getBuildDefinition());
    }
  }