/**
   * Sets cookies according to uri and responseHeaders
   *
   * @param uri the specified uri
   * @param responseHeaders a list of request headers
   * @throws IOException if some error of I/O operation occurs
   */
  @Override
  public void put(URI uri, Map<String, List<String>> responseHeaders) throws IOException {
    if (uri == null || responseHeaders == null) {
      throw new IllegalArgumentException();
    }

    // parse and construct cookies according to the map
    List<HttpCookie> cookies = parseCookie(responseHeaders);
    for (HttpCookie cookie : cookies) {

      // if the cookie doesn't have a domain, set one. The policy will do validation.
      if (cookie.getDomain() == null) {
        cookie.setDomain(uri.getHost());
      }

      // if the cookie doesn't have a path, set one. If it does, validate it.
      if (cookie.getPath() == null) {
        cookie.setPath(pathToCookiePath(uri.getPath()));
      } else if (!HttpCookie.pathMatches(cookie, uri)) {
        continue;
      }

      // if the cookie has the placeholder port list "", set the port. Otherwise validate it.
      if ("".equals(cookie.getPortlist())) {
        cookie.setPortlist(Integer.toString(uri.getEffectivePort()));
      } else if (cookie.getPortlist() != null && !HttpCookie.portMatches(cookie, uri)) {
        continue;
      }

      // if the cookie conforms to the policy, add it into the store
      if (policy.shouldAccept(uri, cookie)) {
        store.add(uri, cookie);
      }
    }
  }
  /**
   * Searches and gets all cookies in the cache by the specified uri in the request header.
   *
   * @param uri the specified uri to search for
   * @param requestHeaders a list of request headers
   * @return a map that record all such cookies, the map is unchangeable
   * @throws IOException if some error of I/O operation occurs
   */
  @Override
  public Map<String, List<String>> get(URI uri, Map<String, List<String>> requestHeaders)
      throws IOException {
    if (uri == null || requestHeaders == null) {
      throw new IllegalArgumentException();
    }

    List<HttpCookie> result = new ArrayList<HttpCookie>();
    for (HttpCookie cookie : store.get(uri)) {
      if (HttpCookie.pathMatches(cookie, uri)
          && HttpCookie.secureMatches(cookie, uri)
          && HttpCookie.portMatches(cookie, uri)) {
        result.add(cookie);
      }
    }

    return cookiesToHeaders(result);
  }