/**
  * 
  * @param PHPExcel_Worksheet $worksheet
  * @param InterfaceObject $ifc
  * @return void
  */
 private function ParseWorksheetWithIfc($worksheet, $ifc)
 {
     /* Use interface name as worksheet name. Format for content is as follows:
        #1 <srcConcept> | <ifc label x> | <ifc label y> | <etc>
        #2 <srcAtomA>   | <tgtAtom1>    | <tgtAtom2>    | <etc>
        #3 <srcAtomB>   | <tgtAtom3>    | <tgtAtom4>    | <etc>
        */
     $highestrow = $worksheet->getHighestRow();
     $highestcolumn = $worksheet->getHighestColumn();
     $highestcolumnnr = PHPExcel_Cell::columnIndexFromString($highestcolumn);
     $leftConcept = Concept::getConceptByLabel((string) $worksheet->getCell('A1'));
     if ($leftConcept != $ifc->tgtConcept) {
         throw new Exception("Target concept of interface '{$ifc->path}' does not match concept specified in cell {$worksheet->getTitle()}:A1", 500);
     }
     // Parse other columns of first row
     $header = array();
     for ($columnnr = 1; $columnnr < $highestcolumnnr; $columnnr++) {
         $columnletter = PHPExcel_Cell::stringFromColumnIndex($columnnr);
         $cell = $worksheet->getCell($columnletter . '1');
         $cellvalue = (string) $cell->getCalculatedValue();
         if ($cellvalue == '') {
             $header[$columnletter] = null;
         } else {
             $subIfc = $ifc->getSubinterfaceByLabel($cellvalue);
             if (!$subIfc->crudU || !$subIfc->relation) {
                 throw new Exception("Update not allowed/possible for {$subIfc->label} as specified in cell {$columnletter}1", 403);
             }
             $header[$columnletter] = $subIfc;
         }
     }
     for ($row = 2; $row <= $highestrow; $row++) {
         $firstCol = (string) $worksheet->getCell('A' . $row)->getCalculatedValue();
         if ($firstCol == '') {
             continue;
         } elseif ($firstCol == '_NEW') {
             if (!$ifc->crudC) {
                 throw new Exception("Trying to create new atom in cell A{$row}. This is not allowed.", 403);
             }
             $leftAtom = $leftConcept->createNewAtom()->addAtom();
         } else {
             $leftAtom = new Atom($firstCol, $leftConcept);
             if (!$leftAtom->atomExists() && !$ifc->crudC) {
                 throw new Exception("Trying to create new {$leftConcept} in cell A{$row}. This is not allowed.", 403);
             }
             $leftAtom->addAtom();
         }
         for ($columnnr = 1; $columnnr < $highestcolumnnr; $columnnr++) {
             $columnletter = PHPExcel_Cell::stringFromColumnIndex($columnnr);
             if (is_null($header[$columnletter])) {
                 continue;
             }
             // skip this column.
             $cell = $worksheet->getCell($columnletter . $row);
             $cellvalue = (string) $cell->getCalculatedValue();
             if ($cellvalue == '') {
                 continue;
             }
             // skip if not value provided
             // overwrite $cellvalue in case of datetime
             // the @ is a php indicator for a unix timestamp (http://php.net/manual/en/datetime.formats.compound.php), later used for typeConversion
             if (PHPExcel_Shared_Date::isDateTime($cell) && !empty($cellvalue)) {
                 $cellvalue = '@' . (string) PHPExcel_Shared_Date::ExcelToPHP($cellvalue);
             }
             $rightAtom = new Atom($cellvalue, $header[$columnletter]->tgtConcept);
             if (!$rightAtom->atomExists() && !$header[$columnletter]->crudC) {
                 throw new Exception("Trying to create new {$header[$columnletter]->tgtConcept} in cell {$columnletter}{$row}. This is not allowed.", 403);
             }
             $header[$columnletter]->relation()->addLink($leftAtom, $rightAtom, $header[$columnletter]->relationIsFlipped, 'ExcelImport');
         }
     }
 }