private static ObjectNode createPreflightIntegration(
            Context<? extends Trait> context,
            Map<CorsHeader, String> headers,
            PathItem pathItem
    ) {
        IntegrationResponse.Builder responseBuilder = IntegrationResponse.builder().statusCode("200");

        // Add each CORS header to the mock integration response.
        for (Map.Entry<CorsHeader, String> e : headers.entrySet()) {
            responseBuilder.putResponseParameter("method.response.header." + e.getKey(), "'" + e.getValue() + "'");
        }

        boolean isPreflightSynced = Boolean.TRUE.equals(context.getConfig().getSyncCorsPreflightIntegration());
        MockIntegrationTrait.Builder integration = MockIntegrationTrait.builder()
                // See https://forums.aws.amazon.com/thread.jspa?threadID=256140
                .contentHandling("CONVERT_TO_TEXT")
                // Passthrough behavior "never" will fail the request with unsupported content type more appropriately.
                // https://docs.aws.amazon.com/apigateway/latest/developerguide/integration-passthrough-behaviors.html
                .passThroughBehavior(isPreflightSynced ? "never" : "when_no_match")
                .putResponse("default", responseBuilder.build())
                .putRequestTemplate(API_GATEWAY_DEFAULT_ACCEPT_VALUE, PREFLIGHT_SUCCESS);

        if (isPreflightSynced) {
            // Adds request template for every unique Content-Type supported by all path operations.
            // This ensures that for Content-Type(s) other than 'application/json', the entire request payload
            // is not sent to APIGW mock integration as stipulated by 'when_no_match' passthroughBehavior.
            // APIGW throws an error if the mock integration request does not follow a set contract,
            // example {"statusCode":200}.
            for (OperationObject operation : pathItem.getOperations().values()) {
                ObjectNode extensionNode = operation.getExtension(INTEGRATION_EXTENSION)
                        .flatMap(Node::asObjectNode)
                        .orElse(Node.objectNode());
                Set<String> mimeTypes = extensionNode.getObjectMember(REQUEST_TEMPLATES_KEY)
                        .map(ObjectNode::getStringMap)
                        .map(Map::keySet)
                        .orElse(SetUtils.of());
                mimeTypes.forEach(mimeType -> integration.putRequestTemplate(mimeType, PREFLIGHT_SUCCESS));
            }
        }

        // Add a request template for every mime-type of every response.
        for (OperationObject operation : pathItem.getOperations().values()) {
            for (ResponseObject response : operation.getResponses().values()) {
                for (String mimeType : response.getContent().keySet()) {
                    integration.putRequestTemplate(mimeType, PREFLIGHT_SUCCESS);
                }
            }
        }

        // Use createIntegration to fix the casing of the passThroughBehavior property.
        return AddIntegrations.createIntegration(integration.build());
    }
Adds CORS-preflight OPTIONS requests using mock API Gateway integrations.

<p>This allows clients to first make an OPTIONS request to a URI to
determine what possible actions can be made on the URI. Rather than require
models to explicitly define and implement these protocol-specific
integrations, we can generate a static response using API Gateway mock
integrations.

<p>TODO: Only add security scheme headers on a per/operation basis.
We currently add security headers to the CORS headers that contains all
security schemes defined in the model. An improvement here would be to only
include headers that are added by security schemes on a per/operation basis.

<p>This extension only takes effect if the service being converted to
OpenAPI has the CORS trait.

@see <a href="https://fetch.spec.whatwg.org/#cors-preflight-fetch-0">CORS-preflight fetch</a>
smithy-aws-apigateway-openapi/src/main/java/software/amazon/smithy/aws/apigateway/openapi/AddCorsPreflightIntegration.java