async function(context <%_ if (allowOverride) { _%>, override = {} <%_ } _%>) {

    <%_ if (!isTrigger) { _%>
    // eslint-disable-next-line no-unused-vars
    const input = context.messages.in.content;
    <%_ } _%>

    <%#
    TODO: Support different expansion styles for arrays and objects: path-style, label expansion, simple-style.
    See https://swagger.io/docs/specification/describing-parameters/#path-parameters
    %>
    <%_ if (path) { _%>
    let url = lib.getBaseUrl(context) + `<%- path.replace(/\{(.+?)\}/g, (m, parameterName) => {
        return '${input["' + parameterName + '"]}';
    }) %>`;
    <%_ } else {_%>
    let url = null;
    <%_ } _%>

    const headers = {};
    <%_ if (queryParameters.length > 0 || authSchemeType === 'apiKeyQuery' || authSchemeType === 'xConnectionApiKeyQuery' || allowOverride) { _%>
    const query = new URLSearchParams;
    <%_ } _%>

    <%_ if (allowPayload) { _%>
    const inputMapping = {
     <%- Object.keys(requestBodyProperties || {}).map(propertyName => {
         // Set and unwrap.
         if (requestBodyProperties[propertyName].originalType) {
            return '\'' + requestBodyProperties[propertyName].path + '\': !!input[\'' + propertyName + '\'] ? JSON.parse(input[\'' + propertyName + '\']) : undefined,'
         }
         return '\'' + requestBodyProperties[propertyName].path + '\': input[\'' + propertyName + '\'],'
     }).join('\n') %>
    };
    let requestBody = {};
    lib.setProperties(requestBody, inputMapping);
    <%_ } _%>

    <%_ if (requestBodyTransform) { _%>
    <%_ if (requestBodyTransform.language === 'javascript') { _%>
    <%- requestBodyTransform.expression %>
    <%_ } _%>
    <%_ } _%>

    <%_ if (requestBodyMediaType === 'multipart/form-data') { _%>
    // Request media type is multipart/form-data. Convert body to FormData object.

    const fileUploadProperties = {
        <%- Object.keys(requestBodyProperties || {}).map(propertyName => {
            const isFileUpload = requestBodyProperties[propertyName].type === 'string' && requestBodyProperties[propertyName].format === 'binary';
            return '"' + propertyName + '": ' + (isFileUpload ? 'true' : 'false');
        }).join(',\n        ') %>
    };

    const form = new lib.FormData;
    for (const propertyName of Object.keys(requestBody || {})) {
        const propertyValue = requestBody[propertyName];

        if (fileUploadProperties[propertyName]) {
            const fileInfo = await context.getFileInfo(propertyValue);
            const fileStream = await context.getFileReadStream(propertyValue);
            // Note that since we're uploading using the GridFSBucketReadStream, we need to provide additional
            // info such as the `filename` to the FormData library. Otherwise, we would get back "MultipartFile content must be provided" error.
            form.append(propertyName, fileStream, { type: 'application/octet-stream', filename: fileInfo.filename });
        } else {
            form.append(propertyName, propertyValue);
        }
    }
    headers['Content-Type'] = `multipart/form-data; boundary=${form.getBoundary()}`;
    requestBody = form;
    <%_ } _%>

    <%_ if (queryParameters.length > 0 || allowOverride) { _%>
    const queryParameters = { <%-
        queryParameters.map(parameter => {
            return '\'' + parameter.name + '\': input[\'' + parameter.name + '\']';
        }).join(',\n        ')
    %> };
    <%_ } _%>

    <%_ if (allowOverride) { _%>
    if (override?.query) {
        Object.keys(override.query).forEach(parameter => {
            queryParameters[parameter] = override.query[parameter];
        });
    }
    <%_ } _%>

    <%_ if (queryParameters.length > 0 || allowOverride) { _%>
    Object.keys(queryParameters).forEach(parameter => {
        if (queryParameters[parameter]) {
            query.append(parameter, queryParameters[parameter]);
        }
    });
    <%_ } _%>

    <%_ if (authSchemeType === 'oauth2AuthorizationCode') { _%>
    headers['Authorization'] = 'Bearer ' + context.auth.accessToken;
    <%_ } else if (authSchemeType === 'bearer') { _%>
    headers['Authorization'] = 'Bearer ' + context.auth.apiKey;
    <%_ } else if (authSchemeType === 'basic') { _%>
    const auth = {
        username: context.auth.username,
        password: context.auth.password
    };
    <%_ } else if (authSchemeType === 'apiKeyHeader') { _%>
    headers['<%= authScheme.name %>'] = context.auth.apiKey;
    <%_ } else if (authSchemeType === 'apiKeyQuery') { _%>
    query.append('<%= authScheme.name %>', context.auth.apiKey);

    <%_ } else if (authSchemeType === 'xConnectionApiKeyHeader') { _%>
    headers['<%= authScheme.name %>'] = '<%= authScheme.value %>'.replace(/{(.*?)}/g, (match, variable) => context.auth[variable]);
    <%_ } else if (authSchemeType === 'xConnectionApiKeyQuery') { _%>
    query.append('<%= authScheme.name %>', '<%= authScheme.value %>'.replace(/{(.*?)}/g, (match, variable) => context.auth[variable]));
    <%_ } _%>

    const req = {
        url: url,
        method: '<%= method.toUpperCase() %>',
        <%_ if (allowPayload) { _%>
            data: requestBody,
        <%_ } _%>
        headers: headers
        <%_ if (authSchemeType === 'basic') { _%>,
        auth: auth
        <%_ } _%>
        <%_ if (responseContentType === 'octet-stream') { _%>,
        responseType: 'arraybuffer'
        <%_ } _%>
    };

    <%_ if (allowOverride) { _%>
    if (override.url) req.url = override.url;
    if (override.body) req.data = override.body;
    if (override.headers) req.headers = override.headers;
    if (override.method) req.method = override.method;
    <%_ } _%>

    <%_ if (queryParameters.length > 0 || authSchemeType === 'apiKeyQuery' || authSchemeType === 'xConnectionApiKeyQuery' || allowOverride) { _%>
    const queryString = query.toString();
    if (queryString) {
       req.url += '?' + queryString;
    }
    <%_ } _%>

    <%_ if (typeof httpRequestTransform === 'string') { _%>
    <%- httpRequestTransform %>
    <%_ } _%>

    try {
        const response = await context.httpRequest(req);
        const log = {
            step: 'http-request-success',
            request: {
                url: req.url,
                method: req.method,
                headers: req.headers
                <%_ if (requestBodyMediaType !== 'multipart/form-data') { _%>
                ,
                data: req.data
                <%_ } _%>
                <%_ if (responseContentType === 'octet-stream') { _%>,
                responseType: req.responseType
                <%_ } _%>
            },
            response: {
                data: response.data,
                status: response.status,
                statusText: response.statusText,
                headers: response.headers
            }
        };
        await context.log(log);
        return response;
    } catch (err) {
        const log = {
            step: 'http-request-error',
            request: {
                url: req.url,
                method: req.method,
                headers: req.headers
                <%_ if (requestBodyMediaType !== 'multipart/form-data') { _%>
                ,
                data: req.data
                <%_ } _%>
            },
            response: err.response ? {
                data: err.response.data,
                status: err.response.status,
                statusText: err.response.statusText,
                headers: err.response.headers
            } : undefined
        };
        await context.log(log);
        throw err;
    }
}
