diff --git a/includes/views/defaults/quiz_results.view.inc b/includes/views/defaults/quiz_results.view.inc
index c0a6ced..68ed588 100644
--- a/includes/views/defaults/quiz_results.view.inc
+++ b/includes/views/defaults/quiz_results.view.inc
@@ -167,6 +167,63 @@ $handler->display->display_options['menu']['context_only_inline'] = 0;
 $handler->display->display_options['tab_options']['type'] = 'tab';
 $handler->display->display_options['tab_options']['title'] = 'Quiz';
 $handler->display->display_options['tab_options']['weight'] = '0';
+
+/* Display: Data export */
+$handler = $view->new_display('views_data_export', 'Data export', 'views_data_export_1');
+$handler->display->display_options['pager']['type'] = 'none';
+$handler->display->display_options['pager']['options']['offset'] = '0';
+$handler->display->display_options['style_plugin'] = 'views_data_export_csv';
+$handler->display->display_options['defaults']['fields'] = FALSE;
+/* Field: User: Name */
+$handler->display->display_options['fields']['name']['id'] = 'name';
+$handler->display->display_options['fields']['name']['table'] = 'users';
+$handler->display->display_options['fields']['name']['field'] = 'name';
+$handler->display->display_options['fields']['name']['relationship'] = 'uid';
+$handler->display->display_options['fields']['name']['label'] = 'Username';
+$handler->display->display_options['fields']['name']['link_to_user'] = FALSE;
+/* Field: Quiz result: Date started */
+$handler->display->display_options['fields']['time_start']['id'] = 'time_start';
+$handler->display->display_options['fields']['time_start']['table'] = 'quiz_node_results';
+$handler->display->display_options['fields']['time_start']['field'] = 'time_start';
+$handler->display->display_options['fields']['time_start']['date_format'] = 'short';
+/* Field: Quiz result: Date finished */
+$handler->display->display_options['fields']['time_end']['id'] = 'time_end';
+$handler->display->display_options['fields']['time_end']['table'] = 'quiz_node_results';
+$handler->display->display_options['fields']['time_end']['field'] = 'time_end';
+$handler->display->display_options['fields']['time_end']['date_format'] = 'short';
+/* Field: Quiz result: Score */
+$handler->display->display_options['fields']['score']['id'] = 'score';
+$handler->display->display_options['fields']['score']['table'] = 'quiz_node_results';
+$handler->display->display_options['fields']['score']['field'] = 'score';
+/* Field: Quiz result: Evaluated */
+$handler->display->display_options['fields']['is_evaluated']['id'] = 'is_evaluated';
+$handler->display->display_options['fields']['is_evaluated']['table'] = 'quiz_node_results';
+$handler->display->display_options['fields']['is_evaluated']['field'] = 'is_evaluated';
+$handler->display->display_options['fields']['is_evaluated']['not'] = 0;
+/* Field: Quiz result: Nid */
+$handler->display->display_options['fields']['nid']['id'] = 'nid';
+$handler->display->display_options['fields']['nid']['table'] = 'quiz_node_results';
+$handler->display->display_options['fields']['nid']['field'] = 'nid';
+$handler->display->display_options['fields']['nid']['exclude'] = TRUE;
+$handler->display->display_options['fields']['nid']['separator'] = '';
+/* Field: Quiz result: Quiz result ID */
+$handler->display->display_options['fields']['result_id']['id'] = 'result_id';
+$handler->display->display_options['fields']['result_id']['table'] = 'quiz_node_results';
+$handler->display->display_options['fields']['result_id']['field'] = 'result_id';
+$handler->display->display_options['fields']['result_id']['exclude'] = TRUE;
+$handler->display->display_options['fields']['result_id']['separator'] = '';
+/* Field: Quiz result: Answers */
+$handler->display->display_options['fields']['answers']['id'] = 'answers';
+$handler->display->display_options['fields']['answers']['table'] = 'quiz_node_results';
+$handler->display->display_options['fields']['answers']['field'] = 'answers';
+$handler->display->display_options['path'] = 'node/%/quiz/results';
+$handler->display->display_options['displays'] = array(
+  'page' => 'page',
+  'default' => 0,
+);
+$handler->display->display_options['use_batch'] = 'batch';
+$handler->display->display_options['segment_size'] = '100';
+
 $translatables['quiz_results'] = array(
   t('Master'),
   t('Quiz results'),
diff --git a/includes/views/handlers/quiz_views_handler_argument_quiz_nid.inc b/includes/views/handlers/quiz_views_handler_argument_quiz_nid.inc
deleted file mode 100644
index 179e4a1..0000000
--- a/includes/views/handlers/quiz_views_handler_argument_quiz_nid.inc
+++ /dev/null
@@ -1,158 +0,0 @@
-<?php
-
-/*
- * @file
- * Handles argument quiz nid.
- */
-
-class quiz_views_handler_argument_quiz_nid extends views_handler_argument_numeric {
-  /**
-   * An array that the subselect will fill with all the corresponding quiz node,
-   * according to the configuration on the argument settings form. These vids
-   * will then be the actual ones used while generating the real query.
-   *
-   * @var array
-   */
-  var $corresponding_vids = array();
-  var $phrase_broken = FALSE;
-
-  function construct() {
-    parent::construct();
-    $this->nid_field = $this->definition['nid field'];
-    $this->vid_field = isset($this->definition['vid field']) ? $this->definition['vid field'] : 'vid';
-  }
-
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['which_vid'] = array('default' => 'latest');
-
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    // Set weighting so that our element can sanely ordered
-    $form['title']['#weight'] = -2;
-    //    $form['default_action']['#weight'] = -3;
-    //    $form['wildcard']['#weight'] = -4;
-    //    $form['wildcard_substitution']['#weight'] = -4;
-    $form['which_vid'] = array(
-      '#type' => 'select',
-      '#title' => t('Quiz revision(s) to use'),
-      '#options' => array(
-        'latest' => t('Latest: most recent version of the quiz ONLY.'),
-        'initial' => t('Initial: original version of the quiz ONLY.'),
-        'all' => t('All: ALL versions of the quiz.')
-      ),
-      '#description' => t('The validator will transform the incoming quiz node id(s) into one or more quiz node revisions, depending on your selection.'),
-      '#default_value' => $this->options['which_vid'],
-      '#weight' => -1,
-    );
-  }
-
-  function title_query() {
-    $titles = array();
-
-    $result = db_query("SELECT n.title FROM {node_revision} n WHERE n.vid IN (:vids)", array(':vids' => implode(', ', $this->corresponding_vids)));
-    while ($term = $result->fetch()) {
-      $titles[] = check_plain($term->title);
-    }
-    return $titles;
-  }
-
-  /**
-   * Override the default behavior of query() to introduce the medial step of
-   * retrieving vids from the provided nids.
-   */
-  function query($group_by = FALSE) {
-    $this->ensure_my_table();
-    $this->break_phrase();
-
-    // Do subselect to get relevant vids, then add where clause
-    $this->subselect_vids();
-    $this->query->add_where(0, "$this->table_alias.$this->nid_field", $this->corresponding_vids);
-  }
-
-  /**
-   * Set up the argument with the vids extracted from nids.
-   *
-   * Needs to be done here, because this is the earliest stage at which we can
-   * guarantee the contents of $this->argument to be available.
-   *
-   * @param string $arg
-   *   The argument, as delivered in the URL.
-   */
-  function set_argument($arg) {
-    $this->argument = $arg;
-    if ($this->validate_arg($arg)) {
-      $this->break_phrase();
-      $this->subselect_vids();
-      return TRUE;
-    }
-    return FALSE;
-  }
-
-  function break_phrase() {
-    if (!$this->phrase_broken) {
-      // Handle multiple argument inputs
-      if (!empty($this->options['break_phrase'])) {
-        views_break_phrase($this->argument, $this);
-      }
-      else {
-        $this->value = array($this->argument);
-      }
-      $this->phrase_broken = TRUE;
-    }
-  }
-
-  /**
-   * Helper method to retrieve the vid(s) the final view query should actually
-   * be run against.
-   *
-   * Would be done in pre_query(), but $this->argument is not yet available at
-   * that time. So, called from set_argument().
-   */
-  function subselect_vids() {
-    $query = db_select('quiz_node_properties', 'qnp');
-    if (count($this->value) > 1) {
-      // Guaranteed to produce multiple values; therefore may need the group by
-      $use_group_by = TRUE;
-      $operator = empty($this->options['not']) ? 'IN' : 'NOT IN';
-      $query->condition('nid', $this->value, $operator);
-    }
-    else {
-      // Multiple values only possible with a NOT; only then do we need group by
-      $use_group_by = !empty($this->options['not']);
-      $operator = empty($this->options['not']) ? '=' : '!=';
-      $query->condition('nid', reset($this->value), $operator);
-    }
-
-    switch ($this->options['which_vid']) {
-      case 'initial':
-        // SQL operation for getting the initial vids based on view config settings
-        $query->addExpression('MIN(vid)', 'vid');
-        break;
-      case 'latest':
-        // SQL operation for getting the latest vids based on view config settings
-        $query->addExpression('MAX(vid)', 'vid');
-        break;
-      default:
-        // Get them all
-        $query->addField('qnp', 'vid');
-        break;
-    }
-    if ($use_group_by) {
-      $query->groupBy('nid');
-    }
-    $result = $query->execute();
-
-    $this->nid_field = $this->vid_field;
-
-    $this->corresponding_vids = array();
-    foreach ($result as $item) {
-      $this->corresponding_vids[] = $item->vid;
-    }
-    return (count($this->corresponding_vids) > 1);
-  }
-}
\ No newline at end of file
diff --git a/includes/views/handlers/quiz_views_handler_argument_user_uid_nullable.inc b/includes/views/handlers/quiz_views_handler_argument_user_uid_nullable.inc
deleted file mode 100644
index 7c5f2e1..0000000
--- a/includes/views/handlers/quiz_views_handler_argument_user_uid_nullable.inc
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-
-/*
- * @file
- * Handles argument user id nullable.
- */
-
-class quiz_views_handler_argument_user_uid_nullable extends views_handler_argument_user_uid {
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['allow_null'] = array('default' => FALSE);
-
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    unset($form['break_phrase']);
-    $form['allow_null'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Used for Quiz Status'),
-      '#description' => t('When this agument is used, this box must be checked if the Quiz Status field is to work properly.'),
-      '#default_value' => $this->options['allow_null'],
-    );
-  }
-
-  function query($group_by = FALSE) {
-    $this->ensure_my_table();
-    $operator = empty($this->options['not']) ? '=' : '!=';
-    $where = "$this->table_alias.$this->real_field";
-    if ($this->options['allow_null']) {
-      $group = $this->query->set_where_group('AND', 'qnr_user');
-      //$where .= " OR ISNULL($this->table_alias.$this->real_field)";
-    }
-    else {
-      $group = 0;
-    }
-
-    // By adding the ISNULL, joins can properly inform us about quiz state
-    $this->query->add_where($group, $where, $this->argument);
-  }
-}
diff --git a/includes/views/handlers/quiz_views_handler_field_node_link_take.inc b/includes/views/handlers/quiz_views_handler_field_node_link_take.inc
deleted file mode 100644
index e095e77..0000000
--- a/includes/views/handlers/quiz_views_handler_field_node_link_take.inc
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-/**
- * @file
- * Definition of quiz_views_handler_field_node_link_take.
- */
-
-/**
- * Field handler to present a link to take a quiz node.
- *
- * @ingroup views_field_handlers
- */
-class quiz_views_handler_field_node_link_take extends views_handler_field_node_link {
-
-  /**
-   * Renders the link.
-   */
-  function render_link($node, $values) {
-    // Ensure user has access to take this quiz.
-    if (!quiz_take_access($node)) {
-      return;
-    }
-
-    $this->options['alter']['make_link'] = TRUE;
-    $this->options['alter']['path'] = "node/$node->nid/take";
-
-    $text = !empty($this->options['text']) ? $this->options['text'] : t('Take quiz');
-    return $text;
-  }
-}
\ No newline at end of file
diff --git a/includes/views/handlers/quiz_views_handler_field_number_questions.inc b/includes/views/handlers/quiz_views_handler_field_number_questions.inc
deleted file mode 100644
index c57ccc4..0000000
--- a/includes/views/handlers/quiz_views_handler_field_number_questions.inc
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-/*
- * @file
- * Handles field question number.
- */
-
-class quiz_views_handler_field_number_questions extends views_handler_field {
-
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['include_random'] = array(
-      'default' => TRUE,
-    );
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $form['include_random'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Include random questions?'),
-      '#description' => t('Whether or not questions set to "random" should be included in the count.'),
-      '#default_value' => $this->options['include_random'],
-    );
-  }
-
-  function query() {
-    $this->ensure_my_table();
-    $this->field_alias = 'question_count';
-    $formula = "COUNT($this->table_alias.child_vid)";
-    if ($this->options['include_random']) {
-      $properties_alias = $this->query->ensure_table('quiz_node_properties');
-
-      $formula .= " + (SELECT number_of_random_questions FROM {quiz_node_properties} WHERE vid = $this->table_alias.parent_vid)";
-    }
-    $this->query->add_field(NULL, "$formula", $this->field_alias);
-  }
-}
diff --git a/includes/views/handlers/quiz_views_handler_field_question_status.inc b/includes/views/handlers/quiz_views_handler_field_question_status.inc
deleted file mode 100644
index bfa5942..0000000
--- a/includes/views/handlers/quiz_views_handler_field_question_status.inc
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-
-/**
- * @file
- * Views field handler that translates question status integer constants (as
- * defined in quiz.module) into their human-readable string counterparts.
- */
-class quiz_views_handler_field_question_status extends views_handler_field {
-  var $text_map = array();
-
-  function pre_render(&$values) {
-    $this->text_map = array(
-      QUIZ_QUESTION_RANDOM => t('Random'), // 'Random-ly' better?
-      QUIZ_QUESTION_ALWAYS => t('Always'),
-      QUIZ_QUESTION_NEVER => t('Never'),
-    );
-  }
-
-  function render($values) {
-    return $this->text_map[$values->{$this->field_alias}];
-  }
-}
diff --git a/includes/views/handlers/quiz_views_handler_field_quiz_question_result_answer.inc b/includes/views/handlers/quiz_views_handler_field_quiz_question_result_answer.inc
new file mode 100644
index 0000000..2e59751
--- /dev/null
+++ b/includes/views/handlers/quiz_views_handler_field_quiz_question_result_answer.inc
@@ -0,0 +1,69 @@
+<?php
+
+class quiz_views_handler_field_quiz_question_result_answer extends views_handler_field_prerender_list {
+
+  /**
+   * Working with node table, adding active credit types to it.
+   */
+  function construct() {
+    parent::construct();
+    $this->additional_fields['result_id'] = array(
+      'table' => 'quiz_node_results',
+      'field' => 'result_id',
+    );
+  }
+
+  /**
+   * Add fields, alias.
+   */
+  function query() {
+    $this->add_additional_fields();
+    $this->field_alias = $this->aliases['result_id'];
+  }
+
+  function option_definition() {
+    $options = parent::option_definition();
+
+    $options['question_nid'] = array(
+      'default' => NULL,
+    );
+    $options['question_vid'] = array(
+      'default' => NULL,
+    );
+    $options['data_type'] = array(
+      'default' => NULL,
+    );
+    return $options;
+  }
+
+  function pre_render(&$values) {
+    $this->items = array();
+
+    $result_ids = array();
+    foreach ($values as $value) {
+      $result_ids[] = $value->result_id;
+    }
+
+    $nid = $this->options['question_nid'];
+    $vid = $this->options['question_vid'];
+    $node = node_load($nid, $vid);
+    $info = quiz_question_get_info();
+    $className = $info[$node->type]['response provider'];
+
+    if ($result_ids) {
+      $raids = db_query('SELECT result_answer_id
+        FROM {quiz_node_results_answers} qnra
+        LEFT JOIN {quiz_node_results} qnr ON (qnra.result_id = qnr.result_id)
+        WHERE question_nid = :nid
+          AND question_vid = :vid
+          AND qnr.result_id IN (:result_id)', array(':nid' => $nid, ':vid' => $vid, ':result_id' => $result_ids))->fetchAllKeyed(0, 0);
+
+      $this->items = $className::viewsGetAnswers($raids);
+    }
+  }
+
+  function render_item($count, $item) {
+    return parent::render_items($item);
+  }
+
+}
diff --git a/includes/views/handlers/quiz_views_handler_field_score_aggregate.inc b/includes/views/handlers/quiz_views_handler_field_score_aggregate.inc
deleted file mode 100644
index 31f96d2..0000000
--- a/includes/views/handlers/quiz_views_handler_field_score_aggregate.inc
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-/*
- * @file
- *  Handler for field score.
- */
-
-class quiz_views_handler_field_score_aggregate extends views_handler_field_numeric {
-
-  function construct() {
-    parent::construct();
-    // This will have to change to be set by options if the methods are ever expanded
-    $this->group_field = $this->definition['group field'];
-  }
-
-  function option_definition() {
-    $options = parent::option_definition();
-    return $options;
-  }
-
-  function query() {
-    $this->ensure_my_table();
-    $this->query->add_field($this->table_alias, $this->group_field);
-    $this->field_alias = $this->query->add_field(
-      NULL, "AVG($this->table_alias.$this->real_field)",
-      $this->table_alias . '__average', array('aggregate' => TRUE)
-    );
-    $this->query->add_groupby("$this->table_alias.$this->group_field"); // nid is OK for average. Others maybe not so much
-  }
-}
diff --git a/includes/views/handlers/quiz_views_handler_field_takes.inc b/includes/views/handlers/quiz_views_handler_field_takes.inc
deleted file mode 100644
index cd67eda..0000000
--- a/includes/views/handlers/quiz_views_handler_field_takes.inc
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-/*
- * @file
- * Hanldes field takes.
- */
-class quiz_views_handler_field_takes extends views_handler_field {
-  function render($values) {
-    $value = $values->{$this->field_alias};
-    if ((int) $value === 0) {
-      return 'Unlimited';
-    }
-    return $value;
-  }
-}
diff --git a/includes/views/handlers/quiz_views_handler_field_time.inc b/includes/views/handlers/quiz_views_handler_field_time.inc
deleted file mode 100644
index 2e36528..0000000
--- a/includes/views/handlers/quiz_views_handler_field_time.inc
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-/**
- * @file A handler to provide proper displays for dates.
- *
- * @ingroup views_field_handlers
- */
-class quiz_views_handler_field_time extends views_handler_field {
-  function render($values) {
-    $value = $values->{$this->field_alias};
-    return _quiz_format_duration($value);
-  }
-}
diff --git a/includes/views/handlers/quiz_views_handler_field_user_quiz_state.inc b/includes/views/handlers/quiz_views_handler_field_user_quiz_state.inc
deleted file mode 100644
index d678e22..0000000
--- a/includes/views/handlers/quiz_views_handler_field_user_quiz_state.inc
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-/*
- * @file
- * Handles field user quiz state.
- */
-class quiz_views_handler_field_user_quiz_state extends views_handler_field {
-
-  function construct() {
-    parent::construct();
-    // TODO: what to do with $this->real_field in this situation?
-    // $this->real_field = REQUEST_TIME . 'BETWEEN '
-  }
-  // Note that the native field is time_start, and time_end is added as an
-  // additional field in the handler declaration
-  function query() {
-    $this->ensure_my_table();
-    $this->query->add_field($this->table_alias, "time_end", 'is_finished');
-    // $this->query->add_field($this->table_alias, REQUEST_TIME . " BETWEEN $this->table_alias.time_start AND $this->table_alias.time_end", $this->field_alias);
-  }
-
-  function render($values) {
-    if ($values->is_finished > 0) {
-      return t('Finished');
-    }
-    else {
-      return t('In Progress');
-    }
-  }
-}
diff --git a/includes/views/handlers/quiz_views_handler_filter_question_status.inc b/includes/views/handlers/quiz_views_handler_filter_question_status.inc
deleted file mode 100644
index c17f0a1..0000000
--- a/includes/views/handlers/quiz_views_handler_filter_question_status.inc
+++ /dev/null
@@ -1,18 +0,0 @@
-<?php
-
-/*
- * @file
- * Handles filter question status.
- */
-class quiz_views_handler_filter_question_status extends views_handler_filter_in_operator {
-  function get_value_options() {
-    if (!isset($this->value_options)) {
-      $this->value_title = t('Question Status in Quiz');
-      $this->value_options = array(
-        QUIZ_QUESTION_RANDOM => t('Random'), // 'Random-ly' better?
-        QUIZ_QUESTION_ALWAYS => t('Always'),
-        QUIZ_QUESTION_NEVER => t('Never'),
-      );
-    }
-  }
-}
diff --git a/includes/views/handlers/quiz_views_handler_filter_quiz_nid.inc b/includes/views/handlers/quiz_views_handler_filter_quiz_nid.inc
deleted file mode 100644
index a1a426c..0000000
--- a/includes/views/handlers/quiz_views_handler_filter_quiz_nid.inc
+++ /dev/null
@@ -1,142 +0,0 @@
-<?php
-
-/*
- * @file
- * // options are either a) show only the most recent version, b) show the original version.
- */
-class quiz_views_handler_filter_quiz_nid extends views_handler_filter {
-
-  /**
-   * An array that the subselect will fill with all the corresponding quiz node,
-   * according to the configuration on the argument settings form. These vids
-   * will then be the actual ones used while generating the real query.
-   *
-   * @var array
-   */
-  var $corresponding_vids = array();
-  var $group_by;
-  var $group_by_table;
-  var $secondary_group_by;
-  var $secondary_table;
-  var $secondary_table_alias;
-  var $secondary_tables = array(
-    'none' => array(
-      'secondary_group_by' => 'nid',
-      'secondary_table' => 'quiz_node_results',
-      'secondary_vid' => 'vid',
-      'secondary_nid' => 'nid',
-    ),
-    'results' => array(
-      'secondary_group_by' => 'uid',
-      'secondary_table' => 'quiz_node_results',
-      'secondary_vid' => 'vid',
-      'secondary_nid' => 'nid',
-    ),
-    'questions' => array(
-      'secondary_group_by' => 'child_nid',
-      'secondary_table' => 'quiz_node_relationship',
-      'secondary_vid' => 'parent_vid',
-      'secondary_nid' => 'parent_nid',
-    ),
-  );
-
-  function construct() {
-    parent::construct();
-    $this->vid_field = !empty($this->definition['vid field']) ? $this->definition['vid field'] : 'vid';
-    if (!empty($this->definition['group by'])) {
-      $this->group_by = $this->definition['group by'];
-    }
-    if (!empty($this->definition['secondary group by'])) {
-      $this->secondary_group_by = $this->definition['secondary group by'];
-    }
-  }
-
-  function can_expose() {
-    return FALSE;
-  }
-
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['which_vid'] = array('default' => 'latest');
-    $options['secondary'] = array('default' => 'none');
-
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $form['which_vid'] = array(
-      '#type' => 'select',
-      '#title' => t('Quiz revision(s) to use'),
-      '#options' => array(
-        'latest' => t('Latest: most recent version of the quiz ONLY.'),
-        'initial' => t('Initial: original version of the quiz ONLY.'),
-        // 'all' => t('All: ALL versions of the quiz.')
-      ),
-      '#description' => t('The filter will limit score results for a particular quiz node id(s) into one or more quiz node revision ids, depending on your selection.'),
-      '#default_value' => $this->options['which_vid'],
-    );
-
-    $tables = array('none' => t('None'));
-    $tables['results'] = t('Use Quiz Results');
-    $tables['questions'] = t('Use Quiz Questions');
-    $form['secondary'] = array(
-      '#type' => 'radios',
-      '#title' => t('Secondary Grouping'),
-      '#options' => $tables,
-      '#default_value' => $this->options['secondary'],
-      '#description' => t('If you are looking to generate a list of either quiz questions or quiz results, you must select the appropriate option from this list.'),
-    );
-  }
-
-  function value_submit($form, &$form_state) {
-    $form_state['values']['options']['secondaries'] = $this->secondary_tables[$form_state['values']['options']['secondary']];
-  }
-
-  /**
-   * Override the default behavior of query() to introduce the medial step of
-   * retrieving vids from the provided nids.
-   */
-  function query() {
-    $this->ensure_my_table();
-
-    foreach ($this->options['secondaries'] as $key => $value) {
-      if (!is_null($value)) {
-        $this->$key = $value;
-      }
-    }
-
-    $this->group_by_table = !empty($this->definition['group by table']) ?
-      $this->query->ensure_table($this->definition['group by table']) :
-      $this->table_alias;
-    //    $this->query->add_groupby("$this->group_by_table.$this->group_by");
-    $this->query->add_groupby("$this->table_alias.$this->field");
-    $this->query->add_groupby("$this->table_alias.$this->vid_field");
-
-    //    if (!empty($this->secondary_group_by) || !empty($this->options['secondary_group_by'])) {
-    if (!empty($this->secondary_group_by)) {
-      $this->secondary_table_alias = $this->query->ensure_table($this->secondary_table);
-      $this->query->add_groupby("$this->secondary_table_alias.$this->secondary_group_by");
-    }
-    $this->query->add_where(0, "$this->secondary_table_alias.$this->secondary_vid", $this->subselect());
-  }
-
-  /**
-   * Helper method to retrieve the vid(s) the final view query should actually
-   * be run against.
-   *
-   * Would be done in pre_query(), but $this->argument is not yet available at
-   * that time. So, called from set_argument().
-   */
-  function subselect() {
-    $operation = ($this->options['which_vid'] == 'initial' ? 'MIN' : 'MAX');
-    $subalias = $this->secondary_table_alias . '__subselect';
-    $subselect = "SELECT $operation($subalias.$this->secondary_vid) FROM ";
-    $subselect .= '{' . $this->secondary_table . "} $subalias WHERE ";
-    $subselect .= "$subalias.$this->secondary_group_by = $this->secondary_table_alias.$this->secondary_group_by AND ";
-    $subselect .= "$subalias.$this->secondary_nid = $this->secondary_table_alias.$this->secondary_nid";
-    return $subselect;
-
-  }
-}
diff --git a/includes/views/handlers/quiz_views_handler_filter_user_nullable.inc b/includes/views/handlers/quiz_views_handler_filter_user_nullable.inc
deleted file mode 100644
index 9b0fd7f..0000000
--- a/includes/views/handlers/quiz_views_handler_filter_user_nullable.inc
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-
-/*
- * @file
- * Handles filter nullable user.
- */
-class quiz_views_handler_filter_user_nullable extends views_handler_filter {
-  function option_definition() {
-    $options = parent::option_definition();
-
-    $options['allow_null'] = array('default' => FALSE);
-    $options['use_current'] = array('default' => FALSE);
-
-    return $options;
-  }
-
-  function options_form(&$form, &$form_state) {
-    parent::options_form($form, $form_state);
-    $form['use_current'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Use Current User'),
-      '#description' => t('Filter using the current user; only quiz results owned by the current user will be shown.'),
-      '#default_value' => $this->options['use_current'],
-    );
-    $form['allow_null'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Used for Quiz Status'),
-      '#description' => t('If you are using the Quiz Status, this box must be checked; otherwise, the field will not work properly.'),
-      '#default_value' => $this->options['allow_null'],
-    );
-  }
-
-  function admin_summary() {
-    return !empty($this->options['use_current']) ? t('Current User') : t('NOT Current User');
-  }
-
-  function query() {
-    $group = $this->query->set_where_group('AND', 'qnr_user');
-    $this->ensure_my_table();
-
-    $operator = empty($this->options['use_current']) ? '!=' : '=';
-    // By adding the isNull, joins can properly inform us about quiz state
-    $this->query->add_where(
-        $group,
-        db_or()
-          ->condition("$this->table_alias.$this->real_field", "***CURRENT_USER***", $operator)
-          ->isNull("$this->table_alias.$this->real_field")
-    );
-  }
-}
diff --git a/includes/views/handlers/quiz_views_handler_filter_user_quiz_state.inc b/includes/views/handlers/quiz_views_handler_filter_user_quiz_state.inc
deleted file mode 100644
index 41fd04a..0000000
--- a/includes/views/handlers/quiz_views_handler_filter_user_quiz_state.inc
+++ /dev/null
@@ -1,73 +0,0 @@
-<?php
-
-/*
- * @file
- * Handles filter user quiz state.
- */
-class quiz_views_handler_filter_user_quiz_state extends views_handler_filter {
-  var $states = array();
-  var $no_operator = TRUE; // for nicer formatting of the form
-  var $no_single = TRUE; // always only a single value, at least for now
-
-  function init(&$view, &$options) {
-    parent::init($view, $options);
-    $this->states = array(
-      'any' => t('All Results (Do not filter)'),
-      'not_started' => t('Not Started'),
-      'in_progress' => t('In Progress'),
-      'finished' => t('Finished'),
-    );
-  }
-
-  function option_definition() {
-    $options = parent::option_definition();
-    $options['value']['quiz_state'] = array('default' => 'finished');
-    return $options;
-  }
-
-  function value_form(&$form, &$form_state) {
-    $form['value'] = array();
-    $form['value']['quiz_state'] = $this->base_form_item();
-  }
-
-  function base_form_item() {
-    return array(
-      '#type' => 'radios',
-      '#title' => t('Quiz State'),
-      '#description' => t('Output will be limited to only include quiz results in this state. If the filter is exposed, the value set here will be used as the default. Note that "Any" is only useful for exposed filters.'),
-      '#options' => $this->states,
-      '#default_value' => !empty($this->value['quiz_state']) ? $this->value['quiz_state'] : 'any',
-    );
-  }
-
-  function exposed_form(&$form, &$form_state) {
-    if (empty($this->options['exposed'])) {
-      return;
-    }
-    if (!empty($this->options['expose']['identifier'])) {
-      $value = $this->options['expose']['identifier'];
-
-      $form[$value]['quiz_state'] = $this->base_form_item();
-      unset($form[$value]['quiz_state']['#title'], $form[$value]['quiz_state']['#description']);
-    }
-  }
-
-  function admin_summary() {
-    return 'is ' . $this->states[$this->value['quiz_state']];
-  }
-
-  function query() {
-    $val = is_array($this->value) ? $this->value['quiz_state'] : $this->value;
-    if (empty($val) || $val == 'any') {
-      return;
-    }
-    $this->ensure_my_table();
-    if ($val == 'not_started') {
-      $this->query->add_where($this->options['group'], "$this->table_alias.time_end", NULL, "IS NULL");
-    }
-    else {
-      $operator = $val == 'in_progress' ? '=' : '>';
-      $this->query->add_where($this->options['group'], "$this->table_alias.time_end", 0, $operator);
-    }
-  }
-}
diff --git a/includes/views/handlers/quiz_views_handler_relationship_quiz_nid.inc b/includes/views/handlers/quiz_views_handler_relationship_quiz_nid.inc
deleted file mode 100644
index 7ed06b6..0000000
--- a/includes/views/handlers/quiz_views_handler_relationship_quiz_nid.inc
+++ /dev/null
@@ -1,10 +0,0 @@
-<?php
-
-/*
- * @file
- * Handles field quiz node relationship.
- */
-
-class quiz_views_handler_relationship_quiz_nid extends views_handler_relationship {
-
-}
diff --git a/includes/views/quiz.views.inc b/includes/views/quiz.views.inc
index e7768f4..04ff3a8 100644
--- a/includes/views/quiz.views.inc
+++ b/includes/views/quiz.views.inc
@@ -87,4 +87,60 @@ function quiz_views_data_alter(&$data) {
       'handler' => 'quiz_views_handler_filter_quiz_question',
     ),
   );
