@SuppressWarnings("unchecked")
  public CompletableFuture<Void> onResponse(final FilterRequestContext requestContext,
                                            final FilterResponseContext responseContext)
  {
    RestLiResponseData<?> responseData = responseContext.getResponseData();

    if (responseData.getResponseEnvelope().isErrorResponse())
    {
      return CompletableFuture.completedFuture(null);
    }

    if (shouldValidateOnResponse(requestContext))
    {

      ResourceMethod method = requestContext.getMethodType();
      RestLiDataValidator validator = createResponseRestLiDataValidator(requestContext);

      switch (method)
      {
        case GET:
          validateSingleResponse(validator, ((GetResponseEnvelope) responseData.getResponseEnvelope()).getRecord());
          break;
        case CREATE:
          if (requestContext.isReturnEntityMethod() && requestContext.isReturnEntityRequested())
          {
            validateSingleResponse(validator, ((CreateResponseEnvelope) responseData.getResponseEnvelope()).getRecord());
          }
          break;
        case PARTIAL_UPDATE:
          if (requestContext.isReturnEntityMethod() && requestContext.isReturnEntityRequested())
          {
            validateSingleResponse(validator, ((PartialUpdateResponseEnvelope) responseData.getResponseEnvelope()).getRecord());
          }
          break;
        case GET_ALL:
          validateCollectionResponse(validator, ((GetAllResponseEnvelope) responseData.getResponseEnvelope()).getCollectionResponse());
          break;
        case FINDER:
          validateCollectionResponse(validator, ((FinderResponseEnvelope) responseData.getResponseEnvelope()).getCollectionResponse());
          break;
        case BATCH_FINDER:
          validateBatchCollectionResponse(validator, ((BatchFinderResponseEnvelope) responseData.getResponseEnvelope()).getItems());
          break;
        case BATCH_GET:
          validateBatchResponse(validator, ((BatchGetResponseEnvelope) responseData.getResponseEnvelope()).getBatchResponseMap());
          break;
        case BATCH_CREATE:
          if (requestContext.isReturnEntityMethod() && requestContext.isReturnEntityRequested())
          {
            validateCreateCollectionResponse(validator, ((BatchCreateResponseEnvelope) responseData.getResponseEnvelope()).getCreateResponses());
          }
          break;
        case BATCH_PARTIAL_UPDATE:
          if (requestContext.isReturnEntityMethod() && requestContext.isReturnEntityRequested())
          {
            validateBatchResponse(validator, ((BatchPartialUpdateResponseEnvelope) responseData.getResponseEnvelope()).getBatchResponseMap());
          }
          break;
      }
    }

    return CompletableFuture.completedFuture(null);
  }
@Test(dataProvider = "returnEntityValidateOnResponseData")
  @SuppressWarnings({"unchecked", "rawtypes"})
  public void testReturnEntityValidateOnResponse(ResourceMethod resourceMethod, RestLiResponseData responseData,
      boolean isReturnEntityMethod, boolean isReturnEntityRequested)
  {
    when(filterRequestContext.getMethodType()).thenReturn(resourceMethod);
    when(filterRequestContext.isReturnEntityMethod()).thenReturn(isReturnEntityMethod);
    when(filterRequestContext.isReturnEntityRequested()).thenReturn(isReturnEntityRequested);
    when(filterResponseContext.getResponseData()).thenReturn(responseData);

    RestLiValidationFilter validationFilter = new RestLiValidationFilter();

    final boolean expectValidateEntity = isReturnEntityMethod && isReturnEntityRequested;

    try
    {
      // Check if validation occurred by catching exceptions for invalid entities
      validationFilter.onResponse(filterRequestContext, filterResponseContext);

      if (expectValidateEntity)
      {
        Assert.fail("Expected validation to occur and cause an exception, but no exception was encountered.");
      }
    }
    catch (RestLiServiceException e)
    {
      if (!expectValidateEntity)
      {
        Assert.fail("Expected validation to be skipped without exceptions, but encountered exception: " + e.getMessage());
      }

      Assert.assertEquals(e.getStatus().getCode(), HttpStatus.S_500_INTERNAL_SERVER_ERROR.getCode(), "Expected HTTP status code 500 for this validation failure.");
      Assert.assertTrue(e.getMessage().contains("/intField :: notAnInt cannot be coerced to Integer"), "Expected validation error for field \"intField\", but found another error.");
    }
  }