/**
  * First, creates a new Tracker Object by importing its structure from an XML file,
  * then, imports it into the Database, before verifying the consistency
  *
  * @param string         $xmlFile        the location of the imported file
  * @param int            $groupId        the Id of the project to create the tracker
  * @param string         $name           the name of the tracker (label)
  * @param string         $description    the description of the tracker
  * @param string         $itemname       the short name of the tracker
  * @param TrackerManager $trackermanager an instance of TrackerManager
  *
  * @return the new Tracker, or null if error
  */
 public function createFromXML($xmlFile, $groupId, $name, $description, $itemname, $trackermanager)
 {
     $tracker = null;
     if ($this->validMandatoryInfoOnCreate($name, $description, $itemname, $groupId)) {
         // XML validation before creating a new tracker
         $dom = new DOMDocument();
         $dom->load($xmlFile);
         $rng = realpath(dirname(__FILE__) . '/../../www/resources/tracker.rng');
         if (!@$dom->relaxNGValidate($rng)) {
             //hide warning since we will extract the errors below
             //try to be more verbose for the end user (RelaxNG notices are hidden)
             $hp = Codendi_HTMLPurifier::instance();
             $indent = $GLOBALS['codendi_utils_prefix'] . '/xml/indent.xsl';
             $jing = $GLOBALS['codendi_utils_prefix'] . '/xml/jing.jar';
             $temp = tempnam($GLOBALS['tmp_dir'], 'xml');
             $cmd_indent = "xsltproc -o {$temp} {$indent} {$xmlFile}";
             `{$cmd_indent}`;
             $output = array();
             $cmd_valid = "java -jar {$jing} {$rng} {$temp}";
             exec($cmd_valid, $output);
             $errors = array();
             if ($trackermanager) {
                 $project = ProjectManager::instance()->getProject($groupId);
                 $breadcrumbs = array(array('title' => 'Create a new tracker', 'url' => TRACKER_BASE_URL . '/?group_id=' . $project->group_id . '&func=create'));
                 $toolbar = array();
                 $trackermanager->displayHeader($project, 'Trackers', $breadcrumbs, $toolbar);
                 //var_dump($cmd_indent, $cmd_valid);
                 echo '<h2>XML file doesnt have correct format</h2>';
                 foreach ($output as $o) {
                     $matches = array();
                     preg_match('/:(\\d+):(\\d+):([^:]+):(.*)/', $o, $matches);
                     //1 line
                     //2 column
                     //3 type
                     //4 message
                     $errors[$matches[1]][$matches[2]][] = array(trim($matches[3]) => trim($matches[4]));
                     echo '<a href="#line_' . $matches[1] . '">' . $matches[3] . ': ' . $matches[4] . '</a><br />';
                 }
                 $clear = $GLOBALS['HTML']->getimage('clear.png', array('width' => 24, 'height' => 1));
                 $icons = array('error' => $GLOBALS['HTML']->getimage('ic/error.png', array('style' => 'vertical-align:middle')));
                 $styles = array('error' => 'color:red; font-weight:bold;');
                 echo '<pre>';
                 foreach (file($temp) as $number => $line) {
                     echo '<div id="line_' . ($number + 1) . '">';
                     echo '<span style="color:gray;">' . sprintf('%4d', $number + 1) . '</span>' . $clear . $hp->purify($line, CODENDI_PURIFIER_CONVERT_HTML);
                     if (isset($errors[$number + 1])) {
                         foreach ($errors[$number + 1] as $c => $e) {
                             echo '<div>' . sprintf('%3s', '') . $clear . sprintf('%' . ($c - 1) . 's', '') . '<span style="color:blue; font-weight:bold;">^</span></div>';
                             foreach ($e as $error) {
                                 foreach ($error as $type => $message) {
                                     $style = isset($styles['error']) ? $styles['error'] : '';
                                     echo '<div style="' . $style . '">';
                                     if (isset($icons[$type])) {
                                         echo $icons[$type];
                                     } else {
                                         echo $clear;
                                     }
                                     echo sprintf('%3s', '') . sprintf('%' . ($c - 1) . 's', '') . $message;
                                     echo '</div>';
                                 }
                             }
                         }
                     }
                     echo '</div>';
                 }
                 echo '</pre>';
                 unlink($temp);
                 $trackermanager->displayFooter($project);
                 exit;
             } else {
                 unlink($temp);
                 echo PHP_EOL;
                 echo implode(PHP_EOL, $output);
                 echo PHP_EOL;
             }
         } else {
             //create the tracker as a SimpleXMLElement
             $trackerXML = simplexml_load_file($xmlFile);
             $tracker = $this->getInstanceFromXML($trackerXML, $groupId, $name, $description, $itemname);
             //Testing consistency of the imported tracker before updating database
             if ($tracker->testImport()) {
                 if ($tracker_id = $this->saveObject($tracker)) {
                     $tracker->setId($tracker_id);
                 } else {
                     $GLOBALS['Response']->addFeedback('error', $GLOBALS['Language']->getText('plugin_tracker_admin', 'error_during_creation'));
                     $tracker = null;
                 }
             } else {
                 $GLOBALS['Response']->addFeedback('error', 'XML file cannot be imported');
                 $tracker = null;
             }
         }
     }
     return $tracker;
 }