@Override
  public void update(String doi, String newUrl) throws HandleException {
    if (StringUtils.isEmpty(doi) || StringUtils.isEmpty(newUrl))
      throw new IllegalArgumentException("DOI and URL cannot be empty");

    log4j.debug("update Handle: DOI: " + doi + " URL: " + newUrl);

    int timestamp = (int) (System.currentTimeMillis() / 1000);

    try {
      HandleValue[] val = {
        new HandleValue(
            URL_RECORD_INDEX,
            "URL".getBytes(DEFAULT_ENCODING),
            newUrl.getBytes(DEFAULT_ENCODING),
            HandleValue.TTL_TYPE_RELATIVE,
            86400,
            timestamp,
            null,
            true,
            true,
            true,
            false)
      };

      AuthenticationInfo authInfo =
          new SecretKeyAuthenticationInfo(
              adminId.getBytes(DEFAULT_ENCODING),
              adminIndex,
              adminPassword.getBytes(DEFAULT_ENCODING));

      ModifyValueRequest req =
          new ModifyValueRequest(doi.getBytes(DEFAULT_ENCODING), val, authInfo);

      if (!dummyMode) {
        AbstractResponse response = resolver.processRequest(req);

        String msg = AbstractMessage.getResponseCodeMessage(response.responseCode);

        log4j.debug("response code from Handle request: " + msg);

        if (response.responseCode != AbstractMessage.RC_SUCCESS) {
          throw new HandleException(msg);
        }
      } else {
        log4j.debug("response code from Handle request: none - dummyMode on");
      }
    } catch (net.handle.hdllib.HandleException e) {
      String message =
          "tried to update handle " + doi + " but failed: [" + e.getCode() + "] " + e.getMessage();
      throw new HandleException(message, e);
    }
  }
  @Override
  public String resolve(String doi) throws HandleException, NotFoundException {
    if (dummyMode) return "dummyMode";

    byte[] handle = Util.encodeString(doi);
    byte[][] types = {Util.encodeString("URL")};
    int[] indexes = new int[0];
    ResolutionRequest resReq = new ResolutionRequest(handle, types, indexes, null);
    resReq.authoritative = true; // always ask a primary server

    try {
      AbstractResponse response = resolver.processRequest(resReq);
      String msg = AbstractMessage.getResponseCodeMessage(response.responseCode);
      log4j.debug("response code from Handle request: " + msg);

      if (response.responseCode == AbstractMessage.RC_HANDLE_NOT_FOUND) {
        throw new NotFoundException("handle " + doi + " does not exist");
      }

      if (response.responseCode == AbstractMessage.RC_VALUES_NOT_FOUND) {
        throw new NotFoundException("handle " + doi + " does not have any URL");
      }

      if (response.responseCode != AbstractMessage.RC_SUCCESS) {
        throw new HandleException(msg);
      }

      HandleValue[] values = ((ResolutionResponse) response).getHandleValues();
      return values[0].getDataAsString();
    } catch (net.handle.hdllib.HandleException e) {
      if (e.getCode() == net.handle.hdllib.HandleException.SERVICE_NOT_FOUND) {
        throw new NotFoundException("prefix of handle " + doi + " does not exist");
      } else {
        String message = "tried to resolve handle " + doi + " but failed: " + e.getMessage();
        log4j.warn(message);
        throw new HandleException(message, e);
      }
    }
  }