context: 
  using System;
  using System.Collections.Generic;
  using System.Collections.ObjectModel;
  using System.Globalization;
  using System.IdentityModel.Selectors;
  using System.IdentityModel.Tokens;
  using System.IO;
  using System.Linq;
  using System.Net;
  using System.Security.Cryptography.X509Certificates;
  using System.Security.Principal;
  using System.ServiceModel;
  using System.ServiceModel.Channels;
  using System.Text;
  using System.Web;
  using System.Web.Configuration;
  using System.Web.Script.Serialization;
  using Microsoft.IdentityModel;
  using Microsoft.IdentityModel.S2S.Protocols.OAuth2;
  using Microsoft.IdentityModel.S2S.Tokens;
  using Microsoft.SharePoint.Client;
  using Microsoft.SharePoint.Client.EventReceivers;
  
  namespace SP_ProviderApp_WAC_csWeb
  {
  
      public class TokenHelper
      {
  
          #region public methods
  
          /// <summary>
          /// Configures .Net to trust all certificates when making network calls.  This is used so that calls 
          /// to an https SharePoint server without a valid certificate are not rejected.  This should only be used during 
          /// testing, and should never be used in a production app.
          /// </summary>
          public static void TrustAllCertificates()
          {
              //Trust all certificates
              System.Net.ServicePointManager.ServerCertificateValidationCallback =
                  ((sender, certificate, chain, sslPolicyErrors) => true);
          }
  
          /// <summary>
          /// Retrieves the context token string from the specified request by looking for well-known parameter names in the 
          /// POSTed form parameters and the querystring. Returns null if no context token is found.
          /// </summary>
          /// <param name="request">HttpRequest in which to look for a context token</param>
          /// <returns>The context token string</returns>
          public static string GetContextTokenFromRequest(HttpRequest request)
          {
              string[] paramNames = { "AppContext", "AppContextToken", "AccessToken", "SPAppToken" };
              foreach (string paramName in paramNames)
              {
                  if (!string.IsNullOrEmpty(request.Form[paramName])) return request.Form[paramName];
                  if (!string.IsNullOrEmpty(request.QueryString[paramName])) return request.QueryString[paramName];
              }
              return null;
          }
  
          /// <summary>
          /// Validate that a specified context token string is intended for this application based on the parameters 
          /// specified in web.config. Parameters used from web.config used for validation include ClientId, 
          /// HostedAppHostName, ClientSecret, and Realm (if it is specified). If the <paramref name="appHostName"/> is not 
          /// null, it is used for validation instead of the web.config's HostedAppHostName. If the token is invalid, an 
          /// exception is thrown. If the token is valid, TokenHelper's static STS metadata url is updated based on the token contents
          /// and a JsonWebSecurityToken based on the context token is returned.
          /// </summary>
          /// <param name="contextTokenString">The context token to validate</param>
          /// <param name="appHostName">The URL authority, consisting of  Domain Name System (DNS) host name or IP address and the port number, to use for token audience validation.
          /// If null, HostedAppHostName web.config setting is used instead.</param>
          /// <returns>A JsonWebSecurityToken based on the context token.</returns>
          public static SharePointContextToken ReadAndValidateContextToken(string contextTokenString, string appHostName = null)
          {
              JsonWebSecurityTokenHandler tokenHandler = CreateJsonWebSecurityTokenHandler();
              SecurityToken securityToken = tokenHandler.ReadToken(contextTokenString);
              JsonWebSecurityToken jsonToken = securityToken as JsonWebSecurityToken;
              SharePointContextToken token = SharePointContextToken.Create(jsonToken);
  
              string stsAuthority = (new Uri(token.SecurityTokenServiceUri)).Authority;
              int firstDot = stsAuthority.IndexOf('.');
  
              GlobalEndPointPrefix = stsAuthority.Substring(0, firstDot);
              AcsHostUrl = stsAuthority.Substring(firstDot + 1);
  
              tokenHandler.ValidateToken(jsonToken);
  
              if (appHostName == null)
              {
                  appHostName = HostedAppHostName;
              }
  
              string realm = Realm ?? token.Realm;
              string principal = GetFormattedPrincipal(ClientId, appHostName, realm);
              if (!StringComparer.OrdinalIgnoreCase.Equals(token.Audience, principal))
              {
                  throw new Microsoft.IdentityModel.Tokens.AudienceUriValidationFailedException(
                      String.Format(CultureInfo.CurrentCulture,
                      "\"{0}\" is not the intended audience \"{1}\"", principal, token.Audience));
              }
  
              return token;
          }
  
          /// <summary>
          /// Retrieves an access token from ACS to call the source of the specified context token at the specified 
          /// targetHost. The targetHost must be registered for principal the that sent the context token.
          /// </summary>
          /// <param name="contextToken">Context token issued by the intended access token audience</param>
          /// <param name="targetHost">Url authority of the target principal</param>
          /// <returns>An access token with an audience matching the context token's source</returns>
          public static OAuth2AccessTokenResponse GetAccessToken(SharePointContextToken contextToken, string targetHost)
          {
  
              string targetPrincipalName = contextToken.TargetPrincipalName;
  
              // Extract the refreshToken from the context token
              string refreshToken = contextToken.RefreshToken;
  
              if (String.IsNullOrEmpty(refreshToken))
              {
                  return null;
              }
  
              string realm = Realm ?? contextToken.Realm;
  
              string resource = GetFormattedPrincipal(targetPrincipalName, targetHost, realm);
              string clientId = GetFormattedPrincipal(ClientId, null, realm);
  
              OAuth2AccessTokenRequest oauth2Request =
                  OAuth2MessageFactory.CreateAccessTokenRequestWithRefreshToken(
                      clientId,
                      ClientSecret,
                      refreshToken,
                      resource);
  
              // Get token
              OAuth2S2SClient client = new OAuth2S2SClient();
              OAuth2AccessTokenResponse oauth2Response;
              try
              {
                  oauth2Response =
                      client.Issue(AcsMetadataParser.GetStsUrl(realm), oauth2Request) as OAuth2AccessTokenResponse;
              }
              catch (WebException wex)
              {
                  using (StreamReader sr = new StreamReader(wex.Response.GetResponseStream()))
                  {
                      string responseText = sr.ReadToEnd();
                      throw new WebException(wex.Message + " - " + responseText, wex);
                  }
              }
  
              return oauth2Response;
          }
  
          /// <summary>
          /// Uses the specified authorization code to retrieve an access token from ACS to call the specified principal 
          /// at the specified targetHost. The targetHost must be registered for target principal.  If specified realm is 
          /// null, the "Realm" setting in web.config will be used instead.
          /// </summary>
          /// <param name="authorizationCode">Authorization code to exchange for access token</param>
          /// <param name="targetPrincipalName">Name of the target principal to retrieve an access token for</param>
          /// <param name="targetHost">Url authority of the target principal</param>
          /// <param name="targetRealm">Realm to use for the access token's nameid and audience</param>
          /// <returns>An access token with an audience of the target principal</returns>
          public static OAuth2AccessTokenResponse GetAccessToken(
              string authorizationCode,
              string targetPrincipalName,
              string targetHost,
              string targetRealm,
              Uri redirectUri)
          {
  
              if (targetRealm == null)
              {
                  targetRealm = Realm;
              }
  
              string resource = GetFormattedPrincipal(targetPrincipalName, targetHost, targetRealm);
              string clientId = GetFormattedPrincipal(ClientId, null, targetRealm);
  
              // Create request for token. The RedirectUri is null here.  This will fail if redirect uri is registered
              OAuth2AccessTokenRequest oauth2Request =
                  OAuth2MessageFactory.CreateAccessTokenRequestWithAuthorizationCode(
                      clientId,
                      ClientSecret,
                      authorizationCode,
                      redirectUri,
                      resource);
  
              // Get token
              OAuth2S2SClient client = new OAuth2S2SClient();
              OAuth2AccessTokenResponse oauth2Response;
              try
              {
                  oauth2Response =
                      client.Issue(AcsMetadataParser.GetStsUrl(targetRealm), oauth2Request) as OAuth2AccessTokenResponse;
              }
              catch (WebException wex)
              {
                  using (StreamReader sr = new StreamReader(wex.Response.GetResponseStream()))
                  {
                      string responseText = sr.ReadToEnd();
                      throw new WebException(wex.Message + " - " + responseText, wex);
                  }
              }
  
              return oauth2Response;
          }
  
          /// <summary>
          /// Uses the specified refresh token to retrieve an access token from ACS to call the specified principal 
          /// at the specified targetHost. The targetHost must be registered for target principal.  If specified realm is 
          /// null, the "Realm" setting in web.config will be used instead.
          /// </summary>
          /// <param name="refreshToken">Refresh token to exchange for access token</param>
          /// <param name="targetPrincipalName">Name of the target principal to retrieve an access token for</param>
          /// <param name="targetHost">Url authority of the target principal</param>
          /// <param name="targetRealm">Realm to use for the access token's nameid and audience</param>
          /// <returns>An access token with an audience of the target principal</returns>
          public OAuth2AccessTokenResponse GetAccessToken(
              string refreshToken,
              string targetPrincipalName,
              string targetHost,
              string targetRealm)
          {
  
              if (targetRealm == null)
              {
                  targetRealm = Realm;
              }
  
              string resource = GetFormattedPrincipal(targetPrincipalName, targetHost, targetRealm);
              string clientId = GetFormattedPrincipal(ClientId, null, targetRealm);
  
              OAuth2AccessTokenRequest oauth2Request = OAuth2MessageFactory.CreateAccessTokenRequestWithRefreshToken(clientId, ClientSecret, refreshToken, resource);
  
              // Get token
              OAuth2S2SClient client = new OAuth2S2SClient();
              OAuth2AccessTokenResponse oauth2Response;
              try
              {
                  oauth2Response =
                      client.Issue(AcsMetadataParser.GetStsUrl(targetRealm), oauth2Request) as OAuth2AccessTokenResponse;
              }
              catch (WebException wex)
              {
                  using (StreamReader sr = new StreamReader(wex.Response.GetResponseStream()))
                  {
                      string responseText = sr.ReadToEnd();
                      throw new WebException(wex.Message + " - " + responseText, wex);
                  }
              }
  
              return oauth2Response;
          }
  
          /// <summary>
          /// Retrieves an app-only access token from ACS to call the specified principal 
          /// at the specified targetHost. The targetHost must be registered for target principal.  If specified realm is 
          /// null, the "Realm" setting in web.config will be used instead.
          /// </summary>
          /// <param name="targetPrincipalName">Name of the target principal to retrieve an access token for</param>
          /// <param name="targetHost">Url authority of the target principal</param>
          /// <param name="targetRealm">Realm to use for the access token's nameid and audience</param>
          /// <returns>An access token with an audience of the target principal</returns>
          public static OAuth2AccessTokenResponse GetAppOnlyAccessToken(
              string targetPrincipalName,
              string targetHost,
              string targetRealm)
          {
  
              if (targetRealm == null)
              {
                  targetRealm = Realm;
              }
  
              string resource = GetFormattedPrincipal(targetPrincipalName, targetHost, targetRealm);
              string clientId = GetFormattedPrincipal(ClientId, HostedAppHostName, targetRealm);
  
              OAuth2AccessTokenRequest oauth2Request = OAuth2MessageFactory.CreateAccessTokenRequestWithClientCredentials(clientId, ClientSecret, resource);
              oauth2Request.Resource = resource;
  
              // Get token
              OAuth2S2SClient client = new OAuth2S2SClient();
  
              OAuth2AccessTokenResponse oauth2Response;
              try
              {
                  oauth2Response =
                      client.Issue(AcsMetadataParser.GetStsUrl(targetRealm), oauth2Request) as OAuth2AccessTokenResponse;
              }
              catch (WebException wex)
              {
                  using (StreamReader sr = new StreamReader(wex.Response.GetResponseStream()))
                  {
                      string responseText = sr.ReadToEnd();
                      throw new WebException(wex.Message + " - " + responseText, wex);
                  }
              }
  
              return oauth2Response;
          }
  
          /// <summary>
          /// Creates a client context based on the properties of a remote event receiver
          /// </summary>
          /// <param name="properties">Properties of a remote event receiver</param>
          /// <returns>A ClientContext ready to call the web where the event originated</returns>
          public static ClientContext CreateRemoteEventReceiverClientContext(SPRemoteEventProperties properties)
          {
              Uri sharepointUrl = null;
              if (properties.ListEventProperties != null)
              {
                  sharepointUrl = new Uri(properties.ListEventProperties.WebUrl);
              }
  
gt:             else if (properties.ItemEventProperties != null)