@SuppressWarnings("unchecked")
  @Test
  public void testSetAuthorization() throws Exception {
    String authorizationHeaderValue = "IAmAuthorized";
    final String endpoint = "endpoint";
    Object soapClient = new Object();
    AdsSession adsSession =
        new AdsSession() {

          public boolean isEnvironment(Endpoint environment) {
            return false;
          }

          public String getEndpoint() {
            return endpoint;
          }
        };
    @SuppressWarnings("rawtypes")
    ArgumentCaptor<Map> headers = ArgumentCaptor.forClass(Map.class);

    when(soapClientHandler.getEndpointAddress(soapClient)).thenReturn(endpoint);
    when(authorizationHeaderProvider.getAuthorizationHeader(same(adsSession), eq(endpoint)))
        .thenReturn(authorizationHeaderValue);

    authorizationHeaderHandler.setAuthorization(soapClient, adsSession);

    verify(soapClientHandler).putAllHttpHeaders(eq(soapClient), headers.capture());
    String actualAuthorizationHeaderValue = (String) headers.getValue().get("Authorization");
    assertEquals(authorizationHeaderValue, actualAuthorizationHeaderValue);
  }
 /**
  * Wraps the underlying SOAP RPC such that first the method, by its name, is applied to the
  * runtime class. If no such method exists, it is assumed that the call is meant for the SOAP
  * client. In this case, the SOAP client handler will invoke the SOAP client method with provided
  * arguments.
  *
  * @param proxy the proxy class that invoke was called on
  * @param method the method to apply to the proxy class or the underlying SOAP client
  * @param args the method arguments
  * @return the return from the {@code SoapServiceClient} or a {@link SoapCallReturn} object
  *     containing the result from the SOAP call
  * @see InvocationHandler#invoke(Object, Method, Object[])
  * @throws Throwable thrown if the SOAP call passed into this method results in an exception. The
  *     exception thrown will be not be wrapped - it will adhere to the "throws" clause of the
  *     passed in {@code Method}.
  */
 @Override
 public Object invoke(Object proxy, final Method method, final Object[] args) throws Throwable {
   try {
     return getClass().getMethod(method.getName(), method.getParameterTypes()).invoke(this, args);
   } catch (NoSuchMethodException e) {
     // Ignore and let the SOAP client handler take over.
   }
   setHeaders();
   SoapCallReturn soapCallReturn =
       callSoapClient(
           createSoapCall(soapClientHandler.getSoapClientMethod(soapClient, method), args));
   logSoapCall(soapCallReturn);
   return unwrapSoapCallReturn(soapCallReturn);
 }
 /** Sets the endpoint address of the underlying SOAP client. */
 public void setEndpointAddress(String endpointAddress) {
   soapClientHandler.setEndpointAddress(soapClient, endpointAddress);
 }
 /**
  * Called from {@link #invoke(Object, Method, Object[])} if the method is intended for the SOAP
  * client. Extending classes should override this method if they wish to wrap the call, such in
  * cases of reauthentication or exception handling. The actual SOAP call is synchronized on the
  * SOAP client so that only one request to the SOAP client can be made with without interruption,
  * useful for logging and exception handling.
  *
  * @param soapCall the call to send to the SOAP client
  * @return the return value from the {@code soapCall}
  */
 protected synchronized SoapCallReturn callSoapClient(SoapCall<T> soapCall) {
   return soapClientHandler.invokeSoapCall(soapCall);
 }