const auto request = session->get_request();
{{#hasBodyParam}}
// body params or form params here from the body content string
std::string bodyContent = extractBodyContent(session);
{{#bodyParams}}
{{#isModel}}
auto {{paramName}} = extractJsonModelBodyParam<{{{baseType}}}>(bodyContent);
{{/isModel}}
{{#isArray}}
auto {{paramName}} = extractJsonArrayBodyParam<{{{baseType}}}>(bodyContent);
{{/isArray}}
{{#isMap}}
{{{dataType}}} {{paramName}}; // TODO
{{/isMap}}
{{^isModel}}
{{^isArray}}
{{^isMap}}
auto {{paramName}} = boost::lexical_cast<{{{dataType}}}>(bodyContent);
{{/isMap}}
{{/isArray}}
{{/isModel}}
{{/bodyParams}}
{{/hasBodyParam}}
{{#hasFormParams}}
{{#formParams}}
{{#isContainer}}
std::string {{{paramName}}}_raw = extractFormParamsFromBody("{{paramName}}", extractBodyContent(session));
{{{dataType}}} {{{paramName}}};
boost::split({{{paramName}}}, {{{paramName}}}_raw, boost::is_any_of(","));
{{/isContainer}}
{{^isContainer}}
auto {{paramName}} = boost::lexical_cast<{{{dataType}}}>(extractFormParamsFromBody("{{paramName}}", extractBodyContent(session)));
{{/isContainer}}
{{/formParams}}
{{/hasFormParams}}
{{#hasPathParams}}
// Getting the path params
{{#pathParams}}
{{#isPrimitiveType}}
{{{dataType}}} {{{paramName}}} = request->get_path_parameter("{{{baseName}}}", {{{defaultValue}}});
{{/isPrimitiveType}}
{{/pathParams}}
{{/hasPathParams}}
{{#hasQueryParams}}
// Getting the query params
{{#queryParams}}
{{#isPrimitiveType}}
{{{dataType}}} {{{paramName}}} = request->get_query_parameter("{{{paramName}}}", {{{defaultValue}}});
{{/isPrimitiveType}}
{{^isPrimitiveType}}
{{#isArray}}
std::string {{{paramName}}}_raw = request->get_query_parameter("{{{paramName}}}");
{{{dataType}}} {{{paramName}}};
std::vector<std::string> {{{paramName}}}_temp;
boost::split({{{paramName}}}_temp, {{{paramName}}}_raw, boost::is_any_of(","));
{{#items}}
{{#isString}}
std::copy({{{paramName}}}_temp.begin(), {{{paramName}}}_temp.end(), std::inserter({{{paramName}}}, std::next({{{paramName}}}.begin())));
{{/isString}}
{{^isString}}
std::transform({{{paramName}}}_temp.begin(), {{{paramName}}}_temp.end(), std::back_inserter({{{paramName}}}), [](const auto& i){ {{{dataType}}} ret; ret.fromString(i); return ret;});
{{/isString}}
{{/items}}
{{/isArray}}
{{#isMap}}
std::stringstream {{{paramName}}}_raw(request->get_query_parameter("{{{paramName}}}"));
boost::property_tree::ptree {{{paramName}}}_pt;
boost::property_tree::json_parser::read_json({{{paramName}}}_raw,{{{paramName}}}_pt);
{{{dataType}}} {{{paramName}}} = {{{defaultValue}}};
for (auto& item: {{{paramName}}}_pt) {
    {{{paramName}}}.emplace(item.first, item.second.get_value<{{{baseType}}}>());
}
{{/isMap}}
{{/isPrimitiveType}}
{{/queryParams}}
{{/hasQueryParams}}
{{#hasHeaderParams}}
// Getting the headers
{{#headerParams}}
{{#isPrimitiveType}}
{{{dataType}}} {{{paramName}}} = request->get_header("{{{baseName}}}", {{{defaultValue}}});
{{/isPrimitiveType}}
{{#isContainer}}
std::string {{{paramName}}}_raw = request->get_header("{{{paramName}}}");
{{{dataType}}} {{{paramName}}};
boost::split({{{paramName}}}, {{{paramName}}}_raw, boost::is_any_of(","));
{{/isContainer}}
{{/headerParams}}
{{/hasHeaderParams}}

int status_code = 500;
{{#returnType}}
{{{.}}} resultObject = {{{defaultResponse}}};
{{/returnType}}
std::string result = "";

try {
{{#returnType}}
    std::tie(status_code, resultObject) =
{{/returnType}}
{{^returnType}}
    status_code =
{{/returnType}}
        handler_{{httpMethod}}({{#allParams}}{{paramName}}{{^-last}}, {{/-last}}{{/allParams}});
}
catch(const {{classname}}Exception& e) {
    std::tie(status_code, result) = handle{{classname}}Exception(e);
}
catch(const std::exception& e) {
    std::tie(status_code, result) = handleStdException(e);
}
catch(...) {
    std::tie(status_code, result) = handleUnspecifiedException();
}

std::multimap< std::string, std::string > responseHeaders {};
static const std::vector<std::string> contentTypes{
{{#hasProduces}}
    {{#produces}}"{{{mediaType}}}",{{/produces}}
{{/hasProduces}}
{{^hasProduces}}
    "application/json"
{{/hasProduces}}
};
static const std::string acceptTypes{
{{#hasConsumes}}
    "{{#consumes}}{{{mediaType}}}, {{/consumes}}"
{{/hasConsumes}}
};

{{#responses}}
if (status_code == {{code}}) {
{{#is2xx}}
    responseHeaders.insert(std::make_pair("Content-Type", selectPreferredContentType(contentTypes)));
    if (!acceptTypes.empty()) {
        responseHeaders.insert(std::make_pair("Accept", acceptTypes));
    }
{{/is2xx}}
{{^is2xx}}
    responseHeaders.insert(std::make_pair("Content-Type", "text/plain"));
    result = "{{message}}";
{{/is2xx}}

{{#returnType}}
{{#isModel}}
{{#isString}}
    result = resultObject;
{{/isString}}
{{^isString}}
{{^isMap}}
    result = resultObject.toJsonString();
{{/isMap}}
{{/isString}}
{{/isModel}}
{{#isMap}}
    result = convertMapResponse(resultObject);
{{/isMap}}
{{/returnType}}
{{#headers}}
    // Description: {{{description}}}
    setResponseHeader(session, "{{baseName}}");
{{/headers}}
    returnResponse(session, {{code}}, result.empty() ? "{}" : result, responseHeaders);
    return;
}
{{/responses}}
defaultSessionClose(session, status_code, result);
