diff --git a/src/DrupalCI/Console/Command/RunCommand.php b/src/DrupalCI/Console/Command/RunCommand.php
index 98bcba5..08304f6 100644
--- a/src/DrupalCI/Console/Command/RunCommand.php
+++ b/src/DrupalCI/Console/Command/RunCommand.php
@@ -129,6 +129,11 @@ class RunCommand extends DrupalCICommandBase {
 
     // Iterate over the build stages
     foreach ($definition as $build_stage => $steps) {
+      // Post-processing needs to happen outside of this loop, in case any one
+      // build stage fails and aborts the job.
+      if ($build_stage == "postprocess") {
+        break;
+      }
       if (empty($steps)) {
         $job_results->updateStageStatus($build_stage, 'Skipped');
         continue;
@@ -157,11 +162,27 @@ class RunCommand extends DrupalCICommandBase {
       }
       $job_results->updateStageStatus($build_stage, 'Completed');
     }
-    // TODO: Gather results.
-    // This should be moved out of the 'build steps' logic, as an error in any
-    // build step halts execution of the entire loop, and the artifacts are not
-    // processed.
 
+    // Perform post-processing steps
+    if (empty($definition["postprocess"])) {
+      $job_results->updateStageStatus("postprocess", 'Skipped');
+      return;
+    }
+    foreach ($definition["postprocess"] as $build_step => $data) {
+      // Iterate over build steps
+      $job_results->updateStepStatus("postprocess", $build_step, 'Executing');
+      // Execute the build step
+      $this->buildStepsPluginManager()->getPlugin("postprocess", $build_step)->run($job, $data);
+      // Check for errors / failures after build step execution
+      $status = $job_results->getResultByStep("postprocess", $build_step);
+
+      // Check for errors / failures after build step execution
+      if ($status == 'Error') {
+        // Step returned an error.  Halt execution.
+        Output::error("Execution Error", "Error encountered while executing job build step <options=bold>postprocess:$build_step</options=bold>");
+        break;
+      }
+    }
   }
 
   /**
diff --git a/src/DrupalCI/Job/Results/JobResults.php b/src/DrupalCI/Job/Results/JobResults.php
index a95612f..afe312f 100644
--- a/src/DrupalCI/Job/Results/JobResults.php
+++ b/src/DrupalCI/Job/Results/JobResults.php
@@ -12,34 +12,123 @@ use DrupalCI\Plugin\JobTypes\JobInterface;
 
 class JobResults {
 
+  // Tracks which stage of the build process is currently being executed
   protected $current_stage;
-  public function getCurrentStage() {  return $this->current_stage;  }
-  public function setCurrentStage($stage) {  $this->current_stage = $stage;  }
 
+  public function getCurrentStage() {
+    return $this->current_stage;
+  }
+
+  public function setCurrentStage($stage) {
+    $this->current_stage = $stage;
+  }
+
+  // Tracks the pass/fail/skipped/error status by job
+  protected $job_results;
+
+  public function getJobResults()
+  {
+    return $this->job_results;
+  }
+
+  public function setJobResults($job_results)
+  {
+    $this->job_results = $job_results;
+  }
+
+  // Tracks the pass/fail/skipped/error status by build process stage
   protected $stage_results;
-  public function getStageResults() {  return $this->stage_results;  }
-  public function setStageResults(array $stage_results) {  $this->stage_results = $stage_results;  }
-  public function getResultByStage($stage) {  return $this->stage_results[$stage];  }
-  public function setResultByStage($stage, $result) {  $this->stage_results[$stage] = $result;  }
 
+  public function getStageResults() {
+    return $this->stage_results;
+  }
+
+  public function setStageResults(array $stage_results) {
+    $this->stage_results = $stage_results;
+  }
+
+  public function getResultByStage($stage) {
+    return $this->stage_results[$stage];
+  }
+
+  public function setResultByStage($stage, $result) {
+    $this->stage_results[$stage] = $result;
+  }
+
+  // Tracks which step of the current build process stage is currently being executed
   protected $current_step;
-  public function getCurrentStep() {  return $this->current_step;  }
-  public function setCurrentStep($step) {  $this->current_step = $step;  }
 
+  public function getCurrentStep() {
+    return $this->current_step;
+  }
+
+  public function setCurrentStep($step) {
+    $this->current_step = $step;
+  }
+
+  // Tracks the pass/fail/skipped/error status for each build process step within the job
   protected $step_results;
-  public function getStepResults() {  return $this->step_results;  }
-  public function setStepResults(array $step_results) {  $this->step_results = $step_results;  }
-  public function getResultByStep($stage, $step) {  return $this->step_results[$stage][$step];  }
-  public function setResultByStep($stage, $step, $result)  {  $this->step_results[$stage][$step] = $result;  }
 
+  public function getStepResults() {
+    return $this->step_results;
+  }
+
+  public function setStepResults(array $step_results) {
+    $this->step_results = $step_results;
+  }
+
+  public function getResultByStep($stage, $step) {
+    return $this->step_results[$stage][$step];
+  }
+
+  public function setResultByStep($stage, $step, $result) {
+    $this->step_results[$stage][$step] = $result;
+  }
+
+  // Stores the console output for each build process step within the job
+  protected $step_output;
+
+  public function getStepOutput() {
+    return $this->step_output;
+  }
+
+  public function setStepOutput(array $step_output) {
+    $this->step_output = $step_output;
+  }
+
+  public function getOutputByStep($stage, $step) {
+    return $this->step_output[$stage][$step];
+  }
+
+  public function setOutputByStep($stage, $step, $output) {
+    $this->step_output[$stage][$step] = $output;
+  }
+
+  // Stores a list of job artifacts to be considered part of the final results for this job
   protected $artifacts;
-  public function setArtifacts($artifacts) { $this->artifacts = $artifacts; }
-  public function getArtifacts() { return $this->artifacts; }
 
+  public function setArtifacts($artifacts) {
+    $this->artifacts = $artifacts;
+  }
+
+  public function getArtifacts() {
+    return $this->artifacts;
+  }
+
+  // Stores a list of publishers which should be notified of the results upon job completion
   protected $publishers = [];
-  public function getPublishers() {  return $this->publishers;  }
-  public function setPublishers($publishers) {  $this->publishers = $publishers;  }
-  public function getPublisher($publisher) {  return $this->publishers[$publisher];  }
+
+  public function getPublishers() {
+    return $this->publishers;
+  }
+
+  public function setPublishers($publishers) {
+    $this->publishers = $publishers;
+  }
+
+  public function getPublisher($publisher) {
+    return $this->publishers[$publisher];
+  }
 
 
   public function __construct(JobInterface $job) {
@@ -76,7 +165,7 @@ class JobResults {
 
   // TODO: Consider adding a 'job publisher' class for interim feedback and/or real-time display
   /*
-    // Pasting this code here for future reference, once we revisit interacting with a results API.
+  // Pasting this code here for future reference, once we revisit interacting with a results API.
 
   public function prepServerForPublishing(JobDefinition $jobDefinition) {
     // If we are publishing this job to a results server (or multiple), prep the server
diff --git a/src/DrupalCI/Plugin/BuildSteps/postprocess/CreateArchive.php b/src/DrupalCI/Plugin/BuildSteps/postprocess/CreateArchive.php
new file mode 100644
index 0000000..5b8300f
--- /dev/null
+++ b/src/DrupalCI/Plugin/BuildSteps/postprocess/CreateArchive.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * @file
+ * Contains \DrupalCI\Plugin\BuildSteps\publish\CreateArchive
+ *
+ * Processes "publish: archive:" instructions from within a job definition.
+ * Gathers the resulting job artifacts and generates a zip file.
+ */
+
+namespace DrupalCI\Plugin\BuildSteps\postprocess;
+
+use DrupalCI\Console\Output;
+use DrupalCI\Plugin\JobTypes\JobInterface;
+use DrupalCI\Plugin\PluginBase;
+use ZipArchive;
+
+/**
+ * @PluginID("archive")
+ */
+class CreateArchive extends PluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function run(JobInterface $job, $data) {
+    // $data defines the directory/filename of the desired zip file.
+    $files = $job->getArtifacts();
+    if (empty($files)) { return; }
+    $zip = new ZipArchive();
+    $filename = $data;
+
+    // Open the zip archive
+    if ($zip->open($filename, ZipArchive::CREATE)!==TRUE) {
+      // TODO: Cannot open zip file ... throw an error.
+      return;
+    }
+
+    // Add artifact files to zip file
+    Output::writeLn("<info>Gathering artifact files:</info>");
+    foreach ($files as $file) {
+      if (file_exists($file)) {
+        $zip->addFile($file);
+        Output::writeLn("<comment>" . $file . "</comment>");
+      }
+      else {
+        Output::writeln("<comment>" . $file . " NOT FOUND.</comment>");
+      }
+    }
+
+    // Close the zip file
+    $zip->close();
+
+    // Store the artifacts filename in the job object for future reference
+    $job->setArtifactFilename($data);
+
+  }
+}
\ No newline at end of file
diff --git a/src/DrupalCI/Plugin/BuildSteps/postprocess/DrupalCIResults.php b/src/DrupalCI/Plugin/BuildSteps/postprocess/DrupalCIResults.php
new file mode 100644
index 0000000..4b78f5c
--- /dev/null
+++ b/src/DrupalCI/Plugin/BuildSteps/postprocess/DrupalCIResults.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * @file
+ * Contains \DrupalCI\Plugin\BuildSteps\publish\DrupalCIResults
+ *
+ * Processes "publish: drupalci_server:" instructions from within a job
+ * definition. Gathers the resulting job artifacts and pushes them to a
+ * DrupalCI Results server.
+ */
+
+namespace DrupalCI\Plugin\BuildSteps\postprocess;
+use DrupalCI\Plugin\JobTypes\JobInterface;
+use DrupalCI\Plugin\PluginBase;
+use DrupalCIResultsApi\Api;
+use Symfony\Component\Yaml\Yaml;
+
+/**
+ * @PluginID("drupalci_results")
+ */
+class DrupalCIResults extends PluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function run(JobInterface $job, $data) {
+    // $data format:
+    // i) array('config' => '<configuration filename>'),
+    // ii) array('host' => '...', 'username' => '...', 'password' => '...')
+    // or a mixed array of the above
+    // iii) array(array(...), array(...))
+    // Normalize data to the third format, if necessary
+    $data = (count($data) == count($data, COUNT_RECURSIVE)) ? [$data] : $data;
+
+    $api = $job->getResultsAPI();
+
+    foreach ($data as $key => $instance) {
+      $job->configureResultsAPI($instance);
+      $url = $api->getUrl();
+      // Retrieve the results node ID for the results server
+      $host = parse_url($url, PHP_URL_HOST);
+      $results_id = $job->getResultsServerID();
+      $states = $api->states();
+      $api->progress($results_id[$host], $states['complete']['id']);
+      // TODO: Calculate a summary message
+      // For now, we just set a default message
+      $api->summary($results_id[$host], "Test complete");
+    }
+
+  }
+
+  protected function loadConfig($source) {
+    $config = array();
+    if ($content = file_get_contents($source)) {
+      $parsed = Yaml::parse($content);
+      $config['results']['host'] = $parsed['results']['host'];
+      $config['results']['username'] = $parsed['results']['username'];
+      $config['results']['password'] = $parsed['results']['password'];
+    }
+    return $config;
+  }
+}
diff --git a/src/DrupalCI/Plugin/BuildSteps/postprocess/EmailResults.php b/src/DrupalCI/Plugin/BuildSteps/postprocess/EmailResults.php
new file mode 100644
index 0000000..bb563ef
--- /dev/null
+++ b/src/DrupalCI/Plugin/BuildSteps/postprocess/EmailResults.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * @file
+ * Contains \DrupalCI\Plugin\BuildSteps\publish\EmailResults
+ *
+ * Processes "publish: email:" instructions from within a job definition.
+ * Gathers the resulting job artifacts and pushes them to an email address.
+ */
+
+namespace DrupalCI\Plugin\BuildSteps\postprocess;
+use DrupalCI\Plugin\PluginBase;
+
+/**
+ * @PluginID("email_results")
+ */
+class EmailResults extends PluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function run() {
+    echo 'EmailResults plugin not yet implemented.';
+  }
+
+}
diff --git a/src/DrupalCI/Plugin/BuildSteps/postprocess/GatherArtifacts.php b/src/DrupalCI/Plugin/BuildSteps/postprocess/GatherArtifacts.php
new file mode 100644
index 0000000..3f08cc8
--- /dev/null
+++ b/src/DrupalCI/Plugin/BuildSteps/postprocess/GatherArtifacts.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * @file
+ * Contains \DrupalCI\Plugin\BuildSteps\publish\GatherArtifacts
+ *
+ * Processes "publish: gather_artifacts:" instructions from within a job definition.
+ * Generates job build artifact files in a common directory.
+ */
+
+namespace DrupalCI\Plugin\BuildSteps\postprocess;
+use DrupalCI\Console\Output;
+use DrupalCI\Plugin\JobTypes\JobInterface;
+use DrupalCI\Plugin\PluginBase;
+use DrupalCI\Plugin\BuildSteps\generic\ContainerCommand;
+
+/**
+ * @PluginID("gather_artifacts")
+ */
+class GatherArtifacts extends PluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function run(JobInterface $job, $target_directory) {
+
+    $docker = $job->getDocker();
+    $manager = $docker->getContainerManager();
+
+    Output::writeLn("<comment>Gathering job build artifacts in a common directory ...</comment>");
+
+    // Create the destination directory
+    if (!empty($target_directory)) {
+      $command = new ContainerCommand();
+      $command->run($job, "mkdir -p $target_directory");
+    }
+
+    // Store the directory in our job object
+    $job->setArtifactDirectory($target_directory);
+
+    // Retrieve the list of build artifacts from the job
+    $artifacts = $job->getArtifacts();
+
+    // Iterate over the build artifacts
+    foreach ($artifacts->getArtifacts() as $key => $artifact) {
+      if ($key == 'jobDefinition') {
+        $destination_filename = $artifact->getValue();
+
+        // Retrieve the job definition from the job
+        $definition = $job->getJobDefinition()->getDefinition();
+        // write the job definition out to a file in the artifact directory on the container.
+        if (!empty($destination_filename)) {
+          $file = $target_directory . DIRECTORY_SEPARATOR . $destination_filename;
+          // TODO: Verify file name - unique, empty, etc.
+          $command = new ContainerCommand();
+          $cmd = "cat >$file <<EOL \n" . print_r($definition, TRUE) . "\nEOL";
+          $command->run($job, $cmd);
+        }
+        else {
+          // TODO: Exception handling
+          Output::writeLn('<info>Error generating job definition build artifact.');
+        }
+      }
+      elseif (strtolower($artifact->getType()) == 'file' || $artifact->getType() == 'directory') {
+        // Copy artifact file to the build artifacts directory
+        $file = $artifact->getValue();
+        $dest = $target_directory . DIRECTORY_SEPARATOR . basename($file);
+        if ($file !== $dest) {
+          $command = new ContainerCommand();
+          $cmd = "cp -r $file $dest";
+          $command->run($job, $cmd);
+        }
+        else {
+          Output::writeLn("<info>Skipping $file, as it already exists in the build artifact directory.");
+        }
+      }
+      elseif (strtolower($artifact->getType()) == 'archive') {
+        // Create a zip archive of the file/directory within the build artifacts directory
+        $file = $artifact->getValue();
+        $dest = $target_directory . DIRECTORY_SEPARATOR . basename($file);
+        $command = new ContainerCommand();
+        $cmd = "tar -zcvf $dest.tar.gz $file";
+        $command->run($job, $cmd);
+      }
+      elseif (strtolower($artifact->getType) == 'string') {
+        // Write string to new file with filename based on the string's key
+        $dest = $target_directory . DIRECTORY_SEPARATOR . $key;
+        $content = $artifact->getValue;
+        $command = new ContainerCommand();
+        $cmd = "cat >$dest <<EOL \n" . print_r($content, TRUE) . "\nEOL";
+        $command->run($job, $cmd);
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/DrupalCI/Plugin/BuildSteps/postprocess/JunitXMLFormat.php b/src/DrupalCI/Plugin/BuildSteps/postprocess/JunitXMLFormat.php
new file mode 100644
index 0000000..12829de
--- /dev/null
+++ b/src/DrupalCI/Plugin/BuildSteps/postprocess/JunitXMLFormat.php
@@ -0,0 +1,274 @@
+<?php
+/**
+ * @file
+ * Contains \DrupalCI\Plugin\BuildSteps\publish\JunitXmlFormat
+ *
+ * Processes "publish: junit_xmlformat:" instructions from within a job
+ * definition.  Connects to the database, queries for the tests, and reformats
+ * them in a sane manner.  (If there is a sqlite results database!)
+ */
+
+namespace DrupalCI\Plugin\BuildSteps\postprocess;
+use Docker\Docker;
+use DrupalCI\Console\Output;
+use DrupalCI\Plugin\JobTypes\JobInterface;
+use DrupalCI\Plugin\PluginBase;
+use PDO;
+use DOMDocument;
+
+/**
+ * @PluginID("junit_xmlformat")
+ */
+class JunitXMLFormat extends PluginBase {
+
+  protected $testlist = [];
+  public function setTestlist($testlist)  {  $this->testlist = $testlist; }
+  public function getTestlist() {  return $this->testlist; }
+
+  protected function loadTestList($file) {
+    $test_list = file($file, FILE_IGNORE_NEW_LINES);
+    // Get rid of the first four lines
+    $this->setTestlist(array_slice($test_list, 4));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function run(JobInterface $job, $output_directory) {
+    // Set up initial variable to store tests
+    $CoreBranch = $job->getBuildVars()["DCI_CoreBranch"];
+    $DBUrlArray = parse_url($job->getBuildVars()["DCI_DBUrl"]);
+    $DBVersion = $job->getBuildVars()["DCI_DBVersion"];
+    $DBScheme = $DBUrlArray["scheme"];
+    $DBUser   = (!empty($DBUrlArray["user"])) ? $DBUrlArray["user"] : "";
+    $DBPass   = (!empty($DBUrlArray["pass"])) ? $DBUrlArray["pass"] : "";
+    $DBDatabase = str_replace('/','',$DBUrlArray["path"]);
+    $DBIp = $job->getServiceContainers()["db"][$DBVersion]["ip"];
+    $tests = [];
+
+    // Load the list of tests from the testgroups.txt build artifact
+    // Assumes that gatherArtifacts plugin has run.
+    // TODO: Verify that gatherArtifacts has ran.
+    $source_dir = $job->getJobCodebase()->getWorkingDir();
+    // TODO: Temporary hack.  Strip /checkout off the directory
+    $artifact_dir = preg_replace('#/checkout$#', '', $source_dir);
+    $this->loadTestList($source_dir . DIRECTORY_SEPARATOR . 'artifacts/testgroups.txt');
+
+    // Set up output directory (inside working directory)
+    $output_directory = $artifact_dir . DIRECTORY_SEPARATOR . 'artifacts' . DIRECTORY_SEPARATOR . $output_directory;
+    mkdir($output_directory, 0777, TRUE);
+
+    // Set an initial default group, in case leading tests are found with no group.
+    $group = 'nogroup';
+    // Iterate through and process the test list
+    $test_list = $this->getTestlist();
+    if(strcmp($CoreBranch,'7.x') === 0 || strcmp($CoreBranch,'6.x') === 0){
+
+      foreach ($test_list as $output_line) {
+        if (substr($output_line, 0, 3) == ' - ') {
+          // This is a class
+          $class = str_replace(array('(',')'),'',end(explode(' ', $output_line)));
+          $test_groups[$class] = $group;
+        }
+        else {
+          // This is a group
+          $group = ucwords($output_line);
+        }
+      }
+      $PDO_con = "$DBScheme:host=$DBIp;dbname=$DBDatabase";
+      $db = new PDO( $PDO_con, $DBUser, $DBPass);
+
+    } else {
+
+      foreach ($test_list as $output_line) {
+        if (substr($output_line, 0, 3) == ' - ') {
+          // This is a class
+          $class = substr($output_line, 3);
+          $test_groups[$class] = $group;
+        }
+        else {
+          // This is a group
+          $group = ucwords($output_line);
+        }
+      }
+      // Crack open the sqlite database.
+      $dbfile = $source_dir . DIRECTORY_SEPARATOR . 'artifacts' . DIRECTORY_SEPARATOR . basename($job->getBuildVar('DCI_SQLite'));
+      $db = new PDO('sqlite:' . $dbfile);
+    }
+
+    // query for simpletest results
+    $results_map = array(
+      'pass' => 'Pass',
+      'fail' => 'Fail',
+      'exception' => 'Exception',
+      'debug' => 'Debug',
+    );
+
+    $q_result = $db->query('SELECT * FROM simpletest ORDER BY test_id, test_class, message_id;');
+
+    $results = array();
+
+    $cases = 0;
+    $errors = 0;
+    $failures = 0;
+
+    //while ($result = $q_result->fetchAll()) {
+    while ($result = $q_result->fetch(PDO::FETCH_ASSOC)) {
+      if (isset($results_map[$result['status']])) {
+        // Set the group from the lookup table
+        $test_group = $test_groups[$result['test_class']];
+
+        // Set the test class
+        if (isset($result['test_class'])) {
+          $test_class = $result['test_class'];
+        }
+        // Jenkins likes to see the groups and classnames together. -
+        // This might need to be re-addressed when we look at the tests.
+        $classname = $test_groups[$test_class] . '.' . $test_class;
+
+        // Cleanup the class, and the parens from the test method name
+        $test_method = substr($result['function'], strpos($result['function'], '>') + 1);
+        $test_method = substr($test_method, 0, strlen($test_method) - 2);
+
+        //$classes[$test_group][$test_class][$test_method]['classname'] = $classname;
+        $result['file'] = substr($result['file'],14); // Trim off /var/www/html
+        $classes[$test_group][$test_class][$test_method][] = array(
+          'status' => $result['status'],
+          'type' => $result['message_group'],
+          'message' => strip_tags(htmlspecialchars_decode($result['message'],ENT_QUOTES)),
+          'line' => $result['line'],
+          'file' => $result['file'],
+        );
+      }
+    }
+    $this->_build_xml($classes, $output_directory);
+  }
+
+  private function _build_xml($test_result_data, $output_dir) {
+    // Maps statuses to their xml element for each testcase.
+    $element_map = array(
+      'pass' => 'system-out',
+      'fail' => 'failure',
+      'exception' => 'error',
+      'debug' => 'system-err',
+    );
+    // Create an xml file per group?
+
+    $test_group_id = 0;
+    $doc = new DomDocument('1.0');
+    $test_suites = $doc->createElement('testsuites');
+
+    // TODO: get test name data from the job.
+    $test_suites->setAttribute('name', "TODO SET");
+    $test_suites->setAttribute('time', "TODO SET");
+    $total_failures = 0;
+    $total_tests = 0;
+    $total_exceptions = 0;
+
+    // Go through the groups, and create a testsuite for each.
+    foreach ($test_result_data as $groupname => $group_classes) {
+      $group_failures = 0;
+      $group_tests = 0;
+      $group_exceptions = 0;
+      $test_suite = $doc->createElement('testsuite');
+      $test_suite->setAttribute('id', $test_group_id);
+      $test_suite->setAttribute('name', $groupname);
+      $test_suite->setAttribute('timestamp', date('c'));
+      $test_suite->setAttribute('hostname', "TODO: Set Hostname");
+      $test_suite->setAttribute('package', $groupname);
+      // TODO: time test runs. $test_group->setAttribute('time', $test_group_id);
+      // TODO: add in the properties of the job into the test run.
+
+      // Loop through the classes in each group
+      foreach ($group_classes as $class_name => $class_methods) {
+        foreach ($class_methods as $test_method => $method_results) {
+          $test_case = $doc->createElement('testcase');
+          $test_case->setAttribute('classname', $groupname . "." . $class_name);
+          $test_case->setAttribute('name', $test_method);
+          $test_case_status = 'pass';
+          $test_case_assertions = 0;
+          $test_case_exceptions = 0;
+          $test_case_failures = 0;
+          $test_output = '';
+          $fail_output = '';
+          $exception_output = '';
+          foreach ($method_results as $assertion) {
+            $assertion_result = $assertion['status'] . ": [" . $assertion['type'] . "] Line " . $assertion['line'] . " of " . $assertion['file'] . ":\n" . $assertion['message'] . "\n\n";
+            $assertion_result = preg_replace('/[^\x{0009}\x{000A}\x{000D}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]/u', '�', $assertion_result);
+
+            // Keep track of overall assersions counts
+            if (!isset($assertion_counter[$assertion['status']])) {
+              $assertion_counter[$assertion['status']] = 0;
+            }
+            $assertion_counter[$assertion['status']]++;
+            if ($assertion['status'] == 'exception') {
+              $test_case_exceptions++;
+              $group_exceptions++;
+              $total_exceptions++;
+              $test_case_status = 'failed';
+              $exception_output .= $assertion_result;
+            } else if ($assertion['status'] == 'fail'){
+              $test_case_failures++;
+              $group_failures++;
+              $total_failures++;
+              $test_case_status = 'failed';
+              $fail_output .= $assertion_result;
+            }
+            elseif (($assertion['status'] == 'debug')) {
+              $test_output .= $assertion_result;
+            }
+
+            $test_case_assertions++;
+            $group_tests++;
+            $total_tests++;
+
+          }
+          if ($test_case_failures > 0) {
+            $element = $doc->createElement("failure");
+            $element->setAttribute('message', $fail_output);
+            $element->setAttribute('type', "fail");
+            $test_case->appendChild($element);
+          }
+
+          if ($test_case_exceptions > 0 ) {
+            $element = $doc->createElement("error");
+            $element->setAttribute('message', $exception_output);
+            $element->setAttribute('type', "exception");
+            $test_case->appendChild($element);
+          }
+          $std_out = $doc->createElement('system-out');
+          $output = $doc->createCDATASection($test_output);
+          $std_out->appendChild($output);
+          $test_case->appendChild($std_out);
+
+          // TODO: Errors and Failures need to be set per test Case.
+          $test_case->setAttribute('status', $test_case_status);
+          $test_case->setAttribute('assertions', $test_case_assertions);
+         // $test_case->setAttribute('time', "TODO: track time");
+
+          $test_suite->appendChild($test_case);
+
+        }
+      }
+
+      // Should this count the tests as part of the loop, or just array_count?
+      $test_suite->setAttribute('tests', $group_tests);
+      $test_suite->setAttribute('failures', $group_failures);
+      $test_suite->setAttribute('errors', $group_exceptions);
+      /* TODO: Someday simpletest will disable or skip tests based on environment
+      $test_group->setAttribute('disabled', $test_group_id);
+      $test_group->setAttribute('skipped', $test_group_id);
+      */
+      $test_suites->appendChild($test_suite);
+      $test_group_id++;
+    }
+    $test_suites->setAttribute('tests', $total_tests);
+    $test_suites->setAttribute('failures', $total_failures);
+   // $test_suites->setAttribute('disabled', "TODO SET");
+    $test_suites->setAttribute('errors', $total_exceptions);
+    $doc->appendChild($test_suites);
+    file_put_contents($output_dir . '/testresults.xml', $doc->saveXML());
+    Output::writeln("<info>Reformatted test results written to <options=bold>" . $output_dir . '/testresults.xml</options=bold></info>');
+  }
+
+}
diff --git a/src/DrupalCI/Plugin/BuildSteps/publish/CreateArchive.php b/src/DrupalCI/Plugin/BuildSteps/publish/CreateArchive.php
deleted file mode 100644
index a1cbafc..0000000
--- a/src/DrupalCI/Plugin/BuildSteps/publish/CreateArchive.php
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-/**
- * @file
- * Contains \DrupalCI\Plugin\BuildSteps\publish\CreateArchive
- *
- * Processes "publish: archive:" instructions from within a job definition.
- * Gathers the resulting job artifacts and generates a zip file.
- */
-
-namespace DrupalCI\Plugin\BuildSteps\publish;
-
-use DrupalCI\Console\Output;
-use DrupalCI\Plugin\JobTypes\JobInterface;
-use DrupalCI\Plugin\PluginBase;
-use ZipArchive;
-
-/**
- * @PluginID("archive")
- */
-class CreateArchive extends PluginBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function run(JobInterface $job, $data) {
-    // $data defines the directory/filename of the desired zip file.
-    $files = $job->getArtifacts();
-    if (empty($files)) { return; }
-    $zip = new ZipArchive();
-    $filename = $data;
-
-    // Open the zip archive
-    if ($zip->open($filename, ZipArchive::CREATE)!==TRUE) {
-      // TODO: Cannot open zip file ... throw an error.
-      return;
-    }
-
-    // Add artifact files to zip file
-    Output::writeLn("<info>Gathering artifact files:</info>");
-    foreach ($files as $file) {
-      if (file_exists($file)) {
-        $zip->addFile($file);
-        Output::writeLn("<comment>" . $file . "</comment>");
-      }
-      else {
-        Output::writeln("<comment>" . $file . " NOT FOUND.</comment>");
-      }
-    }
-
-    // Close the zip file
-    $zip->close();
-
-    // Store the artifacts filename in the job object for future reference
-    $job->setArtifactFilename($data);
-
-  }
-}
\ No newline at end of file
diff --git a/src/DrupalCI/Plugin/BuildSteps/publish/DrupalCIResults.php b/src/DrupalCI/Plugin/BuildSteps/publish/DrupalCIResults.php
deleted file mode 100644
index a5e3902..0000000
--- a/src/DrupalCI/Plugin/BuildSteps/publish/DrupalCIResults.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-/**
- * @file
- * Contains \DrupalCI\Plugin\BuildSteps\publish\DrupalCIResults
- *
- * Processes "publish: drupalci_server:" instructions from within a job
- * definition. Gathers the resulting job artifacts and pushes them to a
- * DrupalCI Results server.
- */
-
-namespace DrupalCI\Plugin\BuildSteps\publish;
-use DrupalCI\Plugin\JobTypes\JobInterface;
-use DrupalCI\Plugin\PluginBase;
-use DrupalCIResultsApi\Api;
-use Symfony\Component\Yaml\Yaml;
-
-/**
- * @PluginID("drupalci_results")
- */
-class DrupalCIResults extends PluginBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function run(JobInterface $job, $data) {
-    // $data format:
-    // i) array('config' => '<configuration filename>'),
-    // ii) array('host' => '...', 'username' => '...', 'password' => '...')
-    // or a mixed array of the above
-    // iii) array(array(...), array(...))
-    // Normalize data to the third format, if necessary
-    $data = (count($data) == count($data, COUNT_RECURSIVE)) ? [$data] : $data;
-
-    $api = $job->getResultsAPI();
-
-    foreach ($data as $key => $instance) {
-      $job->configureResultsAPI($instance);
-      $url = $api->getUrl();
-      // Retrieve the results node ID for the results server
-      $host = parse_url($url, PHP_URL_HOST);
-      $results_id = $job->getResultsServerID();
-      $states = $api->states();
-      $api->progress($results_id[$host], $states['complete']['id']);
-      // TODO: Calculate a summary message
-      // For now, we just set a default message
-      $api->summary($results_id[$host], "Test complete");
-    }
-
-  }
-
-  protected function loadConfig($source) {
-    $config = array();
-    if ($content = file_get_contents($source)) {
-      $parsed = Yaml::parse($content);
-      $config['results']['host'] = $parsed['results']['host'];
-      $config['results']['username'] = $parsed['results']['username'];
-      $config['results']['password'] = $parsed['results']['password'];
-    }
-    return $config;
-  }
-}
diff --git a/src/DrupalCI/Plugin/BuildSteps/publish/EmailResults.php b/src/DrupalCI/Plugin/BuildSteps/publish/EmailResults.php
deleted file mode 100644
index 0e29439..0000000
--- a/src/DrupalCI/Plugin/BuildSteps/publish/EmailResults.php
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-/**
- * @file
- * Contains \DrupalCI\Plugin\BuildSteps\publish\EmailResults
- *
- * Processes "publish: email:" instructions from within a job definition.
- * Gathers the resulting job artifacts and pushes them to an email address.
- */
-
-namespace DrupalCI\Plugin\BuildSteps\publish;
-use DrupalCI\Plugin\PluginBase;
-
-/**
- * @PluginID("email_results")
- */
-class EmailResults extends PluginBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function run() {
-    echo 'EmailResults plugin not yet implemented.';
-  }
-
-}
diff --git a/src/DrupalCI/Plugin/BuildSteps/publish/GatherArtifacts.php b/src/DrupalCI/Plugin/BuildSteps/publish/GatherArtifacts.php
deleted file mode 100644
index b03e0ff..0000000
--- a/src/DrupalCI/Plugin/BuildSteps/publish/GatherArtifacts.php
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-/**
- * @file
- * Contains \DrupalCI\Plugin\BuildSteps\publish\GatherArtifacts
- *
- * Processes "publish: gather_artifacts:" instructions from within a job definition.
- * Generates job build artifact files in a common directory.
- */
-
-namespace DrupalCI\Plugin\BuildSteps\publish;
-use DrupalCI\Console\Output;
-use DrupalCI\Plugin\JobTypes\JobInterface;
-use DrupalCI\Plugin\PluginBase;
-use DrupalCI\Plugin\BuildSteps\generic\ContainerCommand;
-
-/**
- * @PluginID("gather_artifacts")
- */
-class GatherArtifacts extends PluginBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function run(JobInterface $job, $target_directory) {
-
-    $docker = $job->getDocker();
-    $manager = $docker->getContainerManager();
-
-    Output::writeLn("<comment>Gathering job build artifacts in a common directory ...</comment>");
-
-    // Create the destination directory
-    if (!empty($target_directory)) {
-      $command = new ContainerCommand();
-      $command->run($job, "mkdir -p $target_directory");
-    }
-
-    // Store the directory in our job object
-    $job->setArtifactDirectory($target_directory);
-
-    // Retrieve the list of build artifacts from the job
-    $artifacts = $job->getArtifacts();
-
-    // Iterate over the build artifacts
-    foreach ($artifacts->getArtifacts() as $key => $artifact) {
-      if ($key == 'jobDefinition') {
-        $destination_filename = $artifact->getValue();
-
-        // Retrieve the job definition from the job
-        $definition = $job->getJobDefinition()->getDefinition();
-        // write the job definition out to a file in the artifact directory on the container.
-        if (!empty($destination_filename)) {
-          $file = $target_directory . DIRECTORY_SEPARATOR . $destination_filename;
-          // TODO: Verify file name - unique, empty, etc.
-          $command = new ContainerCommand();
-          $cmd = "cat >$file <<EOL \n" . print_r($definition, TRUE) . "\nEOL";
-          $command->run($job, $cmd);
-        }
-        else {
-          // TODO: Exception handling
-          Output::writeLn('<info>Error generating job definition build artifact.');
-        }
-      }
-      elseif (strtolower($artifact->getType()) == 'file' || $artifact->getType() == 'directory') {
-        // Copy artifact file to the build artifacts directory
-        $file = $artifact->getValue();
-        $dest = $target_directory . DIRECTORY_SEPARATOR . basename($file);
-        if ($file !== $dest) {
-          $command = new ContainerCommand();
-          $cmd = "cp -r $file $dest";
-          $command->run($job, $cmd);
-        }
-        else {
-          Output::writeLn("<info>Skipping $file, as it already exists in the build artifact directory.");
-        }
-      }
-      elseif (strtolower($artifact->getType) == 'string') {
-        // Write string to new file with filename based on the string's key
-        $dest = $target_directory . DIRECTORY_SEPARATOR . $key;
-        $content = $artifact->getValue;
-        $command = new ContainerCommand();
-        $cmd = "cat >$dest <<EOL \n" . print_r($content, TRUE) . "\nEOL";
-        $command->run($job, $cmd);
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/src/DrupalCI/Plugin/BuildSteps/publish/JunitXMLFormat.php b/src/DrupalCI/Plugin/BuildSteps/publish/JunitXMLFormat.php
deleted file mode 100644
index 9761dc6..0000000
--- a/src/DrupalCI/Plugin/BuildSteps/publish/JunitXMLFormat.php
+++ /dev/null
@@ -1,274 +0,0 @@
-<?php
-/**
- * @file
- * Contains \DrupalCI\Plugin\BuildSteps\publish\JunitXmlFormat
- *
- * Processes "publish: junit_xmlformat:" instructions from within a job
- * definition.  Connects to the database, queries for the tests, and reformats
- * them in a sane manner.  (If there is a sqlite results database!)
- */
-
-namespace DrupalCI\Plugin\BuildSteps\publish;
-use Docker\Docker;
-use DrupalCI\Console\Output;
-use DrupalCI\Plugin\JobTypes\JobInterface;
-use DrupalCI\Plugin\PluginBase;
-use PDO;
-use DOMDocument;
-
-/**
- * @PluginID("junit_xmlformat")
- */
-class JunitXMLFormat extends PluginBase {
-
-  protected $testlist = [];
-  public function setTestlist($testlist)  {  $this->testlist = $testlist; }
-  public function getTestlist() {  return $this->testlist; }
-
-  protected function loadTestList($file) {
-    $test_list = file($file, FILE_IGNORE_NEW_LINES);
-    // Get rid of the first four lines
-    $this->setTestlist(array_slice($test_list, 4));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function run(JobInterface $job, $output_directory) {
-    // Set up initial variable to store tests
-    $CoreBranch = $job->getBuildVars()["DCI_CoreBranch"];
-    $DBUrlArray = parse_url($job->getBuildVars()["DCI_DBUrl"]);
-    $DBVersion = $job->getBuildVars()["DCI_DBVersion"];
-    $DBScheme = $DBUrlArray["scheme"];
-    $DBUser   = (!empty($DBUrlArray["user"])) ? $DBUrlArray["user"] : "";
-    $DBPass   = (!empty($DBUrlArray["pass"])) ? $DBUrlArray["pass"] : "";
-    $DBDatabase = str_replace('/','',$DBUrlArray["path"]);
-    $DBIp = $job->getServiceContainers()["db"][$DBVersion]["ip"];
-    $tests = [];
-
-    // Load the list of tests from the testgroups.txt build artifact
-    // Assumes that gatherArtifacts plugin has run.
-    // TODO: Verify that gatherArtifacts has ran.
-    $source_dir = $job->getJobCodebase()->getWorkingDir();
-    // TODO: Temporary hack.  Strip /checkout off the directory
-    $artifact_dir = preg_replace('#/checkout$#', '', $source_dir);
-    $this->loadTestList($source_dir . DIRECTORY_SEPARATOR . 'artifacts/testgroups.txt');
-
-    // Set up output directory (inside working directory)
-    $output_directory = $artifact_dir . DIRECTORY_SEPARATOR . 'artifacts' . DIRECTORY_SEPARATOR . $output_directory;
-    mkdir($output_directory, 0777, TRUE);
-
-    // Set an initial default group, in case leading tests are found with no group.
-    $group = 'nogroup';
-    // Iterate through and process the test list
-    $test_list = $this->getTestlist();
-    if(strcmp($CoreBranch,'7.x') === 0 || strcmp($CoreBranch,'6.x') === 0){
-
-      foreach ($test_list as $output_line) {
-        if (substr($output_line, 0, 3) == ' - ') {
-          // This is a class
-          $class = str_replace(array('(',')'),'',end(explode(' ', $output_line)));
-          $test_groups[$class] = $group;
-        }
-        else {
-          // This is a group
-          $group = ucwords($output_line);
-        }
-      }
-      $PDO_con = "$DBScheme:host=$DBIp;dbname=$DBDatabase";
-      $db = new PDO( $PDO_con, $DBUser, $DBPass);
-
-    } else {
-
-      foreach ($test_list as $output_line) {
-        if (substr($output_line, 0, 3) == ' - ') {
-          // This is a class
-          $class = substr($output_line, 3);
-          $test_groups[$class] = $group;
-        }
-        else {
-          // This is a group
-          $group = ucwords($output_line);
-        }
-      }
-      // Crack open the sqlite database.
-      $dbfile = $source_dir . DIRECTORY_SEPARATOR . 'artifacts' . DIRECTORY_SEPARATOR . basename($job->getBuildVar('DCI_SQLite'));
-      $db = new PDO('sqlite:' . $dbfile);
-    }
-
-    // query for simpletest results
-    $results_map = array(
-      'pass' => 'Pass',
-      'fail' => 'Fail',
-      'exception' => 'Exception',
-      'debug' => 'Debug',
-    );
-
-    $q_result = $db->query('SELECT * FROM simpletest ORDER BY test_id, test_class, message_id;');
-
-    $results = array();
-
-    $cases = 0;
-    $errors = 0;
-    $failures = 0;
-
-    //while ($result = $q_result->fetchAll()) {
-    while ($result = $q_result->fetch(PDO::FETCH_ASSOC)) {
-      if (isset($results_map[$result['status']])) {
-        // Set the group from the lookup table
-        $test_group = $test_groups[$result['test_class']];
-
-        // Set the test class
-        if (isset($result['test_class'])) {
-          $test_class = $result['test_class'];
-        }
-        // Jenkins likes to see the groups and classnames together. -
-        // This might need to be re-addressed when we look at the tests.
-        $classname = $test_groups[$test_class] . '.' . $test_class;
-
-        // Cleanup the class, and the parens from the test method name
-        $test_method = substr($result['function'], strpos($result['function'], '>') + 1);
-        $test_method = substr($test_method, 0, strlen($test_method) - 2);
-
-        //$classes[$test_group][$test_class][$test_method]['classname'] = $classname;
-        $result['file'] = substr($result['file'],14); // Trim off /var/www/html
-        $classes[$test_group][$test_class][$test_method][] = array(
-          'status' => $result['status'],
-          'type' => $result['message_group'],
-          'message' => strip_tags(htmlspecialchars_decode($result['message'],ENT_QUOTES)),
-          'line' => $result['line'],
-          'file' => $result['file'],
-        );
-      }
-    }
-    $this->_build_xml($classes, $output_directory);
-  }
-
-  private function _build_xml($test_result_data, $output_dir) {
-    // Maps statuses to their xml element for each testcase.
-    $element_map = array(
-      'pass' => 'system-out',
-      'fail' => 'failure',
-      'exception' => 'error',
-      'debug' => 'system-err',
-    );
-    // Create an xml file per group?
-
-    $test_group_id = 0;
-    $doc = new DomDocument('1.0');
-    $test_suites = $doc->createElement('testsuites');
-
-    // TODO: get test name data from the job.
-    $test_suites->setAttribute('name', "TODO SET");
-    $test_suites->setAttribute('time', "TODO SET");
-    $total_failures = 0;
-    $total_tests = 0;
-    $total_exceptions = 0;
-
-    // Go through the groups, and create a testsuite for each.
-    foreach ($test_result_data as $groupname => $group_classes) {
-      $group_failures = 0;
-      $group_tests = 0;
-      $group_exceptions = 0;
-      $test_suite = $doc->createElement('testsuite');
-      $test_suite->setAttribute('id', $test_group_id);
-      $test_suite->setAttribute('name', $groupname);
-      $test_suite->setAttribute('timestamp', date('c'));
-      $test_suite->setAttribute('hostname', "TODO: Set Hostname");
-      $test_suite->setAttribute('package', $groupname);
-      // TODO: time test runs. $test_group->setAttribute('time', $test_group_id);
-      // TODO: add in the properties of the job into the test run.
-
-      // Loop through the classes in each group
-      foreach ($group_classes as $class_name => $class_methods) {
-        foreach ($class_methods as $test_method => $method_results) {
-          $test_case = $doc->createElement('testcase');
-          $test_case->setAttribute('classname', $groupname . "." . $class_name);
-          $test_case->setAttribute('name', $test_method);
-          $test_case_status = 'pass';
-          $test_case_assertions = 0;
-          $test_case_exceptions = 0;
-          $test_case_failures = 0;
-          $test_output = '';
-          $fail_output = '';
-          $exception_output = '';
-          foreach ($method_results as $assertion) {
-            $assertion_result = $assertion['status'] . ": [" . $assertion['type'] . "] Line " . $assertion['line'] . " of " . $assertion['file'] . ":\n" . $assertion['message'] . "\n\n";
-            $assertion_result = preg_replace('/[^\x{0009}\x{000A}\x{000D}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]/u', '�', $assertion_result);
-
-            // Keep track of overall assersions counts
-            if (!isset($assertion_counter[$assertion['status']])) {
-              $assertion_counter[$assertion['status']] = 0;
-            }
-            $assertion_counter[$assertion['status']]++;
-            if ($assertion['status'] == 'exception') {
-              $test_case_exceptions++;
-              $group_exceptions++;
-              $total_exceptions++;
-              $test_case_status = 'failed';
-              $exception_output .= $assertion_result;
-            } else if ($assertion['status'] == 'fail'){
-              $test_case_failures++;
-              $group_failures++;
-              $total_failures++;
-              $test_case_status = 'failed';
-              $fail_output .= $assertion_result;
-            }
-            elseif (($assertion['status'] == 'debug')) {
-              $test_output .= $assertion_result;
-            }
-
-            $test_case_assertions++;
-            $group_tests++;
-            $total_tests++;
-
-          }
-          if ($test_case_failures > 0) {
-            $element = $doc->createElement("failure");
-            $element->setAttribute('message', $fail_output);
-            $element->setAttribute('type', "fail");
-            $test_case->appendChild($element);
-          }
-
-          if ($test_case_exceptions > 0 ) {
-            $element = $doc->createElement("error");
-            $element->setAttribute('message', $exception_output);
-            $element->setAttribute('type', "exception");
-            $test_case->appendChild($element);
-          }
-          $std_out = $doc->createElement('system-out');
-          $output = $doc->createCDATASection($test_output);
-          $std_out->appendChild($output);
-          $test_case->appendChild($std_out);
-
-          // TODO: Errors and Failures need to be set per test Case.
-          $test_case->setAttribute('status', $test_case_status);
-          $test_case->setAttribute('assertions', $test_case_assertions);
-         // $test_case->setAttribute('time', "TODO: track time");
-
-          $test_suite->appendChild($test_case);
-
-        }
-      }
-
-      // Should this count the tests as part of the loop, or just array_count?
-      $test_suite->setAttribute('tests', $group_tests);
-      $test_suite->setAttribute('failures', $group_failures);
-      $test_suite->setAttribute('errors', $group_exceptions);
-      /* TODO: Someday simpletest will disable or skip tests based on environment
-      $test_group->setAttribute('disabled', $test_group_id);
-      $test_group->setAttribute('skipped', $test_group_id);
-      */
-      $test_suites->appendChild($test_suite);
-      $test_group_id++;
-    }
-    $test_suites->setAttribute('tests', $total_tests);
-    $test_suites->setAttribute('failures', $total_failures);
-   // $test_suites->setAttribute('disabled', "TODO SET");
-    $test_suites->setAttribute('errors', $total_exceptions);
-    $doc->appendChild($test_suites);
-    file_put_contents($output_dir . '/testresults.xml', $doc->saveXML());
-    Output::writeln("<info>Reformatted test results written to <options=bold>" . $output_dir . '/testresults.xml</options=bold></info>');
-  }
-
-}
diff --git a/src/DrupalCI/Plugin/JobTypes/simpletest/SimpletestJob.php b/src/DrupalCI/Plugin/JobTypes/simpletest/SimpletestJob.php
index 9583cc0..2e7efbd 100644
--- a/src/DrupalCI/Plugin/JobTypes/simpletest/SimpletestJob.php
+++ b/src/DrupalCI/Plugin/JobTypes/simpletest/SimpletestJob.php
@@ -46,7 +46,7 @@ class SimpletestJob extends JobBase {
     'DCI_GitCommitHash' => '',
     // 'DCI_XMLOutput' => '/var/www/html/results/xml',
     'DCI_PHPInterpreter' => '/opt/phpenv/shims/php',
-    'DCI_RunOptions' => 'color;keep-results',
+    'DCI_RunOptions' => 'color;keep-results;verbose',
     'DCI_SyntaxCheck' => TRUE,
   );
 
@@ -173,10 +173,10 @@ class SimpletestJob extends JobBase {
     array('testgroups', '/var/www/html/artifacts/testgroups.txt'),
     // array('run_tests_xml', '/var/www/html/results/xml', 'directory'),
     array('sqlite_test_db', '/var/www/html/results/simpletest.sqlite'),
-    // array('php_error_log', 'TODO: Locate'),
-    // array('apache_access_log', 'TODO: Locate'),
-    // array('apache_error_log', 'TODO: Locate'),
-    // array('run_tests_verbose', 'TODO: Locate', 'directory'),
+    // array('php_error_log', 'TODO: Locate'),  // STDERR
+    array('apache_access_log', '/var/log/apache2/test.apache.access.log'),
+    array('apache_error_log', '/var/log/apache2/test.apache.error.log'),
+    array('run_tests_verbose', '/var/www/html/sites/default/files/simpletest/verbose', 'archive'),
   );
 
 }
diff --git a/src/DrupalCI/Plugin/JobTypes/simpletest/drupalci.yml b/src/DrupalCI/Plugin/JobTypes/simpletest/drupalci.yml
index 24d1518..2f2c241 100644
--- a/src/DrupalCI/Plugin/JobTypes/simpletest/drupalci.yml
+++ b/src/DrupalCI/Plugin/JobTypes/simpletest/drupalci.yml
@@ -38,7 +38,7 @@ execute:
     - php %DCI_RunScript% --list --php /opt/phpenv/shims/php > /var/www/html/artifacts/testgroups.txt
   testcommand:
     - cd /var/www/html && sudo -u www-data php %DCI_RunScript% --url http://localhost/checkout --dburl %DCI_DBurl% %DCI_RunOptions% %DCI_TestGroups%
-publish:
+postprocess:
   gather_artifacts: /var/www/html/artifacts
   # archive: /var/www/html/results/artifacts.zip
   # junit_xmlformat:
