/**
  * Creates a route tree from the supplied routes.
  *
  * @param \Viserio\Contracts\Routing\Route[] $routes
  *
  * @return array
  */
 public function build(array $routes) : array
 {
     $rootRouteData = null;
     $nodes = [];
     $groupedRoutes = [];
     foreach ($routes as $route) {
         $groupedRoutes[count($route->getSegments())][] = $route;
     }
     if (isset($groupedRoutes[0])) {
         $rootRouteData = new MatchedRouteDataMap();
         $rootRouteData->addRoute($groupedRoutes[0][0], []);
         unset($groupedRoutes[0]);
     }
     foreach ($groupedRoutes as $segmentDepth => $group) {
         $groupNodes = [];
         foreach ($group as $route) {
             $parameterIndexNameMap = [];
             $segments = $route->getSegments();
             $segmentMatcher = $this->getMatcher(array_shift($segments), $parameterIndexNameMap);
             $firstSegmentHash = $segmentMatcher->getHash();
             if (!isset($groupNodes[$firstSegmentHash])) {
                 $groupNodes[$firstSegmentHash] = new RouteTreeNode([0 => $segmentMatcher], $segmentDepth === 1 ? new MatchedRouteDataMap() : new ChildrenNodeCollection());
             }
             $this->addRouteToNode($groupNodes[$firstSegmentHash], $route, $segments, 1, $parameterIndexNameMap);
         }
         $nodes[$segmentDepth] = new ChildrenNodeCollection($groupNodes);
     }
     return [$rootRouteData, $nodes];
 }
 /**
  * Compile the route http method match switch.
  *
  * @param object              $code
  * @param MatchedRouteDataMap $routeDataMap
  * @param array               $parameters
  */
 protected function compiledRouteHttpMethodMatch($code, MatchedRouteDataMap $routeDataMap, array $parameters)
 {
     $code->appendLine('switch ($method) {');
     ++$code->indent;
     foreach ($routeDataMap->getHttpMethodRouteDataMap() as $item) {
         list($httpMethods, $routeData) = $item;
         foreach ($httpMethods as $httpMethod) {
             $code->appendLine('case ' . VarExporter::export($httpMethod) . ':');
         }
         ++$code->indent;
         $this->compileFoundRoute($code, $routeData, $parameters);
         --$code->indent;
     }
     $code->appendLine('default:');
     ++$code->indent;
     foreach ($routeDataMap->getAllowedHttpMethods() as $method) {
         $code->appendLine('$allowedHttpMethods[] = ' . VarExporter::export($method) . ';');
     }
     $code->appendLine('break;');
     --$code->indent;
     --$code->indent;
     $code->appendLine('}');
 }