class Rage::Router::Backend

def find(env, derived_constraints)

def find(env, derived_constraints)
  method, path = env["REQUEST_METHOD"], env["PATH_INFO"]
  path.delete_suffix!("/") if path.end_with?("/") && path.length > 1
  current_node = @trees[method]
  return nil unless current_node
  origin_path = path
  path_index = current_node.prefix.length
  url_params = []
  path_len = path.length
  brothers_nodes_stack = []
  while true
    if path_index == path_len && current_node.is_leaf_node
      handle = current_node.handler_storage.get_matching_handler(derived_constraints)
      if handle
        return {
          handler: handle[:handler],
          params: handle[:create_params_object].call(url_params)
        }
      end
    end
    node = current_node.get_next_node(path, path_index, brothers_nodes_stack, url_params.length)
    unless node
      return if brothers_nodes_stack.length == 0
      brother_node_state = brothers_nodes_stack.pop
      path_index = brother_node_state[:brother_path_index]
      url_params.slice!(brother_node_state[:params_count], url_params.length)
      node = brother_node_state[:brother_node]
    end
    current_node = node
    if current_node.kind == Rage::Router::Node::STATIC
      path_index += current_node.prefix.length
      next
    end
    if current_node.kind == Rage::Router::Node::WILDCARD
      param = origin_path[path_index, origin_path.length - path_index]
      param = Rack::Utils.unescape(param) if param.include?("%")
      url_params << param
      path_index = path_len
      next
    end
    if current_node.kind == Rage::Router::Node::PARAMETRIC
      param_end_index = origin_path.index("/", path_index)
      param_end_index = path_len unless param_end_index
      param = origin_path.slice(path_index, param_end_index - path_index)
      param = Rack::Utils.unescape(param) if param.include?("%")
      url_params << param
      path_index = param_end_index
    end
  end
end