+
+  $data['quiz_node_results']['answers'] = array(
+    'title' => t('Answers'),
+    'help' => t('When rendered, this field will be replaced by all the answers.'),
+    'field' => array(
+      'title' => 'Answers',
+      'handler' => 'views_handler_field_custom',
+    ),
+  );
+
+  $data['quiz_node_results']['answer'] = array(
+    'title' => t('Answer'),
+    'help' => t('When rendered, this field will be replaced by a requested answer.'),
+    'field' => array(
+      'title' => 'Answer',
+      'handler' => 'quiz_views_handler_field_quiz_question_result_answer',
+    ),
+  );
+}
+
+/**
+ * Implements hook_views_pre_view().
+ *
+ * Replace the static field with dynamic fields.
+ */
+function quiz_views_pre_view(&$view) {
+  if ($view->name == 'quiz_results') {
+    if ($view->display_handler->options['fields']) {
+      $fields = & $view->display_handler->options['fields'];
+    }
+    else {
+      $fields = & $view->display_handler->default_display->options['fields'];
+    }
+
+    $quiz = node_load($view->args[0]);
+    foreach ($fields as $field_name => &$field) {
+      if ($field['id'] == 'answers') {
+        $i = 0;
+        foreach (quiz_get_questions($quiz->nid, $quiz->vid) as $question) {
+          $quizQuestion = _quiz_question_get_instance($question);
+          if ($quizQuestion->isGraded()) {
+            $i++;
+            $newfield = array();
+            $newfield['id'] = 'answer';
+            $newfield['table'] = 'quiz_node_results';
+            $newfield['field'] = 'answer';
+            $newfield['label'] = t('@num. @question', array('@num' => $i, '@question' => $question->title));
+            $newfield['question_nid'] = $question->nid;
+            $newfield['question_vid'] = $question->vid;
+            $fields['answer_' . $question->nid] = $newfield;
+          }
+        }
+        unset($fields['answers']);
+      }
+    }
+  }
 }
