diff --git a/quizfileupload.classes.inc b/quizfileupload.classes.inc
old mode 100755
new mode 100644
index 2982041..d2c1917
--- a/quizfileupload.classes.inc
+++ b/quizfileupload.classes.inc
@@ -2,10 +2,9 @@
 
 
 /**
- * The main classes for the multichoice question type.
+ * The main classes for the quizfileupload question type.
  *
  * These inherit or implement code found in quiz_question.classes.inc.
- * Code: LogicMedia
  *
  * Based on:
  * Other question types in the quiz framework.
@@ -13,7 +12,6 @@
  *
  *
  * @file
- * Question type, enabling the creation of multiple choice and multiple answer questions.
  */
 
 /**
@@ -21,15 +19,15 @@
  */
 class QuizfileuploadQuestion extends QuizQuestion {
 
-   /**
-   * Implementation of save
-   *
-   * Stores the question in the database.
+  // Constants for answer matching options
+  const ANSWER_MATCH = 0;
+  const ANSWER_MANUAL = 1;
+
+  /**
+   * Implementation of saveNodeProperties
    *
-   * @param is_new if - if the node is a new node...
-   * (non-PHPdoc)
-   * @see sites/all/modules/quiz-HEAD/question_types/quiz_question/QuizQuestion#save()
-    */
+   * @see QuizQuestion#saveNodeProperties($is_new)
+   */
   public function saveNodeProperties($is_new = FALSE) {
     $is_new = $is_new || $this->node->revision == 1;
     if ($is_new) {
@@ -38,23 +36,26 @@ class QuizfileuploadQuestion extends QuizQuestion {
           'nid' => $this->node->nid,
           'vid' => $this->node->vid,
           'filetypes' => $this->node->filetypes,
+          'correct_answer_evaluation' => $this->node->correct_answer_evaluation,
         ))
         ->execute();
     }
     else {
       db_update('quiz_fileupload_node_properties')
-        ->fields(array('filetypes' => $this->node->filetypes))
+        ->fields(array(
+          'filetypes' => $this->node->filetypes,
+          'correct_answer_evaluation' => $this->node->correct_answer_evaluation,
+        ))
         ->condition('nid', $this->node->nid)
         ->condition('vid', $this->node->vid)
         ->execute();
     }
-
   }
 
   /**
-   * Implementation of validate
+   * Implementation of validateNode
    *
-   * QuizQuestion#validate()
+   * @see QuizQuestion#validateNode($form)
    */
   public function validateNode(array &$form) {
     //no validation required
@@ -63,7 +64,7 @@ class QuizfileuploadQuestion extends QuizQuestion {
   /**
    * Implementation of delete
    *
-   * @see QuizQuestion#delete()
+   * @see QuizQuestion#delete($only_this_version)
    */
   public function delete($only_this_version = FALSE) {
     if ($only_this_version) {
@@ -99,10 +100,11 @@ class QuizfileuploadQuestion extends QuizQuestion {
     $props = parent::getNodeProperties();
 
     // Load the properties
-    $res_a = db_query('SELECT filetypes FROM {quiz_fileupload_node_properties} WHERE nid = :nid AND vid = :vid',
+    $res_a = db_query('SELECT filetypes, correct_answer_evaluation FROM {quiz_fileupload_node_properties} WHERE nid = :nid AND vid = :vid',
       array(
-        ':nid' => $this->node->nid ,
-        ':vid' => $this->node->vid))->fetchAssoc();
+        ':nid' => $this->node->nid,
+        ':vid' => $this->node->vid
+      ))->fetchAssoc();
 
     if (is_array($res_a)) {
       $props = array_merge($props, $res_a);
@@ -126,18 +128,20 @@ class QuizfileuploadQuestion extends QuizQuestion {
   }
 
   /**
-   * Generates the question form.
+   * Implementation of getAnsweringForm
    *
-   * This is called whenever a question is rendered, either
-   * to an administrator or to a quiz taker.
+   * @see QuizQuestion#getAnsweringForm($form_state, $rid)
    */
   public function getAnsweringForm(array $form_state = NULL, $rid) {
     $form = parent::getAnsweringForm($form_state, $rid);
-
     $fid = db_query('SELECT qf.fid
       FROM {quiz_fileupload_user_answers} qf
       WHERE question_nid = :nid AND question_vid = :vid AND result_id = :result_id',
-      array(':nid' => $this->node->nid, ':vid' => $this->node->vid,  ':result_id' => $rid))
+      array(
+        ':nid' => $this->node->nid,
+        ':vid' => $this->node->vid,
+        ':result_id' => $rid
+      ))
       ->fetchField();
 
     if (is_numeric($fid)) {
@@ -159,7 +163,7 @@ class QuizfileuploadQuestion extends QuizQuestion {
   /**
    * Implementation of getCreationForm
    *
-   * @see QuizQuestion#getCreationForm()
+   * @see QuizQuestion#getCreationForm($form_state)
    */
   public function getCreationForm(array &$form_state = NULL) {
     $allowed = variable_get('quizfileupload_default_extensions', QUIZFILEUPLOAD_DEFAULT_EXTENSIONS);
@@ -170,6 +174,21 @@ class QuizfileuploadQuestion extends QuizQuestion {
       '#default_value' => isset($this->node->filetypes) ? $this->node->filetypes : $allowed,
       '#required' => TRUE,
     );
+
+    $options = array(
+      self::ANSWER_MATCH => t('Automatic'),
+      self::ANSWER_MANUAL => t('Manual'),
+    );
+
+    $form['correct_answer_evaluation'] = array(
+      '#type' => 'radios',
+      '#title' => t('Pick an evaluation method'),
+      '#description' => t('Choose how the answer shall be evaluated.'),
+      '#options' => $options,
+      '#default_value' => isset($this->node->correct_answer_evaluation) ? $this->node->correct_answer_evaluation : self::ANSWER_MATCH,
+      '#required' => TRUE,
+    );
+
     return $form;
   }
 
@@ -188,40 +207,47 @@ class QuizfileuploadQuestion extends QuizQuestion {
  * Extension of QuizQuestionResponse
  */
 class QuizfileuploadResponse extends QuizQuestionResponse {
+
   /**
    * ID of the answer.
    */
   protected $answer_id = 0;
+  protected $file = NULL;
 
   /**
    * Constructor
    */
   public function __construct($result_id, stdClass $question_node, $tries = NULL) {
     parent::__construct($result_id, $question_node, $tries);
-
     $tries = $_FILES;
     $this->answer = $tries;
+    $this->answer_feedback = "";
     if (!isset($result) || !is_object($result)) {
       $result = new stdClass;
     }
     $result->is_correct = TRUE;
-    $this->question->score_weight = 0;
-    $this->evaluated = TRUE;
+    $this->evaluated = 0;
+    $response = $this->getResponse();
+    if (isset($question_node->correct_answer_evaluation)) {
+      if ($question_node->correct_answer_evaluation == 0) {
+        $this->evaluated = 1;
+      }
+    }
     $this->result_id = $result_id;
-
     // Question has been answered allready. We fetch the answer data from the database.
     $r = db_query('SELECT * FROM {quiz_fileupload_user_answers}
     WHERE question_nid = :question_nid AND question_vid = :question_vid AND result_id = :result_id',
-    array(
-      ':question_nid' => $question_node->nid,
-      ':question_vid' => $question_node->vid,
-      ':result_id' => $result_id))->fetchAssoc();
+      array(
+        ':question_nid' => $question_node->nid,
+        ':question_vid' => $question_node->vid,
+        ':result_id' => $result_id
+      ))->fetchAssoc();
     if (is_array($r)) {
       $this->score = $r['score'];
       $this->answer_id = $r['answer_id'];
-    }
-    else {
-      $this->score = variable_get('quizfileupload_default_score', 1);
+      $this->evaluated = $r['is_evaluated'];
+      $this->answer_feedback = $r['answer_feedback'];
+      $this->answer_feedback_format = $r['answer_feedback_format'];
     }
   }
 
@@ -231,7 +257,12 @@ class QuizfileuploadResponse extends QuizQuestionResponse {
    * @see QuizQuestionResponse#isValid()
    */
   public function isValid() {
-    return TRUE;
+    if (isset($this->file->fid)) {
+      return TRUE;
+    }
+    else {
+      return "";
+    }
   }
 
   /**
@@ -240,19 +271,28 @@ class QuizfileuploadResponse extends QuizQuestionResponse {
    * @see QuizQuestionResponse#save()
    */
   public function save() {
-    $file = file_save_upload('tries', array(), 'public://');
-    $this->file->status = FILE_STATUS_PERMANENT;
-    file_save($this->file);
-
-    $this->answer_id = db_insert('quiz_fileupload_user_answers')
-      ->fields(array(
-        'result_id' => $this->rid,
-        'question_vid' => $this->question->vid,
-        'question_nid' => $this->question->nid,
-        'fid' => $file->fid,
-        'score' => $this->score(),
-      ))
-      ->execute();
+    $validator = array(
+      'file_validate_extensions' => array($this->question->filetypes),
+    );
+    $directory = 'public://quizfileupload/' . $this->question->nid . '/';
+    file_prepare_directory($directory, FILE_CREATE_DIRECTORY);
+    $this->file = file_save_upload('tries', $validator, $directory);
+    if (isset($this->file->fid)) {
+      $this->answer_id = db_insert('quiz_fileupload_user_answers')
+        ->fields(array(
+          'result_id' => $this->rid,
+          'question_vid' => $this->question->vid,
+          'question_nid' => $this->question->nid,
+          'fid' => $this->file->fid,
+          'score' => $this->getScore(FALSE),
+          'is_evaluated' => $this->evaluated,
+          'answer_feedback' => $this->answer_feedback,
+        ))
+        ->execute();
+
+      $this->file->status = FILE_STATUS_PERMANENT;
+      file_save($this->file);
+    }
   }
 
   /**
@@ -271,19 +311,28 @@ class QuizfileuploadResponse extends QuizQuestionResponse {
   /**
    * Implementation of score
    *
-   * @return uint
-   *
    * @see QuizQuestionResponse#score()
    */
   public function score() {
-    return variable_get('quizfileupload_default_score', 0);
+    if ($this->question->correct_answer_evaluation == 1) {
+      $score = db_query('SELECT score FROM {quiz_fileupload_user_answers} WHERE result_id = :result_id AND question_vid = :question_vid', array(
+        ':result_id' => $this->rid,
+        ':question_vid' => $this->question->vid
+      ))->fetchField();
+      if (!$score) {
+        $score = 0;
+      }
+    }
+    else {
+      $shortAnswer = new QuizfileuploadQuestion($this->question);
+      $score = $shortAnswer->getMaximumScore();
+    }
+    return $score;
   }
 
   /**
    * Implementation of getResponse
    *
-   * @return answer
-   *
    * @see QuizQuestionResponse#getResponse()
    */
   public function getResponse() {
@@ -304,15 +353,97 @@ class QuizfileuploadResponse extends QuizQuestionResponse {
       array(
         ':result_id' => $result_id,
         ':question_nid' => $this->question->nid,
-        ':question_vid' => $this->question->vid))
-        ->fetchField();
-
+        ':question_vid' => $this->question->vid
+      ))
+      ->fetchField();
     $markup = quiz_file_markup($fid);
+    if ($this->question && !empty($this->question->answers)) {
+      $answer = (object) current($this->question->answers);
+    }
 
-    return array(
-      '#type' => 'markup',
-      '#markup' => $markup
-    );
+    $form['fileupload'] = array('#markup' => $markup);
+    if ($answer->is_evaluated == 1) {
+      // Show feedback, if any.
+      $form['answer_feedback'] = array(
+        '#title' => t('Feedback'),
+        '#type' => 'item',
+        '#markup' => '<span class="quiz_answer_feedback">' . $this->answer_feedback . '</span>',
+      );
+    }
+    else {
+      $feedback = t('This answer has not yet been scored.') .
+        '<br/>' .
+        t('Until the answer is scored, the total score will not be correct.');
+    }
+    return $form;
+  }
+
+  /**
+   * Implementation of getReportFormScore
+   *
+   * @see QuizQuestionResponse#getReportFormScore($showpoints, $showfeedback, $allow_scoring)
+   */
+  public function getReportFormScore($showfeedback = TRUE, $showpoints = TRUE, $allow_scoring = FALSE) {
+    $node = node_load($this->question->nid);
+    $score = ($this->isEvaluated()) ? $this->getScore() : '?';
+    if (quiz_access_to_score() && $allow_scoring && ($node->correct_answer_evaluation == 1)) {
+      return array(
+        '#type' => 'textfield',
+        '#default_value' => $score,
+        '#size' => 3,
+        '#maxlength' => 3,
+        '#attributes' => array('class' => array('quiz-report-score')),
+      );
+    }
+    else {
+      return array(
+        '#markup' => $score,
+      );
+    }
+  }
+
+
+  public function getReportFormAnswerFeedback($showpoints = TRUE, $showfeedback = TRUE, $allow_scoring = FALSE) {
+    if (quiz_access_to_score() && $allow_scoring) {
+      return array(
+        '#title' => t('Enter feedback'),
+        '#type' => 'text_format',
+        '#default_value' => $this->answer_feedback,
+        '#format' => isset($this->answer_feedback_format) ? $this->answer_feedback_format : NULL,
+        '#attributes' => array('class' => array('quiz-report-score')),
+      );
+    }
+    return FALSE;
+  }
+
+  /**
+   * Implementation of getReportFormSubmit
+   *
+   * @see QuizQuestionResponse#getReportFormSubmit($showfeedback, $showpoints, $allow_scoring)
+   */
+  public function getReportFormSubmit($showfeedback = TRUE, $showpoints = TRUE, $allow_scoring = FALSE) {
+    $node = node_load($this->question->nid);
+    if (isset($node->correct_answer_evaluation)) {
+      if (quiz_access_to_score() && $allow_scoring && ($node->correct_answer_evaluation == 1)) {
+        return $allow_scoring ? 'quizfileupload_report_submit' : FALSE;
+      }
+    }
+    return FALSE;
+  }
+
+  /**
+   * Implementation of getReportFormValidate
+   *
+   * @see QuizQuestionResponse#getReportFormValidate($showfeedback, $showpoints, $allow_scoring)
+   */
+  public function getReportFormValidate($showfeedback = TRUE, $showpoints = TRUE, $allow_scoring = FALSE) {
+    $node = node_load($this->question->nid);
+    if (isset($node->correct_answer_evaluation)) {
+      if (quiz_access_to_score() && $allow_scoring && ($node->correct_answer_evaluation == 1)) {
+        return $allow_scoring ? 'quizfileupload_report_validate' : FALSE;
+      }
+    }
+    return FALSE;
   }
 }
 
@@ -325,7 +456,7 @@ function quiz_file_markup($fid) {
 
     // not image
     if (count($errors)) {
-      return l($file->filename , file_create_url($file->uri));
+      return l($file->filename, file_create_url($file->uri));
     }
     // image, we use thumbnail
     else {
diff --git a/quizfileupload.install b/quizfileupload.install
index be72fc2..e56a767 100644
--- a/quizfileupload.install
+++ b/quizfileupload.install
@@ -1,10 +1,8 @@
 <?php
 
 /**
- * Code: logicmedia
- *
+ * The installer file for quizfileupload.
  * @file
- * quizfileupload Install (a quiz question type)
  */
 
 
@@ -12,7 +10,7 @@
  * Implementation of hook_install()
  */
 function quizfileupload_install() {
-  // Add body field to long answer node
+  // Add body field to quizfileupload node
   quiz_question_add_body_field('quizfileupload');
 
   cache_clear_all('autoload:', 'cache');
@@ -31,6 +29,13 @@ function quizfileupload_schema() {
         'unsigned' => TRUE,
         'not null' => TRUE,
       ),
+      'is_evaluated' => array(
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
       'result_id' => array(
         'type' => 'int',
         'unsigned' => TRUE,
@@ -57,7 +62,13 @@ function quizfileupload_schema() {
         'unsigned' => TRUE,
         'not null' => TRUE,
       ),
-
+      'answer_feedback' => array(
+        'type' => 'text'
+      ),
+      'answer_feedback_format' => array(
+        'type' => 'varchar',
+        'length' => 255,
+      ),
     ),
     'primary key' => array('answer_id'),
     'indexes' => array(
@@ -80,6 +91,13 @@ function quizfileupload_schema() {
       'filetypes' => array(
         'type' => 'text',
       ),
+      'correct_answer_evaluation' => array(
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'default' => 0,
+      ),
     ),
     'primary key' => array(
       'nid', 'vid'
@@ -95,3 +113,80 @@ function quizfileupload_uninstall() {
   cache_clear_all('variables', 'cache'); 
   drupal_set_message(t('The quiz file upload module has been uninstalled. Quiz file upload nodes may still exist, but they will not function properly.'));
 }
+
+
+/**
+ * Fixes the data structure for users with the original #2092275 patch
+ */
+function quizfileupload_update_7001() {
+  $instance = field_info_instance('node', 'quizfileupload_scoring', 'quizfileupload');
+  if ($instance) {
+    field_delete_instance ($instance, TRUE);
+  }
+
+  if (db_field_exists('quiz_fileupload_user_answers', 'is_evaluated')) {
+    $spec = array(
+      'type' => 'int',
+      'unsigned' => TRUE,
+      'size' => 'tiny',
+      'not null' => TRUE,
+      'default' => 0,
+    );
+    db_change_field('quiz_fileupload_user_answers', 'is_evaluated', 'is_evaluated', $spec);
+  }
+
+  if (db_field_exists('quiz_fileupload_node_properties', 'type')) {
+    $spec = array(
+      'type' => 'int',
+      'unsigned' => TRUE,
+      'size' => 'tiny',
+      'not null' => TRUE,
+      'default' => 0,
+    );
+    db_change_field('quiz_fileupload_node_properties', 'type', 'correct_answer_evaluation', $spec);
+  }
+}
+
+
+/**
+ * Add the option to manually score the question.
+ */
+function quizfileupload_update_7002() {
+  // Add the required fields to the database.
+  if (!db_field_exists('quiz_fileupload_node_properties', 'correct_answer_evaluation')) {
+    $spec = array(
+      'type' => 'int',
+      'unsigned' => TRUE,
+      'size' => 'tiny',
+      'not null' => TRUE,
+      'default' => 0,
+    );
+    db_add_field('quiz_fileupload_node_properties', 'correct_answer_evaluation', $spec);
+  }
+
+  if (!db_field_exists('quiz_fileupload_user_answers', 'is_evaluated')) {
+    $spec = array(
+      'type' => 'int',
+      'unsigned' => TRUE,
+      'size' => 'tiny',
+      'not null' => TRUE,
+      'default' => 0,
+    );
+    db_add_field('quiz_fileupload_user_answers', 'is_evaluated', $spec);
+  }
+
+  if (!db_field_exists('quiz_fileupload_user_answers', 'answer_feedback')) {
+    $spec = array(
+      'type' => 'text'
+    );
+    db_add_field('quiz_fileupload_user_answers', 'answer_feedback', $spec);
+  }
+
+  if (!db_field_exists('quiz_fileupload_user_answers', 'answer_feedback_format')) {
+    $spec = array(
+      'type' => 'varchar',
+      'length' => 255,
+    );
+    db_add_field('quiz_fileupload_user_answers', 'answer_feedback_format', $spec);
+  }
+}
\ No newline at end of file
diff --git a/quizfileupload.module b/quizfileupload.module
index b4d9883..f30c96e 100644
--- a/quizfileupload.module
+++ b/quizfileupload.module
@@ -3,16 +3,12 @@
 /**
  * The main file for quizfileupload.
  *
- * Code: logicmedia
- *
  * @file
- * Quizfileupload question type for the Quiz module.
- *
  */
 
 /**
  * define default allowed extensions
- */ 
+ */
 define('QUIZFILEUPLOAD_DEFAULT_EXTENSIONS', 'png pdf odf doc docx');
 
 /**
@@ -45,7 +41,7 @@ function quizfileupload_config() {
     '#title' => t('Default score'),
     '#required' => TRUE,
     '#default_value' => variable_get('quizfileupload_default_score', 1),
-  );  
+  );
   $form['quizfileupload_default_extensions'] = array(
     '#type' => 'textarea',
     '#title' => t('Allowed extension'),
@@ -56,16 +52,120 @@ function quizfileupload_config() {
   return $form;
 }
 
-
 /**
  * Fork of file_validate_extensions().
- */ 
+ */
 function quizfileupload_validate_extensions($file, $extensions) {
   $errors = array();
-
   $regex = '/\.(' . preg_replace('/ +/', '|', preg_quote($extensions)) . ')$/i';
   if (!preg_match($regex, $file->filename)) {
     $errors[] = t('Only files with the following extensions are allowed: %files-allowed.', array('%files-allowed' => $extensions));
   }
   return $errors;
 }
+
+/**
+ * Validate the result report for short answer
+ */
+function quizfileupload_report_validate($values, $form_key) {
+  // Check to make sure that entered score is not higher than max allowed score.
+  if (!_quiz_is_int($values['score'], 0, (int) $values['max_score'])) {
+    form_set_error($form_key . '][score', t('The score needs to be a number between 0 and @max', array('@max' => (int) $values['max_score'])));
+  }
+}
+
+/**
+ * Submit the result report for short answer
+ */
+function quizfileupload_report_submit($values) {
+  quizfileupload_score_an_answer($values, FALSE);
+}
+
+function quizfileupload_score_an_answer($values, $update_total = TRUE) {
+  extract($values);
+  // When we set the score we make sure that the max score in the quiz the question belongs to is considered
+  $question_max_score = db_query('SELECT max_score FROM {quiz_question_properties} WHERE nid = :nid AND vid = :vid', array(
+    ':nid' => $nid,
+    ':vid' => $vid
+  ))->FetchField();
+
+  $quiz_max_score = db_query('SELECT max_score FROM {quiz_node_relationship} WHERE parent_vid = :pvid AND child_vid = :cvid', array(
+    ':pvid' => $quiz->vid,
+    ':cvid' => $vid
+  ))->fetchField();
+
+  $db_update_fields = array(
+    'score' => $score * $question_max_score / $quiz_max_score,
+    'is_evaluated' => 1,
+  );
+
+  if (isset($answer_feedback)) {
+    $db_update_fields['answer_feedback'] = empty($answer_feedback['value']) ? '' : $answer_feedback['value'];
+    $db_update_fields['answer_feedback_format'] = $answer_feedback['format'];
+  }
+
+  $changed = db_update('quiz_fileupload_user_answers')
+    ->fields($db_update_fields)
+    ->condition('question_nid', $nid)
+    ->condition('question_vid', $vid)
+    ->condition('result_id', $rid)
+    ->execute();
+  // Now the short answer user data has been updated. We also need to update the data in the quiz tables
+  if ($changed > 0) {
+    $max = db_query('SELECT max_score FROM {quiz_question_properties} WHERE vid = :vid', array(':vid' => $vid))->fetchField();
+    if ($max <= 0) {
+      $is_correct = 0;
+      $points_awarded = 0;
+    }
+    else {
+      $is_correct = ($score / $max > 0.5) ? 1 : 0;
+      $points_awarded = $score;
+    }
+
+    db_update('quiz_node_results_answers')
+      ->fields(array(
+        'points_awarded' => $points_awarded,
+        'is_correct' => $is_correct,
+      ))
+      ->condition('question_vid', $vid)
+      ->condition('result_id', $rid)
+      ->execute();
+
+    // Third, we update the main quiz results table
+    if ($update_total) {
+      quiz_update_total_score($quiz, $rid);
+    }
+  }
+  return $changed;
+}
+
+
+
+/**
+ * Implements hook_stream_wrappers().
+ */
+function quizfileupload_stream_wrappers() {
+  return array(
+    'quizfile' => array(
+      'name' => t('Quizfile folder'),
+      'class' => 'QuizFileStreamWrapper',
+      'description' => t('Provides a seperate folder for Quiz Files.'),
+      'type' => STREAM_WRAPPERS_LOCAL_NORMAL,
+    ),
+  );
+}
+
+
+
+/**
+ * Path to Quizfiles streamwrapper
+ */
+class QuizFileStreamWrapper extends DrupalPrivateStreamWrapper {
+  public function getDirectoryPath() {
+    return 'sites/default/quizfiles';
+  }
+  public function getExternalUrl() {
+    $path = str_replace('\\', '/', $this->getTarget());
+    return $GLOBALS['base_url'] . '/' . self::getDirectoryPath() . '/' . drupal_encode_path($path);
+  }
+}
\ No newline at end of file
