| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353 | 
							- <?php
 
- namespace Aws;
 
- use Aws\Api\ApiProvider;
 
- use Aws\Api\Service;
 
- use Aws\Api\Validator;
 
- use Aws\Auth\AuthResolver;
 
- use Aws\Auth\AuthSchemeResolver;
 
- use Aws\Auth\AuthSchemeResolverInterface;
 
- use Aws\ClientSideMonitoring\ApiCallAttemptMonitoringMiddleware;
 
- use Aws\ClientSideMonitoring\ApiCallMonitoringMiddleware;
 
- use Aws\ClientSideMonitoring\Configuration;
 
- use Aws\Configuration\ConfigurationResolver;
 
- use Aws\Credentials\CredentialProvider;
 
- use Aws\Credentials\Credentials;
 
- use Aws\Credentials\CredentialsInterface;
 
- use Aws\DefaultsMode\ConfigurationInterface as ConfigModeInterface;
 
- use Aws\DefaultsMode\ConfigurationProvider as ConfigModeProvider;
 
- use Aws\Endpoint\EndpointProvider;
 
- use Aws\Endpoint\PartitionEndpointProvider;
 
- use Aws\Endpoint\UseDualstackEndpoint\Configuration as UseDualStackEndpointConfiguration;
 
- use Aws\Endpoint\UseDualstackEndpoint\ConfigurationInterface as UseDualStackEndpointConfigurationInterface;
 
- use Aws\Endpoint\UseDualstackEndpoint\ConfigurationProvider as UseDualStackConfigProvider;
 
- use Aws\Endpoint\UseFipsEndpoint\Configuration as UseFipsEndpointConfiguration;
 
- use Aws\Endpoint\UseFipsEndpoint\ConfigurationInterface as UseFipsEndpointConfigurationInterface;
 
- use Aws\Endpoint\UseFipsEndpoint\ConfigurationProvider as UseFipsConfigProvider;
 
- use Aws\EndpointDiscovery\ConfigurationInterface;
 
- use Aws\EndpointDiscovery\ConfigurationProvider;
 
- use Aws\EndpointV2\EndpointDefinitionProvider;
 
- use Aws\Exception\AwsException;
 
- use Aws\Exception\InvalidRegionException;
 
- use Aws\Retry\ConfigurationInterface as RetryConfigInterface;
 
- use Aws\Retry\ConfigurationProvider as RetryConfigProvider;
 
- use Aws\Signature\SignatureProvider;
 
- use Aws\Token\Token;
 
- use Aws\Token\TokenInterface;
 
- use Aws\Token\TokenProvider;
 
- use GuzzleHttp\Promise\PromiseInterface;
 
- use InvalidArgumentException as IAE;
 
- use Psr\Http\Message\RequestInterface;
 
- /**
 
-  * @internal Resolves a hash of client arguments to construct a client.
 
-  */
 
- class ClientResolver
 
