/// <summary>
        /// Create a service object.
        /// </summary>
        /// <param name="signature">Signature of the service being created.</param>
        /// <param name="user">The user for which the service is being created.
        /// <param name="serverUrl">The server to which the API calls should be
        /// made.</param>
        /// </param>
        /// <returns>An object of the desired service type.</returns>
        public override AdsClient CreateService(ServiceSignature signature, AdsUser user,
                                                Uri serverUrl)
        {
            DfpAppConfig dfpConfig = (DfpAppConfig)Config;

            if (serverUrl == null)
            {
                serverUrl = new Uri(dfpConfig.DfpApiServer);
            }

            if (user == null)
            {
                throw new ArgumentNullException("user");
            }

            CheckServicePreconditions(signature);

            DfpServiceSignature dfpapiSignature = signature as DfpServiceSignature;

            AdsClient    service  = (AdsClient)Activator.CreateInstance(dfpapiSignature.ServiceType);
            PropertyInfo propInfo = dfpapiSignature.ServiceType.GetProperty("RequestHeader");

            if (propInfo != null)
            {
                RequestHeader clonedHeader = (RequestHeader)requestHeader.Clone();
                clonedHeader.Version = dfpapiSignature.Version;
                propInfo.SetValue(service, clonedHeader, null);
            }

            if (dfpConfig.Proxy != null)
            {
                service.Proxy = dfpConfig.Proxy;
            }
            service.Timeout = dfpConfig.Timeout;
            service.Url     = string.Format("{0}apis/ads/publisher/{1}/{2}",
                                            serverUrl, dfpapiSignature.Version, dfpapiSignature.ServiceName);
            service.UserAgent = dfpConfig.GetUserAgent();

            service.Signature = signature;
            service.User      = user;
            return(service);
        }
        /// <summary>
        /// Checks preconditions of the service signature and throws and exception if the service
        /// cannot be generated.
        /// </summary>
        /// <param name="signature">the service signature for generating the service</param>
        protected override void CheckServicePreconditions(ServiceSignature signature)
        {
            if (signature == null)
            {
                throw new ArgumentNullException("signature");
            }
            if (!(signature is DfpServiceSignature))
            {
                throw new InvalidCastException(string.Format(CultureInfo.InvariantCulture,
                                                             DfpErrorMessages.SignatureIsOfWrongType, typeof(DfpServiceSignature)));
            }
            DfpAppConfig        dfpConfig    = (DfpAppConfig)Config;
            DfpServiceSignature dfpSignature = signature as DfpServiceSignature;
            String version = dfpSignature.Version;

            if (dfpConfig.AuthorizationMethod == DfpAuthorizationMethod.ClientLogin &&
                version.CompareTo(FINAL_CLIENT_LOGIN_VERSION) > 0)
            {
                throw new DfpException(string.Format(DfpErrorMessages.ClientLoginNotSupported, version));
            }
        }
        /// <summary>
        /// Create a service object.
        /// </summary>
        /// <param name="signature">Signature of the service being created.</param>
        /// <param name="user">The user for which the service is being created.
        /// <param name="serverUrl">The server to which the API calls should be
        /// made.</param>
        /// </param>
        /// <returns>An object of the desired service type.</returns>
        public override AdsClient CreateService(ServiceSignature signature, AdsUser user,
                                                Uri serverUrl)
        {
            DfpAppConfig dfpConfig = (DfpAppConfig)Config;

            if (serverUrl == null)
            {
                serverUrl = new Uri(dfpConfig.DfpApiServer);
            }

            if (user == null)
            {
                throw new ArgumentNullException("user");
            }

            CheckServicePreconditions(signature);

            DfpServiceSignature dfpapiSignature = signature as DfpServiceSignature;
            EndpointAddress     endpoint        = new EndpointAddress(string.Format(ENDPOINT_TEMPLATE,
                                                                                    serverUrl, dfpapiSignature.Version, dfpapiSignature.ServiceName));

            // Create the binding for the service
            BasicHttpBinding binding = new BasicHttpBinding();

            binding.Security.Mode = BasicHttpSecurityMode.Transport;
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
            binding.MaxReceivedMessageSize = int.MaxValue;
            binding.TextEncoding           = Encoding.UTF8;

            AdsClient service = (AdsClient)Activator.CreateInstance(
                dfpapiSignature.ServiceType,
                new object[] { binding, endpoint });

            ServiceEndpoint serviceEndpoint =
                (ServiceEndpoint)service.GetType().GetProperty("Endpoint").GetValue(service, null);

            AdsServiceInspectorBehavior inspectorBehavior = new AdsServiceInspectorBehavior();

            inspectorBehavior.Add(new OAuth2ClientMessageInspector(user.OAuthProvider));

            RequestHeader clonedHeader = (RequestHeader)requestHeader.Clone();

            clonedHeader.Version = dfpapiSignature.Version;
            inspectorBehavior.Add(new DfpSoapHeaderInspector()
            {
                RequestHeader = clonedHeader,
                Config        = dfpConfig
            });
            inspectorBehavior.Add(new SoapListenerInspector(user, dfpapiSignature.ServiceName));
            inspectorBehavior.Add(new SoapFaultInspector <DfpApiException>()
            {
                ErrorType = dfpapiSignature.ServiceType.Assembly.GetType(
                    dfpapiSignature.ServiceType.Namespace + ".ApiException"),
            });
#if NET452
            serviceEndpoint.Behaviors.Add(inspectorBehavior);
#else
            serviceEndpoint.EndpointBehaviors.Add(inspectorBehavior);
#endif

            if (dfpConfig.Proxy != null)
            {
                service.Proxy = dfpConfig.Proxy;
            }
            service.EnableDecompression = dfpConfig.EnableGzipCompression;
            service.Timeout             = dfpConfig.Timeout;
            service.UserAgent           = dfpConfig.GetUserAgent();

            service.Signature = signature;
            service.User      = user;
            return(service);
        }