@Override
  public RestLiResponseData<BatchGetResponseEnvelope> buildRestLiResponseData(Request request,
                                                      RoutingResult routingResult,
                                                      Object result,
                                                      Map<String, String> headers,
                                                      List<HttpCookie> cookies)
  {
    @SuppressWarnings({ "unchecked" })
    /* constrained by signature of {@link com.linkedin.restli.server.resources.CollectionResource#batchGet(java.util.Set)} */
    final Map<Object, RecordTemplate> entities = (Map<Object, RecordTemplate>) result;
    Map<Object, HttpStatus> statuses = Collections.emptyMap();
    Map<Object, RestLiServiceException> serviceErrors = Collections.emptyMap();

    if (result instanceof BatchResult)
    {
      @SuppressWarnings({ "unchecked" })
      /* constrained by signature of {@link com.linkedin.restli.server.resources.CollectionResource#batchGet(java.util.Set)} */
      final BatchResult<Object, RecordTemplate> batchResult = (BatchResult<Object, RecordTemplate>) result;
      statuses = batchResult.getStatuses();
      serviceErrors = batchResult.getErrors();
    }

    try
    {
      if (statuses.containsKey(null))
      {
        throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR,
            "Unexpected null encountered. Null key inside of a Map returned by the resource method: " + routingResult
                .getResourceMethod());
      }
    }
    catch (NullPointerException e)
    {
      // Some map implementations will throw an NPE if they do not support null keys.
      // In this case it is OK to swallow this exception and proceed.
    }

    TimingContextUtil.beginTiming(routingResult.getContext().getRawRequestContext(),
        FrameworkTimingKeys.SERVER_RESPONSE_RESTLI_PROJECTION_APPLY.key());

    Map<Object, BatchResponseEntry> batchResult = new HashMap<>(entities.size() + serviceErrors.size());
    for (Map.Entry<Object, RecordTemplate> entity : entities.entrySet())
    {
      if (entity.getKey() == null)
      {
        throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR,
            "Unexpected null encountered. Null key inside of a Map returned by the resource method: " + routingResult
                .getResourceMethod());
      }
      Object finalKey = ResponseUtils.translateCanonicalKeyToAlternativeKeyIfNeeded(entity.getKey(), routingResult);

      DataMap rawData = entity.getValue().data();
      if (routingResult.getContext().isFillInDefaultsRequested())
      {
        rawData = (DataMap) ResponseUtils.fillInDataDefault(entity.getValue().schema(), rawData);
      }

      final DataMap projectedData = RestUtils.projectFields(rawData, routingResult.getContext());

      AnyRecord anyRecord = new AnyRecord(projectedData);
      batchResult.put(finalKey, new BatchResponseEntry(statuses.get(entity.getKey()), anyRecord));
    }

    TimingContextUtil.endTiming(routingResult.getContext().getRawRequestContext(),
        FrameworkTimingKeys.SERVER_RESPONSE_RESTLI_PROJECTION_APPLY.key());

    for (Map.Entry<Object, RestLiServiceException> entity : serviceErrors.entrySet())
    {
      if (entity.getKey() == null || entity.getValue() == null)
      {
        throw new RestLiServiceException(HttpStatus.S_500_INTERNAL_SERVER_ERROR,
            "Unexpected null encountered. Null key inside of a Map returned by the resource method: " + routingResult
                .getResourceMethod());
      }
      Object finalKey = ResponseUtils.translateCanonicalKeyToAlternativeKeyIfNeeded(entity.getKey(), routingResult);
      batchResult.put(finalKey, new BatchResponseEntry(statuses.get(entity.getKey()), entity.getValue()));
    }

    final Map<Object, RestLiServiceException> contextErrors = routingResult.getContext().getBatchKeyErrors();
    for (Map.Entry<Object, RestLiServiceException> entry : contextErrors.entrySet())
    {
      Object finalKey = ResponseUtils.translateCanonicalKeyToAlternativeKeyIfNeeded(entry.getKey(), routingResult);
      batchResult.put(finalKey, new BatchResponseEntry(statuses.get(entry.getKey()), entry.getValue()));
    }

    return new RestLiResponseDataImpl<>(new BatchGetResponseEnvelope(HttpStatus.S_200_OK, batchResult), headers, cookies);
  }
@Test(dataProvider = "exceptionTestData")
  public void testBuilderExceptions(Object results, String expectedErrorMessage)
  {
    // Protocol version doesn't matter here
    ServerResourceContext mockContext = getMockResourceContext(null, Collections.emptyMap(),
        null, null, null);
    ResourceMethodDescriptor mockDescriptor = getMockResourceMethodDescriptor(null);
    RoutingResult routingResult = new RoutingResult(mockContext, mockDescriptor);

    Map<String, String> headers = ResponseBuilderUtil.getHeaders();

    BatchGetResponseBuilder responseBuilder = new BatchGetResponseBuilder(new ErrorResponseBuilder());
    try
    {
      responseBuilder.buildRestLiResponseData(null, routingResult, results, headers,
                                              Collections.emptyList());
      Assert.fail("buildRestLiResponseData should have failed because of null elements!");
    }
    catch (RestLiServiceException e)
    {
      Assert.assertTrue(e.getMessage().contains(expectedErrorMessage));
    }
  }