// TODO: Break up this method and clean up URL handling.
  public void doJob(StaplerRequest request, StaplerResponse response)
      throws IOException, URISyntaxException, ServletException {
    requireGET();

    MediaType type = AcceptUtil.matchMediaType(request, ACCEPTABLE);
    if (type == null) {
      throw HttpResponses.status(HttpServletResponse.SC_NOT_ACCEPTABLE);
    }

    String restOfPath = request.getRestOfPath();
    if (restOfPath == null) {
      throw HttpResponses.notFound();
    }

    // Remove leading '/'
    restOfPath = restOfPath.substring(1);
    String segments[] = restOfPath.split("/");

    // URI patterns:
    //   <job-name>
    //   <job-name>/preview
    //   <job-name>/run/<run-number>
    //   <job-name>/run/<run-number>/preview
    //   <job-name>/run/<run-number>/request

    // Find the job.
    String jobName = segments[0];
    Job<?, ?> job = getJob(jobName);
    if (job == null) {
      throw HttpResponses.notFound();
    }

    // Is it a run?
    //   <job-name>/run/<run-number>
    if (segments.length >= 3 && PATH_RUN.equals(segments[1])) {
      String runNumber = segments[2];
      int i;
      try {
        i = Integer.valueOf(Integer.parseInt(runNumber));
      } catch (NumberFormatException e) {
        throw HttpResponses.notFound();
      }

      Run<?, ?> run = job.getBuildByNumber(i);
      if (run == null) {
        throw HttpResponses.notFound();
      }

      if (segments.length == 4) {
        // Is it a run preview?
        //   <job-name>/run/<run-number>/preview
        if (PATH_PREVIEW.equals(segments[3])) {
          /*
           * See /hudson-oslc-auto/src/main/resources/hudson/model/Run/preview.jelly
           */
          response.forward(run, "preview", request);
          return;
        }

        // Is it an AutomationRequest?
        //   <job-name>/run/<run-number>/request
        if (PATH_REQUEST.equals(segments[3])) {
          AutomationRequest autoRequest = toAutomationRequest(request, job, run);
          marshal(autoRequest);
        }

        if ("buildStatus".equals(segments[3])) {
          throw HttpResponses.redirectViaContextPath(run.getUrl() + "/buildStatus");
        }
      } else if (segments.length == 3) { // <job-name>/run/<run-number>
        if (MediaType.TEXT_HTML_TYPE.isCompatible(type)) {
          throw HttpResponses.redirectViaContextPath(run.getUrl());
        }

        if (MarshallerConstants.MT_OSLC_COMPACT.isCompatible(type)) {
          handleCompact(job, run);
        } else {
          AutomationResult result = toAutomationResult(request, job, run);
          marshal(result);
        }
      } else {
        throw HttpResponses.notFound();
      }
    } else {
      // Is it a job preview?
      //   <job-name>/preview
      if (segments.length == 2 && PATH_PREVIEW.equals(segments[1])) {
        /*
         * See /hudson-oslc-auto/src/main/resources/hudson/model/Job/preview.jelly
         */
        response.forward(job, "preview", request);
        return;
      }

      if (segments.length != 1) {
        throw HttpResponses.notFound();
      }

      // Is it just a job name with no other segments?
      //   <job-name>
      if (MediaType.TEXT_HTML_TYPE.isCompatible(type)) {
        throw HttpResponses.redirectViaContextPath(job.getUrl());
      }

      if (MarshallerConstants.MT_OSLC_COMPACT.isCompatible(type)) {
        handleCompact(job);
      } else {
        AutomationPlan plan = toAutomationPlan(job);
        marshal(plan);
      }
    }
  }