Merge pull request #2964 from jtattermusch/refactor_auth_interceptors

Refactor auth interceptors
diff --git a/src/csharp/Grpc.Auth/AuthInterceptors.cs b/src/csharp/Grpc.Auth/AuthInterceptors.cs
new file mode 100644
index 0000000..61338f7
--- /dev/null
+++ b/src/csharp/Grpc.Auth/AuthInterceptors.cs
@@ -0,0 +1,84 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Threading;
+
+using Google.Apis.Auth.OAuth2;
+using Grpc.Core;
+using Grpc.Core.Utils;
+
+namespace Grpc.Auth
+{
+    /// <summary>
+    /// Factory methods to create authorization interceptors.
+    /// </summary>
+    public static class AuthInterceptors
+    {
+        private const string AuthorizationHeader = "Authorization";
+        private const string Schema = "Bearer";
+
+        /// <summary>
+        /// Creates interceptor that will obtain access token from any credential type that implements
+        /// <c>ITokenAccess</c>. (e.g. <c>GoogleCredential</c>).
+        /// </summary>
+        public static HeaderInterceptor FromCredential(ITokenAccess credential)
+        {
+            return new HeaderInterceptor((method, authUri, metadata) =>
+            {
+                // TODO(jtattermusch): Rethink synchronous wait to obtain the result.
+                var accessToken = credential.GetAccessTokenForRequestAsync(authUri, CancellationToken.None)
+                        .ConfigureAwait(false).GetAwaiter().GetResult();
+                metadata.Add(CreateBearerTokenHeader(accessToken));
+            });
+        }
+
+        /// <summary>
+        /// Creates OAuth2 interceptor that will use given access token as authorization.
+        /// </summary>
+        /// <param name="accessToken">OAuth2 access token.</param>
+        public static HeaderInterceptor FromAccessToken(string accessToken)
+        {
+            Preconditions.CheckNotNull(accessToken);
+            return new HeaderInterceptor((method, authUri, metadata) =>
+            {
+                metadata.Add(CreateBearerTokenHeader(accessToken));
+            });
+        }
+
+        private static Metadata.Entry CreateBearerTokenHeader(string accessToken)
+        {
+            return new Metadata.Entry(AuthorizationHeader, Schema + " " + accessToken);
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
index 930a34b..4fb087d 100644
--- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj
+++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
@@ -3,8 +3,6 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>10.0.0</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}</ProjectGuid>
     <OutputType>Library</OutputType>
     <RootNamespace>Grpc.Auth</RootNamespace>
@@ -41,57 +39,47 @@
     <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="BouncyCastle.Crypto, Version=1.7.4137.9688, Culture=neutral, PublicKeyToken=a4292a325f69b123, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth, Version=1.9.3.19379, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.9.3.19383, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Core, Version=1.9.3.19379, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Core.1.9.3\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.168.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
-    </Reference>
-    <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
-    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Net" />
     <Reference Include="System.Net.Http" />
-    <Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
+    <Reference Include="System.Net.Http.WebRequest" />
+    <Reference Include="BouncyCastle.Crypto">
+      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth">
+      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth.PlatformServices">
+      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Core">
+      <HintPath>..\packages\Google.Apis.Core.1.9.3\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Threading.Tasks">
+      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Threading.Tasks.Extensions">
+      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop">
+      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
+    </Reference>
+    <Reference Include="Newtonsoft.Json">
+      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Net.Http.Extensions">
       <HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath>
     </Reference>
-    <Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
+    <Reference Include="System.Net.Http.Primitives">
       <HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
     </Reference>
-    <Reference Include="System.Net.Http.WebRequest" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="..\Grpc.Core\Version.cs">
       <Link>Version.cs</Link>
     </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="OAuth2Interceptors.cs" />
+    <Compile Include="AuthInterceptors.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
diff --git a/src/csharp/Grpc.Auth/OAuth2Interceptors.cs b/src/csharp/Grpc.Auth/OAuth2Interceptors.cs
deleted file mode 100644
index d628a83..0000000
--- a/src/csharp/Grpc.Auth/OAuth2Interceptors.cs
+++ /dev/null
@@ -1,115 +0,0 @@
-#region Copyright notice and license
-
-// Copyright 2015, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Security.Cryptography.X509Certificates;
-using System.Text.RegularExpressions;
-using System.Threading;
-using System.Threading.Tasks;
-
-using Google.Apis.Auth.OAuth2;
-using Google.Apis.Util;
-using Grpc.Core;
-using Grpc.Core.Utils;
-
-namespace Grpc.Auth
-{
-    public static class OAuth2Interceptors
-    {
-        /// <summary>
-        /// Creates OAuth2 interceptor that will obtain access token from GoogleCredentials.
-        /// </summary>
-        public static MetadataInterceptorDelegate FromCredential(GoogleCredential googleCredential)
-        {
-            var interceptor = new OAuth2Interceptor(googleCredential, SystemClock.Default);
-            return new MetadataInterceptorDelegate(interceptor.InterceptHeaders);
-        }
-
-        /// <summary>
-        /// Creates OAuth2 interceptor that will use given OAuth2 token.
-        /// </summary>
-        /// <param name="oauth2Token"></param>
-        /// <returns></returns>
-        public static MetadataInterceptorDelegate FromAccessToken(string oauth2Token)
-        {
-            Preconditions.CheckNotNull(oauth2Token);
-            return new MetadataInterceptorDelegate((authUri, metadata) =>
-            {
-                metadata.Add(OAuth2Interceptor.CreateBearerTokenHeader(oauth2Token));
-            });
-        }
-
-        /// <summary>
-        /// Injects OAuth2 authorization header into initial metadata (= request headers).
-        /// </summary>
-        private class OAuth2Interceptor
-        {
-            private const string AuthorizationHeader = "Authorization";
-            private const string Schema = "Bearer";
-
-            private ITokenAccess credential;
-            private IClock clock;
-
-            public OAuth2Interceptor(ITokenAccess credential, IClock clock)
-            {
-                this.credential = credential;
-                this.clock = clock;
-            }
-
-            /// <summary>
-            /// Gets access token and requests refreshing it if is going to expire soon.
-            /// </summary>
-            /// <param name="cancellationToken"></param>
-            /// <returns></returns>
-            public string GetAccessToken(string authUri, CancellationToken cancellationToken)
-            {
-                // TODO(jtattermusch): Rethink synchronous wait to obtain the result.
-                return credential.GetAccessTokenForRequestAsync(authUri, cancellationToken: cancellationToken).GetAwaiter().GetResult();
-            }
-
-            public void InterceptHeaders(string authUri, Metadata metadata)
-            {
-                var accessToken = GetAccessToken(authUri, CancellationToken.None);
-                metadata.Add(CreateBearerTokenHeader(accessToken));
-            }
-
-            public static Metadata.Entry CreateBearerTokenHeader(string accessToken)
-            {
-                return new Metadata.Entry(AuthorizationHeader, Schema + " " + accessToken);
-            }
-        }
-    }
-}
diff --git a/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs b/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs
index bf020cd..fb9b562 100644
--- a/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs
+++ b/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs
@@ -89,6 +89,24 @@
         }
 
         /// <summary>
+        /// Gets the call status if the call has already finished.
+        /// Throws InvalidOperationException otherwise.
+        /// </summary>
+        public Status GetStatus()
+        {
+            return getStatusFunc();
+        }
+
+        /// <summary>
+        /// Gets the call trailing metadata if the call has already finished.
+        /// Throws InvalidOperationException otherwise.
+        /// </summary>
+        public Metadata GetTrailers()
+        {
+            return getTrailersFunc();
+        }
+
+        /// <summary>
         /// Provides means to cleanup after the call.
         /// If the call has already finished normally (request stream has been completed and call result has been received), doesn't do anything.
         /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
diff --git a/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs b/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs
index 0979de6..183c842 100644
--- a/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs
+++ b/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs
@@ -32,8 +32,6 @@
 #endregion
 
 using System;
-using System.Runtime.CompilerServices;
-using System.Threading.Tasks;
 
 namespace Grpc.Core
 {
diff --git a/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs b/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs
index 380efcd..ab2049f 100644
--- a/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs
+++ b/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs
@@ -32,8 +32,6 @@
 #endregion
 
 using System;
-using System.Runtime.CompilerServices;
-using System.Threading.Tasks;
 
 namespace Grpc.Core
 {
diff --git a/src/csharp/Grpc.Core/ChannelOptions.cs b/src/csharp/Grpc.Core/ChannelOptions.cs
index 0cb2953..ad54b46 100644
--- a/src/csharp/Grpc.Core/ChannelOptions.cs
+++ b/src/csharp/Grpc.Core/ChannelOptions.cs
@@ -71,7 +71,7 @@
         /// Creates a channel option with an integer value.
         /// </summary>
         /// <param name="name">Name.</param>
-        /// <param name="stringValue">String value.</param>
+        /// <param name="intValue">Integer value.</param>
         public ChannelOption(string name, int intValue)
         {
             this.type = OptionType.Integer;
diff --git a/src/csharp/Grpc.Core/ClientBase.cs b/src/csharp/Grpc.Core/ClientBase.cs
index f240d77..7bc100c 100644
--- a/src/csharp/Grpc.Core/ClientBase.cs
+++ b/src/csharp/Grpc.Core/ClientBase.cs
@@ -32,15 +32,15 @@
 #endregion
 
 using System;
-using System.Collections.Generic;
 using System.Text.RegularExpressions;
-
-using Grpc.Core.Internal;
-using Grpc.Core.Utils;
+using System.Threading.Tasks;
 
 namespace Grpc.Core
 {
-    public delegate void MetadataInterceptorDelegate(string authUri, Metadata metadata);
+    /// <summary>
+    /// Interceptor for call headers.
+    /// </summary>
+    public delegate void HeaderInterceptor(IMethod method, string authUri, Metadata metadata);
 
     /// <summary>
     /// Base class for client-side stubs.
@@ -60,10 +60,10 @@
         }
 
         /// <summary>
-        /// Can be used to register a custom header (initial metadata) interceptor.
-        /// The delegate each time before a new call on this client is started.
+        /// Can be used to register a custom header (request metadata) interceptor.
+        /// The interceptor is invoked each time a new call on this client is started.
         /// </summary>
-        public MetadataInterceptorDelegate HeaderInterceptor
+        public HeaderInterceptor HeaderInterceptor
         {
             get;
             set;
@@ -107,7 +107,7 @@
                     options = options.WithHeaders(new Metadata());
                 }
                 var authUri = authUriBase != null ? authUriBase + method.ServiceName : null;
-                interceptor(authUri, options.Headers);
+                interceptor(method, authUri, options.Headers);
             }
             return new CallInvocationDetails<TRequest, TResponse>(channel, method, Host, options);
         }
diff --git a/src/csharp/Grpc.Core/Method.cs b/src/csharp/Grpc.Core/Method.cs
index 4c208b4..4c53285 100644
--- a/src/csharp/Grpc.Core/Method.cs
+++ b/src/csharp/Grpc.Core/Method.cs
@@ -55,9 +55,36 @@
     }
 
     /// <summary>
+    /// A non-generic representation of a remote method.
+    /// </summary>
+    public interface IMethod
+    {
+        /// <summary>
+        /// Gets the type of the method.
+        /// </summary>
+        MethodType Type { get; }
+
+        /// <summary>
+        /// Gets the name of the service to which this method belongs.
+        /// </summary>
+        string ServiceName { get; }
+
+        /// <summary>
+        /// Gets the unqualified name of the method.
+        /// </summary>
+        string Name { get; }
+
+        /// <summary>
+        /// Gets the fully qualified name of the method. On the server side, methods are dispatched
+        /// based on this name.
+        /// </summary>
+        string FullName { get; }
+    }
+
+    /// <summary>
     /// A description of a remote method.
     /// </summary>
-    public class Method<TRequest, TResponse>
+    public class Method<TRequest, TResponse> : IMethod
     {
         readonly MethodType type;
         readonly string serviceName;
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index 385ca92..f4b0a10 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -308,7 +308,7 @@
             Console.WriteLine("running service_account_creds");
             var credential = await GoogleCredential.GetApplicationDefaultAsync();
             credential = credential.CreateScoped(new[] { AuthScope });
-            client.HeaderInterceptor = OAuth2Interceptors.FromCredential(credential);
+            client.HeaderInterceptor = AuthInterceptors.FromCredential(credential);
 
             var request = SimpleRequest.CreateBuilder()
                 .SetResponseType(PayloadType.COMPRESSABLE)
@@ -332,7 +332,7 @@
             Console.WriteLine("running compute_engine_creds");
             var credential = await GoogleCredential.GetApplicationDefaultAsync();
             Assert.IsFalse(credential.IsCreateScopedRequired);
-            client.HeaderInterceptor = OAuth2Interceptors.FromCredential(credential);
+            client.HeaderInterceptor = AuthInterceptors.FromCredential(credential);
             
             var request = SimpleRequest.CreateBuilder()
                 .SetResponseType(PayloadType.COMPRESSABLE)
@@ -357,7 +357,7 @@
             var credential = await GoogleCredential.GetApplicationDefaultAsync();
             // check this a credential with scope support, but don't add the scope.
             Assert.IsTrue(credential.IsCreateScopedRequired);
-            client.HeaderInterceptor = OAuth2Interceptors.FromCredential(credential);
+            client.HeaderInterceptor = AuthInterceptors.FromCredential(credential);
 
             var request = SimpleRequest.CreateBuilder()
                 .SetResponseType(PayloadType.COMPRESSABLE)
@@ -381,7 +381,7 @@
             ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { AuthScope });
             string oauth2Token = await credential.GetAccessTokenForRequestAsync();
 
-            client.HeaderInterceptor = OAuth2Interceptors.FromAccessToken(oauth2Token);
+            client.HeaderInterceptor = AuthInterceptors.FromAccessToken(oauth2Token);
 
             var request = SimpleRequest.CreateBuilder()
                 .SetFillUsername(true)
@@ -401,7 +401,7 @@
 
             ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { AuthScope });
             string oauth2Token = await credential.GetAccessTokenForRequestAsync();
-            var headerInterceptor = OAuth2Interceptors.FromAccessToken(oauth2Token);
+            var headerInterceptor = AuthInterceptors.FromAccessToken(oauth2Token);
 
             var request = SimpleRequest.CreateBuilder()
                 .SetFillUsername(true)
@@ -409,7 +409,7 @@
                 .Build();
 
             var headers = new Metadata();
-            headerInterceptor("", headers);
+            headerInterceptor(null, "", headers);
             var response = client.UnaryCall(request, headers: headers);
 
             Assert.AreEqual(AuthScopeResponse, response.OauthScope);