// Path: src/main/java/com/burgstaller/okhttp/basic/BasicAuthenticator.java
// public class BasicAuthenticator implements CachingAuthenticator {
//     private final Credentials credentials;
//     private final Charset credentialCharset;
//     private boolean proxy;
// 
//     public BasicAuthenticator(Credentials credentials, Charset credentialsCharset) {
//         this.credentials = credentials;
//         this.credentialCharset = credentialsCharset != null ? credentialsCharset : StandardCharsets.ISO_8859_1;
//     }
// 
//     public BasicAuthenticator(Credentials credentials) {
//         this(credentials, StandardCharsets.ISO_8859_1);
//     }
// 
//     @Override
//     public Request authenticate(Route route, Response response) throws IOException {
//         final Request request = response.request();
//         proxy = response.code() == HTTP_PROXY_AUTH;
//         return authFromRequest(request);
//     }
// 
//     private Request authFromRequest(Request request) {
//         // prevent infinite loops when the password is wrong
//         String header = proxy ? "Proxy-Authorization" : "Authorization";
// 
//         final String authorizationHeader = request.header(header);
//         if (authorizationHeader != null && authorizationHeader.startsWith("Basic")) {
//             Platform.get().log( "Previous basic authentication failed, returning null", Platform.WARN,null);
//             return null;
//         }
//         String authValue = okhttp3.Credentials.basic(credentials.getUserName(), credentials.getPassword(), credentialCharset);
//         return request.newBuilder()
//                 .header(header, authValue)
//                 .build();
//     }
// 
//     @Override
//     public Request authenticateWithState(Route route, Request request) throws IOException {
//         return authFromRequest(request);
//     }
// }
// 
// Path: src/main/java/com/burgstaller/okhttp/digest/CachingAuthenticator.java
// public interface CachingAuthenticator extends Authenticator {
//     /**
//      * Authenticate the new request using cached information already established from an earlier
//      * authentication.
//      *
//      * @param route   the route to use
//      * @param request the new request to be authenticated.
//      * @return the modified request with updated auth headers.
//      * @throws IOException in case of a communication problem
//      */
//     Request authenticateWithState(Route route, Request request) throws IOException;
// }
// 
// Path: src/main/java/com/burgstaller/okhttp/digest/Credentials.java
// public class Credentials {
//     private String userName;
//     private String password;
// 
//     public Credentials(String userName, String password) {
//         if (userName == null || password == null) {
//             throw new IllegalArgumentException("username and password cannot be null");
//         }
//         this.userName = userName;
//         this.password = password;
//     }
// 
//     public String getUserName() {
//         return userName;
//     }
// 
//     public void setUserName(String userName) {
//         this.userName = userName;
//     }
// 
//     public String getPassword() {
//         return password;
//     }
// 
//     public void setPassword(String password) {
//         this.password = password;
//     }
// }


