code: private ODataRequest buildODataRequest(HttpServletRequest servletRequest) throws IOException {
          ODataRequest.Builder builder = new ODataRequest.Builder();
  
          builder.setMethod(ODataRequest.Method.valueOf(servletRequest.getMethod()));
  
          // Unfortunately, HttpServletRequest makes it difficult to get the full URI
          StringBuilder sb = getRequestURL(servletRequest);
          String queryString = servletRequest.getQueryString();
          if (!isNullOrEmpty(queryString)) {
              sb.append('?').append(queryString);
          }
          builder.setUri(sb.toString());
  
          // Unfortunately, HttpServletRequest has a very old-style API to iterate the headers
          Enumeration e = servletRequest.getHeaderNames();
          while (e.hasMoreElements()) {
              String name = (String) e.nextElement();
              String value = servletRequest.getHeader(name);
              builder.setHeader(name, value);
          }
  
          // Read the request body
          InputStream in = servletRequest.getInputStream();
          ByteArrayOutputStream out = new ByteArrayOutputStream();
          int count;
          byte[] buffer = new byte[BUFFER_SIZE];
          while ((count = in.read(buffer)) != -1) {
              out.write(buffer, 0, count);
          }
          builder.setBody(out.toByteArray());
  
          return builder.build();
      }
docs: Converts an {@code HttpServletRequest} to an {@code ODataRequest}.
  
  @param servletRequest The {@code HttpServletRequest}.
  @return An {@code ODataRequest} containing the request information.
  @throws java.io.IOException If an I/O error occurs.