diff --git a/question_types/multichoice/multichoice.classes.inc b/question_types/multichoice/multichoice.classes.inc
index 311a59c..cf84e84 100644
--- a/question_types/multichoice/multichoice.classes.inc
+++ b/question_types/multichoice/multichoice.classes.inc
@@ -995,4 +995,28 @@ class MultichoiceResponse extends QuizQuestionResponse {
     $alternatives = $newAlternatives;
   }
 
+  /**
+   * Get answers for a question in a result.
+   *
+   * This static method assists in building views for the mass export of
+   * question answers.
+   *
+   * @see views_handler_field_prerender_list for the expected return value.
+   */
+  public static function viewsGetAnswers(array $result_answer_ids = array()) {
+    $items = array();
+
+    $sql = "SELECT * FROM {quiz_node_results_answers} qnra
+      INNER JOIN {quiz_multichoice_user_answers} qmua on (qnra.result_answer_id = qmua.result_answer_id)
+      INNER JOIN {quiz_multichoice_user_answer_multi} uam ON (uam.user_answer_id = qmua.id)
+      INNER JOIN {quiz_multichoice_answers} ma ON (ma.id = uam.answer_id)
+      WHERE qnra.result_answer_id IN (:result_answer_id)";
+    $result = db_query($sql, array(':result_answer_id' => $result_answer_ids));
+
+    while ($row = $result->fetch()) {
+      $items[$row->result_id][] = array('answer' => $row->answer);
+    }
+    return $items;
+  }
+
 }
