diff --git a/client/views/grade/EditPanel.jsx b/client/components/feedback/EditPanel.jsx
similarity index 87%
rename from client/views/grade/EditPanel.jsx
rename to client/components/feedback/EditPanel.jsx
index f1f574ac6f383042b186a8ac1107caae34f00389..63eb950ab7b52b8f1f9cd6bb810675d5ab001638 100644
--- a/client/views/grade/EditPanel.jsx
+++ b/client/components/feedback/EditPanel.jsx
@@ -40,16 +40,19 @@ class EditPanel extends React.Component {
   }
 
   static getDerivedStateFromProps (nextProps, prevState) {
+    // In case nothing is set, use an empty function that no-ops
+    const updateCallback = nextProps.updateCallback || (_ => {})
     if (nextProps.feedback && prevState.id !== nextProps.feedback.id) {
       const fb = nextProps.feedback
       return {
         id: fb.id,
         name: fb.name,
         description: fb.description,
-        score: fb.score
+        score: fb.score,
+        updateCallback: updateCallback
       }
     }
-    return null
+    return {updateCallback: updateCallback}
   }
 
   changeText = (event) => {
@@ -84,10 +87,15 @@ class EditPanel extends React.Component {
     if (this.state.id) {
       fb.id = this.state.id
       api.put(uri, fb)
-        .then(() => this.props.goBack())
+        .then(() => {
+          this.state.updateCallback(fb)
+          this.props.goBack()
+        })
     } else {
       api.post(uri, fb)
-        .then(() => {
+        .then((response) => {
+          // Response is the feedback option
+          this.state.updateCallback(response)
           this.setState({
             id: null,
             name: '',
@@ -101,14 +109,20 @@ class EditPanel extends React.Component {
   deleteFeedback = () => {
     if (this.state.id) {
       api.del('feedback/' + this.props.problemID + '/' + this.state.id)
-        .then(() => this.props.goBack())
+        .then(() => {
+          this.state.updateCallback({
+            id: this.state.id,
+            deleted: true
+          })
+          this.props.goBack()
+        })
     }
   }
 
   render () {
     return (
-      <nav className='panel'>
-        <p className='panel-heading'>
+      <React.Fragment>
+        <p className={this.props.grading ? 'panel-heading' : 'panel-heading is-radiusless'}>
           Manage feedback
         </p>
 
@@ -168,7 +182,7 @@ class EditPanel extends React.Component {
             onCancel={() => { this.setState({deleting: false}) }}
           />
         </div>
-      </nav>
+      </React.Fragment>
     )
   }
 }
diff --git a/client/views/grade/FeedbackBlock.jsx b/client/components/feedback/FeedbackBlock.jsx
similarity index 84%
rename from client/views/grade/FeedbackBlock.jsx
rename to client/components/feedback/FeedbackBlock.jsx
index 7bc7ba60798917605cb34fa14e589de666679d28..af1429fd855a49d6aad28bd3a5fe9d39f68f058b 100644
--- a/client/views/grade/FeedbackBlock.jsx
+++ b/client/components/feedback/FeedbackBlock.jsx
@@ -32,7 +32,9 @@ class FeedbackBlock extends React.Component {
   render () {
     const shortcut = (this.props.index < 11 ? '' : 'shift + ') + this.props.index % 10
     return (
-      <a className='panel-block is-active' onClick={this.toggle}
+      <a
+        className={this.props.grading ? 'panel-block is-active' : 'panel-block'}
+        onClick={this.props.grading ? this.toggle : this.props.editFeedback}
         style={this.props.selected ? {backgroundColor: '#209cee'} : {}}
       >
         <span
@@ -40,7 +42,9 @@ class FeedbackBlock extends React.Component {
             ? ' tooltip is-tooltip-active is-tooltip-left' : '')}
           data-tooltip={shortcut}
         >
-          <i className={'fa fa-' + (this.props.checked ? 'check-square-o' : 'square-o')} />
+          {this.props.grading &&
+            <i className={'fa fa-' + (this.props.checked ? 'check-square-o' : 'square-o')} />
+          }
         </span>
         <span style={{ width: '80%' }}>
           {this.props.feedback.name}
diff --git a/client/views/grade/FeedbackPanel.jsx b/client/components/feedback/FeedbackPanel.jsx
similarity index 77%
rename from client/views/grade/FeedbackPanel.jsx
rename to client/components/feedback/FeedbackPanel.jsx
index ee5266e6f25447fdb6dcbc3040666bb411f09e98..e2e1ce622ea373b7772b6f14deb5df8f1f47177c 100644
--- a/client/views/grade/FeedbackPanel.jsx
+++ b/client/components/feedback/FeedbackPanel.jsx
@@ -4,7 +4,7 @@ import Notification from 'react-bulma-notification'
 
 import * as api from '../../api.jsx'
 
-import withShortcuts from '../../components/ShortcutBinder.jsx'
+import withShortcuts from '../ShortcutBinder.jsx'
 import FeedbackBlock from './FeedbackBlock.jsx'
 
 class FeedbackPanel extends React.Component {
@@ -35,7 +35,7 @@ class FeedbackPanel extends React.Component {
   static getDerivedStateFromProps (nextProps, prevState) {
     if (prevState.problemID !== nextProps.problem.id || prevState.submissionID !== nextProps.submissionID) {
       return {
-        remark: nextProps.solution.remark,
+        remark: nextProps.grading && nextProps.solution.remark,
         problemID: nextProps.problem.id,
         submissionID: nextProps.submissionID,
         selectedFeedbackIndex: null
@@ -90,29 +90,34 @@ class FeedbackPanel extends React.Component {
     const blockURI = this.props.examID + '/' + this.props.submissionID + '/' + this.props.problem.id
 
     let totalScore = 0
-    for (let i = 0; i < this.props.solution.feedback.length; i++) {
-      const probIndex = this.props.problem.feedback.findIndex(fb => fb.id === this.props.solution.feedback[i])
-      if (probIndex >= 0) totalScore += this.props.problem.feedback[probIndex].score
+    if (this.props.grading) {
+      for (let i = 0; i < this.props.solution.feedback.length; i++) {
+        const probIndex = this.props.problem.feedback.findIndex(fb => fb.id === this.props.solution.feedback[i])
+        if (probIndex >= 0) totalScore += this.props.problem.feedback[probIndex].score
+      }
     }
 
     let selectedFeedbackId = this.state.selectedFeedbackIndex !== null &&
       this.props.problem.feedback[this.state.selectedFeedbackIndex].id
 
     return (
-      <nav className='panel'>
-        <p className='panel-heading'>
-          Total:&nbsp;<b>{totalScore}</b>
-        </p>
+      <React.Fragment>
+        {this.props.grading &&
+          <p className='panel-heading'>
+            Total:&nbsp;<b>{totalScore}</b>
+          </p>}
         {this.props.problem.feedback.map((feedback, index) =>
           <FeedbackBlock key={feedback.id} uri={blockURI} graderID={this.props.graderID}
-            feedback={feedback} checked={this.props.solution.feedback.includes(feedback.id)}
+            feedback={feedback} checked={this.props.grading && this.props.solution.feedback.includes(feedback.id)}
             editFeedback={() => this.props.editFeedback(feedback)} updateSubmission={this.props.updateSubmission}
-            ref={(selectedFeedbackId === feedback.id) ? this.feedbackBlock : null}
+            ref={(selectedFeedbackId === feedback.id) ? this.feedbackBlock : null} grading={this.props.grading}
             selected={selectedFeedbackId === feedback.id} showIndex={this.props.showTooltips} index={index + 1} />
         )}
-        <div className='panel-block'>
-          <textarea className='textarea' rows='2' placeholder='remark' value={this.state.remark} onBlur={this.saveRemark} onChange={this.changeRemark} />
-        </div>
+        {this.props.grading &&
+          <div className='panel-block'>
+            <textarea className='textarea' rows='2' placeholder='remark' value={this.state.remark} onBlur={this.saveRemark} onChange={this.changeRemark} />
+          </div>
+        }
         <div className='panel-block'>
           <button className='button is-link is-outlined is-fullwidth' onClick={() => this.props.editFeedback()}>
             <span className='icon is-small'>
@@ -121,7 +126,7 @@ class FeedbackPanel extends React.Component {
             <span>option</span>
           </button>
         </div>
-      </nav>
+      </React.Fragment>
     )
   }
 }
diff --git a/client/views/Exam.css b/client/views/Exam.css
index e70724da849022d617945ccebe204ea143ad9fea..d1ffaddc6ffb8bd2fdb04f2dc4bae869d4325a2d 100644
--- a/client/views/Exam.css
+++ b/client/views/Exam.css
@@ -30,7 +30,8 @@ div.mcq-option img.mcq-box {
 
 .editor-content {
   background-color: #ddd;
-  border-radius: 10px
+  border-radius: 10px;
+  height: 100%;
 }
 
 .selection-area {
diff --git a/client/views/Exam.jsx b/client/views/Exam.jsx
index 3ccbc0087586e63a07fe50a09b7b2900dded0730..b51eb7fe61e101dba054bcd2b37f889d43eacc67 100644
--- a/client/views/Exam.jsx
+++ b/client/views/Exam.jsx
@@ -11,6 +11,8 @@ import ExamEditor from './ExamEditor.jsx'
 import update from 'immutability-helper'
 import ExamFinalizeMarkdown from './ExamFinalize.md'
 import ConfirmationModal from '../components/ConfirmationModal.jsx'
+import FeedbackPanel from '../components/feedback/FeedbackPanel.jsx'
+import EditPanel from '../components/feedback/EditPanel.jsx'
 
 import * as api from '../api.jsx'
 
@@ -18,6 +20,9 @@ class Exams extends React.Component {
   state = {
     examID: null,
     page: 0,
+    editActive: false,
+    feedbackToEdit: null,
+    problemIdToEditFeedbackOf: null,
     numPages: null,
     selectedWidgetId: null,
     changedWidgetId: null,
@@ -42,11 +47,16 @@ class Exams extends React.Component {
             page: problem.page,
             name: problem.name,
             graded: problem.graded,
+            feedback: problem.feedback || [],
             mc_options: problem.mc_options.map((option) => {
-              option.widget.x -= 7
-              option.widget.y -= 21
+              option.cbOffsetX = 7 // checkbox offset relative to option position on x axis
+              option.cbOffsetY = 21 // checkbox offset relative to option position on y axis
+              option.widget.x -= option.cbOffsetX
+              option.widget.y -= option.cbOffsetY
               return option
             }),
+            widthMCO: 24,
+            heightMCO: 38,
             isMCQ: problem.mc_options && problem.mc_options.length !== 0 // is the problem a mc question - used to display PanelMCQ
           }
         }
@@ -66,7 +76,6 @@ class Exams extends React.Component {
         previewing: false
       }
     }
-
     return null
   }
 
@@ -78,6 +87,10 @@ class Exams extends React.Component {
     // The onBlur event is not fired when the input field is being disabled
     if (prevState.selectedWidgetId !== this.state.selectedWidgetId) {
       this.saveProblemName()
+      this.setState({
+        editActive: false,
+        problemIdToEditFeedbackOf: false
+      })
     }
   }
 
@@ -94,6 +107,43 @@ class Exams extends React.Component {
     }
   }
 
+  editFeedback = (feedback) => {
+    this.setState({
+      editActive: true,
+      feedbackToEdit: feedback,
+      problemIdToEditFeedbackOf: this.state.selectedWidgetId
+    })
+  }
+
+  updateFeedback = (feedback) => {
+    let problemWidget = this.state.widgets[this.state.selectedWidgetId]
+    const index = problemWidget.problem.feedback.findIndex(e => { return e.id === feedback.id })
+    this.updateFeedbackAtIndex(feedback, problemWidget, index)
+  }
+
+  updateFeedbackAtIndex = (feedback, problemWidget, idx) => {
+    if (idx === -1) {
+      problemWidget.problem.feedback.push(feedback)
+    } else {
+      if (feedback.deleted) problemWidget.problem.feedback.splice(idx, 1)
+      else problemWidget.problem.feedback[idx] = feedback
+    }
+    this.setState({
+      widgets: this.state.widgets
+    })
+  }
+
+  backToFeedback = () => {
+    this.props.updateExam(this.props.exam.id)
+    this.setState({
+      editActive: false
+    })
+  }
+
+  isProblemWidget = (widget) => {
+    return widget && this.state.widgets[widget].problem
+  }
+
   saveProblemName = () => {
     const changedWidgetId = this.state.changedWidgetId
     if (!changedWidgetId) return
@@ -134,6 +184,8 @@ class Exams extends React.Component {
               selectedWidgetId: null,
               changedWidgetId: null,
               deletingWidget: false,
+              editActive: false,
+              problemIdToEditFeedbackOf: null,
               widgets: update(prevState.widgets, {
                 $unset: [widgetId]
               })
@@ -182,6 +234,7 @@ class Exams extends React.Component {
           numPages={this.state.numPages}
           onPDFLoad={this.onPDFLoad}
           updateWidget={this.updateWidget}
+          updateMCWidget={this.updateMCWidget}
           selectedWidgetId={this.state.selectedWidgetId}
           selectWidget={(widgetId) => {
             this.setState({
@@ -189,7 +242,6 @@ class Exams extends React.Component {
             })
           }}
           createNewWidget={this.createNewWidget}
-          updateMCWidgetPosition={this.updateMCWidgetPosition}
           updateExam={() => {
             this.props.updateExam(this.props.examID)
           }}
@@ -271,11 +323,16 @@ class Exams extends React.Component {
               // update to try and get a consistent state
               this.props.updateExam(this.props.examID)
             })
+          }).then(res => {
+            let index = widget.problem.feedback.findIndex(e => { return e.id === res.feedback_id })
+            let feedback = widget.problem.feedback[index]
+            feedback.deleted = true
+            this.updateFeedbackAtIndex(feedback, widget, index)
           })
       })
 
       // remove the mc options from the state
-      // note that his can happen before they are removed in the DB due to async calls
+      // note that this can happen before they are removed in the DB due to async calls
       this.setState((prevState) => {
         return {
           widgets: update(prevState.widgets, {
@@ -294,11 +351,11 @@ class Exams extends React.Component {
   }
 
   /**
-   * This method creates a widget object and adds it to the corresponding problem
+   * This method creates a mc option widget object and adds it to the corresponding problem
    * @param problemWidget The widget the mc option belongs to
    * @param data the mc option
    */
-  createNewMCOWidget = (problemWidget, data) => {
+  createNewMCWidget = (problemWidget, data) => {
     this.setState((prevState) => {
       return {
         widgets: update(prevState.widgets, {
@@ -320,12 +377,12 @@ class Exams extends React.Component {
    * @param widget the problem widget that includes the mcq widget
    * @param data the new location of the mcq widget (the location of the top-left corner)
    */
-  updateMCWidgetPosition = (widget, data) => {
+  updateMCWidget = (widget, data) => {
     let newMCO = widget.problem.mc_options.map((option, i) => {
       return {
         'widget': {
           'x': {
-            $set: data.x + i * 24
+            $set: data.x + i * widget.problem.widthMCO
           },
           'y': {
             // each mc option needs to be positioned next to the previous option and should not overlap it
@@ -359,30 +416,41 @@ class Exams extends React.Component {
   generateAnswerBoxes = (problemWidget, labels, index, xPos, yPos) => {
     if (labels.length === index) return
 
+    let feedback = {
+      'name': labels[index],
+      'description': '',
+      'score': 0
+    }
+
     let data = {
       'label': labels[index],
       'problem_id': problemWidget.problem.id,
       'feedback_id': null,
+      'cbOffsetX': 7, // checkbox offset relative to option position on x axis
+      'cbOffsetY': 21, // checkbox offset relative to option position on y axis
       'widget': {
         'name': 'mc_option_' + labels[index],
-        'x': xPos + 7,
-        'y': yPos + 21,
+        'x': xPos,
+        'y': yPos,
         'type': 'mcq_widget'
       }
     }
 
     const formData = new window.FormData()
     formData.append('name', data.widget.name)
-    formData.append('x', data.widget.x)
-    formData.append('y', data.widget.y)
+    formData.append('x', data.widget.x + data.cbOffsetX)
+    formData.append('y', data.widget.y + data.cbOffsetY)
     formData.append('problem_id', data.problem_id)
     formData.append('label', data.label)
+    formData.append('fb_description', feedback.description)
+    formData.append('fb_score', feedback.score)
     api.put('mult-choice/', formData).then(result => {
       data.id = result.mult_choice_id
-      data.widget.x -= 7
-      data.widget.y -= 21
-      this.createNewMCOWidget(problemWidget, data)
-      this.generateAnswerBoxes(problemWidget, labels, index + 1, xPos + 24, yPos)
+      data.feedback_id = result.feedback_id
+      feedback.id = result.feedback_id
+      this.createNewMCWidget(problemWidget, data)
+      this.updateFeedback(feedback)
+      this.generateAnswerBoxes(problemWidget, labels, index + 1, xPos + problemWidget.problem.widthMCO, yPos)
     }).catch(err => {
       console.log(err)
     })
@@ -392,13 +460,14 @@ class Exams extends React.Component {
     const selectedWidgetId = this.state.selectedWidgetId
     let selectedWidget = selectedWidgetId && this.state.widgets[selectedWidgetId]
     let problem = selectedWidget && selectedWidget.problem
-    let widgetEditDisabled = this.state.previewing || !problem
+    let containsMCOptions = (problem && problem.mc_options.length > 0) || false
+    let widgetEditDisabled = (this.state.previewing || !problem) || (this.props.exam.finalized && containsMCOptions)
     let isGraded = problem && problem.graded
     let widgetDeleteDisabled = widgetEditDisabled || isGraded
     let totalNrAnswers = 12 // the upper limit for the nr of possible answer boxes
-    let containsMCOptions = (problem && problem.mc_options.length > 0) || false
     let disabledDeleteBoxes = !containsMCOptions
     let isMCQ = (problem && problem.isMCQ) || false
+    let showPanelMCQ = isMCQ && !this.state.previewing && !this.props.exam.finalized
 
     return (
       <React.Fragment>
@@ -443,7 +512,7 @@ class Exams extends React.Component {
             }
           }
         />
-        { isMCQ ? (
+        { showPanelMCQ ? (
           <PanelMCQ
             totalNrAnswers={totalNrAnswers}
             disabledGenerateBoxes={containsMCOptions}
@@ -505,17 +574,29 @@ class Exams extends React.Component {
             </div>
             <div className='panel-block'>
               <div className='field'>
-                <label className='label'>
-                  <input disabled={props.disableIsMCQ} type='checkbox' checked={props.isMCQProblem} onChange={
-                    (e) => {
-                      props.onMCQChange(e.target.checked)
-                    }} />
-                    Multiple choice question
-                </label>
+                <label className='label'> Multiple choice question </label>
+                <input disabled={props.disableIsMCQ} type='checkbox' checked={props.isMCQProblem} onChange={
+                  (e) => {
+                    props.onMCQChange(e.target.checked)
+                  }} />
               </div>
             </div>
           </React.Fragment>
         )}
+        {this.isProblemWidget(selectedWidgetId) &&
+          <React.Fragment>
+            <div className='panel-block'>
+              {!this.state.editActive && <label className='label'>Feedback options</label>}
+            </div>
+            {this.state.editActive
+              ? <EditPanel problemID={props.problem.id} feedback={this.state.feedbackToEdit}
+                goBack={this.backToFeedback} updateCallback={this.updateFeedback} />
+              : <FeedbackPanel examID={this.props.examID} problem={props.problem}
+                editFeedback={this.editFeedback} showTooltips={this.state.showTooltips}
+                grading={false}
+              />}
+          </React.Fragment>
+        }
         <div className='panel-block'>
           <button
             disabled={props.disabledDelete}
diff --git a/client/views/ExamEditor.jsx b/client/views/ExamEditor.jsx
index 311cadafb250703af69f983cae03a8e88438ea5e..4abdf15844b4980279f7450e362e615551ef92f8 100644
--- a/client/views/ExamEditor.jsx
+++ b/client/views/ExamEditor.jsx
@@ -88,7 +88,10 @@ class ExamEditor extends React.Component {
         const problemData = {
           name: 'New problem', // TODO: Name
           page: this.props.page,
+          feedback: [],
           mc_options: [],
+          widthMCO: 24,
+          heightMCO: 38,
           isMCQ: false
         }
         const widgetData = {
@@ -178,8 +181,8 @@ class ExamEditor extends React.Component {
    * @param widget the widget that was relocated
    * @param data  the new location
    */
-  updateWidgetPositionDB = (widget, data) => {
-    api.patch('widgets/' + widget.id, data).then(() => {
+  updateWidgetDB = (widget, data) => {
+    return api.patch('widgets/' + widget.id, data).then(() => {
       // ok
     }).catch(err => {
       console.log(err)
@@ -188,33 +191,77 @@ class ExamEditor extends React.Component {
     })
   }
 
-  updateState = (widget, data) => {
-    this.props.updateMCWidgetPosition(widget, {
+  /**
+   * This function updates the state and the Database with the positions of the mc options.
+   * @param widget the problem widget the mc options belong to
+   * @param data the new position of the mc widget
+   */
+  updateMCO = (widget, data) => {
+    // update state
+    this.props.updateMCWidget(widget, {
       x: Math.round(data.x),
       y: Math.round(data.y)
     })
-  }
-
-  updateMCOPosition = (widget, data) => {
-    this.updateState(widget, data)
 
+    // update DB
     widget.problem.mc_options.forEach(
       (option, i) => {
         let newData = {
-          x: Math.round(data.x) + i * 24 + 7,
-          y: Math.round(data.y) + 21
+          x: Math.round(data.x) + i * widget.problem.widthMCO + option.cbOffsetX,
+          y: Math.round(data.y) + option.cbOffsetY
         }
-        this.updateWidgetPositionDB(option, newData)
+        this.updateWidgetDB(option, newData)
       })
   }
 
   /**
-   * This function renders a group of options into one draggable widget
-   * @returns {*}
+   * This function updates the position of the mc options inside when the corresponding problem widget changes in
+   * size or position. Note that the positions in the database are not updated. These should be updated once when the
+   * action (resizing/dragging/other) is finalized.
+   * @param widget the problem widget containing mc options
+   * @param data the new data about the new size/position of the problem widget
+   */
+  repositionMC = (widget, data) => {
+    if (widget.problem.mc_options.length > 0) {
+      let oldX = widget.problem.mc_options[0].widget.x
+      let oldY = widget.problem.mc_options[0].widget.y
+      let newX = oldX
+      let newY = oldY
+      let widthOption = widget.problem.widthMCO * widget.problem.mc_options.length
+      let heightOption = widget.problem.heightMCO
+      let widthProblem = data.width ? data.width : widget.width
+      let heightProblem = data.height ? data.height : widget.height
+
+      if (newX < data.x) {
+        newX = data.x
+      } else if (newX + widthOption > data.x + widthProblem) {
+        newX = data.x + widget.width - widthOption
+      }
+
+      if (newY < data.y) {
+        newY = data.y
+      } else if (newY + heightOption > data.y + heightProblem) {
+        newY = data.y + widget.height - heightOption
+      }
+
+      let changed = (oldX !== newX) || (oldY !== newY) // update the state only if the mc options were moved
+      if (changed) {
+        this.props.updateMCWidget(widget, {
+          x: Math.round(newX),
+          y: Math.round(newY)
+        })
+      }
+    }
+  }
+
+  /**
+   * This function renders a group of options into one draggable widget.
+   * @param widget the problem widget that contains a mc options
+   * @return a react component representing the multiple choice widget
    */
   renderMCWidget = (widget) => {
-    let width = 24 * widget.problem.mc_options.length
-    let height = 38
+    let width = widget.problem.widthMCO * widget.problem.mc_options.length
+    let height = widget.problem.heightMCO
     let enableResizing = false
     const isSelected = widget.id === this.props.selectedWidgetId
     let xPos = widget.problem.mc_options[0].widget.x
@@ -248,7 +295,7 @@ class ExamEditor extends React.Component {
           this.props.selectWidget(widget.id)
         }}
         onDragStop={(e, data) => {
-          this.updateMCOPosition(widget, data)
+          this.updateMCO(widget, data)
         }}
       >
         <div className={isSelected ? 'mcq-widget widget selected' : 'mcq-widget widget '}>
@@ -268,9 +315,9 @@ class ExamEditor extends React.Component {
   }
 
   /**
-   * Render problem widget and the mc options that correspond to the problem
+   * Render problem widget and the mc options that correspond to the problem.
    * @param widget the corresponding widget object from the db
-   * @returns {Array}
+   * @returns {Array} an array of react components to be displayed
    */
   renderProblemWidget = (widget) => {
     // Only render when numPage is set
@@ -312,79 +359,49 @@ class ExamEditor extends React.Component {
             x: { $set: Math.round(position.x) },
             y: { $set: Math.round(position.y) }
           })
+          this.repositionMC(widget, {
+            width: ref.offsetWidth,
+            height: ref.offsetHeight,
+            x: Math.round(position.x),
+            y: Math.round(position.y)
+          })
         }}
         onResizeStop={(e, direction, ref, delta, position) => {
-          api.patch('widgets/' + widget.id, {
+          this.updateWidgetDB(widget, {
             x: Math.round(position.x),
             y: Math.round(position.y),
             width: ref.offsetWidth,
             height: ref.offsetHeight
           }).then(() => {
-            // ok
-          }).catch(err => {
-            console.log(err)
-            // update to try and get a consistent state
-            this.props.updateExam()
+            if (widget.problem.mc_options.length > 0) {
+              this.updateMCO(widget, {
+                x: widget.problem.mc_options[0].widget.x, // these are guaranteed to be up to date
+                y: widget.problem.mc_options[0].widget.y
+              })
+            }
           })
         }}
         onDragStart={() => {
           this.props.selectWidget(widget.id)
         }}
-        onDrag={(e, data) => {
-          if (widget.problem.mc_options.length > 0) {
-            let xPos = widget.problem.mc_options[0].widget.x
-            let yPos = widget.problem.mc_options[0].widget.y
-            let width = 24 * widget.problem.mc_options.length
-            let height = 38
-
-            if (xPos < data.x) {
-              xPos = data.x
-            } else if (xPos + width > data.x + widget.width) {
-              xPos = data.x + widget.width - width
-            }
-
-            if (yPos < data.y) {
-              yPos = data.y
-            } else if (yPos + height > data.y + widget.height) {
-              yPos = data.y + widget.height - height
-            }
-
-            this.updateState(widget, { x: xPos, y: yPos })
-          }
-        }}
+        onDrag={(e, data) => this.repositionMC(widget, data)}
         onDragStop={(e, data) => {
           this.props.updateWidget(widget.id, {
             x: { $set: Math.round(data.x) },
             y: { $set: Math.round(data.y) }
           })
-          api.patch('widgets/' + widget.id, {
+          this.updateWidgetDB(widget, {
             x: Math.round(data.x),
             y: Math.round(data.y)
           }).then(() => {
             if (widget.problem.mc_options.length > 0) {
-              let xPos = widget.problem.mc_options[0].widget.x
-              let yPos = widget.problem.mc_options[0].widget.y
-              let width = 24 * widget.problem.mc_options.length
-              let height = 38
-
-              if (xPos < data.x) {
-                xPos = data.x
-              } else if (xPos + width > data.x + widget.width) {
-                xPos = data.x + widget.width - width
-              }
-
-              if (yPos < data.y) {
-                yPos = data.y
-              } else if (yPos + height > data.y + widget.height) {
-                yPos = data.y + widget.height - height
-              }
-
-              this.updateMCOPosition(widget, { x: xPos, y: yPos })
+              this.updateMCO(widget, {
+                // react offers the guarantee that setState calls are processed before handling next event
+                // therefore the data in the state is up to date
+                x: widget.problem.mc_options[0].widget.x,
+                y: widget.problem.mc_options[0].widget.y
+              })
             }
-          }).catch(err => {
-            console.log(err)
-            // update to try and get a consistent state
-            this.props.updateExam()
           })
         }}
       >
@@ -405,7 +422,7 @@ class ExamEditor extends React.Component {
   /**
    * Render exam widgets.
    * @param widget the corresponding widget object from the db
-   * @returns {Array}
+   * @returns {Array} an array of react components to be displayed
    */
   renderExamWidget = (widget) => {
     if (this.props.finalized) return []
@@ -458,15 +475,9 @@ class ExamEditor extends React.Component {
             x: { $set: Math.round(data.x) },
             y: { $set: Math.round(data.y) }
           })
-          api.patch('widgets/' + widget.id, {
+          this.updateWidgetDB(widget, {
             x: Math.round(data.x),
             y: Math.round(data.y)
-          }).then(() => {
-            // ok
-          }).catch(err => {
-            console.log(err)
-            // update to try and get a consistent state
-            this.props.updateExam()
           })
         }}
       >
@@ -484,7 +495,7 @@ class ExamEditor extends React.Component {
 
   /**
    * Render all the widgets by calling the right rendering function for each widget type
-   * @returns {Array}
+   * @returns {Array} containing all widgets components to be displayed
    */
   renderWidgets = () => {
     // Only render when numPage is set
diff --git a/client/views/Grade.jsx b/client/views/Grade.jsx
index e3bafba95d19e35134a4208cb2528bc885bdf4fc..e6d2496948339f39efc508b33dc3f9a73ef0189f 100644
--- a/client/views/Grade.jsx
+++ b/client/views/Grade.jsx
@@ -2,9 +2,9 @@ import React from 'react'
 
 import Hero from '../components/Hero.jsx'
 
-import FeedbackPanel from './grade/FeedbackPanel.jsx'
+import FeedbackPanel from '../components/feedback/FeedbackPanel.jsx'
 import ProblemSelector from './grade/ProblemSelector.jsx'
-import EditPanel from './grade/EditPanel.jsx'
+import EditPanel from '../components/feedback/EditPanel.jsx'
 import SearchBox from '../components/SearchBox.jsx'
 import ProgressBar from '../components/ProgressBar.jsx'
 import withShortcuts from '../components/ShortcutBinder.jsx'
@@ -30,6 +30,7 @@ class Grade extends React.Component {
     // update the tooltips for the associated widgets (in render()).
     this.props.bindShortcut(['left', 'h'], this.prev)
     this.props.bindShortcut(['right', 'l'], this.next)
+    this.props.bindShortcut(['a'], this.approve)
     this.props.bindShortcut(['shift+left', 'shift+h'], (event) => {
       event.preventDefault()
       this.prevUngraded()
@@ -153,6 +154,20 @@ class Grade extends React.Component {
       })
   }
 
+  approve = () => {
+    const exam = this.props.exam
+    const problem = exam.problems[this.state.pIndex]
+    const optionURI = this.state.examID + '/' +
+      exam.submissions[this.state.sIndex].id + '/' +
+      problem.id
+    api.put('solution/approve/' + optionURI, {
+      graderID: this.props.graderID
+    })
+      .then(result => {
+        this.props.updateSubmission(this.state.sIndex)
+      })
+  }
+
   toggleFullPage = (event) => {
     this.setState({
       fullPage: event.target.checked
@@ -210,17 +225,18 @@ class Grade extends React.Component {
               <div className='column is-one-quarter-desktop is-one-third-tablet'>
                 <ProblemSelector problems={exam.problems} changeProblem={this.changeProblem}
                   current={this.state.pIndex} showTooltips={this.state.showTooltips} />
-                {this.state.editActive
-                  ? <EditPanel problemID={problem.id} feedback={this.state.feedbackToEdit}
-                    goBack={this.backToFeedback} />
-                  : <FeedbackPanel examID={exam.id} submissionID={submission.id}
-                    problem={problem} solution={solution} graderID={this.props.graderID}
-                    editFeedback={this.editFeedback} showTooltips={this.state.showTooltips}
-                    updateSubmission={() => {
-                      this.props.updateSubmission(this.state.sIndex)
-                    }
-                    } />
-                }
+                <nav className='panel'>
+                  {this.state.editActive
+                    ? <EditPanel problemID={problem.id} feedback={this.state.feedbackToEdit}
+                      goBack={this.backToFeedback} />
+                    : <FeedbackPanel examID={exam.id} submissionID={submission.id}
+                      problem={problem} solution={solution} graderID={this.props.graderID}
+                      editFeedback={this.editFeedback} showTooltips={this.state.showTooltips}
+                      updateSubmission={() => {
+                        this.props.updateSubmission(this.state.sIndex)
+                      }} grading />
+                  }
+                </nav>
               </div>
 
               <div className='column'>
@@ -260,9 +276,13 @@ class Grade extends React.Component {
                           renderSuggestion={(submission) => {
                             const stud = submission.student
                             return (
-                              <div>
-                                <b>{`${stud.firstName} ${stud.lastName}`}</b>
-                                <i style={{float: 'right'}}>({stud.id})</i>
+                              <div className='flex-parent'>
+                                <b className='flex-child truncated'>
+                                  {`${stud.firstName} ${stud.lastName}`}
+                                </b>
+                                <i className='flex-child fixed'>
+                                  ({stud.id})
+                                </i>
                               </div>
                             )
                           }}
diff --git a/client/views/grade/Grade.css b/client/views/grade/Grade.css
index 90e5dab9e507f7bcb2185c4541ce7632a4564d55..8b88019a647828998811e4a4df4a7a6dec7559c8 100644
--- a/client/views/grade/Grade.css
+++ b/client/views/grade/Grade.css
@@ -1,3 +1,19 @@
 .box.is-graded {
     box-shadow: 0px 0px 6px #23d160, 0 0 0 1px rgba(10, 10, 10, 0.1);
 }
+
+.flex-parent {
+    display: flex;
+    align-items: center;
+}
+
+.flex-child.truncated {
+    flex: 1;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+
+.flex-child.fixed {
+    white-space: nowrap;
+}
diff --git a/tests/api/test_exams.py b/tests/api/test_exams.py
new file mode 100644
index 0000000000000000000000000000000000000000..c115ac5284ea006c30ed66804e9ba8f58c806047
--- /dev/null
+++ b/tests/api/test_exams.py
@@ -0,0 +1,48 @@
+import pytest
+
+from flask import json
+from zesje.database import db, Exam, Problem, ProblemWidget
+
+
+@pytest.fixture
+def add_test_data(app):
+    with app.app_context():
+        exam1 = Exam(id=1, name='exam 1', finalized=False)
+        db.session.add(exam1)
+        db.session.commit()
+
+        problem1 = Problem(id=1, name='Problem 1', exam_id=1)
+        db.session.add(problem1)
+        db.session.commit()
+
+        problem_widget_1 = ProblemWidget(id=1, name='problem widget', problem_id=1, page=2,
+                                         width=100, height=150, x=40, y=200, type='problem_widget')
+        db.session.add(problem_widget_1)
+        db.session.commit()
+
+
+def test_get_exams(test_client, add_test_data):
+    mc_option_1 = {
+        'x': 100,
+        'y': 40,
+        'problem_id': 1,
+        'page': 1,
+        'label': 'a',
+        'name': 'test'
+    }
+    test_client.put('/api/mult-choice/', data=mc_option_1)
+
+    mc_option_2 = {
+        'x': 100,
+        'y': 40,
+        'problem_id': 1,
+        'page': 1,
+        'label': 'a',
+        'name': 'test'
+    }
+    test_client.put('/api/mult-choice/', data=mc_option_2)
+
+    response = test_client.get('/api/exams/1')
+    data = json.loads(response.data)
+
+    assert len(data['problems'][0]['mc_options']) == 2
diff --git a/tests/api/test_mc_option.py b/tests/api/test_mc_option.py
new file mode 100644
index 0000000000000000000000000000000000000000..4d109bde2c608e9e80db244e8026c9acdccf8220
--- /dev/null
+++ b/tests/api/test_mc_option.py
@@ -0,0 +1,155 @@
+import pytest
+
+from flask import json
+
+from zesje.database import db, Exam, Problem, ProblemWidget
+
+
+@pytest.fixture
+def add_test_data(app):
+    with app.app_context():
+        exam1 = Exam(id=1, name='exam 1', finalized=False)
+        exam2 = Exam(id=2, name='exam 2', finalized=True)
+        exam3 = Exam(id=3, name='exam 3', finalized=False)
+
+        db.session.add(exam1)
+        db.session.add(exam2)
+        db.session.add(exam3)
+
+        problem1 = Problem(id=1, name='Problem 1', exam_id=1)
+        problem2 = Problem(id=2, name='Problem 2', exam_id=2)
+        problem3 = Problem(id=3, name='Problem 3', exam_id=3)
+
+        db.session.add(problem1)
+        db.session.add(problem2)
+        db.session.add(problem3)
+
+        problem_widget_1 = ProblemWidget(id=1, name='problem widget', problem_id=1, page=2,
+                                         width=100, height=150, x=40, y=200, type='problem_widget')
+        db.session.add(problem_widget_1)
+
+        db.session.commit()
+
+
+def mco_json():
+    return {
+        'x': 100,
+        'y': 40,
+        'problem_id': 1,
+        'page': 1,
+        'label': 'a',
+        'name': 'test'
+    }
+
+
+'''
+ACTUAL TESTS
+'''
+
+
+def test_not_present(test_client, add_test_data):
+    result = test_client.get('/api/mult-choice/1')
+    data = json.loads(result.data)
+
+    assert data['status'] == 404
+
+
+def test_add(test_client, add_test_data):
+    req = mco_json()
+    response = test_client.put('/api/mult-choice/', data=req)
+
+    data = json.loads(response.data)
+
+    assert data['message'] == 'New multiple choice question with id 2 inserted. ' \
+        + 'New feedback option with id 1 inserted.'
+
+    assert data['mult_choice_id'] == 2
+    assert data['status'] == 200
+
+
+def test_add_get(test_client, add_test_data):
+    req = mco_json()
+
+    response = test_client.put('/api/mult-choice/', data=req)
+    data = json.loads(response.data)
+
+    id = data['mult_choice_id']
+
+    result = test_client.get(f'/api/mult-choice/{id}')
+    data = json.loads(result.data)
+
+    exp_resp = {
+        'id': 2,
+        'name': 'test',
+        'x': 100,
+        'y': 40,
+        'type': 'mcq_widget',
+        'feedback_id': 1,
+        'label': 'a',
+    }
+
+    assert exp_resp == data
+
+
+def test_update_put(test_client, add_test_data):
+    req = mco_json()
+
+    response = test_client.put('/api/mult-choice/', data=req)
+    data = json.loads(response.data)
+    id = data['mult_choice_id']
+
+    req2 = {
+        'x': 120,
+        'y': 50,
+        'problem_id': 4,
+        'page': 1,
+        'label': 'b',
+        'name': 'test'
+    }
+
+    result = test_client.patch(f'/api/mult-choice/{id}', data=req2)
+    data = json.loads(result.data)
+
+    assert data['status'] == 200
+
+
+def test_delete(test_client, add_test_data):
+    req = mco_json()
+
+    response = test_client.put('/api/mult-choice/', data=req)
+    data = json.loads(response.data)
+    id = data['mult_choice_id']
+
+    response = test_client.delete(f'/api/mult-choice/{id}')
+    data = json.loads(response.data)
+
+    assert data['status'] == 200
+
+
+def test_delete_not_present(test_client, add_test_data):
+    id = 100
+
+    response = test_client.delete(f'/api/mult-choice/{id}')
+    data = json.loads(response.data)
+
+    assert data['status'] == 404
+
+
+def test_delete_finalized_exam(test_client, add_test_data):
+    mc_option_json = {
+        'x': 100,
+        'y': 40,
+        'problem_id': 2,
+        'page': 1,
+        'label': 'a',
+        'name': 'test'
+    }
+
+    response = test_client.put('/api/mult-choice/', data=mc_option_json)
+    data = json.loads(response.data)
+    mc_id = data['mult_choice_id']
+
+    response = test_client.delete(f'/api/mult-choice/{mc_id}')
+    data = json.loads(response.data)
+
+    assert data['status'] == 401
diff --git a/tests/conftest.py b/tests/conftest.py
index 0c373c16efa7c85627e2ba0efc09afa8b578987b..789157d6d71df52ade172f0aea9f5824f46adfdc 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -2,8 +2,41 @@ import os
 
 import pytest
 
+from flask import Flask
+from zesje.api import api_bp
+from zesje.database import db
+
 
 # Adapted from https://stackoverflow.com/a/46062148/1062698
 @pytest.fixture
 def datadir():
     return os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data')
+
+
+@pytest.fixture(scope="module")
+def app():
+    app = Flask(__name__, static_folder=None)
+
+    app.config.update(
+        SQLALCHEMY_DATABASE_URI='sqlite:///:memory:',
+        SQLALCHEMY_TRACK_MODIFICATIONS=False  # Suppress future deprecation warning
+    )
+    db.init_app(app)
+
+    with app.app_context():
+        db.create_all()
+
+    app.register_blueprint(api_bp, url_prefix='/api')
+
+    return app
+
+
+@pytest.fixture
+def test_client(app):
+    client = app.test_client()
+
+    yield client
+
+    with app.app_context():
+        db.drop_all()
+        db.create_all()
diff --git a/tests/test_three_corners.py b/tests/test_three_corners.py
index 1e3fb938e911061e2a5e741c619f9d86e7454a00..0994a98a87ef649fc6cb62c3a561b1979cb44eef 100644
--- a/tests/test_three_corners.py
+++ b/tests/test_three_corners.py
@@ -1,27 +1,20 @@
 import cv2
 import os
 import numpy as np
+import pytest
 
 from zesje.images import fix_corner_markers
 from zesje.scans import find_corner_marker_keypoints
 
 
-def test_three_straight_corners_1():
-    shape = (240, 200, 3)
-    corner_markers = [(50, 50), (120, 50), (50, 200)]
-
-    corner_markers = fix_corner_markers(corner_markers, shape)
-
-    assert (120, 200) in corner_markers
-
-
-def test_three_straight_corners_2():
-    shape = (240, 200, 3)
-    corner_markers = [(120, 50), (50, 200), (120, 200)]
-
-    corner_markers = fix_corner_markers(corner_markers, shape)
-
-    assert (50, 50) in corner_markers
+@pytest.mark.parametrize(
+    'shape,corners,expected',
+    [((240, 200, 3), [(50, 50), (120, 50), (50, 200)], (120, 200)),
+        ((240, 200, 3), [(120, 50), (50, 200), (120, 200)], (50, 50))],
+    ids=["", ""])
+def test_three_straight_corners(shape, corners, expected):
+    corner_markers = fix_corner_markers(corners, shape)
+    assert expected in corner_markers
 
 
 def test_pdf(datadir):
diff --git a/zesje/api/__init__.py b/zesje/api/__init__.py
index 17dfe1554eee0c8752ef1e0f5e71b713d8d150f1..513cef8c67caebaadaeaf2de695136b8e973c947 100644
--- a/zesje/api/__init__.py
+++ b/zesje/api/__init__.py
@@ -8,7 +8,7 @@ from .students import Students
 from .submissions import Submissions
 from .problems import Problems
 from .feedback import Feedback
-from .solutions import Solutions
+from .solutions import Solutions, Approve
 from .widgets import Widgets
 from .emails import EmailTemplate, RenderedEmailTemplate, Email
 from .mult_choice import MultipleChoice
@@ -50,11 +50,12 @@ api.add_resource(RenderedEmailTemplate,
 api.add_resource(Email,
                  '/email/<int:exam_id>',
                  '/email/<int:exam_id>/<int:student_id>')
+api.add_resource(Approve,
+                 '/solution/approve/<int:exam_id>/<int:submission_id>/<int:problem_id>')
 api.add_resource(MultipleChoice,
                  '/mult-choice/<int:id>',
                  '/mult-choice/')
 
-
 # Other resources that don't return JSON
 # It is possible to get flask_restful to work with these, but not
 # very idiomatic.
diff --git a/zesje/api/exams.py b/zesje/api/exams.py
index 83dd18b52229ab84363cd29a877c4cb832c34f31..c82da7a602aca76694a107635f4384ab2019e014 100644
--- a/zesje/api/exams.py
+++ b/zesje/api/exams.py
@@ -9,7 +9,8 @@ from flask_restful import Resource, reqparse
 from werkzeug.datastructures import FileStorage
 from sqlalchemy.orm import selectinload
 
-from ..pdf_generation import PAGE_FORMATS, generate_pdfs, output_pdf_filename_format, join_pdfs, page_is_size
+from ..pdf_generation import generate_pdfs, output_pdf_filename_format, join_pdfs, page_is_size, make_pages_even
+from ..pdf_generation import PAGE_FORMATS
 from ..database import db, Exam, ExamWidget, Submission
 
 
@@ -280,10 +281,9 @@ class Exams(Resource):
 
         exam_dir = _get_exam_dir(exam.id)
         pdf_path = os.path.join(exam_dir, 'exam.pdf')
-
         os.makedirs(exam_dir, exist_ok=True)
 
-        pdf_data.save(pdf_path)
+        make_pages_even(pdf_path, args['pdf'])
 
         print(f"Added exam {exam.id} (name: {exam_name}, token: {exam.token}) to database")
 
diff --git a/zesje/api/mult_choice.py b/zesje/api/mult_choice.py
index 29eaa61dfa5363f18a0a7afb91d78893da1a678d..fafed9c85b3265c9cab607bf780e762092f1fce0 100644
--- a/zesje/api/mult_choice.py
+++ b/zesje/api/mult_choice.py
@@ -34,23 +34,17 @@ class MultipleChoice(Resource):
     put_parser.add_argument('x', type=int, required=True)
     put_parser.add_argument('y', type=int, required=True)
     put_parser.add_argument('label', type=str, required=False)
+    put_parser.add_argument('fb_description', type=str, required=False)
+    put_parser.add_argument('fb_score', type=str, required=False)
     put_parser.add_argument('problem_id', type=int, required=True)  # Used for FeedbackOption
 
-    def put(self, id=None):
-        """Adds or updates a multiple choice option to the database
-
-        If the parameter id is not present, a new multiple choice question
-        will be inserted with the data provided in the request body.
+    def put(self):
+        """Adds a multiple choice option to the database
 
         For each new multiple choice option, a feedback option that links to
         the multiple choice option is inserted into the database. The new
         feedback option also refers to same problem as the MultipleChoiceOption
-
-        Parameters
-        ----------
-            id: The id of the multiple choice option
         """
-
         args = self.put_parser.parse_args()
 
         # Get request arguments
@@ -58,38 +52,28 @@ class MultipleChoice(Resource):
         x = args['x']
         y = args['y']
         label = args['label']
+        fb_description = args['fb_description']
+        fb_score = args['fb_score']
         problem_id = args['problem_id']
 
-        # TODO: Set type here or add to request?
         mc_type = 'mcq_widget'
 
-        if not id:
-            # Insert new empty feedback option that links to the same problem, with the label as name
-            new_feedback_option = FeedbackOption(problem_id=problem_id, text=label)
-            db.session.add(new_feedback_option)
-            db.session.commit()
-
-            # Insert new entry into the database
-            mc_entry = MultipleChoiceOption()
-            set_mc_data(mc_entry, name, x, y, mc_type, new_feedback_option.id, label)
-
-            db.session.add(mc_entry)
-            db.session.commit()
-
-            return dict(status=200, mult_choice_id=mc_entry.id, feedback_id=new_feedback_option.id,
-                        message=f'New multiple choice question with id {mc_entry.id} inserted. '
-                        + f'New feedback option with id {new_feedback_option.id} inserted.'), 200
-
-        # Update existing entry otherwise
-        mc_entry = MultipleChoiceOption.query.get(id)
+        # Insert new empty feedback option that links to the same problem
+        new_feedback_option = FeedbackOption(problem_id=problem_id, text=label,
+                                             description=fb_description, score=fb_score)
+        db.session.add(new_feedback_option)
+        db.session.commit()
 
-        if not mc_entry:
-            return dict(status=404, message=f"Multiple choice question with id {id} does not exist"), 404
+        # Insert new entry into the database
+        mc_entry = MultipleChoiceOption()
+        set_mc_data(mc_entry, name, x, y, mc_type, new_feedback_option.id, label)
 
-        set_mc_data(mc_entry, name, x, y, mc_type, label)
+        db.session.add(mc_entry)
         db.session.commit()
 
-        return dict(status=200, message=f'Multiple choice question with id {id} updated'), 200
+        return dict(status=200, mult_choice_id=mc_entry.id, feedback_id=new_feedback_option.id,
+                    message=f'New multiple choice question with id {mc_entry.id} inserted. '
+                            + f'New feedback option with id {new_feedback_option.id} inserted.'), 200
 
     def get(self, id):
         """Fetches multiple choice option from the database
@@ -122,6 +106,32 @@ class MultipleChoice(Resource):
 
         return json
 
+    def patch(self, id):
+        """
+        Updates a multiple choice option
+
+        Parameters
+        ----------
+            id: The id of the multiple choice option in the database.s
+        """
+        args = self.put_parser.parse_args()
+
+        name = args['name']
+        x = args['x']
+        y = args['y']
+        label = args['label']
+        mc_type = 'mcq_widget'
+
+        mc_entry = MultipleChoiceOption.query.get(id)
+
+        if not mc_entry:
+            return dict(status=404, message=f"Multiple choice question with id {id} does not exist"), 404
+
+        set_mc_data(mc_entry, name, x, y, mc_type, mc_entry.feedback_id, label)
+        db.session.commit()
+
+        return dict(status=200, message=f'Multiple choice question with id {id} updated'), 200
+
     def delete(self, id):
         """Deletes a multiple choice option from the database.
         Also deletes the associated feedback option with this multiple choice option.
@@ -157,5 +167,6 @@ class MultipleChoice(Resource):
         db.session.delete(mult_choice.feedback)
         db.session.commit()
 
-        return dict(status=200, message=f'Multiple choice question with id {id} deleted.'
+        return dict(status=200, mult_choice_id=id, feedback_id=mult_choice.feedback_id,
+                    message=f'Multiple choice question with id {id} deleted.'
                     + f'Feedback option with id {mult_choice.feedback_id} deleted.'), 200
diff --git a/zesje/api/solutions.py b/zesje/api/solutions.py
index 8001d52994905f0f5b7d5b2504895a6845d35907..2e41beae2297e99e2adabc2c8d8c053cb2d96707 100644
--- a/zesje/api/solutions.py
+++ b/zesje/api/solutions.py
@@ -147,3 +147,43 @@ class Solutions(Resource):
         db.session.commit()
 
         return {'state': state}
+
+
+class Approve(Resource):
+    """ add just a grader to a specifc problem on an exam """
+    put_parser = reqparse.RequestParser()
+    put_parser.add_argument('graderID', type=int, required=True)
+
+    def put(self, exam_id, submission_id, problem_id):
+        """Takes an existing feedback checks if it is valid then gives the current graders id to the solution this is
+        usefull for approving pre graded solutions
+
+        Parameters
+        ----------
+            graderID: int
+
+        Returns
+        -------
+            state: boolean
+        """
+        args = self.put_parser.parse_args()
+
+        grader = Grader.query.get(args.graderID)
+
+        sub = Submission.query.filter(Submission.exam_id == exam_id,
+                                      Submission.copy_number == submission_id).one_or_none()
+        if sub is None:
+            return dict(status=404, message='Submission does not exist.'), 404
+
+        solution = Solution.query.filter(Solution.submission_id == sub.id,
+                                         Solution.problem_id == problem_id).one_or_none()
+        if solution is None:
+            return dict(status=404, message='Solution does not exist.'), 404
+
+        graded = len(solution.feedback)
+
+        if graded:
+            solution.graded_at = datetime.now()
+            solution.graded_by = grader
+
+        return {'state': graded}
diff --git a/zesje/pdf_generation.py b/zesje/pdf_generation.py
index e4b3c2ece43bfb237c09cdfc05f2bca60507c336..083d73f7b29fcfe882197714bf157b9795c43e39 100644
--- a/zesje/pdf_generation.py
+++ b/zesje/pdf_generation.py
@@ -402,3 +402,19 @@ def page_is_size(exam_pdf_file, shape, tolerance=0):
         pass
 
     return not invalid
+
+
+def make_pages_even(output_filename, exam_pdf_file):
+    exam_pdf = PdfReader(exam_pdf_file)
+    new = PdfWriter()
+    new.addpages(exam_pdf.pages)
+    pagecount = len(exam_pdf.pages)
+
+    if (pagecount % 2 == 1):
+        blank = PageMerge()
+        box = exam_pdf.pages[0].MediaBox
+        blank.mbox = box
+        blank = blank.render()
+        new.addpage(blank)
+
+    new.write(output_filename)
diff --git a/zesje/statistics.py b/zesje/statistics.py
index a2382447d4c1d3faf8820a5d7bcf4571c9348634..ff74c4e6e9ee3a274e0d3cda0c3d29a609af5093 100644
--- a/zesje/statistics.py
+++ b/zesje/statistics.py
@@ -5,7 +5,7 @@ from sqlalchemy.orm.exc import NoResultFound
 import numpy as np
 import pandas
 
-from .database import Exam, Problem, Student
+from .database import Exam, Student
 
 
 def solution_data(exam_id, student_id):
@@ -68,7 +68,7 @@ def full_exam_data(exam_id):
     if not data:
         # No students were assigned.
         columns = []
-        for problem in exam.problems.order_by(Problem.id):
+        for problem in exam.problems:  # Sorted by problem.id
             if not len(problem.feedback_options):
                 # There is no possible feedback for this problem.
                 continue