private void ntlmChallenge(
      String authenticateHeader, //
      Request request, //
      HttpHeaders headers, //
      Realm realm, //
      NettyResponseFuture<?> future) {

    if (authenticateHeader.equals("NTLM")) {
      // server replied bare NTLM => we didn't preemptively sent Type1Msg
      String challengeHeader = NtlmEngine.INSTANCE.generateType1Msg();
      // FIXME we might want to filter current NTLM and add (leave other
      // Authorization headers untouched)
      headers.set(HttpHeaders.Names.AUTHORIZATION, "NTLM " + challengeHeader);
      future.getInAuth().set(false);

    } else {
      String serverChallenge = authenticateHeader.substring("NTLM ".length()).trim();
      String challengeHeader =
          NtlmEngine.INSTANCE.generateType3Msg(
              realm.getPrincipal(),
              realm.getPassword(),
              realm.getNtlmDomain(),
              realm.getNtlmHost(),
              serverChallenge);
      // FIXME we might want to filter current NTLM and add (leave other
      // Authorization headers untouched)
      headers.set(HttpHeaders.Names.AUTHORIZATION, "NTLM " + challengeHeader);
    }
  }
  private Realm ntlmChallenge(
      List<String> wwwAuth,
      Request request,
      ProxyServer proxyServer,
      FluentCaseInsensitiveStringsMap headers,
      Realm realm,
      NettyResponseFuture<?> future)
      throws NTLMEngineException {

    boolean useRealm = proxyServer == null && realm != null;

    String ntlmDomain = useRealm ? realm.getNtlmDomain() : proxyServer.getNtlmDomain();
    String ntlmHost = useRealm ? realm.getNtlmHost() : proxyServer.getHost();
    String principal = useRealm ? realm.getPrincipal() : proxyServer.getPrincipal();
    String password = useRealm ? realm.getPassword() : proxyServer.getPassword();

    if (realm != null && !realm.isNtlmMessageType2Received()) {
      String challengeHeader = NTLMEngine.INSTANCE.generateType1Msg(ntlmDomain, ntlmHost);

      URI uri = request.getURI();
      addNTLMAuthorizationHeader(headers, challengeHeader);
      future.getAndSetAuth(false);
      return newRealmBuilder(realm) //
          .setScheme(realm.getAuthScheme()) //
          .setUri(uri.getRawPath()) //
          .setMethodName(request.getMethod()) //
          .setNtlmMessageType2Received(true) //
          .build();

    } else {
      addType3NTLMAuthorizationHeader(wwwAuth, headers, principal, password, ntlmDomain, ntlmHost);
      Realm.AuthScheme authScheme = realm != null ? realm.getAuthScheme() : Realm.AuthScheme.NTLM;
      return newRealmBuilder(realm) //
          .setScheme(authScheme) //
          .setUri(request.getURI().getPath()) //
          .setMethodName(request.getMethod()) //
          .build();
    }
  }