private void addQueryParameters(URI uri) {
   if (isNonEmpty(uri.getRawQuery())) {
     String[] queries = uri.getRawQuery().split("&");
     int pos;
     for (String query : queries) {
       pos = query.indexOf('=');
       if (pos <= 0) {
         addQueryParameter(query, null);
       } else {
         try {
           if (useRawUrl) {
             addQueryParameter(query.substring(0, pos), query.substring(pos + 1));
           } else {
             addQueryParameter(
                 URLDecoder.decode(query.substring(0, pos), StandardCharsets.UTF_8.name()),
                 URLDecoder.decode(query.substring(pos + 1), StandardCharsets.UTF_8.name()));
           }
         } catch (UnsupportedEncodingException e) {
           throw new RuntimeException(e);
         }
       }
     }
   }
 }
/** Represents a proxy server. */
public class ProxyServer {

  public enum Protocol {
    HTTP("http"),
    HTTPS("https"),
    NTLM("NTLM"),
    KERBEROS("KERBEROS"),
    SPNEGO("SPNEGO");

    private final String protocol;

    private Protocol(final String protocol) {
      this.protocol = protocol;
    }

    public String getProtocol() {
      return protocol;
    }

    @Override
    public String toString() {
      return getProtocol();
    }
  }

  private final List<String> nonProxyHosts = new ArrayList<String>();
  private final Protocol protocol;
  private final String host;
  private final String principal;
  private final String password;
  private final int port;
  private final String url;
  private String encoding = StandardCharsets.UTF_8.name();
  private Charset charset = StandardCharsets.UTF_8;
  private String ntlmDomain = System.getProperty("http.auth.ntlm.domain", "");

  public ProxyServer(
      final Protocol protocol,
      final String host,
      final int port,
      String principal,
      String password) {
    this.protocol = protocol;
    this.host = host;
    this.port = port;
    this.principal = principal;
    this.password = password;
    url = protocol + "://" + host + ":" + port;
  }

  public ProxyServer(final String host, final int port, String principal, String password) {
    this(Protocol.HTTP, host, port, principal, password);
  }

  public ProxyServer(final Protocol protocol, final String host, final int port) {
    this(protocol, host, port, null, null);
  }

  public ProxyServer(final String host, final int port) {
    this(Protocol.HTTP, host, port, null, null);
  }

  public Protocol getProtocol() {
    return protocol;
  }

  public String getProtocolAsString() {
    return protocol.toString();
  }

  public String getHost() {
    return host;
  }

  public int getPort() {
    return port;
  }

  public String getPrincipal() {
    return principal;
  }

  public String getPassword() {
    return password;
  }

  public ProxyServer setEncoding(String encoding) {
    this.encoding = encoding;
    this.charset = Charset.forName(encoding);
    return this;
  }

  public String getEncoding() {
    return encoding;
  }

  public Charset getCharset() {
    return charset;
  }

  public String getUrl() {
    return url;
  }

  public ProxyServer addNonProxyHost(String uri) {
    nonProxyHosts.add(uri);
    return this;
  }

  public ProxyServer removeNonProxyHost(String uri) {
    nonProxyHosts.remove(uri);
    return this;
  }

  public List<String> getNonProxyHosts() {
    return Collections.unmodifiableList(nonProxyHosts);
  }

  public ProxyServer setNtlmDomain(String ntlmDomain) {
    this.ntlmDomain = ntlmDomain;
    return this;
  }

  public String getNtlmDomain() {
    return ntlmDomain;
  }

  @Override
  public String toString() {
    return url;
  }
}