         s("id").match(solution_id)).without("pdf").limit(10).coerceTo('array').run(con)
 
     # Also stores the last sharejs data
-    lockSpecificSolutionForPdfProcessor: (id) ->
+    lockSpecificSolutionForPdfProcessorQuery: (id) ->
       rdb.do(
         API.storeSolution(id),
         rdb.table("Solutions").get(id).update({"processingLock": true}, {returnChanges: true})
       )
+
+    lockSpecificSolutionForPdfProcessor: (id) ->
+      API.lockSpecificSolutionForPdfProcessorQuery(id).run con;
 
     ############################################################################
     # Locks a single solution which is due.

      rdb.table("Solutions").get(solutionId).pluck(rdb.args(pluckArr)).run con

    # Store all solutions that are due and haven't been stored yet.
    storeAllFinalSolutions: () ->
      (rdb.table("Solutions").eqJoin("exercise", rdb.table("Exercises")).filter(
        # has not been stored before
        rdb.row("left")("finalSolutionStored")
        .default(false)
        .eq(false)
        .and(rdb.row("right")("dueDate").lt(rdb.now()))
      ).map ( (solution) ->
        solution.merge({
          finalSolutionStored: true,
          tasks: solution("right")("tasks").map( (task) ->
            rdb
            .db(config.sharejs.rethinkdb.db)
            .table(config.sharejs.tableName)
            .get(
              rdb.add(
                solution("left")("group").coerceTo("string"),
                ":",
                solution("left")("exercise").coerceTo("string"),
                ":",
                task("number").coerceTo("string")
              )
            )
          )
        })
      )).coerceTo("array").run con

    # Stores just one final solution, for load balancing
    storeFinalSolutionSample: () ->
      rdb.table("Solutions").eqJoin("exercise", rdb.table("Exercises")).filter(
        rdb.row("left")("finalSolutionStored")
        .default(false)
        .eq(false)
        .and(rdb.row("right")("dueDate").lt(rdb.now()))
      ).sample(1).map( (solution) ->
        solution.merge({
          finalSolutionStored: true,
          tasks: solution("right")("tasks").map( (task) ->
            rdb
            .db(config.sharejs.rethinkdb.db)
            .table(config.sharejs.tableName)
            .get(
              rdb.add(
                solution("left")("group").coerceTo("string"),
                ":",
                solution("left")("exercise").coerceTo("string"),
                ":",
                task("number").coerceTo("string")
              )
            )
          )
        })
      ).run con

    # Store just one solution, does not perform checkings and is meant to be used for admins.
    storeSolution: (sid) ->
      rdb.table("Solutions").eqJoin("exercise", rdb.table("Exercises"))
      .filter((solution) -> solution("left")("id").eq(sid))
      .map( (solution) ->
        solution.merge({
          #finalSolutionStored: rdb.table("Exercises").get(solution("right")("id")),
          finalSolutionStored: solution("right")("dueDate").lt(rdb.now()),
          tasks: solution("right")("tasks").map( (task) ->
            rdb
            .db(config.sharejs.rethinkdb.db)
            .table(config.sharejs.tableName)
            .get(
              rdb.add(
                solution("left")("group").coerceTo("string"),
                ":",
                solution("left")("exercise").coerceTo("string"),
                ":",
                task("number").coerceTo("string")
              )
            )
          )
        })
      ).coerceTo('array')

    ############################################################################
    # UpdateOldestSolution copies the sharejs data over into the solution table

        ).sample(1).nth(0).default(null), (solution) ->
          rdb.branch(
            rdb.expr(solution).ne(null),
            API.lockSpecificSolutionForPdfProcessorQuery(solution("left")("id")).do(
              rdb.expr(solution)("left")
            ),
            rdb.expr(solution) # return null