diff --git a/question_types/quiz_question/quiz_question.core.inc b/question_types/quiz_question/quiz_question.core.inc
index 4ff3d80..2210bda 100644
--- a/question_types/quiz_question/quiz_question.core.inc
+++ b/question_types/quiz_question/quiz_question.core.inc
@@ -462,7 +462,6 @@ abstract class QuizQuestion {
     return TRUE;
   }
 
-
   /**
    * Is this "question" an actual question? For example, a Quiz Page is not a
    * question, neither is a "quiz directions".
@@ -476,6 +475,20 @@ abstract class QuizQuestion {
     return TRUE;
   }
 
+  /**
+   * If this question type has answers to report on, this is necessary to do it
+   * from within Views.
+   *
+   * Question types should return an array expected by
+   * views_handler_field_prerender_list().
+   *
+   * @param type $result_ids
+   *   An array of result IDs.
+   * @param type $nid
+   *   The question node ID.
+   * @param type $vid
+   *   The question node revision ID.
+   */
 }
 
 /**
@@ -895,4 +908,33 @@ abstract class QuizQuestionResponse {
     $this->result_answer_id = $result_answer_id;
   }
 
+  /**
+   * Get answers for a question in a result.
+   *
+   * This static method assists in building views for the mass export of
+   * question answers.
+   *
+   * It is not as easy as instantiating all the question responses and returning
+   * the answer. To do this in views scalably we have to gather the data
+   * carefully.
+   *
+   * This base method provides a very poor way of gathering the data.
+   *
+   * @see views_handler_field_prerender_list for the expected return value.
+   *
+   * @see MultichoiceResponse::viewsGetAnswers for a correct approach
+   * @see TrueFalseResponse::viewsGetAnswers for a correct approach
+   */
+  public static function viewsGetAnswers(array $result_answer_ids = array()) {
+    $items = array();
+    foreach ($result_answer_ids as $result_answer_id) {
+      $ra = entity_load_single('quiz_result_answer', $result_answer_id);
+      $question = node_load($ra->question_nid, $ra->question_vid);
+      /** var $ra_i QuizQuestionResponse */
+      $ra_i = _quiz_question_response_get_instance($ra->result_id, $question);
+      $items[$ra->result_id][] = array('answer' => $ra_i->getResponse());
+    }
+    return $items;
+  }
+
 }
