                     @return_assignment_to_student(assignment_id, student_id)
                 else
                     @set_error("copy_assignment -- unknown type: #{type}")
+
+        # This doesn't really stop it yet, since that's not supported by the backend.
+        # It does stop the spinner and let the user try to restart the copy.
+        stop_copying_assignment: (type, assignment_id, student_id) =>
+            switch type
+                when 'assigned'
+                    type = 'last_assignment'
+                when 'collected'
+                    type = 'last_collect'
+                when 'graded'
+                    type = 'last_return_graded'
+            @_stop_copy(assignment_id, student_id, type)
 
         open_assignment: (type, assignment_id, student_id) =>
             # type = assigned, collected, graded


        _finish_copy: (assignment, student, type, err) =>
            if student? and assignment?
                where = {table:'assignments', assignment_id:assignment.get('assignment_id')}
                x = syncdb.select_one(where:where)?[type] ? {}
                x[student.get('student_id')] = {time: misc.mswalltime(), error:err}
                @_update(set:{"#{type}":x}, where:where)

        # Copy the files for the given assignment to the given student. If
        # the student project doesn't exist yet, it will be created.

        #
        # where time >= now is the current time in milliseconds.
        copy_assignment_from_student: (assignment, student) =>
            if @_start_copy(assignment, student, 'last_collect')
                return
            id = @set_activity(desc:"Copying assignment from a student")
            finish = (err) =>
                @clear_activity(id)
