public function verifyAnswer(Answer $answer)
 {
     // TODO check typecasting
     if ($answer->answer == $this->answer) {
         return TRUE;
     }
     try {
         return Cislo::parse($answer->answer) == $this->answer;
     } catch (\Exception $e) {
         return FALSE;
     }
 }
 /**
  * @param array $node
  * @param array $vars
  * @param $inLatex
  * @param $inColor
  * @return string
  */
 private function compileNode(array $node, array $vars, &$inLatex, &$inColor)
 {
     switch ($node['tag']) {
         case self::T_TEXT:
             return isset($node['value']) ? $node['value'] : '';
         case self::T_EVAL:
             if ($node['type'] !== self::S_COMPLETE) {
                 throw new InvalidArgumentException();
             }
             return $this->evaluate($node['value'], $vars);
         case self::T_LATEX:
             if ($node['type'] === self::S_OPEN) {
                 $inLatex = TRUE;
                 $out = '$';
                 if ($inColor) {
                     $open = $this->getColorOpen($inColor, TRUE);
                     $out = "</span>\${$open}";
                 }
                 return $out . (isset($node['value']) ? $node['value'] : '');
             } else {
                 if ($node['type'] === self::S_CLOSE) {
                     $inLatex = FALSE;
                     if ($inColor) {
                         $open = $this->getColorOpen($inColor, FALSE);
                         return "}\${$open}";
                     }
                     return '$';
                 } else {
                     if ($node['type'] === self::S_INNER) {
                         return $node['value'];
                     } else {
                         if ($inColor) {
                             $openLatex = $this->getColorOpen($inColor, TRUE);
                             $openText = $this->getColorOpen($inColor, FALSE);
                             return "</span>\${$openLatex}{$node['value']}}\${$openText}";
                         }
                         return '$' . $node['value'] . '$';
                     }
                 }
             }
         case self::T_COLOR:
             $color = $inColor ?: $node['attributes']['ID'];
             $open = $this->getColorOpen($color, $inLatex);
             $close = $inLatex ? '}' : '</span>';
             if ($node['type'] === self::S_COMPLETE) {
                 return $open . $node['value'] . $close;
             } else {
                 if ($node['type'] === self::S_OPEN) {
                     $inColor = $color;
                     return $open . (isset($node['value']) ? $node['value'] : '');
                 } else {
                     if ($node['type'] === self::S_INNER) {
                         return $node['value'];
                     } else {
                         $inColor = FALSE;
                         return $close;
                     }
                 }
             }
         case self::T_INFLECT:
             if ($node['type'] === self::S_COMPLETE) {
                 return $this->inflection->inflect($node['value'], $node['attributes']['CASE']);
             } else {
                 if ($node['type'] === self::S_OPEN) {
                     $this->bufferLevel++;
                     $this->bufferData[$this->bufferLevel] = $node['attributes']['CASE'];
                     return '';
                 } else {
                     if ($node['type'] === self::S_INNER) {
                         return $node['value'];
                     } else {
                         $buffer = $this->buffers[$this->bufferLevel];
                         $case = $this->bufferData[$this->bufferLevel];
                         $out = $this->inflection->inflect($buffer, $case);
                         $this->bufferLevel--;
                         array_pop($this->buffers);
                         return $out;
                     }
                 }
             }
         case self::T_IMG:
             if ($node['type'] !== self::S_COMPLETE) {
                 throw new BlueprintCompilerException('Invalid image syntax');
             }
             $url = isset($node['attributes']['SRC']) ? $node['attributes']['SRC'] : $this->evaluate($node['attributes']['EVALSRC'], $vars);
             if (strpos($url, 'http://') !== FALSE) {
                 throw new BlueprintCompilerException("Invalid image source '{$url}', http not allowed.");
             }
             if (strpos($url, 'https://') === FALSE) {
                 $url = "/data/exercise/{$url}";
             }
             $count = $this->evaluate($node['attributes']['COUNT'], $vars);
             $size = isset($node['attributes']['SIZE']) ? $node['attributes']['SIZE'] : 48;
             return str_repeat("<img src=\"{$url}\" height=\"{$size}\" />", max(0, $count));
         case self::T_NUMBER:
             if ($node['type'] === self::S_COMPLETE) {
                 return Cislo::toWord($node['value']);
             } else {
                 if ($node['type'] === self::S_OPEN) {
                     $this->bufferLevel++;
                     return '';
                 } else {
                     if ($node['type'] === self::S_INNER) {
                         return $node['value'];
                     } else {
                         $buffer = $this->buffers[$this->bufferLevel];
                         $out = Cislo::toWord($buffer);
                         $this->bufferLevel--;
                         array_pop($this->buffers);
                         return $out;
                     }
                 }
             }
         case self::T_BOX:
             return '<span class="fillin-box"></span>';
         default:
             throw new NotImplementedException("Unknown tag '{$node['tag']}' in '{$this->errorContext}'");
     }
 }