diff --git a/question_types/truefalse/truefalse.classes.inc b/question_types/truefalse/truefalse.classes.inc
index 791291e..5106d54 100644
--- a/question_types/truefalse/truefalse.classes.inc
+++ b/question_types/truefalse/truefalse.classes.inc
@@ -290,4 +290,27 @@ class TrueFalseResponse extends QuizQuestionResponse {
     return $data;
   }
 
+
+  /**
+   * Get answers for a question in a result.
+   *
+   * This static method assists in building views for the mass export of
+   * question answers.
+   *
+   * @see views_handler_field_prerender_list for the expected return value.
+   */
+  public static function viewsGetAnswers(array $result_answer_ids = array()) {
+    $items = array();
+
+    $sql = "SELECT * FROM {quiz_node_results_answers} qnra
+      INNER JOIN {quiz_truefalse_user_answers} tfua on (qnra.result_answer_id = tfua.result_answer_id)
+      WHERE qnra.result_answer_id in (:result_answer_id)";
+    $result = db_query($sql, array(':result_answer_id' => $result_answer_ids));
+
+    while ($row = $result->fetch()) {
+      $items[$row->result_id][] = array('answer' => $row->answer ? t('True') : t('False'));
+    }
+    return $items;
+  }
+
 }
diff --git a/quiz.info b/quiz.info
index 39bff6c..d6b8ee4 100644
--- a/quiz.info
+++ b/quiz.info
@@ -24,22 +24,9 @@ files[] = includes/QuizResultAnswerController.class.inc
 files[] = includes/QuizResultAnswerMetadataController.class.inc
 files[] = includes/QuizResultController.class.inc
 files[] = includes/QuizResultMetadataController.class.inc
