Find a route based on method and path.
@param $path
@param $method
@return MatchedRoute|null
764524
public function findFromPath($path, $method = null)
    {
        foreach ($this->getRoutes() as $route) {
            if ($matchedRoute = $route->matches($path, $method)) {
                return $matchedRoute;
            }
        }
        return null;
    }
657363
public function match(string $path, string $method = 'GET'): array
    {
        // if enable 'matchAll'
        if ($matchAll = $this->matchAll) {
            if (\is_string($matchAll) && $matchAll{0} === '/') {
                $path = $matchAll;
            } elseif (\is_callable($matchAll)) {
                return [self::FOUND, $path, [
                    'handler' => $matchAll,
                ]];
            }
        }

        $path = $this->formatUriPath($path, $this->ignoreLastSlash);
        $method = strtoupper($method);

        // find in route caches.
        if ($this->cacheRoutes && isset($this->cacheRoutes[$path][$method])) {
            return [self::FOUND, $path, $this->cacheRoutes[$path][$method]];
        }

        // is a static route path
        if ($this->staticRoutes && ($routeInfo = $this->findInStaticRoutes($path, $method))) {
            return [self::FOUND, $path, $routeInfo];
        }

        $first = null;
        $allowedMethods = [];

        // eg '/article/12'
        if ($pos = strpos($path, '/', 1)) {
            $first = substr($path, 1, $pos - 1);
        }

        // is a regular dynamic route(the first node is 1th level index key).
        if ($first && isset($this->regularRoutes[$first])) {
            $result = $this->findInRegularRoutes($this->regularRoutes[$first], $path, $method);

            if ($result[0] === self::FOUND) {
                return $result;
            }

            $allowedMethods = $result[1];
        }

        // is a irregular dynamic route
        if (isset($this->vagueRoutes[$method])) {
            $result = $this->findInVagueRoutes($this->vagueRoutes[$method], $path, $method);

            if ($result[0] === self::FOUND) {
                return $result;
            }
        }

        // For HEAD requests, attempt fallback to GET
        if ($method === 'HEAD') {
            if (isset($this->cacheRoutes[$path]['GET'])) {
                return [self::FOUND, $path, $this->cacheRoutes[$path]['GET']];
            }

            if ($routeInfo = $this->findInStaticRoutes($path, 'GET')) {
                return [self::FOUND, $path, $routeInfo];
            }

            if ($first && isset($this->regularRoutes[$first])) {
                $result = $this->findInRegularRoutes($this->regularRoutes[$first], $path, 'GET');

                if ($result[0] === self::FOUND) {
                    return $result;
                }
            }

            if (isset($this->vagueRoutes['GET'])) {
                $result = $this->findInVagueRoutes($this->vagueRoutes['GET'], $path, 'GET');

                if ($result[0] === self::FOUND) {
                    return $result;
                }
            }
        }

        // If nothing else matches, try fallback routes. $router->any('*', 'handler');
        if ($this->staticRoutes && ($routeInfo = $this->findInStaticRoutes('/*', $method))) {
            return [self::FOUND, $path, $routeInfo];
        }

        if ($this->notAllowedAsNotFound) {
            return [self::NOT_FOUND, $path, null];
        }

        // collect allowed methods from: staticRoutes, vagueRoutes OR return not found.
        return $this->findAllowedMethods($path, $method, $allowedMethods);
    }
564331
private function collectRoute(String $method, String $path, Callable $callback) : Route {

		if(in_array([$path, $method], $this->getRoutes()))
			throw new RouterException('Route already defined.');

		$route = new Route($method, $path, $callback);
		array_push($this->routes, $route);
		return $route;

	}
1315105
public function getByMethod($method = null)
    {
        if (is_null($method)) {
            return $this->getRoutes();
        }

        // Filter routes by the given method
        return ArrayHelper::get($this->routes, $method, []);
    }
