public static function parse_sorter($text)
 {
     if (!self::$_sort_keywords) {
         self::$_sort_keywords = array("by" => "by", "up" => "up", "down" => "down", "reverse" => "down", "reversed" => "down", "count" => "C", "counts" => "C", "av" => "A", "ave" => "A", "average" => "A", "med" => "E", "median" => "E", "var" => "V", "variance" => "V", "max-min" => "D", "my" => "Y", "score" => "");
     }
     $text = simplify_whitespace($text);
     $sort = ListSorter::make_empty($text === "");
     if (($ch1 = substr($text, 0, 1)) === "-" || $ch1 === "+") {
         $sort->reverse = $ch1 === "-";
         $text = ltrim(substr($text, 1));
     }
     // separate text into words
     $words = array();
     $bypos = false;
     while ($text !== "") {
         preg_match(',\\A([^\\s\\(]*)(.*)\\z,s', $text, $m);
         if (substr($m[2], 0, 1) === "(") {
             $pos = self::find_end_balanced_parens($m[2]);
             $m[1] .= substr($m[2], 0, $pos);
             $m[2] = substr($m[2], $pos);
         }
         $words[] = $m[1];
         $text = ltrim($m[2]);
         if ($m[1] === "by" && $bypos === false) {
             $bypos = count($words) - 1;
         }
     }
     // go over words
     $next_words = array();
     for ($i = 0; $i != count($words); ++$i) {
         $w = $words[$i];
         if (($bypos === false || $i > $bypos) && isset(self::$_sort_keywords[$w])) {
             $x = self::$_sort_keywords[$w];
             if ($x === "up") {
                 $sort->reverse = false;
             } else {
                 if ($x === "down") {
                     $sort->reverse = true;
                 } else {
                     if (ctype_upper($x)) {
                         $sort->score = $x;
                     }
                 }
             }
         } else {
             if ($bypos === false || $i < $bypos) {
                 $next_words[] = $w;
             }
         }
     }
     if (count($next_words)) {
         $sort->type = join(" ", $next_words);
     }
     return $sort;
 }