protected function sortRoutes()
    {
        //TODO store the first preordering set in cache, it need to order just one time
        $routes = array();
        foreach ($this->routes as $i => $item) {
            $this->routes[$i]['patCount'] = count(explode('/', $item->getPattern()));
            $this->routes[$i]['reqCount'] = count($item->getRequirements());
            $this->routes[$i]['varCount'] = count($item->getVars());
            $this->routes[$i]['pop'] = trim(array_pop(explode('/', $item->getPattern())));
        }

        $list = $this->routes;
        // first, order by separator number '/'
        usort($list, function ($a, $b)
        {
            if ($b['patCount'] == $a['patCount']) {
                return 0;
            }

            return $b['patCount'] < $a['patCount'] ? 1 : -1;
        });

        $n = count($list);
        for ($i = 1; $i < $n; $i++) {
            $j= $i - 1;
            while (
                $j>=0 && $list[$j]['patCount'] == $list[$i]['patCount'] &&
                $list[$j]['varCount'] > $list[$i]['varCount']
            ) {
                $this->swapValues($list[$j+1],$list[$j]);
                $j--;
            }
        }

        for ($i = 1; $i < $n; $i++) {
            $j= $i - 1;
            while (
                $j>=0 && $list[$j]['patCount'] == $list[$i]['patCount'] &&
                $list[$j]['varCount'] >= $list[$i]['varCount'] && $list[$j]['reqCount'] < $list[$i]['reqCount']
            ) {
                $this->swapValues($list[$j+1],$list[$j]);
                $j--;
            }
        }

        $this->routes = $list;
    }