/**
  * Overridden version of `buildTestFuture` so that the unit test can be run
  * via `cscover`, which instruments assemblies and reports on code coverage.
  *
  * @param  string  Name of the test assembly.
  * @return array   The future, output filename and coverage filename
  *                 stored in an array.
  */
 protected function buildTestFuture($test_assembly)
 {
     if ($this->getEnableCoverage() === false) {
         return parent::buildTestFuture($test_assembly);
     }
     // FIXME: Can't use TempFile here as xUnit doesn't like
     // UNIX-style full paths. It sees the leading / as the
     // start of an option flag, even when quoted.
     $xunit_temp = Filesystem::readRandomCharacters(10) . '.results.xml';
     if (file_exists($xunit_temp)) {
         unlink($xunit_temp);
     }
     $cover_temp = new TempFile();
     $cover_temp->setPreserveFile(true);
     $xunit_cmd = $this->runtimeEngine;
     $xunit_args = null;
     if ($xunit_cmd === '') {
         $xunit_cmd = $this->testEngine;
         $xunit_args = csprintf('%s /xml %s', $test_assembly, $xunit_temp);
     } else {
         $xunit_args = csprintf('%s %s /xml %s', $this->testEngine, $test_assembly, $xunit_temp);
     }
     $assembly_dir = dirname($test_assembly);
     $assemblies_to_instrument = array();
     foreach (Filesystem::listDirectory($assembly_dir) as $file) {
         if (substr($file, -4) == '.dll' || substr($file, -4) == '.exe') {
             if ($this->assemblyShouldBeInstrumented($file)) {
                 $assemblies_to_instrument[] = $assembly_dir . DIRECTORY_SEPARATOR . $file;
             }
         }
     }
     if (count($assemblies_to_instrument) === 0) {
         return parent::buildTestFuture($test_assembly);
     }
     $future = new ExecFuture('%C -o %s -c %s -a %s -w %s %Ls', trim($this->runtimeEngine . ' ' . $this->coverEngine), $cover_temp, $xunit_cmd, $xunit_args, $assembly_dir, $assemblies_to_instrument);
     $future->setCWD(Filesystem::resolvePath($this->projectRoot));
     return array($future, $assembly_dir . DIRECTORY_SEPARATOR . $xunit_temp, $cover_temp);
 }
 protected function didFailParse($message)
 {
     $context = 5;
     $min = max(0, $this->line - $context);
     $max = min($this->line + $context, count($this->text) - 1);
     $context = '';
     for ($ii = $min; $ii <= $max; $ii++) {
         $context .= sprintf('%8.8s %6.6s   %s', $ii == $this->line ? '>>>  ' : '', $ii + 1, $this->text[$ii]);
     }
     $out = array();
     $out[] = pht('Diff Parse Exception: %s', $message);
     if ($this->writeDiffOnFailure) {
         $temp = new TempFile();
         $temp->setPreserveFile(true);
         Filesystem::writeFile($temp, $this->rawDiff);
         $out[] = pht('Raw input file was written to: %s', $temp);
     }
     $out[] = $context;
     $out = implode("\n\n", $out);
     throw new Exception($out);
 }