def METHOD_NAME(
    request: Request, url_params: Dict[str, Any] = None
) -> ApiInvocationContext:
    """
    Converts an HTTP Request object into an ApiInvocationContext.
    :param request: the original request
    :param url_params: the parameters extracted from the URL matching rules
    :return: the ApiInvocationContext
    """
    if url_params is None:
        url_params = {}
    method = request.method
    # Base path is not URL-decoded.
    # Example: test%2Balias@gmail.com => test%2Balias@gmail.com
    path = request.environ.get("RAW_URI")
    data = restore_payload(request)
    headers = Headers(request.headers)
    # adjust the X-Forwarded-For header
    x_forwarded_for = headers.getlist("X-Forwarded-For")
    x_forwarded_for.append(request.remote_addr)
    x_forwarded_for.append(request.host)
    headers["X-Forwarded-For"] = ", ".join(x_forwarded_for)
    # set the x-localstack-edge header, it is used to parse the domain
    headers[HEADER_LOCALSTACK_EDGE_URL] = request.host_url.strip("/")
    # FIXME: Use the already parsed url params instead of parsing them into the ApiInvocationContext part-by-part.
    #   We already would have all params at hand to avoid _all_ the parsing, but the parsing
    #   has side-effects (f.e. setting the region in a thread local)!
    #   It would be best to use a small (immutable) context for the already parsed params and the Request object
    #   and use it everywhere.
    return ApiInvocationContext(method, path, data, headers, stage=url_params.get("stage"))