private function _nextCommand()
 {
     $return = "";
     $this->_debug("[+] _nextCommand");
     $this->_intend++;
     $nextToken = $this->_next();
     if (is_string($nextToken)) {
         $this->_debug("[+] _runString \" " . $nextToken . " \"");
     } else {
         $this->_debug("[+] _runCommand (" . token_name($nextToken[0]) . ") [" . htmlentities($nextToken[1]) . "]");
     }
     $this->_intend++;
     switch ($nextToken[0]) {
         case ";":
             #				echo "Found ;";
             #				var_dump($return);
             #return $return;
             break;
         case T_IF:
             $return = $this->_run_if();
             break;
         case T_FOREACH:
             $this->_run_foreach();
             break;
         case T_ARRAY:
             $return = $this->_getFunctionParameters();
             break;
         case T_VARIABLE:
             if ($this->_nextByReference == true) {
                 $byRef = true;
                 $this->_nextByReference = false;
             } else {
                 $byRef = false;
             }
             $varName = substr($nextToken[1], 1);
             $tmpToken = $this->_next(false);
             $pointerSet = false;
             $varPointer = false;
             $addItem = false;
             if ($tmpToken == "[") {
                 $keys = array();
                 $this->_debug('Array found');
                 while ($this->_next(false) == "[") {
                     $this->_currentPos++;
                     if ($this->_next(false) == "]") {
                         $this->_currentPos++;
                         $addItem = true;
                         break;
                     }
                     $keys[] = $this->_getArrayKey();
                 }
                 $pointerSet = true;
                 $varPointer =& $this->_variables[$varName];
                 foreach ($keys as $key) {
                     if (!is_array($varPointer)) {
                         $varPointer = array();
                     }
                     $pointerSet = true;
                     $varPointer =& $varPointer[$key];
                 }
                 if ($addItem == true) {
                     if (!is_array(&$varPointer)) {
                         $varPointer = array();
                     }
                     array_push(&$varPointer, null);
                     $pointerSet = true;
                     $varPointer =& $varPointer[count($varPointer) - 1];
                 }
             }
             $tmpToken = $this->_next(false);
             // Wird eine Zuweisung
             if (!is_array($tmpToken) && $tmpToken == "=" || is_array($tmpToken) && in_array($tmpToken[0], array(T_PLUS_EQUAL, T_MINUS_EQUAL))) {
                 $this->_debug(" #  prepare Assignment [" . $varName . "]");
                 $this->_currentPos++;
                 if (!is_array($tmpToken) || !in_array($tmpToken[0], array(T_PLUS_EQUAL, T_MINUS_EQUAL))) {
                     $valueOfVariable = $this->_nextCommand();
                 }
                 if (is_array($tmpToken) && in_array($tmpToken[0], array(T_PLUS_EQUAL, T_MINUS_EQUAL))) {
                     if (!$pointerSet) {
                         if (isset($this->_variables[$varName])) {
                             $startvalue = $this->_variables[$varName];
                             $this->_debug(" #  _getVariable [" . $varName . "] = " . $startvalue);
                         }
                     } else {
                         $startvalue = $varPointer;
                         $this->_debug(" #  _getArrayVariable [" . $varName . "][" . implode("][", $keys) . "] = " . $startvalue);
                     }
                 } else {
                     $startvalue = 0;
                 }
                 if (is_array($tmpToken) && $tmpToken[0] == T_MINUS_EQUAL) {
                     $valueOfVariable = $startvalue - $this->_nextCommand();
                 } elseif (is_array($tmpToken) && $tmpToken[0] == T_PLUS_EQUAL) {
                     $valueOfVariable = $startvalue + $this->_nextCommand();
                 }
                 if ($varName == "disableFunctionlist" && $valueOfVariable == "1") {
                     $this->_disableFunctionlist = true;
                 }
                 if (!$pointerSet) {
                     $this->_debug(" #  _setVariable [" . $varName . "] = " . serialize($valueOfVariable));
                     $this->_variables[$varName] = $valueOfVariable;
                 } else {
                     $this->_debug(" #  _setArrayVariable [" . $varName . "][" . implode("][", $keys) . "] = " . serialize($valueOfVariable));
                     $varPointer = $valueOfVariable;
                 }
             } elseif (isset($this->_variables[$varName]) || $pointerSet) {
                 if (!$pointerSet) {
                     if ($byRef == true) {
                         $value =& $this->_variables[$varName];
                     } else {
                         $value = $this->_variables[$varName];
                     }
                     $this->_debug(" #  _getVariable " . ($byRef == true ? "&" : "") . "[" . $varName . "] = " . $value);
                 } else {
                     if ($byRef == true) {
                         $value =& $varPointer;
                     } else {
                         $value = $varPointer;
                     }
                     $this->_debug(" #  _getArrayVariable " . ($byRef == true ? "&" : "") . "[" . $varName . "][" . implode("][", $keys) . "] = " . $value);
                 }
                 $return = $value;
             } elseif (is_array($tmpToken) && $tmpToken[0] == T_OBJECT_OPERATOR) {
                 $this->_debug(" #  _getValue from reference");
                 $this->_currentPos++;
                 $moduleToken = $this->_next(false);
                 if ($varName != "current_user") {
                     /**
                      * @var $reference VTEntity
                      */
                     $reference = $this->_context->getReference($moduleToken[1], $varName);
                 } else {
                     global $current_user;
                     /**
                      * @var $reference VTEntity
                      */
                     $reference = VTEntity::getForId($current_user->id, $moduleToken[1]);
                 }
                 $this->_currentPos++;
                 $tmpToken = $this->_next(false);
                 if (is_array($tmpToken) && $tmpToken[0] == T_OBJECT_OPERATOR) {
                     $this->_currentPos++;
                     $tmpToken = $this->_next(false);
                     $this->_currentPos++;
                     if ($reference instanceof VTEntity) {
                         $return = $reference->get($tmpToken[1]);
                     } else {
                         #error_log("No Reference defined for $".$varName."->".$moduleToken[1]);
                         throw new ExpressionException("No Reference defined for \$" . $varName . "->" . $moduleToken[1]);
                     }
                 } else {
                     throw new ExpressionException("Error in ExpressionParser near \$" . $varName . "->" . $moduleToken[1]);
                 }
             } else {
                 $return = $this->_context->get($varName);
                 $this->_debug(" #  _getValue {$varName} = ('" . $return . "')");
             }
             #var_dump($this->_variables);
             break;
         case T_DNUMBER:
             $return = $nextToken[1];
             break;
         case T_STRING:
             if (defined($nextToken[1])) {
                 $this->_debug(" #  Constant Found");
                 $return = constant($nextToken[1]);
             } elseif (function_exists("VT_" . $nextToken[1])) {
                 $this->_debug(" #  Custom function");
                 // Methodennamen werden umgeschrieben um nur bestimmte Funktionen zuzulassen
                 $methodName = "VT_" . $nextToken[1];
                 $parameter = $this->_getFunctionParameters();
                 $return = call_user_func_array($methodName, $parameter);
             } elseif ($this->_disableFunctionlist || in_array($nextToken[1], self::$WhitelistPHPfunctions) || substr($nextToken[1], 0, 3) == "str" || substr($nextToken[1], 0, 5) == "array" || substr($nextToken[1], 0, 3) == "wf_" || substr($nextToken[1], 0, 5) == "array") {
                 $this->_debug(" #  Whitelisted PHP Function");
                 $parameter = $this->_getFunctionParameters();
                 $return = call_user_func_array($nextToken[1], $parameter);
             }
             break;
         case "-":
             #$this->_currentPos++;
             $nextValue = $this->_next();
             $return = -1 * $nextValue[1];
             break;
         case "&":
             $this->_nextByReference = true;
             break;
         case "(":
             $return = $this->_nextCommand();
             $this->_currentPos++;
             break;
         case ")":
             $this->_debug("    RETURN Brackets ['" . $return . "']");
             $this->_intend--;
             return $return;
             break;
         case T_LNUMBER:
             $return = floatval($nextToken[1]);
             break;
         case T_CONSTANT_ENCAPSED_STRING:
             if ((substr($nextToken[1], 0, 1) == "'" || substr($nextToken[1], 0, 1) == '"') && substr($nextToken[1], -1, 1) == substr($nextToken[1], 0, 1)) {
                 $nextToken[1] = trim($nextToken[1], "'" . '"');
             }
             $return = $nextToken[1];
             break;
         case T_RETURN:
             $return = $this->_nextCommand();
             $this->_setReturn($return);
             break;
         case T_COMMENT:
             $return = $this->_nextCommand();
             break;
         case T_IS_NOT_IDENTICAL:
         case T_IS_IDENTICAL:
         case T_IS_EQUAL:
         case T_IS_GREATER_OR_EQUAL:
         case T_IS_IDENTICAL:
         case T_IS_NOT_EQUAL:
         case T_IS_NOT_IDENTICAL:
         case T_IS_SMALLER_OR_EQUAL:
             $this->_currentPos--;
             $return = false;
             break;
         default:
             break;
     }
     $this->_debug("  potential next: " . $this->_next(false));
     if ($this->_next(false) == ")") {
         #$this->_intend--;
         #return $return;
     }
     if ($this->_next(false) == ".") {
         $this->_currentPos++;
         $this->_debug("[ ] _foundCombination");
         $return .= $this->_nextCommand();
     }
     $this->_intend--;
     $tmpToken = $this->_next(false);
     if (in_array($tmpToken, array("+", "-", "*", "/", "^"))) {
         $this->_debug("    found Operation");
         $this->_currentPos++;
         $valueOfVariable = $this->_nextCommand();
         if (empty($return)) {
             $return = 0;
         }
         if (empty($valueOfVariable)) {
             $valueOfVariable = 0;
         }
         $this->_debug("    run Operation ('return " . $return . " " . $tmpToken . " " . $valueOfVariable . ";')");
         $return = eval('return ' . $return . ' ' . $tmpToken . ' ' . $valueOfVariable . ';');
     }
     $this->_intend--;
     $this->_debug("[-] _nextCommand ['" . htmlentities($return . "") . "']");
     return $return;
 }
 protected function matchHandler($match)
 {
     // Wenn count($match) == 2, dann nur $email und keine referenzierten Felder
     if (count($match) == 2) {
         // Special Variables
         if ($match[0] == '$current_user_id') {
             global $current_user, $adb;
             $sql = "SELECT id FROM vtiger_ws_entity WHERE name = 'Users'";
             $result = $adb->query($sql);
             $wsTabId = $adb->query_result($result, 0, "id");
             return $wsTabId . "x" . $current_user->id;
         }
         $fieldname = $match[1];
         $fieldvalue = $this->_context->get($fieldname);
         if ($fieldvalue === false) {
             return '$' . $fieldname;
         }
         if (!empty($fieldvalue)) {
             return $fieldvalue;
         }
         // it is a global function
     } elseif (substr($match[0], 0, 2) == "\$[") {
         $function = strtolower($match[3]);
         if (count($match) > 4 && $match[4] != "") {
             $parameter = explode(",", $match[6]);
             for ($i = 0; $i < count($parameter); $i++) {
                 $parameter[$i] = trim($parameter[$i], "'\" ");
             }
         } else {
             $parameter = false;
         }
         switch ($function) {
             case "url":
                 if ($parameter != false && count($parameter) > 0) {
                     $parameter[0] = intval($parameter[0]);
                     $objTMP = VTEntity::getForId($parameter[0]);
                     global $site_URL;
                     return $site_URL . '/index.php?action=DetailView&module=' . $objTMP->getModuleName() . '&record=' . $parameter[0];
                 }
                 break;
             case "now":
                 $format = "Y-m-d";
                 $time = time();
                 if ($parameter != false) {
                     if (!empty($parameter[0])) {
                         $time += intval($parameter[0]) * 86400;
                     }
                     if (!empty($parameter[1])) {
                         $format = $parameter[1];
                     }
                 }
                 return date($format, $time);
                 break;
             case "entityname":
                 if ($parameter != false) {
                     $parameter[0] = VTTemplate::parse($parameter[0], $this->_context);
                     if (strpos($parameter[0], "x") !== false) {
                         $crmid = explode("x", $parameter[0]);
                         $crmid = intval($crmid[1]);
                     } else {
                         $crmid = intval($parameter[0]);
                     }
                     global $adb;
                     $sql = "SELECT setype FROM vtiger_crmentity WHERE crmid=?";
                     $result = $adb->pquery($sql, array($crmid));
                     $data = $adb->fetchByAssoc($result);
                     $return = getEntityName($data['setype'], array($crmid));
                     return $return[$crmid];
                 } else {
                     return "";
                 }
                 break;
         }
     } else {
         preg_match('/\\((\\w+) ?: \\(([_\\w]+)\\) (\\w+)\\)/', $match[1], $matches);
         list($full, $referenceField, $referenceModule, $fieldname) = $matches;
         if ($referenceField == "smownerid") {
             $referenceField = "assigned_user_id";
         }
         if ($referenceModule === '__VtigerMeta__') {
             return $this->_getMetaValue($fieldname);
         } else {
             if ($referenceField != "current_user") {
                 $referenceId = $this->_context->get($referenceField);
                 if ($referenceId == null) {
                     return "";
                 }
             } else {
                 global $current_user;
                 $referenceId = $current_user->id;
             }
             $entity = VTEntity::getForId($referenceId, $referenceModule == "Users" ? "Users" : false);
             return $entity->get($fieldname);
         }
     }
 }