             solution.without("processed").without("processingLock").without("pdf")
           ).run con
       )
+
+    resetPdfForAllSolutions: () ->
+      rdb.table("Solutions").replace((solution) ->
+        solution.without("processed").without("processingLock").without("pdf")
+      ).run con
 
     # Save the finished pdf file into the solution
     insertFinishedPdf: (solutionId, pdfData)->

              s.merge({"solution": s("_data")}).without("_data")
            } , {nonAtomic: true})
          ).run(con)

            )
          )
        })
      ).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
    # for the solution that hasn't been updated the longest.
    #
    # In order to update this solution, the stored solution must not be final
    # and older than minAge seconds.
    ############################################################################
    updateOldestSolution: (minAge) ->
      minAge = minAge or 300
      if !config.sharejs?.rethinkdb?.db?
        return Promise.reject "No sharejs database defined"

      rdb.do(
        rdb.table("Solutions")
          .orderBy({index: "lastStore"})
          .filter(
            rdb.row("lastStore").add(minAge).lt(rdb.now()).and(
              rdb.row("finalSolutionStored").default(false).eq(false)
            )
          )
          .eqJoin('exercise', rdb.table("Exercises")).nth(0).default(null),
        (oldest) ->
          rdb.branch(
            rdb.expr(oldest).ne(null),
            rdb.table("Solutions").get(oldest("left")("id")).update({
              lastStore: rdb.now()
              finalSolutionStored: oldest("right")("dueDate").lt(rdb.now())
              tasks: oldest("right")("tasks").map( (task) ->
                # left = Solutions
                # right = Exercises
                # id = group : exercise : task("number")
                rdb.db(config.sharejs.rethinkdb.db)
                  .table(config.sharejs.tableName)
                  .get(
                    rdb.add(oldest("left")("group").coerceTo("string"),":",oldest("right")("id").coerceTo("string"),":",task("number").coerceTo("string"))
                  ).pluck("_data")
              ).map (s) ->
                s.merge({"solution": s("_data")}).without("_data")
              } , {nonAtomic: true}
            ),
            {} # noop
          )
      ).run con

      # old less robust and slower implementation, kept in case something was missed
      ###
      rdb.do(
        rdb.table("Solutions")
          .orderBy({index: "lastStore"})
