diff --git a/pift.admin.inc b/pift.admin.inc
index ab531bd..5d188b4 100644
--- a/pift.admin.inc
+++ b/pift.admin.inc
@@ -79,24 +79,27 @@ function pift_admin_settings_form($form, &$form_state) {
     '#required' => TRUE,
   );
 
-  $project_types = array();
-  foreach (project_get_project_types() as $key => $project_type) {
-    $project_types[$key] = $project_type->name;
-  }
-  $form['results'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Results Display'),
-    '#weight' => 0,
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-  );
-  $form['results']['pift_results_display'] = array(
-    '#type' => 'checkboxes',
-    '#title' => t('Project types'),
-    '#description' => t('Project types for which the "Testing Status" tab should be displayed on the project page.'),
-    '#options' => $project_types,
-    '#default_value' => variable_get('pift_results_display', array()),
-  );
+  // Removing for the D7 port, as the plan is to move the 'Automated Testing'
+  // tab interface over to the Conduit project
+  //$project_types = array();
+  //array();
+  //foreach (project_project_node_types() as $key => $project_type) {
+  //  $project_types[$project_type] = $project_type;
+  //}
+  //$form['results'] = array(
+  //  '#type' => 'fieldset',
+  //  '#title' => t('Results Display'),
+  //  '#weight' => 0,
+  //  '#collapsible' => TRUE,
+  //  '#collapsed' => TRUE,
+  //);
+  //$form['results']['pift_results_display'] = array(
+  //  '#type' => 'checkboxes',
+  //  '#title' => t('Project types'),
+  //  '#description' => t('Project types for which the "Testing Status" tab should be displayed on the project page.'),
+  //  '#options' => $project_types,
+  //  '#default_value' => variable_get('pift_results_display', array()),
+  //);
 
   $form['criteria'] = array(
     '#type' => 'fieldset',
@@ -124,7 +127,7 @@ function pift_admin_settings_form($form, &$form_state) {
     '#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' => project_release_compatibility_list(),
+    '#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.
@@ -200,8 +203,16 @@ function pift_admin_settings_form_validate($form, &$form_state) {
  * Query pid using project title.
  */
 function pift_admin_settings_form_submit($form, &$form_state) {
-  $form_state['values']['pift_pid'] = db_query("SELECT nid
-              FROM {node}
-              WHERE title = :title
-              AND type = :type", array(':title' => $form_state['values']['pift_pid'], ':type' => 'project_project'))->fetchField();
+  $query = new EntityFieldQuery();
+  $query->entityCondition('entity_type', 'node')
+    ->entityCondition('bundle', project_project_node_types(), 'IN')
+    ->propertyCondition('status', 1)
+    ->propertyCondition('title', $form_state['values']['pift_pid'])
+    ->range(0,1);
+  $result = $query->execute();
+
+  if (isset($result['node'])) {
+    $form_state['values']['pift_pid'] = reset(array_keys($result['node']));
+  }
 }
+
diff --git a/pift.cron.inc b/pift.cron.inc
index c8f24f7..715f271 100644
--- a/pift.cron.inc
+++ b/pift.cron.inc
@@ -25,6 +25,7 @@ function pift_cron_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) {
+      // TODO:  UPDATE THIS QUERY (Upload table doesn't exist anymore)
       db_query("UPDATE {pift_test}
                 SET status = :status
                 WHERE type = :type
@@ -188,50 +189,62 @@ function pift_cron_queue_batch_build() {
  * @param array $branches Branches that must be loaded.
  */
 function pift_cron_queue_batch_build_files(array &$batch, array &$branches) {
-  // Load all files that are marked as needs testing or have never been tested.
-  $result = db_query('SELECT f.fid, f.filepath, u.nid AS u_nid, cu.nid AS c_nid, cu.cid AS c_cid
-                      FROM {pift_test} t
-                      JOIN {files} f
-                        ON (t.type = :type AND t.id = f.fid)
-                      LEFT JOIN {upload} u
-                        ON f.fid = u.fid
-                      LEFT JOIN {comment_upload} cu
-                        ON f.fid = cu.fid
-                      WHERE t.status = :status
-                      LIMIT :limit', array(':type' => PIFT_TYPE_FILE, ':status' => PIFT_STATUS_QUEUE, ':limit' => PIFT_XMLRPC_MAX), array('fetch' => PDO::FETCH_ASSOC));
-  foreach ($result as $file) {
-    // Load the issue related to the file, either from the comment or node.
-    $issue_nid = !empty($file['u_nid']) ? $file['u_nid'] : $file['c_nid'];
-    $item = array(
-      'client_identifier' => $file['fid'],
-      'file_url' => file_create_url($file['filepath']),
-    );
 
+  // Retrieve all file tests which are marked as needs testing.
+  $query = db_select('pift_test', 't', array('fetch' => PDO::FETCH_ASSOC))
+    ->fields('t', array('test_id', 'id'))
+    ->condition('type', 2, '=')
+    ->condition('status', 1, '=')
+    ->orderBy('id', 'DESC');
+  $result = $query->execute();
+  $tests = array();
+  foreach ($result as $record) {
+    $tests[$record['test_id']] = $record['id'];
+  }
+
+  // Retrieve the associated project_issue node for each test.
+  $query = new EntityFieldQuery();
+  $query->entityCondition('entity_type', 'node')
+    ->entityCondition('bundle', project_issue_issue_node_types())
+    ->propertyCondition('status', 1)
+    ->fieldCondition('field_issue_files', 'fid', $tests, 'IN');
+  $result = $query->execute();
+
+  // Load the project_issue entities
+  if (isset($result['node'])) {
+    $issue_nids = array_keys($result['node']);
+    $issues = entity_load('node', $issue_nids);
+  }
 
-    $branch_info_result = db_query('SELECT prn.nid AS rid, prn.version_major, prn.tag
-                             FROM {project_issues} pi, {project_release_nodes} prn
-                             WHERE pi.nid = :nid AND pi.rid = :rid', array(':nid' => $issue_nid, ':rid' => prn . nid), array('fetch' => PDO::FETCH_ASSOC));
+  // Foreach issue, datafill the file test batch array placeholder item
+  foreach ($issues as $issue) {
+    $pid = $issue->field_project[LANGUAGE_NONE][0]['target_id'];
+    $version = $issue->field_issue_version[LANGUAGE_NONE][0]['value'];
+    $rid = project_release_exists($pid, $version);
+    $item['branch_identifier'] = $rid;
 
-    $item['branch_identifier'] = $branch_info_result['rid'];
-    // Store branch as needed to be included with data.
-    $branches[$branch_info_result['rid']] = FALSE; // Do not test unless commit found.
+    // Store the branch as required for the file test to the 'branches' array.
+    // We mark the value 'FALSE' to indicate that we do not need to test this
+    // branch, unless a commit is found on that branch later in processing.
+    $branches[$rid] = FALSE;
 
-    // Get any dependent branches and add them to the $branches array
-    $branch_dependencies = project_dependency_get_dependencies($branch_info_result['rid'], PROJECT_DEPENDENCY_DEPENDENCY_REQUIRED);
+    // Add any additional branches which this branch is dependent on
+    $branch_dependencies = project_dependency_get_dependencies($rid, PROJECT_DEPENDENCY_DEPENDENCY_REQUIRED);
     foreach ($branch_dependencies as $dep) {
       $branches[$dep['release_nid']] = FALSE;
     }
 
-    // Generate link to file issue and comment if relevant.
-    if ($file['c_cid']) {
-      $item['link'] = url('node/' . $issue_nid, array('absolute' => TRUE, 'fragment' => 'comment-' . $file['c_cid']));
-    }
-    else {
-      $item['link'] = url('node/' . $issue_nid, array('absolute' => TRUE));
+    // Add each relevant file on this issue to the batch
+    foreach ($issue->field_issue_files[LANGUAGE_NONE] as $file) {
+      if (in_array($file['fid'], $tests)) {
+        // Finish datafilling the placeholder item.
+        $item['client_identifier'] = $file['fid'];
+        $item['file_url'] = file_create_url($file['uri']);
+        $item['link'] = url('node/' . $issue->nid, array('absolute' => TRUE));
+        // Add the placeholder item to the batch.
+        $batch['files'][] = $item;
+      }
     }
-
-    // Add file to batch.
-    $batch['files'][] = $item;
   }
 }
 
@@ -241,12 +254,19 @@ function pift_cron_queue_batch_build_files(array &$batch, array &$branches) {
  * @param array $branches Branches that must be loaded.
  */
 function pift_cron_queue_batch_build_branches(array &$branches) {
-  // Load the branches that are marked as needs testing or have never been tested.
-  $result = db_query('SELECT t.id AS rid
-                      FROM {pift_test} t
-                      WHERE t.type = :type
-                      AND t.status = :status
-                      LIMIT :limit', array(':type' => PIFT_TYPE_RELEASE, ':status' => PIFT_STATUS_QUEUE, ':limit' => PIFT_XMLRPC_MAX), array('fetch' => PDO::FETCH_ASSOC));
+  // Load branches that are marked as needs testing or have never been tested.
+  $result = db_query(
+    'SELECT t.id AS rid
+    FROM {pift_test} t
+    WHERE t.type = :type AND t.status = :status
+    LIMIT :limit',
+    array(
+      ':type' => PIFT_TYPE_RELEASE,
+      ':status' => PIFT_STATUS_QUEUE,
+      ':limit' => PIFT_XMLRPC_MAX
+    ),
+    array('fetch' => PDO::FETCH_ASSOC)
+  );
   foreach ($result as $branch) {
     $branches[$branch['rid']] = TRUE;
   }
@@ -275,29 +295,25 @@ function pift_cron_queue_batch_build_branches_process(array &$batch, array &$bra
 
     // Generate branch information.
     $item = array(
-      'project_identifier' => $branch->project_release['pid'],
+      'project_identifier' => $branch->field_release_project[LANGUAGE_NONE][0]['target_id'],
       'client_identifier' => $branch->nid,
-      'vcs_identifier' => $branch->project_release['tag'],
+      'vcs_identifier' => $branch->field_release_vcs_label[LANGUAGE_NONE][0]['value'],
       'dependency' => '',
       'plugin_argument' => array(),
       'test' => $test,
       'link' => url('node/' . $branch->nid, array('absolute' => TRUE)),
     );
 
-    // Attempt to determine the Drupal core API version.
+    // Determine the Drupal core API version.
     $api = array();
-    foreach ($branch->taxonomy as $tid => $term) {
-      if (in_array($tid, $api_versions)) {
-        $api['version'] = array_shift(explode('.', $term->name, 2));
-        $api['tid'] = $term->tid;
-        break;
-      }
+    $term = taxonomy_term_load(project_release_get_release_api_tid($branch));
+    if (in_array($term->tid, $api_versions)) {
+      $api['version'] = array_shift(exploide('.', $term->name, 2));
+      $api['tid'] = $term->tid;
     }
-
     // If the API version not found then ignore this branch.
-    if (empty($api)) {
+    else {
       watchdog('pift', 'Project release node [@nid] does not have a Drupal core API taxonomy term.', array('@nid' => $branch->nid), WATCHDOG_ERROR);
-      continue;
     }
 
     // If the project is Drupal core then add the plugin argument, otherwise
@@ -386,14 +402,16 @@ function pift_cron_queue_batch_build_projects(array &$batch, array $projects) {
  * @return array Release NIDs that match.
  */
 function pift_cron_get_release($pid, $tags) {
-  $result = db_query('SELECT nid
-                      FROM {project_release_nodes}
-                      WHERE pid = :pid
-                      AND tag IN (:tags)',
-                      array(':pid' => $pid, ':tags' => $tags));
+  $query = new EntityFieldQuery();
+  $query->entityCondition('entity_type', 'node')
+    ->entityCondition('bundle', 'project_release')
+    ->propertyCondition('status', 1)
+    ->fieldCondition('field_release_project', 'target_id', $pid, '=')
+    ->fieldCondition('field_release_vcs_label', 'value', $tags, 'IN');
+  $result = $query->execute();
   $rids = array();
-  while ($rid = $result->fetchField()) {
-    $rids[] = $rid;
+  if (isset($result['node'])) {
+    $rids = array_keys($result['node']);
   }
   return $rids;
 }
@@ -455,33 +473,19 @@ function pift_cron_check_auto_followup(array $result) {
     $test = pift_test_get($result['test_id']);
     if ($test['fid']) {
       // Get the current issue state and ensure that the test is the last one
-      // for the particular issue. Cycle through clauses to remove the need for
-      // an OR clause and thus improve performance.
+      // for the particular issue.
       $results = array();
-      foreach (array('u.nid = i.nid', 'cu.nid = i.nid') as $clause) {
-        $result = db_query('SELECT t.test_id, t.id
-                            FROM {pift_test} t
-                            LEFT JOIN {upload} u
-                              ON (t.type = :type AND t.id = u.fid)
-                            LEFT JOIN {comment_upload} cu
-                              ON (t.type = :type AND t.id = cu.fid)
-                            JOIN {project_issues} i
-                              ON ' . $clause . '
-                            WHERE u.nid = :nid OR cu.nid = :nid
-                            ORDER BY t.id DESC
-                            LIMIT 1',
-                            array(
-                              ':type' => PIFT_TYPE_FILE,
-                              ':nid' => $test['nid'],
-                            ), array('fetch' => PDO::FETCH_ASSOC));
-        $results[] = $result;
-      }
-
-      // To simulate OR clause and descending order by 'id' select the test_id
-      // that has the highest 'id' value.
-      $test_id = $results[0]['id'] > $results[1]['id'] ? $results[0]['test_id'] : $results[1]['test_id'];
-
-      if ($test_id == $test['test_id'] && pift_test_check_criteria_issue(node_load($test['nid']))) {
+      $query = db_select('pift_test', 't', array('fetch' => PDO::FETCH_ASSOC))
+        ->fields('t', array('test_id', 'id'))
+        ->condition('t.type', PIFT_TYPE_FILE, '=');
+      $query->leftJoin('field_data_field_issue_files', 'fd', 't.id = fd.field_issue_files_fid');
+      $query->join('project_issues', 'i', 'fd.entity_id = i.nid');
+      $query->condition('fd.entity_id', $test['nid'], '=');
+      $query->orderBy('t.id', 'DESC')
+        ->range(0,1);
+      $result = $query->execute()->fetchField();
+
+      if ($result == $test['test_id'] && pift_test_check_criteria_issue(node_load($test['nid']))) {
         // Test is last one for the particular issue and still fits the criteria.
         pift_cron_auto_followup($test['nid'], $test['cid'], $test['filename']);
       }
@@ -497,11 +501,11 @@ function pift_cron_check_auto_followup(array $result) {
  * @param string $filename Name of file.
  */
 function pift_cron_auto_followup($nid, $cid, $filename) {
-  project_issue_add_auto_followup(array(
-    'nid' => $nid,
-    'sid' => PIFT_FOLLOWUP_FAIL,
-    'comment' => theme('pift_auto_followup', array('type' => 'fail', 'nid' => $nid, 'cid' => $cid, 'filename' => $filename)),
-  ));
+  $node = node_load($nid);
+  $node->field_issue_status['value'] = PIFT_FOLLOWUP_FAIL;
+  $node->nodechanges_uid = variable_get('project_issue_followup_user', drupal_anonymous_user()->uid);
+  $node->nodechanges_comment_body['value'] = theme('pift_auto_followup', array('type' => 'fail', 'nid' => $nid, 'cid' => $cid, 'filename' => $filename));
+  node_save($node);
 }
 
 /**
diff --git a/pift.module b/pift.module
index 50aec00..fd9287e 100644
--- a/pift.module
+++ b/pift.module
@@ -18,7 +18,7 @@ define('PIFT_DESCRIPTION', variable_get('pift_description', ''));
 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', -1));
+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_DELETE', variable_get('pift_delete', FALSE));
 define('PIFT_LAST_RETRIEVE', variable_get('pift_last_retrieve', 1));
@@ -99,17 +99,21 @@ function pift_menu() {
     'file' => 'pift.pages.inc',
     'type' => MENU_CALLBACK,
   );
-  $items['node/%node/testing-status'] = array(
+
+// TODO: The plan was to remove the testing-status tab for the D7 Port, and
+// add it back in with Conduit.  However, we need somewhere to store the
+// 'enable testing' checkbox, so leaving this in temporarily until the Conduit
+// piece is available.
+  $items['node/%node/qa-settings'] = array(
     'title' => t('Automated Testing'),
     'access callback' => 'pift_results_visibility',
     'access arguments' => array(1),
-    'page callback' => 'pift_results_project_tab',
-    'page arguments' => array(1),
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('pift_pages_project_issue_settings', 1),
     'file' => 'pift.results.inc',
     'weight' => '5',
     'type' => MENU_LOCAL_TASK,
   );
-
   return $items;
 }
 
@@ -117,21 +121,14 @@ function pift_menu() {
  * Access callback to determine whether the Automated Testing tab is visible.
  */
 function pift_results_visibility($node) {
-  // Check if we have a module node which has a Git repository
-  // Do not display the tab if the project does not have any release nodes
-  // TODO: Once PIFT/PIFR has been refactored to use label_ids instead of
-  // release nids, the last condition can be changed to enable reporting
-  // of tests for any tag/branch within a project.
-
-  // Determine if node represents a valid project type for results display
-  $valid_type = array_intersect(variable_get('pift_results_display', array()), array_keys($node->taxonomy));
-  if ($node->type == 'project_project'
-     && !empty($valid_type)
-     && !empty($node->versioncontrol_project['repo']->vcs)
-     && $node->versioncontrol_project['repo']->vcs == 'git'
-     && user_access('pift access project testing tab')
-     && pift_get_releases($node, TRUE) != array()) {
-    return TRUE;
+  // Only display the tab on projects with releases
+  if (project_node_is_project($node)) {
+    if ($node->field_project_has_releases[$node->language][0]['value']) {
+      // Ensure user has access to enable testing on the node
+      if (user_access('pift enable project testing')) {
+        return TRUE;
+      }
+    }
   }
   return FALSE;
 }
@@ -216,45 +213,6 @@ function pift_cron() {
 }
 
 /**
- * Implements hook_versioncontrol_git_refs_updated().
- */
-function pift_versioncontrol_git_refs_updated($repository, $refs) {
-  // Ignore commits for disabled projects.
-  if (!pift_project_enabled($repository->project_nid)) {
-    return;
-  }
-
-  module_load_include('cron.inc', 'pift');
-
-  // @TODO Decide if we want to and how to handle with tags.
-  $api_versions = pift_core_api_versions();
-  $rids = pift_cron_get_release($repository->project_nid, array_keys($refs['branches']));
-  foreach ($rids as $rid) {
-    // Ensure that one of the compatibility terms is present on the release node.
-    $release = node_load($rid);
-    $found = FALSE;
-    foreach ($api_versions as $api_version) {
-      if (array_key_exists($api_version, $release->taxonomy)) {
-        // Compatible term found, continue processing.
-        $test_id = db_query('SELECT test_id
-                                        FROM {pift_test}
-                                        WHERE type = :type
-                                        AND id = :id', array(':type' => PIFT_TYPE_RELEASE, ':id' => $rid))->fetchField();
-
-        // If existing test for release, queue it, otherwise add a new test.
-        if ($test_id) {
-          pift_test_requeue($test_id);
-        }
-        else if ($test_id !== 0) {
-          pift_test_add(PIFT_TYPE_RELEASE, $rid);
-        }
-        break;
-      }
-    }
-  }
-}
-
-/**
  * Implements hook_versioncontrol_code_arrival().
  */
 function pift_versioncontrol_code_arrival(VersioncontrolRepository $repository, VersioncontrolEvent $event) {
@@ -310,11 +268,11 @@ function pift_get_releases($node, $quiet = FALSE) {
   $valid = pift_valid_prefix_list();
   $branches = array();
   $topbranches = array();
-  if ($node->type == 'project_project') {
+  if (project_node_is_project($node)) {
     $result = db_query("Select b.name from {versioncontrol_release_labels} a
        join {versioncontrol_labels} b on a.label_id = b.label_id
-       where a.project_nid = %s", $node->nid);
-    while ($data = db_fetch_object($result)) {
+       where a.project_nid = :nid", array(':nid' => $node->nid));
+    foreach ($result as $data) {
       // Filter out any branches < 6 (not accepted by PIFT)
       // Move '.x' releases to the top
       if (in_array(substr($data->name, 0, 3), $valid)) {
@@ -376,53 +334,46 @@ function pift_array_reverse($array) {
 }
 
 /**
- * Implements hook_form_alter(). Must use generic form_alter() due to().
- * comment_upload implementation.
+ * Implements hook_form_FORM_ID_alter().
  */
-function pift_form_alter(&$form, $form_state, $form_id) {
-  if ($form_id == 'comment_form' || $form_id == 'project_issue_node_form') {
+function pift_form_project_issue_node_form_alter(&$form, $form_state, $form_id) {
     module_load_include('pages.inc', 'pift');
     pift_pages_description_add($form, $form_state, $form_id);
-  }
-}
-
-/**
- * Implements hook_form_alter(): project_issue_project_edit_form().
- */
-function pift_form_project_issue_project_edit_form_alter(&$form, $form_state) {
-  module_load_include('pages.inc', 'pift');
-  pift_pages_project_issue_settings($form, $form_state);
 }
 
 /**
  * Implements hook_node_view().
- */
-function pift_node_view($node, $view_mode = 'full') {
-  if (pift_node_is_interesting($node)) {
-    if (!$a3 && pift_project_enabled($node->project_issue['pid'])) { // Full view.
-      $files = pift_test_get_files_node($node->nid);
-      $status = $node->project_issue['sid'];
-      $node->content['pift_files'] = array(
-        '#value' => '<div id="pift-results-' . $node->nid . '">' .
-                        theme('pift_attachments', array('files' => $files, 'closed' => $status)) . '</div>',
-        '#weight' => 50,
-      );
-      unset($node->content['files']); // Remove old attachments table.
-    }
-  }
-}
+ *
+ * TODO:  This approach is no longer valid after the project* changes. The
+ * new approach will be to implement a field formatter on the field_issue_files
+ * field, and add the pift testing results via this field formatter; which
+ * should be much cleaner than removing and injecting the file attachments
+ * table as was done in D6.
+ */
+//function pift_node_view($node, $view_mode = 'full') {
+//  if (pift_node_is_interesting($node)) {
+//    if (!$a3 && pift_project_enabled($node->project_issue['pid'])) { // Full view.
+//      $files = pift_test_get_files_node($node->nid);
+//      $status = $node->project_issue['sid'];
+//      $node->content['pift_files'] = array(
+//        '#value' => '<div id="pift-results-' . $node->nid . '">' .
+//                        theme('pift_attachments', array('files' => $files, 'closed' => $status)) . '</div>',
+//        '#weight' => 50,
+//      );
+//      unset($node->content['files']); // Remove old attachments table.
+//    }
+//  }
+//}
 
 /**
  * Implements hook_node_insert().
  */
 function pift_node_insert($node) {
   if (pift_node_is_interesting($node)) {
-    pift_node_alias_update($node);
-
-    $proper = pift_nodeapi_clean($node);
-    if (pift_test_check_criteria_issue($proper)) {
-      $files = upload_load($proper);
-      pift_test_add_files($files);
+    if (!empty($node->field_issue_files)) {
+      if (pift_test_check_criteria_issue($node)) {
+        pift_test_add_files($node->field_issue_files);
+      }
     }
   }
 }
@@ -431,7 +382,15 @@ function pift_node_insert($node) {
  * Implements hook_node_update().
  */
 function pift_node_update($node) {
-  pift_node_alias_update($node);
+  if (pift_node_is_interesting($node)) {
+    if ($node->field_issue_files != $node->original->field_issue_files) {
+      if (!empty($node->field_issue_files)) {
+        if (pift_test_check_criteria_issue($node)) {
+          pift_test_add_files($node->field_issue_files);
+        }
+      }
+    }
+  }
 }
 
 /**
@@ -439,29 +398,12 @@ function pift_node_update($node) {
  */
 function pift_node_delete($node) {
   if (pift_node_is_interesting($node)) {
-    pift_node_alias_update($node, TRUE);
-
-    // Flag pift that a project node was deleted.
-    variable_set('pift_delete', TRUE);
-  }
-}
-
-/**
- * Maintain "nice" url aliases for testing status pages.
- *
- * @todo Use pathauto in rewrite (just cleaning up slightly in port).
- */
-function pift_node_alias_update($node, $delete_only = FALSE) {
-  if ($node->type == 'project_project') {
-    $src = 'node/' . $node->nid . '/testing-status';
-    if ($delete_only) {
-      path_delete(array('src' => $src));
-    }
-    else {
-      $path = path_load(array('src' => $src));
-      $path['dst'] = 'project/' . drupal_encode_path($node->project['uri']) . '/testing-status';
-      path_save($path);
+    // Flag pift that a project or issue node was deleted.
+    if (project_node_is_project($node)) {
+      // Remove this project from the pift_project table
+      db_delete('pift_project')->condition('nid', $node->nid)->execute();
     }
+    variable_set('pift_delete', TRUE);
   }
 }
 
@@ -471,85 +413,104 @@ function pift_node_alias_update($node, $delete_only = FALSE) {
  * Used in hook_node_*() to filter out irrelevant nodes.
  */
 function pift_node_is_interesting($node) {
-  return $node->type == 'project_project' || ($node->type == 'project_issue' && !empty($node->files));
+  return project_node_is_project($node) || (project_issue_node_is_issue($node) && !empty($node->field_issue_files));
 }
 
 /**
  * Cleanup the inconsistent project_issue property placement.
  *
+ * TODO:  Confirm this approach is no longer valid after the project* changes.
+ *
  * In order to remove the need to a bunch of conditions all over PIFT, convert
  * the inconsistent node format to the one used everywhere else. The
  * inconsistent format is only found during node creation, after a node has
  * been created and hook_load() is used the properties are prefixed by
  * project_issue.
  *
+ *
+ *
  * @param object $node Node to convert.
  * @return object Properly formatted node.
  * @link http://drupal.org/node/519562
  */
-function pift_nodeapi_clean($node) {
-  $node->project_issue = array();
-
-  $fields = array('pid', 'rid', 'component', 'category', 'priority', 'assigned', 'sid');
-  foreach ($fields as $field) {
-    $node->project_issue[$field] = $node->$field;
-  }
-
-  return $node;
-}
+//function pift_nodeapi_clean($node) {
+//  $node->project_issue = array();
+//
+//  $fields = array('pid', 'rid', 'component', 'category', 'priority', 'assigned', 'sid');
+//  foreach ($fields as $field) {
+//    $node->project_issue[$field] = $node->$field;
+//  }
+//
+//  return $node;
+//}
 
 /**
  * Implements hook_comment_view().
- */
-function pift_comment_view($comment) {
-  if ($node = pift_comment_is_insteresting($comment)) {
-    if (!empty($comment->files) && pift_project_enabled($node->project_issue['pid'])) {
-      // Remove comment_upload attachments table and generate new one.
-      $comment->comment = preg_replace('/<table class="comment-upload-attachments">.*?<\/table>/s', '', $comment->comment);
-      $files = pift_test_get_files_comment($comment->cid);
-      $status = $node->project_issue['sid'];
-      $comment->comment .= '<div id="pift-results-' . $comment->nid . '-' . $comment->cid . '">' .
-                              theme('pift_attachments', array('files' => $files, 'closed' => $status)) . '</div>';
-    }
-  }
-}
+ *
+ * TODO:  This approach is no longer valid after the project* changes. The
+ * new approach will be to implement a field formatter on the field_issue_files
+ * field and comments, and add the pift testing results via this field
+ * formatter; which should be much cleaner than removing and injecting the file
+ * attachments table as was done in D6.
+ */
+//function pift_comment_view($comment) {
+//  if ($node = pift_comment_is_interesting($comment)) {
+//    if (!empty($comment->files) && pift_project_enabled($node->project_issue['pid'])) {
+//      // Remove comment_upload attachments table and generate new one.
+//      $comment->comment = preg_replace('/<table class="comment-upload-attachments">.*?<\/table>/s', '', $comment->comment);
+//      $files = pift_test_get_files_comment($comment->cid);
+//      $status = $node->project_issue['sid'];
+//      $comment->comment .= '<div id="pift-results-' . $comment->nid . '-' . $comment->cid . '">' .
+//                              theme('pift_attachments', array('files' => $files, 'closed' => $status)) . '</div>';
+//    }
+//  }
+//}
 
 /**
  * Implements hook_comment_insert().
- */
-function pift_comment_insert($comment) {
-  if ($node = pift_comment_is_insteresting($comment)) {
-    if (pift_test_check_criteria_issue($node)) {
-      if (!empty($comment->files)) {
-        // Add attachments to this comment to the send queue.
-        $files = comment_upload_load_files($comment['cid']);
-        pift_test_add_files($files);
-      }
-
-      // Add previously submitted files if issue state changes.
-      pift_test_add_previous_files($comment['nid']);
-    }
-  }
-}
+ *
+ * TODO:  This approach is no longer valid after the project* changes. Files
+ * and patches are now attached to the node directly.
+ */
+//function pift_comment_insert($comment) {
+//  if ($node = pift_comment_is_interesting($comment)) {
+//    if (pift_test_check_criteria_issue($node)) {
+//      if (!empty($comment->files)) {
+//        // Add attachments to this comment to the send queue.
+//        $files = comment_upload_load_files($comment['cid']);
+//        pift_test_add_files($files);
+//      }
+//      // Add previously submitted files if issue state changes.
+//      pift_test_add_previous_files($comment['nid']);
+//    }
+//  }
+//}
 
 /**
  * Implements hook_comment_delete().
+ *
+ * TODO:  Determine if we want to remove patches when the associated comment is
+ * deleted ... this may now be redundant, since we can simply delete the file
+ * from the field_issue_files field.
  */
-function pift_comment_delete($comment) {
-  if (pift_comment_is_insteresting($comment)) {
-    variable_set('pift_delete', TRUE);
-  }
-}
+//function pift_comment_delete($comment) {
+//  if (pift_comment_is_interesting($comment)) {
+//    variable_set('pift_delete', TRUE);
+//  }
+//}
 
 /**
  * Check that comment is attached to a project_issue node.
+ *
+ * TODO:  This is only called from three functions, all of which have been
+ * commented out as part of the D7 port.
  */
-function pift_comment_is_insteresting($comment) {
-  if (($node = node_load($comment->nid)) && $node->type == 'project_issue') {
-    return $node;
-  }
-  return FALSE;
-}
+//function pift_comment_is_interesting($comment) {
+//  if (($node = node_load($comment->nid)) && $node->type == 'project_issue') {
+//    return $node;
+//  }
+//  return FALSE;
+//}
 
 /**
  * Theme the auto followup comments.
@@ -561,6 +522,8 @@ function pift_comment_is_insteresting($comment) {
  * @return string HTML output.
  */
 function theme_pift_auto_followup($variables) {
+  // TODO: Validate whether these variables are still valid after the project*
+  // changes introduced with the D7 port.
   $type = $variables['type'];
   $nid = $variables['nid'];
   $cid = $variables['cid'];
@@ -604,21 +567,47 @@ function pift_core_api_versions() {
  */
 function pift_core_api_release($api_tid) {
   static $api_releases = array();
-
   if (!isset($api_branches[$api_tid])) {
-    $result = db_query('SELECT p.nid
-                        FROM {node} n
-                        JOIN {project_release_nodes} p
-                          ON p.nid = n.nid
-                        JOIN {taxonomy_term_node} t
-                          ON t.vid = n.vid
-                        WHERE p.pid = :p.pid
-                        AND p.rebuild = :p.rebuild
-                        AND t.tid = :t.tid
-                        ORDER BY n.vid DESC
-                        LIMIT 1', array(':p.pid' => PIFT_PID, ':p.rebuild' => 1, ':t.tid' => $api_tid));
-    $api_releases[$api_tid] = $result->fetchField();
+    $api_vocabulary = taxonomy_vocabulary_load(variable_get('project_release_api_vocabulary', ''));
+    $taxonomy_field = 'taxonomy_vocabulary_' . $api_vocabulary->machine_name;
+
+    $query = new EntityFieldQuery();
+    $query->entityCondition('entity_type', 'node')
+      ->entityCondition('bundle', 'project_release')   // TODO: Drupal.org specific
+      ->fieldCondition('field_release_project', 'target_id', PIFT_PID, '=')
+      ->fieldCondition($taxonomy_field, 'tid', $api_tid)
+      ->propertyOrderBy('nid', 'DESC')
+      ->range(0,1);
+    $result = $query->execute();
+
+    if (isset($result['node'])) {
+      $api_releases[$api_tid] = reset(array_keys($result['node']));
+    }
   }
 
   return $api_releases[$api_tid];
 }
+
+/**
+ * Return a list of active project release compatibility terms in the system.
+ */
+function pift_compatibility_list() {
+  $compatibility_list = array();
+
+  $query = new EntityFieldQuery();
+  $query->entityCondition('entity_type', 'taxonomy_term')
+    ->propertyCondition('vid', variable_get('project_release_api_vocabulary', -1))
+    ->fieldCondition('field_release_recommended', 'value', '1');
+  $result = $query->execute();
+
+  if (isset($result['taxonomy_term'])) {
+    $term_ids = array_keys($result['taxonomy_term']);
+    $terms = entity_load('taxonomy_term', $term_ids);
+  }
+
+  foreach ($terms as $key => $term) {
+    $compatibility_list[$key] = $term->name;
+  }
+
+  return $compatibility_list;
+}
diff --git a/pift.pages.inc b/pift.pages.inc
index 7fc0cf9..f431100 100644
--- a/pift.pages.inc
+++ b/pift.pages.inc
@@ -8,26 +8,23 @@
  */
 
 /**
- * Add additional description to attachment form.
+ * Add additional description to file attachment form on issues.
  */
 function pift_pages_description_add(&$form, $form_state, $form_id) {
-
   global $user;
-  // Add description on uploads if it is set.
+  // Add description on field_issue_files if it is set.
   if (PIFT_DESCRIPTION) {
     // Detect project issue node ID.
     $nid = NULL;
-    if ($form_id == 'comment_form' && isset($form['original_issue'])) {
-      $node = node_load($form['nid']['#value']);
-      $nid = $node->project_issue['pid'];
-    }
-    elseif ($form_id == 'project_issue_node_form') {
-      $nid = $form['project_info']['pid']['#value'];
-    }
-
-    if (isset($form['attachments']['wrapper']['new']['upload']) && $nid && pift_project_enabled($nid)) {
-      $description = filter_xss_admin(PIFT_DESCRIPTION);
-      $form['attachments']['wrapper']['new']['upload']['#description'] .= $description;
+    // TODO: This is drupal.org specific, as any node type can be marked as an
+    // issue after the Project* D7 changes.  This code assumes a single node
+    // type of 'project_issue'.
+    if ($form_id == 'project_issue_node_form') {
+      $nid = $form['#node']->field_project['und'][0]['target_id'];
+      if (isset($form['field_issue_files'][LANGUAGE_NONE]['#file_upload_description']) && $nid && pift_project_enabled($nid)) {
+        $description = filter_xss_admin(PIFT_DESCRIPTION);
+        $form['field_issue_files'][LANGUAGE_NONE]['#file_upload_description'] .= " " . $description;
+      }
     }
   }
 }
@@ -35,15 +32,8 @@ function pift_pages_description_add(&$form, $form_state, $form_id) {
 /**
  * Add testing setting.
  */
-function pift_pages_project_issue_settings(&$form, $form_state) {
-  // We don't want to inject any of these settings the project has no releases.
-  $project_node = node_load($form['nid']['#value']);
-  if (empty($project_node->project_release['releases'])) {
-    return;
-  }
-
-  $form['issue']['#weight'] = -10;
-  $form['issue']['#email'] = -8;
+function pift_pages_project_issue_settings(&$form, $form_state, $node) {
+  $form = array();
   $form['testing'] = array(
     '#type' => 'fieldset',
     '#title' => t('Testing'),
@@ -64,9 +54,12 @@ function pift_pages_project_issue_settings(&$form, $form_state) {
     '#title' => t('Enable automated testing'),
     '#description' => t('Enable automated testing of @versions compatible branches and patches.',
       array('@versions' => implode(', ', $versions))),
-    '#default_value' => pift_project_enabled($form['nid']['#value']),
+    '#default_value' => pift_project_enabled($node->nid),
+  );
+  $form['testing']['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save Settings'),
   );
-  $form['#submit'][] = 'pift_pages_project_issue_settings_submit';
 }
 
 /**
@@ -145,27 +138,20 @@ function pift_pages_retest_confirm_form($form, &$form_state, $test_id) {
  */
 function pift_pages_retest_confirm_form_submit($form, &$form_state) {
   global $user;
-
   $test = $form_state['values']['test'];
-
   if ($test['status'] > PIFT_STATUS_SENT) {
     if ($test['type'] == PIFT_TYPE_FILE) {
       // Base changes to be made in followup comment.
-      $changes = array(
-        'nid' => $test['nid'],
-        'uid' => $user->uid,
-        'comment' => theme('pift_auto_followup', array('type' => 'retest', 'nid' => $test['nid'], 'cid' => $test['cid'], 'filename' => $test['title'])),
-      );
-
+      $node = node_load($test['nid']);
+      $node->nodechanges_uid = $user->uid;
+      $node->nodechanges_comment_body['value'] = theme('pift_auto_followup', array('type' => 'retest', 'nid' => $test['nid'], 'cid' => $test['cid'], 'filename' => $test['title']));
       // If node issue status is not already a valid status then set to default
       // retest status, otherwise leave status alone.
-      $node = node_load($test['nid']);
       if (!in_array($node->project_issue['sid'], variable_get('pift_status', array()))) {
-        $changes['sid'] = PIFT_FOLLOWUP_RETEST;
+        $node->field_issue_status['value'] = PIFT_FOLLOWUP_RETEST;
       }
-
       // Add followup to issue.
-      project_issue_add_auto_followup($changes);
+      node_save($node);
     }
 
     // Update test record to reflect change.
@@ -244,7 +230,8 @@ function pift_pages_delete_test_confirm_form_submit($form, &$form_state) {
  * @return string HTML output.
  */
 function theme_pift_attachments($variables) {
-  // TODO: Not sure if these are correct.
+  // TODO: Validate whether these variables are still valid after the project*
+  // changes introduced with the D7 port.
   $files = $variables['files'];
   $status = $variables['status'];
   $header = array(t('Attachment'), t('Size'), t('Status'), t('Test result'), t('Operations'));
diff --git a/pift.results.inc b/pift.results.inc
deleted file mode 100644
index 9e049e5..0000000
--- a/pift.results.inc
+++ /dev/null
@@ -1,317 +0,0 @@
-<?php
-
-/**
- * @file
- * Provide the Automated Testing tab and UI functions.
- */
-
-/**
- * Produce html code for the Automated Testing tab.
- */
-function pift_results_project_tab($node, $version = NULL) {
-  // Load array of release branches in this projects repo.
-  $versions = pift_get_releases($node);
-
-  if (empty($version) && !empty($versions)) {
-    $version = current($versions);
-  }
-
-  // Retrieve project test results for the current branch/tag from {PIFT_TEST}
-  $tests = pift_results_testresult_load($node, $versions);
-
-  // Determine list of releases without tests
-  $noresults = $versions;
-
-  if (!empty($tests)) {
-    foreach ($tests as $testdata) {
-      foreach ($testdata as $test) {
-        unset($noresults[$test['version']]);
-      }
-    }
-    // Format test results
-    $statusoutput = pift_results_format_testresult_table($tests);
-  }
-  else {
-    $statusoutput = pift_results_empty_text();
-  }
-
-  // Okay we have the variable data let's build the page.
-  $content = array();
-  $content[] = '<p>' . t('This page provides information regarding automated testing status for this project\'s releases.') . '</p>';
-
-  // Add the 'Testing Status' table
-  $content[] = '<h3>' . t('Branch Test Results') . '</h3>';
-  $content[] =  $statusoutput;
-
-  // If there are any untested branches, provide a form which can be
-  // used to initiate an 'on-demand' branch test.
-  if (!empty($noresults)) {
-    $content[] = '<br /><br />' . drupal_get_form('pift_results_test_branch_form', $node, $noresults);
-  }
-
-  // TODO:  (Future development) If test has been queued or sent for too
-  // long, provide a form which will allow the user to reset the test (by
-  // updating status for tests with id = branch_nid in the pift_test table)
-
-  return implode("\n", $content);
-}
-
-/**
- * Prepare a form API array to mark a specific module version for testing
- *
- * @param $form_state
- * @param $project object The project node object
- * @param versions array List of versions
- * @return array
- */
-function pift_results_test_branch_form($form, &$form_state, $project, $versions = array()) {
-  $form = array(
-    '#prefix' => '<div class="container-inline">',
-    '#suffix' => '</div>',
-  );
-
-  $description = '<strong>' . t('Note: Automated tests are typically run on ".x" branches.') . '</strong><br />';
-  $description .= t('Core examples: 6.x, 7.x, 8.x') . '<br />';
-  $description .= t('Contrib examples: 6.x-1.x, 7.x-2.x, 8.x-1.x') . '<br />';
-  $description = t('Marking a branch for testing will add it to the list of branch/patch requests sent to the automated testing infrastructure. ');
-  $description .= t('Once the tests complete, the results will be passed back to drupal.org and reflected on this page. ');
-  $description .= '<br />';
-
-  $form['nid'] = array(
-    '#type' => 'value',
-    '#value' => $project->nid,
-  );
-
-  $form['additional'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Test Additional Branches'),
-    '#collapsible' => TRUE,
-    '#collapsed' => TRUE,
-    '#prefix' => '<div>',
-    '#suffix' => '</div>',
-    '#description' => $description,
-  );
-
-  $form['additional']['version'] = array(
-    '#type' => 'select',
-    '#title' => t('Select a branch/tag to queue for testing'),
-    '#options' => $versions,
-    '#required' => TRUE,
-  );
-
-  $form['additional'][] = array(
-    '#type' => 'submit',
-    '#value' => t('Queue Test'),
-  );
-
-  return $form;
-}
-
-/**
- * Validate the submitted pift_results_test_branch_form form
- *
- * @param $form form to validate
- * @param $form_state A keyed array containing the current state of the form.
- */
-function pift_results_test_branch_form_validate($form, &$form_state) {
-  // Ensure required values have been passed
-  if (!$form_state['values']['nid'] || !$form_state['values']['version']) {
-    form_set_error('form', t('Error: Unable to determine correct project tag/branch.'));
-  }
-}
-
-/**
- * Process the submitted pift_results_test_branch_form form
- *
- * @param $form form to submit
- * @param $form_state A keyed array containing the current state of the form.
- */
-function pift_results_test_branch_form_submit($form, &$form_state) {
-  pift_results_test_add($form_state['values']['nid'], $form_state['values']['version']);
-}
-
-/**
- * Queues a particular project branch/tag/release for testing
- *
- * @param $nid The node id for the given project to be tested
- * @param $version A label representing a particular project branch/tag/release
- */
-function pift_results_test_add($nid, $version) {
-
-  // Get the repo_id for the project
-  $repo_id = db_query("SELECT repo_id FROM {versioncontrol_project_projects} WHERE nid = :nid", array(':nid' => $nid))->fetchField();
-
-  // Get the label_id for the passed version
-  $label_id = db_query("SELECT label_id FROM {versioncontrol_labels} WHERE repo_id = :repo_id AND name = :name", array(':repo_id' => $repo_id, ':name' => $version))->fetchField();
-
-  /********************* Version Control Label ID code ********************
-   // For use if/when PIFT/PIFR are refactored to use label_id instead of release_nid.
-   if ($label_id) {
-   db_query('INSERT INTO {pift_test} (type, id, status) VALUES (%d, %d, %d)', PIFT_TYPE_RELEASE, $label_id, PIFT_STATUS_QUEUE);
-   drupal_set_message(t("This project branch/tag has been queued for testing."));
-   }
-   else {
-   drupal_set_message("Unable to queue this project branch/tag for testing, due to an error in resolving the corresponding label ID.", 'error');
-   }
-   */
-  /********************* Release Nid code ********************/
-  $release_nid = db_query("SELECT release_nid FROM {versioncontrol_release_labels} WHERE label_id = :label_id AND project_nid = :project_nid", array(':label_id' => $label_id, ':project_nid' => $nid))->fetchField();
-  if ($release_nid) {
-    $id = db_insert('pift_test')
-      ->fields(array(
-        'type' => PIFT_TYPE_RELEASE,
-        'id' => $release_nid,
-        'status' => PIFT_STATUS_QUEUE,
-      ))
-      ->execute();
-    drupal_set_message("This project branch/tag has been queued for testing.");
-  }
-  else {
-    drupal_set_message("This branch does not have an associated release node.  Unable to queue branch for testing.", 'error');
-  }
-}
-
-/**
- * Retrieves recent testing status for a given project branch/tag/release
- *
- * @param $node The node id for the given project
- * @param $versions An array of project branch/tag/release labels
- *
- * @return $status Array of test results, or FALSE if no results available
- */
-function pift_results_testresult_load($node, $versions) {
-  // Ensure we've been passed an actual project node
-  if ($node->type != 'project_project') {
-    return FALSE;
-  }
-  // Initialize placeholder for test results return value
-  $tests = array();
-
-  // Get the repo_id for the project
-  $repo_id = db_query("SELECT repo_id FROM {versioncontrol_project_projects} WHERE nid = :nid", array(':nid' => $node->nid))->fetchField();
-
-  // Get the label_ids for the passed versions
-  $label_ids = array();
-  $result = db_query("SELECT label_id, name FROM {versioncontrol_labels}
-          WHERE repo_id = :repo_id AND name IN (:versions)",
-          array(':repo_id' => $repo_id, ':versions' => $versions), array('fetch' => PDO::FETCH_ASSOC));
-  foreach ($result as $data) {
-    $label_ids[$data->name] = $data->label_id;
-  }
-
-  /********************* Version Control Label ID code ********************
-   // Get the branch test results for this label_id
-   $sql = "Select * from {pift_test} where type = 1 and id IN (" . db_placeholders($label_ids, 'int') . ")";
-   $result = db_query($sql, $label_ids);
-   */
-  /********************* Release Nid code ********************/
-  // Retrieve corresponding release nids for the requested labels
-  $release_nids = array();
-  $result = db_query("SELECT release_nid, label_id FROM {versioncontrol_release_labels}
-          WHERE project_nid = :project_nid AND label_id IN (:label_ids)",
-          array(':project_nid' => $node->nid, ':label_ids' => $label_ids), array('fetch' => PDO::FETCH_ASSOC));
-  foreach ($result as $data) {
-    $release_nids[$data->label_id] = $data->release_nid;
-  }
-
-  // Obtain the actual test results
-  $sql = "SELECT test_id, status, message, id, last_tested FROM {pift_test}
-          WHERE type = 1 AND id IN (:release_nids)
-          ORDER BY last_tested DESC";
-  $result = db_query($sql, array(':release_nids' => $release_nids), array('fetch' => PDO::FETCH_ASSOC));
-  foreach ($result as $data) {
-    $data['version'] = array_search(array_search($data['id'], $release_nids), $label_ids);
-    unset($data['id']);
-    $tests[$data['version']][] = $data;
-  }
-  if (!empty($tests)) {
-    // Re-order tests array
-    $sorted = array();
-    foreach ($versions as $version) {
-      if (array_key_exists($version, $tests)) {
-        $sorted[] = $tests[$version];
-      }
-    }
-    return $sorted;
-  }
-  return FALSE;
-}
-
-/**
- * Formats the testing results table for output
- *
- * @param $tests An array of test statuses to be rendered
- *
- * @return Themed table containing the testing status for the given branch
- */
-function pift_results_format_testresult_table($tests = array()) {
-  if (!empty($tests)) {
-    $header = array('Version', 'Status', 'Result', 'Last Tested', 'Operations');
-    foreach ($tests as $testdata) {
-      foreach ($testdata as $test) {
-        $rows[] = pift_results_build_testresult_row($test);
-      }
-    }
-  }
-  return theme('table', array('header' => $header, 'rows' => $rows));
-}
-
-/**
- * Formats a row of the testing results table for output
- *
- * @param $test An array of test status information to render
- *
- * @return Themed table containing the testing status for the given branch
- */
-function pift_results_build_testresult_row($test = array()) {
-  if (!empty($test)) {
-    $options = array(
-      '1' => 'Queued',
-      '2' => 'Sent',
-      '3' => 'Failed',
-      '4' => 'Passed',
-    );
-    $rowclass = array(
-      '1' => 'pift-retest',
-      '2' => 'pift-retest',
-      '3' => 'pift-fail',
-      '4' => 'pift-pass',
-    );
-    $operations = array();
-    // A first-time queued test will not have a test_id, so hide links
-    if ($test['test_id'] > 0) {
-      $operations = array(
-        l('View Test', variable_get('pift_server', 'http://qa.drupal.org/') . 'pifr/test/' . $test['test_id']),
-      );
-      if (user_access('pift re-test files') && $test['status'] > PIFT_STATUS_SENT) {
-        $operations[] = l('Re-test', 'pift/retest/' . $test['test_id']);
-      }
-      if (user_access('pift re-test files') && $test['status'] == PIFT_STATUS_SENT) {
-        $operations[] = l('Remove Test', 'pift/delete/' . $test['test_id']);
-      }
-    }
-    // Hide old results if new test queued/sent
-    if ($test['status'] <= PIFT_STATUS_SENT) {
-      $test['message'] = t('Waiting for results.');
-    }
-    // Format 'Last Tested' value
-    $test['last_tested'] = $test['last_tested'] > 0 ? format_date($test['last_tested'], 'short') : 'never';
-    $row = array(
-      'data' => array($test['version'], $options[$test['status']], $test['message'], $test['last_tested'], implode(" | ", $operations)),
-      'class' => $rowclass[$test['status']],
-    );
-    return $row;
-  }
-  return array();
-}
-
-/**
- * Returns the default 'no test results available' text
- */
-function pift_results_empty_text() {
-  $default = <<<EOT
-<p>No Test Results Available.</p>
-<p>Please use the 'queue test' form below to trigger a new test.</p>
-EOT;
-  return $default;
-}
diff --git a/pift.test.inc b/pift.test.inc
index 61eb4d5..38cfafb 100644
--- a/pift.test.inc
+++ b/pift.test.inc
@@ -14,81 +14,113 @@
  * @return array Test data.
  */
 function pift_test_get($test_id) {
-  return db_query('SELECT t.*, f.fid, f.filename, f.filepath, f.filesize,
-                                     IF(u.nid IS NULL, cu.nid, u.nid) AS nid, cu.cid
-                                   FROM {pift_test} t
-                                   LEFT JOIN {files} f
-                                     ON (t.type = :type AND t.id = f.fid)
-                                   LEFT JOIN {upload} u
-                                     ON f.fid = u.fid
-                                   LEFT JOIN {comment_upload} cu
-                                     ON f.fid = cu.fid
-                                   WHERE t.test_id = :test_id', array(':type' => PIFT_TYPE_FILE, ':test_id' => $test_id), array('fetch' => PDO::FETCH_ASSOC));
+  // Get test and files
+  $query = db_query('SELECT t.*, f.fid, f.filename, f.filepath, f.filesize,
+      FROM {pift_test} t
+      LEFT JOIN {file_managed} f
+        ON (t.type = :type AND t.id = f.fid)
+      WHERE t.test_id = :test_id',
+    array(':type' => PIFT_TYPE_FILE, ':test_id' => $test_id),
+    array('fetch' => PDO::FETCH_ASSOC)
+  );
+  $test = $query->execute()->fetchAssoc();
+
+  // Retrieve the associated project_issue node for each test.
+  $query = new EntityFieldQuery();
+  $query->entityCondition('entity_type', 'node')
+    ->entityCondition('bundle', project_issue_issue_node_types())
+    ->propertyCondition('status', 1)
+    ->fieldCondition('field_issue_files', 'fid', $test['fid'], '=');
+  $result = $query->execute();
+  // Load the project_issue entities
+  if (isset($result['node'])) {
+    $test['nid'] = reset(array_keys($result['node']));
+    $issue = entity_load('node', $test['nid']);
+    // TODO: Determine how to add "cid" to the test item.
+  }
+  return $test;
 }
 
 /**
  * Get the files and test data for the specified comment ID.
  *
+ * TODO:  Confirm this is no longer required after the Project* changes during
+ * the port to D7.  This is only called from pift_comment_view(), which should
+ * no longer be required.
+ *
  * @param integer $cid Comment ID.
  * @return array List of files and test data.
  */
-function pift_test_get_files_comment($cid) {
-  return db_query('SELECT f.fid, f.filename, f.filepath, f.filesize, cu.nid, cu.cid, t.*
-                      FROM {files} f
-                      INNER JOIN {comment_upload} cu
-                        ON f.fid = cu.fid
-                      LEFT JOIN {pift_test} t
-                        ON (t.type = :type AND f.fid = t.id)
-                      WHERE cu.cid = :cid
-                      ORDER BY cu.weight, f.fid', array(':type' => PIFT_TYPE_FILE, ':cid' => $cid), array('fetch' => PDO::FETCH_ASSOC));
-}
+//function pift_test_get_files_comment($cid) {
+//  return db_query('SELECT f.fid, f.filename, f.filepath, f.filesize, cu.nid, cu.cid, t.*
+//                      FROM {files} f
+//                      INNER JOIN {comment_upload} cu
+//                        ON f.fid = cu.fid
+//                      LEFT JOIN {pift_test} t
+//                        ON (t.type = :type AND f.fid = t.id)
+//                      WHERE cu.cid = :cid
+//                      ORDER BY cu.weight, f.fid', array(':type' => PIFT_TYPE_FILE, ':cid' => $cid), array('fetch' => PDO::FETCH_ASSOC));
+//}
 
 /**
  * Get the files and test data on comments for the specified node ID.
  *
+ * TODO:  Confirm this is no longer required after the Project* changes during
+ * the port to D7.  Because all files are now attached to the node itself, we
+ * should no longer need to concern ourselves with comments.
+ *
  * @param integer $nid Node ID.
  * @return array List of files and test data.
  */
-function pift_test_get_files_comment_all($nid) {
-  return db_query('SELECT f.fid, f.filename, f.filepath, f.filesize, cu.nid, cu.cid, t.*
-                      FROM {files} f
-                      INNER JOIN {comment_upload} cu
-                        ON f.fid = cu.fid
-                      LEFT JOIN {pift_test} t
-                        ON (t.type = :type AND f.fid = t.id)
-                      WHERE cu.nid = :nid
-                      ORDER BY cu.weight, f.fid', array(':type' => PIFT_TYPE_FILE, ':nid' => $nid), array('fetch' => PDO::FETCH_ASSOC));
-}
-
+//function pift_test_get_files_comment_all($nid) {
+//  return db_query('SELECT f.fid, f.filename, f.filepath, f.filesize, cu.nid, cu.cid, t.*
+//                      FROM {files} f
+//                      INNER JOIN {comment_upload} cu
+//                        ON f.fid = cu.fid
+//                      LEFT JOIN {pift_test} t
+//                        ON (t.type = :type AND f.fid = t.id)
+//                      WHERE cu.nid = :nid
+//                      ORDER BY cu.weight, f.fid', array(':type' => PIFT_TYPE_FILE, ':nid' => $nid), array('fetch' => PDO::FETCH_ASSOC));
+//}
 
 /**
  * Get the files and test data for the specified node ID.
  *
+ * TODO: Confirm this is no longer needed after the Project* changes during the
+ * port to D7.  This is only called from pift_test_get_files_node_all, which is
+ * only called from pift_test_add_previous_files(), which in turn is only
+ * called from pift_comment_insert(); which does not apply now that all files
+ * are attached to a node directly.
+ *
  * @param integer $nid Node ID.
  * @return array List of files and test data.
  */
-function pift_test_get_files_node($nid) {
-  $node = node_load($nid);
-  return db_query('SELECT f.fid, f.filename, f.filepath, f.filesize, u.nid, t.*
-                      FROM {files} f
-                      INNER JOIN {upload} u
-                        ON f.fid = u.fid
-                      LEFT JOIN {pift_test} t
-                        ON (t.type = :type AND f.fid = t.id)
-                      WHERE u.nid = :nid AND u.vid = :vid
-                      ORDER BY u.weight, f.fid', array(':type' => PIFT_TYPE_FILE, 'nid' => $node->nid, ':vid' => $node->vid), array('fetch' => PDO::FETCH_ASSOC));
-}
+//function pift_test_get_files_node($nid) {
+//  return db_query('SELECT f.fid, f.filename, f.filepath, f.filesize, u.nid, t.*
+//                      FROM {files} f
+//                      INNER JOIN {upload} u
+//                        ON f.fid = u.fid
+//                      LEFT JOIN {pift_test} t
+//                        ON (t.type = :type AND f.fid = t.id)
+//                      WHERE u.nid = :nid AND u.vid = :vid
+//                      ORDER BY u.weight, f.fid', array(':type' => PIFT_TYPE_FILE, 'nid' => $node->nid, ':vid' => $node->vid), array('fetch' => PDO::FETCH_ASSOC));
+//}
 
 
 /**
  * Get the files and test data for the specified node ID and its comments.
  *
+ * TODO: Confirm this is no longer needed after the Project* changes during the
+ * port to D7.  This is only called from pift_test_add_previous_files(), which
+ * in turn is only called from pift_comment_insert(); which does not apply now
+ * that all files are attached to a node directly.
+ *
  * @param integer $nid Node ID.
  * @return array List of files and test data.
  */
-function pift_test_get_files_node_all($nid) {
-  return array_merge(pift_test_get_files_node($nid), pift_test_get_files_comment_all($nid));
-}
+//function pift_test_get_files_node_all($nid) {
+//  return array_merge(pift_test_get_files_node($nid), pift_test_get_files_comment_all($nid));
+//}
 
 /**
  * Check the criteria for the specified issue.
@@ -99,25 +131,29 @@ function pift_test_get_files_node_all($nid) {
  * @return boolean Passed criteria.
  */
 function pift_test_check_criteria_issue($node) {
-  // Ensure that the issue is in one of the acceptable statuses.
-  if (!in_array($node->project_issue['sid'], variable_get('pift_status', array()))) {
+  // Ensure we are passed an issue node
+  if (!project_issue_node_is_issue()) {
+    return FALSE;
+  }
+  // Ensure the issue has a valid 'testing' status
+  if (!in_array($node->field_issue_status[LANGUAGE_NONE][0]['value'], variable_get('pift_status', array()))) {
     return FALSE;
   }
-
   // Ensure that the project has testing enabled.
-  if (!pift_project_enabled($node->project_issue['pid'])) {
+  $pid = $node->field_project[LANGUAGE_NONE][0]['target_id'];
+  if (!pift_project_enabled($pid)) {
     return FALSE;
   }
-
   // Ensure that one of the compatibility terms is present on the release node.
-  $release = node_load($node->project_issue['rid']);
-  $api_versions = pift_core_api_versions();
-  foreach ($api_versions as $api_version) {
-    if (array_key_exists($api_version, $release->taxonomy)) {
-      return TRUE;
-    }
+  $version = $node->field_issue_version[LANGUAGE_NONE][0]['value'];
+  if (!($rid = project_release_exists($pid, $version))) {
+    return FALSE;
+  }
+  $release_node = node_load($rid);
+  $release_api = project_release_get_release_api_tid($release_node);
+  if (array_key_exists($release_api, pift_core_api_versions())) {
+    return TRUE;
   }
-
   return FALSE;
 }
 
@@ -140,8 +176,7 @@ function pift_test_check_criteria_file(array $file) {
  * @param array $files Files to add.
  */
 function pift_test_add_files(array $files) {
-  foreach ($files as $file) {
-    $file = (array) $file;
+  foreach ($files[LANGUAGE_NONE] as $file) {
     if (pift_test_check_criteria_file($file)) {
       pift_test_add(PIFT_TYPE_FILE, $file['fid']);
     }
@@ -201,21 +236,25 @@ function pift_test_delete_files() {
     WHERE type = :type
     AND id NOT IN (
       SELECT fid
-      FROM {files}
+      FROM {file_managed}
     )', array(':type' => PIFT_TYPE_FILE));
 }
 
 /**
  * Add previously submitted files once the node meets the criteria.
  *
+ * TODO:  Confirm this is no longer required after the Project* changes during
+ * the port to D7.  This is only called from pift_comment_insert(), which is
+ * irrelevant when files are attached directly to a node.
+ *
  * @param integer $nid Node ID.
  */
-function pift_test_add_previous_files($nid) {
-  $files = pift_test_get_files_node_all($nid);
-  foreach ($files as $file) {
-    $file = (array) $file;
-    if ($file['test_id'] === NULL && pift_test_check_criteria_file($file)) {
-      pift_test_add(PIFT_TYPE_FILE, $file['fid']);
-    }
-  }
-}
+//function pift_test_add_previous_files($nid) {
+//  $files = pift_test_get_files_node_all($nid);
+//  foreach ($files as $file) {
+//    $file = (array) $file;
+//    if ($file['test_id'] === NULL && pift_test_check_criteria_file($file)) {
+//      pift_test_add(PIFT_TYPE_FILE, $file['fid']);
+//    }
+//  }
+//}