-files[] = includes/views/handlers/quiz_views_handler_argument_quiz_nid.inc
-files[] = includes/views/handlers/quiz_views_handler_argument_user_uid_nullable.inc
-files[] = includes/views/handlers/quiz_views_handler_field_node_link_take.inc
-files[] = includes/views/handlers/quiz_views_handler_field_number_questions.inc
-files[] = includes/views/handlers/quiz_views_handler_field_question_status.inc
-files[] = includes/views/handlers/quiz_views_handler_field_score_aggregate.inc
-files[] = includes/views/handlers/quiz_views_handler_field_takes.inc
-files[] = includes/views/handlers/quiz_views_handler_field_time.inc
-files[] = includes/views/handlers/quiz_views_handler_field_user_quiz_state.inc
-files[] = includes/views/handlers/quiz_views_handler_filter_question_status.inc
-files[] = includes/views/handlers/quiz_views_handler_filter_quiz_nid.inc
 files[] = includes/views/handlers/quiz_views_handler_filter_quiz_question.inc
 files[] = includes/views/handlers/quiz_views_handler_filter_quiz_question_type.inc
-files[] = includes/views/handlers/quiz_views_handler_filter_user_nullable.inc
-files[] = includes/views/handlers/quiz_views_handler_filter_user_quiz_state.inc
-files[] = includes/views/handlers/quiz_views_handler_relationship_quiz_nid.inc
+files[] = includes/views/handlers/quiz_views_handler_field_quiz_question_result_answer.inc
 files[] = tests/QuizCreationTestCase.test
 files[] = tests/QuizFeedbackTestCase.test
 files[] = tests/QuizNavigationTestCase.test
