/**
   * Creates a new connection to the server.
   *
   * @param builder The HttpFileSystemConfigBuilder.
   * @param scheme The protocol.
   * @param hostname The hostname.
   * @param port The port number.
   * @param username The username.
   * @param password The password
   * @param fileSystemOptions The file system options.
   * @return a new HttpClient connection.
   * @throws FileSystemException if an error occurs.
   * @since 2.0
   */
  public static HttpClient createConnection(
      HttpFileSystemConfigBuilder builder,
      String scheme,
      String hostname,
      int port,
      String username,
      String password,
      FileSystemOptions fileSystemOptions)
      throws FileSystemException {
    HttpClient client;
    try {
      HttpConnectionManager mgr = new MultiThreadedHttpConnectionManager();
      HttpConnectionManagerParams connectionMgrParams = mgr.getParams();

      client = new HttpClient(mgr);

      final HostConfiguration config = new HostConfiguration();
      config.setHost(hostname, port, scheme);

      if (fileSystemOptions != null) {
        String proxyHost = builder.getProxyHost(fileSystemOptions);
        int proxyPort = builder.getProxyPort(fileSystemOptions);

        if (proxyHost != null && proxyHost.length() > 0 && proxyPort > 0) {
          config.setProxy(proxyHost, proxyPort);
        }

        UserAuthenticator proxyAuth = builder.getProxyAuthenticator(fileSystemOptions);
        if (proxyAuth != null) {
          UserAuthenticationData authData =
              UserAuthenticatorUtils.authenticate(
                  proxyAuth,
                  new UserAuthenticationData.Type[] {
                    UserAuthenticationData.USERNAME, UserAuthenticationData.PASSWORD
                  });

          if (authData != null) {
            final UsernamePasswordCredentials proxyCreds =
                new UsernamePasswordCredentials(
                    UserAuthenticatorUtils.toString(
                        UserAuthenticatorUtils.getData(
                            authData, UserAuthenticationData.USERNAME, null)),
                    UserAuthenticatorUtils.toString(
                        UserAuthenticatorUtils.getData(
                            authData, UserAuthenticationData.PASSWORD, null)));

            AuthScope scope = new AuthScope(proxyHost, AuthScope.ANY_PORT);
            client.getState().setProxyCredentials(scope, proxyCreds);
          }

          if (builder.isPreemptiveAuth(fileSystemOptions)) {
            HttpClientParams httpClientParams = new HttpClientParams();
            httpClientParams.setAuthenticationPreemptive(true);
            client.setParams(httpClientParams);
          }
        }

        Cookie[] cookies = builder.getCookies(fileSystemOptions);
        if (cookies != null) {
          client.getState().addCookies(cookies);
        }
      }
      /**
       * ConnectionManager set methodsmust be called after the host & port and proxy host & port are
       * set in the HostConfiguration. They are all used as part of the key when
       * HttpConnectionManagerParams tries to locate the host configuration.
       */
      connectionMgrParams.setMaxConnectionsPerHost(
          config, builder.getMaxConnectionsPerHost(fileSystemOptions));
      connectionMgrParams.setMaxTotalConnections(builder.getMaxTotalConnections(fileSystemOptions));

      client.setHostConfiguration(config);

      if (username != null) {
        final UsernamePasswordCredentials creds =
            new UsernamePasswordCredentials(username, password);
        AuthScope scope = new AuthScope(hostname, AuthScope.ANY_PORT);
        client.getState().setCredentials(scope, creds);
      }

      client.executeMethod(new HeadMethod());
    } catch (final Exception exc) {
      throw new FileSystemException(
          "vfs.provider.http/connect.error", new Object[] {hostname}, exc);
    }

    return client;
  }