1293498
public function findRoute($method, $uri)
	{
		$this->method = $method;
		if ($this->routesTree === null) {
			$this->routesTree = $this->parseRoutes($this->rawRoutes);
		}

		$search = $this->normalize($uri);

		$node   = $this->routesTree;
		$params = [];

		//loop every segment in request url, compare it, collect parameters names and values
		foreach ($search as $key => $v) {

			if (isset($node[$v["use"]])) {
				$node = $node[$v["use"]];
			} else if (isset($node["*"])) {

				$subnode = $node["*"];
				if (($definitions = $this->rawRoutes[$subnode["routeName"]]["definitions"]) !== null) {
					if (isset($definitions[$subnode["name"]])) {
						$definition = $definitions[$subnode["name"]];
						$regex = ($definition[0] === "(") ? $definition : $this->getMatchType($definition, "(.*)");

						if ($regex === "(.*)") {
							break;
						} else {
							if (!preg_match($regex, $v['name'])) {
								throw new RouteNotFoundException("Route for uri: {$uri} was not found");
							}
						}
					}
				}
				// This sets node to continue
				$node = $subnode;
				$params[$subnode["name"]] = $v["name"];

			} else if (isset($node["?"])) {
				$node = $node["?"];

				if (($definitions = $this->rawRoutes[$method][$node["routeName"]]["definitions"]) !== null) {
					if (isset($definitions[$node["name"]])) {
						$definition = $definitions[$node["name"]];
						$regex = ($definition[0] === "(") ? $definition : $this->getMatchType($definition, "any");

						if ($regex === "(.*)") {
							$c = count($search);
							for ($i=$key; $i < $c; $i++) {
								$b[] = $search[$i]["use"];
							}
							$params[$node["name"]] = $b;
							break;
						} else {
							if (!preg_match($regex, $v['name'])) {
								continue;
							}
							$node = $node["?"];
							$params[$node["name"]] = $v["name"];
						}
					}
				}

				$params[$node["name"]] = $v["name"];
			} else {
				throw new RouteNotFoundException("Route for uri: {$uri} was not found");
			}

		}

		// Check for route with optional parameters that are not in request url until valid action is found
		// This make tree to go to last key
		while (!isset($node["exec"]) && isset($node["?"])) {
			$node = $node["?"];
		}

		if (isset($node["exec"])) {
			if (!isset($node["exec"]["method"][$method])
				&& !isset($node["exec"]["method"]["any"])
			) {
				throw new MethodNotAllowedException("Method: {$method} is not allowed for this route");
			}

			$Route = $node["exec"]["method"][$method];
			$Route->params = $params;
			if ($a = is_array($Route->action) || is_string($Route->action)) {
				if ($a) {
					$Route->action = [$Route->namespace.$Route->action[0], $Route->action[1]];
				} else {
					$Route->action = $Route->namespace.$Route->action;
				}
			}
			return $Route;
		}
		throw new RouteNotFoundException("Route for uri: {$uri} was not found");
	}
1078460
public function request($method, $path = null, $parameters = array())
    {
        if (null === $path) {
            $url = '/messages';
        } else {
            $url  = '/messages/'.$path;
        }

        return json_decode($this->requestRaw($method, $url, $parameters), true);
    }
119188
private function _getRouteMatch($path,$routes)
	{
		foreach ($routes as $route)
		{
			if ($match = $route->getMatch($path, $this->metadata($route->getName())))
				return $match;
		}
		return false;
	}
136593
public function add($pattern, $paths = null, $method = null)
    {
        return $this->_addRoute($pattern, $paths, $method);
    }
22879
public function findMethod($method = null)
    {
        if ($method === null) {
            return $this->getConfig('findMethod');
        }

        return $this->setConfig('findMethod', $method);
    }
1081522
private function getMatchRoute(string $method, string $url)
    {
        $parsedRoutes = $this->parseRoutes($this->routeCollection);
        foreach ($parsedRoutes as $singleParsedRoute) {
            list($routeRegex, $route) = $singleParsedRoute;
            $matchedParameters        = $this->routeMatch($routeRegex, $url);

            if ($matchedParameters !== false) {
                $routeMethod = $route->getMethod();
                if ($routeMethod === $method || $routeMethod === Method::ANY) {
                    $route->setParameters($matchedParameters);

                    return $route;
                }
            }
        }

        return false;
    }
510864
public function getUriRouteFor(string $method): ?Route
    {
        if (!$this->isMethodAllowed($method)) {
            return null;
        }

        return $this->uriRoutes[$method];
    }
1347722
public Routed<T> route(M method, String path) {
    MethodlessRouter<T> router = routers.get(method);
    if (router == null) router = anyMethodRouter;

    Routed<T> ret = router.route(path);
    if (ret != null) return ret;

    if (router != anyMethodRouter) {
      ret = anyMethodRouter.route(path);
      if (ret != null) return ret;
    }

    if (notFound != null) return new Routed<T>(notFound, true, Collections.<String, String>emptyMap());

    return null;
  }
1336354
public function routes($method = null)
    {
        if ($method && isset($this->methods[$method])) {
            return $this->routes[$method];
        }
        return $this->routes;
    }
1131345
public function detectCurrentRoute($declaration, $method) {
        foreach($this->routes as $i => $route) {
            if(preg_match("#^" . $route["url"] . "$#", $declaration, $matches, PREG_OFFSET_CAPTURE)) {
                $this->routeFound = true;
                $this->methodsAvailable[] = $route["method"];

                if($method != $route["method"]) {
                    continue;
                }

                array_shift($matches);

                foreach($matches as $k => $match) {
                    $route["expressions"][$k]["value"] = $match[0];
                }

                $this->currentRoute = $route;
                return true;
            }
        }

        return false;
    }
888564
public function match( $method, $path, callable $callback ) {
        $route = new Route( mb_strtoupper( $method ), $path, $callback );
        $this->_routes[] = $route;
        return $route;
    }
526951
public static function getRoute($route, $method=null) {
// 		$routes	= static::getRoutes();
		if( $method ) {
			return isset(static::$routes[$route][$method]) ? static::$routes[$route][$method] : null;
		}
		foreach( static::getKnownMethods() as $method ) {
			if( isset(static::$routes[$route][$method]) ) {
				return static::$routes[$route][$method];
			}
		}
		return null;
	}
1341681
protected function get($method = null)
	{
		if (is_null($method)) return $this->getRoutes();

		return array_get($this->routes, $method, array());
	}