Tries to match a URL with a set of routes.
string $pathinfo The path info to be parsed:
RouteCollection $routes The set of routes:
array An array of parameters
ResourceNotFoundException If the resource could not be found
MethodNotAllowedException If the resource was found but the request method is not allowed
protected function matchCollection($pathinfo, RouteCollection $routes) {
  foreach ($routes as $name => $route) {
    if ($route instanceof RouteCollection) {
      if (false === strpos($route
        ->getPrefix(), '{') && $route
        ->getPrefix() !== substr($pathinfo, 0, strlen($route
        ->getPrefix()))) {
        continue;
      }
      if (!($ret = $this
        ->matchCollection($pathinfo, $route))) {
        continue;
      }
      return $ret;
    }
    $compiledRoute = $route
      ->compile();
    // check the static prefix of the URL first. Only use the more expensive preg_match when it matches
    if ('' !== $compiledRoute
      ->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute
      ->getStaticPrefix())) {
      continue;
    }
    if (!preg_match($compiledRoute
      ->getRegex(), $pathinfo, $matches)) {
      continue;
    }
    // check HTTP method requirement
    if ($req = $route
      ->getRequirement('_method')) {
      // HEAD and GET are equivalent as per RFC
      if ('HEAD' === ($method = $this->context
        ->getMethod())) {
        $method = 'GET';
      }
      if (!in_array($method, $req = explode('|', strtoupper($req)))) {
        $this->allow = array_merge($this->allow, $req);
        continue;
      }
    }
    $status = $this
      ->handleRouteRequirements($pathinfo, $name, $route);
    if (self::ROUTE_MATCH === $status[0]) {
      return $status[1];
    }
    if (self::REQUIREMENT_MISMATCH === $status[0]) {
      continue;
    }
    return array_merge($this
      ->mergeDefaults($matches, $route
      ->getDefaults()), array(
      '_route' => $name,
    ));
  }
}