code: @Nullable V removeWithWriter(Object key) {
      @SuppressWarnings("unchecked")
      K castKey = (K) key;
      @SuppressWarnings({"unchecked", "rawtypes"})
      Node<K, V>[] node = new Node[1];
      @SuppressWarnings("unchecked")
      V[] oldValue = (V[]) new Object[1];
      RemovalCause[] cause = new RemovalCause[1];
  
      data.computeIfPresent(nodeFactory.newLookupKey(key), (k, n) -> {
        synchronized (n) {
          oldValue[0] = n.getValue();
          if (oldValue[0] == null) {
            cause[0] = RemovalCause.COLLECTED;
          } else if (hasExpired(n, expirationTicker().read())) {
            cause[0] = RemovalCause.EXPIRED;
          } else {
            cause[0] = RemovalCause.EXPLICIT;
          }
          writer.delete(castKey, oldValue[0], cause[0]);
          n.retire();
        }
        node[0] = n;
        return null;
      });
  
      if (cause[0] != null) {
        afterWrite(new RemovalTask(node[0]));
        if (hasRemovalListener()) {
          notifyRemoval(castKey, oldValue[0], cause[0]);
        }
      }
      return (cause[0] == RemovalCause.EXPLICIT) ? oldValue[0] : null;
    }
docs: Removes the mapping for a key after notifying the writer.
  
  @param key key whose mapping is to be removed
  @return the removed value or null if no mapping was found