Index: server/pifr_server.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue_file_review/server/pifr_server.test,v
retrieving revision 1.12
diff -u -r1.12 pifr_server.test
--- server/pifr_server.test	21 Sep 2009 19:41:18 -0000	1.12
+++ server/pifr_server.test	24 Sep 2009 02:55:39 -0000
@@ -197,6 +197,7 @@
    * Implementation of setUp().
    */
   public function setUp() {
+    require_once 'includes/xmlrpc.inc';
     parent::setUp('pifr', 'chart', 'pifr_server', 'pifr_client');
 
     module_load_include('xmlrpc.inc', 'pifr_server');
@@ -354,7 +355,7 @@
     $batch['files'][] = array(
       'test_id' => 2,
       'branch_nid' => 201,
-      'file_url' => drupal_get_path('module', 'pifr_server') . '/server/confirmation/syntax.patch',
+      'file_url' => drupal_get_path('module', 'pifr_server') . '/confirmation/syntax.patch',
       'issue_nid' => 300,
       'issue_cid' => 400,
     );
Index: server/pifr_server.xmlrpc.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue_file_review/server/pifr_server.xmlrpc.inc,v
retrieving revision 1.29
diff -u -r1.29 pifr_server.xmlrpc.inc
--- server/pifr_server.xmlrpc.inc	13 Aug 2009 20:23:08 -0000	1.29
+++ server/pifr_server.xmlrpc.inc	24 Sep 2009 02:55:39 -0000
@@ -313,7 +313,7 @@
   if ($client) {
     pifr_debug('XML-RPC result(): valid test client.');
 
-    // Ensure that test was assigned to client.
+    // Ensure that test was sent to the client returning the result.
     $test = pifr_server_test_get($result['test_id']);
     if ($test['status'] != PIFR_SERVER_TEST_STATUS_SENT || $test['client_id'] != $client['client_id']) {
       watchdog('pifr_server', 'Test not assigned to client: (t: @test_id, c: @client_id)',
Index: server/pifr_server.manage.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue_file_review/server/pifr_server.manage.inc,v
retrieving revision 1.24
diff -u -r1.24 pifr_server.manage.inc
--- server/pifr_server.manage.inc	22 Sep 2009 01:14:31 -0000	1.24
+++ server/pifr_server.manage.inc	24 Sep 2009 02:55:39 -0000
@@ -234,35 +234,27 @@
   }
 
   // No need to display list of environments if user cannot create a test client.
-  if (user_access('pifr add test client')) {
-    $form['client']['environment_id'] = array(
-      '#type' => 'radios',
-      '#title' => t('Environment'),
-      '#description' => t('The environment the client will be testing (does not apply to project client).'),
-      '#options' => array(
-        PIFR_SERVER_CLIENT_ENVIRONMENT_MYSQL_5_0_ISAM,
-        PIFR_SERVER_CLIENT_ENVIRONMENT_POSTGRES,
-        PIFR_SERVER_CLIENT_ENVIRONMENT_SQLITE,
-        PIFR_SERVER_CLIENT_ENVIRONMENT_MYSQL_5_1_ISAM,
-        PIFR_SERVER_CLIENT_ENVIRONMENT_MYSQL_5_0_INNO,
-      ),
-      '#default_value' => (isset($client) ? $client['environment_id'] : PIFR_SERVER_CLIENT_ENVIRONMENT_MYSQL_5_0_ISAM),
-      '#required' => TRUE
-    );
-    $form['client']['environment_id']['#options'] = drupal_map_assoc($form['client']['environment_id']['#options'],
-      'pifr_server_client_environment');
-  }
-  else {
-    $form['client']['environment_id'] = array(
-      '#type' => 'value',
-      '#value' => PIFR_SERVER_CLIENT_ENVIRONMENT_MYSQL_5_0_ISAM,
-    );
+  $form['client']['environment'] = array(
+    '#type' => 'checkboxes',
+    '#title' => t('Environment'),
+    '#description' => t('The environment(s) the client will be testing.'),
+    '#options' => array(),
+    '#default_value' => (isset($client) ? $client['environment'] : array()),
+    '#access' => user_access('pifr add test client'),
+  );
+  $environments = pifr_server_environment_get_all();
+  foreach ($environments as $environment) {
+    $form['client']['environment']['#options'][$environment['environment_id']] = $environment['environment_key'];
   }
 
   $form['op'] = array(
     '#type' => 'submit',
     '#value' => t('Save')
   );
+  $form['cancel'] = array(
+    '#type' => 'markup',
+    '#value' => l(t('Cancel'), 'user/' . $GLOBALS['user']->uid . '/pifr'),
+  );
 
   return $form;
 }
@@ -280,6 +272,9 @@
   else if (drupal_substr($form_state['values']['url'], drupal_strlen($form_state['values']['url']) - 1) != '/') {
     form_set_error('url', t('Client URL must end with a slash.'));
   }
+  if ($form_state['values']['type'] == PIFR_SERVER_CLIENT_TYPE_TEST && !in_array(1, $form_state['values']['environment'])) {
+    form_set_error('environment', t('At least one environment must be selected.'));
+  }
 }
 
 
Index: server/pifr_server.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue_file_review/server/pifr_server.install,v
retrieving revision 1.31
diff -u -r1.31 pifr_server.install
--- server/pifr_server.install	22 Sep 2009 00:49:56 -0000	1.31
+++ server/pifr_server.install	24 Sep 2009 02:55:39 -0000
@@ -34,10 +34,12 @@
         'unsigned' => TRUE,
         'not null' => TRUE,
       ),
-      'environment_id' => array(
-        'description' => t('Environment ID which the client will test (does not apply to project client).'),
-        'type' => 'int',
+      'environment' => array(
+        'description' => t('Environment ID(s) which the client can test (does not apply to project client).'),
+        'type' => 'varchar',
         'not null' => TRUE,
+        'length' => 255,
+        'default' => '',
       ),
       'uid' => array(
         'description' => t('Reference to user that controls client.'),
@@ -70,6 +72,30 @@
     ),
     'primary key' => array('client_id'),
   );
+  $schema['pifr_client_test'] = array(
+    'description' => t('Keep track of client confirmation testing stage.'),
+    'fields' => array(
+      'client_id' => array(
+        'description' => t('Reference to client ID.'),
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'environment_id' => array(
+        'description' => t('Current environment in which the testing is taking place.'),
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'stage' => array(
+        'description' => t('Arbitrary stage in the client confirmation process.'),
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+    ),
+    'primary key' => array('client_id'),
+  );
   $schema['pifr_branch'] = array(
     'description' => t('Store branch information.'),
     'fields' => array(
@@ -202,6 +228,7 @@
       ),
     ),
     'indexes' => array(
+      'test_id' => array('test_id'),
       'client_id' => array('client_id'),
     ),
     'primary key' => array('test_id', 'environment_id'),
@@ -391,9 +418,8 @@
         'type' => 'int',
         'not null' => TRUE,
       ),
-      'type' => array(
-        'description' => t('Type of result, either client confirmation for one of results (PIFR_SERVER_CLIENT_RESULT_*), ' .
-                           'or environment type (PIFR_SERVER_CLIENT_ENVIRONMENT_*).'),
+      'environment_id' => array(
+        'description' => t('Environment ID (from pifr_environment table) for which the result was obtained in.'),
         'type' => 'int',
         'not null' => TRUE,
       ),
Index: server/pifr_server.test.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue_file_review/server/pifr_server.test.inc,v
retrieving revision 1.37
diff -u -r1.37 pifr_server.test.inc
--- server/pifr_server.test.inc	20 Aug 2009 00:30:43 -0000	1.37
+++ server/pifr_server.test.inc	24 Sep 2009 02:55:39 -0000
@@ -19,53 +19,85 @@
                                    WHERE test_id = %d', $test_id));
 }
 
-function pifr_server_test_get_client($client_id) {
-  return db_fetch_array(db_query('SELECT *
-                                   FROM {pifr_test}
-                                   WHERE client_id = %d
-                                   AND status = %d', $client_id, PIFR_SERVER_TEST_STATUS_SENT));
-}
-
+/**
+ * Get the current test being reviewed by a client.
+ *
+ * @param array $client Client information.
+ * @return mixed Test information, or FALSE.
+ */
+function pifr_server_test_get_client(array $client) {
+  $result = db_query('SELECT t.*
+                      FROM {pifr_test} t
+                      JOIN {pifr_environment_status} s
+                        ON t.test_id = s.test_id
+                      WHERE s.client_id = %d', $client['client_id']);
+  return db_fetch_array($result);
+}
+
+/**
+ * Get the next eligible test for a client.
+ *
+ * @param array $client Client information.
+ * @return array Test information, or an empty array.
+ */
 function pifr_server_test_get_next(array $client) {
-  $test = pifr_server_test_get($client['test_id']);
-  if (time() - $test['last_tested'] >= (PIFR_SERVER_CLIENT_TEST_INTERVAL * 60 * 60)) {
-    // Client needs to be re-confirmed.
-    pifr_server_client_confirmation_init($client);
-    $client = pifr_server_client_get($client['client_id']);
-  }
+  // Check if client tests need to be re-run.
+  $client = pifr_server_client_confirmation_necessary($client);
 
   if ($client['status'] == PIFR_SERVER_CLIENT_STATUS_TESTING) {
-    // Next client test file.
+    // Return the next stage of the client testing process.
     $test = pifr_server_test_get($client['test_id']);
-    pifr_server_test_sent($test, $client);
-    return pifr_server_client_confirmation_next($client);
+    if ($test['status'] == PIFR_SERVER_TEST_STATUS_SENT) {
+      // TODO Make some sort of public note that the failure is due to the
+      // client requesting another test without properly returning the results.
+      pifr_server_client_confirmation_fail($client);
+    }
+    else {
+      pifr_server_test_sent($test, $client);
+      return pifr_server_client_confirmation_next($client);
+    }
   }
   else if ($client['status'] == PIFR_SERVER_CLIENT_STATUS_ENABLED) {
     // If the client currently has a test out, reset the test.
-    $test = pifr_server_test_get_client($client['client_id']);
-    if ($test) {
-      $test['status'] = PIFR_SERVER_TEST_STATUS_QUEUED;
-      pifr_server_test_save($test);
-      pifr_server_log_event($test['test_id'], t('Test reset by client request.'));
-    }
-
-    // Next branch or file test.
-    $test = db_fetch_array(db_query('SELECT t.*
-                                     FROM {pifr_test} t
-                                     LEFT JOIN {pifr_result} r
-                                       ON (t.test_id = r.test_id AND r.type = %d)
-                                     WHERE t.type != %d
-                                     AND t.status = %d
-                                     AND r.result_id IS NULL
-                                     ORDER BY t.type, t.test_count, t.last_tested, t.test_id
-                                     LIMIT 1',
-                                     $client['environment_id'], PIFR_SERVER_TEST_TYPE_CLIENT, PIFR_SERVER_TEST_STATUS_QUEUED));
-    if ($test) {
+    if ($test = pifr_server_test_get_client($client)) {
+      pifr_server_test_reset($test, $client);
+    }
+
+    // Next eligible branch or file test.
+    if ($test = pifr_server_test_get_next_eligible($client)) {
       pifr_server_test_sent($test, $client);
+
+      // Prepare test XML-RPC reponse.
       return pifr_server_test_xmlrpc($test);
     }
-    return array();
   }
+
+  // No eligibile tests for the client at this time.
+  return array();
+}
+
+/**
+ * Get the next eligible branch or file test.
+ *
+ * @param array $client Client information.
+ * @return mixed Test information, or FALSE.
+ */
+function pifr_server_test_get_next_eligible(array $client) {
+  $test = db_query('SELECT t.*
+                    FROM {pifr_test} t
+                    LEFT JOIN {pifr_environment_status} s
+                      ON (t.test_id = s.test_id AND s.environment_id IN (' . db_placeholders($client['environment'], 'int') . ')
+                    LEFT JOIN {pifr_result} r
+                      ON (t.test_id = r.test_id AND r.type = %d)
+                    WHERE t.type != %d
+                    AND t.status = %d
+                    AND s.client_id IS NULL
+                    AND r.result_id IS NULL
+                    ORDER BY t.type, t.test_count, t.last_tested, t.test_id
+                    LIMIT 1',
+                    array_merge(array($client['environment_id']), $client['environment'],
+                    array(PIFR_SERVER_TEST_TYPE_CLIENT, PIFR_SERVER_TEST_STATUS_QUEUED)));
+  return db_fetch_array($test);
 }
 
 function pifr_server_test_get_since($timestamp) {
@@ -80,28 +112,43 @@
   return $tests;
 }
 
+/**
+ * Build XML-RPC reponse for pifr.next() containing test definition.
+ *
+ * @param array $test Test information.
+ * @return array Test definition as defined by pifr_server_xmlrpc_next().
+ * @see pifr_server_xmlrpc_next()
+ */
 function pifr_server_test_xmlrpc(array $test) {
+  // Initiate reponse with test ID.
   $response = array(
     'test_id' => $test['test_id'],
   );
 
+  // Add test type specific information.
   if ($test['type'] == PIFR_SERVER_TEST_TYPE_FILE) {
+    // File test, load file information and related branch.
     $file = pifr_server_file_get_test($test['test_id']);
     $response['file_url'] = pifr_server_file_get_url($file);
 
     $branch = pifr_server_branch_get($file['branch_id']);
-    $project = pifr_server_project_get($branch['project_id']);
   }
   else {
+    // Branch test, load related branch.
     $branch = pifr_server_branch_get_test($test['test_id']);
-    $project = pifr_server_project_get($branch['project_id']);
   }
 
+  // Get the project related to the branch.
+  $project = pifr_server_project_get($branch['project_id']);
+
+  // Check if branch depends on a specific core branch, otherwise assume the
+  // branch being tested is a core branch.
   if ($branch['core_branch_id']) {
     // Load core branch.
     $core_branch = pifr_server_branch_get($branch['core_branch_id']);
     $core_project = pifr_server_project_get($core_branch['project_id']);
 
+    // Place branch information in module section.
     $response['module'] = array(
       'repository' => array(
         'type' => $project['repository_type'],
@@ -111,10 +158,12 @@
     );
   }
   else {
+    // No module branch, so set branch being tested to core branch.
     $core_branch = $branch;
     $core_project = $project;
   }
 
+  // Add core branch information to response.
   $response['core'] = array(
     'repository' => array(
       'type' => $core_project['repository_type'],
@@ -125,63 +174,107 @@
   return $response;
 }
 
+/**
+ * Queue test for testing.
+ *
+ * If test is already queued or currently being tested the queue request will
+ * be ignored and an appropriate log message will be made.
+ *
+ * @param array $test Test information.
+ */
 function pifr_server_test_queue(array $test) {
-  if ($test['status'] == PIFR_SERVER_TEST_STATUS_SENT) {
-    pifr_server_log_event($test['test_id'], t('Re-test request ignored (test is active).'));
+  if ($test['status'] == PIFR_SERVER_TEST_STATUS_QUEUED) {
+    pifr_server_log_event($test['test_id'], t('Re-test request ignored because test is already queued.'));
+  }
+  elseif ($test['status'] == PIFR_SERVER_TEST_STATUS_SENT) {
+    pifr_server_log_event($test['test_id'], t('Re-test request ignored because test is currently being tested.'));
   }
   else {
+    // Update test status and last received timestamp.
     $test['status'] = PIFR_SERVER_TEST_STATUS_QUEUED;
     $test['last_received'] = time();
     pifr_server_test_save($test);
+
+    // Clear the previous results for the test.
     pifr_server_result_clear($test['test_id']);
+
+    // Log the test queue event.
     pifr_server_log_event($test['test_id'], t('@action request received.',
                           array('@action' => $test['test_count'] == 0 ? t('Test') : t('Re-test'))));
   }
 }
 
+/**
+ * Perform test send event operations.
+ *
+ * @param array $test Test information.
+ * @param array $client Client information.
+ */
 function pifr_server_test_sent(array $test, array $client) {
-  $test['status'] = PIFR_SERVER_TEST_STATUS_SENT;
-  $test['client_id'] = $client['client_id'];
+  // Reserver the client's environment for the test.
+  pifr_server_environment_status_reserve($client['environment_id'], $test['test_id'], $client['client_id']);
+
+  // Update the last requested timestamp.
   $test['last_requested'] = time();
   pifr_server_test_save($test);
 
+  // Log the event.
   pifr_server_log_event($test['test_id'], t('Requested by test client #@client_id.',
                                             array('@client_id' => $client['client_id'])));
 }
 
+/**
+ * Perform test reset event operations.
+ *
+ * @param array $test Test information.
+ * @param array $client Client information.
+ */
+function pifr_server_test_reset(array $test, array $client) {
+  // Clear environment reservation.
+  pifr_server_environment_status_clear($client['environment_id'], $test['test_id']);
+
+  // Log the event.
+  pifr_server_log_event($test['test_id'], t('Test reset by client request.'));
+}
+
+/**
+ * Record the result of a test.
+ *
+ * @param array $test Test information.
+ * @param array $result Result information, see pifr_server_xmlrpc_result().
+ * @param array $client Client information.
+ * @see pifr_server_xmlrpc_result()
+ */
 function pifr_server_test_result(array $test, array $result, array $client) {
   $results = pifr_server_result_get_all($test['test_id']);
+  $environments = pifr_server_environment_get_all_test($test['test_id']);
 
-  // Update test record.
-  if ($result['code'] != PIFR_SERVER_TEST_RESULT_PASS || count($results) + 1 == PIFR_SERVER_CLIENT_ENVIRONMENT_COUNT) {
-    $test['status'] = PIFR_SERVER_TEST_STATUS_RESULT;
-  }
-  else {
-    $test['status'] = PIFR_SERVER_TEST_STATUS_QUEUED;
-  }
+  // Update test record to reflect the fact that a result has been returned.
+  $test['status'] = count($results) == count($environemnts) ? PIFR_SERVER_TEST_STATUS_RESULT : PIFR_SERVER_TEST_STATUS_QUEUED;
   $test['last_tested'] = time();
   $test['test_count']++;
   pifr_server_test_save($test);
 
-  // Save test results.
-  if ($client['status'] == PIFR_SERVER_CLIENT_STATUS_TESTING) {
-    $last = pifr_server_client_confirmation_last($client);
-    $result['type'] = $last + 1;
-  }
-  else {
-    $result['type'] = $client['environment_id'];
-  }
+  // Prepare the results for saving. Determine the environment ID that the
+  // client is supposed to be testing.
+  $environment_id = pifr_server_environment_status_get_client($test, $client);
+  $result['environment_id'] = $environment_id;
   $result['details'] = serialize($result['details']);
+
+  // Save the prepared result.
   pifr_server_result_save($result);
 
+  // Log the test result event.
   pifr_server_log_event($test['test_id'], t('Result received from test client #@client_id.',
                                             array('@client_id' => $client['client_id'])));
 
-  if ($client['status'] == PIFR_SERVER_CLIENT_STATUS_TESTING) {
+  // If client is undergoing testing then allow the results to be checked based
+  // on the client confirmation testing stage. If testing is incomplete then
+  // the test may be re-enabled.
+  if ($test['type'] == PIFR_SERVER_TEST_TYPE_CLIENT) {
     pifr_server_client_confirmation_check($client, $result);
   }
-
-  if ($test['type'] == PIFR_SERVER_TEST_TYPE_BRANCH) {
+  elseif ($test['type'] == PIFR_SERVER_TEST_TYPE_BRANCH) {
     // Branch result may effect related files.
     $branch = pifr_server_branch_get_test($test['test_id']);
     if ($result['code'] == PIFR_SERVER_TEST_RESULT_PASS) {
@@ -226,13 +319,21 @@
             WHERE test_id = %d', $test_id);
 }
 
+/**
+ * View a test result.
+ *
+ * @param integer $test_id Test ID.
+ * @return string HTML output.
+ */
 function pifr_server_test_view($test_id) {
-  drupal_add_css(drupal_get_path('module', 'pifr') . '/pifr.css');
-  drupal_add_css(drupal_get_path('module', 'pifr_server') . '/pifr_server.css');
-  drupal_add_js(drupal_get_path('module', 'pifr_server') . '/pifr_server.js');
+  // Determine if the specified test ID is a valid test.
+  if ($test = pifr_server_test_get($test_id)) {
+    // Include style sheets and javascript.
+    drupal_add_css(drupal_get_path('module', 'pifr') . '/pifr.css');
+    drupal_add_css(drupal_get_path('module', 'pifr_server') . '/pifr_server.css');
+    drupal_add_js(drupal_get_path('module', 'pifr_server') . '/pifr_server.js');
 
-  $test = pifr_server_test_get($test_id);
-  if ($test) {
+    // Load the object that will generate the proper test information.
     $object = PIFRTest::getInstanceByTest($test_id);
 
     drupal_set_title(t('View test - @title', array('@title' => $object->getTitle())));
@@ -256,9 +357,10 @@
       '#attributes' => array('id' => 'pifr-environment', 'class' => 'pifr-test'),
       '#weight' => -9,
     );
+    $rows = $object->getEnvironmentTable();
     $form['environment']['table'] = array(
       '#type' => 'markup',
-      '#value' => theme('table', array(), $object->getEnvironmentTable()),
+      '#value' => $rows ? theme('table', array(), $rows) : '<em>' . t('No applicable environments.') . '</em>',
     );
 
     $form['info'] = array(
@@ -308,10 +410,6 @@
       $rows = array();
 
       for ($i = 1; $i <= PIFR_SERVER_TEST_RESULT_PASS; $i++) {
-        if ($i == PIFR_SERVER_TEST_RESULT_FORMAT) {
-          continue;
-        }
-
         $row = array();
         $row['status'] = $map['exception'];
         $row['step'] = pifr_server_client_step($i);
@@ -551,7 +649,7 @@
     // Insert a row and status for each relevant environment.
     $environments = pifr_server_environment_get_all_test($this->test['test_id']);
     foreach ($environments as $environment) {
-      $status = pifr_server_environment_get_status($environment['environment_id'], $this->test['test_id']);
+      $status = pifr_server_environment_status_get($environment['environment_id'], $this->test['test_id']);
       $message = t($status['status']);
       if ($status['status'] == 'result') {
         $message = $status['code'] == PIFR_SERVER_TEST_RESULT_PASS ? 'pass' : 'fail';
Index: server/pifr_server.result.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue_file_review/server/pifr_server.result.inc,v
retrieving revision 1.16
diff -u -r1.16 pifr_server.result.inc
--- server/pifr_server.result.inc	29 Jul 2009 04:39:44 -0000	1.16
+++ server/pifr_server.result.inc	24 Sep 2009 02:55:39 -0000
@@ -45,20 +45,20 @@
  * Get all the results for a particular test.
  *
  * @param integer $test_id Test ID.
- * @return array Set of results keyed by result type. The results will be in
- *   order of increasing type ID.
+ * @return array Set of results keyed by environment ID and arein order of
+ *   increasing environment ID.
  * @see pifr_server_result_get().
  */
 function pifr_server_result_get_all($test_id) {
   $results = db_query('SELECT result_id
                        FROM {pifr_result}
                        WHERE test_id = %d
-                       ORDER BY type ASC', $test_id);
+                       ORDER BY environment_id ASC', $test_id);
 
   $test_results = array();
   while ($result_id = db_result($results)) {
     $result = pifr_server_result_get($result_id);
-    $test_results[$result['type']] = $result;
+    $test_results[$result['environment_id']] = $result;
   }
   return $test_results;
 }
@@ -132,8 +132,6 @@
       return 'Unable to apply patch.';
     case PIFR_SERVER_TEST_RESULT_SYNTAX:
       return 'Invalid PHP syntax in @filename.';
-    case PIFR_SERVER_TEST_RESULT_FORMAT:
-      return '-- not implemented --';
     case PIFR_SERVER_TEST_RESULT_INSTALL:
       return 'Failed to install Drupal on @environment.';
     case PIFR_SERVER_TEST_RESULT_TEST:
@@ -161,8 +159,6 @@
       return 'Unable to apply patch.';
     case PIFR_SERVER_TEST_RESULT_SYNTAX:
       return 'Invalid PHP syntax.';
-    case PIFR_SERVER_TEST_RESULT_FORMAT:
-      return '-- not implemented --';
     case PIFR_SERVER_TEST_RESULT_INSTALL:
       return 'Failed to install Drupal.';
     case PIFR_SERVER_TEST_RESULT_TEST:
Index: server/pifr_server.file.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue_file_review/server/pifr_server.file.inc,v
retrieving revision 1.23
diff -u -r1.23 pifr_server.file.inc
--- server/pifr_server.file.inc	24 Jul 2009 02:00:43 -0000	1.23
+++ server/pifr_server.file.inc	24 Sep 2009 02:55:39 -0000
@@ -39,6 +39,13 @@
                                    WHERE test_id = %d', $test_id));
 }
 
+/**
+ * Update the status all file tests related to the branch.
+ *
+ * @param integer $branch_id Branch ID.
+ * @param integer $status_from Status to update from.
+ * @param integer $status_to Status to change to.
+ */
 function pifr_server_file_branch_update($branch_id, $status_from, $status_to) {
   db_query('UPDATE {pifr_test}
             SET status = %d
Index: server/pifr_server.client.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue_file_review/server/pifr_server.client.inc,v
retrieving revision 1.32
diff -u -r1.32 pifr_server.client.inc
--- server/pifr_server.client.inc	5 Aug 2009 21:12:13 -0000	1.32
+++ server/pifr_server.client.inc	24 Sep 2009 02:55:39 -0000
@@ -17,7 +17,9 @@
   $result = db_query('SELECT *
                       FROM {pifr_client}
                       WHERE client_id = %d', $client_id);
-  return db_fetch_array($result);
+  $client = db_fetch_array($result);
+  $client['environment'] = unserialize($client['environment']);
+  return $client;
 }
 
 /**
@@ -30,14 +32,18 @@
   $result = db_query("SELECT *
                       FROM {pifr_client}
                       WHERE client_key = '%s'", $client_key);
-  return db_fetch_array($result);
+  $client = db_fetch_array($result);
+  $client['environment'] = unserialize($client['environment']);
+  return $client;
 }
 
 function pifr_server_client_get_test($test_id) {
   $result = db_query("SELECT *
                       FROM {pifr_client}
                       WHERE test_id = %d", $test_id);
-  return db_fetch_array($result);
+  $client = db_fetch_array($result);
+  $client['environment'] = unserialize($client['environment']);
+  return $client;
 }
 
 /**
@@ -59,6 +65,7 @@
 
   $clients = array();
   while ($client = db_fetch_array($result)) {
+    $client['environment'] = unserialize($client['environment']);
     $clients[] = $client;
   }
   return $clients;
@@ -99,130 +106,199 @@
 
   $clients = array();
   while ($client = db_fetch_array($result)) {
+    $client['environment'] = unserialize($client['environment']);
     $clients[] = $client;
   }
   return $clients;
 }
 
 /**
- * Initialize the confirmation process.
+ * Check if client confirmation tests need to be rerun and if so queue them.
+ *
+ * If the client confirmation tests were last tested longer then the the client
+ * test interval then set initiate the client testing process.
+ *
+ * @param array $client Client information.
+ * @return array Client information which may be updated if client testing
+ *   process was started.
+ * @see pifr_server_client_confirmation_init()
+ */
+function pifr_server_client_confirmation_necessary(array $client) {
+  $test = pifr_server_test_get($client['test_id']);
+  if (time() - $test['last_tested'] >= (PIFR_SERVER_CLIENT_TEST_INTERVAL * 60 * 60)) {
+    pifr_server_client_confirmation_init($client);
+    $client = pifr_server_client_get($client['client_id']);
+  }
+  return $client;
+}
+
+/**
+ * Initialize the client confirmation process.
+ *
+ * If the client is a project client it is simply enabled, but if the client
+ * is a testing client then it is marked as testing and the related client test
+ * is queued.
  *
  * @param array $client Client.
  */
 function pifr_server_client_confirmation_init(array $client) {
+  // Currently there is no testing of project clients, so just enable.
   if ($client['type'] == PIFR_SERVER_CLIENT_TYPE_PROJECT) {
     $client['status'] = PIFR_SERVER_CLIENT_STATUS_ENABLED;
     pifr_server_client_save($client);
     return;
   }
 
+  // Mark client as testing.
   $client['status'] = PIFR_SERVER_CLIENT_STATUS_TESTING;
   pifr_server_client_save($client);
 
+  // Queue client test.
   $test = pifr_server_test_get($client['test_id']);
   pifr_server_test_queue($test);
+}
 
-  // Check client versin number.
-  if (!pifr_server_client_confirmation_check_version($client)) {
-    pifr_server_client_confirmation_fail($client);
-
-    // TODO Store message that explains version issue.
+/**
+ * Get the next stage of the client confirmation testing process.
+ *
+ * @param array $client Client information.
+ * @return array XML-RPC reponse containing test definition.
+ */
+function pifr_server_client_confirmation_next($client) {
+  // Determine the current status of the client confirmation test process.
+  $environments = pifr_server_environment_get_all_test($client['test_id']);
+  $status = pifr_server_client_confirmation_status($client);
+  if (!$status) {
+    // Client confirmation process has not started, pick the first environment.
+    $status = array(
+      'client_id' => $client['client_id'],
+      'environment_id' => $environment[0]['environment_id'],
+      'stage' => 1,
+    );
+  }
+  elseif ($status['stage'] == 0) {
+    // Confirmation testing of the current environment has been completed.
+    // Begin testing of next environment or mark testing as complete.
+    $next = FALSE;
+    foreach ($environments as $environment) {
+      if ($next) {
+        $status['environment_id'] = $environment['environment_id'];
+        $status['stage'] = 1;
+        break;
+      }
+
+      if ($environment['environment_id'] == $status['environment_id']) {
+        $next = TRUE;
+      }
+    }
+  }
+  else {
+    // Incrament stage and continue testing on current environment.
+    $status['stage']++;
   }
-}
 
-function pifr_server_client_confirmation_check_version(array $client) {
-  $info = parse_ini_file(drupal_get_path('module', 'pifr') . '/pifr.info');
-  $version = (isset($info['version']) ? $info['version'] : 'unknown');
+  // Save update status information.
+  pifr_server_client_confirmation_status_save($status, $client);
 
-  $return = xmlrpc($client['url'] . 'xmlrpc.php', 'pifr.version');
-  return ($return === FALSE ? FALSE : $return == $version);
+  // Get the confirmation test definition for the current status.
+  return pifr_server_client_confirmation_test_get($client, $status['stage']);
 }
 
-function pifr_server_client_confirmation_next($client) {
-  $last = pifr_server_client_confirmation_last($client);
-
-  // Get the next confirmation test.
-  return pifr_server_client_confirmation_get_test($client, $last + 1);
+/**
+ * Get the current status of a client confirmation test.
+ *
+ * @param array $client Client information.
+ * @return array Status information including: 'client_id', 'environment_id',
+ *   and 'stage'.
+ */
+function pifr_server_client_confirmation_status(array $client) {
+  $result = db_query('SELECT *
+                      FROM {pifr_client_test}
+                      WHERE client_id = %d', $client['client_id']);
+  return db_fetch_array($result);
 }
 
-function pifr_server_client_confirmation_last($client) {
-  $results = pifr_server_result_get_all($client['test_id']);
-
-  // Determine the last test type run, PIFR_SERVER_TEST_TYPE_*.
-  if (!$results) {
-    $last = 1; // Assume setup passes, PIFR_SERVER_TEST_TYPE_SETUP (1).
+/**
+ * Save the status of a client confirmation test.
+ *
+ * Checks if the status information already exists and if so updates it,
+ * otherwise the status information is inserted.
+ *
+ * @param array $status Status information.
+ * @return array Status information.
+ */
+function pifr_server_client_confirmation_status_save(array $status, array $client) {
+  if ($current = pifr_server_client_confirmation_status($client)) {
+    db_query('UPDATE {pifr_client_test}
+              SET environment_id = %d,
+              stage = %d
+              WHERE client_id = %d', $status['environment_id'], $status['stage'], $status['client_id']);
   }
   else {
-    $last = array_pop($results);
-    $last = $last['type'];
-
-    if ($last == PIFR_SERVER_TEST_RESULT_SYNTAX) {
-      // TODO Skip.
-      $last++;
-    }
+    db_query('INSERT INTO {pifr_client_test} (client_id, environment_id, stage)
+              VALUES (%d, %d, %d)', $status['client_id'], $status['environment_id'], $status['stage']);
   }
-  return $last;
+  return $status;
 }
 
 /**
  * Get a test that will ensure that the specified result code is triggered.
  *
  * @param object Client.
- * @param integer $type Result code.
- * @return unknown_type
+ * @param integer $stage Confirmation stage.
+ * @return array XML-RPC reponse containing test definition
  */
-function pifr_server_client_confirmation_get_test(array $client, $type) {
-  switch ($type) {
-    case PIFR_SERVER_TEST_RESULT_SETUP:
-      break;
-    case PIFR_SERVER_TEST_RESULT_FETCH:
-      return pifr_server_client_confirmation_get_test_array($client, array(
-        'file_url' => 'http://example.com/pifr_server/some.patch',
-      ));
-    case PIFR_SERVER_TEST_RESULT_CVS:
-      return pifr_server_client_confirmation_get_test_array($client, array(
-        'core' => array(
-          'repository' => array(
-            'type' => 'cvs',
-            'url' => 'example.com/cvs',
-          ),
+function pifr_server_client_confirmation_test_get(array $client, $stage) {
+  $changes = pifr_server_client_confirmation_test_get_array_changes($stage);
+  return pifr_server_client_confirmation_test_get_array_merged($client, $changes);
+}
+
+/**
+ * Get the changes to the default client confirmation test array.
+ *
+ * The changes should then be merged with the default client confirmation test
+ * array before being sent as the XML-RPC response.
+ *
+ * @param integer $stage Confirmation stage.
+ * @return array Changes to default client confirmation test array.
+ */
+function pifr_server_client_confirmation_test_get_array_changes($stage) {
+  // Incrament stage by one since PIFR_SERVER_TEST_RESULT_SETUP is ignored.
+  $stage++;
+
+  if ($stage == PIFR_SERVER_TEST_RESULT_FETCH) {
+    return array(
+      'file_url' => 'http://example.com/pifr_server/some.patch',
+    );
+  }
+  elseif ($stage == PIFR_SERVER_TEST_RESULT_CVS) {
+    return array(
+      'core' => array(
+        'repository' => array(
+          'type' => 'cvs',
+          'url' => 'example.com/cvs',
         ),
-      ));
-    case PIFR_SERVER_TEST_RESULT_PATCH:
-      return pifr_server_client_confirmation_get_test_array($client, array(
-        'file_url' => url(file_directory_path() . '/pifr_server/patch.patch', array('absolute' => TRUE)),
-      ));
-    case PIFR_SERVER_TEST_RESULT_APPLY:
-      return pifr_server_client_confirmation_get_test_array($client, array(
-        'file_url' => url(file_directory_path() . '/pifr_server/apply.patch', array('absolute' => TRUE)),
-      ));
-    case PIFR_SERVER_TEST_RESULT_SYNTAX:
-      return pifr_server_client_confirmation_get_test_array($client, array(
-        'file_url' => url(file_directory_path() . '/pifr_server/syntax.patch', array('absolute' => TRUE)),
-      ));
-    case PIFR_SERVER_TEST_RESULT_FORMAT:
-      // TODO Not implemented.
-      break;
-    case PIFR_SERVER_TEST_RESULT_INSTALL:
-      return pifr_server_client_confirmation_get_test_array($client, array(
-        'file_url' => url(file_directory_path() . '/pifr_server/install.patch', array('absolute' => TRUE)),
-      ));
-    case PIFR_SERVER_TEST_RESULT_TEST:
-      return pifr_server_client_confirmation_get_test_array($client, array(
-        'file_url' => url(file_directory_path() . '/pifr_server/test.patch', array('absolute' => TRUE)),
-      ));
-    case PIFR_SERVER_TEST_RESULT_FAIL:
-      return pifr_server_client_confirmation_get_test_array($client, array(
-        'file_url' => url(file_directory_path() . '/pifr_server/fail.patch', array('absolute' => TRUE)),
-      ));
-    case PIFR_SERVER_TEST_RESULT_PASS:
-      return pifr_server_client_confirmation_get_test_array($client, array(
-        'file_url' => url(file_directory_path() . '/pifr_server/pass.patch', array('absolute' => TRUE)),
-      ));
+      ),
+    );
+  }
+  else {
+    // Stages: PIFR_SERVER_TEST_RESULT_PATCH through PIFR_SERVER_TEST_RESULT_PASS.
+    $patches = array('patch', 'apply', 'syntax', 'install', 'test', 'fail', 'pass');
+    $patch = $patches[$stage - PIFR_SERVER_TEST_RESULT_PATCH];
+    return array(
+      'file_url' => url(drupal_get_path('module', 'pifr_server') . '/' . $patch . '.patch', array('absolute' => TRUE)),
+    );
   }
 }
 
-function pifr_server_client_confirmation_get_test_array($client, array $changes) {
+/**
+ * Merge an array of changes with the default client confirmation test array.
+ *
+ * @param array $client Client information
+ * @param array $changes Changes to default client confirmation test array.
+ * @return array XML-RPC reponse containing test definition.
+ */
+function pifr_server_client_confirmation_test_get_array_merged($client, array $changes) {
   $default = array(
     'test_id' => $client['test_id'],
     'core' => array(
@@ -236,15 +312,36 @@
   return array_merge($default, $changes);
 }
 
+/**
+ * Check the results of a client confirmation test.
+ *
+ * The results of a client confirmation test need to be checked against the
+ * stage of the test. If the results demonstrate a failure then the client will
+ * be failed and the test will be halted, otherwise if the test demonstrates a
+ * pass then the test will continue to the next stage. If there are no more
+ * stages then the test will be marked as a pass.
+ *
+ * @param array $client Client information.
+ * @param array $result Result information.
+ */
 function pifr_server_client_confirmation_check(array $client, array $result) {
-  if ($result['type'] != $result['code']) {
-    pifr_server_client_confirmation_fail($client);
-    return;
-  }
-
   if ($result['type'] == PIFR_SERVER_TEST_RESULT_PASS) {
+    // Client confirmation has reached the last stage and is now complete.
     pifr_server_client_confirmation_pass($client);
   }
+  else {
+    // Check the result against the current stage.
+    $status = pifr_server_client_confirmation_status($client);
+    if ($result['code'] != $status['stage']) {
+      pifr_server_client_confirmation_fail($client);
+    }
+    else {
+      // Result is fine and the test is not complete so continue to next stage.
+      $test = pifr_server_test_get($result['test_id']);
+      $test['status'] = PIFR_SERVER_TEST_STATUS_QUEUED;
+      pifr_server_test_save($test);
+    }
+  }
 }
 
 function pifr_server_client_confirmation_pass(array $client) {
@@ -270,25 +367,27 @@
  * @return array Updated client array.
  */
 function pifr_server_client_save(array $client) {
+  $client['environment'] = serialize($client['environment']);
+
   if (isset($client['client_id'])) {
     // Existing client, update record.
     db_query("UPDATE {pifr_client}
               SET client_key = '%s',
                 type = %d,
-                environment_id = %d,
+                environment = '%s',
                 uid = %d,
                 url = '%s',
                 status = %d,
                 test_id = %d
               WHERE client_id = %d",
-              $client['client_key'], $client['type'], $client['environment_id'], $client['uid'],
+              $client['client_key'], $client['type'], $client['environment'], $client['uid'],
               $client['url'], $client['status'], $client['test_id'], $client['client_id']);
   }
   else {
     // Insert test record.
     $test = array(
       'type' => PIFR_SERVER_TEST_TYPE_CLIENT,
-      'status' => PIFR_SERVER_TEST_STATUS_QUEUED,
+      'status' => $client['type'] == PIFR_SERVER_CLIENT_TYPE_PROJECT ? PIFR_SERVER_TEST_STATUS_STUB : PIFR_SERVER_TEST_STATUS_QUEUED,
       'title' => 'Client', // Place holder until a client_id has been assigned.
       'client_id' => 0,
       'last_received' => 0,
@@ -355,29 +454,6 @@
   }
 }
 
-/**
- * Get the client status from the code.
- *
- * @param integer $client_environemnt Client environment code.
- * @return string Representation of client environment.
- */
-function pifr_server_client_environment($client_environemnt) {
-  switch ($client_environemnt) {
-    case PIFR_SERVER_CLIENT_ENVIRONMENT_MYSQL_5_0_ISAM:
-      return t('MySQL 5.0 ISAM');
-    case PIFR_SERVER_CLIENT_ENVIRONMENT_POSTGRES:
-      return t('PostgreSQL 8.3');
-    case PIFR_SERVER_CLIENT_ENVIRONMENT_SQLITE:
-      return t('SQLite');
-    case PIFR_SERVER_CLIENT_ENVIRONMENT_MYSQL_5_1_ISAM:
-      return t('MySQL 5.1 ISAM');
-    case PIFR_SERVER_CLIENT_ENVIRONMENT_MYSQL_5_0_INNO:
-      return t('MySQL 5.0 INNO');
-    default:
-      return 'Unknown';
-  }
-}
-
 function pifr_server_client_step($type) {
   switch ($type) {
     case PIFR_SERVER_TEST_RESULT_SETUP:
@@ -392,8 +468,6 @@
       return t('Detect non-applicable patch.');
     case PIFR_SERVER_TEST_RESULT_SYNTAX:
       return 'Detect invalid PHP syntax.';
-    case PIFR_SERVER_TEST_RESULT_FORMAT:
-      return '-- not implemented --';
     case PIFR_SERVER_TEST_RESULT_INSTALL:
       return 'Detect Drupal installation failure.';
     case PIFR_SERVER_TEST_RESULT_TEST:
@@ -431,8 +505,14 @@
   public function getInfoTable() {
     $rows = array();
 
+    $environments = array();
+    foreach ($this->client['environment'] as $environment_id) {
+      $environment = pifr_server_environment_get($environment_id);
+      $environments[] = $environment['environment_key'];
+    }
+
     $rows['type'] = array(t('Type'), pifr_server_client_type($this->client['type']));
-    $rows['environment'] = array(t('Environment'), pifr_server_client_environment($this->client['environment_id']));
+    $rows['environment'] = array(t('Environment'), count($environments) > 1 ? theme('item_list', $environments) : $environments[0]);
     $rows['status'] = array(t('Status'), pifr_server_client_status($this->client['status']));
 
     return $this->formatTable($rows);
Index: server/pifr_server.environment.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue_file_review/server/pifr_server.environment.inc,v
retrieving revision 1.2
diff -u -r1.2 pifr_server.environment.inc
--- server/pifr_server.environment.inc	20 Aug 2009 00:30:43 -0000	1.2
+++ server/pifr_server.environment.inc	24 Sep 2009 02:55:39 -0000
@@ -313,11 +313,12 @@
                                           FROM {pifr_environment}
                                           WHERE environment_id = %d', $environment_id));
 
-  $environment['client'] = unserialize($environment['client']);
-  $environment['project'] = unserialize($environment['project']);
-  $environment['branch'] = unserialize($environment['branch']);
-  $environment['type'] = unserialize($environment['type']);
-
+  if ($environment) {
+    $environment['client'] = unserialize($environment['client']);
+    $environment['project'] = unserialize($environment['project']);
+    $environment['branch'] = unserialize($environment['branch']);
+    $environment['type'] = unserialize($environment['type']);
+  }
   return $environment;
 }
 
@@ -347,9 +348,20 @@
   // Get tree of test related information.
   $test = pifr_server_test_get($test_id);
   if ($test['type'] == PIFR_SERVER_TEST_TYPE_CLIENT) {
-    // The only environment a client test should run in is its own.
     $client = pifr_server_client_get_test($test['test_id']);
-    return array(pifr_server_environment_get($client['environment_id']));
+
+    if ($client['type'] == PIFR_SERVER_CLIENT_TYPE_PROJECT) {
+      // Project clients do not have any relevant environments.
+      return array();
+    }
+    else {
+      // The only environment(s) a test client test should run in is its own.
+      $environments = array();
+      foreach ($client['environment'] as $environment_id) {
+        $environments[] = pifr_server_environment_get($environment_id);
+      }
+      return $environments;
+    }
   }
   elseif ($test['type'] == PIFR_SERVER_TEST_TYPE_BRANCH) {
     $branch = pifr_server_branch_get_test($test['test_id']);
@@ -387,13 +399,13 @@
  *     array('status' => 'queued'),
  *   </code>
  */
-function pifr_server_environment_get_status($environment_id, $test_id) {
+function pifr_server_environment_status_get($environment_id, $test_id) {
   $result = db_query('SELECT s.client_id, r.result_id, r.code
                       FROM {pifr_test} t
                       LEFT JOIN {pifr_environment_status} s
                         ON (t.test_id = s.test_id AND s.environment_id = %d)
                       LEFT JOIN {pifr_result} r
-                        ON (t.test_id = r.test_id AND r.type = %d)
+                        ON (t.test_id = r.test_id AND r.environment_id = %d)
                       WHERE t.test_id = %d', $environment_id, $environment_id, $test_id);
   $result = db_fetch_array($result);
   if ($result['client_id']) {
@@ -406,6 +418,45 @@
 }
 
 /**
+ * Get the environment ID that the client is currently testing.
+ *
+ * @param array $test Test information.
+ * @param array $client Client information.
+ * @return interger Environment ID, or FALSE.
+ */
+function pifr_server_environment_status_get_client(array $test, array $client) {
+  $result = db_query('SELECT environment_id
+                      FROM {pifr_environment_status}
+                      WHERE test_id = %d
+                      AND client_id = %d', $test['test_id'], $client['client_id']);
+  return db_result($result);
+}
+
+/**
+ * Reserve an environment for a particular test and client.
+ *
+ * @param integer $environment_id Environment ID.
+ * @param integer $test_id Test ID.
+ * @param integer $client_id Client ID.
+ */
+function pifr_server_environment_status_reserve($environment_id, $test_id, $client_id) {
+  db_query('INSERT INTO {pifr_environment_status} (environment_id, test_id, client_id)
+            VALUES (%d, %d, %d)', $environment_id, $test_id, $client_id);
+}
+
+/**
+ * Clear an environment for a particular test.
+ *
+ * @param integer $environment_id Environment ID.
+ * @param integer $test_id Test ID.
+ */
+function pifr_server_environment_status_clear($environment_id, $test_id) {
+  db_query('DELETE FROM {pifr_environment_status}
+            WHERE environment_id = %d
+            AND test_id = %d', $environment_id. $test_id);
+}
+
+/**
  * Save an environment.
  *
  * If no environment exists the environment will be inserted, otherwise the
Index: server/pifr_server.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue_file_review/server/pifr_server.module,v
retrieving revision 1.44
diff -u -r1.44 pifr_server.module
--- server/pifr_server.module	19 Aug 2009 06:34:35 -0000	1.44
+++ server/pifr_server.module	24 Sep 2009 02:55:39 -0000
@@ -29,20 +29,6 @@
 define('PIFR_SERVER_CLIENT_STATUS_ENABLED', 4);
 
 /*
- * Client environment codes.
- */
-define('PIFR_SERVER_CLIENT_ENVIRONMENT_MYSQL_5_0_ISAM', 1);
-define('PIFR_SERVER_CLIENT_ENVIRONMENT_POSTGRES', 2);
-define('PIFR_SERVER_CLIENT_ENVIRONMENT_SQLITE', 3);
-define('PIFR_SERVER_CLIENT_ENVIRONMENT_MYSQL_5_1_ISAM', 4);
-define('PIFR_SERVER_CLIENT_ENVIRONMENT_MYSQL_5_0_INNO', 5);
-
-/**
- * Number of environments.
- */
-define('PIFR_SERVER_CLIENT_ENVIRONMENT_COUNT', 1);
-
-/*
  * Project type codes.
  */
 define('PIFR_SERVER_PROJECT_TYPE_CORE', 1);
@@ -73,11 +59,10 @@
 define('PIFR_SERVER_TEST_RESULT_PATCH', 4);
 define('PIFR_SERVER_TEST_RESULT_APPLY', 5);
 define('PIFR_SERVER_TEST_RESULT_SYNTAX', 6);
-define('PIFR_SERVER_TEST_RESULT_FORMAT', 7);
-define('PIFR_SERVER_TEST_RESULT_INSTALL', 8);
-define('PIFR_SERVER_TEST_RESULT_TEST', 9);
-define('PIFR_SERVER_TEST_RESULT_FAIL', 10);
-define('PIFR_SERVER_TEST_RESULT_PASS', 11);
+define('PIFR_SERVER_TEST_RESULT_INSTALL', 7);
+define('PIFR_SERVER_TEST_RESULT_TEST', 8);
+define('PIFR_SERVER_TEST_RESULT_FAIL', 9);
+define('PIFR_SERVER_TEST_RESULT_PASS', 10);
 
 /*
  * Maximum number of items to send in a batch.
Index: client/review/pifr_client_review.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project_issue_file_review/client/review/pifr_client_review.inc,v
retrieving revision 1.35
diff -u -r1.35 pifr_client_review.inc
--- client/review/pifr_client_review.inc	12 Aug 2009 23:42:22 -0000	1.35
+++ client/review/pifr_client_review.inc	24 Sep 2009 02:55:39 -0000
@@ -98,7 +98,7 @@
     watchdog('pifr_client', 'review.run()');
 
     $operations = array('setup', 'fetchFile', 'checkout', 'checkPatch', 'applyPatch',
-                         'checkSyntax', 'checkFormat', 'install', 'runTests');
+                         'checkSyntax', 'install', 'runTests');
 
     $code = 1;
     foreach ($operations as $operation) {
@@ -309,10 +309,6 @@
     chdir($this->ORIGINAL['directory']);
   }
 
-  protected function checkFormat() {
-    // Do nothing.
-  }
-
   protected function install() {
     global $base_url, $base_path;
 
Index: util/xmlrpc-log.patch
===================================================================
RCS file: util/xmlrpc-log.patch
diff -N util/xmlrpc-log.patch
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ util/xmlrpc-log.patch	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,29 @@
+Index: includes/xmlrpcs.inc
+===================================================================
+RCS file: /cvs/drupal/drupal/includes/xmlrpcs.inc,v
+retrieving revision 1.24.2.1
+diff -u -r1.24.2.1 xmlrpcs.inc
+--- includes/xmlrpcs.inc  28 Apr 2008 10:04:52 -0000  1.24.2.1
++++ includes/xmlrpcs.inc  22 Sep 2009 23:11:22 -0000
+@@ -143,6 +143,10 @@
+  *   Array containing any parameters that were sent along with the request.
+  */
+ function xmlrpc_server_call($xmlrpc_server, $methodname, $args) {
++  file_put_contents('xmlrpc.log', "-- XML-RPC call received --\n", FILE_APPEND);
++  file_put_contents('xmlrpc.log', $methodname . "()\n", FILE_APPEND);
++  file_put_contents('xmlrpc.log', 'args: ' . var_export($args, TRUE) . "\n\n", FILE_APPEND);
++
+   // Make sure parameters are in an array
+   if ($args && !is_array($args)) {
+     $args = array($args);
+@@ -206,7 +210,9 @@
+     return xmlrpc_error(-32601, t('Server error. Requested function @method does not exist.', array("@method" => $method)));
+   }
+   // Call the mapped function
+-  return call_user_func_array($method, $args);
++  $response = call_user_func_array($method, $args);
++  file_put_contents('xmlrpc.log', 'response: ' . var_export($response, TRUE) . "\n\n\n", FILE_APPEND);
++  return $response;
+ }
+ 
+ function xmlrpc_server_multicall($methodcalls) {