import com.burgstaller.okhttp.basic.BasicAuthenticator;
import com.burgstaller.okhttp.digest.CachingAuthenticator;
import com.burgstaller.okhttp.digest.Credentials;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ProxySelector;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
import javax.net.SocketFactory;
import okhttp3.Address;
import okhttp3.Authenticator;
import okhttp3.Connection;
import okhttp3.ConnectionSpec;
import okhttp3.Dns;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.Route;
import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.BDDMockito.given;
            public Response proceed(Request request) {
                final String authorization = request.header("Authorization");
                authResultHeader.set(authorization);
                return null;
            }
        });
        return authResultHeader.get();
    }

    private String whenInterceptAuthenticationForUrlWithNoConnection(Interceptor interceptor, final String url) throws IOException {
        // we need a result holder for passing into the anonymous class
        final AtomicReference<String> authResultHeader = new AtomicReference<>();
        final Request request = new Request.Builder()
                .url(url)
                .get()
                .build();

        interceptor.intercept(new ChainAdapter(request, mockConnection) {
            @Override
            public Response proceed(Request request) {
                final String authorization = request.header("Authorization");
                authResultHeader.set(authorization);
                return null;
            }
        });
        return authResultHeader.get();
    }

    private void givenCachedAuthenticationFor(String url, Map<String, CachingAuthenticator> authCache) throws IOException {
        Authenticator decorator = new CachingAuthenticatorDecorator(
// Path: src/main/java/com/burgstaller/okhttp/basic/BasicAuthenticator.java
// public class BasicAuthenticator implements CachingAuthenticator {
//     private final Credentials credentials;
//     private final Charset credentialCharset;
//     private boolean proxy;
// 
//     public BasicAuthenticator(Credentials credentials, Charset credentialsCharset) {
//         this.credentials = credentials;
//         this.credentialCharset = credentialsCharset != null ? credentialsCharset : StandardCharsets.ISO_8859_1;
//     }
// 
//     public BasicAuthenticator(Credentials credentials) {
//         this(credentials, StandardCharsets.ISO_8859_1);
//     }
// 
//     @Override
//     public Request authenticate(Route route, Response response) throws IOException {
//         final Request request = response.request();
//         proxy = response.code() == HTTP_PROXY_AUTH;
//         return authFromRequest(request);
//     }
// 
//     private Request authFromRequest(Request request) {
//         // prevent infinite loops when the password is wrong
//         String header = proxy ? "Proxy-Authorization" : "Authorization";
// 
//         final String authorizationHeader = request.header(header);
//         if (authorizationHeader != null && authorizationHeader.startsWith("Basic")) {
//             Platform.get().log( "Previous basic authentication failed, returning null", Platform.WARN,null);
//             return null;
//         }
//         String authValue = okhttp3.Credentials.basic(credentials.getUserName(), credentials.getPassword(), credentialCharset);
//         return request.newBuilder()
//                 .header(header, authValue)
//                 .build();
//     }
// 
//     @Override
//     public Request authenticateWithState(Route route, Request request) throws IOException {
//         return authFromRequest(request);
//     }
// }
// 
// Path: src/main/java/com/burgstaller/okhttp/digest/CachingAuthenticator.java
// public interface CachingAuthenticator extends Authenticator {
//     /**
//      * Authenticate the new request using cached information already established from an earlier
//      * authentication.
//      *
//      * @param route   the route to use
//      * @param request the new request to be authenticated.
//      * @return the modified request with updated auth headers.
//      * @throws IOException in case of a communication problem
//      */
//     Request authenticateWithState(Route route, Request request) throws IOException;
// }
// 
// Path: src/main/java/com/burgstaller/okhttp/digest/Credentials.java
// public class Credentials {
//     private String userName;
//     private String password;
// 
//     public Credentials(String userName, String password) {
//         if (userName == null || password == null) {
//             throw new IllegalArgumentException("username and password cannot be null");
//         }
//         this.userName = userName;
//         this.password = password;
//     }
// 
//     public String getUserName() {
//         return userName;
//     }
// 
//     public void setUserName(String userName) {
//         this.userName = userName;
//     }
// 
//     public String getPassword() {
//         return password;
//     }
// 
//     public void setPassword(String password) {
//         this.password = password;
//     }
// }


// Path: src/test/java/com/burgstaller/okhttp/AuthenticationCacheInterceptorTest.java
import com.burgstaller.okhttp.basic.BasicAuthenticator;
import com.burgstaller.okhttp.digest.CachingAuthenticator;
import com.burgstaller.okhttp.digest.Credentials;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ProxySelector;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
import javax.net.SocketFactory;
import okhttp3.Address;
import okhttp3.Authenticator;
import okhttp3.Connection;
import okhttp3.ConnectionSpec;
import okhttp3.Dns;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.Route;
import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.BDDMockito.given;

            public Response proceed(Request request) {
                final String authorization = request.header("Authorization");
                authResultHeader.set(authorization);
                return null;
            }
        });
        return authResultHeader.get();
    }

    private String whenInterceptAuthenticationForUrlWithNoConnection(Interceptor interceptor, final String url) throws IOException {
        // we need a result holder for passing into the anonymous class
        final AtomicReference<String> authResultHeader = new AtomicReference<>();
        final Request request = new Request.Builder()
                .url(url)
                .get()
                .build();

        interceptor.intercept(new ChainAdapter(request, mockConnection) {
            @Override
            public Response proceed(Request request) {
                final String authorization = request.header("Authorization");
                authResultHeader.set(authorization);
                return null;
            }
        });
        return authResultHeader.get();
    }

    private void givenCachedAuthenticationFor(String url, Map<String, CachingAuthenticator> authCache) throws IOException {
        Authenticator decorator = new CachingAuthenticatorDecorator(
                new BasicAuthenticator(new Credentials("user1", "user1")),