public T header(String name, String value) {
   Validate.notEmpty(name, "Header name must not be empty");
   Validate.notNull(value, "Header value must not be null");
   removeHeader(name); // ensures we don't get an "accept-encoding" and a "Accept-Encoding"
   headers.put(name, value);
   return (T) this;
 }
 public Connection url(String url) {
   Validate.notEmpty(url, "Must supply a valid URL");
   try {
     req.url(new URL(url));
   } catch (MalformedURLException e) {
     throw new IllegalArgumentException("Malformed URL: " + url, e);
   }
   return this;
 }
 public Connection data(String... keyvals) {
   Validate.notNull(keyvals, "Data key value pairs must not be null");
   Validate.isTrue(keyvals.length % 2 == 0, "Must supply an even number of key value pairs");
   for (int i = 0; i < keyvals.length; i += 2) {
     String key = keyvals[i];
     String value = keyvals[i + 1];
     Validate.notEmpty(key, "Data key must not be empty");
     Validate.notNull(value, "Data value must not be null");
     req.data(KeyVal.create(key, value));
   }
   return this;
 }
 public KeyVal key(String key) {
   Validate.notEmpty(key, "Data key must not be empty");
   this.key = key;
   return this;
 }
 public static KeyVal create(String key, String value) {
   Validate.notEmpty(key, "Data key must not be empty");
   Validate.notNull(value, "Data value must not be null");
   return new KeyVal(key, value);
 }
 public T removeCookie(String name) {
   Validate.notEmpty("Cookie name must not be empty");
   cookies.remove(name);
   return (T) this;
 }
 public boolean hasCookie(String name) {
   Validate.notEmpty("Cookie name must not be empty");
   return cookies.containsKey(name);
 }
 public T cookie(String name, String value) {
   Validate.notEmpty(name, "Cookie name must not be empty");
   Validate.notNull(value, "Cookie value must not be null");
   cookies.put(name, value);
   return (T) this;
 }
 public T removeHeader(String name) {
   Validate.notEmpty(name, "Header name must not be empty");
   Map.Entry<String, String> entry = scanHeaders(name); // remove is case insensitive too
   if (entry != null) headers.remove(entry.getKey()); // ensures correct case
   return (T) this;
 }
 public boolean hasHeader(String name) {
   Validate.notEmpty(name, "Header name must not be empty");
   return getHeaderCaseInsensitive(name) != null;
 }