- {
 
-     /** @var array */
 
-     private $argDefinitions;
 
-     /** @var array Map of types to a corresponding function */
 
-     private static $typeMap = [
 
-         'resource' => 'is_resource',
 
-         'callable' => 'is_callable',
 
-         'int'      => 'is_int',
 
-         'bool'     => 'is_bool',
 
-         'boolean'  => 'is_bool',
 
-         'string'   => 'is_string',
 
-         'object'   => 'is_object',
 
-         'array'    => 'is_array',
 
-     ];
 
-     private static $defaultArgs = [
 
-         'service' => [
 
-             'type'     => 'value',
 
-             'valid'    => ['string'],
 
-             'doc'      => 'Name of the service to utilize. This value will be supplied by default when using one of the SDK clients (e.g., Aws\\S3\\S3Client).',
 
-             'required' => true,
 
-             'internal' => true
 
-         ],
 
-         'exception_class' => [
 
-             'type'     => 'value',
 
-             'valid'    => ['string'],
 
-             'doc'      => 'Exception class to create when an error occurs.',
 
-             'default'  => AwsException::class,
 
-             'internal' => true
 
-         ],
 
-         'scheme' => [
 
-             'type'     => 'value',
 
-             'valid'    => ['string'],
 
-             'default'  => 'https',
 
-             'doc'      => 'URI scheme to use when connecting connect. The SDK will utilize "https" endpoints (i.e., utilize SSL/TLS connections) by default. You can attempt to connect to a service over an unencrypted "http" endpoint by setting ``scheme`` to "http".',
 
-         ],
 
-         'disable_host_prefix_injection' => [
 
-             'type'      => 'value',
 
-             'valid'     => ['bool'],
 
-             'doc'       => 'Set to true to disable host prefix injection logic for services that use it. This disables the entire prefix injection, including the portions supplied by user-defined parameters. Setting this flag will have no effect on services that do not use host prefix injection.',
 
-             'default'   => false,
 
-         ],
 
-         'ignore_configured_endpoint_urls' => [
 
-             'type'      => 'value',
 
-             'valid'     => ['bool'],
 
-             'doc'       => 'Set to true to disable endpoint urls configured using `AWS_ENDPOINT_URL` and `endpoint_url` shared config option.',
 
-             'fn'        => [__CLASS__, '_apply_ignore_configured_endpoint_urls'],
 
-             'default'   => [__CLASS__, '_default_ignore_configured_endpoint_urls'],
 
-         ],
 
-         'endpoint' => [
 
-             'type'  => 'value',
 
-             'valid' => ['string'],
 
-             'doc'   => 'The full URI of the webservice. This is only required when connecting to a custom endpoint (e.g., a local version of S3).',
 
-             'fn'    => [__CLASS__, '_apply_endpoint'],
 
-             'default'   => [__CLASS__, '_default_endpoint']
 
-         ],
 
-         'region' => [
 
-             'type'     => 'value',
 
-             'valid'    => ['string'],
 
-             'doc'      => 'Region to connect to. See http://docs.aws.amazon.com/general/latest/gr/rande.html for a list of available regions.',
 
-             'fn'       => [__CLASS__, '_apply_region'],
 
-             'default'  => [__CLASS__, '_default_region']
 
-         ],
 
-         'version' => [
 
-             'type'     => 'value',
 
-             'valid'    => ['string'],
 
-             'doc'      => 'The version of the webservice to utilize (e.g., 2006-03-01).',
 
-             'default' => 'latest',
 
-         ],
 
-         'signature_provider' => [
 
-             'type'    => 'value',
 
-             'valid'   => ['callable'],
 
-             'doc'     => 'A callable that accepts a signature version name (e.g., "v4"), a service name, and region, and  returns a SignatureInterface object or null. This provider is used to create signers utilized by the client. See Aws\\Signature\\SignatureProvider for a list of built-in providers',
 
-             'default' => [__CLASS__, '_default_signature_provider'],
 
-         ],
 
-         'api_provider' => [
 
-             'type'     => 'value',
 
-             'valid'    => ['callable'],
 
-             'doc'      => 'An optional PHP callable that accepts a type, service, and version argument, and returns an array of corresponding configuration data. The type value can be one of api, waiter, or paginator.',
 
-             'fn'       => [__CLASS__, '_apply_api_provider'],
 
-             'default'  => [ApiProvider::class, 'defaultProvider'],
 
-         ],
 
-         'configuration_mode' => [
 
-             'type'    => 'value',
 
-             'valid'   => [ConfigModeInterface::class, CacheInterface::class, 'string', 'closure'],
 
-             'doc'     => "Sets the default configuration mode. Otherwise provide an instance of Aws\DefaultsMode\ConfigurationInterface, an instance of  Aws\CacheInterface, or a string containing a valid mode",
 
-             'fn'      => [__CLASS__, '_apply_defaults'],
 
-             'default' => [ConfigModeProvider::class, 'defaultProvider']
 
-         ],
 
-         'use_fips_endpoint' => [
 
-             'type'      => 'value',
 
-             'valid'     => ['bool', UseFipsEndpointConfiguration::class, CacheInterface::class, 'callable'],
 
-             'doc'       => 'Set to true to enable the use of FIPS pseudo regions',
 
-             'fn'        => [__CLASS__, '_apply_use_fips_endpoint'],
 
-             'default'   => [__CLASS__, '_default_use_fips_endpoint'],
 
-         ],
 
-         'use_dual_stack_endpoint' => [
 
-             'type'      => 'value',
 
-             'valid'     => ['bool', UseDualStackEndpointConfiguration::class, CacheInterface::class, 'callable'],
 
-             'doc'       => 'Set to true to enable the use of dual-stack endpoints',
 
-             'fn'        => [__CLASS__, '_apply_use_dual_stack_endpoint'],
 
-             'default'   => [__CLASS__, '_default_use_dual_stack_endpoint'],
 
-         ],
 
-         'endpoint_provider' => [
 
-             'type'     => 'value',
 
-             'valid'    => ['callable', EndpointV2\EndpointProviderV2::class],
 
-             'fn'       => [__CLASS__, '_apply_endpoint_provider'],
 
-             'doc'      => 'An optional PHP callable that accepts a hash of options including a "service" and "region" key and returns NULL or a hash of endpoint data, of which the "endpoint" key is required. See Aws\\Endpoint\\EndpointProvider for a list of built-in providers.',
 
-             'default'  => [__CLASS__, '_default_endpoint_provider'],
 
-         ],
 
-         'serializer' => [
 
-             'default'   => [__CLASS__, '_default_serializer'],
 
-             'fn'        => [__CLASS__, '_apply_serializer'],
 
-             'internal'  => true,
 
-             'type'      => 'value',
 
-             'valid'     => ['callable'],
 
-         ],
 
-         'signature_version' => [
 
-             'type'    => 'config',
 
-             'valid'   => ['string'],
 
-             'doc'     => 'A string representing a custom signature version to use with a service (e.g., v4). Note that per/operation signature version MAY override this requested signature version.',
 
-             'default' => [__CLASS__, '_default_signature_version'],
 
-         ],
 
-         'signing_name' => [
 
-             'type'    => 'config',
 
-             'valid'   => ['string'],
 
-             'doc'     => 'A string representing a custom service name to be used when calculating a request signature.',
 
-             'default' => [__CLASS__, '_default_signing_name'],
 
-         ],
 
-         'signing_region' => [
 
-             'type'    => 'config',
 
-             'valid'   => ['string'],
 
-             'doc'     => 'A string representing a custom region name to be used when calculating a request signature.',
 
-             'default' => [__CLASS__, '_default_signing_region'],
 
-         ],
 
-         'profile' => [
 
-             'type'  => 'config',
 
-             'valid' => ['string'],
 
-             'doc'   => 'Allows you to specify which profile to use when credentials are created from the AWS credentials file in your HOME directory. This setting overrides the AWS_PROFILE environment variable. Note: Specifying "profile" will cause the "credentials" and "use_aws_shared_config_files" keys to be ignored.',
 
-             'fn'    => [__CLASS__, '_apply_profile'],
 
-         ],
 
-         'credentials' => [
 
-             'type'    => 'value',
 
-             'valid'   => [CredentialsInterface::class, CacheInterface::class, 'array', 'bool', 'callable'],
 
-             'doc'     => 'Specifies the credentials used to sign requests. Provide an Aws\Credentials\CredentialsInterface object, an associative array of "key", "secret", and an optional "token" key, `false` to use null credentials, or a callable credentials provider used to create credentials or return null. See Aws\\Credentials\\CredentialProvider for a list of built-in credentials providers. If no credentials are provided, the SDK will attempt to load them from the environment.',
 
-             'fn'      => [__CLASS__, '_apply_credentials'],
 
-             'default' => [__CLASS__, '_default_credential_provider'],
 
-         ],
 
-         'token' => [
 
-             'type'    => 'value',
 
-             'valid'   => [TokenInterface::class, CacheInterface::class, 'array', 'bool', 'callable'],
 
-             'doc'     => 'Specifies the token used to authorize requests. Provide an Aws\Token\TokenInterface object, an associative array of "token", and an optional "expiration" key, `false` to use a null token, or a callable token provider used to fetch a token or return null. See Aws\\Token\\TokenProvider for a list of built-in credentials providers. If no token is provided, the SDK will attempt to load one from the environment.',
 
-             'fn'      => [__CLASS__, '_apply_token'],
 
-             'default' => [__CLASS__, '_default_token_provider'],
 
-         ],
 
-         'auth_scheme_resolver' => [
 
-             'type'    => 'value',
 
-             'valid'   => [AuthSchemeResolverInterface::class],
 
-             'doc'     => 'An instance of Aws\Auth\AuthSchemeResolverInterface which selects a modeled auth scheme and returns a signature version',
 
-             'default' => [__CLASS__, '_default_auth_scheme_resolver'],
 
-         ],
 
-         'endpoint_discovery' => [
 
-             'type'     => 'value',
 
-             'valid'    => [ConfigurationInterface::class, CacheInterface::class, 'array', 'callable'],
 
-             'doc'      => 'Specifies settings for endpoint discovery. Provide an instance of Aws\EndpointDiscovery\ConfigurationInterface, an instance Aws\CacheInterface, a callable that provides a promise for a Configuration object, or an associative array with the following keys: enabled: (bool) Set to true to enable endpoint discovery, false to explicitly disable it. Defaults to false; cache_limit: (int) The maximum number of keys in the endpoints cache. Defaults to 1000.',
 
-             'fn'       => [__CLASS__, '_apply_endpoint_discovery'],
 
-             'default'  => [__CLASS__, '_default_endpoint_discovery_provider']
 
-         ],
 
-         'stats' => [
 
-             'type'  => 'value',
 
-             'valid' => ['bool', 'array'],
 
-             'default' => false,
 
-             'doc'   => 'Set to true to gather transfer statistics on requests sent. Alternatively, you can provide an associative array with the following keys: retries: (bool) Set to false to disable reporting on retries attempted; http: (bool) Set to true to enable collecting statistics from lower level HTTP adapters (e.g., values returned in GuzzleHttp\TransferStats). HTTP handlers must support an http_stats_receiver option for this to have an effect; timer: (bool) Set to true to enable a command timer that reports the total wall clock time spent on an operation in seconds.',
 
-             'fn'    => [__CLASS__, '_apply_stats'],
 
-         ],
 
-         'retries' => [
 
-             'type'    => 'value',
 
-             'valid'   => ['int', RetryConfigInterface::class, CacheInterface::class, 'callable', 'array'],
 
-             'doc'     => "Configures the retry mode and maximum number of allowed retries for a client (pass 0 to disable retries). Provide an integer for 'legacy' mode with the specified number of retries. Otherwise provide an instance of Aws\Retry\ConfigurationInterface, an instance of  Aws\CacheInterface, a callable function, or an array with the following keys: mode: (string) Set to 'legacy', 'standard' (uses retry quota management), or 'adapative' (an experimental mode that adds client-side rate limiting to standard mode); max_attempts: (int) The maximum number of attempts for a given request. ",
 
-             'fn'      => [__CLASS__, '_apply_retries'],
 
-             'default' => [RetryConfigProvider::class, 'defaultProvider']
 
-         ],
 
-         'validate' => [
 
-             'type'    => 'value',
 
-             'valid'   => ['bool', 'array'],
 
-             'default' => true,
 
-             'doc'     => 'Set to false to disable client-side parameter validation. Set to true to utilize default validation constraints. Set to an associative array of validation options to enable specific validation constraints.',
 
-             'fn'      => [__CLASS__, '_apply_validate'],
 
-         ],
 
-         'debug' => [
 
-             'type'  => 'value',
 
-             'valid' => ['bool', 'array'],
 
-             'doc'   => 'Set to true to display debug information when sending requests. Alternatively, you can provide an associative array with the following keys: logfn: (callable) Function that is invoked with log messages; stream_size: (int) When the size of a stream is greater than this number, the stream data will not be logged (set to "0" to not log any stream data); scrub_auth: (bool) Set to false to disable the scrubbing of auth data from the logged messages; http: (bool) Set to false to disable the "debug" feature of lower level HTTP adapters (e.g., verbose curl output).',
 
-             'fn'    => [__CLASS__, '_apply_debug'],
 
-         ],
 
-         'disable_request_compression' => [
 
-             'type'      => 'value',
 
-             'valid'     => ['bool', 'callable'],
 
-             'doc'       => 'Set to true to disable request compression for supported operations',
 
-             'fn'        => [__CLASS__, '_apply_disable_request_compression'],
 
-             'default'   => [__CLASS__, '_default_disable_request_compression'],
 
-         ],
 
-         'request_min_compression_size_bytes' => [
 
-             'type'      => 'value',
 
-             'valid'     => ['int', 'callable'],
 
-             'doc'       => 'Set to a value between between 0 and 10485760 bytes, inclusive. This value will be ignored if `disable_request_compression` is set to `true`',
 
-             'fn'        => [__CLASS__, '_apply_min_compression_size'],
 
-             'default'   => [__CLASS__, '_default_min_compression_size'],
 
-         ],
 
-         'csm' => [
 
-             'type'     => 'value',
 
-             'valid'    => [\Aws\ClientSideMonitoring\ConfigurationInterface::class, 'callable', 'array', 'bool'],
 
-             'doc'      => 'CSM options for the client. Provides a callable wrapping a promise, a boolean "false", an instance of ConfigurationInterface, or an associative array of "enabled", "host", "port", and "client_id".',
 
-             'fn'       => [__CLASS__, '_apply_csm'],
 
-             'default'  => [\Aws\ClientSideMonitoring\ConfigurationProvider::class, 'defaultProvider']
 
-         ],
 
-         'http' => [
 
-             'type'    => 'value',
 
-             'valid'   => ['array'],
 
-             'default' => [],
 
-             'doc'     => 'Set to an array of SDK request options to apply to each request (e.g., proxy, verify, etc.).',
 
-         ],
 
-         'http_handler' => [
 
-             'type'    => 'value',
 
-             'valid'   => ['callable'],
 
-             'doc'     => 'An HTTP handler is a function that accepts a PSR-7 request object and returns a promise that is fulfilled with a PSR-7 response object or rejected with an array of exception data. NOTE: This option supersedes any provided "handler" option.',
 
-             'fn'      => [__CLASS__, '_apply_http_handler']
 
-         ],
 
-         'handler' => [
 
-             'type'     => 'value',
 
-             'valid'    => ['callable'],
 
-             'doc'      => 'A handler that accepts a command object, request object and returns a promise that is fulfilled with an Aws\ResultInterface object or rejected with an Aws\Exception\AwsException. A handler does not accept a next handler as it is terminal and expected to fulfill a command. If no handler is provided, a default Guzzle handler will be utilized.',
 
-             'fn'       => [__CLASS__, '_apply_handler'],
 
-             'default'  => [__CLASS__, '_default_handler']
 
-         ],
 
-         'app_id' => [
 
-             'type' => 'value',
 
-             'valid' => ['string'],
 
-             'doc' => 'app_id(AppId) is an optional application specific identifier that can be set. 
 
-              When set it will be appended to the User-Agent header of every request in the form of App/{AppId}. 
 
-              This value is also sourced from environment variable AWS_SDK_UA_APP_ID or the shared config profile attribute sdk_ua_app_id.',
 
-             'fn' => [__CLASS__, '_apply_app_id'],
 
-             'default' => [__CLASS__, '_default_app_id']
 
-         ],
 
-         'ua_append' => [
 
-             'type'     => 'value',
 
-             'valid'    => ['string', 'array'],
 
-             'doc'      => 'Provide a string or array of strings to send in the User-Agent header.',
 
-             'fn'       => [__CLASS__, '_apply_user_agent'],
 
-             'default'  => [],
 
-         ],
 
-         'idempotency_auto_fill' => [
 
-             'type'      => 'value',
 
-             'valid'     => ['bool', 'callable'],
 
-             'doc'       => 'Set to false to disable SDK to populate parameters that enabled \'idempotencyToken\' trait with a random UUID v4 value on your behalf. Using default value \'true\' still allows parameter value to be overwritten when provided. Note: auto-fill only works when cryptographically secure random bytes generator functions(random_bytes, openssl_random_pseudo_bytes or mcrypt_create_iv) can be found. You may also provide a callable source of random bytes.',
 
-             'default'   => true,
 
-             'fn'        => [__CLASS__, '_apply_idempotency_auto_fill']
 
-         ],
 
-         'use_aws_shared_config_files' => [
 
-             'type'      => 'value',
 
-             'valid'     => ['bool'],
 
-             'doc'       => 'Set to false to disable checking for shared aws config files usually located in \'~/.aws/config\' and \'~/.aws/credentials\'.  This will be ignored if you set the \'profile\' setting.',
 
-             'default'   => true,
 
-         ],
 
-     ];
 
-     /**
 
-      * Gets an array of default client arguments, each argument containing a
 
-      * hash of the following:
 
-      *
 
-      * - type: (string, required) option type described as follows:
 
-      *   - value: The default option type.
 
-      *   - config: The provided value is made available in the client's
 
-      *     getConfig() method.
 
-      * - valid: (array, required) Valid PHP types or class names. Note: null
 
-      *   is not an allowed type.
 
-      * - required: (bool, callable) Whether or not the argument is required.
 
-      *   Provide a function that accepts an array of arguments and returns a
 
-      *   string to provide a custom error message.
 
-      * - default: (mixed) The default value of the argument if not provided. If
 
-      *   a function is provided, then it will be invoked to provide a default
 
-      *   value. The function is provided the array of options and is expected
 
-      *   to return the default value of the option. The default value can be a
 
-      *   closure and can not be a callable string that is not  part of the
 
-      *   defaultArgs array.
 
-      * - doc: (string) The argument documentation string.
 
-      * - fn: (callable) Function used to apply the argument. The function
 
-      *   accepts the provided value, array of arguments by reference, and an
 
-      *   event emitter.
 
-      *
 
-      * Note: Order is honored and important when applying arguments.
 
-      *
 
-      * @return array
 
-      */
 
-     public static function getDefaultArguments()
 
-     {
 
-         return self::$defaultArgs;
 
-     }
 
-     /**
 
-      * @param array $argDefinitions Client arguments.
 
-      */
 
-     public function __construct(array $argDefinitions)
 
-     {
 
-         $this->argDefinitions = $argDefinitions;
 
-     }
 
-     /**
 
-      * Resolves client configuration options and attached event listeners.
 
-      * Check for missing keys in passed arguments
 
-      *
 
-      * @param array       $args Provided constructor arguments.
 
-      * @param HandlerList $list Handler list to augment.
 
-      *
 
-      * @return array Returns the array of provided options.
 
-      * @throws \InvalidArgumentException
 
-      * @see Aws\AwsClient::__construct for a list of available options.
 
-      */
 
-     public function resolve(array $args, HandlerList $list)
 
-     {
 
-         $args['config'] = [];
 
-         foreach ($this->argDefinitions as $key => $a) {
 
-             // Add defaults, validate required values, and skip if not set.
 
-             if (!isset($args[$key])) {
 
-                 if (isset($a['default'])) {
 
-                     // Merge defaults in when not present.
 
-                     if (is_callable($a['default'])
 
-                         && (
 
-                             is_array($a['default'])
 
-                             || $a['default'] instanceof \Closure
 
-                         )
 
-                     ) {
 
-                         $args[$key] = $a['default']($args);
 
-                     } else {
 
-                         $args[$key] = $a['default'];
 
-                     }
 
-                 } elseif (empty($a['required'])) {
 
-                     continue;
 
-                 } else {
 
-                     $this->throwRequired($args);
 
-                 }
 
-             }
 
-             // Validate the types against the provided value.
 
-             foreach ($a['valid'] as $check) {
 
-                 if (isset(self::$typeMap[$check])) {
 
-                     $fn = self::$typeMap[$check];
 
-                     if ($fn($args[$key])) {
 
-                         goto is_valid;
 
-                     }
 
-                 } elseif ($args[$key] instanceof $check) {
 
-                     goto is_valid;
 
-                 }
 
-             }
 
-             $this->invalidType($key, $args[$key]);
 
-             // Apply the value
 
-             is_valid:
 
-             if (isset($a['fn'])) {
 
-                 $a['fn']($args[$key], $args, $list);
 
-             }
 
-             if ($a['type'] === 'config') {
 
-                 $args['config'][$key] = $args[$key];
 
-             }
 
-         }
 
-         $this->_apply_client_context_params($args);
 
-         return $args;
 
-     }
 
-     /**
 
-      * Creates a verbose error message for an invalid argument.
 
-      *
 
-      * @param string $name        Name of the argument that is missing.
 
-      * @param array  $args        Provided arguments
 
-      * @param bool   $useRequired Set to true to show the required fn text if
 
-      *                            available instead of the documentation.
 
-      * @return string
 
-      */
 
-     private function getArgMessage($name, $args = [], $useRequired = false)
 
-     {
 
-         $arg = $this->argDefinitions[$name];
 
-         $msg = '';
 
-         $modifiers = [];
 
-         if (isset($arg['valid'])) {
 
-             $modifiers[] = implode('|', $arg['valid']);
 
-         }
 
-         if (isset($arg['choice'])) {
 
-             $modifiers[] = 'One of ' . implode(', ', $arg['choice']);
 
-         }
 
-         if ($modifiers) {
 
-             $msg .= '(' . implode('; ', $modifiers) . ')';
 
-         }
 
-         $msg = wordwrap("{$name}: {$msg}", 75, "\n  ");
 
-         if ($useRequired && is_callable($arg['required'])) {
 
-             $msg .= "\n\n  ";
 
-             $msg .= str_replace("\n", "\n  ", call_user_func($arg['required'], $args));
 
-         } elseif (isset($arg['doc'])) {
 
-             $msg .= wordwrap("\n\n  {$arg['doc']}", 75, "\n  ");
 
-         }
 
-         return $msg;
 
-     }
 
-     /**
 
-      * Throw when an invalid type is encountered.
 
-      *
 
-      * @param string $name     Name of the value being validated.
 
-      * @param mixed  $provided The provided value.
 
-      * @throws \InvalidArgumentException
 
-      */
 
-     private function invalidType($name, $provided)
 
-     {
 
-         $expected = implode('|', $this->argDefinitions[$name]['valid']);
 
-         $msg = "Invalid configuration value "
 
-             . "provided for \"{$name}\". Expected {$expected}, but got "
 
-             . describe_type($provided) . "\n\n"
 
-             . $this->getArgMessage($name);
 
-         throw new IAE($msg);
 
-     }
 
-     /**
 
-      * Throws an exception for missing required arguments.
 
-      *
 
-      * @param array $args Passed in arguments.
 
-      * @throws \InvalidArgumentException
 
-      */
 
-     private function throwRequired(array $args)
 
-     {
 
-         $missing = [];
 
-         foreach ($this->argDefinitions as $k => $a) {
 
-             if (empty($a['required'])
 
-                 || isset($a['default'])
 
-                 || isset($args[$k])
 
-             ) {
 
-                 continue;
 
-             }
 
-             $missing[] = $this->getArgMessage($k, $args, true);
 
-         }
 
-         $msg = "Missing required client configuration options: \n\n";
 
-         $msg .= implode("\n\n", $missing);
 
-         throw new IAE($msg);
 
-     }
 
-     public static function _apply_retries($value, array &$args, HandlerList $list)
 
-     {
 
-         // A value of 0 for the config option disables retries
 
-         if ($value) {
 
-             $config = RetryConfigProvider::unwrap($value);
 
-             if ($config->getMode() === 'legacy') {
 
-                 // # of retries is 1 less than # of attempts
 
-                 $decider = RetryMiddleware::createDefaultDecider(
 
-                     $config->getMaxAttempts() - 1
 
-                 );
 
-                 $list->appendSign(
 
-                     Middleware::retry($decider, null, $args['stats']['retries']),
 
-                     'retry'
 
-                 );
 
-             } else {
 
-                 $list->appendSign(
 
-                     RetryMiddlewareV2::wrap(
 
-                         $config,
 
-                         ['collect_stats' => $args['stats']['retries']]
 
-                     ),
 
-                     'retry'
 
-                 );
 
-             }
 
-         }
 
-     }
 
-     public static function _apply_defaults($value, array &$args, HandlerList $list)
 
-     {
 
-         $config = ConfigModeProvider::unwrap($value);
 
-         if ($config->getMode() !== 'legacy') {
 
-             if (!isset($args['retries']) && !is_null($config->getRetryMode())) {
 
-                 $args['retries'] = ['mode' => $config->getRetryMode()];
 
-             }
 
-             if (
 
-                 !isset($args['sts_regional_endpoints'])
 
-                 && !is_null($config->getStsRegionalEndpoints())
 
-             ) {
 
-                 $args['sts_regional_endpoints'] = ['mode' => $config->getStsRegionalEndpoints()];
 
-             }
 
-             if (
 
-                 !isset($args['s3_us_east_1_regional_endpoint'])
 
-                 && !is_null($config->getS3UsEast1RegionalEndpoints())
 
-             ) {
 
-                 $args['s3_us_east_1_regional_endpoint'] = ['mode' => $config->getS3UsEast1RegionalEndpoints()];
 
-             }
 
-             if (!isset($args['http'])) {
 
-                 $args['http'] = [];
 
-             }
 
-             if (
 
-                 !isset($args['http']['connect_timeout'])
 
-                 && !is_null($config->getConnectTimeoutInMillis())
 
-             ) {
 
-                 $args['http']['connect_timeout'] = $config->getConnectTimeoutInMillis() / 1000;
 
-             }
 
-             if (
 
-                 !isset($args['http']['timeout'])
 
-                 && !is_null($config->getHttpRequestTimeoutInMillis())
 
-             ) {
 
-                 $args['http']['timeout'] = $config->getHttpRequestTimeoutInMillis() / 1000;
 
-             }
 
-         }
 
-     }
 
-     public static function _apply_disable_request_compression($value, array &$args) {
 
-         if (is_callable($value)) {
 
-             $value = $value();
 
-         }
 
-         if (!is_bool($value)) {
 
-             throw new IAE(
 
-                 "Invalid configuration value provided for 'disable_request_compression'."
 
-                 . " value must be a bool."
 
-             );
 
-         }
 
-         $args['config']['disable_request_compression'] = $value;
 
-     }
 
-     public static function _default_disable_request_compression(array &$args) {
 
-         return ConfigurationResolver::resolve(
 
-             'disable_request_compression',
 
-             false,
 
-             'bool',
 
-             $args
 
-         );
 
-     }
 
-     public static function _apply_min_compression_size($value, array &$args) {
 
-         if (is_callable($value)) {
 
-             $value = $value();
 
-         }
 
-         if (!is_int($value)
 
-             || (is_int($value)
 
-                 && ($value < 0 || $value > 10485760))
 
-         ) {
 
-             throw new IAE(" Invalid configuration value provided for 'min_compression_size_bytes'."
 
-                 . " value must be an integer between 0 and 10485760, inclusive.");
 
-         }
 
-         $args['config']['request_min_compression_size_bytes'] = $value;
 
-     }
 
-     public static function _default_min_compression_size(array &$args) {
 
-         return ConfigurationResolver::resolve(
 
-             'request_min_compression_size_bytes',
 
-             10240,
 
-             'int',
 
-             $args
 
-         );
 
-     }
 
-     public static function _apply_credentials($value, array &$args)
 
-     {
 
-         if (is_callable($value)) {
 
-             return;
 
-         }
 
-         if ($value instanceof CredentialsInterface) {
 
-             $args['credentials'] = CredentialProvider::fromCredentials($value);
 
-         } elseif (is_array($value)
 
-             && isset($value['key'])
 
-             && isset($value['secret'])
 
-         ) {
 
-             $args['credentials'] = CredentialProvider::fromCredentials(
 
-                 new Credentials(
 
-                     $value['key'],
 
-                     $value['secret'],
 
-                     $value['token'] ?? null,
 
-                     $value['expires'] ?? null
 
-                 )
 
-             );
 
-         } elseif ($value === false) {
 
-             $args['credentials'] = CredentialProvider::fromCredentials(
 
-                 new Credentials('', '')
 
-             );
 
-             $args['config']['signature_version'] = 'anonymous';
 
-             $args['config']['configured_signature_version'] = true;
 
-         } elseif ($value instanceof CacheInterface) {
 
-             $args['credentials'] = CredentialProvider::defaultProvider($args);
 
-         } else {
 
-             throw new IAE('Credentials must be an instance of '
 
-                 . "'" . CredentialsInterface::class . ', an associative '
 
-                 . 'array that contains "key", "secret", and an optional "token" '
 
-                 . 'key-value pairs, a credentials provider function, or false.');
 
-         }
 
-     }
 
-     public static function _default_credential_provider(array $args)
 
-     {
 
-         return CredentialProvider::defaultProvider($args);
 
-     }
 
-     public static function _apply_token($value, array &$args)
 
-     {
 
-         if (is_callable($value)) {
 
-             return;
 
-         }
 
-         if ($value instanceof Token) {
 
-             $args['token'] = TokenProvider::fromToken($value);
 
-         } elseif (is_array($value)
 
-             && isset($value['token'])
 
-         ) {
 
-             $args['token'] = TokenProvider::fromToken(
 
-                 new Token(
 
-                     $value['token'],
 
-                     $value['expires'] ?? null
 
-                 )
 
-             );
 
-         } elseif ($value instanceof CacheInterface) {
 
-             $args['token'] = TokenProvider::defaultProvider($args);
 
-         } else {
 
-             throw new IAE('Token must be an instance of '
 
-                 . TokenInterface::class . ', an associative '
 
-                 . 'array that contains "token" and an optional "expires" '
 
-                 . 'key-value pairs, a token provider function, or false.');
 
-         }
 
-     }
 
-     public static function _default_token_provider(array $args)
 
-     {
 
-         return TokenProvider::defaultProvider($args);
 
-     }
 
-     public static function _apply_csm($value, array &$args, HandlerList $list)
 
-     {
 
-         if ($value === false) {
 
-             $value = new Configuration(
 
-                 false,
 
-                 \Aws\ClientSideMonitoring\ConfigurationProvider::DEFAULT_HOST,
 
-                 \Aws\ClientSideMonitoring\ConfigurationProvider::DEFAULT_PORT,
 
-                 \Aws\ClientSideMonitoring\ConfigurationProvider::DEFAULT_CLIENT_ID
 
-             );
 
-             $args['csm'] = $value;
 
-         }
 
-         $list->appendBuild(
 
-             ApiCallMonitoringMiddleware::wrap(
 
-                 $args['credentials'],
 
-                 $value,
 
-                 $args['region'],
 
-                 $args['api']->getServiceId()
 
-             ),
 
-             'ApiCallMonitoringMiddleware'
 
-         );
 
-         $list->appendAttempt(
 
-             ApiCallAttemptMonitoringMiddleware::wrap(
 
-                 $args['credentials'],
 
-                 $value,
 
-                 $args['region'],
 
-                 $args['api']->getServiceId()
 
-             ),
 
-             'ApiCallAttemptMonitoringMiddleware'
 
-         );
 
-     }
 
-     public static function _apply_api_provider(callable $value, array &$args)
 
-     {
 
-         $api = new Service(
 
-             ApiProvider::resolve(
 
-                 $value,
 
-                 'api',
 
-                 $args['service'],
 
-                 $args['version']
 
-             ),
 
-             $value
 
-         );
 
-         if (
 
-             empty($args['config']['signing_name'])
 
-             && isset($api['metadata']['signingName'])
 
-         ) {
 
-             $args['config']['signing_name'] = $api['metadata']['signingName'];
 
-         }
 
-         $args['api'] = $api;
 
-         $args['parser'] = Service::createParser($api);
 
-         $args['error_parser'] = Service::createErrorParser($api->getProtocol(), $api);
 
-     }
 
-     public static function _apply_endpoint_provider($value, array &$args)
 
-     {
 
-         if (!isset($args['endpoint'])) {
 
-             if ($value instanceof \Aws\EndpointV2\EndpointProviderV2) {
 
-                 $options = self::getEndpointProviderOptions($args);
 
-                 $value = PartitionEndpointProvider::defaultProvider($options)
 
-                     ->getPartition($args['region'], $args['service']);
 
-             }
 
-             $endpointPrefix = $args['api']['metadata']['endpointPrefix'] ?? $args['service'];
 
-             // Check region is a valid host label when it is being used to
 
-             // generate an endpoint
 
-             if (!self::isValidRegion($args['region'])) {
 
-                 throw new InvalidRegionException('Region must be a valid RFC'
 
-                     . ' host label.');
 
-             }
 
-             $serviceEndpoints =
 
-                 is_array($value) && isset($value['services'][$args['service']]['endpoints'])
 
-                     ? $value['services'][$args['service']]['endpoints']
 
-                     : null;
 
-             if (isset($serviceEndpoints[$args['region']]['deprecated'])) {
 
-                 trigger_error("The service " . $args['service'] . "has "
 
-                     . " deprecated the region " . $args['region'] . ".",
 
-                     E_USER_WARNING
 
-                 );
 
-             }
 
-             $args['region'] = \Aws\strip_fips_pseudo_regions($args['region']);
 
-             // Invoke the endpoint provider and throw if it does not resolve.
 
-             $result = EndpointProvider::resolve($value, [
 
-                 'service' => $endpointPrefix,
 
-                 'region'  => $args['region'],
 
-                 'scheme'  => $args['scheme'],
 
-                 'options' => self::getEndpointProviderOptions($args),
 
-             ]);
 
-             $args['endpoint'] = $result['endpoint'];
 
-             if (empty($args['config']['signature_version'])) {
 
-                 if (
 
-                     isset($args['api'])
 
-                     && $args['api']->getSignatureVersion() == 'bearer'
 
-                 ) {
 
-                     $args['config']['signature_version'] = 'bearer';
 
-                 } elseif (isset($result['signatureVersion'])) {
 
-                     $args['config']['signature_version'] = $result['signatureVersion'];
 
-                 }
 
-             }
 
-             if (
 
-                 empty($args['config']['signing_region'])
 
-                 && isset($result['signingRegion'])
 
-             ) {
 
-                 $args['config']['signing_region'] = $result['signingRegion'];
 
-             }
 
-             if (
 
-                 empty($args['config']['signing_name'])
 
-                 && isset($result['signingName'])
 
-             ) {
 
-                 $args['config']['signing_name'] = $result['signingName'];
 
-             }
 
-         }
 
-     }
 
-     public static function _apply_endpoint_discovery($value, array &$args) {
 
-         $args['endpoint_discovery'] = $value;
 
-     }
 
-     public static function _default_endpoint_discovery_provider(array $args)
 
-     {
 
-         return ConfigurationProvider::defaultProvider($args);
 
-     }
 
-     public static function _apply_use_fips_endpoint($value, array &$args) {
 
-         if ($value instanceof CacheInterface) {
 
-             $value = UseFipsConfigProvider::defaultProvider($args);
 
-         }
 
-         if (is_callable($value)) {
 
-             $value = $value();
 
-         }
 
-         if ($value instanceof PromiseInterface) {
 
-             $value = $value->wait();
 
-         }
 
-         if ($value instanceof UseFipsEndpointConfigurationInterface) {
 
-             $args['config']['use_fips_endpoint'] = $value;
 
-         } else {
 
-             // The Configuration class itself will validate other inputs
 
-             $args['config']['use_fips_endpoint'] = new UseFipsEndpointConfiguration($value);
 
-         }
 
-     }
 
-     public static function _default_use_fips_endpoint(array &$args) {
 
-         return UseFipsConfigProvider::defaultProvider($args);
 
-     }
 
-     public static function _apply_use_dual_stack_endpoint($value, array &$args) {
 
-         if ($value instanceof CacheInterface) {
 
-             $value = UseDualStackConfigProvider::defaultProvider($args);
 
-         }
 
-         if (is_callable($value)) {
 
-             $value = $value();
 
-         }
 
-         if ($value instanceof PromiseInterface) {
 
-             $value = $value->wait();
 
-         }
 
-         if ($value instanceof UseDualStackEndpointConfigurationInterface) {
 
-             $args['config']['use_dual_stack_endpoint'] = $value;
 
-         } else {
 
-             // The Configuration class itself will validate other inputs
 
-             $args['config']['use_dual_stack_endpoint'] =
 
-                 new UseDualStackEndpointConfiguration($value, $args['region']);
 
-         }
 
-     }
 
-     public static function _default_use_dual_stack_endpoint(array &$args) {
 
-         return UseDualStackConfigProvider::defaultProvider($args);
 
-     }
 
-     public static function _apply_serializer($value, array &$args, HandlerList $list)
 
-     {
 
-         $list->prependBuild(Middleware::requestBuilder($value), 'builder');
 
-     }
 
-     public static function _apply_debug($value, array &$args, HandlerList $list)
 
-     {
 
-         if ($value !== false) {
 
-             $list->interpose(
 
-                 new TraceMiddleware(
 
-                     $value === true ? [] : $value,
 
-                     $args['api'])
 
-             );
 
-         }
 
-     }
 
-     public static function _apply_stats($value, array &$args, HandlerList $list)
 
-     {
 
-         // Create an array of stat collectors that are disabled (set to false)
 
-         // by default. If the user has passed in true, enable all stat
 
-         // collectors.
 
-         $defaults = array_fill_keys(
 
-             ['http', 'retries', 'timer'],
 
-             $value === true
 
-         );
 
-         $args['stats'] = is_array($value)
 
-             ? array_replace($defaults, $value)
 
-             : $defaults;
 
-         if ($args['stats']['timer']) {
 
-             $list->prependInit(Middleware::timer(), 'timer');
 
-         }
 
-     }
 
-     public static function _apply_profile($_, array &$args)
 
-     {
 
-         $args['credentials'] = CredentialProvider::ini($args['profile']);
 
-     }
 
-     public static function _apply_validate($value, array &$args, HandlerList $list)
 
-     {
 
-         if ($value === false) {
 
-             return;
 
-         }
 
-         $validator = $value === true
 
-             ? new Validator()
 
-             : new Validator($value);
 
-         $list->appendValidate(
 
-             Middleware::validation($args['api'], $validator),
 
-             'validation'
 
-         );
 
-     }
 
-     public static function _apply_handler($value, array &$args, HandlerList $list)
 
-     {
 
-         $list->setHandler($value);
 
-     }
 
-     public static function _default_handler(array &$args)
 
-     {
 
-         return new WrappedHttpHandler(
 
-             default_http_handler(),
 
-             $args['parser'],
 
-             $args['error_parser'],
 
-             $args['exception_class'],
 
-             $args['stats']['http']
 
-         );
 
-     }
 
-     public static function _apply_http_handler($value, array &$args, HandlerList $list)
 
-     {
 
-         $args['handler'] = new WrappedHttpHandler(
 
-             $value,
 
-             $args['parser'],
 
-             $args['error_parser'],
 
-             $args['exception_class'],
 
-             $args['stats']['http']
 
-         );
 
-     }
 
-     public static function _apply_app_id($value, array &$args)
 
-     {
 
-         // AppId should not be longer than 50 chars
 
-         static $MAX_APP_ID_LENGTH = 50;
 
-         if (strlen($value) > $MAX_APP_ID_LENGTH) {
 
-             trigger_error("The provided or configured value for `AppId`, "
 
-                 ."which is an user agent parameter, exceeds the maximum length of "
 
-             ."$MAX_APP_ID_LENGTH characters.", E_USER_WARNING);
 
-         }
 
-         $args['app_id'] = $value;
 
-     }
 
-     public static function _default_app_id(array $args)
 
-     {
 
-         return ConfigurationResolver::resolve(
 
-             'sdk_ua_app_id',
 
-             '',
 
-             'string',
 
-             $args
 
-         );
 
-     }
 
-     public static function _apply_user_agent($inputUserAgent, array &$args, HandlerList $list)
 
-     {
 
-         // Add SDK version
 
-         $userAgent = ['aws-sdk-php/' . Sdk::VERSION];
 
-         // User Agent Metadata
 
-         $userAgent[] = 'ua/2.0';
 
-         // If on HHVM add the HHVM version
 
-         if (defined('HHVM_VERSION')) {
 
-             $userAgent []= 'HHVM/' . HHVM_VERSION;
 
-         }
 
-         // Add OS version
 
-         $disabledFunctions = explode(',', ini_get('disable_functions'));
 
-         if (function_exists('php_uname')
 
-             && !in_array('php_uname', $disabledFunctions, true)
 
-         ) {
 
-             $osName = "OS/" . php_uname('s') . '#' . php_uname('r');
 
-             if (!empty($osName)) {
 
-                 $userAgent []= $osName;
 
-             }
 
-         }
 
-         // Add the language version
 
-         $userAgent []= 'lang/php#' . phpversion();
 
-         // Add exec environment if present
 
-         if ($executionEnvironment = getenv('AWS_EXECUTION_ENV')) {
 
-             $userAgent []= $executionEnvironment;
 
-         }
 
-         // Add endpoint discovery if set
 
-         if (isset($args['endpoint_discovery'])) {
 
-             if (($args['endpoint_discovery'] instanceof \Aws\EndpointDiscovery\Configuration
 
-                 && $args['endpoint_discovery']->isEnabled())
 
-             ) {
 
-                 $userAgent []= 'cfg/endpoint-discovery';
 
-             } elseif (is_array($args['endpoint_discovery'])
 
-                 && isset($args['endpoint_discovery']['enabled'])
 
-                 && $args['endpoint_discovery']['enabled']
 
-             ) {
 
-                 $userAgent []= 'cfg/endpoint-discovery';
 
-             }
 
-         }
 
-         // Add retry mode if set
 
-         if (isset($args['retries'])) {
 
-             if ($args['retries'] instanceof \Aws\Retry\Configuration) {
 
-                 $userAgent []= 'cfg/retry-mode#' . $args["retries"]->getMode();
 
-             } elseif (is_array($args['retries'])
 
-                 && isset($args["retries"]["mode"])
 
-             ) {
 
-                 $userAgent []= 'cfg/retry-mode#' . $args["retries"]["mode"];
 
-             }
 
-         }
 
-         // AppID Metadata
 
-         if (!empty($args['app_id'])) {
 
-             $userAgent[] = 'app/' . $args['app_id'];
 
-         }
 
-         // Add the input to the end
 
-         if ($inputUserAgent){
 
-             if (!is_array($inputUserAgent)) {
 
-                 $inputUserAgent = [$inputUserAgent];
 
-             }
 
-             $inputUserAgent = array_map('strval', $inputUserAgent);
 
-             $userAgent = array_merge($userAgent, $inputUserAgent);
 
-         }
 
-         $args['ua_append'] = $userAgent;
 
-         $list->appendBuild(static function (callable $handler) use ($userAgent) {
 
-             return function (
 
-                 CommandInterface $command,
 
-                 RequestInterface $request
 
-             ) use ($handler, $userAgent) {
 
-                 return $handler(
 
-                     $command,
 
-                     $request->withHeader(
 
-                         'X-Amz-User-Agent',
 
-                         implode(' ', array_merge(
 
-                             $userAgent,
 
-                             $request->getHeader('X-Amz-User-Agent')
 
-                         ))
 
-                     )->withHeader(
 
-                         'User-Agent',
 
-                         implode(' ', array_merge(
 
-                             $userAgent,
 
-                             $request->getHeader('User-Agent')
 
-                         ))
 
-                     )
 
-                 );
 
-             };
 
-         });
 
-     }
 
-     public static function _apply_endpoint($value, array &$args, HandlerList $list)
 
-     {
 
-         if (empty($value)) {
 
-             unset($args['endpoint']);
 
-             return;
 
-         }
 
-         $args['endpoint'] = $value;
 
-     }
 
-     public static function _apply_idempotency_auto_fill(
 
-         $value,
 
-         array &$args,
 
-         HandlerList $list
 
-     ) {
 
-         $enabled = false;
 
-         $generator = null;
 
-         if (is_bool($value)) {
 
-             $enabled = $value;
 
-         } elseif (is_callable($value)) {
 
-             $enabled = true;
 
-             $generator = $value;
 
-         }
 
-         if ($enabled) {
 
-             $list->prependInit(
 
-                 IdempotencyTokenMiddleware::wrap($args['api'], $generator),
 
-                 'idempotency_auto_fill'
 
-             );
 
-         }
 
-     }
 
-     public static function _default_endpoint_provider(array $args)
 
-     {
 
-         $service = $args['api'] ?? null;
 
-         $serviceName = isset($service) ? $service->getServiceName() : null;
 
-         $apiVersion = isset($service) ? $service->getApiVersion() : null;
 
-         if (self::isValidService($serviceName)
 
-             && self::isValidApiVersion($serviceName, $apiVersion)
 
-         ) {
 
-             $ruleset = EndpointDefinitionProvider::getEndpointRuleset(
 
-                 $service->getServiceName(),
 
-                 $service->getApiVersion()
 
-             );
 
-             return new \Aws\EndpointV2\EndpointProviderV2(
 
-                 $ruleset,
 
-                 EndpointDefinitionProvider::getPartitions()
 
-             );
 
-         }
 
-         $options = self::getEndpointProviderOptions($args);
 
-         return PartitionEndpointProvider::defaultProvider($options)
 
-             ->getPartition($args['region'], $args['service']);
 
-     }
 
-     public static function _default_serializer(array $args)
 
-     {
 
-         return Service::createSerializer(
 
-             $args['api'],
 
-             $args['endpoint']
 
-         );
 
-     }
 
-     public static function _default_signature_provider()
 
-     {
 
-         return SignatureProvider::defaultProvider();
 
-     }
 
-     public static function _default_auth_scheme_resolver(array $args)
 
-     {
 
-         return new AuthSchemeResolver($args['credentials'], $args['token']);
 
-     }
 
-     public static function _default_signature_version(array &$args)
 
-     {
 
-         if (isset($args['config']['signature_version'])) {
 
-             return $args['config']['signature_version'];
 
-         }
 
-         $args['__partition_result'] = isset($args['__partition_result'])
 
-             ? isset($args['__partition_result'])
 
-             : call_user_func(PartitionEndpointProvider::defaultProvider(), [
 
-                 'service' => $args['service'],
 
-                 'region' => $args['region'],
 
-             ]);
 
-         return isset($args['__partition_result']['signatureVersion'])
 
-             ? $args['__partition_result']['signatureVersion']
 
-             : $args['api']->getSignatureVersion();
 
-     }
 
-     public static function _default_signing_name(array &$args)
 
-     {
 
-         if (isset($args['config']['signing_name'])) {
 
-             return $args['config']['signing_name'];
 
-         }
 
-         $args['__partition_result'] = isset($args['__partition_result'])
 
-             ? isset($args['__partition_result'])
 
-             : call_user_func(PartitionEndpointProvider::defaultProvider(), [
 
-                 'service' => $args['service'],
 
-                 'region' => $args['region'],
 
-             ]);
 
-         if (isset($args['__partition_result']['signingName'])) {
 
-             return $args['__partition_result']['signingName'];
 
-         }
 
-         if ($signingName = $args['api']->getSigningName()) {
 
-             return $signingName;
 
-         }
 
-         return $args['service'];
 
-     }
 
-     public static function _default_signing_region(array &$args)
 
-     {
 
-         if (isset($args['config']['signing_region'])) {
 
-             return $args['config']['signing_region'];
 
-         }
 
-         $args['__partition_result'] = isset($args['__partition_result'])
 
-             ? isset($args['__partition_result'])
 
-             : call_user_func(PartitionEndpointProvider::defaultProvider(), [
 
-                 'service' => $args['service'],
 
-                 'region' => $args['region'],
 
-             ]);
 
-         return $args['__partition_result']['signingRegion'] ?? $args['region'];
 
-     }
 
-     public static function _apply_ignore_configured_endpoint_urls($value, array &$args)
 
-     {
 
-         $args['config']['ignore_configured_endpoint_urls'] = $value;
 
-     }
 
-     public static function _default_ignore_configured_endpoint_urls(array &$args)
 
-     {
 
-         return ConfigurationResolver::resolve(
 
-             'ignore_configured_endpoint_urls',
 
-             false,
 
-             'bool',
 
-             $args
 
-         );
 
-     }
 
-     public static function _default_endpoint(array &$args)
 
-     {
 
-         if ($args['config']['ignore_configured_endpoint_urls']
 
-             || !self::isValidService($args['service'])
 
-         ) {
 
-             return '';
 
-         }
 
-         $serviceIdentifier = \Aws\manifest($args['service'])['serviceIdentifier'];
 
-         $value =  ConfigurationResolver::resolve(
 
-             'endpoint_url_' . $serviceIdentifier,
 
-             '',
 
-             'string',
 
-             $args + [
 
-                 'ini_resolver_options' => [
 
-                     'section' => 'services',
 
-                     'subsection' => $serviceIdentifier,
 
-                     'key' => 'endpoint_url'
 
-                 ]
 
-             ]
 
-         );
 
-         if (empty($value)) {
 
-             $value = ConfigurationResolver::resolve(
 
-                 'endpoint_url',
 
-                 '',
 
-                 'string',
 
-                 $args
 
-             );
 
-         }
 
-         if (!empty($value)) {
 
-             $args['config']['configured_endpoint_url'] = true;
 
-         }
 
-         return $value;
 
-     }
 
-     public static function _apply_region($value, array &$args)
 
-     {
 
-         if (empty($value)) {
 
-             self::_missing_region($args);
 
-         }
 
-         $args['region'] = $value;
 
-     }
 
-     public static function _default_region(&$args)
 
-     {
 
-         return ConfigurationResolver::resolve('region', '', 'string');
 
-     }
 
-     public static function _missing_region(array $args)
 
-     {
 
-         $service = $args['service'] ?? '';
 
-         $msg = <<<EOT
 
- Missing required client configuration options:
 
- region: (string)
 
- A "region" configuration value is required for the "{$service}" service
 
- (e.g., "us-west-2"). A list of available public regions and endpoints can be
 
- found at http://docs.aws.amazon.com/general/latest/gr/rande.html.
 
- EOT;
 
-         throw new IAE($msg);
 
-     }
 
-     /**
 
-      * Extracts client options for the endpoint provider to its own array
 
-      *
 
-      * @param array $args
 
-      * @return array
 
-      */
 
-     private static function getEndpointProviderOptions(array $args)
 
-     {
 
-         $options = [];
 
-         $optionKeys = [
 
-             'sts_regional_endpoints',
 
-             's3_us_east_1_regional_endpoint',
 
-         ];
 
-         $configKeys = [
 
-             'use_dual_stack_endpoint',
 
-             'use_fips_endpoint',
 
-         ];
 
-         foreach ($optionKeys as $key) {
 
-             if (isset($args[$key])) {
 
-                 $options[$key] = $args[$key];
 
-             }
 
-         }
 
-         foreach ($configKeys as $key) {
 
-             if (isset($args['config'][$key])) {
 
-                 $options[$key] = $args['config'][$key];
 
-             }
 
-         }
 
-         return $options;
 
-     }
 
-     /**
 
-      * Validates a region to be used for endpoint construction
 
-      *
 
-      * @param $region
 
-      * @return bool
 
-      */
 
-     private static function isValidRegion($region)
 
-     {
 
-         return is_valid_hostlabel($region);
 
-     }
 
-     private function _apply_client_context_params(array $args)
 
-     {
 
-         if (isset($args['api'])
 
-             && !empty($args['api']->getClientContextParams()))
 
-         {
 
-             $clientContextParams = $args['api']->getClientContextParams();
 
-             foreach($clientContextParams as $paramName => $paramDefinition) {
 
-                 $definition = [
 
-                     'type' => 'value',
 
-                     'valid' => [$paramDefinition['type']],
 
-                     'doc' => $paramDefinition['documentation'] ?? null
 
-                 ];
 
-                 $this->argDefinitions[$paramName] = $definition;
 
-                 if (isset($args[$paramName])) {
 
-                     $fn = self::$typeMap[$paramDefinition['type']];
 
-                     if (!$fn($args[$paramName])) {
 
-                         $this->invalidType($paramName, $args[$paramName]);
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-     }
 
-     private static function isValidService($service) {
 
-         if (is_null($service)) {
 
-             return false;
 
-         }
 
-         $services = \Aws\manifest();
 
-         return isset($services[$service]);
 
-     }
 
-     private static function isValidApiVersion($service, $apiVersion) {
 
-         if (is_null($apiVersion)) {
 
-             return false;
 
-         }
 
-         return is_dir(
 
-             __DIR__ . "/data/{$service}/$apiVersion"
 
-         );
 
-     }
 
- }
 
 
  |