diff --git a/pift.admin.inc b/pift.admin.inc
index 091ae1c..9516071 100644
--- a/pift.admin.inc
+++ b/pift.admin.inc
@@ -119,6 +119,20 @@ function pift_admin_settings_form($form, &$form_state) {
     '#default_value' => PIFT_REGEX,
     '#required' => TRUE,
   );
+  // Defines the core compatibility criteria.
+  $form['criteria']['pift_core'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Core branches'),
+      '#description' => t('Drupal core branches that are to be tested. Issues pertaining to them will have files tested.'),
+      '#options' => pift_compatibility_list(),
+      '#default_value' => variable_get('pift_core', array()),
+  );
+  // Release must be compatible with Drupal 6 or later in order to be tested.
+  foreach ($form['criteria']['pift_core']['#options'] as $key => $option) {
+      if ($option[0] < 6) {
+          unset($form['criteria']['pift_core']['#options'][$key]);
+      }
+  }
   // Defines project_issue issue status criteria.
   $form['criteria']['pift_status'] = array(
     '#type' => 'select',
@@ -129,20 +143,6 @@ function pift_admin_settings_form($form, &$form_state) {
     '#options' => list_allowed_values($field),
     '#required' => TRUE,
   );
-  // Defines the core compatibility criteria.
-  $form['criteria']['pift_core'] = array(
-    '#type' => 'checkboxes',
-    '#title' => t('Core branches'),
-    '#description' => t('Drupal core branches that are to be tested. Issues pertaining to them will have files tested.'),
-    '#options' => pift_compatibility_list(),
-    '#default_value' => variable_get('pift_core', array()),
-  );
-  // Release must be compatible with Drupal 6 or later in order to be tested.
-  foreach ($form['criteria']['pift_core']['#options'] as $key => $option) {
-    if ($option[0] < 6) {
-      unset($form['criteria']['pift_core']['#options'][$key]);
-    }
-  }
   // Advanced settings container.
   $form['advanced'] = array(
     '#type' => 'fieldset',
@@ -160,34 +160,62 @@ function pift_admin_settings_form($form, &$form_state) {
     '#default_value' => ($project ? $project->title : ''),
     '#required' => TRUE,
   );
-  /*
-  // Defines file result expiry (i.e. retest interval). Currently disabled.
+  // Defines the base URL location for the git repositories.
+  $form['advanced']['pift_git_base_url'] = array(
+    '#type' => 'textfield',
+    '#title' => t('PIFT Git Base URL'),
+    '#description' => t('Base URL for Git repositories, like git://git.drupal.org/project/'),
+    '#default_value' => variable_get('pift_git_base_url', 'git://git.drupal.org/project/'),
+    '#required' => TRUE,
+  );
+  // Defines file result expiry (i.e. retest interval).
   $form['advanced']['pift_retest'] = array(
     '#type' => 'select',
     '#title' => t('Re-test interval'),
     '#description' => t('Number of days to wait before re-testing a previously passed file.'),
     '#options' => array(
       -1,
-      24 * 60 * 60,
-      48 * 60 * 60,
-      72 * 60 * 60,
-      96 * 60 * 60,
+      1 * 24 * 60 * 60,
+      2 * 24 * 60 * 60,
+      3 * 24 * 60 * 60,
+      4 * 24 * 60 * 60,
+      5 * 24 * 60 * 60,
+      7 * 24 * 60 * 60,
+      14 * 24 * 60 * 60,
     ),
     '#default_value' => PIFT_RETEST,
     '#required' => TRUE,
   );
   $form['advanced']['pift_retest']['#options'] = drupal_map_assoc($form['advanced']['pift_retest']['#options'], 'format_interval');
   $form['advanced']['pift_retest']['#options'][-1] = t('Disabled');
-  */
-  // Defines the base URL location for the git repositories.
-  $form['advanced']['pift_git_base_url'] = array(
+  // Defines project_issue retest issue status criteria.
+  $form['advanced']['pift_retest_status'] = array(
+    '#type' => 'select',
+    '#multiple' => TRUE,
+    '#title' => t('Issue statuses'),
+    '#description' => t('List of issue statuses that an issue must belong to in order to re-test a previously passed file.'),
+    '#default_value' => variable_get('pift_retest_status', array()),
+    '#options' => list_allowed_values($field),
+  );
+  // Defines whether to retest all projects or only core
+  $form['advanced']['pift_retest_projects'] = array(
+    '#type' => 'select',
+    '#title' => t('Projects'),
+    '#description' => t('Projects for which to allow re-testing of previously tested patches.'),
+    '#default_value' => variable_get('pift_retest_projects', 'core'),
+    '#options' => array(
+      'core' => t('Core project only'),
+      'all' => t('All projects')),
+    '#required' => TRUE,
+  );
+  // Defines the maximum number of tests to re-test
+  $form['advanced']['pift_retest_quantity'] = array(
     '#type' => 'textfield',
-    '#title' => t('PIFT Git Base URL'),
-    '#description' => t('Base URL for Git repositories, like git://git.drupal.org/project/'),
-    '#default_value' => variable_get('pift_git_base_url', 'git://git.drupal.org/project/'),
+    '#title' => t('Max re-test batch size.'),
+    '#description' => t('Maximum number of previously passed files to re-test on each run.'),
+    '#default_value' => variable_get('pift_retest_quantity', '1'),
     '#required' => TRUE,
   );
-
   $form['#submit'] = array('pift_admin_settings_form_submit');
   return system_settings_form($form);
 }
diff --git a/pift.cron.inc b/pift.cron.inc
index b60e88a..b3f0137 100644
--- a/pift.cron.inc
+++ b/pift.cron.inc
@@ -10,66 +10,99 @@
  *
  * Mark files for re-testing if they still meet all the criteria and the
  * re-test interval has passed.
- *
- * TODO:  Update the retest query, since the upload table doesn't exist in
- * Drupal 7 anymore.
- * TODO:  Update for the id => nid data move within pift_data
  */
-/*
-function pift_cron_retest() {
-  if (PIFT_RETEST == -1) {
-    return;
-  }
+
+function pift_cron_retest($quantity = NULL, $count_only_flag = FALSE, $projects = array()) {
 
   $api_versions = pift_core_api_versions();
-  $sids = variable_get('pift_status', array());
+  $sids = variable_get('pift_retest_status', array());
+
+  $retest_interval = variable_get('pift_retest', -1);
+  if ($retest_interval == -1) {
+    $retest_interval = 86400;
+  }
 
   // Only attempt query if both values are not empty.
-  if ($api_versions && $sids) {
-    $retest_time = REQUEST_TIME - PIFT_RETEST;
-
-    // Loop over 'ON' clause to remove an 'OR' which should be more efficient.
-    foreach (array('u.nid = pi.nid', 'cu.nid = pi.nid') as $clause) {
-
-      db_query("UPDATE {pift_data}
-                SET status = :status
-                WHERE type = :type
-                AND id IN (
-                  SELECT f.fid
-                  FROM {files} f
-                  LEFT JOIN {upload} u
-                    ON f.fid = u.fid
-                  LEFT JOIN {comment_upload} cu
-                    ON f.fid = cu.fid
-
-                  JOIN {project_issues} pi
-                    ON " . $clause . "
-                  JOIN {pift_project} p
-                    ON pi.pid = p.pid
-                  JOIN {project_release_nodes} r
-                    ON pi.rid = r.nid
-
-                  JOIN {node} n
-                    ON r.nid = n.nid
-                  JOIN {taxonomy_term_node} t
-                    ON (n.vid = t.vid AND t.tid IN (:api_versions))
-
-                  WHERE pi.sid IN (:sids)
-                )
-                AND status > :status2
-                AND last_tested < :last_tested",
-                array(
-                  ':status' => PIFT_STATUS_QUEUE,
-                  ':type' => PIFT_TYPE_FILE,
-                  ':api_versions' => $api_versions,
-                  ':sids' => $sids,
-                  ':status2' => PIFT_STATUS_SENT,
-                  ':last_tested' => $retest_time,
-                ));
+  if (!empty($api_versions) && !empty($sids)) {
+    $retest_time = time() - $retest_interval;
+
+    // Retrieve last test for each issue
+    $query = db_select('pift_data', 'pd');
+
+    // Add required table joins
+    $query->join('node', 'n', 'pd.nid = n.nid');
+    $query->join('field_data_field_issue_status', 'fdfis', 'n.nid = fdfis.entity_id AND n.type = fdfis.bundle');
+    $query->join('field_data_field_project', 'fdfp', 'n.nid = fdfp.entity_id AND n.type = fdfp.bundle');
+
+    // Restrict to the last test in any given issue
+    $query->addExpression('MAX(test_id)', 'max_id');
+    $query->groupBy('pd.nid');
+
+    // Restrict to $quantity recent file tests which have passed and not been
+    // tested in the retest interval, ordered by oldest first.
+    if (empty($quantity)) {
+      $quantity = (int) variable_get('pift_retest_quantity', 1);
+    }
+    $query->condition('pd.type', PIFT_TYPE_FILE, '=')
+      ->condition('pd.status', PIFT_STATUS_PASS, '=')
+      ->condition('pd.last_tested', $retest_time, '<')
+      ->orderBy('pd.last_tested', 'ASC')
+      ->range(0, $quantity);
+
+    // Restrict to issue node types with the right status
+    $project_issue_types = project_issue_issue_node_types();
+    $query->condition('fdfis.entity_type', 'node', '=')
+      ->condition('fdfis.bundle', $project_issue_types, 'IN')
+      ->condition('fdfis.field_issue_status_value', $sids, 'IN');
+
+    // Determine projects
+    if (!empty($projects)) {
+      $query->condition('fdfp.field_project_target_id', $projects, 'IN');
+    }
+    elseif (variable_get('pift_retest_projects', 'core') == 'core') {
+      $query->condition('fdfp.field_project_target_id', PIFT_PID, '=');
+    }
+
+    // Execute query
+    $result = $query->execute();
+
+    $retest_candidates = array();
+
+    foreach ($result as $record) {
+      $retest_candidates[] = $record->max_id;
+      // TODO: Ensure test matches a valid API term
+    }
+
+    if ($count_only_flag) {
+      if (function_exists('drush_main')) {
+        drupal_set_message(t("Test Count: %test_count", array('%test_count' => count($retest_candidates))));
+      }
+      else {
+        watchdog('pift', 'Test Count: %test_count', array('%test_count' => count($retest_candidates)));
+      }
+      return;
+    }
+
+    if (!empty($retest_candidates)) {
+      // Update status for tests with final results (Passed or Failed)
+      // and which have not been tested in the retest period.
+      $updated = db_update('pift_data')
+        ->fields(array(
+          'status' => PIFT_STATUS_QUEUE,
+        ))
+        ->condition('status', PIFT_STATUS_SENT, '>')
+        ->condition('last_tested', $retest_time, '<')
+        ->condition('test_id', $retest_candidates, 'IN')
+        ->execute();
+      if (function_exists('drush_main')) {
+        drupal_set_message(t("Requeued %test_count new tests.", array('%test_count' => $updated)));
+      }
+      else {
+        watchdog('pift', 'Requeued %test_count new tests.', array('%test_count' => $updated));
+      }
     }
   }
 }
-*/
 
 /**
  * Create test batch and send it to the PIFR testing server.
diff --git a/pift.drush.inc b/pift.drush.inc
index 23f5f79..a6ff1f9 100644
--- a/pift.drush.inc
+++ b/pift.drush.inc
@@ -11,20 +11,37 @@ function pift_drush_command() {
   $items = array();
 
   $items['pift-cron'] = array(
-    'description' => 'Requeue expired test results, test out batch, and retrieve results.',
+    'description' => 'Send batch for testing, and retrieve results.',
+  );
+
+  $items['pift-cron-retest'] = array(
+    'description' => 'Requeue expired test results.',
+    'arguments' => array(
+      'quantity' => 'Maximum number of tests to requeue. (Defaults to "3").',
+    ),
+    'options' => array(
+      'project' => array(
+        'description' => 'Comma delimited list of project ids to include.',
+        'value' => 'required',
+      ),
+      'count' => 'Return the number of tests meeting the retest criteria, without queuing tests.',
+    ),
   );
 
   return $items;
 }
 
 /**
- * Requeue expired test results, test the batch, and retrieve results.
+ * Send batch for testing, and retrieve results.
  */
 function drush_pift_cron() {
   module_load_include('cron.inc', 'pift');
 
-  // Requeue all tests that have passed the re-test interval.
-//   pift_cron_retest(); TODO fix query.
+  // Check whether retesting is enabled
+  if (PIFT_RETEST != -1) {
+    // Requeue all tests that have passed the re-test interval.
+    pift_cron_retest();
+  }
 
   // Send a batch of queued tests.
   pift_cron_queue_batch();
@@ -32,3 +49,22 @@ function drush_pift_cron() {
   // Retrieve any results that have occured since last cron run.
   pift_cron_retrieve_results();
 }
+
+/**
+ * Requeue expired test results
+ */
+function drush_pift_cron_retest($quantity = 3) {
+  module_load_include('cron.inc', 'pift');
+
+  // Requeue all tests that have passed the re-test interval
+  $projects = array();
+
+  $count_only_flag = drush_get_option('count');
+
+  if ($projects = drush_get_option('project')) {
+    pift_cron_retest($quantity, $count_only_flag, explode(',', $projects));
+  }
+  else {
+    pift_cron_retest($quantity, $count_only_flag);
+  }
+}
\ No newline at end of file
diff --git a/pift.module b/pift.module
index 673bb0c..7cceb8f 100644
--- a/pift.module
+++ b/pift.module
@@ -17,7 +17,7 @@ define('PIFT_FOLLOWUP_FAIL', variable_get('pift_followup_fail', 0));
 define('PIFT_FOLLOWUP_RETEST', variable_get('pift_followup_retest', 0));
 define('PIFT_REGEX', variable_get('pift_regex', '/(\.diff|\.patch)$/'));
 define('PIFT_PID', variable_get('pift_pid', 3060));  // TODO: Drupal.org specific, to expediate the D7 port
-//define('PIFT_RETEST', variable_get('pift_retest', 24 * 60 * 60));
+define('PIFT_RETEST', variable_get('pift_retest', -1));
 define('PIFT_LAST_RETRIEVE', variable_get('pift_last_retrieve', 1));
 
 /**
@@ -173,8 +173,11 @@ function pift_cron() {
   if (PIFT_FREQUENCY != -1 && $time > PIFT_LAST + PIFT_FREQUENCY) {
     module_load_include('cron.inc', 'pift');
 
-    // Requeue all tests that have passed the re-test interval.
-    // pift_cron_retest(); TODO fix query.
+    // Check whether retesting is enabled
+    if (PIFT_RETEST != -1) {
+      // Requeue all tests that have passed the re-test interval.
+      pift_cron_retest();
+    }
 
     // Send a batch of queued tests.
     pift_cron_queue_batch();
