class Rage::Router::Backend

def __on(method, path, handler, constraints, defaults, meta)

def __on(method, path, handler, constraints, defaults, meta)
  @constrainer.validate_constraints(constraints)
  # Let the constrainer know if any constraints are being used now
  @constrainer.note_usage(constraints)
  # Boot the tree for this method if it doesn't exist yet
  @trees[method] ||= Rage::Router::StaticNode.new("/")
  pattern = path
  if pattern == "*" && !@trees[method].prefix.empty?
    current_root = @trees[method]
    @trees[method] = Rage::Router::StaticNode.new("")
    @trees[method].static_children["/"] = current_root
  end
  current_node = @trees[method]
  parent_node_path_index = current_node.prefix.length
  i, params = 0, []
  while i <= pattern.length
    if pattern[i] == ":" && pattern[i + 1] == ":"
      # It's a double colon
      i += 2
      next
    end
    is_parametric_node = pattern[i] == ":" && pattern[i + 1] != ":"
    is_wildcard_node = pattern[i] == "*"
    if is_parametric_node || is_wildcard_node || (i == pattern.length && i != parent_node_path_index)
      static_node_path = pattern[parent_node_path_index, i - parent_node_path_index]
      static_node_path = static_node_path.split("::").join(":")
      static_node_path = static_node_path.split("%").join("%25")
      # add the static part of the route to the tree
      current_node = current_node.create_static_child(static_node_path)
    end
    if is_parametric_node
      last_param_start_index = i + 1
      j = last_param_start_index
      while true
        char = pattern[j]
        is_end_of_node = (char == "/" || j == pattern.length)
        if is_end_of_node
          param_name = pattern[last_param_start_index, j - last_param_start_index]
          params << param_name
          static_part_start_index = j
          while j < pattern.length
            j_char = pattern[j]
            break if j_char == "/"
            if j_char == ":"
              next_char = pattern[j + 1]
              next_char == ":" ? j += 1 : break
            end
            j += 1
          end
          static_part = pattern[static_part_start_index, j - static_part_start_index]
          unless static_part.empty?
            static_part = static_part.split("::").join(":")
            static_part = static_part.split("%").join("%25")
          end
          last_param_start_index = j + 1
          if is_end_of_node || pattern[j] == "/" || j == pattern.length
            node_path = pattern[i, j - i]
            pattern = "#{pattern[0, i + 1]}#{static_part}#{pattern[j, pattern.length - j]}"
            i += static_part.length
            current_node = current_node.create_parametric_child(static_part == "" ? nil : static_part, node_path)
            parent_node_path_index = i + 1
            break
          end
        end
        j += 1
      end
    elsif is_wildcard_node
      # add the wildcard parameter
      params << "*"
      current_node = current_node.create_wildcard_child
      parent_node_path_index = i + 1
      raise ArgumentError, "Wildcard must be the last character in the route" if i != pattern.length - 1
    end
    i += 1
  end
  if pattern == "*"
    pattern = "/*"
  end
  @routes.each do |existing_route|
    if existing_route[:method] == method &&
       existing_route[:pattern] == pattern &&
       existing_route[:constraints] == constraints
      raise ArgumentError, "Method '#{method}' already declared for route '#{pattern}' with constraints '#{constraints.inspect}'"
    end
  end
  route = { method:, path:, pattern:, params:, constraints:, handler:, defaults:, meta: }
  @routes << route
  current_node.add_route(route, @constrainer)
end