/** {@inheritDoc} */
  @Override
  public Response submit(HttpServletRequest request, String tickId)
      throws RepositoryNotFoundException {
    String crsid = (String) request.getSession().getAttribute("RavenRemoteUser");

    /* Get the fork object, returning if not found */
    Tick tick = db.getTick(tickId);
    Fork fork = db.getFork(Fork.generateForkId(crsid, tickId));
    if (fork == null) {
      log.error(
          "User "
              + crsid
              + " requested fork "
              + Fork.generateForkId(crsid, tickId)
              + " to submission, but it couldn't be found");
      return Response.status(Status.NOT_FOUND).entity(Strings.MISSING).build();
    }

    /*
     * Check if the deadline has passed, replace the deadline if an
     * extension exists for this user
     */
    DateTime extension = tick.getExtensions().get(crsid);

    if (extension != null) {
      tick.setDeadline(extension);
    }

    if (tick.getDeadline() != null && tick.getDeadline().isBeforeNow()) {
      return Response.status(Status.NOT_FOUND).entity(Strings.DEADLINE).build();
    }

    /* Parse id for the git service via the test service */
    String repoName = Tick.replaceDelimeter(tickId);

    String forkRepoName = crsid + "/" + repoName;

    /* Call the git service */
    try {
      testServiceProxy.runNewTest(
          config.getConfig().getSecurityToken(), crsid, tickId, forkRepoName);

    } catch (InternalServerErrorException e) {
      RemoteFailureHandler h = new RemoteFailureHandler();
      SerializableException s = h.readException(e);

      if (s.getClassName().equals(IOException.class.getName())) {
        log.error(
            "User "
                + crsid
                + " failed to start new test on "
                + repoName
                + "\nCause: "
                + s.toString());
        return Response.status(Status.INTERNAL_SERVER_ERROR)
            .entity(Strings.IDEMPOTENTRETRY)
            .build();
      }

      if (s.getClassName().equals(TestStillRunningException.class.getName())) {
        log.error(
            "User "
                + crsid
                + " failed to start new test on "
                + repoName
                + "\nCause: "
                + s.toString());
        return Response.status(Status.SERVICE_UNAVAILABLE).entity(Strings.TESTRUNNING).build();
      }

      if (s.getClassName().equals(TestIDNotFoundException.class.getName())) {
        log.error(
            "User "
                + crsid
                + " failed to start new test on "
                + repoName
                + "\nCause: "
                + s.toString());
        return Response.status(Status.NOT_FOUND).entity(Strings.MISSING).build();
      }

      if (s.getClassName().equals(NoCommitsToRepoException.class.getName())) {
        log.error(
            "User "
                + crsid
                + " failed to start new test on "
                + repoName
                + "\nCause: "
                + s.toString());
        return Response.status(Status.BAD_REQUEST).entity(Strings.NOCOMMITS).build();

      } else {
        log.error(
            "User "
                + crsid
                + " failed to start new test on "
                + repoName
                + "\nCause: "
                + s.toString());
        return Response.status(Status.INTERNAL_SERVER_ERROR)
            .entity(Strings.IDEMPOTENTRETRY)
            .build();
      }

    } catch (IOException
        | TestStillRunningException
        | TestIDNotFoundException
        | NoCommitsToRepoException e) {
      log.error("User " + crsid + " failed to start new test on " + repoName, e);
      return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e).build();
    }

    /* The fork is not submitted for testing */
    fork.setTesting(true);

    /* Save and return the fork object */
    db.saveFork(fork);
    return Response.status(Status.CREATED).build();
  }