private function validate()
 {
     if (empty($this->raw) or '' == trim($this->raw)) {
         $this->valid = true;
         return true;
     }
     // CAS keyval may not contain @ or $.
     if (strpos($this->raw, '@') !== false || strpos($this->raw, '$') !== false) {
         $this->errors = stack_string('illegalcaschars');
         $this->valid = false;
         return false;
     }
     // Subtle one: must protect things inside strings before we explode.
     $str = $this->raw;
     $strings = stack_utils::all_substring_strings($str);
     foreach ($strings as $key => $string) {
         $str = str_replace('"' . $string . '"', '[STR:' . $key . ']', $str);
     }
     $str = str_replace("\n", ';', $str);
     $str = stack_utils::remove_comments($str);
     $str = str_replace(';', "\n", $str);
     $kvarray = explode("\n", $str);
     foreach ($strings as $key => $string) {
         foreach ($kvarray as $kkey => $kstr) {
             $kvarray[$kkey] = str_replace('[STR:' . $key . ']', '"' . $string . '"', $kstr);
         }
     }
     // 23/4/12 - significant changes to the way keyvals are interpreted.  Use Maxima assignmentsm i.e. x:2.
     $errors = '';
     $valid = true;
     $vars = array();
     foreach ($kvarray as $kvs) {
         $kvs = trim($kvs);
         if ('' != $kvs) {
             $cs = new stack_cas_casstring($kvs);
             $cs->get_valid($this->security, $this->syntax, $this->insertstars);
             $vars[] = $cs;
         }
     }
     $this->session->add_vars($vars);
     $this->valid = $this->session->get_valid();
     $this->errors = $this->session->get_errors();
 }
 /**
  * Checks the castext syntax is valid, no missing @'s, $'s etc
  *
  * @access public
  * @return bool
  */
 private function validate()
 {
     if (strlen(trim($this->rawcastext)) > 64000) {
         // Limit to just less than 64kb. Maximum practical size of a post. (about 14pages).
         $this->errors = stack_string("stackCas_tooLong");
         $this->valid = false;
         return false;
     }
     // Remove any comments from the castext.
     $this->trimmedcastext = stack_utils::remove_comments(str_replace("\n", ' ', $this->rawcastext));
     if (trim($this->trimmedcastext) === '') {
         $this->valid = true;
         return true;
     }
     // Find reasons to invalidate the text...
     $this->valid = true;
     // Check @'s match.
     $amps = stack_utils::check_matching_pairs($this->trimmedcastext, '@');
     if ($amps == false) {
         $this->errors .= stack_string('stackCas_MissingAt');
         $this->valid = false;
     }
     // Dollars can be protected for use with currency.
     $protected = str_replace('\\$', '', $this->trimmedcastext);
     $dollar = stack_utils::check_matching_pairs($protected, '$');
     if ($dollar == false) {
         $this->errors .= stack_string('stackCas_MissingDollar');
         $this->valid = false;
     }
     $html = stack_utils::check_bookends($this->trimmedcastext, '<html>', '</html>');
     if ($html !== true) {
         // The method check_bookends does not return false.
         $this->valid = false;
         if ($html == 'left') {
             $this->errors .= stack_string('stackCas_MissingOpenHTML');
         } else {
             $this->errors .= stack_string('stackCas_MissingCloseHTML');
         }
     }
     $inline = stack_utils::check_bookends($this->trimmedcastext, '\\[', '\\]');
     if ($inline !== true) {
         // The method check_bookends does not return false.
         $this->valid = false;
         if ($inline == 'left') {
             $this->errors .= stack_string('stackCas_MissingOpenDisplay');
         } else {
             $this->errors .= stack_string('stackCas_MissingCloseDisplay');
         }
     }
     $inline = stack_utils::check_bookends($this->trimmedcastext, '\\(', '\\)');
     if ($inline !== true) {
         // The method check_bookends does not return false.
         $this->valid = false;
         if ($inline == 'left') {
             $this->errors .= stack_string('stackCas_MissingOpenInline');
         } else {
             $this->errors .= stack_string('stackCas_MissingCloseInline');
         }
     }
     // Perform validation on the existing session.
     if (null != $this->session) {
         if (!$this->session->get_valid()) {
             $this->valid = false;
             $this->errors .= $this->session->get_errors();
         }
     }
     // Now extract and perform validation on the CAS variables.
     // This does alot more than strictly "validate" the castext, but is makes sense to do all these things at once...
     $this->extract_cas_commands();
     if (false === $this->valid) {
         $this->errors = '<span class="error">' . stack_string("stackCas_failedValidation") . '</span>' . $this->errors;
     }
     return $this->valid;
 }