@SuppressWarnings("unchecked")
  public String uploadFile(
      String parentPath,
      String name,
      InputStream inputStream,
      String mediaType,
      Date modified,
      String description)
      throws IOException, InvalidTokenException, DestinationMemoryFullException {
    String url;
    try {
      URIBuilder builder =
          getUriBuilder()
              .setPath(CONTENT_API_PATH_PREFIX + "/mounts/primary/files/put")
              .setParameter("path", parentPath)
              .setParameter("filename", name)
              .setParameter("autorename", "true")
              .setParameter("info", "true");
      if (description != null && description.length() > 0) {
        builder.setParameter("tags", "description=" + description);
      }
      if (modified != null) {
        builder.setParameter("modified", Long.toString(modified.getTime()));
      }
      url = builder.build().toString();
    } catch (URISyntaxException e) {
      throw new IllegalStateException("Could not produce url.", e);
    }

    Request.Builder requestBuilder = getRequestBuilder(url);

    RequestBody uploadBody = new InputStreamRequestBody(MediaType.parse(mediaType), inputStream);

    requestBuilder.post(uploadBody);

    // We need to reset the input stream because the request could already read some data
    try (Response response =
        getResponse(fileUploadClient, requestBuilder, inputStream::reset)) {
      int code = response.code();
      ResponseBody body = response.body();
      if (code == 413) {
        throw new DestinationMemoryFullException(
            "Koofr quota exceeded", new Exception("Koofr file upload response code " + code));
      }
      if (code < 200 || code > 299) {
        throw new KoofrClientIOException(response);
      }

      Map<String, Object> responseData = objectMapper.readValue(body.bytes(), Map.class);
      String newName = (String) responseData.get("name");
      Preconditions.checkState(
          !Strings.isNullOrEmpty(newName), "Expected name value to be present in %s", responseData);
      return parentPath + "/" + newName;
    }
  }
@Test
  public void testUploadFileTokenExpired() throws Exception {
    when(credentialFactory.refreshCredential(credential))
        .then(
            (InvocationOnMock invocation) -> {
              final Credential cred = invocation.getArgument(0);
              cred.setAccessToken("acc1");
              return cred;
            });

    server.enqueue(new MockResponse().setResponseCode(401));
    server.enqueue(
        new MockResponse()
            .setResponseCode(200)
            .setHeader("Content-Type", "application/json")
            .setBody(
                "{\"name\":\"image.jpg\",\"type\":\"file\",\"modified\":1591868314156,\"size\":5,\"contentType\":\"image/jpeg\",\"hash\":\"d05374dc381d9b52806446a71c8e79b1\",\"tags\":{}}"));

    final InputStream inputStream = new ByteArrayInputStream(new byte[] {0, 1, 2, 3, 4});
    String fullPath =
        client.uploadFile("/path/to/folder", "image.jpg", inputStream, "image/jpeg", null, null);
    assertEquals("/path/to/folder/image.jpg", fullPath);

    assertEquals(2, server.getRequestCount());

    RecordedRequest recordedRequest = server.takeRequest();

    assertEquals("POST", recordedRequest.getMethod());
    assertEquals(
        "/content/api/v2/mounts/primary/files/put?path=%2Fpath%2Fto%2Ffolder&filename=image.jpg&autorename=true&info=true",
        recordedRequest.getPath());
    assertEquals("Bearer acc", recordedRequest.getHeader("Authorization"));
    assertEquals("2.1", recordedRequest.getHeader("X-Koofr-Version"));
    assertEquals("image/jpeg", recordedRequest.getHeader("Content-Type"));
    assertEquals(5, recordedRequest.getBodySize());

    recordedRequest = server.takeRequest();

    assertEquals("POST", recordedRequest.getMethod());
    assertEquals(
        "/content/api/v2/mounts/primary/files/put?path=%2Fpath%2Fto%2Ffolder&filename=image.jpg&autorename=true&info=true",
        recordedRequest.getPath());
    assertEquals("Bearer acc1", recordedRequest.getHeader("Authorization"));
    assertEquals("2.1", recordedRequest.getHeader("X-Koofr-Version"));
    assertEquals("image/jpeg", recordedRequest.getHeader("Content-Type"));
    assertEquals(5, recordedRequest.getBodySize());
  }