static function run_script($layout_script, $param = '', $layout_name = '[inline]')
 {
     if (!self::$shutdown_function_registered) {
         register_shutdown_function(function () {
             if (($e = error_get_last()) && $e['message'] > '') {
                 echo LayoutProcessor::error($e['message'] . "\n* Script crashed with error code " . $e['type'] . ': ' . $e['file'] . ' line ' . $e['line'] . "\n* Scope stack dump:" . print_r(LayoutProcessor::$scope, true));
             }
         });
         self::$shutdown_function_registered = true;
     }
     $lines = Indentation::blocks($layout_script);
     $line_no_offset = 0;
     $output = array();
     $scope = array('layout_name' => $layout_name, 'statement_type' => '', 'line_no' => 0, 'vars' => array('_param' => $param), 'if_state' => NULL);
     if (self::$scope && isset(self::$scope[count(self::$scope) - 1]['statement_type']) && self::$scope[count(self::$scope) - 1]['statement_type'] == 'method command' && isset(self::$scope[count(self::$scope) - 1]['cmd']) && in_array(self::$scope[count(self::$scope) - 1]['cmd'], array('if', 'elseif', 'else', 'loop', 'while'))) {
         $scope['vars'] =& self::$scope[count(self::$scope) - 1]['vars'];
         $scope['layout_name'] = self::$scope[count(self::$scope) - 1]['layout_name'];
         $line_no_offset = self::$scope[count(self::$scope) - 1]['line_no'];
     }
     if (count(self::$scope) >= static::MAX_RECURSION_DEPTH) {
         return static::error('Recursion error when calling ' . $layout_name);
     }
     self::$scope[] =& $scope;
     foreach ($lines as $linedata) {
         list($scope['line_no'], $line) = $linedata;
         $scope['line_no'] += $line_no_offset;
         if (in_array($prefix = substr($line, 0, 1), array_keys(self::$prefix))) {
             list($statement_type, $callback) = static::resolve_statement_type($prefix);
             $scope['statement_type'] = $statement_type;
             if ($statement_type != 'invalid') {
                 $stmt = substr($line, 1);
                 # remove prefix
                 $output[] = forward_static_call($callback, $stmt);
             } else {
                 $output[] = static::error("Prefix {$prefix} is not callable!");
             }
         } else {
             list($layout_name, $param) = strpos($line, ':') !== false ? explode(':', $line, 2) : array($line, '');
             $scope['statement_type'] = 'layout';
             $layout_script = static::get($layout_name);
             if ($layout_script === false) {
                 if (strlen($layout_name) > static::$layout_name_cap) {
                     # probably indentation error
                     $layout_name = substr($layout_name, 0, static::$layout_name_cap) . '...';
                 }
                 $output[] = static::error("Undefined layout '{$layout_name}'");
             } else {
                 $layout_item = self::$layouts[$layout_name];
                 $remember_context = self::$context;
                 self::$context = (isset($layout_item['name']) ? $layout_item['name'] : $layout_name) . (isset($layout_item['parent']) ? ' #' . $layout_item['parent'] : '') . (isset($layout_item['id']) ? '/' . $layout_item['id'] : '');
                 $layout_script = str_replace(static::PARAM_PLACEHOLDER, $param, $layout_script);
                 $param = Indentation::unindent($param);
                 $output[] = static::run_script($layout_script, $param, $layout_name);
                 # ! recursive
                 self::$context = $remember_context;
             }
         }
         if ($scope['statement_type'] == 'method command') {
             $scope['prev_cmd'] = $scope['cmd'];
         } elseif ($scope['statement_type'] == 'method comment') {
         } else {
             unset($scope['cmd'], $scope['prev_cmd']);
         }
         if (self::$error_exit) {
             if (static::$error_mode & self::ERR_CANCEL) {
                 return array_pop($output);
             }
             if (static::$error_mode & self::ERR_RESUME) {
                 if (self::$error_exit != $scope['layout_name']) {
                     self::$error_exit = false;
                 } else {
                     break;
                 }
             } else {
                 break;
             }
         }
         if (self::$continue_loop || self::$break_counter) {
             break;
         }
         if (self::$return) {
             if (self::$return != $scope['layout_name']) {
                 self::$return = false;
             } else {
                 break;
             }
         }
     }
     array_pop(self::$scope);
     return implode('', $output);
 }